Draft: big refactor
This commit is contained in:
3
Makefile
3
Makefile
@@ -3,6 +3,7 @@
|
||||
SWAG ?= ~/go/bin/swag
|
||||
|
||||
TARGET := $(shell find . -type f -name '*.go')
|
||||
DEST := server/docs
|
||||
|
||||
all: swagger docker install
|
||||
|
||||
@@ -17,7 +18,7 @@ game: $(TARGET)
|
||||
|
||||
swagger:
|
||||
$(SWAG) fmt
|
||||
$(SWAG) init -o backend/docs -g cmd/serve/backend.go -pdl 1
|
||||
$(SWAG) init -o $(DEST) -g cmd/serve/backend.go -pdl 1
|
||||
|
||||
clean:
|
||||
-rm -f game
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
|
||||
"github.com/uptrace/bunrouter"
|
||||
)
|
||||
|
||||
// GetLobbyRooms
|
||||
//
|
||||
// @Router /api/lobby/rooms [get]
|
||||
func (self *Handlers) GetLobbyRooms(
|
||||
w http.ResponseWriter,
|
||||
req bunrouter.Request,
|
||||
) error {
|
||||
ctx := req.Context()
|
||||
|
||||
rooms, err := self.db.GetRooms(ctx)
|
||||
if err != nil {
|
||||
return middlewares.HTTPError{
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
Message: "failed to get room",
|
||||
OriginError: err,
|
||||
}
|
||||
}
|
||||
|
||||
return bunrouter.JSON(w, rooms)
|
||||
}
|
||||
@@ -21,8 +21,8 @@ var RootCmd = &cobra.Command{
|
||||
SetDisableWarn(true)
|
||||
|
||||
queue := []*tea.Program{}
|
||||
queue = append(queue,
|
||||
tea.NewProgram(plays.NewLanding(plays.NewBase(client))))
|
||||
queue = append(queue, tea.NewProgram(
|
||||
plays.NewLanding(plays.NewBase(client))))
|
||||
|
||||
for len(queue) > 0 {
|
||||
program := queue[0]
|
||||
@@ -41,4 +41,5 @@ var RootCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(clientCmd)
|
||||
}
|
||||
|
||||
@@ -16,20 +16,20 @@ import (
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.uber.org/zap"
|
||||
|
||||
_ "gitea.konchin.com/ytshih/inp2025/game/backend/docs"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/backend/handlers/api"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/backend/handlers/auth"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/implements"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/backend/api"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/backend/auth"
|
||||
_ "gitea.konchin.com/ytshih/inp2025/game/server/docs"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/tracing"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/utils"
|
||||
)
|
||||
|
||||
// @title Intro. to Network Programming Game
|
||||
// @version 0.0.1-alpha
|
||||
// @license.name 0BSD
|
||||
// @securityDefinitions.basic BasicAuth
|
||||
// @BasePath /
|
||||
// @title Intro. to Network Programming Game
|
||||
// @version 0.0.1-alpha
|
||||
// @license.name 0BSD
|
||||
// @securityDefinitions.basic BasicAuth
|
||||
// @BasePath /
|
||||
var backendCmd = &cobra.Command{
|
||||
Use: "backend",
|
||||
Short: "Game backend",
|
||||
|
||||
@@ -3,7 +3,7 @@ services:
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
env_file: ./backend/.env
|
||||
env_file: ./server/.env
|
||||
ports:
|
||||
- 8081:8080
|
||||
restart: unless-stopped
|
||||
|
||||
1
go.mod
1
go.mod
@@ -44,6 +44,7 @@ require (
|
||||
github.com/go-resty/resty/v2 v2.16.5 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
|
||||
2
go.sum
2
go.sum
@@ -67,6 +67,8 @@ github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17k
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
|
||||
@@ -38,16 +38,6 @@ func (self *BunDatabase) GetUserStatuses(
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *BunDatabase) GetRooms(
|
||||
ctx context.Context,
|
||||
) ([]models.Room, error) {
|
||||
var ret []models.Room
|
||||
err := self.db.NewSelect().
|
||||
Model(&ret).
|
||||
Scan(ctx)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *BunDatabase) InsertUser(
|
||||
ctx context.Context,
|
||||
user models.User,
|
||||
@@ -81,16 +71,6 @@ func (self *BunDatabase) InsertUserStatus(
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *BunDatabase) InsertRoom(
|
||||
ctx context.Context,
|
||||
room models.Room,
|
||||
) error {
|
||||
_, err := self.db.NewInsert().
|
||||
Model(&room).
|
||||
Exec(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *BunDatabase) DeleteUserStatus(
|
||||
ctx context.Context,
|
||||
username string,
|
||||
@@ -101,14 +81,3 @@ func (self *BunDatabase) DeleteUserStatus(
|
||||
Exec(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *BunDatabase) DeleteRoom(
|
||||
ctx context.Context,
|
||||
roomId int,
|
||||
) error {
|
||||
_, err := self.db.NewDelete().
|
||||
Model(&models.Room{Id: roomId}).
|
||||
WherePK().
|
||||
Exec(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -16,10 +16,6 @@ type Database interface {
|
||||
ctx context.Context,
|
||||
) ([]models.UserStatus, error)
|
||||
|
||||
GetRooms(
|
||||
ctx context.Context,
|
||||
) ([]models.Room, error)
|
||||
|
||||
InsertUser(
|
||||
ctx context.Context,
|
||||
user models.User,
|
||||
@@ -30,18 +26,8 @@ type Database interface {
|
||||
userStatus models.UserStatus,
|
||||
) error
|
||||
|
||||
InsertRoom(
|
||||
ctx context.Context,
|
||||
room models.Room,
|
||||
) error
|
||||
|
||||
DeleteUserStatus(
|
||||
ctx context.Context,
|
||||
username string,
|
||||
) error
|
||||
|
||||
DeleteRoom(
|
||||
ctx context.Context,
|
||||
roomId int,
|
||||
) error
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
type RoomType int
|
||||
|
||||
const (
|
||||
RoomTypeWordle RoomType = iota
|
||||
)
|
||||
|
||||
var (
|
||||
RoomTypeStr = []string{"Wordle"}
|
||||
)
|
||||
|
||||
type RoomStatus int
|
||||
|
||||
const (
|
||||
RoomStatusWaiting RoomStatus = iota
|
||||
RoomStatusPlaying
|
||||
RoomStatusEnded
|
||||
)
|
||||
|
||||
var (
|
||||
RoomStatusStr = []string{"Waiting", "Playing", "Ended"}
|
||||
)
|
||||
|
||||
type Room struct {
|
||||
bun.BaseModel `bun:"table:room"`
|
||||
|
||||
Id int `bun:"id,pk,autoincrement"`
|
||||
Creater string `bun:"creater"`
|
||||
Type RoomType `bun:"type"`
|
||||
Status RoomStatus `bun:"status"`
|
||||
}
|
||||
|
||||
func (self Room) View() string {
|
||||
return fmt.Sprintf("%2d. %10s %10s [%s]",
|
||||
self.Id,
|
||||
self.Creater,
|
||||
RoomTypeStr[self.Type],
|
||||
RoomStatusStr[self.Status],
|
||||
)
|
||||
}
|
||||
77
plays/game.go
Normal file
77
plays/game.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package plays
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/game/types"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
type Game struct {
|
||||
*Base
|
||||
state types.WordleState
|
||||
input string
|
||||
}
|
||||
|
||||
func NewGame(base *Base) *Game {
|
||||
m := Game{
|
||||
Base: base,
|
||||
state: types.NewWordleState(),
|
||||
input: "",
|
||||
}
|
||||
|
||||
return &m
|
||||
}
|
||||
|
||||
func (m *Game) Init() tea.Cmd {
|
||||
return tea.Batch(tea.ClearScreen)
|
||||
}
|
||||
|
||||
func (m *Game) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
if _, cmd := m.Base.Update(msg); cmd != nil {
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
switch msg.Type {
|
||||
case tea.KeyBackspace:
|
||||
if len(m.input) > 0 {
|
||||
m.input = m.input[:len(m.input)-1]
|
||||
}
|
||||
case tea.KeyEnter:
|
||||
if len(m.input) == types.MaxLength {
|
||||
return m, tea.Quit
|
||||
}
|
||||
case tea.KeyRunes:
|
||||
if len(m.input) < types.MaxLength {
|
||||
m.input = m.input + string(msg.Runes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *Game) View() string {
|
||||
var b strings.Builder
|
||||
|
||||
for _, s := range m.history {
|
||||
b.WriteString(s.View())
|
||||
b.WriteRune('\n')
|
||||
}
|
||||
|
||||
b.WriteString(m.input)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func (m *Game) Next(queue *[]*tea.Program) error {
|
||||
if len(m.input) == types.MaxLength {
|
||||
resp, err := m.Base.client.R().
|
||||
Post("/api/guess")
|
||||
|
||||
*queue = append(*queue,
|
||||
tea.NewProgram(NewGame(m.Base)))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -25,7 +25,7 @@ type Lobby struct {
|
||||
|
||||
updateCh chan struct{}
|
||||
users []models.UserStatus
|
||||
rooms []models.Room
|
||||
rooms []types.Room
|
||||
}
|
||||
|
||||
func NewLobby(base *Base) *Lobby {
|
||||
@@ -58,7 +58,8 @@ func updateLobbyInfo(m *Lobby) error {
|
||||
}
|
||||
m.users = users
|
||||
|
||||
var rooms []models.Room
|
||||
var rooms []types.Room
|
||||
// TODO: scan rooms
|
||||
_, err = m.Base.client.R().
|
||||
SetResult(&rooms).
|
||||
ForceContentType("application/json").
|
||||
|
||||
@@ -3,7 +3,7 @@ package api
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
|
||||
"github.com/uptrace/bunrouter"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"database/sql"
|
||||
"net/http"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
|
||||
"github.com/uptrace/bunrouter"
|
||||
)
|
||||
|
||||
@@ -3,8 +3,8 @@ package auth
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/models"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/types"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/utils"
|
||||
"github.com/uptrace/bunrouter"
|
||||
@@ -3,8 +3,8 @@ package auth
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/models"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/types"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/utils"
|
||||
"github.com/uptrace/bunrouter"
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/game/backend/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/models"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/types"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/utils"
|
||||
"github.com/uptrace/bunrouter"
|
||||
@@ -18,11 +18,6 @@ const docTemplate = `{
|
||||
"host": "{{.Host}}",
|
||||
"basePath": "{{.BasePath}}",
|
||||
"paths": {
|
||||
"/api/lobby/rooms": {
|
||||
"get": {
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/api/lobby/users": {
|
||||
"get": {
|
||||
"responses": {}
|
||||
@@ -10,11 +10,6 @@
|
||||
},
|
||||
"basePath": "/",
|
||||
"paths": {
|
||||
"/api/lobby/rooms": {
|
||||
"get": {
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/api/lobby/users": {
|
||||
"get": {
|
||||
"responses": {}
|
||||
@@ -14,9 +14,6 @@ info:
|
||||
title: Intro. to Network Programming Game
|
||||
version: 0.0.1-alpha
|
||||
paths:
|
||||
/api/lobby/rooms:
|
||||
get:
|
||||
responses: {}
|
||||
/api/lobby/users:
|
||||
get:
|
||||
responses: {}
|
||||
29
server/wordle/handlers.go
Normal file
29
server/wordle/handlers.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package wordle
|
||||
|
||||
import "gitea.konchin.com/ytshih/inp2025/game/types"
|
||||
|
||||
type Operation struct {
|
||||
}
|
||||
|
||||
type Handlers struct {
|
||||
state WordleState
|
||||
opCh chan Operation
|
||||
subs []chan types.WordleState
|
||||
}
|
||||
|
||||
func NewHandlers() *Handlers {
|
||||
ret := &Handlers{subs: nil}
|
||||
go ret.GameFlow()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *Handlers) GameFlow() {
|
||||
for {
|
||||
select {
|
||||
case op := <-self.opCh:
|
||||
if opCh.Type {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
server/wordle/wsGetState.go
Normal file
66
server/wordle/wsGetState.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package wordle
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/types"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/utils"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/uptrace/bunrouter"
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
func gameFlow(
|
||||
dataCh chan types.WordleState,
|
||||
retCh chan error,
|
||||
) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
func (self *handlers) WSGetState(
|
||||
w http.ResponseWriter,
|
||||
req bunrouter.Request,
|
||||
) error {
|
||||
ctx := req.Context()
|
||||
|
||||
c, err := upgrader.Upgrade(w, req, nil)
|
||||
if err != nil {
|
||||
return middlewares.HTTPError{
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
Message: "failed to upgrade websocket",
|
||||
OriginError: err,
|
||||
}
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
dataCh := make(chan types.WordleState)
|
||||
retCh := make(chan error)
|
||||
|
||||
go gameFlow(dataCh, retCh)
|
||||
for {
|
||||
select {
|
||||
case err := <-retCh:
|
||||
if err != nil {
|
||||
return middlewares.HTTPError{
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
Message: "wordle server error",
|
||||
OriginError: err,
|
||||
}
|
||||
}
|
||||
break
|
||||
case data := <-dataCh:
|
||||
b, err := msgpack.Marshal(data)
|
||||
if err != nil {
|
||||
return middlewares.HTTPError{
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
Message: "failed to marshal data into msgpack",
|
||||
OriginError: err,
|
||||
}
|
||||
}
|
||||
c.WriteMessage(websocket.BinaryMessage, b)
|
||||
}
|
||||
}
|
||||
|
||||
return utils.Success(w)
|
||||
}
|
||||
27
types/game.go
Normal file
27
types/game.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package types
|
||||
|
||||
import "fmt"
|
||||
|
||||
type RoomStatus int
|
||||
|
||||
const (
|
||||
RoomStatusWaiting RoomStatus = iota
|
||||
RoomStatusPlaying
|
||||
RoomStatusEnded
|
||||
)
|
||||
|
||||
var (
|
||||
RoomStatusStr = []string{"Waiting", "Playing", "Ended"}
|
||||
)
|
||||
|
||||
type Room struct {
|
||||
Creater string
|
||||
Status RoomStatus
|
||||
}
|
||||
|
||||
func (self Room) View() string {
|
||||
return fmt.Sprintf("%10s [%s]",
|
||||
self.Creater,
|
||||
RoomStatusStr[self.Status],
|
||||
)
|
||||
}
|
||||
81
types/wordle.go
Normal file
81
types/wordle.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
type CharStatus int
|
||||
|
||||
const (
|
||||
CharStatusA CharStatus = iota
|
||||
CharStatusB
|
||||
CharStatusC
|
||||
)
|
||||
|
||||
type Char struct {
|
||||
Char rune `msgpack:"char"`
|
||||
Status CharStatus `msgpack:"status"`
|
||||
}
|
||||
|
||||
func NewChar() Char {
|
||||
return Char{
|
||||
Char: 0x0,
|
||||
Status: CharStatusC,
|
||||
}
|
||||
}
|
||||
|
||||
func (self Char) View() string {
|
||||
style := lipgloss.NewStyle()
|
||||
|
||||
switch self.Status {
|
||||
case CharStatusA:
|
||||
style = style.Background(lipgloss.Color("#00ff00"))
|
||||
case CharStatusB:
|
||||
style = style.Background(lipgloss.Color("#ffff00"))
|
||||
case CharStatusC:
|
||||
style = style.Background(lipgloss.Color("#808080"))
|
||||
}
|
||||
|
||||
return style.Render(string(self.Char))
|
||||
}
|
||||
|
||||
type Word struct {
|
||||
Chars []Char `msgpack:"chars"`
|
||||
}
|
||||
|
||||
func NewWord() Word {
|
||||
return Word{
|
||||
Chars: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (self Word) View() string {
|
||||
var b strings.Builder
|
||||
|
||||
for _, char := range self.Chars {
|
||||
b.WriteString(char.View())
|
||||
b.WriteRune('\n')
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
const (
|
||||
MaxLength = 5
|
||||
)
|
||||
|
||||
type UserState struct {
|
||||
History []Word `msgpack:"history"`
|
||||
}
|
||||
|
||||
type WordleState struct {
|
||||
Users []UserState `msgpack:"users"`
|
||||
}
|
||||
|
||||
func NewWordleState() WordleState {
|
||||
return WordleState{
|
||||
Users: nil,
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,5 @@ func InitDB(ctx context.Context, db *bun.DB) error {
|
||||
return db.ResetModel(ctx,
|
||||
(*models.User)(nil),
|
||||
(*models.UserStatus)(nil),
|
||||
(*models.Room)(nil),
|
||||
)
|
||||
}
|
||||
|
||||
32
workflows/wordleServer.go
Normal file
32
workflows/wordleServer.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package workflows
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"gitea.konchin.com/ytshih/inp2025/game/implements"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/middlewares"
|
||||
"gitea.konchin.com/ytshih/inp2025/game/server/wordle"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/uptrace/bunrouter"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
func WordleServer(ctx context.Context) {
|
||||
handlers := wordle.NewHandlers()
|
||||
middlewareHandlers := middlewares.NewHandlers(
|
||||
implements.NewBunDatabase(nil))
|
||||
|
||||
router := bunrouter.New()
|
||||
|
||||
apiGroup := router.NewGroup("/api").
|
||||
Use(middlewareHandlers.ErrorHandler)
|
||||
apiGroup.GET("/state",
|
||||
handlers.WSGetState)
|
||||
apiGroup.POST("/guess",
|
||||
handlers.WSPostGuess)
|
||||
|
||||
log.Println(http.ListenAndServe(":"+viper.GetString("port"),
|
||||
otelhttp.NewHandler(router, "")))
|
||||
}
|
||||
Reference in New Issue
Block a user