diff options
Diffstat (limited to 'internal/casino/manager.go')
| -rw-r--r-- | internal/casino/manager.go | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/internal/casino/manager.go b/internal/casino/manager.go index b1281b2..b71e5df 100644 --- a/internal/casino/manager.go +++ b/internal/casino/manager.go @@ -7,6 +7,7 @@ import ( "math/rand" "reflect" "sort" + "strconv" "strings" "sync" ) @@ -361,26 +362,32 @@ func (m *Manager) RekeyRooms(idMap map[int]int) { } m.mu.Lock() defer m.mu.Unlock() - rekey := func(key string) (string, bool) { - var roomID int - var tableID string - if _, err := fmt.Sscanf(key, "%d:%s", &roomID, &tableID); err != nil { - return "", false + // rekey parses a room:table key and returns the remapped key and room ID. + // strings.Cut/strconv is used instead of fmt.Sscanf because a table or + // machine ID may legally contain whitespace (validation rejects only + // surrounding whitespace) and %s would stop at the first space, rebuilding + // a corrupted key and orphaning the game. + rekey := func(key string) (string, int, bool) { + roomStr, tableID, found := strings.Cut(key, ":") + if !found { + return "", 0, false + } + roomID, err := strconv.Atoi(roomStr) + if err != nil { + return "", 0, false } newID, ok := idMap[roomID] if !ok || newID == roomID { - return "", false + return "", 0, false } - return fmt.Sprintf("%d:%s", newID, tableID), true + return fmt.Sprintf("%d:%s", newID, tableID), newID, true } movedTables := make(map[string]*Table, len(m.tables)) for key, table := range m.tables { - if newKey, ok := rekey(key); ok { - var roomID int - var tableID string - fmt.Sscanf(key, "%d:%s", &roomID, &tableID) - table.RoomID = idMap[roomID] - table.game.setRoom(table.RoomID) + if newKey, newRoomID, ok := rekey(key); ok { + // The Table handle and the game share one *tableBase, so this + // single assignment updates event routing for both. + table.RoomID = newRoomID movedTables[newKey] = table delete(m.tables, key) } @@ -390,11 +397,8 @@ func (m *Manager) RekeyRooms(idMap map[int]int) { } movedMachines := make(map[string]*Machine, len(m.machines)) for key, machine := range m.machines { - if newKey, ok := rekey(key); ok { - var roomID int - var tableID string - fmt.Sscanf(key, "%d:%s", &roomID, &tableID) - machine.RoomID = idMap[roomID] + if newKey, newRoomID, ok := rekey(key); ok { + machine.RoomID = newRoomID movedMachines[newKey] = machine delete(m.machines, key) } |
