Clean up console commands

Improve functionality of network console commands and make displaying of who is who clearer.
This commit is contained in:
Boondorl 2025-07-03 15:16:22 -04:00 committed by Ricardo Luís Vaz Silva
commit a1a3be1046
2 changed files with 226 additions and 154 deletions

View file

@ -2476,9 +2476,9 @@ void Net_DoCommand(int cmd, uint8_t **stream, int player)
if (deathmatch && teamplay)
Printf(PRINT_CHAT, "(All) ");
if ((who & MSG_BOLD) && !cl_noboldchat)
Printf(PRINT_CHAT, TEXTCOLOR_BOLD "* %s" TEXTCOLOR_BOLD "%s" TEXTCOLOR_BOLD "\n", name, s);
Printf(PRINT_CHAT, TEXTCOLOR_BOLD "* %s [%d]" TEXTCOLOR_BOLD "%s" TEXTCOLOR_BOLD "\n", name, player, s);
else
Printf(PRINT_CHAT, "%s" TEXTCOLOR_CHAT ": %s" TEXTCOLOR_CHAT "\n", name, s);
Printf(PRINT_CHAT, "%s [%d]" TEXTCOLOR_CHAT ": %s" TEXTCOLOR_CHAT "\n", name, player, s);
if (!cl_nochatsound)
S_Sound(CHAN_VOICE, CHANF_UI, gameinfo.chatSound, 1.0f, ATTN_NONE);
@ -2492,9 +2492,9 @@ void Net_DoCommand(int cmd, uint8_t **stream, int player)
if (deathmatch && teamplay)
Printf(PRINT_TEAMCHAT, "(Team) ");
if ((who & MSG_BOLD) && !cl_noboldchat)
Printf(PRINT_TEAMCHAT, TEXTCOLOR_BOLD "* %s" TEXTCOLOR_BOLD "%s" TEXTCOLOR_BOLD "\n", name, s);
Printf(PRINT_TEAMCHAT, TEXTCOLOR_BOLD "* %s [%d]" TEXTCOLOR_BOLD "%s" TEXTCOLOR_BOLD "\n", name, player, s);
else
Printf(PRINT_TEAMCHAT, "%s" TEXTCOLOR_TEAMCHAT ": %s" TEXTCOLOR_TEAMCHAT "\n", name, s);
Printf(PRINT_TEAMCHAT, "%s [%d]" TEXTCOLOR_TEAMCHAT ": %s" TEXTCOLOR_TEAMCHAT "\n", name, player, s);
if (!cl_nochatsound)
S_Sound(CHAN_VOICE, CHANF_UI, gameinfo.chatSound, 1.0f, ATTN_NONE);
@ -2859,8 +2859,10 @@ void Net_DoCommand(int cmd, uint8_t **stream, int player)
{
uint8_t playernum = ReadInt8(stream);
players[playernum].settings_controller = true;
if (consoleplayer == playernum || consoleplayer == Net_Arbitrator)
Printf("%s has been added to the controller list.\n", players[playernum].userinfo.GetName());
if (consoleplayer == playernum)
Printf("You can now control game settings\n");
else if (consoleplayer == Net_Arbitrator)
Printf("%s [%d] is now a settings controller\n", players[playernum].userinfo.GetName(), playernum);
}
break;
@ -2868,8 +2870,10 @@ void Net_DoCommand(int cmd, uint8_t **stream, int player)
{
uint8_t playernum = ReadInt8(stream);
players[playernum].settings_controller = false;
if (consoleplayer == playernum || consoleplayer == Net_Arbitrator)
Printf("%s has been removed from the controller list.\n", players[playernum].userinfo.GetName());
if (consoleplayer == playernum)
Printf("You can no longer control game settings\n");
else if (consoleplayer == Net_Arbitrator)
Printf("%s [%d] is no longer a settings controller\n", players[playernum].userinfo.GetName(), playernum);
}
break;
@ -3021,11 +3025,10 @@ void Net_DoCommand(int cmd, uint8_t **stream, int player)
{
I_Error("You have been kicked from the game");
}
else
else if (NetworkClients.InGame(pNum))
{
Printf("%s has been kicked from the game\n", players[pNum].userinfo.GetName());
if (NetworkClients.InGame(pNum))
DisconnectClient(pNum);
Printf("%s [%d] has been kicked from the game\n", players[pNum].userinfo.GetName(), pNum);
DisconnectClient(pNum);
}
}
break;
@ -3287,7 +3290,7 @@ CCMD(pings)
{
if (!netgame)
{
Printf("Not currently in a net game\n");
Printf("This command can only be used when playing in a net game\n");
return;
}
@ -3298,37 +3301,21 @@ CCMD(pings)
for (auto client : NetworkClients)
{
if ((NetMode == NET_PeerToPeer && client != consoleplayer) || (NetMode == NET_PacketServer && client != Net_Arbitrator))
Printf("%ums %s\n", ClientStates[client].AverageLatency, players[client].userinfo.GetName());
}
}
CCMD(listplayers)
{
if (!netgame)
{
Printf("Not currently in a net game\n");
return;
}
for (auto client : NetworkClients)
{
if (client == consoleplayer)
Printf("* ");
Printf("%s - %d\n", players[client].userinfo.GetName(), client);
Printf("%ums %s [%d]\n", ClientStates[client].AverageLatency, players[client].userinfo.GetName(), client);
}
}
CCMD(kick)
{
if (argv.argc() == 1)
if (argv.argc() < 2)
{
Printf("Usage: kick <player number>\n");
Printf("Usage: kick <client numbers>\nRemove these clients from the game\n");
return;
}
if (!netgame)
{
Printf("Not currently in a net game\n");
Printf("This command can only be used when playing in a net game\n");
return;
}
@ -3336,99 +3323,102 @@ CCMD(kick)
// the host can grant.
if (consoleplayer != Net_Arbitrator)
{
Printf("Only the host is allowed to kick other players\n");
Printf("This command is only accessible to the host\n");
return;
}
int pNum = -1;
if (!C_IsValidInt(argv[1], pNum))
TArray<int> cNums = {};
for (size_t i = 1u; i < argv.argc(); ++i)
{
Printf("A player number must be provided. Use listplayers for more information\n");
return;
int cNum = -1;
if (!C_IsValidInt(argv[i], cNum) || cNum < 0 || cNum >= MAXPLAYERS)
Printf("Bad client number %s\n", argv[i]);
else if (cNum != consoleplayer && cNums.Find(cNum) >= cNums.Size())
cNums.Push(cNum);
}
if (pNum == consoleplayer || pNum < 0 || pNum >= MAXPLAYERS)
for (auto cNum : cNums)
{
Printf("Invalid player number provided\n");
return;
if (!NetworkClients.InGame(cNum))
{
Printf("Client %d is not in game\n", cNum);
}
else
{
Net_WriteInt8(DEM_KICK);
Net_WriteInt8(cNum);
}
}
if (!NetworkClients.InGame(pNum))
{
Printf("Player is not currently in the game\n");
return;
}
Net_WriteInt8(DEM_KICK);
Net_WriteInt8(pNum);
}
CCMD(mute)
{
if (argv.argc() == 1)
if (argv.argc() < 2)
{
Printf("Usage: mute <player number> - Don't receive messages from this player\n");
Printf("Usage: mute <player numbers>\nDisable messages from these players\n");
return;
}
if (!netgame)
if (!multiplayer)
{
Printf("Not currently in a net game\n");
Printf("This command can only be used when playing in multiplayer\n");
return;
}
int pNum = -1;
if (!C_IsValidInt(argv[1], pNum))
TArray<int> pNums = {};
for (size_t i = 1u; i < argv.argc(); ++i)
{
Printf("A player number must be provided. Use listplayers for more information\n");
return;
int pNum = -1;
if (!C_IsValidInt(argv[i], pNum) || pNum < 0 || pNum >= MAXPLAYERS)
Printf("Bad player number %s\n", argv[i]);
else if (pNum != consoleplayer && pNums.Find(pNum) >= pNums.Size())
pNums.Push(pNum);
}
if (pNum == consoleplayer || pNum < 0 || pNum >= MAXPLAYERS)
for (auto pNum : pNums)
{
Printf("Invalid player number provided\n");
return;
if (!playeringame[pNum])
{
Printf("Player %d is not in game\n", pNum);
}
else
{
MutedClients |= (uint64_t)1u << pNum;
Printf("Muted player %s [%d]\n", players[pNum].userinfo.GetName(), pNum);
}
}
if (!NetworkClients.InGame(pNum))
{
Printf("Player is not currently in the game\n");
return;
}
MutedClients |= (uint64_t)1u << pNum;
}
CCMD(muteall)
{
if (!netgame)
if (!multiplayer)
{
Printf("Not currently in a net game\n");
Printf("This command can only be used when playing in multiplayer\n");
return;
}
for (auto client : NetworkClients)
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (client != consoleplayer)
MutedClients |= (uint64_t)1u << client;
if (playeringame[i] && i != consoleplayer)
MutedClients |= (uint64_t)1u << i;
}
}
CCMD(listmuted)
{
if (!netgame)
if (!multiplayer)
{
Printf("Not currently in a net game\n");
Printf("This command can only be used when playing in multiplayer\n");
return;
}
bool found = false;
for (auto client : NetworkClients)
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (MutedClients & ((uint64_t)1u << client))
if (MutedClients & ((uint64_t)1u << i))
{
found = true;
Printf("%s - %d\n", players[client].userinfo.GetName(), client);
Printf("%d. %s\n", i, players[i].userinfo.GetName());
}
}
@ -3438,39 +3428,47 @@ CCMD(listmuted)
CCMD(unmute)
{
if (argv.argc() == 1)
if (argv.argc() < 2)
{
Printf("Usage: unmute <player number> - Allow messages from this player again\n");
Printf("Usage: unmute <player numbers>\nAllow messages from these players again\n");
return;
}
if (!netgame)
if (!multiplayer)
{
Printf("Not currently in a net game\n");
Printf("This command can only be used when playing in multiplayer\n");
return;
}
int pNum = -1;
if (!C_IsValidInt(argv[1], pNum))
TArray<int> pNums = {};
for (size_t i = 1u; i < argv.argc(); ++i)
{
Printf("A player number must be provided. Use listplayers for more information\n");
return;
int pNum = -1;
if (!C_IsValidInt(argv[i], pNum) || pNum < 0 || pNum >= MAXPLAYERS)
Printf("Bad player number %s\n", argv[i]);
else if (pNum != consoleplayer && pNums.Find(pNum) >= pNums.Size())
pNums.Push(pNum);
}
if (pNum == consoleplayer || pNum < 0 || pNum >= MAXPLAYERS)
for (auto pNum : pNums)
{
Printf("Invalid player number provided\n");
return;
if (!playeringame[pNum])
{
Printf("Player %d is not in game\n", pNum);
}
else
{
MutedClients &= ~((uint64_t)1u << pNum);
Printf("Unmuted player %s [%d]\n", players[pNum].userinfo.GetName(), pNum);
}
}
MutedClients &= ~((uint64_t)1u << pNum);
}
CCMD(unmuteall)
{
if (!netgame)
if (!multiplayer)
{
Printf("Not currently in a net game\n");
Printf("This command can only be used when playing in multiplayer\n");
return;
}
@ -3479,108 +3477,158 @@ CCMD(unmuteall)
//==========================================================================
//
// Network_Controller
// Net_ChangeSettingsControllers
//
// Implement players who have the ability to change settings in a network
// game.
//
//==========================================================================
static void Network_Controller(int pNum, bool add)
static void Net_ChangeSettingsControllers(const TArray<int>& cNums, bool add)
{
if (!netgame)
{
Printf("This command can only be used when playing a net game.\n");
Printf("This command can only be used when playing in a net game\n");
return;
}
if (consoleplayer != Net_Arbitrator)
{
Printf("This command is only accessible to the host.\n");
Printf("This command is only accessible to the host\n");
return;
}
if (pNum == Net_Arbitrator)
for (auto cNum : cNums)
{
Printf("The host cannot change their own settings controller status.\n");
return;
if (cNum == Net_Arbitrator)
{
Printf("The host cannot change their own settings controller status\n");
}
else if (!NetworkClients.InGame(cNum))
{
Printf("Client %d is not in game\n", cNum);
}
else if (players[cNum].settings_controller && add)
{
Printf("Client %d is already a settings controller\n", cNum);
}
else if (!players[cNum].settings_controller && !add)
{
Printf("Client %d is already not a settings controller\n", cNum);
}
else
{
Net_WriteInt8(add ? DEM_ADDCONTROLLER : DEM_DELCONTROLLER);
Net_WriteInt8(cNum);
}
}
if (!NetworkClients.InGame(pNum))
{
Printf("Player %d is not a valid client\n", pNum);
return;
}
if (players[pNum].settings_controller && add)
{
Printf("%s is already on the setting controller list.\n", players[pNum].userinfo.GetName());
return;
}
if (!players[pNum].settings_controller && !add)
{
Printf("%s is not on the setting controller list.\n", players[pNum].userinfo.GetName());
return;
}
Net_WriteInt8(add ? DEM_ADDCONTROLLER : DEM_DELCONTROLLER);
Net_WriteInt8(pNum);
}
//==========================================================================
//
// CCMD net_addcontroller
// CCMD addsettingscontrollers
//
//==========================================================================
CCMD(net_addcontroller)
CCMD(addsettingscontrollers)
{
if (argv.argc() < 2)
{
Printf("Usage: net_addcontroller <player num>\n");
Printf("Usage: addsettingscontrollers <client numbers>\nAllow these clients to control game settings\n");
return;
}
Network_Controller(atoi (argv[1]), true);
TArray<int> cNums = {};
for (size_t i = 1u; i < argv.argc(); ++i)
{
int cNum = -1;
if (!C_IsValidInt(argv[i], cNum) || cNum < 0 || cNum >= MAXPLAYERS)
Printf("Bad client number %s\n", argv[i]);
else if (cNum != Net_Arbitrator && cNums.Find(cNum) >= cNums.Size())
cNums.Push(cNum);
}
Net_ChangeSettingsControllers(cNums, true);
}
//==========================================================================
//
// CCMD net_removecontroller
// CCMD removesettingscontrollers
//
//==========================================================================
CCMD(net_removecontroller)
CCMD(removesettingscontrollers)
{
if (argv.argc() < 2)
{
Printf("Usage: net_removecontroller <player num>\n");
Printf("Usage: removesettingscontrollers <client numbers>\nRemove the ability for these clients to control game settings\n");
return;
}
Network_Controller(atoi(argv[1]), false);
TArray<int> cNums = {};
for (size_t i = 1u; i < argv.argc(); ++i)
{
int cNum = -1;
if (!C_IsValidInt(argv[i], cNum) || cNum < 0 || cNum >= MAXPLAYERS)
Printf("Bad player number %s\n", argv[i]);
else if (cNum != Net_Arbitrator && cNums.Find(cNum) >= cNums.Size())
cNums.Push(cNum);
}
Net_ChangeSettingsControllers(cNums, false);
}
//==========================================================================
//
// CCMD net_listcontrollers
// CCMD removeallsettingscontrollers
//
//==========================================================================
CCMD(net_listcontrollers)
CCMD(removeallsettingscontrollers)
{
TArray<int> cNums = {};
for (auto client : NetworkClients)
{
if (client != Net_Arbitrator && players[client].settings_controller)
cNums.Push(client);
}
Net_ChangeSettingsControllers(cNums, false);
}
//==========================================================================
//
// CCMD listsettingscontrollers
//
//==========================================================================
CCMD(listsettingscontrollers)
{
if (!netgame)
{
Printf ("This command can only be used when playing a net game.\n");
Printf("This command can only be used when playing in a net game\n");
return;
}
TArray<int> cNums = {};
for (auto client : NetworkClients)
{
if (client != Net_Arbitrator && players[client].settings_controller)
cNums.Push(client);
}
if (!cNums.Size())
{
Printf("No other settings controllers\n");
return;
}
Printf("The following players can change the game settings:\n");
for (auto client : NetworkClients)
for (auto cNum : cNums)
{
if (players[client].settings_controller)
Printf("- %s\n", players[client].userinfo.GetName());
Printf("%d. %s", cNum, players[cNum].userinfo.GetName());
if (cNum == consoleplayer)
Printf(" [*]");
Printf("\n");
}
}

View file

@ -1016,50 +1016,75 @@ void ReadUserInfo(FSerializer &arc, userinfo_t &info, FString &skin)
}
}
CCMD (playerinfo)
CCMD(playerinfo)
{
if (argv.argc() < 2)
TArray<int> inGame = {};
for (int i = 0; i < MAXPLAYERS; ++i)
{
int i;
if (playeringame[i])
inGame.Push(i);
}
for (i = 0; i < MAXPLAYERS; i++)
const bool isMulti = inGame.Size() > 1;
if (isMulti && argv.argc() < 2)
{
for (auto i : inGame)
{
if (playeringame[i])
Printf("%d. %s", i, players[i].userinfo.GetName());
if (i == consoleplayer || i == Net_Arbitrator || players[i].Bot != nullptr || players[i].settings_controller)
{
Printf("%d. %s\n", i, players[i].userinfo.GetName());
Printf(" [");
if (i == consoleplayer)
Printf("*");
if (i == Net_Arbitrator)
Printf("H");
if (players[i].Bot != nullptr)
Printf("B");
else if (players[i].settings_controller && i != Net_Arbitrator)
Printf("C");
Printf("]");
}
Printf("\n");
}
Printf("Pass a player number for more info\n");
}
else
{
int i = atoi(argv[1]);
if (i < 0 || i >= MAXPLAYERS)
int i = -1;
if (!isMulti)
{
Printf("Bad player number\n");
i = consoleplayer;
}
else if (!C_IsValidInt(argv[1], i) || i < 0 || i >= MAXPLAYERS)
{
Printf("Bad player number %s\n", argv[1]);
return;
}
userinfo_t *ui = &players[i].userinfo;
if (!playeringame[i])
{
Printf(TEXTCOLOR_ORANGE "Player %d is not in the game\n", i);
Printf("Player %d is not in game\n", i);
return;
}
const userinfo_t& info = players[i].userinfo;
// Print special info
Printf("%20s: %s\n", "Name", ui->GetName());
Printf("%20s: %s (%d)\n", "Team", ui->GetTeam() == TEAM_NONE ? "None" : Teams[ui->GetTeam()].GetName(), ui->GetTeam());
Printf("%20s: %s (%d)\n", "Skin", Skins[ui->GetSkin()].Name.GetChars(), ui->GetSkin());
Printf("%20s: %s (%d)\n", "Gender", GenderNames[ui->GetGender()], ui->GetGender());
Printf("%20s: %s\n", "Host", i == Net_Arbitrator ? "Yes" : "No");
Printf("%20s: %s\n", "Console Player", i == consoleplayer ? "Yes" : "No");
Printf("%20s: %s\n", "Bot", players[i].Bot != nullptr ? "Yes" : "No");
Printf("%20s: %s\n", "Settings Controller", players[i].settings_controller && players[i].Bot == nullptr ? "Yes" : "No");
Printf("%20s: %s\n", "Name", info.GetName());
Printf("%20s: %s (%d)\n", "Team", info.GetTeam() == TEAM_NONE ? "None" : Teams[info.GetTeam()].GetName(), info.GetTeam());
Printf("%20s: %s (%d)\n", "Skin", Skins[info.GetSkin()].Name.GetChars(), info.GetSkin());
Printf("%20s: %s (%d)\n", "Gender", GenderNames[info.GetGender()], info.GetGender());
Printf("%20s: %s (%d)\n", "PlayerClass",
ui->GetPlayerClassNum() == -1 ? "Random" : ui->GetPlayerClassType()->GetDisplayName().GetChars(),
ui->GetPlayerClassNum());
info.GetPlayerClassNum() == -1 ? "Random" : info.GetPlayerClassType()->GetDisplayName().GetChars(),
info.GetPlayerClassNum());
// Print generic info
TMapIterator<FName, FBaseCVar *> it(*ui);
TMap<FName, FBaseCVar *>::Pair *pair;
TMap<FName, FBaseCVar*>::ConstIterator it = { info };
TMap<FName, FBaseCVar*>::ConstPair* pair = nullptr;
while (it.NextPair(pair))
{
if (pair->Key != NAME_Name && pair->Key != NAME_Team && pair->Key != NAME_Skin &&
@ -1068,10 +1093,9 @@ CCMD (playerinfo)
Printf("%20s: %s\n", pair->Key.GetChars(), pair->Value->GetHumanString());
}
}
if (argv.argc() > 2)
{
if (argv.argc() > 2 || (!isMulti && argv.argc() > 1))
PrintMiscActorInfo(players[i].mo);
}
}
}