1package protocol
  2
  3import (
  4	"time"
  5
  6	"github.com/mailru/easyjson"
  7	"github.com/zikaeroh/codies/internal/game"
  8)
  9
 10// See protocol/index.ts.
 11
 12//go:generate go run github.com/mailru/easyjson/easyjson -disallow_unknown_fields protocol.go
 13
 14type ExistsQuery struct {
 15	RoomID string `queryparam:"roomID"`
 16}
 17
 18//easyjson:json
 19type RoomRequest struct {
 20	RoomName string `json:"roomName"`
 21	RoomPass string `json:"roomPass"`
 22	Create   bool   `json:"create"`
 23}
 24
 25func (r *RoomRequest) Valid() (msg string, valid bool) {
 26	if len(r.RoomName) == 0 {
 27		return "Room name cannot be empty.", false
 28	}
 29
 30	if len(r.RoomName) > 20 {
 31		return "Room name too long.", false
 32	}
 33
 34	if len(r.RoomPass) == 0 {
 35		return "Room pass cannot be empty.", false
 36	}
 37
 38	return "", true
 39}
 40
 41//easyjson:json
 42type RoomResponse struct {
 43	ID    *string `json:"id,omitempty"`
 44	Error *string `json:"error,omitempty"`
 45}
 46
 47//easyjson:json
 48type TimeResponse struct {
 49	Time time.Time `json:"time"`
 50}
 51
 52//easyjson:json
 53type StatsResponse struct {
 54	Rooms   int `json:"rooms"`
 55	Clients int `json:"clients"`
 56}
 57
 58type WSQuery struct {
 59	RoomID   string `queryparam:"roomID"`
 60	Nickname string `queryparam:"nickname"`
 61}
 62
 63func (w *WSQuery) Valid() (msg string, valid bool) {
 64	if w.RoomID == "" {
 65		return "Room ID cannot be empty.", false
 66	}
 67
 68	if len(w.Nickname) == 0 {
 69		return "Nickname cannot be empty.", false
 70	}
 71
 72	if len(w.Nickname) > 16 {
 73		return "Nickname too long.", false
 74	}
 75
 76	return "", true
 77}
 78
 79//easyjson:json
 80type ClientNote struct {
 81	Method  ClientMethod        `json:"method,intern"` //nolint:staticcheck
 82	Version int                 `json:"version"`
 83	Params  easyjson.RawMessage `json:"params"`
 84}
 85
 86type ClientMethod string
 87
 88const NewGameMethod = ClientMethod("newGame")
 89
 90//easyjson:json
 91type NewGameParams struct{}
 92
 93const EndTurnMethod = ClientMethod("endTurn")
 94
 95//easyjson:json
 96type EndTurnParams struct{}
 97
 98const RandomizeTeamsMethod = ClientMethod("randomizeTeams")
 99
100//easyjson:json
101type RandomizeTeamsParams struct{}
102
103const RevealMethod = ClientMethod("reveal")
104
105//easyjson:json
106type RevealParams struct {
107	Row int `json:"row"`
108	Col int `json:"col"`
109}
110
111const ChangeTeamMethod = ClientMethod("changeTeam")
112
113//easyjson:json
114type ChangeTeamParams struct {
115	Team game.Team `json:"team"`
116}
117
118const ChangeNicknameMethod = ClientMethod("changeNickname")
119
120//easyjson:json
121type ChangeNicknameParams struct {
122	Nickname string `json:"nickname"`
123}
124
125const ChangeRoleMethod = ClientMethod("changeRole")
126
127//easyjson:json
128type ChangeRoleParams struct {
129	Spymaster bool `json:"spymaster"`
130}
131
132const ChangePackMethod = ClientMethod("changePack")
133
134//easyjson:json
135type ChangePackParams struct {
136	Num    int  `json:"num"`
137	Enable bool `json:"enable"`
138}
139
140const ChangeTurnModeMethod = ClientMethod("changeTurnMode")
141
142//easyjson:json
143type ChangeTurnModeParams struct {
144	Timed bool `json:"timed"`
145}
146
147const ChangeTurnTimeMethod = ClientMethod("changeTurnTime")
148
149//easyjson:json
150type ChangeTurnTimeParams struct {
151	Seconds int `json:"seconds"`
152}
153
154const AddPacksMethod = ClientMethod("addPacks")
155
156//easyjson:json
157type AddPacksParams struct {
158	Packs []struct {
159		Name  string   `json:"name"`
160		Words []string `json:"words"`
161	} `json:"packs"`
162}
163
164const RemovePackMethod = ClientMethod("removePack")
165
166//easyjson:json
167type RemovePackParams struct {
168	Num int `json:"num"`
169}
170
171type ServerMethod string
172
173//easyjson:json
174type ServerNote struct {
175	Method ServerMethod `json:"method"`
176	Params interface{}  `json:"params"`
177}
178
179const ChangeHideBombMethod = ClientMethod("changeHideBomb")
180
181//easyjson:json
182type ChangeHideBombParams struct {
183	HideBomb bool `json:"hideBomb"`
184}
185
186func NewStateNote(playerID game.PlayerID, s *RoomState) ServerNote {
187	return ServerNote{
188		Method: "state",
189		Params: &State{
190			PlayerID:  playerID,
191			RoomState: s,
192		},
193	}
194}
195
196//easyjson:json
197type State struct {
198	PlayerID  game.PlayerID `json:"playerID"`
199	RoomState *RoomState    `json:"roomState"`
200}
201
202//easyjson:json
203type RoomState struct {
204	Version   int              `json:"version"`
205	Teams     [][]*StatePlayer `json:"teams"`
206	Turn      game.Team        `json:"turn"`
207	Winner    *game.Team       `json:"winner"`
208	Board     [][]*StateTile   `json:"board"`
209	WordsLeft []int            `json:"wordsLeft"`
210	Lists     []*StateWordList `json:"lists"`
211	Timer     *StateTimer      `json:"timer"`
212	HideBomb  bool             `json:"hideBomb"`
213}
214
215//easyjson:json
216type StatePlayer struct {
217	PlayerID  game.PlayerID `json:"playerID"`
218	Nickname  string        `json:"nickname"`
219	Spymaster bool          `json:"spymaster"`
220}
221
222//easyjson:json
223type StateTile struct {
224	Word     string     `json:"word"`
225	Revealed bool       `json:"revealed"`
226	View     *StateView `json:"view"`
227}
228
229//easyjson:json
230type StateView struct {
231	Team    game.Team `json:"team"`
232	Neutral bool      `json:"neutral"`
233	Bomb    bool      `json:"bomb"`
234}
235
236//easyjson:json
237type StateWordList struct {
238	Name    string `json:"name"`
239	Count   int    `json:"count"`
240	Custom  bool   `json:"custom"`
241	Enabled bool   `json:"enabled"`
242}
243
244//easyjson:json
245type StateTimer struct {
246	TurnTime int       `json:"turnTime"`
247	TurnEnd  time.Time `json:"turnEnd"`
248}