@@ -53,11 +53,13 @@ func (g *Game) Start() {
5353 Username : g .Player1 .Username ,
5454 Symbol : 1 ,
5555 Type : getPlayerType (g .Player1 ),
56+ IsOnline : true ,
5657 },
5758 Opponent : PlayerInfo {
5859 Username : g .Player2 .Username ,
5960 Symbol : 2 ,
6061 Type : getPlayerType (g .Player2 ),
62+ IsOnline : true ,
6163 },
6264 YourTurn : true ,
6365 },
@@ -74,11 +76,13 @@ func (g *Game) Start() {
7476 Username : g .Player2 .Username ,
7577 Symbol : 2 ,
7678 Type : getPlayerType (g .Player2 ),
79+ IsOnline : true ,
7780 },
7881 Opponent : PlayerInfo {
7982 Username : g .Player1 .Username ,
8083 Symbol : 1 ,
8184 Type : getPlayerType (g .Player1 ),
85+ IsOnline : true ,
8286 },
8387 YourTurn : false ,
8488 },
@@ -264,8 +268,55 @@ func (g *Game) HandleDisconnect(player *Player) {
264268 player .IsConnected = false
265269 player .DisconnectedAt = time .Now ()
266270
271+ // Notify opponent about disconnect
272+ opponent := GetOpponent (g , player )
273+ opponent .SendMessage (Message {
274+ Type : MsgPlayerStatus ,
275+ Payload : PlayerStatusPayload {
276+ PlayerSymbol : player .Symbol ,
277+ IsOnline : false ,
278+ TimeLeft : 30 ,
279+ },
280+ })
281+
282+ // Start countdown timer with updates
267283 go func () {
268- time .Sleep (30 * time .Second )
284+ ticker := time .NewTicker (1 * time .Second )
285+ defer ticker .Stop ()
286+
287+ startTime := time .Now ()
288+ for i := 29 ; i >= 0 ; i -- {
289+ <- ticker .C
290+
291+ g .Mutex .Lock ()
292+ if g .State != "active" || player .IsConnected {
293+ g .Mutex .Unlock ()
294+ return
295+ }
296+
297+ elapsed := int (time .Since (startTime ).Seconds ())
298+ timeLeft := 30 - elapsed
299+ if timeLeft < 0 {
300+ timeLeft = 0
301+ }
302+
303+ opponent := GetOpponent (g , player )
304+ opponent .SendMessage (Message {
305+ Type : MsgPlayerStatus ,
306+ Payload : PlayerStatusPayload {
307+ PlayerSymbol : player .Symbol ,
308+ IsOnline : false ,
309+ TimeLeft : timeLeft ,
310+ },
311+ })
312+ g .Mutex .Unlock ()
313+
314+ if timeLeft == 0 {
315+ break
316+ }
317+ }
318+
319+ // Final check after 30 seconds
269320 g .Mutex .Lock ()
270321 defer g .Mutex .Unlock ()
271322
@@ -311,6 +362,16 @@ func (g *Game) HandleReconnect(playerID string, conn *websocket.Conn) (*Player,
311362
312363 opponent := GetOpponent (g , p )
313364
365+ // Notify opponent about reconnect
366+ opponent .SendMessage (Message {
367+ Type : MsgPlayerStatus ,
368+ Payload : PlayerStatusPayload {
369+ PlayerSymbol : p .Symbol ,
370+ IsOnline : true ,
371+ TimeLeft : 0 ,
372+ },
373+ })
374+
314375 reconnectMsg := Message {
315376 Type : MsgReconnect ,
316377 Payload : ReconnectPayload {
@@ -320,11 +381,13 @@ func (g *Game) HandleReconnect(playerID string, conn *websocket.Conn) (*Player,
320381 Username : p .Username ,
321382 Symbol : p .Symbol ,
322383 Type : getPlayerType (p ),
384+ IsOnline : true ,
323385 },
324386 Opponent : PlayerInfo {
325387 Username : opponent .Username ,
326388 Symbol : opponent .Symbol ,
327389 Type : getPlayerType (opponent ),
390+ IsOnline : opponent .IsConnected ,
328391 },
329392 Grid : g .Board .Grid ,
330393 CurrentTurn : g .Turn ,
0 commit comments