dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit f53e923efe81f4c37838b68ceb95aa3484691f4c
parent 4110fee2c067fa1c58b7b2ed5e326158b4fa0958
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Sat, 28 Jan 2023 20:07:37 -0800

remove (in chat) chess hack

Diffstat:
Mpkg/web/handlers/api/v1/chess.go | 69+++++++++++++++++++++++++++++++++++++++++++--------------------------
Mpkg/web/handlers/api/v1/handlers.go | 16++++++++++++++++
Mpkg/web/handlers/api/v1/topBarHandler.go | 3---
Mpkg/web/handlers/handlers.go | 6+++---
Mpkg/web/middlewares/middlewares.go | 6++----
Mpkg/web/web.go | 1+
6 files changed, 65 insertions(+), 36 deletions(-)

diff --git a/pkg/web/handlers/api/v1/chess.go b/pkg/web/handlers/api/v1/chess.go @@ -264,7 +264,7 @@ func (g *ChessGame) renderBoardB64(isFlipped bool) string { return imgB64 } -func (g *ChessGame) DrawPlayerCard(inChat, isBlack, isYourTurn bool) string { +func (g *ChessGame) DrawPlayerCard(roomName string, inChat, isBlack, isYourTurn bool) string { enemy := g.Player2 if isBlack { enemy = g.Player1 @@ -287,9 +287,15 @@ func (g *ChessGame) DrawPlayerCard(inChat, isBlack, isYourTurn bool) string { <button type="submit">Resign</button> </form> {{ if .IsYourTurn }} - <form method="post"{{ if .InChat }} action="/api/v1/chat/top-bar/chess" target="iframe1"{{ end }}> + <form method="post"{{ if .InChat }} action="/api/v1/chess"{{ end }}> {{ .Table }} - <input type="hidden" name="message" value="/pm {{ .Username }} /c move" /> + {{ if .InChat }} + <input type="hidden" name="room" value="{{ .RoomName }}" /> + <input type="hidden" name="enemyUsername" value="{{ .Username }}" /> + <input type="hidden" name="move" value="move" /> + {{ else }} + <input type="hidden" name="message" value="/pm {{ .Username }} /c move" /> + {{ end }} <button type="submit">Move</button> </form> {{ else }} @@ -305,6 +311,7 @@ func (g *ChessGame) DrawPlayerCard(inChat, isBlack, isYourTurn bool) string { ` data := map[string]any{ + "RoomName": roomName, "IsYourTurn": isYourTurn, "InChat": inChat, "White": g.Player1, @@ -407,6 +414,12 @@ func (b *Chess) NewGame(gameKey string, user1, user2 database.User) *ChessGame { return g } +func (b *Chess) newGame(gameKey string, user1, user2 database.User) *ChessGame { + g := newChessGame(gameKey, user1, user2) + b.games[gameKey] = g + return g +} + func (b *Chess) SendMove(gameKey string, userID database.UserID, g *ChessGame, c echo.Context) error { if (g.Game.Position().Turn() == chess.White && userID != g.Player1.ID) || (g.Game.Position().Turn() == chess.Black && userID != g.Player2.ID) { @@ -470,55 +483,59 @@ func (b *Chess) SendMove(gameKey string, userID database.UserID, g *ChessGame, c } func (b *Chess) InterceptMsg(cmd *Command) { - b.Lock() - defer b.Unlock() - m := cRgx.FindStringSubmatch(cmd.message) if len(m) != 3 { return } + enemyUsername := m[1] + pos := m[2] + if err := b.playMove(enemyUsername, pos, *cmd.authUser, cmd.c, cmd.room.Name, cmd.roomKey, cmd.room.ID); err != nil { + cmd.err = err + return + } + cmd.err = ErrStop +} + +func (b *Chess) playMove(enemyUsername, pos string, authUser database.User, c echo.Context, roomName, roomKey string, roomID database.RoomID) error { + b.Lock() + defer b.Unlock() - user, err := database.GetUserByUsername(m[1]) + user, err := database.GetUserByUsername(enemyUsername) if err != nil { - cmd.err = errors.New("invalid username") - return + return errors.New("invalid username") } var gameKey string - if cmd.fromUserID < user.ID { - gameKey = fmt.Sprintf("%d_%d", cmd.fromUserID, user.ID) + if authUser.ID < user.ID { + gameKey = fmt.Sprintf("%d_%d", authUser.ID, user.ID) } else { - gameKey = fmt.Sprintf("%d_%d", user.ID, cmd.fromUserID) + gameKey = fmt.Sprintf("%d_%d", user.ID, authUser.ID) } - pos := m[2] - g, ok := b.games[gameKey] if ok { - if err := b.SendMove(gameKey, cmd.fromUserID, g, cmd.c); err != nil { - cmd.err = err - return + if err := b.SendMove(gameKey, authUser.ID, g, c); err != nil { + return err } } else { if pos != "" { - cmd.err = errors.New("no Game ongoing") - return + return errors.New("no Game ongoing") } - g = b.NewGame(gameKey, user, *cmd.authUser) + g = b.newGame(gameKey, user, authUser) } // Delete old messages sent by "0" to the players if err := database.DB. - Where("room_id = ? AND user_id = ? AND (to_user_id = ? OR to_user_id = ?)", cmd.room.ID, b.zeroID, g.Player1.ID, g.Player2.ID). + Where("room_id = ? AND user_id = ? AND (to_user_id = ? OR to_user_id = ?)", roomID, b.zeroID, g.Player1.ID, g.Player2.ID). Delete(&database.ChatMessage{}).Error; err != nil { logrus.Error(err) } - card1 := g.DrawPlayerCard(true, false, true) - _, _ = database.CreateMsg(card1, card1, cmd.roomKey, cmd.room.ID, b.zeroID, &g.Player1.ID) + card1 := g.DrawPlayerCard(roomName, true, false, true) + _, _ = database.CreateMsg(card1, card1, roomKey, roomID, b.zeroID, &g.Player1.ID) - card1 = g.DrawPlayerCard(true, true, true) - _, _ = database.CreateMsg(card1, card1, cmd.roomKey, cmd.room.ID, b.zeroID, &g.Player2.ID) + card1 = g.DrawPlayerCard(roomName, true, true, true) + _, _ = database.CreateMsg(card1, card1, roomKey, roomID, b.zeroID, &g.Player2.ID) - cmd.err = ErrStop + return nil } diff --git a/pkg/web/handlers/api/v1/handlers.go b/pkg/web/handlers/api/v1/handlers.go @@ -510,6 +510,22 @@ func CaptchaSolverHandler(c echo.Context) error { return c.JSON(http.StatusOK, map[string]any{"answer": answer}) } +func ChessHandler(c echo.Context) error { + authUser := c.Get("authUser").(*database.User) + roomName := c.Request().PostFormValue("room") + enemyUsername := c.Request().PostFormValue("enemyUsername") + pos := c.Request().PostFormValue("move") + redirectURL := "/api/v1/chat/messages/" + roomName + room, roomKey, err := dutils.GetRoomAndKey(c, roomName) + if err != nil { + return c.Redirect(http.StatusFound, redirectURL+"?error="+err.Error()+"&errorTs="+utils.FormatInt64(time.Now().Unix())) + } + if err = ChessInstance.playMove(enemyUsername, pos, *authUser, c, roomName, roomKey, room.ID); err != nil { + return c.Redirect(http.StatusFound, redirectURL+"?error="+err.Error()+"&errorTs="+utils.FormatInt64(time.Now().Unix())) + } + return c.Redirect(http.StatusFound, redirectURL) +} + func BattleshipHandler(c echo.Context) error { authUser := c.Get("authUser").(*database.User) roomName := c.Request().PostFormValue("room") diff --git a/pkg/web/handlers/api/v1/topBarHandler.go b/pkg/web/handlers/api/v1/topBarHandler.go @@ -209,9 +209,6 @@ func ChatTopBarHandler(c echo.Context) error { authUser := c.Get("authUser").(*database.User) var data chatTopBarData data.RoomName = c.Param("roomName") - if data.RoomName == "chess" { - data.RoomName = "general" - } queryParams := c.QueryParams() origMl := utils.DoParseBool(c.QueryParam(redirectMultilineQP)) diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go @@ -4377,7 +4377,7 @@ func ChessGameHandler(c echo.Context) error { c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8) c.Response().WriteHeader(http.StatusOK) _, _ = c.Response().Write([]byte(cssReset)) - card1 := g.DrawPlayerCard(false, isFlipped, isYourTurn) + card1 := g.DrawPlayerCard("", false, isFlipped, isYourTurn) _, _ = c.Response().Write([]byte(fmt.Sprintf(`<div id="div_0">%s</div>`, card1))) return nil } @@ -4421,7 +4421,7 @@ func ChessGameHandler(c echo.Context) error { if isSpectator { card1 = g.DrawSpectatorCard(isFlipped) } else { - card1 = g.DrawPlayerCard(false, isFlipped, isYourTurn) + card1 = g.DrawPlayerCard("", false, isFlipped, isYourTurn) } _, _ = c.Response().Write([]byte(fmt.Sprintf(`<div id="div_0">%s</div>`, card1))) @@ -4451,7 +4451,7 @@ Loop: if isSpectator { card1 = g.DrawSpectatorCard(isFlipped) } else { - card1 = g.DrawPlayerCard(false, isFlipped, isYourTurnFn()) + card1 = g.DrawPlayerCard("", false, isFlipped, isYourTurnFn()) } _, _ = c.Response().Write([]byte(fmt.Sprintf(`<style>#div_%d { display: none; }</style>`, i-1))) _, _ = c.Response().Write([]byte(fmt.Sprintf(`<div id="div_%d">%s</div>`, i, card1))) diff --git a/pkg/web/middlewares/middlewares.go b/pkg/web/middlewares/middlewares.go @@ -174,7 +174,8 @@ func CSRFMiddleware() echo.MiddlewareFunc { Skipper: func(c echo.Context) bool { apiKey := c.Request().Header.Get("DKF_API_KEY") if (apiKey != "" && strings.HasPrefix(c.Path(), "/api/v1/")) || - c.Path() == "/api/v1/battleship" { + c.Path() == "/api/v1/battleship" || + c.Path() == "/api/v1/chess" { return true } if c.Path() == "/chess/:key" { @@ -183,9 +184,6 @@ func CSRFMiddleware() echo.MiddlewareFunc { if strings.HasPrefix(c.Path(), "/api/v1/chat/top-bar/:roomName") && c.Param("roomName") == "werewolf" { return true } - if strings.HasPrefix(c.Path(), "/api/v1/chat/top-bar/:roomName") && c.Param("roomName") == "chess" { - return true - } return false }, } diff --git a/pkg/web/web.go b/pkg/web/web.go @@ -135,6 +135,7 @@ func getMainServer(i18nBundle *i18n.Bundle, renderer *tmp.Templates) echo.Handle authGroup.GET("/api/v1/captcha-svc", v1.GetCaptchaHandler) authGroup.POST("/api/v1/chat/:roomID/notifier", v1.RoomNotifierHandler) authGroup.POST("/api/v1/battleship", v1.BattleshipHandler) + authGroup.POST("/api/v1/chess", v1.ChessHandler) authGroup.POST("/api/v1/captcha/solver", v1.CaptchaSolverHandler) authGroup.GET("/api/v1/chat/top-bar/:roomName", v1.ChatTopBarHandler) authGroup.POST("/api/v1/chat/top-bar/:roomName", v1.ChatTopBarHandler, middlewares.AuthRateLimitMiddleware(1*time.Second, 3))