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:
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)