Skip to content

Commit 2519d58

Browse files
committed
gateway: fix concurrent write and elimination room fixes
1 parent 50c270c commit 2519d58

File tree

2 files changed

+79
-24
lines changed

2 files changed

+79
-24
lines changed

http/gateway/handler.go

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type WebSocketConnection struct {
2020
ID string
2121
}
2222

23-
var connections = make(map[string]WebSocketConnection, 0)
23+
var connections = make(map[string]*WebSocketConnection, 0)
2424

2525
func Handle(c *websocket.Conn) {
2626
id, err := session.Generate(8)
@@ -34,7 +34,7 @@ func Handle(c *websocket.Conn) {
3434
Conn: c,
3535
ID: sid,
3636
}
37-
connections[sid] = ws
37+
connections[sid] = &ws
3838

3939
for {
4040
var msg AnyMessage
@@ -72,14 +72,14 @@ func handleHello(c *WebSocketConnection, d *AnyMessage) {
7272
}
7373

7474
if len(r.Players) >= room.PlayerLimit {
75-
c.Kick(r, RoomFullKick, "Too many players online")
75+
c.Kick(RoomFullKick, "Too many players online")
7676
return
7777
}
7878

7979
if r.Mode == room.EliminationMode &&
8080
r.State != room.CountdownState &&
8181
r.State != room.WaitingState {
82-
c.Kick(r, RoomIngameKick, "Room is already in-game")
82+
c.Kick(RoomIngameKick, "Room is already in-game")
8383
return
8484
}
8585

@@ -112,22 +112,43 @@ func handleHello(c *WebSocketConnection, d *AnyMessage) {
112112

113113
r.Players = append(r.Players, &p)
114114

115-
fmt.Println(r)
115+
resData := map[string]interface{}{
116+
"user": p,
117+
"users": r.Players,
118+
"objects": r.Map.Objects,
119+
"interval": PingInterval,
120+
"items": r.Items,
121+
"roomCreatedAt": r.CreatedAt,
122+
}
123+
124+
fmt.Println(r.Mode, len(r.Players), room.MinPlayerStartup, r.State, room.WaitingState)
125+
126+
if r.Mode == room.EliminationMode {
127+
if len(r.Players) >= room.MinPlayerStartup && r.State == room.WaitingState {
128+
r.State = room.CountdownState
129+
r.CountdownStarted = time.Now().UnixNano() / int64(time.Millisecond)
130+
BroadcastMessage(r, AnyMessage{
131+
Op: OpEvent,
132+
T: StateChangeEvent,
133+
Data: map[string]interface{}{
134+
"state": r.State,
135+
"countdownStarted": r.CountdownStarted,
136+
},
137+
})
138+
}
139+
140+
resData["state"] = r.State
141+
resData["waitingTime"] = room.WaitingTime
142+
resData["countdownStarted"] = r.CountdownStarted
143+
}
144+
145+
fmt.Println(resData)
146+
116147
c.Send(AnyMessage{
117-
Op: OpEvent,
118-
T: HeartbeatEvent,
119-
Data: map[string]interface{}{
120-
"user": p,
121-
"users": r.Players,
122-
"objects": r.Map.Objects,
123-
"interval": PingInterval,
124-
"items": r.Items,
125-
"roomCreatedAt": r.CreatedAt,
126-
"state": r.State,
127-
"countdownStarted": r.CountdownStarted,
128-
},
148+
Op: OpEvent,
149+
T: HeartbeatEvent,
150+
Data: resData,
129151
})
130-
// TODO: check if room is elimination room and if it meets requirements for room start
131152
}
132153

133154
func handleHeartbeat(c *WebSocketConnection, d *AnyMessage) {
@@ -167,6 +188,12 @@ func handleEvent(c *WebSocketConnection, d *AnyMessage) {
167188
func handleClose(c *WebSocketConnection) {
168189
c.Conn.Close()
169190
delete(connections, c.ID)
191+
192+
// TODO: optimize this
193+
r := room.FindLobbyByWebsocketID(c.ID)
194+
if r != nil {
195+
r.RemovePlayer(r.GetPlayerIndexByWebSocketID(c.ID))
196+
}
170197
}
171198

172199
func (c *WebSocketConnection) Send(d AnyMessage) error {
@@ -175,7 +202,7 @@ func (c *WebSocketConnection) Send(d AnyMessage) error {
175202
return c.Conn.WriteJSON(d)
176203
}
177204

178-
func (c *WebSocketConnection) Kick(r *room.Room, kickType uint8, reason string) error {
205+
func (c *WebSocketConnection) Kick(kickType uint8, reason string) error {
179206
fmt.Println(AnyMessage{
180207
Op: OpClose,
181208
T: PlayerKickEvent,
@@ -196,21 +223,30 @@ func (c *WebSocketConnection) Kick(r *room.Room, kickType uint8, reason string)
196223
return err
197224
}
198225

199-
r.RemovePlayer(r.GetPlayerIndexByWebSocketID(c.ID))
200-
201226
handleClose(c)
202227
return nil
203228
}
204229

205230
// HandleAntiCheatFlags checks whether the user has reached the flag limit and kicks them
206231
func (c *WebSocketConnection) HandleAntiCheatFlags(r *room.Room, flags int) bool {
207232
if flags > utils.FlagLimit {
208-
c.Kick(r, FlagLimitKick, "Too many flags")
233+
c.Kick(FlagLimitKick, "Too many flags")
209234
return true
210235
}
211236
return false
212237
}
213238

239+
func BroadcastMessage(r *room.Room, d AnyMessage) {
240+
for _, p := range r.Players {
241+
conn, ok := connections[p.ID]
242+
if !ok {
243+
continue
244+
}
245+
246+
conn.Send(d)
247+
}
248+
}
249+
214250
func WatchRoom(r *room.Room) {
215251
for {
216252
for _, p := range r.Players {
@@ -219,6 +255,8 @@ func WatchRoom(r *room.Room) {
219255
continue
220256
}
221257

258+
// TODO: check p.LastPing
259+
222260
conn.Send(AnyMessage{
223261
Op: OpEvent,
224262
T: CoordinateChangeEvent,
@@ -228,6 +266,23 @@ func WatchRoom(r *room.Room) {
228266
})
229267
}
230268

269+
if r.Mode == room.EliminationMode &&
270+
r.State == room.CountdownState &&
271+
(time.Now().UnixNano()/int64(time.Millisecond)) >= r.StartsAt() {
272+
StartEliminationRoom(r)
273+
}
274+
231275
time.Sleep(time.Millisecond * 25)
232276
}
233277
}
278+
279+
func StartEliminationRoom(r *room.Room) {
280+
r.State = room.IngameState
281+
BroadcastMessage(r, AnyMessage{
282+
Op: OpEvent,
283+
T: StateChangeEvent,
284+
Data: map[string]interface{}{
285+
"state": r.State,
286+
},
287+
})
288+
}

http/gateway/player_kick.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func PlayerKickEventCallback(c *WebSocketConnection, d *AnyMessage) {
3838
}
3939

4040
if p.Role != user.AdminRole {
41-
c.Kick(r, ClientModKick, "Insufficient permissions")
41+
c.Kick(ClientModKick, "Insufficient permissions")
4242
return
4343
}
4444

@@ -51,5 +51,5 @@ func PlayerKickEventCallback(c *WebSocketConnection, d *AnyMessage) {
5151
if !ok {
5252
return
5353
}
54-
conn.Kick(r, ModKick, reason)
54+
conn.Kick(ModKick, reason)
5555
}

0 commit comments

Comments
 (0)