Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion doc/lua/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,10 @@ Change the players team.

**SetColor(color or colorIdx)**
Sets the players color by index or directly if its alpha value is not zero.
Duplicate color values are possible, so you have to ensure unique colors if you want them!
When the color is currently used by an active player/AI, a new one will be chosen out of the standard player colors.
You can change the colors freely for slots not yet taken, so if the final distribution of colors is unique,
they will be kept after using e.g. `SetAI`.
In any case, using `SetAI` will ensure a unique color.

**Close()**
Closes a spot kicking any player or AI there.
Expand Down
9 changes: 8 additions & 1 deletion libs/s25main/SavedFile.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Copyright (C) 2005 - 2024 Settlers Freaks (sf-team at siedler25.org)
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
//
// SPDX-License-Identifier: GPL-2.0-or-later

#include "SavedFile.h"
#include "BasePlayerInfo.h"
#include "RTTR_Version.h"
#include "enum_cast.hpp"
#include "helpers/format.hpp"
#include "gameData/MaxPlayers.h"
#include "libendian/ConvertEndianess.h"
#include "s25util/BinaryFile.h"
#include "s25util/Serializer.h"
Expand Down Expand Up @@ -145,6 +147,11 @@ void SavedFile::ReadPlayerData(BinaryFile& file)
Serializer ser;
ser.ReadFromFile(file);
const unsigned playerCt = ser.PopUnsignedChar();
if(playerCt > MAX_PLAYERS)
{
throw std::length_error(
helpers::format(_("Number of players (%1%) exceeds maximum allowed of %2%!"), playerCt, MAX_PLAYERS));
}
players.reserve(playerCt);
for(unsigned i = 0; i < playerCt; i++)
{
Expand Down
17 changes: 10 additions & 7 deletions libs/s25main/network/GameServer.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2005 - 2024 Settlers Freaks (sf-team at siedler25.org)
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
//
// SPDX-License-Identifier: GPL-2.0-or-later

Expand Down Expand Up @@ -177,7 +177,11 @@ bool GameServer::Start(const CreateServerInfo& csi, const MapDescription& map, c
LOG.write("Map %1% has no players!\n") % mapinfo.filepath;
return false;
}

if(playerInfos.size() > MAX_PLAYERS)
{
LOG.write("Map %1% has too many players! (%1% > %2%)\n") % mapinfo.filepath % playerInfos.size() % MAX_PLAYERS;
return false;
}
if(!mapinfo.mapData.CompressFromFile(mapinfo.filepath, &mapinfo.mapChecksum))
return false;

Expand Down Expand Up @@ -1587,10 +1591,9 @@ void GameServer::SendAsyncLog(const bfs::path& asyncLogFilePath)
void GameServer::CheckAndSetColor(unsigned playerIdx, unsigned newColor)
{
RTTR_Assert(playerIdx < playerInfos.size());
RTTR_Assert(playerInfos.size() <= PLAYER_COLORS.size()); // Else we may not find a valid color!

JoinPlayerInfo& player = playerInfos[playerIdx];
RTTR_Assert(player.isUsed()); // Should only set colors for taken spots
// If either of those fails we may not find a valid color!
static_assert(PLAYER_COLORS.size() >= MAX_PLAYERS, "Not enough player colors defined!");
RTTR_Assert(playerInfos.size() <= PLAYER_COLORS.size());

// Get colors used by other players
std::set<unsigned> takenColors;
Expand All @@ -1610,9 +1613,9 @@ void GameServer::CheckAndSetColor(unsigned playerIdx, unsigned newColor)
while(helpers::contains(takenColors, newColor))
newColor = PLAYER_COLORS[(++newColorIdx) % PLAYER_COLORS.size()];

JoinPlayerInfo& player = playerInfos[playerIdx];
if(player.color == newColor)
return;

player.color = newColor;

SendToAll(GameMessage_Player_Color(playerIdx, player.color));
Expand Down
Loading