Browse Source

Removed all Beta 1/2/3 code; removed all eXtendedRCON code; Added Server::Kill().

pull/3/head v0.14.1
JustinAJ 10 years ago
parent
commit
aa830819bd
  1. BIN
      Release/Plugins/RenX.Core.lib
  2. 2
      RenX.Core/RenX.Core.vcxproj
  3. 6
      RenX.Core/RenX.Core.vcxproj.filters
  4. 10
      RenX.Core/RenX_Plugin.cpp
  5. 4
      RenX.Core/RenX_Plugin.h
  6. 723
      RenX.Core/RenX_Server.cpp
  7. 68
      RenX.Core/RenX_Server.h
  8. 73
      RenX.Core/RenX_ServerProfile.cpp
  9. 51
      RenX.Core/RenX_ServerProfile.h
  10. 4
      RenX.Core/RenX_Tags.cpp
  11. 2
      RenX.Core/RenX_Tags.h
  12. 47
      RenX.Logging/RenX_Logging.cpp
  13. 7
      RenX.Logging/RenX_Logging.h

BIN
Release/Plugins/RenX.Core.lib

Binary file not shown.

2
RenX.Core/RenX.Core.vcxproj

@ -78,7 +78,6 @@
<ClInclude Include="RenX_PlayerInfo.h" /> <ClInclude Include="RenX_PlayerInfo.h" />
<ClInclude Include="RenX_Plugin.h" /> <ClInclude Include="RenX_Plugin.h" />
<ClInclude Include="RenX_Server.h" /> <ClInclude Include="RenX_Server.h" />
<ClInclude Include="RenX_ServerProfile.h" />
<ClInclude Include="RenX_Tags.h" /> <ClInclude Include="RenX_Tags.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -88,7 +87,6 @@
<ClCompile Include="RenX_GameCommand.cpp" /> <ClCompile Include="RenX_GameCommand.cpp" />
<ClCompile Include="RenX_Plugin.cpp" /> <ClCompile Include="RenX_Plugin.cpp" />
<ClCompile Include="RenX_Server.cpp" /> <ClCompile Include="RenX_Server.cpp" />
<ClCompile Include="RenX_ServerProfile.cpp" />
<ClCompile Include="RenX_Tags.cpp" /> <ClCompile Include="RenX_Tags.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

6
RenX.Core/RenX.Core.vcxproj.filters

@ -44,9 +44,6 @@
<ClInclude Include="RenX_GameCommand.h"> <ClInclude Include="RenX_GameCommand.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="RenX_ServerProfile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RenX_BanDatabase.h"> <ClInclude Include="RenX_BanDatabase.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -70,9 +67,6 @@
<ClCompile Include="RenX_GameCommand.cpp"> <ClCompile Include="RenX_GameCommand.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="RenX_ServerProfile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RenX_BanDatabase.cpp"> <ClCompile Include="RenX_BanDatabase.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

10
RenX.Core/RenX_Plugin.cpp

@ -430,16 +430,6 @@ void RenX::Plugin::RenX_OnLog(Server *, const Jupiter::ReadableString &)
return; return;
} }
void RenX::Plugin::RenX_XOnVersion(Server *, unsigned int)
{
return;
}
void RenX::Plugin::RenX_XOnOther(Server *, const Jupiter::ReadableString &)
{
return;
}
void RenX::Plugin::RenX_OnCommand(Server *, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnCommand(Server *, const Jupiter::ReadableString &)
{ {
return; return;

4
RenX.Core/RenX_Plugin.h

@ -139,10 +139,6 @@ namespace RenX
/** Other Logs */ /** Other Logs */
virtual void RenX_OnLog(Server *server, const Jupiter::ReadableString &raw); virtual void RenX_OnLog(Server *server, const Jupiter::ReadableString &raw);
/** eXtended RCON */
virtual void RenX_XOnVersion(Server *server, unsigned int version);
virtual void RenX_XOnOther(Server *server, const Jupiter::ReadableString &raw);
/** Command type */ /** Command type */
virtual void RenX_OnCommand(Server *server, const Jupiter::ReadableString &raw); virtual void RenX_OnCommand(Server *server, const Jupiter::ReadableString &raw);

723
RenX.Core/RenX_Server.cpp

@ -174,46 +174,30 @@ int RenX::Server::sendMessage(const Jupiter::ReadableString &message)
if (RenX::Server::neverSay) if (RenX::Server::neverSay)
{ {
int r = 0; int r = 0;
if (RenX::Server::profile->privateMessages && RenX::Server::players.size() != 0) if (RenX::Server::players.size() != 0)
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = RenX::Server::players.getNode(0); node != nullptr; node = node->next) for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = RenX::Server::players.getNode(0); node != nullptr; node = node->next)
if (node->data->isBot == false) if (node->data->isBot == false)
{ r += RenX::Server::sock.send(Jupiter::StringS::Format("chostprivatesay pid%d %.*s\n", node->data->id, message.size(), message.ptr()));
if (RenX::Server::rconVersion <= 2)
r += RenX::Server::sock.send(Jupiter::StringS::Format("cevaprivatesay pid%d %.*s\n", node->data->id, message.size(), message.ptr()));
else
r += RenX::Server::sock.send(Jupiter::StringS::Format("chostprivatesay pid%d %.*s\n", node->data->id, message.size(), message.ptr()));
}
return r; return r;
} }
else else
{ {
Jupiter::StringS cmd = STRING_LITERAL_AS_REFERENCE("chostsay "); Jupiter::StringS cmd = STRING_LITERAL_AS_REFERENCE("chostsay ");
if (RenX::Server::rconVersion <= 2)
cmd = STRING_LITERAL_AS_REFERENCE("csay ");
cmd += message; cmd += message;
cmd += '\n'; cmd += '\n';
if (RenX::Server::profile->mustSanitize)
RenX::sanitizeString(cmd);
return RenX::Server::sock.send(cmd); return RenX::Server::sock.send(cmd);
} }
} }
int RenX::Server::sendMessage(const RenX::PlayerInfo *player, const Jupiter::ReadableString &message) int RenX::Server::sendMessage(const RenX::PlayerInfo *player, const Jupiter::ReadableString &message)
{ {
if (RenX::Server::profile->privateMessages == false)
return RenX::Server::sendMessage(message);
Jupiter::String cmd(message.size() + 28); Jupiter::String cmd(message.size() + 28);
if (RenX::Server::rconVersion <= 2) cmd = STRING_LITERAL_AS_REFERENCE("chostprivatesay pid");
cmd = STRING_LITERAL_AS_REFERENCE("cevaprivatesay pid");
else
cmd = STRING_LITERAL_AS_REFERENCE("chostprivatesay pid");
cmd += Jupiter::StringS::Format("%d ", player->id); cmd += Jupiter::StringS::Format("%d ", player->id);
cmd += message; cmd += message;
cmd += '\n'; cmd += '\n';
RenX::sanitizeString(cmd); RenX::sanitizeString(cmd);
return RenX::Server::sock.send(cmd); return RenX::Server::sock.send(cmd);
//return RenX::Server::sock.send(Jupiter::StringS::Format("cevaprivatesay pid%d %.*s\n", player->id, message.size(), message.ptr()));
//return RenX::Server::sock.send(Jupiter::StringS::Format("chostprivatesay pid%d %.*s\n", player->id, message.size(), message.ptr())); //return RenX::Server::sock.send(Jupiter::StringS::Format("chostprivatesay pid%d %.*s\n", player->id, message.size(), message.ptr()));
} }
@ -304,30 +288,18 @@ Jupiter::StringS RenX::Server::formatSteamID(uint64_t id) const
void RenX::Server::kickPlayer(int id) void RenX::Server::kickPlayer(int id)
{ {
RenX::Server::sock.send(Jupiter::StringS::Format(this->rconVersion >= 3 ? "ckick pid%d\n" : "cadminkick pid%d\n", id)); RenX::Server::sock.send(Jupiter::StringS::Format("ckick pid%d\n", id));
} }
void RenX::Server::kickPlayer(const RenX::PlayerInfo *player) void RenX::Server::kickPlayer(const RenX::PlayerInfo *player)
{ {
if (this->profile->pidbug) RenX::Server::kickPlayer(player->id);
{
if (player->isBot)
RenX::Server::sock.send(Jupiter::StringS::Format("cadminkick %.*s\n", player->name.size(), player->name.ptr()));
else if (player->id < 1000)
RenX::Server::kickPlayer(player->id);
else if (player->name.contains('|') == false)
RenX::Server::sock.send(Jupiter::StringS::Format("cadminkick %.*s\n", player->name.size(), player->name.ptr()));
else
RenX::Server::kickPlayer(player->id);
}
else
RenX::Server::kickPlayer(player->id);
} }
void RenX::Server::banPlayer(int id) void RenX::Server::banPlayer(int id)
{ {
if (RenX::Server::rconBan) if (RenX::Server::rconBan)
RenX::Server::sock.send(Jupiter::StringS::Format(this->rconVersion >= 3 ? "ckickban pid%d\n" : "cadminkickban pid%d\n", id)); RenX::Server::sock.send(Jupiter::StringS::Format("ckickban pid%d\n", id));
else else
{ {
RenX::PlayerInfo *player = RenX::Server::getPlayer(id); RenX::PlayerInfo *player = RenX::Server::getPlayer(id);
@ -339,23 +311,10 @@ void RenX::Server::banPlayer(int id)
void RenX::Server::banPlayer(const RenX::PlayerInfo *player, time_t length) void RenX::Server::banPlayer(const RenX::PlayerInfo *player, time_t length)
{ {
if (RenX::Server::rconBan && length == 0) if (RenX::Server::rconBan && length == 0)
{ RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban pid%d\n", player->id));
if (this->profile->pidbug)
{
if (player->isBot)
RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban %.*s\n", player->name.size(), player->name.ptr()));
else if (player->id < 1000)
RenX::Server::banPlayer(player->id);
else if (player->name.contains('|') == false)
RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban %.*s\n", player->name.size(), player->name.ptr()));
else
RenX::Server::banPlayer(player->id);
}
else
RenX::Server::sock.send(Jupiter::StringS::Format("cadminkickban pid%d\n", player->id));
}
else else
RenX::Server::kickPlayer(player); RenX::Server::kickPlayer(player);
if (RenX::Server::localBan) if (RenX::Server::localBan)
RenX::banDatabase->add(this, player, length); RenX::banDatabase->add(this, player, length);
} }
@ -385,39 +344,33 @@ bool RenX::Server::removePlayer(RenX::PlayerInfo *player)
bool RenX::Server::updateClientList() bool RenX::Server::updateClientList()
{ {
if (RenX::Server::xRconVersion != 0)
return RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("_x\x01\n")) > 0;
if (RenX::Server::rconVersion <= 2)
return RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("clogclientlist\n")) > 0;
return RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("cclientvarlist KILLS\xA0""DEATHS\xA0""SCORE\xA0""CREDITS\xA0""CHARACTER\xA0""VEHICLE\xA0""PING\xA0""ADMIN\xA0""STEAM\xA0""IP\xA0""PLAYERLOG\n")) > 0 return RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("cclientvarlist KILLS\xA0""DEATHS\xA0""SCORE\xA0""CREDITS\xA0""CHARACTER\xA0""VEHICLE\xA0""PING\xA0""ADMIN\xA0""STEAM\xA0""IP\xA0""PLAYERLOG\n")) > 0
&& RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("cbotvarlist KILLS\xA0""DEATHS\xA0""SCORE\xA0""CREDITS\xA0""CHARACTER\xA0""VEHICLE\xA0""PLAYERLOG\n")); && RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("cbotvarlist KILLS\xA0""DEATHS\xA0""SCORE\xA0""CREDITS\xA0""CHARACTER\xA0""VEHICLE\xA0""PLAYERLOG\n")) > 0;
//return RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("cclientlist\n")) > 0; //return RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("cclientlist\n")) > 0;
} }
bool RenX::Server::gameover() bool RenX::Server::gameover()
{ {
return RenX::Server::rconVersion >= 3 && RenX::Server::send(STRING_LITERAL_AS_REFERENCE("endmap")) > 0; return RenX::Server::send(STRING_LITERAL_AS_REFERENCE("endmap")) > 0;
} }
bool RenX::Server::setMap(const Jupiter::ReadableString &map) bool RenX::Server::setMap(const Jupiter::ReadableString &map)
{ {
return RenX::Server::rconVersion >= 3 && RenX::Server::send(Jupiter::StringS::Format("changemap %.*s", map.size(), map.ptr())) > 0; return RenX::Server::send(Jupiter::StringS::Format("changemap %.*s", map.size(), map.ptr())) > 0;
} }
bool RenX::Server::loadMutator(const Jupiter::ReadableString &mutator) bool RenX::Server::loadMutator(const Jupiter::ReadableString &mutator)
{ {
return RenX::Server::rconVersion >= 3 && RenX::Server::send(Jupiter::StringS::Format("loadmutator %.*s", mutator.size(), mutator.ptr())) > 0; return RenX::Server::send(Jupiter::StringS::Format("loadmutator %.*s", mutator.size(), mutator.ptr())) > 0;
} }
bool RenX::Server::unloadMutator(const Jupiter::ReadableString &mutator) bool RenX::Server::unloadMutator(const Jupiter::ReadableString &mutator)
{ {
return RenX::Server::rconVersion >= 3 && RenX::Server::send(Jupiter::StringS::Format("unloadmutator %.*s", mutator.size(), mutator.ptr())) > 0; return RenX::Server::send(Jupiter::StringS::Format("unloadmutator %.*s", mutator.size(), mutator.ptr())) > 0;
} }
bool RenX::Server::cancelVote(const RenX::TeamType team) bool RenX::Server::cancelVote(const RenX::TeamType team)
{ {
if (RenX::Server::rconVersion < 3)
return false;
switch (team) switch (team)
{ {
default: default:
@ -431,28 +384,27 @@ bool RenX::Server::cancelVote(const RenX::TeamType team)
bool RenX::Server::swapTeams() bool RenX::Server::swapTeams()
{ {
return RenX::Server::rconVersion >= 3 && RenX::Server::send(STRING_LITERAL_AS_REFERENCE("swapteams")) > 0; return RenX::Server::send(STRING_LITERAL_AS_REFERENCE("swapteams")) > 0;
} }
bool RenX::Server::recordDemo() bool RenX::Server::recordDemo()
{ {
return RenX::Server::rconVersion >= 3 && RenX::Server::send(STRING_LITERAL_AS_REFERENCE("recorddemo")) > 0; return RenX::Server::send(STRING_LITERAL_AS_REFERENCE("recorddemo")) > 0;
} }
bool RenX::Server::mute(const RenX::PlayerInfo *player) bool RenX::Server::mute(const RenX::PlayerInfo *player)
{ {
return RenX::Server::rconVersion >= 3 && RenX::Server::send(Jupiter::StringS::Format("textmute pid%u", player->id)) > 0; return RenX::Server::send(Jupiter::StringS::Format("textmute pid%u", player->id)) > 0;
} }
bool RenX::Server::unmute(const RenX::PlayerInfo *player) bool RenX::Server::unmute(const RenX::PlayerInfo *player)
{ {
return RenX::Server::rconVersion >= 3 && RenX::Server::send(Jupiter::StringS::Format("textunmute pid%u", player->id)) > 0; return RenX::Server::send(Jupiter::StringS::Format("textunmute pid%u", player->id)) > 0;
} }
bool RenX::Server::giveCredits(int id, double credits) bool RenX::Server::giveCredits(int id, double credits)
{ {
return (RenX::Server::xRconVersion != 0 && RenX::Server::sock.send(Jupiter::StringS::Format("_x\x04%d%c%.4f\n", id, RenX::DelimC, credits)) > 0) return RenX::Server::send(Jupiter::StringS::Format("givecredits pid%d %f", id, credits)) > 0;
|| (RenX::Server::rconVersion >= 3 && RenX::Server::send(Jupiter::StringS::Format("givecredits pid%d %f", id, credits)) > 0);
} }
bool RenX::Server::giveCredits(RenX::PlayerInfo *player, double credits) bool RenX::Server::giveCredits(RenX::PlayerInfo *player, double credits)
@ -460,29 +412,24 @@ bool RenX::Server::giveCredits(RenX::PlayerInfo *player, double credits)
return RenX::Server::giveCredits(player->id, credits); return RenX::Server::giveCredits(player->id, credits);
} }
bool RenX::Server::changeTeam(int id, bool resetCredits) bool RenX::Server::kill(int id)
{ {
if (resetCredits) return RenX::Server::send(Jupiter::StringS::Format("kill pid%d", id)) > 0;
return (RenX::Server::xRconVersion != 0 && RenX::Server::sock.send(Jupiter::StringS::Format("_x\x07%d%c\x03\n", id, RenX::DelimC)) > 0)
|| (RenX::Server::rconVersion >= 3 && RenX::Server::send(Jupiter::StringS::Format("team pid%d", id)) > 0);
else
return (RenX::Server::xRconVersion != 0 && RenX::Server::sock.send(Jupiter::StringS::Format("_x\x07%d%c\x01\n", id, RenX::DelimC)) > 0)
|| (RenX::Server::rconVersion >= 3 && RenX::Server::send(Jupiter::StringS::Format("team2 pid%d", id)) > 0);
} }
bool RenX::Server::changeTeam(RenX::PlayerInfo *player, bool resetCredits) bool RenX::Server::kill(RenX::PlayerInfo *player)
{ {
return RenX::Server::changeTeam(player->id, resetCredits); return RenX::Server::kill(player->id);
} }
bool RenX::Server::setTeam(int id, int team, unsigned char options) bool RenX::Server::changeTeam(int id, bool resetCredits)
{ {
return RenX::Server::xRconVersion != 0 && RenX::Server::sock.send(Jupiter::StringS::Format("_x\x07%d%c%c%c%d\n", id, RenX::DelimC, options, RenX::DelimC, team)) > 0; return RenX::Server::send(Jupiter::StringS::Format(resetCredits ? "team pid%d" : "team2 pid%d", id)) > 0;
} }
bool RenX::Server::setTeam(RenX::PlayerInfo *player, int team, unsigned char options) bool RenX::Server::changeTeam(RenX::PlayerInfo *player, bool resetCredits)
{ {
return RenX::Server::setTeam(player->id, team, options); return RenX::Server::changeTeam(player->id, resetCredits);
} }
const Jupiter::ReadableString &RenX::Server::getPrefix() const const Jupiter::ReadableString &RenX::Server::getPrefix() const
@ -2021,581 +1968,6 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
buff.shiftLeft(1); buff.shiftLeft(1);
} }
} }
else // RCONv2
{
Jupiter::ReferenceString playerData = buff.getToken(1, RenX::DelimC);
Jupiter::ReferenceString action = buff.getToken(2, RenX::DelimC);
if (header.equals("lGAME:"))
{
if (action.equals("deployed"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
Jupiter::ReferenceString objectType = buff.getToken(3, RenX::DelimC);
if (objectType.match("*Beacon"))
player->beaconPlacements++;
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnDeploy(this, player, objectType);
onAction();
}
else if (action.equals("suicided by"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
player->deaths++;
player->suicides++;
Jupiter::ReferenceString damageType = buff.getToken(3, RenX::DelimC);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnSuicide(this, player, damageType);
this->firstDeath = true;
onAction();
}
else if (action.equals("killed"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
Jupiter::ReferenceString victimData = buff.getToken(3, RenX::DelimC);
Jupiter::ReferenceString vidToken = victimData.getToken(1, ',');
if (vidToken.size() != 0)
{
Jupiter::ReferenceString vname = victimData.getToken(2, ',');
int vid;
bool visBot = false;
if (vidToken[0] == 'b')
{
vidToken.shiftRight(1);
visBot = true;
}
vid = vidToken.asInt(10);
TeamType vteam = RenX::getTeam(victimData.getToken(0, ','));
Jupiter::ReferenceString damageType = buff.getToken(5, RenX::DelimC);
RenX::PlayerInfo *victim = getPlayerOrAdd(vname, vid, vteam, visBot, 0, Jupiter::ReferenceString::empty);
player->kills++;
if (damageType.equals("Rx_DmgType_Headshot")) player->headshots++;
victim->deaths++;
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnKill(this, player, victim, damageType);
}
if (this->needsCList)
{
this->updateClientList();
this->needsCList = false;
}
this->firstKill = true;
this->firstDeath = true;
onAction();
}
else if (action.match("died by"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
player->deaths++;
Jupiter::ReferenceString damageType = buff.getToken(3, RenX::DelimC);
if (damageType.equals("DamageType"))
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnTeamChange(this, player, RenX::getEnemy(player->team));
else
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnDie(this, player, damageType);
this->firstDeath = true;
onAction();
}
else if (action.match("destroyed*"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
Jupiter::ReferenceString victim = buff.getToken(3, RenX::DelimC);
Jupiter::ReferenceString damageType = buff.getToken(5, RenX::DelimC);
ObjectType type;
if (action.equals("destroyed building"))
{
type = ObjectType::Building;
player->buildingKills++;
}
else if (victim.match("Rx_Defence_*"))
{
type = ObjectType::Defence;
player->defenceKills++;
}
else
{
type = ObjectType::Vehicle;
player->vehicleKills++;
}
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnDestroy(this, player, victim, RenX::getEnemy(player->team), damageType, type);
onAction();
}
else if (playerData.match("??? wins (*)"))
{
TeamType team = RenX::getTeam(playerData.getToken(0, ' '));
int gScore = buff.getToken(2, RenX::DelimC).gotoToken(1, '=').asInt(10);
int nScore = buff.getToken(3, RenX::DelimC).gotoToken(1, '=').asInt(10);
Jupiter::ReferenceString winType = Jupiter::ReferenceString::substring(playerData, 10);
winType.truncate(1);
WinType iWinType = WinType::Unknown;
if (gScore == nScore)
iWinType = WinType::Tie;
else if (winType.equals("TimeLimit"))
iWinType = WinType::Score;
else if (winType.equals("Buildings"))
iWinType = WinType::Base;
this->needsCList = true;
if (!this->seamless)
this->silenceParts = true;
onPreGameOver(iWinType, team, gScore, nScore);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnGameOver(this, iWinType, team, gScore, nScore);
onPostGameOver(iWinType, team, gScore, nScore);
}
else if (playerData.equals("Tie"))
{
int gScore;
switch (RenX::Server::profile->tieFormat)
{
default:
case 1:
gScore = buff.getToken(2, RenX::DelimC).gotoToken(1, '=').asInt(10);
break;
case 0:
gScore = action.gotoToken(1, '=').asInt(10);
break;
}
int nScore = buff.getToken(3, RenX::DelimC).gotoToken(1, '=').asInt(10);
this->needsCList = true;
if (!this->seamless)
this->silenceParts = true;
if (gScore == nScore)
{
onPreGameOver(WinType::Tie, TeamType::Other, gScore, nScore);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnGameOver(this, WinType::Tie, TeamType::Other, gScore, nScore);
onPostGameOver(WinType::Tie, TeamType::Other, gScore, nScore);
}
else
{
TeamType winTeam = gScore > nScore ? RenX::getTeam(0) : RenX::getTeam(1);
onPreGameOver(WinType::Shutdown, winTeam, gScore, nScore);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnGameOver(this, WinType::Shutdown, winTeam, gScore, nScore);
onPostGameOver(WinType::Shutdown, winTeam, gScore, nScore);
}
}
else
{
Jupiter::ReferenceString raw = buff.gotoToken(1, RenX::DelimC);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnGame(this, raw);
}
}
else if (header.equals("lCHAT:"))
{
if (action.equals("teamsay:"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
Jupiter::ReferenceString message = buff.getToken(3, RenX::DelimC);
onChat(player, message);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnTeamChat(this, player, message);
}
else if (action.equals("say:"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
Jupiter::ReferenceString message = buff.getToken(3, RenX::DelimC);
onChat(player, message);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnChat(this, player, message);
}
onAction();
}
else if (header.equals("lPLAYER:"))
{
if (action.equals("disconnected"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
if (this->silenceParts == false)
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnPart(this, player);
this->removePlayer(player);
}
else if (action.equals("entered from"))
{
PARSE_PLAYER_DATA_P(playerData);
RenX::PlayerInfo *player = getPlayerOrAdd(name, id, team, isBot, buff.getToken(4, RenX::DelimC).equals("steamid") ? buff.getToken(5, RenX::DelimC).asUnsignedLongLong() : 0, buff.getToken(3, RenX::DelimC));
if (this->silenceJoins == false)
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnJoin(this, player);
}
else if (action.equals("changed name to:"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
Jupiter::ReferenceString newName = buff.getToken(3, RenX::DelimC);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnNameChange(this, player, newName);
setPlayerName(player, newName);
onAction();
}
}
else if (header.equals("lRCON:"))
{
if (action.equals("executed:"))
{
Jupiter::ReferenceString command = buff.getToken(3, RenX::DelimC);
Jupiter::ReferenceString cmd = command.getWord(0, " ");
if (cmd.equalsi("say"))
{
Jupiter::ReferenceString message = command.gotoWord(1, " ");
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnHostChat(this, message);
}
else if (cmd.equalsi("evaprivatesay"))
{
RenX::PlayerInfo *player = this->getPlayerByName(command.getWord(1, " "));
if (player != nullptr)
{
Jupiter::ReferenceString message = command.gotoWord(2, " ");
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnHostPage(this, player, message);
}
else
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnExecute(this, playerData, command);
}
else
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnExecute(this, playerData, command);
}
else if (action.equals("subscribed"))
{
if (this->rconUser.isEmpty())
this->rconUser = playerData;
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnSubscribe(this, playerData);
}
else
{
Jupiter::ReferenceString raw = buff.gotoToken(1, RenX::DelimC);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnRCON(this, raw);
}
}
else if (header.equals("lADMIN:"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData);
if (action.equals("logged in as"))
{
player->adminType = buff.getToken(3, RenX::DelimC);
if (player->adminType.equalsi("moderator") && player->access < 1)
player->access = 1;
else if (player->adminType.equalsi("administrator") && player->access < 2)
player->access = 2;
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnAdminLogin(this, player);
}
else if (action.equals("logged out of"))
{
Jupiter::ReferenceString type = buff.getToken(3, RenX::DelimC);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnAdminLogout(this, player);
player->adminType = "";
player->access = 0;
}
else if (action.equals("granted"))
{
player->adminType = buff.getToken(3, RenX::DelimC);
if (player->adminType.equalsi("moderator") && player->access < 1)
player->access = 1;
else if (player->adminType.equalsi("administrator") && player->access < 2)
player->access = 2;
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnAdminGrant(this, player);
}
else
{
Jupiter::ReferenceString raw = buff.gotoToken(1, RenX::DelimC);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnAdmin(this, raw);
}
}
else if (header.equals("lC-LIST:"))
{
// ID IP SteamID Team Name
if (playerData.isEmpty())
break;
static const Jupiter::ReferenceString CListDelim = STRING_LITERAL_AS_REFERENCE(" ");
int id;
bool isBot = false;
if (playerData.get(0) == 'b')
{
isBot = true;
playerData.shiftRight(1);
id = playerData.asInt(10);
playerData.shiftLeft(1);
}
else id = playerData.asInt(10);
Jupiter::ReferenceString ip = playerData.getToken(1, CListDelim);
Jupiter::ReferenceString steamid = playerData.getToken(2, CListDelim);
RenX::TeamType team;
Jupiter::ReferenceString name;
if (steamid.equals("-----NO")) // RCONv2-2a
{
steamid = "";
team = getTeam(playerData.getToken(4, CListDelim));
name = playerData.gotoToken(5, CListDelim);
}
else
{
if (steamid.equals("-----NO-STEAM-----")) // RCONv2-2.5a
steamid = "";
team = getTeam(playerData.getToken(3, CListDelim));
name = playerData.gotoToken(4, CListDelim);
}
RenX::PlayerInfo *player = getPlayerOrAdd(name, id, team, isBot, steamid.asUnsignedLongLong(), ip);
}
else
{
buff.shiftRight(1);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnLog(this, buff);
buff.shiftLeft(1);
}
}
break;
case 'x':
header.shiftRight(1);
if (header.size() == 0)
{
header.shiftLeft(1);
break;
}
if (header[0] == 'r') // Command response
{
if (header.size() == 1)
{
header.shiftLeft(1);
break;
}
header.shiftRight(1);
switch (header[0])
{
case 1: // Client list: Normal Player Data | IP | Steam ID | Start Time | Ping | Kills | Deaths | Score | Credits | Class
header.shiftRight(1);
{
PARSE_PLAYER_DATA_P(header);
PlayerInfo *player = getPlayerOrAdd(name, id, team, isBot, buff.getToken(1, RenX::DelimC).asUnsignedLongLong(0), buff.getToken(2, RenX::DelimC));
player->ping = buff.getToken(4, RenX::DelimC).asUnsignedInt() * 4;
player->kills = buff.getToken(5, RenX::DelimC).asUnsignedInt();
player->deaths = buff.getToken(6, RenX::DelimC).asUnsignedInt();
player->score = static_cast<float>(buff.getToken(7, RenX::DelimC).asDouble());
player->credits = static_cast<float>(buff.getToken(8, RenX::DelimC).asDouble());
player->character = RenX::getCharacter(buff.getToken(9, RenX::DelimC));
}
header.shiftLeft(1);
break;
case 2: // Ping, Score, Credits list: Normal Player Data | Ping | Score | Credits
header.shiftRight(1);
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(header);
player->ping = buff.getToken(1, RenX::DelimC).asUnsignedInt();
player->score = static_cast<float>(buff.getToken(2, RenX::DelimC).asDouble());
player->credits = static_cast<float>(buff.getToken(3, RenX::DelimC).asDouble());
}
header.shiftLeft(1);
break;
case 3: // Echo: Data
break;
case 4: // Add Credits: Normal Player Data | Credits
header.shiftRight(1);
parseGetPlayerOrAdd(header)->credits = static_cast<float>(buff.getToken(1, RenX::DelimC).asDouble());
header.shiftLeft(1);
break;
case 5: // Ping: {Average Ping}/{Normal Player Data | Ping}
break;
case 6: // Command 2 on Timer: Time interval
break;
case 7: // Team change: Normal Player Data | Options (00<Reset Kills><Reset Deaths><Force-Zero(Never returned)><Reset Score><Reset Credits><Kill>)
header.shiftRight(1);
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(header);
unsigned char options = 0;
Jupiter::ReferenceString optionsToken = buff.getToken(1, RenX::DelimC);
if (optionsToken.isEmpty() == false)
options = optionsToken.get(0);
if (options & 0x02)
player->credits = 0.0f;
if (options & 0x04)
player->score = 0.0f;
// 0x08 unused.
if (options & 0x10)
player->deaths = 0;
if (options & 0x20)
player->kills = 0;
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnTeamChange(this, player, RenX::getEnemy(player->team));
}
header.shiftLeft(1);
break;
default:
break;
}
header.shiftLeft(1);
}
else if (header.equals("version"))
{
Jupiter::ReferenceString xVersionToken = buff.getToken(1, RenX::DelimC);
RenX::Server::xRconVersion = xVersionToken.asUnsignedInt(10);
RenX::Server::xRconRevision = xVersionToken.getToken(1, '.').asUnsignedInt(10);
if (this->rconUser.equals(buff.getToken(2, RenX::DelimC)) == false)
this->rconUser = buff.getToken(2, RenX::DelimC);
RenX::Server::serverName = buff.getToken(3, RenX::DelimC);
RenX::Server::map = buff.getToken(4, RenX::DelimC);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_XOnVersion(this, RenX::Server::xRconVersion);
RenX::Server::updateClientList();
RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("_x\x06\n"));
}
else if (header.equals("grant_character"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(1, RenX::DelimC));
Jupiter::ReferenceString character = buff.getToken(2, RenX::DelimC);
if (character.match("Rx_InventoryManager_???_Soldier") == false && player->character != RenX::getCharacter(character))
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnCharacterPurchase(this, player, character);
player->character = RenX::getCharacter(character);
}
else if (header.equals("grant_weapon"))
{
// Support dropped
/*RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(1, RenX::DelimC));
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnWeaponPurchase(this, player, buff.getToken(2, RenX::DelimC));*/
}
else if (header.equals("spawn_vehicle"))
{
Jupiter::ReferenceString tok1 = buff.getToken(1, RenX::DelimC);
if (tok1.equalsi("buy"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(3, RenX::DelimC));
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnVehiclePurchase(this, player, buff.getToken(2, RenX::DelimC));
}
else
{
RenX::TeamType team = RenX::getTeam(tok1);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnVehicleSpawn(this, team, buff.getToken(2, RenX::DelimC));
}
}
else if (header.equals("mine_place"))
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(1, RenX::DelimC));
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnDeploy(this, player, buff.getToken(2, RenX::DelimC));
}
/*else if (header.equals("mlimit_inc"))
{
}*/
else if (header.equals("kill"))
{
Jupiter::ReferenceString kData = buff.getToken(2, RenX::DelimC);
Jupiter::ReferenceString vData = buff.getToken(3, RenX::DelimC);
if (kData.isEmpty() == false && vData.isEmpty() == false) // Safety check
{
struct
{
uint8_t type; // 1 = Player, 2 = Non-Player, 3 = None
Jupiter::ReferenceString data;
} killerData, victimData;
Jupiter::ReadableString &damageType = buff.getToken(1, RenX::DelimC);
killerData.type = kData[0];
killerData.data = kData.substring(1);
victimData.type = vData[0];
victimData.data = vData.substring(1);
if (killerData.type == 1)
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(killerData.data.gotoToken(1, ','));
player->character = RenX::getCharacter(killerData.data.getToken(0, ','));
if (victimData.type == 1) // This is handled in standard RCON logs; update models and move on.
{
if (this->xRconVersion > 1 || this->xRconRevision >= 1 || victimData.data.findi(STRING_LITERAL_AS_REFERENCE("None")) != 0)
{
RenX::PlayerInfo *victim = parseGetPlayerOrAdd(victimData.data.gotoToken(1, ','));
victim->character = RenX::getCharacter(victimData.data.getToken(0, ','));
}
}
else if (victimData.type == 2)
{
TeamType victimTeam = RenX::getTeam(victimData.data.getToken(0, ','));
victimData.data = victimData.data.gotoToken(1, ',');
ObjectType type;
if (victimData.data.match("Rx_Building_*"))
type = ObjectType::Building;
else if (victimData.data.match("Rx_Defence_*"))
type = ObjectType::Defence;
else
type = ObjectType::Vehicle;
if (this->xRconVersion > 1 || this->xRconRevision != 0)
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnDestroy(this, player, victimData.data, victimTeam, damageType, type);
}
}
else if (killerData.type == 3) // No killer!
{
if (victimData.type == 2)
{
TeamType victimTeam = RenX::getTeam(victimData.data.getToken(0, ','));
victimData.data = victimData.data.gotoToken(1, ',');
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnDie(this, victimData.data, victimTeam, damageType);
}
}
else if (killerData.data.size() != 0) // Non-player killer (log!)
{
TeamType killerTeam = RenX::getTeam(killerData.data.getToken(0, ','));
killerData.data = killerData.data.gotoToken(1, ',');
if (victimData.type == 1) // Non-player killed player
{
if (this->xRconVersion > 1 || this->xRconRevision >= 1 || victimData.data.findi(STRING_LITERAL_AS_REFERENCE("None")) != 0)
{
RenX::PlayerInfo *player = parseGetPlayerOrAdd(victimData.data.gotoToken(1, ','));
player->character = RenX::getCharacter(victimData.data.getToken(0, ','));
player->deaths++;
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnKill(this, killerData.data, killerTeam, player, damageType);
}
}
else if (victimData.data.size() != 0) // Non-player destroyed non-player
{
TeamType victimTeam = RenX::getTeam(victimData.data.getToken(0, ','));
victimData.data = victimData.data.gotoToken(1, ',');
ObjectType type;
if (victimData.data.match("Rx_Building_*"))
type = ObjectType::Building;
else if (victimData.data.match("Rx_Defence_*"))
type = ObjectType::Defence;
else
type = ObjectType::Vehicle;
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnDestroy(this, killerData.data, killerTeam, victimData.data, victimTeam, damageType, type);
}
}
}
}
else
{
buff.shiftRight(1);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_XOnOther(this, buff);
buff.shiftLeft(1);
}
header.shiftLeft(1);
break; break;
case 'c': case 'c':
@ -2619,35 +1991,30 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
this->rconVersion = buff.asInt(10); this->rconVersion = buff.asInt(10);
this->gameVersion = buff.substring(3); this->gameVersion = buff.substring(3);
if (this->rconVersion == 1) if (this->rconVersion >= 3)
this->profile = RenX::openBeta1Profile;
else if (gameVersion.equals("Open Beta 2"))
this->profile = RenX::openBeta2Profile;
else if (gameVersion.equals("Open Beta 3"))
this->profile = RenX::openBeta3Profile;
RenX::Server::updateClientList();
if (this->profile->disconnectOnGameOver == false)
{ {
RenX::Server::updateClientList();
this->firstGame = true; this->firstGame = true;
this->seamless = true; this->seamless = true;
}
else if (this->firstGame == false) /*else if (this->firstGame == false)
{ {
this->firstAction = false; this->firstAction = false;
this->silenceJoins = true; this->silenceJoins = true;
} }*/
for (size_t i = 0; i < xPlugins.size(); i++) for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnVersion(this, buff); xPlugins.get(i)->RenX_OnVersion(this, buff);
buff.shiftLeft(1); buff.shiftLeft(1);
}
else
this->disconnect();
break; break;
case 'a': case 'a':
buff.shiftRight(1); buff.shiftRight(1);
if (RenX::Server::rconVersion >= 3) RenX::Server::rconUser = buff;
RenX::Server::rconUser = buff;
for (size_t i = 0; i < xPlugins.size(); i++) for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnAuthorized(this, buff); xPlugins.get(i)->RenX_OnAuthorized(this, buff);
buff.shiftLeft(1); buff.shiftLeft(1);
@ -2706,16 +2073,6 @@ unsigned int RenX::Server::getVersion() const
return RenX::Server::rconVersion; return RenX::Server::rconVersion;
} }
unsigned int RenX::Server::getXVersion() const
{
return RenX::Server::xRconVersion;
}
unsigned int RenX::Server::getXRevision() const
{
return RenX::Server::xRconRevision;
}
const Jupiter::ReadableString &RenX::Server::getGameVersion() const const Jupiter::ReadableString &RenX::Server::getGameVersion() const
{ {
return RenX::Server::gameVersion; return RenX::Server::gameVersion;

68
RenX.Core/RenX_Server.h

@ -33,7 +33,6 @@
#include "Jupiter/Thinker.h" #include "Jupiter/Thinker.h"
#include "Jupiter/Rehash.h" #include "Jupiter/Rehash.h"
#include "RenX.h" #include "RenX.h"
#include "RenX_ServerProfile.h"
/** DLL Linkage Nagging */ /** DLL Linkage Nagging */
#if defined _MSC_VER #if defined _MSC_VER
@ -83,7 +82,6 @@ namespace RenX
public: // RenX::Server public: // RenX::Server
Jupiter::DLList<RenX::PlayerInfo> players; /** A list of players in the server */ Jupiter::DLList<RenX::PlayerInfo> players; /** A list of players in the server */
Jupiter::INIFile varData; /** This may be replaced later with a more dedicated type. */ Jupiter::INIFile varData; /** This may be replaced later with a more dedicated type. */
const RenX::ServerProfile *profile = RenX::defaultProfile;
/** /**
* @brief Checks if the server is connected to RCON. * @brief Checks if the server is connected to RCON.
@ -293,70 +291,70 @@ namespace RenX
bool updateClientList(); bool updateClientList();
/** /**
* @brief Forces the current game to end, if the server supports it. * @brief Forces the current game to end.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool gameover(); bool gameover();
/** /**
* @brief Forces the current game to end and changes the map, if the server supports it. * @brief Forces the current game to end and changes the map.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool setMap(const Jupiter::ReadableString &map); bool setMap(const Jupiter::ReadableString &map);
/** /**
* @brief Forces the current game to end, if the server supports it. * @brief Forces the current game to end.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool loadMutator(const Jupiter::ReadableString &mutator); bool loadMutator(const Jupiter::ReadableString &mutator);
/** /**
* @brief Forces the current game to end, if the server supports it. * @brief Forces the current game to end.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool unloadMutator(const Jupiter::ReadableString &mutator); bool unloadMutator(const Jupiter::ReadableString &mutator);
/** /**
* @brief Forcefully ends the current vote, if the server supports it. * @brief Forcefully ends the current vote.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool cancelVote(const RenX::TeamType team); bool cancelVote(const RenX::TeamType team);
/** /**
* @brief Swaps the teams, if the server supports it. * @brief Swaps the teams.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool swapTeams(); bool swapTeams();
/** /**
* @brief Starts a demo recording, if the server supports it. * @brief Starts a demo recording.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool recordDemo(); bool recordDemo();
/** /**
* @brief Mutes a player from the game chat, if the server supports it. * @brief Mutes a player from the game chat.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool mute(const RenX::PlayerInfo *player); bool mute(const RenX::PlayerInfo *player);
/** /**
* @brief Allows a player to use the game chat, if the server supports it. * @brief Allows a player to use the game chat.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool unmute(const RenX::PlayerInfo *player); bool unmute(const RenX::PlayerInfo *player);
/** /**
* @brief Gives a player additional credits, if the server supports it. * @brief Gives a player additional credits.
* *
* @param id ID of the player to give credits to * @param id ID of the player to give credits to
* @param credits Credits to give to player * @param credits Credits to give to player
@ -365,7 +363,7 @@ namespace RenX
bool giveCredits(int id, double credits); bool giveCredits(int id, double credits);
/** /**
* @brief Gives a player additional credits, if the server supports it. * @brief Gives a player additional credits.
* *
* @param player Player to give credits to * @param player Player to give credits to
* @param credits Credits to give to player * @param credits Credits to give to player
@ -374,42 +372,38 @@ namespace RenX
bool giveCredits(RenX::PlayerInfo *player, double credits); bool giveCredits(RenX::PlayerInfo *player, double credits);
/** /**
* @brief Forces a player to change teams, if the server supports it. * @brief Kills a player.
* *
* @param id ID of the player to give credits to * @param id ID of the player to kill
* @param resetCredits True to reset the player's credits, false otherwise.
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool changeTeam(int id, bool resetCredits = true); bool kill(int id);
/** /**
* @brief Forces a player to change teams, if the server supports it. * @brief Kills a player.
* *
* @param player Player to change teams * @param player Player to kill
* @param resetCredits True to reset the player's credits, false otherwise.
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool changeTeam(RenX::PlayerInfo *player, bool resetCredits = true); bool kill(RenX::PlayerInfo *player);
/** /**
* @brief Forces a player to change teams, if the server supports it. * @brief Forces a player to change teams.
* *
* @param id ID of the player to give credits to * @param id ID of the player to give credits to
* @param team Team number to switch to * @param resetCredits True to reset the player's credits, false otherwise.
* @param options Options to pass to the command
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool setTeam(int id, int team, unsigned char options = 0x03); bool changeTeam(int id, bool resetCredits = true);
/** /**
* @brief Forces a player to change teams, if the server supports it. * @brief Forces a player to change teams.
* *
* @param player Player to change teams * @param player Player to change teams
* @param team Team number to switch to * @param resetCredits True to reset the player's credits, false otherwise.
* @param options Options to pass to the command
* @return True on success, false otherwise. * @return True on success, false otherwise.
*/ */
bool setTeam(RenX::PlayerInfo *player, int team, unsigned char options = 0x03); bool changeTeam(RenX::PlayerInfo *player, bool resetCredits = true);
/** /**
* @brief Fetches a server's IRC logging prefix. * @brief Fetches a server's IRC logging prefix.
@ -627,20 +621,6 @@ namespace RenX
*/ */
unsigned int getVersion() const; unsigned int getVersion() const;
/**
* @brief Fetches the eXtended-RCON version number, or 0 if none has been set.
*
* @return XRCON version number
*/
unsigned int getXVersion() const;
/**
* @brief Fetches the eXtended-RCON revision number, or 0 if none has been set.
*
* @return XRCON revision number
*/
unsigned int getXRevision() const;
/** /**
* @brief Fetches the game version string, or an empty string if none has been set. * @brief Fetches the game version string, or an empty string if none has been set.
* *
@ -682,8 +662,6 @@ namespace RenX
bool firstDeath = false; bool firstDeath = false;
bool firstAction = false; bool firstAction = false;
unsigned int rconVersion = 0; unsigned int rconVersion = 0;
unsigned int xRconVersion = 0;
unsigned int xRconRevision = 0;
time_t lastAttempt = 0; time_t lastAttempt = 0;
Jupiter::String lastLine; Jupiter::String lastLine;
Jupiter::StringS commandListFormat; Jupiter::StringS commandListFormat;

73
RenX.Core/RenX_ServerProfile.cpp

@ -1,73 +0,0 @@
/**
* Copyright (C) 2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#include "RenX_ServerProfile.h"
struct BaseProfile : RenX::ServerProfile
{
BaseProfile()
{
supported = true;
privateMessages = true;
disconnectOnGameOver = false;
pidbug = false;
mustSanitize = false;
tieFormat = 1;
}
} _baseProfile;
const RenX::ServerProfile *RenX::defaultProfile = &_baseProfile;
struct OpenBeta1Profile : BaseProfile
{
OpenBeta1Profile()
{
supported = false;
privateMessages = false;
mustSanitize = true;
}
} _openBeta1Profile;
const RenX::ServerProfile *RenX::openBeta1Profile = &_openBeta1Profile;
struct OpenBeta2Profile : BaseProfile
{
OpenBeta2Profile()
{
privateMessages = false;
pidbug = true;
tieFormat = 0;
mustSanitize = true;
}
} _openBeta2Profile;
const RenX::ServerProfile *RenX::openBeta2Profile = &_openBeta2Profile;
struct OpenBeta3Profile : BaseProfile
{
OpenBeta3Profile()
{
disconnectOnGameOver = true;
mustSanitize = true;
}
} _openBeta3Profile;
const RenX::ServerProfile *RenX::openBeta3Profile = &_openBeta3Profile;
struct OpenBeta4Profile : BaseProfile
{
OpenBeta4Profile()
{
}
} _openBeta4Profile;
const RenX::ServerProfile *RenX::openBeta4Profile = &_openBeta4Profile;

51
RenX.Core/RenX_ServerProfile.h

@ -1,51 +0,0 @@
/**
* Copyright (C) 2014 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
* component of this program must not be commercial, unless explicit
* permission is granted from the original author. The use of this
* program for non-profit purposes is permitted.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In the event that this license restricts you from making desired use of this program, contact the original author.
* Written by Justin James <justin.aj@hotmail.com>
*/
#if !defined _RENX_SERVERPROFILE_H_HEADER
#define _RENX_SERVERPROFILE_H_HEADER
/**
* @file RenX_ServerProfile.h
* @brief Defines the ServerProfile class, and known profiles.
*/
#include "RenX.h"
namespace RenX
{
/**
* @brief Contains information about features supported by a server version.
*/
struct RENX_API ServerProfile
{
bool supported;
bool privateMessages;
bool disconnectOnGameOver;
bool pidbug;
bool mustSanitize;
int tieFormat;
};
RENX_API extern const ServerProfile *defaultProfile; /** Default server profile */
RENX_API extern const ServerProfile *openBeta1Profile; /** Open Beta 1 server profile */
RENX_API extern const ServerProfile *openBeta2Profile; /** Open Beta 2 server profile */
RENX_API extern const ServerProfile *openBeta3Profile; /** Open Beta 3 server profile */
RENX_API extern const ServerProfile *openBeta4Profile; /** Open Beta 4 server profile */
}
#endif // _RENX_SERVERPROFILE_H_HEADER

4
RenX.Core/RenX_Tags.cpp

@ -67,7 +67,6 @@ TagsImp::TagsImp()
/** Server tags */ /** Server tags */
this->INTERNAL_RCON_VERSION_TAG = this->getUniqueInternalTag(); this->INTERNAL_RCON_VERSION_TAG = this->getUniqueInternalTag();
this->INTERNAL_GAME_VERSION_TAG = this->getUniqueInternalTag(); this->INTERNAL_GAME_VERSION_TAG = this->getUniqueInternalTag();
this->INTERNAL_XRCON_VERSION_TAG = this->getUniqueInternalTag();
this->INTERNAL_RULES_TAG = this->getUniqueInternalTag(); this->INTERNAL_RULES_TAG = this->getUniqueInternalTag();
this->INTERNAL_USER_TAG = this->getUniqueInternalTag(); this->INTERNAL_USER_TAG = this->getUniqueInternalTag();
this->INTERNAL_SERVER_NAME_TAG = this->getUniqueInternalTag(); this->INTERNAL_SERVER_NAME_TAG = this->getUniqueInternalTag();
@ -160,7 +159,6 @@ TagsImp::TagsImp()
/** Server tags */ /** Server tags */
this->rconVersionTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("RCONVersionTag"), STRING_LITERAL_AS_REFERENCE("{RVER}")); this->rconVersionTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("RCONVersionTag"), STRING_LITERAL_AS_REFERENCE("{RVER}"));
this->gameVersionTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("GameVersionTag"), STRING_LITERAL_AS_REFERENCE("{GVER}")); this->gameVersionTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("GameVersionTag"), STRING_LITERAL_AS_REFERENCE("{GVER}"));
this->xRconVersionTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("XRCONVersionTag"), STRING_LITERAL_AS_REFERENCE("{XVER}"));
this->rulesTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("RulesTag"), STRING_LITERAL_AS_REFERENCE("{RULES}")); this->rulesTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("RulesTag"), STRING_LITERAL_AS_REFERENCE("{RULES}"));
this->userTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("UserTag"), STRING_LITERAL_AS_REFERENCE("{USER}")); this->userTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("UserTag"), STRING_LITERAL_AS_REFERENCE("{USER}"));
this->serverNameTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("ServerNameTag"), STRING_LITERAL_AS_REFERENCE("{SERVERNAME}")); this->serverNameTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("ServerNameTag"), STRING_LITERAL_AS_REFERENCE("{SERVERNAME}"));
@ -253,7 +251,6 @@ void TagsImp::processTags(Jupiter::StringType &msg, const RenX::Server *server,
{ {
msg.replace(this->INTERNAL_RCON_VERSION_TAG, Jupiter::StringS::Format("%u", server->getVersion())); msg.replace(this->INTERNAL_RCON_VERSION_TAG, Jupiter::StringS::Format("%u", server->getVersion()));
msg.replace(this->INTERNAL_GAME_VERSION_TAG, server->getGameVersion()); msg.replace(this->INTERNAL_GAME_VERSION_TAG, server->getGameVersion());
msg.replace(this->INTERNAL_XRCON_VERSION_TAG, Jupiter::StringS::Format("%u.%u", server->getXVersion(), server->getXRevision()));
msg.replace(this->INTERNAL_RULES_TAG, server->getRules()); msg.replace(this->INTERNAL_RULES_TAG, server->getRules());
msg.replace(this->INTERNAL_USER_TAG, server->getUser()); msg.replace(this->INTERNAL_USER_TAG, server->getUser());
msg.replace(this->INTERNAL_SERVER_NAME_TAG, server->getName()); msg.replace(this->INTERNAL_SERVER_NAME_TAG, server->getName());
@ -352,7 +349,6 @@ void TagsImp::sanitizeTags(Jupiter::StringType &fmt)
/** Server tags */ /** Server tags */
fmt.replace(this->rconVersionTag, this->INTERNAL_RCON_VERSION_TAG); fmt.replace(this->rconVersionTag, this->INTERNAL_RCON_VERSION_TAG);
fmt.replace(this->gameVersionTag, this->INTERNAL_GAME_VERSION_TAG); fmt.replace(this->gameVersionTag, this->INTERNAL_GAME_VERSION_TAG);
fmt.replace(this->xRconVersionTag, this->INTERNAL_XRCON_VERSION_TAG);
fmt.replace(this->rulesTag, this->INTERNAL_RULES_TAG); fmt.replace(this->rulesTag, this->INTERNAL_RULES_TAG);
fmt.replace(this->userTag, this->INTERNAL_USER_TAG); fmt.replace(this->userTag, this->INTERNAL_USER_TAG);
fmt.replace(this->serverNameTag, this->INTERNAL_SERVER_NAME_TAG); fmt.replace(this->serverNameTag, this->INTERNAL_SERVER_NAME_TAG);

2
RenX.Core/RenX_Tags.h

@ -57,7 +57,6 @@ namespace RenX
/** Server tags */ /** Server tags */
Jupiter::StringS INTERNAL_RCON_VERSION_TAG; Jupiter::StringS INTERNAL_RCON_VERSION_TAG;
Jupiter::StringS INTERNAL_GAME_VERSION_TAG; Jupiter::StringS INTERNAL_GAME_VERSION_TAG;
Jupiter::StringS INTERNAL_XRCON_VERSION_TAG;
Jupiter::StringS INTERNAL_RULES_TAG; Jupiter::StringS INTERNAL_RULES_TAG;
Jupiter::StringS INTERNAL_USER_TAG; Jupiter::StringS INTERNAL_USER_TAG;
Jupiter::StringS INTERNAL_SERVER_NAME_TAG; Jupiter::StringS INTERNAL_SERVER_NAME_TAG;
@ -150,7 +149,6 @@ namespace RenX
/** Server tags */ /** Server tags */
Jupiter::StringS rconVersionTag; Jupiter::StringS rconVersionTag;
Jupiter::StringS gameVersionTag; Jupiter::StringS gameVersionTag;
Jupiter::StringS xRconVersionTag;
Jupiter::StringS rulesTag; Jupiter::StringS rulesTag;
Jupiter::StringS userTag; Jupiter::StringS userTag;
Jupiter::StringS serverNameTag; Jupiter::StringS serverNameTag;

47
RenX.Logging/RenX_Logging.cpp

@ -83,8 +83,6 @@ void RenX_LoggingPlugin::init()
RenX_LoggingPlugin::demoRecordStopPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DemoRecordStopPublic"), true); RenX_LoggingPlugin::demoRecordStopPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DemoRecordStopPublic"), true);
RenX_LoggingPlugin::demoPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DemoPublic"), false); RenX_LoggingPlugin::demoPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DemoPublic"), false);
RenX_LoggingPlugin::logPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("LogPublic"), false); RenX_LoggingPlugin::logPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("LogPublic"), false);
RenX_LoggingPlugin::xVersionPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("XVersionPublic"), true);
RenX_LoggingPlugin::xOtherPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("XOtherPublic"), false);
RenX_LoggingPlugin::commandPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("CommandPublic"), false); RenX_LoggingPlugin::commandPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("CommandPublic"), false);
RenX_LoggingPlugin::errorPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("ErrorPublic"), false); RenX_LoggingPlugin::errorPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("ErrorPublic"), false);
RenX_LoggingPlugin::versionPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("VersionPublic"), true); RenX_LoggingPlugin::versionPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("VersionPublic"), true);
@ -320,12 +318,6 @@ void RenX_LoggingPlugin::init()
RenX_LoggingPlugin::logFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("LogFormat"), RenX_LoggingPlugin::logFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("LogFormat"),
Jupiter::StringS::Format(IRCCOLOR "07[Log]" IRCCOLOR " %.*s", RenX::tags->messageTag.size(), RenX::tags->messageTag.ptr())); Jupiter::StringS::Format(IRCCOLOR "07[Log]" IRCCOLOR " %.*s", RenX::tags->messageTag.size(), RenX::tags->messageTag.ptr()));
RenX_LoggingPlugin::xVersionFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("XVersionFormat"),
Jupiter::StringS::Format(IRCCOLOR "03This server is using eXtended RCON version %.*s", RenX::tags->xRconVersionTag.size(), RenX::tags->xRconVersionTag.ptr()));
RenX_LoggingPlugin::xOtherFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("XOtherFormat"),
Jupiter::StringS::Format(IRCCOLOR "06[XOther]" IRCCOLOR " %.*s", RenX::tags->messageTag.size(), RenX::tags->messageTag.ptr()));
RenX_LoggingPlugin::commandFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("CommandFormat"), RenX_LoggingPlugin::commandFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("CommandFormat"),
Jupiter::StringS::Format("")); // Disabled by default. Jupiter::StringS::Format("")); // Disabled by default.
@ -418,8 +410,6 @@ void RenX_LoggingPlugin::init()
RenX::sanitizeTags(demoRecordStopFmt); RenX::sanitizeTags(demoRecordStopFmt);
RenX::sanitizeTags(demoFmt); RenX::sanitizeTags(demoFmt);
RenX::sanitizeTags(logFmt); RenX::sanitizeTags(logFmt);
RenX::sanitizeTags(xVersionFmt);
RenX::sanitizeTags(xOtherFmt);
RenX::sanitizeTags(commandFmt); RenX::sanitizeTags(commandFmt);
RenX::sanitizeTags(errorFmt); RenX::sanitizeTags(errorFmt);
RenX::sanitizeTags(versionFmt); RenX::sanitizeTags(versionFmt);
@ -1322,9 +1312,6 @@ void RenX_LoggingPlugin::RenX_OnGameOver(RenX::Server *server, RenX::WinType win
msg.replace(RenX::tags->INTERNAL_MESSAGE_TAG, RenX::translateWinType(winType)); msg.replace(RenX::tags->INTERNAL_MESSAGE_TAG, RenX::translateWinType(winType));
(server->*func)(msg); (server->*func)(msg);
} }
if (server->profile->disconnectOnGameOver)
server->sendLogChan(IRCCOLOR "07[Warning]" IRCCOLOR " Game version \"%.*s\" gets disconnected when a map unloads; to prevent disconnect spam, player disconnects are silenced until the bot reconnects.", server->getGameVersion().size(), server->getGameVersion().ptr());
} }
void RenX_LoggingPlugin::RenX_OnGame(RenX::Server *server, const Jupiter::ReadableString &raw) void RenX_LoggingPlugin::RenX_OnGame(RenX::Server *server, const Jupiter::ReadableString &raw)
@ -1683,40 +1670,6 @@ void RenX_LoggingPlugin::RenX_OnLog(RenX::Server *server, const Jupiter::Readabl
} }
} }
void RenX_LoggingPlugin::RenX_XOnVersion(RenX::Server *server, unsigned int version)
{
logFuncType func;
if (RenX_LoggingPlugin::xVersionPublic)
func = &RenX::Server::sendLogChan;
else
func = &RenX::Server::sendAdmChan;
Jupiter::String msg = this->xVersionFmt;
if (msg.isEmpty() == false)
{
RenX::processTags(msg, server);
msg.replace(RenX::tags->INTERNAL_XRCON_VERSION_TAG, Jupiter::StringS::Format("%u", version));
(server->*func)(msg);
}
}
void RenX_LoggingPlugin::RenX_XOnOther(RenX::Server *server, const Jupiter::ReadableString &raw)
{
logFuncType func;
if (RenX_LoggingPlugin::xOtherPublic)
func = &RenX::Server::sendLogChan;
else
func = &RenX::Server::sendAdmChan;
Jupiter::String msg = this->xOtherFmt;
if (msg.isEmpty() == false)
{
RenX::processTags(msg, server);
msg.replace(RenX::tags->INTERNAL_MESSAGE_TAG, raw);
(server->*func)(msg);
}
}
void RenX_LoggingPlugin::RenX_OnCommand(RenX::Server *server, const Jupiter::ReadableString &raw) void RenX_LoggingPlugin::RenX_OnCommand(RenX::Server *server, const Jupiter::ReadableString &raw)
{ {
logFuncType func; logFuncType func;

7
RenX.Logging/RenX_Logging.h

@ -96,9 +96,6 @@ public: // RenX::Plugin
void RenX_OnLog(RenX::Server *server, const Jupiter::ReadableString &raw) override; void RenX_OnLog(RenX::Server *server, const Jupiter::ReadableString &raw) override;
void RenX_XOnVersion(RenX::Server *server, unsigned int version) override;
void RenX_XOnOther(RenX::Server *server, const Jupiter::ReadableString &raw) override;
void RenX_OnCommand(RenX::Server *server, const Jupiter::ReadableString &raw) override; void RenX_OnCommand(RenX::Server *server, const Jupiter::ReadableString &raw) override;
void RenX_OnError(RenX::Server *server, const Jupiter::ReadableString &raw) override; void RenX_OnError(RenX::Server *server, const Jupiter::ReadableString &raw) override;
void RenX_OnVersion(RenX::Server *server, const Jupiter::ReadableString &raw) override; void RenX_OnVersion(RenX::Server *server, const Jupiter::ReadableString &raw) override;
@ -172,8 +169,6 @@ private:
unsigned int demoRecordStopPublic : 1; unsigned int demoRecordStopPublic : 1;
unsigned int demoPublic : 1; unsigned int demoPublic : 1;
unsigned int logPublic : 1; unsigned int logPublic : 1;
unsigned int xVersionPublic : 1;
unsigned int xOtherPublic : 1;
unsigned int commandPublic : 1; unsigned int commandPublic : 1;
unsigned int errorPublic : 1; unsigned int errorPublic : 1;
unsigned int versionPublic : 1; unsigned int versionPublic : 1;
@ -253,8 +248,6 @@ private:
Jupiter::StringS demoRecordStopFmt; Jupiter::StringS demoRecordStopFmt;
Jupiter::StringS demoFmt; Jupiter::StringS demoFmt;
Jupiter::StringS logFmt; Jupiter::StringS logFmt;
Jupiter::StringS xVersionFmt;
Jupiter::StringS xOtherFmt;
Jupiter::StringS commandFmt; Jupiter::StringS commandFmt;
Jupiter::StringS errorFmt; Jupiter::StringS errorFmt;
Jupiter::StringS versionFmt; Jupiter::StringS versionFmt;

Loading…
Cancel
Save