forked from Mirrors/openclonk
Make network lobby command line processing available to the editor and dedi
Most of the processing was already done by C4MessageInput::ProcessInput and C4MessageInput::ProcessCommand. Simply move the Lobby-only commands there, too, and make them work without a Lobby MainDlg. This required almost only cosmetic changes.stable-5.3
parent
acc37860ed
commit
d5d72344ef
|
@ -446,164 +446,7 @@ namespace C4GameLobby
|
|||
// store input in backbuffer before processing commands
|
||||
// because those might kill the edit field
|
||||
::MessageInput.StoreBackBuffer(szInputText);
|
||||
bool fProcessed = false;
|
||||
// CAUTION when implementing special commands (like /quit) here:
|
||||
// those must not be executed when text is pasted, because that could crash the GUI system
|
||||
// when there are additional lines to paste, but the edit field is destructed by the command
|
||||
if (!fProcessed && *szInputText == '/')
|
||||
{
|
||||
// must be 1 char longer than the longest command only. If given commands are longer, they will be truncated, and such a command won't exist anyway
|
||||
const int32_t MaxCommandLen = 20;
|
||||
char Command[MaxCommandLen+1];
|
||||
const char *szPar = szInputText;
|
||||
// parse command until first space
|
||||
int32_t iParPos = SCharPos(' ', szInputText);
|
||||
if (iParPos<0)
|
||||
{
|
||||
// command w/o par
|
||||
SCopy(szInputText, Command, MaxCommandLen);
|
||||
szPar += SLen(szPar);
|
||||
}
|
||||
else
|
||||
{
|
||||
// command with following par
|
||||
SCopy(szInputText, Command, Min(MaxCommandLen, iParPos));
|
||||
szPar += iParPos+1;
|
||||
}
|
||||
fProcessed = true;
|
||||
// evaluate lobby-only commands
|
||||
// ------------------------------------------------------
|
||||
if (SEqualNoCase(Command, "/joinplr"))
|
||||
{
|
||||
// compose path from given filename
|
||||
StdStrBuf plrPath;
|
||||
plrPath.Format("%s%s", Config.General.UserDataPath, szPar);
|
||||
// player join - check filename
|
||||
if (!ItemExists(plrPath.getData()))
|
||||
{
|
||||
LobbyError(FormatString(LoadResStr("IDS_MSG_CMD_JOINPLR_NOFILE"), plrPath.getData()).getData());
|
||||
}
|
||||
else
|
||||
::Network.Players.JoinLocalPlayer(plrPath.getData(), true);
|
||||
}
|
||||
// ------------------------------------------------------
|
||||
else if (SEqualNoCase(Command, "/plrclr"))
|
||||
{
|
||||
// get player name from input text
|
||||
int iSepPos = SCharPos(' ', szPar, 0);
|
||||
C4PlayerInfo *pNfo=NULL;
|
||||
int32_t idLocalClient = -1;
|
||||
if (::Network.Clients.GetLocal()) idLocalClient = ::Network.Clients.GetLocal()->getID();
|
||||
if (iSepPos>0)
|
||||
{
|
||||
// a player name is given: Parse it
|
||||
StdStrBuf sPlrName;
|
||||
sPlrName.Copy(szPar, iSepPos);
|
||||
szPar += iSepPos+1; int32_t id=0;
|
||||
while ((pNfo = Game.PlayerInfos.GetNextPlayerInfoByID(id)))
|
||||
{
|
||||
id = pNfo->GetID();
|
||||
if (WildcardMatch(sPlrName.getData(), pNfo->GetName())) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
// no player name: Set local player
|
||||
pNfo = Game.PlayerInfos.GetPrimaryInfoByClientID(idLocalClient);
|
||||
C4ClientPlayerInfos *pCltNfo=NULL;
|
||||
if (pNfo) pCltNfo = Game.PlayerInfos.GetClientInfoByPlayerID(pNfo->GetID());
|
||||
if (!pCltNfo)
|
||||
{
|
||||
LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_NOPLAYER"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// may color of this client be set?
|
||||
if (pCltNfo->GetClientID() != idLocalClient && !::Network.isHost())
|
||||
{
|
||||
LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_NOACCESS"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// get color to set
|
||||
uint32_t dwNewClr;
|
||||
if (sscanf(szPar, "%x", &dwNewClr) != 1)
|
||||
{
|
||||
LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_USAGE"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// color validation
|
||||
dwNewClr |= 0xff000000;
|
||||
if (!dwNewClr) ++dwNewClr;
|
||||
// request a color change to this color
|
||||
C4ClientPlayerInfos LocalInfoRequest = *pCltNfo;
|
||||
C4PlayerInfo *pPlrInfo = LocalInfoRequest.GetPlayerInfoByID(pNfo->GetID());
|
||||
assert(pPlrInfo);
|
||||
if (pPlrInfo)
|
||||
{
|
||||
pPlrInfo->SetOriginalColor(dwNewClr); // set this as a new color wish
|
||||
::Network.Players.RequestPlayerInfoUpdate(LocalInfoRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------
|
||||
else if (SEqualNoCase(Command, "/start"))
|
||||
{
|
||||
// timeout given?
|
||||
int32_t iTimeout = Config.Lobby.CountdownTime;
|
||||
if (!::Network.isHost())
|
||||
LobbyError(LoadResStr("IDS_MSG_CMD_HOSTONLY"));
|
||||
else if (szPar && *szPar && (!sscanf(szPar, "%d", &iTimeout) || iTimeout<0))
|
||||
LobbyError(LoadResStr("IDS_MSG_CMD_START_USAGE"));
|
||||
else
|
||||
{
|
||||
// abort previous countdown
|
||||
if (eCountdownState) ::Network.AbortLobbyCountdown();
|
||||
// start new countdown (aborts previous if necessary)
|
||||
Start(iTimeout);
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------
|
||||
else if (SEqualNoCase(Command, "/abort"))
|
||||
{
|
||||
if (!::Network.isHost())
|
||||
LobbyError(LoadResStr("IDS_MSG_CMD_HOSTONLY"));
|
||||
else if (eCountdownState)
|
||||
::Network.AbortLobbyCountdown();
|
||||
else
|
||||
LobbyError(LoadResStr("IDS_MSG_CMD_ABORT_NOCOUNTDOWN"));
|
||||
}
|
||||
// ------------------------------------------------------
|
||||
else if (SEqualNoCase(Command, "/help"))
|
||||
{
|
||||
Log(LoadResStr("IDS_TEXT_COMMANDSAVAILABLEDURINGLO"));
|
||||
LogF("/start [time] - %s", LoadResStr("IDS_TEXT_STARTTHEROUNDWITHSPECIFIE"));
|
||||
LogF("/abort - %s", LoadResStr("IDS_TEXT_ABORTSTARTCOUNTDOWN"));
|
||||
LogF("/alert - %s", LoadResStr("IDS_TEXT_ALERTTHEHOSTIFTHEHOSTISAW"));
|
||||
LogF("/joinplr [filename] - %s", LoadResStr("IDS_TEXT_JOINALOCALPLAYERFROMTHESP"));
|
||||
LogF("/kick [client] - %s", LoadResStr("IDS_TEXT_KICKTHESPECIFIEDCLIENT"));
|
||||
LogF("/observer [client] - %s", LoadResStr("IDS_TEXT_SETTHESPECIFIEDCLIENTTOOB"));
|
||||
LogF("/me [action] - %s", LoadResStr("IDS_TEXT_PERFORMANACTIONINYOURNAME"));
|
||||
LogF("/sound [sound] - %s", LoadResStr("IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO"));
|
||||
LogF("/team [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOYOUR"));
|
||||
LogF("/plrclr [player] [RGB] - %s", LoadResStr("IDS_TEXT_CHANGETHECOLOROFTHESPECIF"));
|
||||
LogF("/plrclr [RGB] - %s", LoadResStr("IDS_TEXT_CHANGEYOUROWNPLAYERCOLOR"));
|
||||
LogF("/set comment [comment] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKCOMMENT"));
|
||||
LogF("/set password [password] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKPASSWORD"));
|
||||
LogF("/set maxplayer [number] - %s", LoadResStr("IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA"));
|
||||
LogF("/clear - %s", LoadResStr("IDS_MSG_CLEARTHEMESSAGEBOARD"));
|
||||
}
|
||||
// ------------------------------------------------------
|
||||
else
|
||||
{
|
||||
// command not known or not a specific lobby command - forward to messageinput
|
||||
fProcessed = false;
|
||||
}
|
||||
}
|
||||
// not processed? Then forward to messageinput, which parses additional commands and sends regular messages
|
||||
if (!fProcessed) ::MessageInput.ProcessInput(szInputText);
|
||||
::MessageInput.ProcessInput(szInputText);
|
||||
}
|
||||
// clear edit field after text has been processed
|
||||
pEdt->SelectAll(); pEdt->DeleteSelection();
|
||||
|
@ -862,6 +705,7 @@ namespace C4GameLobby
|
|||
// get lobby
|
||||
MainDlg *pLobby = ::Network.GetLobby();
|
||||
if (pLobby) pLobby->OnError(szErrorMsg);
|
||||
else Log(szErrorMsg);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -132,7 +132,6 @@ namespace C4GameLobby
|
|||
|
||||
private:
|
||||
void SetCountdownState(CountdownState eToState, int32_t iTimer);
|
||||
void Start(int32_t iCountdownTime); // host only: Do game start with specified countdown time (forwards to network system)
|
||||
int32_t ValidatedCountdownTime(int32_t iTimeout); // correct invalid timeout settings
|
||||
|
||||
void UpdatePlayerList();
|
||||
|
@ -156,6 +155,7 @@ namespace C4GameLobby
|
|||
void OnCountdownPacket(const C4PacketCountdown &Pkt); // called when a countdown packet is received: Update countdown state
|
||||
|
||||
bool IsCountdown();
|
||||
void Start(int32_t iCountdownTime); // host only: Do game start with specified countdown time (forwards to network system)
|
||||
void UpdatePassword();
|
||||
void ClearLog();
|
||||
};
|
||||
|
|
|
@ -445,30 +445,159 @@ bool C4MessageInput::ProcessCommand(const char *szCommand)
|
|||
{
|
||||
C4GameLobby::MainDlg *pLobby = ::Network.GetLobby();
|
||||
// command
|
||||
char szCmdName[C4MaxName + 1];
|
||||
SCopyUntil(szCommand + 1, szCmdName, ' ', C4MaxName);
|
||||
// must be 1 char longer than the longest command only. If given commands are longer, they will be truncated, and such a command won't exist anyway
|
||||
const int32_t MaxCommandLen = 20;
|
||||
char szCmdName[MaxCommandLen + 1];
|
||||
SCopyUntil(szCommand + 1, szCmdName, ' ', MaxCommandLen);
|
||||
// parameter
|
||||
const char *pCmdPar = SSearch(szCommand, " ");
|
||||
if (!pCmdPar) pCmdPar = "";
|
||||
|
||||
// dev-scripts
|
||||
// CAUTION when implementing special commands (like /quit) here:
|
||||
// those must not be executed when text is pasted, because that could crash the GUI system
|
||||
// when there are additional lines to paste, but the edit field is destructed by the command
|
||||
|
||||
// lobby-only commands
|
||||
if (!Game.IsRunning && SEqualNoCase(szCmdName, "joinplr"))
|
||||
{
|
||||
// compose path from given filename
|
||||
StdStrBuf plrPath;
|
||||
plrPath.Format("%s%s", Config.General.UserDataPath, pCmdPar);
|
||||
// player join - check filename
|
||||
if (!ItemExists(plrPath.getData()))
|
||||
{
|
||||
C4GameLobby::LobbyError(FormatString(LoadResStr("IDS_MSG_CMD_JOINPLR_NOFILE"), plrPath.getData()).getData());
|
||||
}
|
||||
else
|
||||
::Network.Players.JoinLocalPlayer(plrPath.getData(), true);
|
||||
return true;
|
||||
}
|
||||
if (!Game.IsRunning && SEqualNoCase(szCmdName, "plrclr"))
|
||||
{
|
||||
// get player name from input text
|
||||
int iSepPos = SCharPos(' ', pCmdPar, 0);
|
||||
C4PlayerInfo *pNfo=NULL;
|
||||
int32_t idLocalClient = -1;
|
||||
if (::Network.Clients.GetLocal()) idLocalClient = ::Network.Clients.GetLocal()->getID();
|
||||
if (iSepPos>0)
|
||||
{
|
||||
// a player name is given: Parse it
|
||||
StdStrBuf sPlrName;
|
||||
sPlrName.Copy(pCmdPar, iSepPos);
|
||||
pCmdPar += iSepPos+1; int32_t id=0;
|
||||
while ((pNfo = Game.PlayerInfos.GetNextPlayerInfoByID(id)))
|
||||
{
|
||||
id = pNfo->GetID();
|
||||
if (WildcardMatch(sPlrName.getData(), pNfo->GetName())) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
// no player name: Set local player
|
||||
pNfo = Game.PlayerInfos.GetPrimaryInfoByClientID(idLocalClient);
|
||||
C4ClientPlayerInfos *pCltNfo=NULL;
|
||||
if (pNfo) pCltNfo = Game.PlayerInfos.GetClientInfoByPlayerID(pNfo->GetID());
|
||||
if (!pCltNfo)
|
||||
{
|
||||
C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_NOPLAYER"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// may color of this client be set?
|
||||
if (pCltNfo->GetClientID() != idLocalClient && !::Network.isHost())
|
||||
{
|
||||
C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_NOACCESS"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// get color to set
|
||||
uint32_t dwNewClr;
|
||||
if (sscanf(pCmdPar, "%x", &dwNewClr) != 1)
|
||||
{
|
||||
C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_PLRCLR_USAGE"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// color validation
|
||||
dwNewClr |= 0xff000000;
|
||||
if (!dwNewClr) ++dwNewClr;
|
||||
// request a color change to this color
|
||||
C4ClientPlayerInfos LocalInfoRequest = *pCltNfo;
|
||||
C4PlayerInfo *pPlrInfo = LocalInfoRequest.GetPlayerInfoByID(pNfo->GetID());
|
||||
assert(pPlrInfo);
|
||||
if (pPlrInfo)
|
||||
{
|
||||
pPlrInfo->SetOriginalColor(dwNewClr); // set this as a new color wish
|
||||
::Network.Players.RequestPlayerInfoUpdate(LocalInfoRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!Game.IsRunning && SEqualNoCase(szCmdName, "start"))
|
||||
{
|
||||
// timeout given?
|
||||
int32_t iTimeout = Config.Lobby.CountdownTime;
|
||||
if (!::Network.isHost())
|
||||
C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_HOSTONLY"));
|
||||
else if (pCmdPar && *pCmdPar && (!sscanf(pCmdPar, "%d", &iTimeout) || iTimeout<0))
|
||||
C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_START_USAGE"));
|
||||
else if (pLobby)
|
||||
{
|
||||
// abort previous countdown
|
||||
if (::Network.isLobbyCountDown()) ::Network.AbortLobbyCountdown();
|
||||
// start new countdown (aborts previous if necessary)
|
||||
pLobby->Start(iTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iTimeout)
|
||||
::Network.StartLobbyCountdown(iTimeout);
|
||||
else
|
||||
::Network.Start();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!Game.IsRunning && SEqualNoCase(szCmdName, "abort"))
|
||||
{
|
||||
if (!::Network.isHost())
|
||||
C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_HOSTONLY"));
|
||||
else if (::Network.isLobbyCountDown())
|
||||
::Network.AbortLobbyCountdown();
|
||||
else
|
||||
C4GameLobby::LobbyError(LoadResStr("IDS_MSG_CMD_ABORT_NOCOUNTDOWN"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SEqual(szCmdName, "help"))
|
||||
{
|
||||
Log(LoadResStr("IDS_TEXT_COMMANDSAVAILABLEDURINGGA"));
|
||||
LogF("/private [player] [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOTHES"));
|
||||
LogF("/team [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOYOUR"));
|
||||
LogF("/me [action] - %s", LoadResStr("IDS_TEXT_PERFORMANACTIONINYOURNAME"));
|
||||
LogF("/sound [sound] - %s", LoadResStr("IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO"));
|
||||
Log(LoadResStr(pLobby ? "IDS_TEXT_COMMANDSAVAILABLEDURINGLO" : "IDS_TEXT_COMMANDSAVAILABLEDURINGGA"));
|
||||
if (!Game.IsRunning)
|
||||
{
|
||||
LogF("/start [time] - %s", LoadResStr("IDS_TEXT_STARTTHEROUNDWITHSPECIFIE"));
|
||||
LogF("/abort - %s", LoadResStr("IDS_TEXT_ABORTSTARTCOUNTDOWN"));
|
||||
LogF("/alert - %s", LoadResStr("IDS_TEXT_ALERTTHEHOSTIFTHEHOSTISAW"));
|
||||
LogF("/joinplr [filename] - %s", LoadResStr("IDS_TEXT_JOINALOCALPLAYERFROMTHESP"));
|
||||
LogF("/plrclr [player] [RGB] - %s", LoadResStr("IDS_TEXT_CHANGETHECOLOROFTHESPECIF"));
|
||||
LogF("/plrclr [RGB] - %s", LoadResStr("IDS_TEXT_CHANGEYOUROWNPLAYERCOLOR"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LogF("/fast [x] - %s", LoadResStr("IDS_TEXT_SETTOFASTMODESKIPPINGXFRA"));
|
||||
LogF("/slow - %s", LoadResStr("IDS_TEXT_SETTONORMALSPEEDMODE"));
|
||||
LogF("/chart - %s", LoadResStr("IDS_TEXT_DISPLAYNETWORKSTATISTICS"));
|
||||
LogF("/nodebug - %s", LoadResStr("IDS_TEXT_PREVENTDEBUGMODEINTHISROU"));
|
||||
LogF("/script [script] - %s", LoadResStr("IDS_TEXT_EXECUTEASCRIPTCOMMAND"));
|
||||
}
|
||||
LogF("/kick [client] - %s", LoadResStr("IDS_TEXT_KICKTHESPECIFIEDCLIENT"));
|
||||
LogF("/observer [client] - %s", LoadResStr("IDS_TEXT_SETTHESPECIFIEDCLIENTTOOB"));
|
||||
LogF("/fast [x] - %s", LoadResStr("IDS_TEXT_SETTOFASTMODESKIPPINGXFRA"));
|
||||
LogF("/slow - %s", LoadResStr("IDS_TEXT_SETTONORMALSPEEDMODE"));
|
||||
LogF("/chart - %s", LoadResStr("IDS_TEXT_DISPLAYNETWORKSTATISTICS"));
|
||||
LogF("/nodebug - %s", LoadResStr("IDS_TEXT_PREVENTDEBUGMODEINTHISROU"));
|
||||
LogF("/me [action] - %s", LoadResStr("IDS_TEXT_PERFORMANACTIONINYOURNAME"));
|
||||
LogF("/sound [sound] - %s", LoadResStr("IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO"));
|
||||
if (Game.IsRunning) LogF("/private [player] [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOTHES"));
|
||||
LogF("/team [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOYOUR"));
|
||||
LogF("/set comment [comment] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKCOMMENT"));
|
||||
LogF("/set password [password] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKPASSWORD"));
|
||||
LogF("/set maxplayer [4] - %s", LoadResStr("IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA"));
|
||||
LogF("/script [script] - %s", LoadResStr("IDS_TEXT_EXECUTEASCRIPTCOMMAND"));
|
||||
LogF("/set maxplayer [number] - %s", LoadResStr("IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA"));
|
||||
LogF("/clear - %s", LoadResStr("IDS_MSG_CLEARTHEMESSAGEBOARD"));
|
||||
return true;
|
||||
}
|
||||
|
@ -645,12 +774,14 @@ bool C4MessageInput::ProcessCommand(const char *szCommand)
|
|||
}
|
||||
|
||||
// show chart
|
||||
if (Game.IsRunning) if (SEqual(szCmdName, "chart"))
|
||||
if (Game.IsRunning)
|
||||
if (SEqual(szCmdName, "chart"))
|
||||
return Game.ToggleChart();
|
||||
|
||||
// custom command
|
||||
C4MessageBoardCommand *pCmd;
|
||||
if (Game.IsRunning) if ((pCmd = GetCommand(szCmdName)))
|
||||
if (Game.IsRunning)
|
||||
if ((pCmd = GetCommand(szCmdName)))
|
||||
{
|
||||
StdStrBuf Script, CmdScript;
|
||||
// replace %player% by calling player number
|
||||
|
|
|
@ -298,6 +298,7 @@ public:
|
|||
// lobby countdown
|
||||
void StartLobbyCountdown(int32_t iCountdownTime);
|
||||
void AbortLobbyCountdown();
|
||||
bool isLobbyCountDown() { return pLobbyCountdown != 0; }
|
||||
|
||||
// streaming
|
||||
size_t getPendingStreamData() const { return StreamingBuf.getSize() - StreamCompressor.avail_out; }
|
||||
|
|
Loading…
Reference in New Issue