@@ -249,6 +249,11 @@ type
249249 hasRole* : bool
250250 hasColor* : bool
251251
252+ SlotCredentialMatch = enum
253+ SlotCredentialNone ,
254+ SlotCredentialValid ,
255+ SlotCredentialConflict
256+
252257 GameConfig * = object
253258 motionScale* : int
254259 accel* : int
@@ -1478,6 +1483,14 @@ proc canAddPlayer*(sim: SimServer): bool =
14781483 # # Returns whether the game has room for another player.
14791484 sim.players.len < sim.config.playerSlotLimit ()
14801485
1486+ proc playerLimitError (config: GameConfig ): string =
1487+ # # Returns a user-facing message for the current player cap.
1488+ if config.closedRoster:
1489+ let limit = config.playerSlotLimit ()
1490+ return " Configured roster is full (" & $ limit &
1491+ (if limit == 1 : " player)." else : " players)." )
1492+ " can't do more than " & $ MaxPlayers & " players."
1493+
14811494proc slotConfig (config: GameConfig , slotIndex: int ): PlayerSlotConfig =
14821495 # # Returns one slot config or an empty config for missing entries.
14831496 if slotIndex >= 0 and slotIndex < config.slots.len:
@@ -1523,6 +1536,24 @@ proc validatePlayerSlot(
15231536 " Player token does not match configured slot " & $ slotIndex & " ."
15241537 )
15251538
1539+ proc slotCredentialMatch (
1540+ config: GameConfig ,
1541+ slotIndex: int ,
1542+ address,
1543+ token: string
1544+ ): SlotCredentialMatch =
1545+ # # Classifies whether a player identity/token pair matches one configured slot.
1546+ let slot = config.slotConfig (slotIndex)
1547+ let
1548+ matchedName = slot.name.len > 0 and slot.name == address
1549+ matchedToken = slot.token.len > 0 and token.len > 0 and slot.token == token
1550+ if not matchedName and not matchedToken:
1551+ return SlotCredentialNone
1552+ if config.slotAuthMatches (slotIndex, address, token):
1553+ SlotCredentialValid
1554+ else :
1555+ SlotCredentialConflict
1556+
15261557proc configuredPlayerName * (config: GameConfig , requestedSlot: int , token: string ): string =
15271558 # # Returns the configured identity for a tokenized slot request.
15281559 if token.len == 0 :
@@ -1544,11 +1575,7 @@ proc matchingConfiguredSlot(
15441575): int =
15451576 # # Returns a configured slot matched by name or token without occupancy checks.
15461577 for i in 0 ..< config.slots.len:
1547- let slot = config.slots[i]
1548- let couldMatchName = slot.name.len > 0 and slot.name == address
1549- let couldMatchToken = slot.token.len > 0 and slot.token == token
1550- if (couldMatchName or couldMatchToken) and
1551- config.slotAuthMatches (i, address, token):
1578+ if config.slotCredentialMatch (i, address, token) == SlotCredentialValid :
15521579 return i
15531580 - 1
15541581
@@ -1559,12 +1586,7 @@ proc conflictingConfiguredSlot(
15591586): int =
15601587 # # Returns a configured slot matched by only one required credential.
15611588 for i in 0 ..< config.slots.len:
1562- let slot = config.slots[i]
1563- let matchedName = slot.name.len > 0 and slot.name == address
1564- let matchedToken =
1565- slot.token.len > 0 and token.len > 0 and slot.token == token
1566- if (matchedName or matchedToken) and
1567- not config.slotAuthMatches (i, address, token):
1589+ if config.slotCredentialMatch (i, address, token) == SlotCredentialConflict :
15681590 return i
15691591 - 1
15701592
@@ -1596,11 +1618,7 @@ proc matchingConfiguredSlot(
15961618 for i in 0 ..< sim.config.slots.len:
15971619 if sim.slotOccupied (i):
15981620 continue
1599- let slot = sim.config.slots[i]
1600- let couldMatchName = slot.name.len > 0 and slot.name == address
1601- let couldMatchToken = slot.token.len > 0 and slot.token == token
1602- if (couldMatchName or couldMatchToken) and
1603- sim.config.slotAuthMatches (i, address, token):
1621+ if sim.config.slotCredentialMatch (i, address, token) == SlotCredentialValid :
16041622 return i
16051623 - 1
16061624
@@ -1613,12 +1631,7 @@ proc conflictingConfiguredSlot(
16131631 for i in 0 ..< sim.config.slots.len:
16141632 if sim.slotOccupied (i):
16151633 continue
1616- let slot = sim.config.slots[i]
1617- let matchedName = slot.name.len > 0 and slot.name == address
1618- let matchedToken =
1619- slot.token.len > 0 and token.len > 0 and slot.token == token
1620- if (matchedName or matchedToken) and
1621- not sim.config.slotAuthMatches (i, address, token):
1634+ if sim.config.slotCredentialMatch (i, address, token) == SlotCredentialConflict :
16221635 return i
16231636 - 1
16241637
@@ -1793,7 +1806,7 @@ proc addPlayer*(
17931806): int =
17941807 # # Adds one player, optionally validating and using a requested slot.
17951808 if not sim.canAddPlayer ():
1796- raise newException (AmongThemError , " can't do more than 16 players. " )
1809+ raise newException (AmongThemError , sim.config. playerLimitError () )
17971810 if sim.playerAddressOccupied (address):
17981811 raise newException (
17991812 AmongThemError ,
0 commit comments