diff --git a/include/StartupInfo.h b/include/StartupInfo.h index 498bf83691..6bb97075e6 100644 --- a/include/StartupInfo.h +++ b/include/StartupInfo.h @@ -30,6 +30,7 @@ class StartupInfo bool hasConfiguration; bool autoConnect; + char serverAllowedTeams[7]; char serverName[80]; int serverPort; bool useUDPconnection; diff --git a/src/bzflag/JoinMenu.cxx b/src/bzflag/JoinMenu.cxx index 651fd8ea06..2160571c38 100644 --- a/src/bzflag/JoinMenu.cxx +++ b/src/bzflag/JoinMenu.cxx @@ -80,12 +80,18 @@ JoinMenu::JoinMenu() : serverStartMenu(NULL), serverMenu(NULL) std::vector& teams = team->getList(); // these do not need to be in enum order, but must match getTeam() & setTeam() teams.push_back(std::string(Team::getName(AutomaticTeam))); - teams.push_back(std::string(Team::getName(RogueTeam))); - teams.push_back(std::string(Team::getName(RedTeam))); - teams.push_back(std::string(Team::getName(GreenTeam))); - teams.push_back(std::string(Team::getName(BlueTeam))); - teams.push_back(std::string(Team::getName(PurpleTeam))); - teams.push_back(std::string(Team::getName(ObserverTeam))); + if(info->serverAllowedTeams[0] == '1') + teams.push_back(std::string(Team::getName(RogueTeam))); + if(info->serverAllowedTeams[1] == '1') + teams.push_back(std::string(Team::getName(RedTeam))); + if(info->serverAllowedTeams[2] == '1') + teams.push_back(std::string(Team::getName(GreenTeam))); + if(info->serverAllowedTeams[3] == '1') + teams.push_back(std::string(Team::getName(BlueTeam))); + if(info->serverAllowedTeams[4] == '1') + teams.push_back(std::string(Team::getName(PurpleTeam))); + if(info->serverAllowedTeams[5] == '1') + teams.push_back(std::string(Team::getName(ObserverTeam))); team->update(); setTeam(info->team); listHUD.push_back(team); @@ -161,7 +167,26 @@ void JoinMenu::show() // set fields callsign->setString(info->callsign); password->setString(info->password); + { + std::vector& teams = team->getList(); + teams.clear(); + teams.push_back(std::string(Team::getName(AutomaticTeam))); + if (info->serverAllowedTeams[0] == '1') + teams.push_back(std::string(Team::getName(RogueTeam))); + if (info->serverAllowedTeams[1] == '1') + teams.push_back(std::string(Team::getName(RedTeam))); + if (info->serverAllowedTeams[2] == '1') + teams.push_back(std::string(Team::getName(GreenTeam))); + if (info->serverAllowedTeams[3] == '1') + teams.push_back(std::string(Team::getName(BlueTeam))); + if (info->serverAllowedTeams[4] == '1') + teams.push_back(std::string(Team::getName(PurpleTeam))); + if (info->serverAllowedTeams[5] == '1') + teams.push_back(std::string(Team::getName(ObserverTeam))); + team->update(); + } setTeam(info->team); + updateTeamTexture(); server->setString(info->serverName); char buffer[10]; @@ -273,12 +298,27 @@ void JoinMenu::setFailedMessage(const char* msg) TeamColor JoinMenu::getTeam() const { - return team->getIndex() == 0 ? AutomaticTeam : TeamColor(team->getIndex() - 1); + const int idx = team->getIndex(); + const std::vector &list = team->getList(); + if (idx < 0 || idx >= (int)list.size()) + return AutomaticTeam; + return Team::getTeam(list[idx]); } void JoinMenu::setTeam(TeamColor teamcol) { - team->setIndex(teamcol == AutomaticTeam ? 0 : int(teamcol) + 1); + const std::string want = Team::getName(teamcol); + const std::vector &list = team->getList(); + for (size_t i = 0; i < list.size(); ++i) + { + if (list[i] == want) + { + team->setIndex((int)i); + return; + } + } + // fallback to Automatic if not found + team->setIndex(0); } void JoinMenu::setStatus(const char* msg, const std::vector *) diff --git a/src/bzflag/ServerMenu.cxx b/src/bzflag/ServerMenu.cxx index 258253c404..ee832f9538 100644 --- a/src/bzflag/ServerMenu.cxx +++ b/src/bzflag/ServerMenu.cxx @@ -33,6 +33,8 @@ const int ServerMenu::NumReadouts = 24; const int ServerMenu::NumItems = 10; +char ServerMenu::JoinableTeams[7] = { '1','1','1','1','1','1', '\0' }; + ServerMenuDefaultKey::~ServerMenuDefaultKey() { delete serverListFilterMenu; @@ -552,6 +554,11 @@ void ServerMenu::pick() char buf[60]; std::vector& listHUD = getControls(); + // reset JoinableTeams + for (int i = 0; i < 6; ++i) + JoinableTeams[i] = '1'; + JoinableTeams[6] = '\0'; + const uint8_t maxes [] = { ping.maxPlayers, ping.rogueMax, ping.redMax, ping.greenMax, ping.blueMax, ping.purpleMax, ping.observerMax }; @@ -572,7 +579,10 @@ void ServerMenu::pick() ((HUDuiLabel*)listHUD[1])->setLabel(buf); if (ping.rogueMax == 0) + { buf[0]=0; + JoinableTeams[0]='0'; + } else if (ping.rogueMax >= ping.maxPlayers) sprintf(buf, "%d", ping.rogueCount); else @@ -580,7 +590,10 @@ void ServerMenu::pick() ((HUDuiLabel*)listHUD[2])->setLabel(buf); if (ping.redMax == 0) + { buf[0]=0; + JoinableTeams[1]='0'; + } else if (ping.redMax >= ping.maxPlayers) sprintf(buf, "%d", ping.redCount); else @@ -588,7 +601,10 @@ void ServerMenu::pick() ((HUDuiLabel*)listHUD[3])->setLabel(buf); if (ping.greenMax == 0) + { buf[0]=0; + JoinableTeams[2]='0'; + } else if (ping.greenMax >= ping.maxPlayers) sprintf(buf, "%d", ping.greenCount); else @@ -596,7 +612,10 @@ void ServerMenu::pick() ((HUDuiLabel*)listHUD[4])->setLabel(buf); if (ping.blueMax == 0) + { buf[0]=0; + JoinableTeams[3]='0'; + } else if (ping.blueMax >= ping.maxPlayers) sprintf(buf, "%d", ping.blueCount); else @@ -604,7 +623,10 @@ void ServerMenu::pick() ((HUDuiLabel*)listHUD[5])->setLabel(buf); if (ping.purpleMax == 0) + { buf[0]=0; + JoinableTeams[4]='0'; + } else if (ping.purpleMax >= ping.maxPlayers) sprintf(buf, "%d", ping.purpleCount); else @@ -612,7 +634,10 @@ void ServerMenu::pick() ((HUDuiLabel*)listHUD[6])->setLabel(buf); if (ping.observerMax == 0) + { buf[0]=0; + JoinableTeams[5]='0'; + } else if (ping.observerMax >= ping.maxPlayers) sprintf(buf, "%d", ping.observerCount); else @@ -810,6 +835,8 @@ void ServerMenu::execute() info->serverName[sizeof(info->serverName) - 1] = '\0'; info->serverPort = ntohs((unsigned short) serverList.getServers()[selectedIndex].ping.serverId.port); + strncpy(info->serverAllowedTeams, JoinableTeams, sizeof(info->serverAllowedTeams) - 1); + info->serverAllowedTeams[sizeof(info->serverAllowedTeams) - 1] = '\0'; // all done HUDDialogStack::get()->pop(); diff --git a/src/bzflag/ServerMenu.h b/src/bzflag/ServerMenu.h index 7f92347f04..c6d0c126d7 100644 --- a/src/bzflag/ServerMenu.h +++ b/src/bzflag/ServerMenu.h @@ -64,6 +64,7 @@ class ServerMenu final : public HUDDialog { return &defaultKey; } + int getSelected() const; void setSelected(int, bool forcerefresh=false); void show() override; @@ -114,6 +115,8 @@ class ServerMenu final : public HUDDialog int lastWidth, lastHeight; static const int NumReadouts; + + static char JoinableTeams[7]; }; diff --git a/src/bzflag/bzflag.cxx b/src/bzflag/bzflag.cxx index e2a35217d4..36e07434d7 100644 --- a/src/bzflag/bzflag.cxx +++ b/src/bzflag/bzflag.cxx @@ -610,6 +610,7 @@ void dumpResources() BZDB.set("team", Team::getName(startupInfo.team)); BZDB.set("server", startupInfo.serverName); + BZDB.set("serverAllowedTeams", startupInfo.serverAllowedTeams); if (startupInfo.serverPort != ServerPort) BZDB.set("port", TextUtils::format("%d", startupInfo.serverPort)); else @@ -837,6 +838,13 @@ int main(int argc, char** argv) sizeof(startupInfo.serverName) - 1); startupInfo.serverName[sizeof(startupInfo.serverName) - 1] = '\0'; } + if (BZDB.isSet("serverAllowedTeams")) + { + // Flawfinder: ignore + strncpy(startupInfo.serverAllowedTeams, BZDB.get("serverAllowedTeams").c_str(), + sizeof(startupInfo.serverAllowedTeams) - 1); + startupInfo.serverAllowedTeams[sizeof(startupInfo.serverAllowedTeams) - 1] = '\0'; + } if (BZDB.isSet("port")) startupInfo.serverPort = atoi(BZDB.get("port").c_str()); diff --git a/src/game/StartupInfo.cxx b/src/game/StartupInfo.cxx index eb1dcb07c5..247293d5cb 100644 --- a/src/game/StartupInfo.cxx +++ b/src/game/StartupInfo.cxx @@ -27,6 +27,7 @@ StartupInfo::StartupInfo() : hasConfiguration(false), listServerURL(DefaultListServerURL), listServerPort(ServerPort + 1) { + strcpy(serverAllowedTeams, "111111"); strcpy(serverName, ""); strcpy(callsign, ""); strcpy(password, ""); @@ -39,6 +40,7 @@ StartupInfo::~StartupInfo() { hasConfiguration = false; autoConnect = false; + memset(serverAllowedTeams, 0, 7); memset(serverName, 0, 80); serverPort = -1; useUDPconnection = false;