diff --git a/main.go b/main.go index 9689ffa..7dd33ad 100644 --- a/main.go +++ b/main.go @@ -24,8 +24,8 @@ func config() models.Config { func testConfig() models.Config { return models.Config{ - Token: "7757765456:AAFpFXhbi9XCfgRt7P3OT3F_jrBBplubWZA", - HostName: "217.12.40.237", + Token: "8301440775:AAF7j6ENql93UXB5VwrOAg7k7W3JLjMbPcU", + HostName: "quizer.space", DbName: "test", UserName: "root", Password: "12641264", @@ -57,7 +57,9 @@ func main() { dickController := controllers.NewDick(dc) duelController := controllers.NewDuel(b, dc) bonusController := controllers.NewBonusController(b, dc) + acceptButton := tele.Btn{Unique: controllers.AcceptDuelButtonUnique} + b.Handle(&acceptButton, duelController.AcceptMatch) b.Handle("/dick", dickController.Dick) b.Handle("/top_dick", dickController.TopDick) diff --git a/src/controllers/duelController.go b/src/controllers/duelController.go index 28f7671..d985319 100644 --- a/src/controllers/duelController.go +++ b/src/controllers/duelController.go @@ -11,6 +11,9 @@ import ( tele "gopkg.in/telebot.v4" ) +// AcceptDuelButtonUnique is the unique identifier for the duel accept button. +const AcceptDuelButtonUnique = "accept_duel" + type DuelController struct { PlayerOne struct { ID int64 @@ -70,14 +73,24 @@ func (s *DuelController) StartMatch(c tele.Context) error { s.PlayerOne.ID = c.Sender().ID s.PlayerOne.FName = c.Sender().FirstName - user := s.DC.GetUser(s.PlayerOne.ID) + user := s.DC.GetUser(s.PlayerOne.ID) // Assuming GetUser now returns (*User, error) + // CRITICAL: Check if the user was found to prevent a panic. + if user == nil { + s.Inited = false // Reset state since the duel can't start + return c.Send("Не удалось найти вас в базе данных. Попробуйте /start.") + } if user.DickSize < summ { s.Inited = false return c.Send("У вас недостаточно длинный пенис для состязания!") } - return c.Send(fmt.Sprintf("%s начал дуель, ставка: %d", s.PlayerOne.FName, summ)) + // Create an inline keyboard with an "Accept" button + markup := &tele.ReplyMarkup{} + btnAccept := markup.Data("Принять", AcceptDuelButtonUnique) + markup.Inline(markup.Row(btnAccept)) + + return c.Send(fmt.Sprintf("%s начал дуель, ставка: %d", s.PlayerOne.FName, summ), markup) } // Accept Match @@ -93,7 +106,12 @@ func (s *DuelController) AcceptMatch(c tele.Context) error { s.PlayerTwo.ID = c.Sender().ID s.PlayerTwo.FName = c.Sender().FirstName - user := s.DC.GetUser(s.PlayerTwo.ID) + user := s.DC.GetUser(s.PlayerTwo.ID) // Assuming GetUser now returns (*User, error) + // CRITICAL: Check if the user was found to prevent a panic. + if user == nil { + // No need to reset state here, the duel is still waiting for a valid player. + return c.Send("Не удалось найти вас в базе данных. Попробуйте /start.") + } if user.DickSize < s.Summ { return c.Send("У вас недостаточно длинный пенис для состязания!") @@ -103,10 +121,10 @@ func (s *DuelController) AcceptMatch(c tele.Context) error { return c.Send("Вы не можете принять участие в своей же дуэли!") } - s.Summ *= 2 - go s.gameProccess(c.Chat()) - s.MatchAccepted = true + s.Summ *= 2 + + go s.gameProccess(c.Chat()) return c.Send(fmt.Sprintf("%s принимает участие в дуэли.", s.PlayerTwo.FName)) } @@ -114,27 +132,34 @@ func (s *DuelController) AcceptMatch(c tele.Context) error { // Clear match func (s *DuelController) ClearMatch(c tele.Context) error { if c.Sender().ID == s.PlayerOne.ID { - s.PlayerOne.Counter = 0 - s.PlayerTwo.Counter = 0 - s.PlayerOne.FName = "" - s.PlayerTwo.FName = "" - s.PlayerOne.ID = 0 - s.PlayerTwo.ID = 0 - s.Inited = false - s.Summ = 0 - + s.resetDuelState() return c.Send(fmt.Sprintf("%s отменил дуель!", c.Sender().FirstName)) } else { return c.Send("Отменить дуель может только инициатор!") } } +// resetDuelState clears the current duel's information, making it ready for a new one. +func (s *DuelController) resetDuelState() { + s.PlayerOne.Counter = 0 + s.PlayerTwo.Counter = 0 + s.PlayerOne.FName = "" + s.PlayerTwo.FName = "" + s.PlayerOne.ID = 0 + s.PlayerTwo.ID = 0 + s.Summ = 0 + s.Inited = false + s.MatchAccepted = false +} + // Start Game func (s *DuelController) gameProccess(r tele.Recipient) { time.Sleep(time.Second * 3) msg, err := s.Bot.Send(r, fmt.Sprintf("Дуэль началась!\nНа кону: %d", s.Summ)) if err != nil { - log.Fatal(err) + log.Printf("Error sending duel start message: %v", err) + s.resetDuelState() // Reset state if we can't even send the message + return } s.RoundOne(msg) } @@ -177,8 +202,16 @@ func (s *DuelController) RoundThree(msg *tele.Message) { // Check Win func (s *DuelController) CheckWin(msg *tele.Message) { + // Ensure the duel state is reset regardless of how this function exits. + defer s.resetDuelState() + userOne := s.DC.GetUser(s.PlayerOne.ID) userTwo := s.DC.GetUser(s.PlayerTwo.ID) + if userOne == nil || userTwo == nil { + log.Println("Error: Could not find one or both duel participants in CheckWin.") + s.Bot.Edit(msg, "Произошла ошибка, дуэль отменена.") + return + } time.Sleep(time.Second * 3) if s.PlayerOne.Counter > s.PlayerTwo.Counter { @@ -192,10 +225,4 @@ func (s *DuelController) CheckWin(msg *tele.Message) { } else if s.PlayerOne.Counter == s.PlayerTwo.Counter { s.Bot.Edit(msg, "Ничья!") } - - s.PlayerOne.Counter = 0 - s.PlayerTwo.Counter = 0 - s.Summ = 0 - s.Inited = false - s.MatchAccepted = false }