dkforest

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

commit 3631e795f662cec5ce5d48f62fab2477b23ce309
parent f4b702761b2c26288b85f80654ebe17d3c0518cd
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Wed,  9 Nov 2022 14:17:50 -0800

UI form to create chess games

Diffstat:
Apkg/database/utils/utils.go | 39+++++++++++++++++++++++++++++++++++++++
Mpkg/web/handlers/api/v1/chess.go | 15+++++++++++++++
Mpkg/web/handlers/api/v1/slashInterceptor.go | 37++-----------------------------------
Mpkg/web/handlers/api/v1/topBarHandler.go | 14++++++--------
Mpkg/web/handlers/data.go | 4+++-
Mpkg/web/handlers/handlers.go | 16++++++++++++++++
Mpkg/web/public/views/pages/chess.gohtml | 12++++++++++++
Mpkg/web/web.go | 1+
8 files changed, 94 insertions(+), 44 deletions(-)

diff --git a/pkg/database/utils/utils.go b/pkg/database/utils/utils.go @@ -0,0 +1,39 @@ +package utils + +import ( + "dkforest/pkg/config" + "dkforest/pkg/database" + "github.com/sirupsen/logrus" +) + +func GetZeroUser() database.User { + zeroUser, err := database.GetUserByUsername(config.NullUsername) + if err != nil { + logrus.Fatal(err) + } + return zeroUser +} + +func SendNewChessGameMessages(key string, zeroUser, player1, player2 database.User) { + // Send game link to players + getPlayerMsg := func(opponent database.User) (raw string, msg string) { + raw = `Chess game against ` + opponent.Username + msg = `<a href="/chess/` + key + `" rel="noopener noreferrer" target="_blank">Chess game against ` + opponent.Username + `</a>` + return + } + raw, msg := getPlayerMsg(player2) + _, _ = database.CreateMsg(raw, msg, "", config.GeneralRoomID, zeroUser.ID, &player1.ID) + raw, msg = getPlayerMsg(player1) + _, _ = database.CreateMsg(raw, msg, "", config.GeneralRoomID, zeroUser.ID, &player2.ID) + + // Send notifications to chess games subscribers + raw = `Chess game: ` + player1.Username + ` VS ` + player2.Username + msg = `<a href="/chess/` + key + `" rel="noopener noreferrer" target="_blank">Chess game: ` + player1.Username + ` VS ` + player2.Username + `</a>` + users, _ := database.GetChessSubscribers() + for _, user := range users { + if user.ID == player1.ID || user.ID == player2.ID { + continue + } + _, _ = database.CreateMsg(raw, msg, "", config.GeneralRoomID, zeroUser.ID, &user.ID) + } +} diff --git a/pkg/web/handlers/api/v1/chess.go b/pkg/web/handlers/api/v1/chess.go @@ -5,12 +5,14 @@ import ( "dkforest/bindata" "dkforest/pkg/config" "dkforest/pkg/database" + dutils "dkforest/pkg/database/utils" "dkforest/pkg/pubsub" "dkforest/pkg/utils" "encoding/base64" "errors" "fmt" "github.com/fogleman/gg" + "github.com/google/uuid" "github.com/labstack/echo" "github.com/notnil/chess" "github.com/sirupsen/logrus" @@ -380,6 +382,19 @@ func (b *Chess) GetGames() (out []ChessGame) { return } +func (b *Chess) NewGame1(player1, player2 database.User) (*ChessGame, error) { + if player1.ID == player2.ID { + return nil, errors.New("can't play yourself") + } + + key := uuid.New().String() + g := b.NewGame(key, player1, player2) + + zeroUser := dutils.GetZeroUser() + dutils.SendNewChessGameMessages(key, zeroUser, player1, player2) + return g, nil +} + func (b *Chess) NewGame(gameKey string, user1, user2 database.User) *ChessGame { g := newChessGame(gameKey, user1, user2) b.Lock() diff --git a/pkg/web/handlers/api/v1/slashInterceptor.go b/pkg/web/handlers/api/v1/slashInterceptor.go @@ -8,7 +8,6 @@ import ( "dkforest/pkg/utils" "errors" "fmt" - "github.com/google/uuid" "github.com/sirupsen/logrus" "sort" "strings" @@ -970,48 +969,16 @@ func handleChessCmd(c *Command) (handled bool) { c.err = errors.New("invalid username") return true } - if player1.ID == player2.ID { - c.err = errors.New("can't play yourself") + if _, err := ChessInstance.NewGame1(player1, player2); err != nil { + c.err = err return true } - key := uuid.New().String() - ChessInstance.NewGame(key, player1, player2) - - sendNewChessGameMessages(c, key, player1, player2) - c.err = NewErrSuccess("chess game created") - return true } return } -func sendNewChessGameMessages(c *Command, key string, player1, player2 database.User) { - zeroUser := c.getZeroUser() - - // Send game link to players - getPlayerMsg := func(opponent database.User) (raw string, msg string) { - raw = `Chess game against ` + opponent.Username - msg = `<a href="/chess/` + key + `" rel="noopener noreferrer" target="_blank">Chess game against ` + opponent.Username + `</a>` - return - } - raw, msg := getPlayerMsg(player2) - c.rawMsg(zeroUser, &player1, raw, msg) - raw, msg = getPlayerMsg(player1) - c.rawMsg(zeroUser, &player2, raw, msg) - - // Send notifications to chess games subscribers - raw = `Chess game: ` + player1.Username + ` VS ` + player2.Username - msg = `<a href="/chess/` + key + `" rel="noopener noreferrer" target="_blank">Chess game: ` + player1.Username + ` VS ` + player2.Username + `</a>` - users, _ := database.GetChessSubscribers() - for _, user := range users { - if user.ID == player1.ID || user.ID == player2.ID { - continue - } - c.rawMsg(zeroUser, &user, raw, msg) - } -} - func handleInboxCmd(c *Command) (handled bool) { if m := inboxRgx.FindStringSubmatch(c.message); len(m) == 4 { username := m[1] diff --git a/pkg/web/handlers/api/v1/topBarHandler.go b/pkg/web/handlers/api/v1/topBarHandler.go @@ -4,6 +4,7 @@ import ( "dkforest/pkg/clockwork" "dkforest/pkg/config" "dkforest/pkg/database" + dutils "dkforest/pkg/database/utils" "dkforest/pkg/hashset" "dkforest/pkg/managers" "dkforest/pkg/utils" @@ -473,10 +474,7 @@ func (c *Command) receivePM() { // Lazy loading and cache of the zero user func (c *Command) getZeroUser() database.User { if c.zeroUser == nil { - zeroUser, err := database.GetUserByUsername(config.NullUsername) - if err != nil { - logrus.Fatal(err) - } + zeroUser := dutils.GetZeroUser() c.zeroUser = &zeroUser } return *c.zeroUser @@ -496,13 +494,13 @@ func (c *Command) zeroProcMsg(rawMsg string) { func (c *Command) zeroProcMsgRoom(rawMsg, roomKey string, roomID int64) { zeroUser := c.getZeroUser() procMsg, _ := ProcessRawMessage(rawMsg, roomKey, c.authUser.ID, roomID, nil) - c.rawMsgRoom(zeroUser, c.authUser, rawMsg, procMsg, roomKey, roomID) + rawMsgRoom(zeroUser, c.authUser, rawMsg, procMsg, roomKey, roomID) } func (c *Command) zeroPublicProcMsgRoom(rawMsg, roomKey string, roomID int64) { zeroUser := c.getZeroUser() procMsg, _ := ProcessRawMessage(rawMsg, roomKey, c.authUser.ID, roomID, nil) - c.rawMsgRoom(zeroUser, nil, rawMsg, procMsg, roomKey, roomID) + rawMsgRoom(zeroUser, nil, rawMsg, procMsg, roomKey, roomID) } func (c *Command) zeroPublicMsg(raw, msg string) { @@ -511,10 +509,10 @@ func (c *Command) zeroPublicMsg(raw, msg string) { } func (c *Command) rawMsg(user1 database.User, user2 *database.User, raw, msg string) { - c.rawMsgRoom(user1, user2, raw, msg, c.roomKey, c.room.ID) + rawMsgRoom(user1, user2, raw, msg, c.roomKey, c.room.ID) } -func (c *Command) rawMsgRoom(user1 database.User, user2 *database.User, raw, msg, roomKey string, roomID int64) { +func rawMsgRoom(user1 database.User, user2 *database.User, raw, msg, roomKey string, roomID int64) { var toUserID *int64 if user2 != nil { toUserID = &user2.ID diff --git a/pkg/web/handlers/data.go b/pkg/web/handlers/data.go @@ -819,5 +819,7 @@ type stego1RoadChallengeData struct { } type chessData struct { - Games []v1.ChessGame + Games []v1.ChessGame + Error string + Username string } diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go @@ -4157,8 +4157,24 @@ func Stego1ChallengeHandler(c echo.Context) error { } func ChessHandler(c echo.Context) error { + authUser := c.Get("authUser").(*database.User) var data chessData data.Games = v1.ChessInstance.GetGames() + + if c.Request().Method == http.MethodPost { + data.Username = c.Request().PostFormValue("username") + player2, err := database.GetUserByUsername(data.Username) + if err != nil { + data.Error = "invalid username" + return c.Render(http.StatusOK, "chess", data) + } + if _, err := v1.ChessInstance.NewGame1(*authUser, player2); err != nil { + data.Error = err.Error() + return c.Render(http.StatusOK, "chess", data) + } + return c.Redirect(http.StatusFound, c.Request().Referer()) + } + return c.Render(http.StatusOK, "chess", data) } diff --git a/pkg/web/public/views/pages/chess.gohtml b/pkg/web/public/views/pages/chess.gohtml @@ -4,6 +4,18 @@ <div class="container"> <h3>Games</h3> <p>You can create a chess game with someone by using the <code>/chess username</code> command.</p> + <form method="post" style="width: 400px;"> + <input type="hidden" name="csrf" value="{{ .CSRF }}" /> + <div class="input-group"> + <input type="text" name="username" value="{{ .Data.Username }}" placeholder="opponent username" class="form-control form-control-sm{{ if .Data.Error }} is-invalid{{ end }}" /> + <div class="input-group-append"> + <button class="btn btn-sm btn-primary">Create chess game</button> + </div> + {{ if .Data.Error }} + <div class="invalid-feedback">{{ .Data.Error }}</div> + {{ end }} + </div> + </form> <div class="mt-4"> <table class="table table-novpadding table-sm table-hover table-striped"> <tr> diff --git a/pkg/web/web.go b/pkg/web/web.go @@ -114,6 +114,7 @@ func getMainServer() echo.HandlerFunc { authGroup.POST("/captcha", handlers.CaptchaHandler, middlewares.AuthRateLimitMiddleware(time.Second, 1)) authGroup.GET("/shop", handlers.ShopHandler) authGroup.GET("/chess", handlers.ChessHandler) + authGroup.POST("/chess", handlers.ChessHandler) authGroup.GET("/chess/:key", handlers.ChessGameHandler) authGroup.POST("/chess/:key", handlers.ChessGameHandler) authGroup.GET("/settings/chat", handlers.SettingsChatHandler)