@@ -117,7 +117,7 @@ func (g *GameServer) tcpSendCustom(conn *net.TCPConn, customID byte) {
117117
118118func (g * GameServer ) tcpSendReg (conn * net.TCPConn ) {
119119 startTime := time .Now ()
120- for len ( g . Players ) != len ( g . registrations ) {
120+ for g . GetPlayersLength ( ) != g . GetRegistrationsLength ( ) {
121121 time .Sleep (time .Millisecond )
122122 if time .Since (startTime ) > TCPTimeout {
123123 g .Logger .Info ("TCP connection timed out in tcpSendReg" )
@@ -128,13 +128,13 @@ func (g *GameServer) tcpSendReg(conn *net.TCPConn) {
128128 registrations := make ([]byte , 24 )
129129 current := 0
130130 for i = range 4 {
131- _ , ok := g .registrations [ i ]
131+ v , ok := g .registrations . Load ( i )
132132 if ok {
133- binary .BigEndian .PutUint32 (registrations [current :], g . registrations [ i ] .regID )
133+ binary .BigEndian .PutUint32 (registrations [current :], v .( * Registration ) .regID )
134134 current += 4
135- registrations [current ] = g . registrations [ i ] .plugin
135+ registrations [current ] = v .( * Registration ) .plugin
136136 current ++
137- registrations [current ] = g . registrations [ i ] .raw
137+ registrations [current ] = v .( * Registration ) .raw
138138 current ++
139139 } else {
140140 current += 6
@@ -282,36 +282,35 @@ func (g *GameServer) processTCP(conn *net.TCPConn) {
282282 regID := binary .BigEndian .Uint32 (regIDBytes )
283283
284284 response := make ([]byte , 2 )
285- _ , ok := g .registrations [ playerNumber ]
285+ v , ok := g .registrations . Load ( playerNumber )
286286 if ! ok {
287287 if playerNumber > 0 && plugin == 2 { // Only P1 can use mempak
288288 plugin = 1
289289 }
290290
291- g .registrationsMutex .Lock () // any player can modify this, which would be in a different thread
292- g .registrations [playerNumber ] = & Registration {
291+ g .registrations .Store (playerNumber , & Registration {
293292 regID : regID ,
294293 plugin : plugin ,
295294 raw : raw ,
296- }
297- g .registrationsMutex .Unlock ()
295+ })
298296
299297 response [0 ] = 1
300- g .Logger .Info ("registered player" , "registration " , g . registrations [ playerNumber ] , "number" , playerNumber , "bufferLeft" , tcpData .buffer .Len (), "address" , conn .RemoteAddr ().String ())
298+ g .Logger .Info ("registered player" , "regID " , regID , "number" , playerNumber , "bufferLeft" , tcpData .buffer .Len (), "address" , conn .RemoteAddr ().String ())
301299
302- g .gameDataMutex .Lock () // any player can modify this, which would be in a different thread
300+ g .gameDataMutex .Lock ()
303301 g .gameData .pendingInput [playerNumber ] = InputData {0 , plugin }
304302 g .gameData .playerAlive [playerNumber ] = true
305303 g .gameDataMutex .Unlock ()
306304 } else {
307- if g . registrations [ playerNumber ] .regID == regID {
308- g .Logger .Error (fmt .Errorf ("re-registration" ), "player already registered" , "registration" , g . registrations [ playerNumber ] , "number" , playerNumber , "bufferLeft" , tcpData .buffer .Len (), "address" , conn .RemoteAddr ().String ())
305+ if v .( * Registration ) .regID == regID {
306+ g .Logger .Error (fmt .Errorf ("re-registration" ), "player already registered" , "registration" , v .( * Registration ) , "number" , playerNumber , "bufferLeft" , tcpData .buffer .Len (), "address" , conn .RemoteAddr ().String ())
309307 response [0 ] = 1
310308 } else {
311- g .Logger .Error (fmt .Errorf ("registration failure" ), "could not register player" , "registration" , g . registrations [ playerNumber ] , "number" , playerNumber , "bufferLeft" , tcpData .buffer .Len (), "address" , conn .RemoteAddr ().String ())
309+ g .Logger .Error (fmt .Errorf ("registration failure" ), "could not register player" , "registration" , v .( * Registration ) , "number" , playerNumber , "bufferLeft" , tcpData .buffer .Len (), "address" , conn .RemoteAddr ().String ())
312310 response [0 ] = 0
313311 }
314312 }
313+
315314 response [1 ] = uint8 (g .BufferTarget )
316315 _ , err = conn .Write (response )
317316 if err != nil {
@@ -334,30 +333,27 @@ func (g *GameServer) processTCP(conn *net.TCPConn) {
334333 regID := binary .BigEndian .Uint32 (regIDBytes )
335334 var i byte
336335 for i = range 4 {
337- v , ok := g .registrations [i ]
338- if ok {
339- if v .regID == regID {
340- g .Logger .Info ("player disconnected TCP" , "regID" , regID , "player" , i , "address" , conn .RemoteAddr ().String ())
341-
342- // Same lock order as ManagePlayers / RegisterPlayer: registrationsMutex, then gameDataMutex.
343- g .registrationsMutex .Lock ()
344- g .gameDataMutex .Lock ()
345- g .gameData .playerAlive [i ] = false
346- g .gameData .status |= (0x1 << (i + 1 ))
347- delete (g .registrations , i )
348-
349- for k , v := range g .Players {
350- if v .Number == int (i ) {
351- g .PlayersMutex .Lock ()
352- delete (g .Players , k )
353- g .NeedsUpdatePlayers = true
354- g .PlayersMutex .Unlock ()
355- }
336+ v , ok := g .registrations .Load (i )
337+ if ok && v .(* Registration ).regID == regID {
338+ g .Logger .Info ("player disconnected TCP" , "regID" , regID , "player" , i , "address" , conn .RemoteAddr ().String ())
339+
340+ g .gameDataMutex .Lock ()
341+ g .gameData .playerAlive [i ] = false
342+ g .gameData .status |= (0x1 << (i + 1 ))
343+ g .gameDataMutex .Unlock ()
344+ g .registrations .Delete (i )
345+
346+ g .Players .Range (func (k , v any ) bool {
347+ if v .(Client ).Number == int (i ) {
348+ g .Players .Delete (k )
349+ g .NeedsUpdatePlayers = true
356350 }
357- g .gameData .bufferHealth [i ] = g .gameData .bufferHealth [i ][:0 ]
358- g .gameDataMutex .Unlock ()
359- g .registrationsMutex .Unlock ()
360- }
351+ return true
352+ })
353+
354+ g .gameDataMutex .Lock ()
355+ g .gameData .bufferHealth [i ] = g .gameData .bufferHealth [i ][:0 ]
356+ g .gameDataMutex .Unlock ()
361357 }
362358 }
363359 tcpData .request = RequestNone
@@ -413,11 +409,12 @@ func (g *GameServer) watchTCP() {
413409 conn .Close () //nolint:errcheck
414410 continue
415411 }
416- for _ , v := range g . Players {
417- if remoteAddr .IP .Equal (v .IP ) {
412+ g . Players . Range ( func ( k , v any ) bool {
413+ if remoteAddr .IP .Equal (v .( Client ). IP ) {
418414 validated = true
419415 }
420- }
416+ return true
417+ })
421418 if ! validated {
422419 g .Logger .Error (fmt .Errorf ("invalid tcp connection" ), "bad IP" , "IP" , conn .RemoteAddr ().String ())
423420 conn .Close () //nolint:errcheck
@@ -440,7 +437,6 @@ func (g *GameServer) createTCPServer(basePort int, maxGames int) int {
440437 g .tcpFiles = make (map [string ][]byte )
441438 g .customData = make (map [byte ][]byte )
442439 g .tcpSettings = make ([]byte , SettingsSize )
443- g .registrations = map [byte ]* Registration {}
444440 go g .watchTCP ()
445441 return g .Port
446442 }
0 commit comments