From 4ed9acf6ec222da7b304bb9333b94d7beec48592 Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Sat, 7 Mar 2015 20:32:41 -0500 Subject: [PATCH] * Removed redundant RenX::Core::send() * Added additional weapon translations * Added some projectile translations * Added Silo translation * Replaced RenX::getTeam() with 2 different getTeam() functions * Removed RenX::sanitizeString() for C-style Strings. * Added events: OnDisarm, OnExplode, OnCharacterPurchase, OnItemPurchase, OnWeaponPurchase, OnRefillPurchase, OnVehiclePurchase, OnVehicleSpawn, OnSpawn, OnBotJoin, OnVehicleCrate, OnDeathCrate, OnMoneyCrate, OnCharacterCrate, OnSpyCrate, OnRefillCrate, OnDonate, OnDemoRecordStop * Added functions to RenX::Server: isSeamless(), gameover(), setMap(), loadMutator(), unloadMutator(), cancelVote(), swapTeams(), recordDemo(), mute(), unmute(). Replaced RenX::Server::changeTeam() parameter "options" with "resetCredits". * Server profile added for Open Beta 4. * Updated Jupiter * Updated plugins according to the above changes. --- Jupiter | 2 +- Release/Bot.lib | Bin 19858 -> 19858 bytes Release/Plugins/RenX.Core.lib | Bin 99250 -> 110490 bytes RenX.Commands/RenX_Commands.cpp | 206 ++++++--- RenX.Commands/RenX_Commands.h | 2 +- RenX.Core/RenX_Core.cpp | 7 +- RenX.Core/RenX_Core.h | 9 - RenX.Core/RenX_Functions.cpp | 95 ++-- RenX.Core/RenX_Functions.h | 18 +- RenX.Core/RenX_Plugin.cpp | 127 ++++-- RenX.Core/RenX_Plugin.h | 26 +- RenX.Core/RenX_Server.cpp | 723 +++++++++++++++++++++++++------ RenX.Core/RenX_Server.h | 80 +++- RenX.Core/RenX_ServerProfile.cpp | 13 +- RenX.Core/RenX_ServerProfile.h | 1 + RenX.Logging/RenX_Logging.cpp | 612 +++++++++++++++++++++----- RenX.Logging/RenX_Logging.h | 74 +++- RenX.Medals/RenX_Medals.cpp | 2 +- RenX.Medals/RenX_Medals.h | 2 +- 19 files changed, 1582 insertions(+), 417 deletions(-) diff --git a/Jupiter b/Jupiter index 46ce354..54a9e74 160000 --- a/Jupiter +++ b/Jupiter @@ -1 +1 @@ -Subproject commit 46ce3548d245459aba3f0b14c7fd7fd8528a0c59 +Subproject commit 54a9e74686b814f6935d8203822c54168f0af5e2 diff --git a/Release/Bot.lib b/Release/Bot.lib index 0cecd97a7f2c2f292339cfb609b6b0135321d675..dbe2a145ea5572096ff840618ee1f1ff6256d8ea 100644 GIT binary patch delta 1646 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 delta 13753 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 z1Y&tZ6(8lD)~send(source->getChannel(channel)->getType(), Jupiter::StringS::Format("say %.*s", parameters.size(), parameters.ptr())) == 0) + int type = source->getChannel(channel)->getType(); + + bool success = false; + for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) + { + RenX::Server *server = RenX::getCore()->getServer(i); + if (server->isLogChanType(type)) + success = server->sendMessage(parameters) > 0; + } + if (!success) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers.")); } else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: hmsg ")); @@ -948,7 +957,7 @@ IRC_COMMAND_INIT(SetRulesIRCCommand) void ReconnectIRCCommand::create() { this->addTrigger(STRING_LITERAL_AS_REFERENCE("reconnect")); - this->setAccessLevel(4); + this->setAccessLevel(3); } void ReconnectIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &) @@ -963,7 +972,7 @@ void ReconnectIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString RenX::Server *server = RenX::getCore()->getServer(i); if (server->isLogChanType(type)) { - if (server->reconnect()) msg.format("Connection established"); + if (server->reconnect()) msg.set("Connection established"); else msg.format("[RenX] ERROR: Failed to connect to %.*s on port %u." ENDL, server->getHostname().size(), server->getHostname().ptr(), server->getPort()); source->sendMessage(channel, msg); } @@ -971,7 +980,7 @@ void ReconnectIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString if (msg.isEmpty()) { // We didn't connect anywhere!! - msg.format("ERROR: No servers found to connect to."); + msg.set("ERROR: No servers found to connect to."); source->sendMessage(channel, msg); } } @@ -979,102 +988,139 @@ void ReconnectIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString const Jupiter::ReadableString &ReconnectIRCCommand::getHelp(const Jupiter::ReadableString &) { - static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Gets information about a player. Syntax: Reconnect"); + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Resets the RCON connection. Syntax: Reconnect"); return defaultHelp; } IRC_COMMAND_INIT(ReconnectIRCCommand) -// RestartMap IRC Command +// GameOver IRC Command -/*void RestartMapIRCCommand::create() +void GameOverIRCCommand::create() { - this->addTrigger("restartmap"); - this->setAccessLevel(2); + this->addTrigger(STRING_LITERAL_AS_REFERENCE("gameover")); + this->addTrigger(STRING_LITERAL_AS_REFERENCE("endmap")); + this->setAccessLevel(3); } -void RestartMapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) +void GameOverIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &) { - int r = RenX::getCore()->send(source->getChannel(channel.c_str())->getType(), "adminrestartmap"); - if (r > 0) + Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); + if (chan != nullptr) { - char t[256]; - sprintf(t, "Command sent to %d servers.", r); - source->sendMessage(channel.c_str(), t); + int type = chan->getType(); + bool match = false; + for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) + { + RenX::Server *server = RenX::getCore()->getServer(i); + if (server->isLogChanType(type)) + { + match = true; + if (server->gameover() == false) + source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Server does not support gameover.")); + } + } + if (match == false) + source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers.")); } - else source->sendMessage(channel.c_str(), "Error: Channel not attached to any connected Renegade X servers."); } -const char *RestartMapIRCCommand::getHelp() +const Jupiter::ReadableString &GameOverIRCCommand::getHelp(const Jupiter::ReadableString &) { - return "Restarts the current map. Syntax: RestartMap"; + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Ends the game immediately. Syntax: Gameover"); + return defaultHelp; } -IRC_COMMAND_INIT(RestartMapIRCCommand) +IRC_COMMAND_INIT(GameOverIRCCommand) // SetMap IRC Command void SetMapIRCCommand::create() { - this->addTrigger("setmap"); - this->setAccessLevel(3); + this->addTrigger(STRING_LITERAL_AS_REFERENCE("setmap")); + this->setAccessLevel(4); } void SetMapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) { - if (parameters != nullptr) + if (parameters.isEmpty() == false) { - Jupiter::StringL cmd = "adminrestartmap "; - cmd += parameters; - int r = RenX::getCore()->send(source->getChannel(channel.c_str())->getType(), cmd.c_str()); - if (r > 0) + Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); + if (chan != nullptr) { - char t[256]; - sprintf(t, "Command sent to %d servers.", r); - source->sendMessage(channel.c_str(), t); + int type = chan->getType(); + bool match = false; + for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) + { + RenX::Server *server = RenX::getCore()->getServer(i); + if (server->isLogChanType(type)) + { + match = true; + if (server->setMap(parameters) == false) + source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Server does not support setmap.")); + } + } + if (match == false) + source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers.")); } - else source->sendMessage(channel.c_str(), "Error: Channel not attached to any connected Renegade X servers."); } - else source->sendNotice(nick.c_str(), "Error: Too Few Parameters. Syntax: SetMap "); + else + source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: setmap ")); } -const char *SetMapIRCCommand::getHelp() +const Jupiter::ReadableString &SetMapIRCCommand::getHelp(const Jupiter::ReadableString &) { - return "Sets the next map, and ends the current map. Syntax: SetMap "; + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Ends the game immediately. Syntax: setmap "); + return defaultHelp; } -IRC_COMMAND_INIT(SetMapIRCCommand)*/ +IRC_COMMAND_INIT(SetMapIRCCommand) // Mute IRC Command -/*void MuteIRCCommand::create() +void MuteIRCCommand::create() { - this->addTrigger("mute"); - this->addTrigger("silence"); + this->addTrigger(STRING_LITERAL_AS_REFERENCE("mute")); this->setAccessLevel(2); } void MuteIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) { - if (parameters != nullptr) + if (parameters.isEmpty() == false) { - Jupiter::StringL cmd = "AdminForceTextMute "; - cmd += parameters; - int r = RenX::getCore()->send(source->getChannel(channel.c_str())->getType(), cmd.c_str()); - if (r > 0) + Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); + if (chan != nullptr) { - char t[256]; - sprintf(t, "Command sent to %d servers.", r); - source->sendMessage(channel.c_str(), t); + int type = chan->getType(); + RenX::PlayerInfo *player; + bool match = false; + for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) + { + RenX::Server *server = RenX::getCore()->getServer(i); + if (server->isLogChanType(type)) + { + match = true; + player = server->getPlayerByPartName(parameters); + if (player != nullptr) + { + if (server->mute(player) == false) + source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Server does not support muting players.")); + } + else + source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found.")); + } + } + if (match == false) + source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers.")); } - else source->sendMessage(channel.c_str(), "Error: Channel not attached to any connected Renegade X servers."); } - else source->sendNotice(nick.c_str(), "Error: Too Few Parameters. Syntax: Mute "); + else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: mute ")); } -const char *MuteIRCCommand::getHelp() +const Jupiter::ReadableString &MuteIRCCommand::getHelp(const Jupiter::ReadableString &) { - return "Mutes a player from the game chat. Syntax: Mute "; + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Mutes a player. Syntax: mute "); + return defaultHelp; } IRC_COMMAND_INIT(MuteIRCCommand) @@ -1083,34 +1129,50 @@ IRC_COMMAND_INIT(MuteIRCCommand) void UnMuteIRCCommand::create() { - this->addTrigger("unmute"); + this->addTrigger(STRING_LITERAL_AS_REFERENCE("unmute")); this->setAccessLevel(2); } void UnMuteIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) { - if (parameters != nullptr) + if (parameters.isEmpty() == false) { - Jupiter::StringL cmd = "AdminForceTextUnMute "; - cmd += parameters; - int r = RenX::getCore()->send(source->getChannel(channel.c_str())->getType(), cmd.c_str()); - if (r > 0) + Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); + if (chan != nullptr) { - char t[256]; - sprintf(t, "Command sent to %d servers.", r); - source->sendMessage(channel.c_str(), t); + int type = chan->getType(); + RenX::PlayerInfo *player; + bool match = false; + for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) + { + RenX::Server *server = RenX::getCore()->getServer(i); + if (server->isLogChanType(type)) + { + match = true; + player = server->getPlayerByPartName(parameters); + if (player != nullptr) + { + if (server->unmute(player) == false) + source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Server does not support muting players.")); + } + else + source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found.")); + } + } + if (match == false) + source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers.")); } - else source->sendMessage(channel.c_str(), "Error: Channel not attached to any connected Renegade X servers."); } - else source->sendNotice(nick.c_str(), "Error: Too Few Parameters. Syntax: UnMute "); + else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: unmute ")); } -const char *UnMuteIRCCommand::getHelp() +const Jupiter::ReadableString &UnMuteIRCCommand::getHelp(const Jupiter::ReadableString &) { - return "UnMutes a player from the game chat. Syntax: UnMute "; + static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Unmutes a player. Syntax: unmute "); + return defaultHelp; } -IRC_COMMAND_INIT(UnMuteIRCCommand)*/ +IRC_COMMAND_INIT(UnMuteIRCCommand) // Kick IRC Command @@ -1337,8 +1399,7 @@ void AddBotsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString & { RenX::Server *server; Jupiter::StringL cmd; - Jupiter::ReferenceString targetTeam = Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE); - RenX::TeamType team = targetTeam.isEmpty() ? RenX::TeamType::Other : RenX::getTeam(targetTeam[0]); + RenX::TeamType team = RenX::getTeam(Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE)); switch (team) { @@ -1348,6 +1409,7 @@ void AddBotsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString & case RenX::TeamType::Nod: cmd = "addbluebots "; break; + case RenX::TeamType::None: case RenX::TeamType::Other: cmd = "addbots "; break; @@ -1584,7 +1646,6 @@ void TeamChangeIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableStrin { int type = chan->getType(); Jupiter::ReferenceString playerName = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE); - double credits = Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE).asDouble(); RenX::PlayerInfo *player; bool playerFound = false; for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) @@ -1640,7 +1701,6 @@ void TeamChange2IRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableStri { int type = chan->getType(); Jupiter::ReferenceString playerName = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE); - double credits = Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE).asDouble(); RenX::PlayerInfo *player; bool playerFound = false; for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) @@ -1654,7 +1714,7 @@ void TeamChange2IRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableStri if (player->name.findi(playerName) != Jupiter::INVALID_INDEX) { playerFound = true; - if (server->changeTeam(player, 0x01) == false) + if (server->changeTeam(player, false) == false) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Server does not support team changing.")); } } @@ -2007,10 +2067,9 @@ void AddBotsGameCommand::create() void AddBotsGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters) { - Jupiter::ReferenceString targetTeam = Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE); - RenX::TeamType team = targetTeam.isEmpty() ? RenX::TeamType::Other : RenX::getTeam(targetTeam[0]); + RenX::TeamType team = RenX::getTeam(Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE)); - const char *cmd; + Jupiter::StringS cmd; switch (team) { case RenX::TeamType::GDI: @@ -2020,6 +2079,7 @@ void AddBotsGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, cmd = "addbluebots "; break; default: + case RenX::TeamType::None: case RenX::TeamType::Other: cmd = "addbots "; break; @@ -2030,7 +2090,9 @@ void AddBotsGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, amount = 1; else amount = parameters.asUnsignedInt(); - source->send(Jupiter::StringS::Format("%s %u", cmd, amount)); + cmd += Jupiter::StringS::Format("%u", amount); + + source->send(cmd); source->sendMessage(player, Jupiter::StringS::Format("%u bots have been added to the server.", amount)); } diff --git a/RenX.Commands/RenX_Commands.h b/RenX.Commands/RenX_Commands.h index 0e3df39..4e3052f 100644 --- a/RenX.Commands/RenX_Commands.h +++ b/RenX.Commands/RenX_Commands.h @@ -67,7 +67,7 @@ GENERIC_IRC_COMMAND(ShowRulesIRCCommand) GENERIC_IRC_COMMAND(RulesIRCCommand) GENERIC_IRC_COMMAND(SetRulesIRCCommand) GENERIC_IRC_COMMAND(ReconnectIRCCommand) -GENERIC_IRC_COMMAND(RestartMapIRCCommand) +GENERIC_IRC_COMMAND(GameOverIRCCommand) GENERIC_IRC_COMMAND(SetMapIRCCommand) GENERIC_IRC_COMMAND(MuteIRCCommand) GENERIC_IRC_COMMAND(UnMuteIRCCommand) diff --git a/RenX.Core/RenX_Core.cpp b/RenX.Core/RenX_Core.cpp index c1508b7..7f5fe12 100644 --- a/RenX.Core/RenX_Core.cpp +++ b/RenX.Core/RenX_Core.cpp @@ -62,11 +62,6 @@ RenX::Core::~Core() RenX::Core::servers.emptyAndDelete(); } -int RenX::Core::send(RenX::Server *server, const Jupiter::ReadableString &msg) -{ - return server->send(msg); -} - unsigned int RenX::Core::send(int type, const Jupiter::ReadableString &msg) { unsigned int r = 0; @@ -74,7 +69,7 @@ unsigned int RenX::Core::send(int type, const Jupiter::ReadableString &msg) for (size_t i = 0; i != RenX::Core::servers.size(); i++) { server = RenX::Core::getServer(i); - if (server->isLogChanType(type) && RenX::Core::send(server, msg) > 0) r++; + if (server->isLogChanType(type) && server->send(msg) > 0) r++; } return r; } diff --git a/RenX.Core/RenX_Core.h b/RenX.Core/RenX_Core.h index c61c558..d5c504e 100644 --- a/RenX.Core/RenX_Core.h +++ b/RenX.Core/RenX_Core.h @@ -66,15 +66,6 @@ namespace RenX */ const Jupiter::ReadableString &getName() override { return name; } - /** - * @brief Sends a command to a specific server. - * - * @param server Server to send the command to. - * @param data Command to send. - * @return Number of bytes sent on success, less than or equal to 0 otherwise. - */ - int send(Server *server, const Jupiter::ReadableString &data); - /** * @brief Sends a command to all servers of a specific type. * diff --git a/RenX.Core/RenX_Functions.cpp b/RenX.Core/RenX_Functions.cpp index a3af4bd..7fad43f 100644 --- a/RenX.Core/RenX_Functions.cpp +++ b/RenX.Core/RenX_Functions.cpp @@ -102,9 +102,31 @@ Jupiter::ReferenceString translated_Vehicle_AC130_DmgType_HeavyCannon = STRING_L Jupiter::ReferenceString translated_Vehicle_AC130_DmgType_AutoCannon = STRING_LITERAL_AS_REFERENCE("AC130 Auto Cannon"); /** Weapons */ +Jupiter::ReferenceString translated_Weapon_HeavyPistol = STRING_LITERAL_AS_REFERENCE("Heavy Pistol"); +Jupiter::ReferenceString translated_Weapon_Carbine = STRING_LITERAL_AS_REFERENCE("Carbine"); +Jupiter::ReferenceString translated_Weapon_Airstrike_GDI = STRING_LITERAL_AS_REFERENCE("GDI Airstrike"); +Jupiter::ReferenceString translated_Weapon_Airstrike_Nod = STRING_LITERAL_AS_REFERENCE("Nod Airstrike"); +Jupiter::ReferenceString translated_Weapon_TiberiumFlechetteRifle = STRING_LITERAL_AS_REFERENCE("Tiberium Flechette Gun"); +Jupiter::ReferenceString translated_Weapon_TiberiumAutoRifle = STRING_LITERAL_AS_REFERENCE("Tiberium Automatic Rifle"); +Jupiter::ReferenceString translated_Weapon_EMPGrenade = STRING_LITERAL_AS_REFERENCE("EMP Grenade"); +Jupiter::ReferenceString translated_Weapon_SmokeGrenade = STRING_LITERAL_AS_REFERENCE("Smoke Grenade"); +Jupiter::ReferenceString translated_Weapon_TimedC4 = STRING_LITERAL_AS_REFERENCE("Timed C4"); +Jupiter::ReferenceString translated_Weapon_RemoteC4 = STRING_LITERAL_AS_REFERENCE("Remote C4"); +Jupiter::ReferenceString translated_Weapon_ProxyC4 = STRING_LITERAL_AS_REFERENCE("Proximity C4"); +Jupiter::ReferenceString translated_Weapon_ATMine = STRING_LITERAL_AS_REFERENCE("Anti-Tank Mine"); +Jupiter::ReferenceString translated_Weapon_IonCannonBeacon = STRING_LITERAL_AS_REFERENCE("Ion Cannon Beacon"); +Jupiter::ReferenceString translated_Weapon_NukeBeacon = STRING_LITERAL_AS_REFERENCE("Nuclear Missile Beacon"); Jupiter::ReferenceString translated_Weapon_DeployedC4 = STRING_LITERAL_AS_REFERENCE("Timed C4"); +Jupiter::ReferenceString translated_Weapon_DeployedTimedC4 = STRING_LITERAL_AS_REFERENCE("Timed C4"); Jupiter::ReferenceString translated_Weapon_DeployedRemoteC4 = STRING_LITERAL_AS_REFERENCE("Remote C4"); Jupiter::ReferenceString translated_Weapon_DeployedProxyC4 = STRING_LITERAL_AS_REFERENCE("Proximity C4"); +Jupiter::ReferenceString translated_Weapon_DeployedATMine = STRING_LITERAL_AS_REFERENCE("Anti-Tank Mine"); +Jupiter::ReferenceString translated_Weapon_DeployedIonCannonBeacon = STRING_LITERAL_AS_REFERENCE("Ion Cannon Beacon"); +Jupiter::ReferenceString translated_Weapon_DeployedNukeBeacon = STRING_LITERAL_AS_REFERENCE("Nuclear Missile Beacon"); + +/** Projectiles */ +Jupiter::ReferenceString translated_Projectile_EMPGrenade = STRING_LITERAL_AS_REFERENCE("EMP Grenade"); +Jupiter::ReferenceString translated_Projectile_SmokeGrenade = STRING_LITERAL_AS_REFERENCE("Smoke Grenade"); /** GDI Characters */ Jupiter::ReferenceString translated_GDI_Deadeye = STRING_LITERAL_AS_REFERENCE("Deadeye"); @@ -254,6 +276,9 @@ Jupiter::ReferenceString translated_Building_PowerPlant_GDI_Internals = STRING_L Jupiter::ReferenceString translated_Building_AdvancedGuardTower_Internals = STRING_LITERAL_AS_REFERENCE("Advanced Guard Tower"); Jupiter::ReferenceString translated_Building_Obelisk_Internals = STRING_LITERAL_AS_REFERENCE("Obelisk of Light"); +/** Other structures */ +Jupiter::ReferenceString translated_Building_Silo_Internals = STRING_LITERAL_AS_REFERENCE("Tiberium Silo"); + /** Defences */ Jupiter::ReferenceString translated_Defence_GuardTower = STRING_LITERAL_AS_REFERENCE("Guard Tower"); Jupiter::ReferenceString translated_Defence_Turret = STRING_LITERAL_AS_REFERENCE("Turret"); @@ -276,21 +301,32 @@ Jupiter::ReferenceString translated_IonCannonBeacon = STRING_LITERAL_AS_REFERENC Jupiter::ReferenceString translated_NukeBeacon = STRING_LITERAL_AS_REFERENCE("Nuclear Strike Beacon"); Jupiter::ReferenceString translated_KillZDamageType = STRING_LITERAL_AS_REFERENCE("Kill Zone"); -RenX::TeamType RenX::getTeam(char team) +RenX::TeamType RenX::getTeam(int teamNum) { - switch (team) + switch (teamNum) { - case 'g': - case 'G': + case 0: return RenX::TeamType::GDI; - case 'n': - case 'N': + case 1: return RenX::TeamType::Nod; + case 255: + return RenX::TeamType::None; default: return RenX::TeamType::Other; } } +RenX::TeamType RenX::getTeam(const Jupiter::ReadableString &team) +{ + if (team.equalsi("GDI")) + return RenX::TeamType::GDI; + if (team.equalsi("Nod")) + return RenX::TeamType::Nod; + if (team.isEmpty() || team.equalsi("Neutral") || team.equalsi("Civilians")) + return RenX::TeamType::None; + return RenX::TeamType::Other; +} + const Jupiter::ReadableString &RenX::getTeamColor(TeamType team) { switch (team) @@ -451,10 +487,33 @@ const Jupiter::ReadableString &RenX::translateName(const Jupiter::ReadableString else if (object.find(STRING_LITERAL_AS_REFERENCE("Weapon_")) == 0) { object.shiftRight(7); + if (object.equals(STRING_LITERAL_AS_REFERENCE("HeavyPistol"))) return translated_Weapon_HeavyPistol; + if (object.equals(STRING_LITERAL_AS_REFERENCE("Carbine"))) return translated_Weapon_Carbine; + if (object.equals(STRING_LITERAL_AS_REFERENCE("Airstrike_GDI"))) return translated_Weapon_Airstrike_GDI; + if (object.equals(STRING_LITERAL_AS_REFERENCE("Airstrike_Nod"))) return translated_Weapon_Airstrike_Nod; + if (object.equals(STRING_LITERAL_AS_REFERENCE("TiberiumFlechetteRifle"))) return translated_Weapon_TiberiumFlechetteRifle; + if (object.equals(STRING_LITERAL_AS_REFERENCE("TiberiumAutoRifle"))) return translated_Weapon_TiberiumAutoRifle; + if (object.equals(STRING_LITERAL_AS_REFERENCE("EMPGrenade"))) return translated_Weapon_EMPGrenade; + if (object.equals(STRING_LITERAL_AS_REFERENCE("SmokeGrenade"))) return translated_Weapon_SmokeGrenade; + if (object.equals(STRING_LITERAL_AS_REFERENCE("TimedC4"))) return translated_Weapon_TimedC4; + if (object.equals(STRING_LITERAL_AS_REFERENCE("RemoteC4"))) return translated_Weapon_RemoteC4; + if (object.equals(STRING_LITERAL_AS_REFERENCE("ProxyC4"))) return translated_Weapon_ProxyC4; + if (object.equals(STRING_LITERAL_AS_REFERENCE("ATMine"))) return translated_Weapon_ATMine; + if (object.equals(STRING_LITERAL_AS_REFERENCE("IonCannonBeacon"))) return translated_Weapon_IonCannonBeacon; + if (object.equals(STRING_LITERAL_AS_REFERENCE("NukeBeacon"))) return translated_Weapon_NukeBeacon; if (object.equals(STRING_LITERAL_AS_REFERENCE("DeployedC4"))) return translated_Weapon_DeployedC4; + if (object.equals(STRING_LITERAL_AS_REFERENCE("DeployedTimedC4"))) return translated_Weapon_DeployedTimedC4; if (object.equals(STRING_LITERAL_AS_REFERENCE("DeployedRemoteC4"))) return translated_Weapon_DeployedRemoteC4; if (object.equals(STRING_LITERAL_AS_REFERENCE("DeployedProxyC4"))) return translated_Weapon_DeployedProxyC4; - // TODO: Add more translations. + if (object.equals(STRING_LITERAL_AS_REFERENCE("DeployedATMine"))) return translated_Weapon_DeployedATMine; + if (object.equals(STRING_LITERAL_AS_REFERENCE("DeployedIonCannonBeacon"))) return translated_Weapon_DeployedIonCannonBeacon; + if (object.equals(STRING_LITERAL_AS_REFERENCE("DeployedNukeBeacon"))) return translated_Weapon_DeployedNukeBeacon; + } + else if (object.find(STRING_LITERAL_AS_REFERENCE("Projectile_")) == 0) + { + object.shiftRight(11); + if (object.equals(STRING_LITERAL_AS_REFERENCE("EMPGrenade"))) return translated_Projectile_EMPGrenade; + if (object.equals(STRING_LITERAL_AS_REFERENCE("SmokeGrenade"))) return translated_Projectile_SmokeGrenade; } else if (object.find(STRING_LITERAL_AS_REFERENCE("InventoryManager_")) == 0) { @@ -593,6 +652,9 @@ const Jupiter::ReadableString &RenX::translateName(const Jupiter::ReadableString /** Defense structures */ if (object.equals(STRING_LITERAL_AS_REFERENCE("AdvancedGuardTower_Internals"))) return translated_Building_AdvancedGuardTower_Internals; if (object.equals(STRING_LITERAL_AS_REFERENCE("Obelisk_Internals"))) return translated_Building_Obelisk_Internals; + + /** Other structures */ + if (object.equals(STRING_LITERAL_AS_REFERENCE("Silo_Internals"))) return translated_Building_Silo_Internals; } else if (object.find(STRING_LITERAL_AS_REFERENCE("Defence_")) == 0) { @@ -712,25 +774,6 @@ Jupiter::String RenX::getFormattedPlayerName(const RenX::PlayerInfo *player) return r; } -void RenX::sanitizeString(char *str) -{ - while (*str != 0) - { - switch (*str) - { - case '|': - *str = '/'; - break; - case '\\': - if (*(str + 1) == 0) *str = '/'; // So users get something at least. - break; - default: - break; - } - str++; - } -} - void RenX::sanitizeString(Jupiter::StringType &str) { if (str.isEmpty() == false) diff --git a/RenX.Core/RenX_Functions.h b/RenX.Core/RenX_Functions.h index ec07af7..8759b61 100644 --- a/RenX.Core/RenX_Functions.h +++ b/RenX.Core/RenX_Functions.h @@ -34,12 +34,20 @@ namespace RenX class Server; /** - * @brief Translates the first character of a team's name into a TeamType. + * @brief Translates a team's number into a TeamType. * - * @param First character of the team name. + * @param teamNum Team number * @return A corresponding TeamType. */ - RENX_API TeamType getTeam(char team); + RENX_API TeamType getTeam(int teamNum); + + /** + * @brief Translates team number into a TeamType. + * + * @param team Team name + * @return A corresponding TeamType. + */ + RENX_API TeamType getTeam(const Jupiter::ReadableString &team); /** * @brief Fetches the corresponding IRC color code for a team. @@ -127,12 +135,12 @@ namespace RenX RENX_API Jupiter::String getFormattedPlayerName(const RenX::PlayerInfo *player); /** - * @brief Sanitizes a string into a RCON-ready state. + * @brief Sanitizes a string into a RCON-ready state by replacing special + * characters with HTML-style character codes. * Note: This resolves the pipe character ('|') exploit. * * @brief str String to sanitize. */ - RENX_API void sanitizeString(char *str); RENX_API void sanitizeString(Jupiter::StringType &str); /** diff --git a/RenX.Core/RenX_Plugin.cpp b/RenX.Core/RenX_Plugin.cpp index 769b198..207879a 100644 --- a/RenX.Core/RenX_Plugin.cpp +++ b/RenX.Core/RenX_Plugin.cpp @@ -125,6 +125,21 @@ void RenX::Plugin::RenX_OnDisarm(Server *, const RenX::PlayerInfo *, const Jupit return; } +void RenX::Plugin::RenX_OnDisarm(Server *, const RenX::PlayerInfo *, const Jupiter::ReadableString &, const RenX::PlayerInfo *) +{ + return; +} + +void RenX::Plugin::RenX_OnExplode(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnExplode(Server *, const Jupiter::ReadableString &) +{ + return; +} + void RenX::Plugin::RenX_OnSuicide(Server *, const RenX::PlayerInfo *, const Jupiter::ReadableString &) { return; @@ -150,7 +165,7 @@ void RenX::Plugin::RenX_OnDie(Server *, const Jupiter::ReadableString &, const T return; } -void RenX::Plugin::RenX_OnDestroy(Server *, const RenX::PlayerInfo *, const Jupiter::ReadableString &, const Jupiter::ReadableString &, ObjectType) +void RenX::Plugin::RenX_OnDestroy(Server *, const RenX::PlayerInfo *, const Jupiter::ReadableString &, const TeamType &, const Jupiter::ReadableString &, ObjectType) { return; } @@ -170,6 +185,76 @@ void RenX::Plugin::RenX_OnNeutralize(Server *, const PlayerInfo *, const Jupiter return; } +void RenX::Plugin::RenX_OnCharacterPurchase(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnItemPurchase(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnWeaponPurchase(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnRefillPurchase(Server *, const PlayerInfo *) +{ + return; +} + +void RenX::Plugin::RenX_OnVehiclePurchase(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnVehicleSpawn(Server *, const TeamType &, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnSpawn(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnBotJoin(Server *, const PlayerInfo *) +{ + return; +} + +void RenX::Plugin::RenX_OnVehicleCrate(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnDeathCrate(Server *, const PlayerInfo *) +{ + return; +} + +void RenX::Plugin::RenX_OnMoneyCrate(Server *, const PlayerInfo *, int) +{ + return; +} + +void RenX::Plugin::RenX_OnCharacterCrate(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnSpyCrate(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +{ + return; +} + +void RenX::Plugin::RenX_OnRefillCrate(Server *, const PlayerInfo *) +{ + return; +} + void RenX::Plugin::RenX_OnSteal(Server *, const PlayerInfo *, const Jupiter::ReadableString &) { return; @@ -180,6 +265,11 @@ void RenX::Plugin::RenX_OnSteal(Server *, const PlayerInfo *, const Jupiter::Rea return; } +void RenX::Plugin::RenX_OnDonate(Server *, const PlayerInfo *, const PlayerInfo *, double) +{ + return; +} + void RenX::Plugin::RenX_OnGameOver(Server *, RenX::WinType, const TeamType &, int, int) { return; @@ -285,7 +375,7 @@ void RenX::Plugin::RenX_OnVoteCall(Server *, const TeamType &, const Jupiter::Re return; } -void RenX::Plugin::RenX_OnVoteOver(Server *server, const TeamType &, const Jupiter::ReadableString &, bool, int, int) +void RenX::Plugin::RenX_OnVoteOver(Server *, const TeamType &, const Jupiter::ReadableString &, bool, int, int) { return; } @@ -315,53 +405,32 @@ void RenX::Plugin::RenX_OnMap(Server *, const Jupiter::ReadableString &) return; } -void RenX::Plugin::RenX_OnDemoRecord(Server *server, const PlayerInfo *) -{ - return; -} - -void RenX::Plugin::RenX_OnDemoRecord(Server *server, const Jupiter::ReadableString &) +void RenX::Plugin::RenX_OnDemoRecord(Server *, const PlayerInfo *) { return; } - -void RenX::Plugin::RenX_OnDemo(Server *server, const Jupiter::ReadableString &) +void RenX::Plugin::RenX_OnDemoRecord(Server *, const Jupiter::ReadableString &) { return; } -void RenX::Plugin::RenX_OnLog(Server *, const Jupiter::ReadableString &) +void RenX::Plugin::RenX_OnDemoRecordStop(Server *) { return; } -void RenX::Plugin::RenX_XOnVersion(Server *, unsigned int) +void RenX::Plugin::RenX_OnDemo(Server *, const Jupiter::ReadableString &) { return; } -void RenX::Plugin::RenX_OnGrantCharacter(Server *, const PlayerInfo *, const Jupiter::ReadableString &) -{ - return; -} - -void RenX::Plugin::RenX_OnGrantWeapon(Server *, const PlayerInfo *, const Jupiter::ReadableString &) -{ - return; -} - -void RenX::Plugin::RenX_OnSpawnVehicle(Server *, const PlayerInfo *, const Jupiter::ReadableString &) -{ - return; -} - -void RenX::Plugin::RenX_OnSpawnVehicleNoOwner(Server *, const TeamType &, const Jupiter::ReadableString &) +void RenX::Plugin::RenX_OnLog(Server *, const Jupiter::ReadableString &) { return; } -void RenX::Plugin::RenX_OnMinePlace(Server *, const PlayerInfo *, const Jupiter::ReadableString &) +void RenX::Plugin::RenX_XOnVersion(Server *, unsigned int) { return; } diff --git a/RenX.Core/RenX_Plugin.h b/RenX.Core/RenX_Plugin.h index db6e553..26b3ae7 100644 --- a/RenX.Core/RenX_Plugin.h +++ b/RenX.Core/RenX_Plugin.h @@ -65,17 +65,35 @@ namespace RenX /** Game type logs */ virtual void RenX_OnDeploy(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &object); virtual void RenX_OnDisarm(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &object); + virtual void RenX_OnDisarm(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &object, const PlayerInfo *victim); + virtual void RenX_OnExplode(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &object); + virtual void RenX_OnExplode(Server *server, const Jupiter::ReadableString &object); virtual void RenX_OnSuicide(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &damageType); virtual void RenX_OnKill(Server *server, const PlayerInfo *player, const PlayerInfo *victim, const Jupiter::ReadableString &damageType); virtual void RenX_OnKill(Server *server, const Jupiter::ReadableString &killer, const TeamType &killerTeam, const PlayerInfo *victim, const Jupiter::ReadableString &damageType); virtual void RenX_OnDie(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &damageType); virtual void RenX_OnDie(Server *server, const Jupiter::ReadableString &object, const TeamType &objectTeam, const Jupiter::ReadableString &damageType); - virtual void RenX_OnDestroy(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &objectName, const Jupiter::ReadableString &damageType, ObjectType type); + virtual void RenX_OnDestroy(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &objectName, const TeamType &victimTeam, const Jupiter::ReadableString &damageType, ObjectType type); virtual void RenX_OnDestroy(Server *server, const Jupiter::ReadableString &killer, const TeamType &killerTeam, const Jupiter::ReadableString &objectName, const TeamType &objectTeam, const Jupiter::ReadableString &damageType, ObjectType type); virtual void RenX_OnCapture(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &building, const TeamType &oldTeam); virtual void RenX_OnNeutralize(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &building, const TeamType &oldTeam); + virtual void RenX_OnCharacterPurchase(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &character); + virtual void RenX_OnItemPurchase(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &item); + virtual void RenX_OnWeaponPurchase(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &weapon); + virtual void RenX_OnRefillPurchase(Server *server, const PlayerInfo *player); + virtual void RenX_OnVehiclePurchase(Server *server, const PlayerInfo *owner, const Jupiter::ReadableString &vehicle); + virtual void RenX_OnVehicleSpawn(Server *server, const TeamType &team, const Jupiter::ReadableString &vehicle); + virtual void RenX_OnSpawn(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &character); + virtual void RenX_OnBotJoin(Server *server, const PlayerInfo *player); + virtual void RenX_OnVehicleCrate(Server *server, const PlayerInfo *owner, const Jupiter::ReadableString &vehicle); + virtual void RenX_OnDeathCrate(Server *server, const PlayerInfo *player); + virtual void RenX_OnMoneyCrate(Server *server, const PlayerInfo *player, int amount); + virtual void RenX_OnCharacterCrate(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &character); + virtual void RenX_OnSpyCrate(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &character); + virtual void RenX_OnRefillCrate(Server *server, const PlayerInfo *player); virtual void RenX_OnSteal(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &vehicle); virtual void RenX_OnSteal(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &vehicle, const PlayerInfo *victim); + virtual void RenX_OnDonate(Server *server, const PlayerInfo *donor, const PlayerInfo *player, double amount); virtual void RenX_OnGameOver(Server *server, WinType winType, const TeamType &team, int gScore, int nScore); virtual void RenX_OnGame(Server *server, const Jupiter::ReadableString &raw); @@ -115,6 +133,7 @@ namespace RenX /** Demo Type Logs */ virtual void RenX_OnDemoRecord(Server *server, const PlayerInfo *player); virtual void RenX_OnDemoRecord(Server *server, const Jupiter::ReadableString &user); // Note: user is currently always empty. + virtual void RenX_OnDemoRecordStop(Server *server); virtual void RenX_OnDemo(Server *server, const Jupiter::ReadableString &raw); /** Other Logs */ @@ -122,11 +141,6 @@ namespace RenX /** eXtended RCON */ virtual void RenX_XOnVersion(Server *server, unsigned int version); - virtual void RenX_OnGrantCharacter(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &character); - virtual void RenX_OnGrantWeapon(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &weapon); - virtual void RenX_OnSpawnVehicle(Server *server, const PlayerInfo *owner, const Jupiter::ReadableString &vehicle); - virtual void RenX_OnSpawnVehicleNoOwner(Server *server, const TeamType &team, const Jupiter::ReadableString &vehicle); - virtual void RenX_OnMinePlace(Server *server, const PlayerInfo *player, const Jupiter::ReadableString &mine); virtual void RenX_XOnOther(Server *server, const Jupiter::ReadableString &raw); /** Command type */ diff --git a/RenX.Core/RenX_Server.cpp b/RenX.Core/RenX_Server.cpp index 02d74c4..1f18e5f 100644 --- a/RenX.Core/RenX_Server.cpp +++ b/RenX.Core/RenX_Server.cpp @@ -135,6 +135,16 @@ bool RenX::Server::isFirstDeath() const return RenX::Server::firstDeath; } +bool RenX::Server::isFirstAction() const +{ + return RenX::Server::firstAction; +} + +bool RenX::Server::isSeamless() const +{ + return RenX::Server::seamless; +} + bool RenX::Server::isPublicLogChanType(int type) const { return RenX::Server::logChanType == type; @@ -152,17 +162,11 @@ bool RenX::Server::isLogChanType(int type) const int RenX::Server::send(const Jupiter::ReadableString &command) { - char *t = new char[command.size() + 2]; - *t = 'c'; - for (size_t i = 0; i != command.size(); i++) - t[i + 1] = command.get(i); - t[command.size() + 1] = '\n'; - int r; - if (RenX::Server::profile->mustSanitize) - RenX::sanitizeString(t); - r = RenX::Server::sock.send(t, command.size() + 2); - delete[] t; - return r; + Jupiter::String cmd(command.size() + 2); + cmd = 'c'; + cmd += command; + cmd += '\n'; + return RenX::Server::sock.send(cmd); } int RenX::Server::sendMessage(const Jupiter::ReadableString &message) @@ -199,9 +203,18 @@ int RenX::Server::sendMessage(const RenX::PlayerInfo *player, const Jupiter::Rea if (RenX::Server::profile->privateMessages == false) return RenX::Server::sendMessage(message); + Jupiter::String cmd(message.size() + 28); if (RenX::Server::rconVersion <= 2) - 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())); + cmd = STRING_LITERAL_AS_REFERENCE("cevaprivatesay pid"); + else + cmd = STRING_LITERAL_AS_REFERENCE("chostprivatesay pid"); + cmd += Jupiter::StringS::Format("%d ", player->id); + cmd += message; + cmd += '\n'; + RenX::sanitizeString(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())); } int RenX::Server::sendData(const Jupiter::ReadableString &data) @@ -376,12 +389,70 @@ bool RenX::Server::updateClientList() 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("cclientlist\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")); + //return RenX::Server::sock.send(STRING_LITERAL_AS_REFERENCE("cclientlist\n")) > 0; +} + +bool RenX::Server::gameover() +{ + return RenX::Server::rconVersion >= 3 && RenX::Server::send(STRING_LITERAL_AS_REFERENCE("endmap")) > 0; +} + +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; +} + +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; +} + +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; +} + +bool RenX::Server::cancelVote(const RenX::TeamType team) +{ + if (RenX::Server::rconVersion < 3) + return false; + switch (team) + { + default: + return RenX::Server::send(STRING_LITERAL_AS_REFERENCE("cancelvote -1")) > 0; + case TeamType::GDI: + return RenX::Server::send(STRING_LITERAL_AS_REFERENCE("cancelvote 0")) > 0; + case TeamType::Nod: + return RenX::Server::send(STRING_LITERAL_AS_REFERENCE("cancelvote 1")) > 0; + } +} + +bool RenX::Server::swapTeams() +{ + return RenX::Server::rconVersion >= 3 && RenX::Server::send(STRING_LITERAL_AS_REFERENCE("swapteams")) > 0; +} + +bool RenX::Server::recordDemo() +{ + return RenX::Server::rconVersion >= 3 && RenX::Server::send(STRING_LITERAL_AS_REFERENCE("recorddemo")) > 0; +} + +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; +} + +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; } 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::xRconVersion != 0 && RenX::Server::sock.send(Jupiter::StringS::Format("_x\x04%d%c%.4f\n", id, RenX::DelimC, 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) @@ -389,14 +460,19 @@ bool RenX::Server::giveCredits(RenX::PlayerInfo *player, double credits) return RenX::Server::giveCredits(player->id, credits); } -bool RenX::Server::changeTeam(int id, 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\n", id, RenX::DelimC, options)) > 0; + if (resetCredits) + 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, unsigned char options) +bool RenX::Server::changeTeam(RenX::PlayerInfo *player, bool resetCredits) { - return RenX::Server::changeTeam(player->id, options); + return RenX::Server::changeTeam(player->id, resetCredits); } bool RenX::Server::setTeam(int id, int team, unsigned char options) @@ -729,14 +805,23 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) this->silenceJoins = false; } }; + auto setPlayerSteamID = [this](RenX::PlayerInfo *player, uint64_t steamid) + { + player->steamid = steamid; + if (this->uuidMode == 0) + player->uuid = this->formatSteamID(steamid); + }; + auto setPlayerName = [this](RenX::PlayerInfo *player, const Jupiter::ReadableString &name) + { + player->name = name; + if (this->uuidMode == 1) + player->uuid = name; + }; auto parsePlayerData = [this](const Jupiter::ReadableString &data, Jupiter::ReferenceString &name, TeamType &team, int &id, bool &isBot) { Jupiter::ReferenceString idToken = Jupiter::ReferenceString::getToken(data, 1, ','); name = Jupiter::ReferenceString::gotoToken(data, 2, ','); - if (data[0] == ',') - team = TeamType::Other; - else - team = RenX::getTeam(data[0]); + team = RenX::getTeam(Jupiter::ReferenceString::getToken(data, 0, ',')); if (idToken.get(0) == 'b') { idToken.shiftRight(1); @@ -760,9 +845,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } if (r->steamid == 0U && steamid != 0U) { - r->steamid = steamid; - if (this->uuidMode == 0) - r->uuid = this->formatSteamID(r); + setPlayerSteamID(r, steamid); checkBans = true; } }; @@ -771,15 +854,13 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) checkBans = true; r = new RenX::PlayerInfo(); r->id = id; - r->name = name; + setPlayerName(r, name); checkMissing(); if (r->isBot = isBot) r->formatNamePrefix = IRCCOLOR "05[B]"; r->joinTime = time(nullptr); if (id != 0) this->players.add(r); - if (this->uuidMode == 1) - r->uuid = r->name; for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnPlayerCreate(this, r); @@ -818,6 +899,21 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) PARSE_PLAYER_DATA_P(token); return getPlayerOrAdd(name, id, team, isBot, 0U, Jupiter::ReferenceString::empty); }; + auto resetPlayerCharacter = [](PlayerInfo *player) + { + switch (player->team) + { + case TeamType::GDI: + player->character = STRING_LITERAL_AS_REFERENCE("Rx_FamilyInfo_GDI_Soldier"); + break; + case TeamType::Nod: + player->character = STRING_LITERAL_AS_REFERENCE("Rx_FamilyInfo_Nod_Soldier"); + break; + default: + player->character = Jupiter::ReferenceString::empty; + break; + } + }; if (buff.size() != 0) { @@ -849,9 +945,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) if (steamToken.equals("-----NO-STEAM-----") == false) steamid = steamToken.asUnsignedLongLong(); - - if (teamToken.isEmpty() == false) - team = RenX::getTeam(teamToken.get(0)); + team = RenX::getTeam(teamToken); if (adminToken.equalsi("None")) getPlayerOrAdd(buff.getToken(5, RenX::DelimC), id, team, isBot, steamid, buff.getToken(1, RenX::DelimC)); @@ -860,6 +954,227 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } header.shiftLeft(1); } + else if (this->lastCommand.equalsi("clientvarlist")) + { + buff.shiftRight(1); + if (this->commandListFormat.isEmpty()) + this->commandListFormat = buff; + else + { + /* + lRCON Command; Conn4 executed: clientvarlist PlayerLog Kills PlayerKills BotKills Deaths Score Credits Character BoundVehicle Vehicle Spy RemoteC4 ATMine KDR Ping Admin Steam IP ID Name Team TeamNum + rPlayerLog Kills PlayerKills BotKills Deaths Score Credits Character BoundVehicle Vehicle Spy RemoteC4 ATMine KDR Ping Admin Steam IP ID Name Team TeamNum + rGDI,256,EKT-J 0 0 0 0 0 5217.9629 Rx_FamilyInfo_GDI_Soldier   False 0 0 0.0000 8 None 0x0110000104AE0666 127.0.0.1 256 EKT-J GDI 0 + */ + Jupiter::INIFile::Section table; + size_t i = this->commandListFormat.tokenCount(RenX::DelimC); + while (i-- != 0) + table.set(this->commandListFormat.getToken(i, RenX::DelimC), buff.getToken(i, RenX::DelimC)); + auto parse = [&table](RenX::PlayerInfo *player) + { + Jupiter::INIFile::Section::KeyValuePair *pair; + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Kills")); + if (pair != nullptr) + player->kills = pair->getValue().asUnsignedInt(); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Deaths")); + if (pair != nullptr) + player->deaths = pair->getValue().asUnsignedInt(); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Score")); + if (pair != nullptr) + player->score = static_cast(pair->getValue().asDouble()); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Credits")); + if (pair != nullptr) + player->credits = static_cast(pair->getValue().asDouble()); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Character")); + if (pair != nullptr) + player->character = pair->getValue(); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Vehicle")); + if (pair != nullptr) + player->vehicle = pair->getValue(); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Ping")); + if (pair != nullptr) + player->ping = pair->getValue().asUnsignedInt(); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Admin")); + if (pair != nullptr) + player->adminType = pair->getValue(); + }; + Jupiter::INIFile::Section::KeyValuePair *pair = table.getPair(STRING_LITERAL_AS_REFERENCE("PlayerLog")); + if (pair != nullptr) + parse(getPlayerOrAdd(Jupiter::ReferenceString::getToken(pair->getValue(), 2, ','), Jupiter::ReferenceString::getToken(pair->getValue(), 1, ',').asInt(), RenX::getTeam(Jupiter::ReferenceString::getToken(pair->getValue(), 0, ',')), false, table.get(STRING_LITERAL_AS_REFERENCE("STEAM")).asUnsignedLongLong(), table.get(STRING_LITERAL_AS_REFERENCE("IP")))); + else + { + Jupiter::INIFile::Section::KeyValuePair *namePair = table.getPair(STRING_LITERAL_AS_REFERENCE("Name")); + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("ID")); + + if (pair != nullptr) + { + RenX::PlayerInfo *player = getPlayer(pair->getValue().asInt()); + if (player != nullptr) + { + if (player->name.isEmpty()) + player->name = table.get(STRING_LITERAL_AS_REFERENCE("Name")); + if (player->ip.isEmpty()) + player->ip = table.get(STRING_LITERAL_AS_REFERENCE("IP")); + if (player->steamid == 0) + setPlayerSteamID(player, table.get(STRING_LITERAL_AS_REFERENCE("STEAM")).asUnsignedLongLong()); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("TeamNum")); + if (pair != nullptr) + player->team = RenX::getTeam(pair->getValue().asInt()); + else + { + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Team")); + if (pair != nullptr) + player->team = RenX::getTeam(pair->getValue()); + } + + parse(player); + } + // I *could* try and fetch a player by name, but that seems like it *could* open a security hole. + // In addition, would I update their ID? + } + else if (namePair != nullptr) + { + RenX::PlayerInfo *player = getPlayerByName(namePair->getValue()); + if (player != nullptr) + { + if (player->ip.isEmpty()) + player->ip = table.get(STRING_LITERAL_AS_REFERENCE("IP")); + if (player->steamid == 0) + setPlayerSteamID(player, table.get(STRING_LITERAL_AS_REFERENCE("STEAM")).asUnsignedLongLong()); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("TeamNum")); + if (pair != nullptr) + player->team = RenX::getTeam(pair->getValue().asInt()); + else + { + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Team")); + if (pair != nullptr) + player->team = RenX::getTeam(pair->getValue()); + } + + parse(player); + } + // No other way to identify player -- worthless command format. + } + } + } + buff.shiftLeft(1); + } + else if (this->lastCommand.equalsi("botlist")) + { + // Team,ID,Name + buff.shiftRight(1); + if (commandListFormat.isEmpty()) + commandListFormat = buff; + else + parseGetPlayerOrAdd(buff); + buff.shiftLeft(1); + } + else if (this->lastCommand.equalsi("botvarlist")) + { + buff.shiftRight(1); + if (this->commandListFormat.isEmpty()) + this->commandListFormat = buff; + else + { + /* + lRCON Command; Conn4 executed: clientvarlist PlayerLog Kills PlayerKills BotKills Deaths Score Credits Character BoundVehicle Vehicle Spy RemoteC4 ATMine KDR Ping Admin Steam IP ID Name Team TeamNum + rPlayerLog Kills PlayerKills BotKills Deaths Score Credits Character BoundVehicle Vehicle Spy RemoteC4 ATMine KDR Ping Admin Steam IP ID Name Team TeamNum + rGDI,256,EKT-J 0 0 0 0 0 5217.9629 Rx_FamilyInfo_GDI_Soldier   False 0 0 0.0000 8 None 0x0110000104AE0666 127.0.0.1 256 EKT-J GDI 0 + */ + Jupiter::INIFile::Section table; + size_t i = this->commandListFormat.tokenCount(RenX::DelimC); + while (i-- != 0) + table.set(this->commandListFormat.getToken(i, RenX::DelimC), buff.getToken(i, RenX::DelimC)); + auto parse = [&table](RenX::PlayerInfo *player) + { + Jupiter::INIFile::Section::KeyValuePair *pair; + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Kills")); + if (pair != nullptr) + player->kills = pair->getValue().asUnsignedInt(); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Deaths")); + if (pair != nullptr) + player->deaths = pair->getValue().asUnsignedInt(); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Score")); + if (pair != nullptr) + player->score = static_cast(pair->getValue().asDouble()); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Credits")); + if (pair != nullptr) + player->credits = static_cast(pair->getValue().asDouble()); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Character")); + if (pair != nullptr) + player->character = pair->getValue(); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Vehicle")); + if (pair != nullptr) + player->vehicle = pair->getValue(); + }; + Jupiter::INIFile::Section::KeyValuePair *pair = table.getPair(STRING_LITERAL_AS_REFERENCE("PlayerLog")); + if (pair != nullptr) + parse(getPlayerOrAdd(Jupiter::ReferenceString::getToken(pair->getValue(), 2, ','), Jupiter::ReferenceString::getToken(pair->getValue(), 1, ',').substring(1).asInt(), RenX::getTeam(Jupiter::ReferenceString::getToken(pair->getValue(), 0, ',')), true, 0ULL, Jupiter::ReferenceString::empty)); + else + { + Jupiter::INIFile::Section::KeyValuePair *namePair = table.getPair(STRING_LITERAL_AS_REFERENCE("Name")); + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("ID")); + + if (pair != nullptr) + { + RenX::PlayerInfo *player = getPlayer(pair->getValue().asInt()); + if (player != nullptr) + { + if (player->name.isEmpty()) + player->name = table.get(STRING_LITERAL_AS_REFERENCE("Name")); + + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("TeamNum")); + if (pair != nullptr) + player->team = RenX::getTeam(pair->getValue().asInt()); + else + { + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Team")); + if (pair != nullptr) + player->team = RenX::getTeam(pair->getValue()); + } + + parse(player); + } + } + else if (namePair != nullptr) + { + RenX::PlayerInfo *player = getPlayerByName(namePair->getValue()); + if (player != nullptr) + { + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("TeamNum")); + if (pair != nullptr) + player->team = RenX::getTeam(pair->getValue().asInt()); + else + { + pair = table.getPair(STRING_LITERAL_AS_REFERENCE("Team")); + if (pair != nullptr) + player->team = RenX::getTeam(pair->getValue()); + } + + parse(player); + } + // No other way to identify player -- worthless command format. + } + } + } + buff.shiftLeft(1); + } break; case 'l': if (RenX::Server::rconVersion >= 3) @@ -870,7 +1185,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) { if (subHeader.equals("Deployed;")) { - // Beacon | "by" | Player + // Object (Beacon/Mine) | Player + // Object (Beacon/Mine) | Player | "on" | Surface RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(4, RenX::DelimC)); Jupiter::ReferenceString objectType = buff.getToken(2, RenX::DelimC); if (objectType.match("*Beacon")) @@ -881,35 +1197,47 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } else if (subHeader.equals("Disarmed;")) { - // Beacon | "by" | Player + // Object (Beacon/Mine) | "by" | Player + // Object (Beacon/Mine) | "by" | Player | "owned by" | Owner RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(4, RenX::DelimC)); Jupiter::ReferenceString objectType = buff.getToken(2, RenX::DelimC); if (objectType.match("*Beacon")) player->beaconDisarms++; - for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnDisarm(this, player, objectType); + + if (buff.getToken(5, RenX::DelimC).equals("owned by")) + { + RenX::PlayerInfo *victim = parseGetPlayerOrAdd(buff.getToken(6, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnDisarm(this, player, objectType, victim); + } + else + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnDisarm(this, player, objectType); onAction(); } - /*else if (subHeader.equals("Exploded;")) + else if (subHeader.equals("Exploded;")) { + // Explosive | "at" | Location // Explosive | "at" | Location | "by" | Owner + Jupiter::ReferenceString explosive = buff.getToken(2, RenX::DelimC); + if (buff.getToken(5, RenX::DelimC).equals("by")) + { + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(6, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnExplode(this, player, explosive); + } + else + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnExplode(this, explosive); onAction(); - }*/ + } else if (subHeader.equals("Captured;")) { - // Team ',' Building | "by" | Player + // Team ',' Building | "id" | Building ID | "by" | Player Jupiter::ReferenceString teamBuildingToken = buff.getToken(2, RenX::DelimC); - Jupiter::ReferenceString teamToken = teamBuildingToken.getToken(0, ','); Jupiter::ReferenceString building = teamBuildingToken.getToken(1, ','); - if (building.size() > 2) // temporary fix to remove unique identifier from building token - { - if (building.get(building.size() - 2) == '_') - building.truncate(2); - else if (building.size() > 3 && building.get(building.size() - 3) == '_') - building.truncate(3); - } - TeamType oldTeam = teamToken.isEmpty() ? TeamType::None : RenX::getTeam(teamToken.get(0)); - RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(4, RenX::DelimC)); + TeamType oldTeam = RenX::getTeam(teamBuildingToken.getToken(0, ',')); + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(6, RenX::DelimC)); player->captures++; for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnCapture(this, player, building, oldTeam); @@ -917,23 +1245,137 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } else if (subHeader.equals("Neutralized;")) { - // Team ',' Building | "by" | Player + // Team ',' Building | "id" | Building ID | "by" | Player Jupiter::ReferenceString teamBuildingToken = buff.getToken(2, RenX::DelimC); - Jupiter::ReferenceString teamToken = teamBuildingToken.getToken(0, ','); Jupiter::ReferenceString building = teamBuildingToken.getToken(1, ','); - if (building.size() > 2) // temporary fix to remove unique identifier from building token - { - if (building.get(building.size() - 2) == '_') - building.truncate(2); - else if (building.size() > 3 && building.get(building.size() - 3) == '_') - building.truncate(3); - } - TeamType oldTeam = teamToken.isEmpty() ? TeamType::None : RenX::getTeam(teamToken.get(0)); - RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(4, RenX::DelimC)); + TeamType oldTeam = RenX::getTeam(teamBuildingToken.getToken(0, ',')); + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(6, RenX::DelimC)); for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnNeutralize(this, player, building, oldTeam); onAction(); } + else if (subHeader.equals("Purchase;")) + { + // "character" | Character | "by" | Player + // "item" | Item | "by" | Player + // "weapon" | Weapon | "by" | Player + // "refill" | Player + // "vehicle" | Vehicle | "by" | Player + Jupiter::ReferenceString type = buff.getToken(2, RenX::DelimC); + Jupiter::ReferenceString obj = buff.getToken(3, RenX::DelimC); + if (type.equals("character")) + { + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(5, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnCharacterPurchase(this, player, obj); + player->character = obj; + } + else if (type.equals("item")) + { + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(5, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnItemPurchase(this, player, obj); + } + else if (type.equals("weapon")) + { + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(5, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnWeaponPurchase(this, player, obj); + } + else if (type.equals("refill")) + { + RenX::PlayerInfo *player = parseGetPlayerOrAdd(obj); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnRefillPurchase(this, player); + } + else if (type.equals("vehicle")) + { + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(5, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnVehiclePurchase(this, player, obj); + } + } + else if (subHeader.equals("Spawn;")) + { + // "vehicle" | Vehicle Team, Vehicle + // "player" | Player | "character" | Character + // "bot" | Player + if (buff.getToken(2, RenX::DelimC).equals("vehicle")) + { + Jupiter::ReferenceString vehicle = buff.getToken(3, RenX::DelimC); + Jupiter::ReferenceString vehicleTeamToken = vehicle.getToken(0, ','); + vehicle.shiftRight(vehicleTeamToken.size() + 1); + TeamType team = RenX::getTeam(vehicleTeamToken); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnVehicleSpawn(this, team, vehicle); + } + else if (buff.getToken(2, RenX::DelimC).equals("player")) + { + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(3, RenX::DelimC)); + Jupiter::ReferenceString character = buff.getToken(5, RenX::DelimC); + player->character = character; + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnSpawn(this, player, character); + } + else if (buff.getToken(2, RenX::DelimC).equals("bot")) + { + RenX::PlayerInfo *bot = parseGetPlayerOrAdd(buff.getToken(3, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnBotJoin(this, bot); + } + } + else if (subHeader.equals("Crate;")) + { + // "vehicle" | Vehicle | "by" | Player + // "death" | "by" | Player + // "money" | Amount | "by" | Player + // "character" | Character | "by" | Player + // "spy" | Character | "by" | Player + // "refill" | "by" | Player + Jupiter::ReferenceString type = buff.getToken(2, RenX::DelimC); + if (type.equals("vehicle")) + { + Jupiter::ReferenceString vehicle = buff.getToken(3, RenX::DelimC); + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(5, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnVehicleCrate(this, player, vehicle); + } + else if (type.equals("death")) + { + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(4, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnDeathCrate(this, player); + } + else if (type.equals("money")) + { + int amount = buff.getToken(3, RenX::DelimC).asInt(); + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(5, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnMoneyCrate(this, player, amount); + } + else if (type.equals("character")) + { + Jupiter::ReferenceString character = buff.getToken(3, RenX::DelimC); + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(5, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnCharacterCrate(this, player, character); + player->character = character; + } + else if (type.equals("spy")) + { + Jupiter::ReferenceString character = buff.getToken(3, RenX::DelimC); + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(5, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnSpyCrate(this, player, character); + player->character = character; + } + else if (type.equals("refill")) + { + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(4, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnRefillCrate(this, player); + } + } else if (subHeader.equals("Death;")) { // "player" | Player | "by" | Killer Player | "with" | Damage Type @@ -944,7 +1386,6 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) if (playerToken.isEmpty() == false) { RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerToken); - player->deaths++; Jupiter::ReferenceString type = buff.getToken(4, RenX::DelimC); Jupiter::ReferenceString damageType; if (type.equals("by")) @@ -953,15 +1394,16 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) Jupiter::ReferenceString killerData = buff.getToken(5, RenX::DelimC); Jupiter::ReferenceString kName = killerData.getToken(2, ','); Jupiter::ReferenceString kIDToken = killerData.getToken(1, ','); - Jupiter::ReferenceString kTeamToken = killerData.getToken(0, ','); - RenX::TeamType vTeam = TeamType::Other; - if (kTeamToken.isEmpty() == false) - vTeam = RenX::getTeam(kTeamToken.get(0)); + RenX::TeamType vTeam = RenX::getTeam(killerData.getToken(0, ',')); if (kIDToken.equals("ai") || kIDToken.isEmpty()) + { + player->deaths++; for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnKill(this, kName, vTeam, player, damageType); + } else { + player->deaths++; int kID = 0; bool kIsBot = false; if (kIDToken.get(0) == 'b') @@ -983,17 +1425,20 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } else if (type.equals("died by")) { + player->deaths++; damageType = buff.getToken(5, RenX::DelimC); for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnDie(this, player, damageType); } else if (type.equals("suicide by")) { + player->deaths++; player->suicides++; damageType = buff.getToken(5, RenX::DelimC); for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnSuicide(this, player, damageType); } + resetPlayerCharacter(player); } onAction(); } @@ -1042,14 +1487,11 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) if (buff.getToken(4, RenX::DelimC).equals("by")) { Jupiter::ReferenceString killerToken = buff.getToken(5, RenX::DelimC); - Jupiter::ReferenceString teamToken = killerToken.getToken(0, ','); Jupiter::ReferenceString idToken = killerToken.getToken(1, ','); Jupiter::ReferenceString name = killerToken.gotoToken(2, ','); Jupiter::ReferenceString damageType = buff.getToken(7, RenX::DelimC); - RenX::TeamType team = TeamType::Other; - if (teamToken.isEmpty() == false) - team = RenX::getTeam(teamToken.get(0)); + RenX::TeamType team = RenX::getTeam(killerToken.getToken(0, ',')); if (idToken.equals("ai") || idToken.isEmpty()) for (size_t i = 0; i < xPlugins.size(); i++) @@ -1080,12 +1522,24 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) break; } for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnDestroy(this, player, objectName, damageType, type); + xPlugins.get(i)->RenX_OnDestroy(this, player, objectName, RenX::getEnemy(player->team), damageType, type); } } } onAction(); } + else if (subHeader.equals("Donated;")) + { + // Amount | "to" | Recipient | "by" | Donor + if (buff.getToken(5, RenX::DelimC).equals("by")) + { + double amount = buff.getToken(2, RenX::DelimC).asDouble(); + RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(4, RenX::DelimC)); + RenX::PlayerInfo *donor = parseGetPlayerOrAdd(buff.getToken(6, RenX::DelimC)); + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnDonate(this, donor, player, amount); + } + } else if (subHeader.equals("MatchEnd;")) { // "winner" | Winner | Reason("TimeLimit" etc) | "GDI=" GDI Score | "Nod=" Nod Score @@ -1102,10 +1556,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) else if (sWinType.equals("triggered")) winType = WinType::Shutdown; - Jupiter::ReferenceString winTeam = buff.getToken(3, RenX::DelimC); - TeamType team = TeamType::Other; - if (winTeam.isEmpty() == false) - team = RenX::getTeam(winTeam.get(0)); + TeamType team = RenX::getTeam(buff.getToken(3, RenX::DelimC)); int gScore = buff.getToken(5, RenX::DelimC).getToken(1, '=').asInt(); int nScore = buff.getToken(6, RenX::DelimC).getToken(1, '=').asInt(); @@ -1186,14 +1637,13 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) // Player | "joined" | Team // Player | "joined" | Team | "left" | Old Team RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(2, RenX::DelimC)); + resetPlayerCharacter(player); if (buff.tokenCount(RenX::DelimC) > 4) { - Jupiter::ReferenceString oldTeamToken = buff.getToken(6, RenX::DelimC); - RenX::TeamType oldTeam = TeamType::Other; - if (oldTeamToken.isEmpty() == false) - oldTeam = RenX::getTeam(oldTeamToken.get(0)); - for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnTeamChange(this, player, oldTeam); + RenX::TeamType oldTeam = RenX::getTeam(buff.getToken(6, RenX::DelimC)); + if (oldTeam != RenX::TeamType::None) + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnTeamChange(this, player, oldTeam); } } else if (subHeader.equals("Exit;")) @@ -1209,7 +1659,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) { // Player | "to:" | New Name RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(2, RenX::DelimC)); - Jupiter::ReferenceString newName = buff.getToken(3, RenX::DelimC); + Jupiter::ReferenceString newName = buff.getToken(4, RenX::DelimC); for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnNameChange(this, player, newName); player->name = newName; @@ -1498,11 +1948,12 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) { // Map | Mode="seamless" / "nonseamless" Jupiter::ReferenceString map = buff.getToken(2, RenX::DelimC); - bool seamless = true; - if (buff.getToken(3, RenX::DelimC).equals("nonseamless")) + if (buff.getToken(3, RenX::DelimC).equals("seamless")) + this->seamless = true; + else { + this->seamless = false; this->silenceParts = true; - seamless = false; } for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnMapChange(this, map, seamless); @@ -1544,6 +1995,12 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) xPlugins.get(i)->RenX_OnDemoRecord(this, user); } } + else if (subHeader.equals("RecordStop;")) + { + // Empty + for (size_t i = 0; i < xPlugins.size(); i++) + xPlugins.get(i)->RenX_OnDemoRecordStop(this); + } else { Jupiter::ReferenceString raw = buff.gotoToken(1, RenX::DelimC); @@ -1595,9 +2052,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) { RenX::PlayerInfo *player = parseGetPlayerOrAdd(playerData); Jupiter::ReferenceString victimData = buff.getToken(3, RenX::DelimC); - Jupiter::ReferenceString vTeamToken = victimData.getToken(0, ','); Jupiter::ReferenceString vidToken = victimData.getToken(1, ','); - if (vTeamToken.size() != 0 && vidToken.size() != 0) + if (vidToken.size() != 0) { Jupiter::ReferenceString vname = victimData.getToken(2, ','); int vid; @@ -1608,7 +2064,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) visBot = true; } vid = vidToken.asInt(10); - TeamType vteam = RenX::getTeam(vTeamToken.get(0)); + 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++; @@ -1665,12 +2121,12 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) player->vehicleKills++; } for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnDestroy(this, player, victim, damageType, type); + 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[0]); + 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); @@ -1684,7 +2140,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) iWinType = WinType::Base; this->needsCList = true; - if (this->profile->disconnectOnGameOver) + if (!this->seamless) this->silenceParts = true; onPreGameOver(iWinType, team, gScore, nScore); @@ -1708,7 +2164,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) int nScore = buff.getToken(3, RenX::DelimC).gotoToken(1, '=').asInt(10); this->needsCList = true; - if (this->profile->disconnectOnGameOver) + if (!this->seamless) this->silenceParts = true; if (gScore == nScore) @@ -1720,7 +2176,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } else { - TeamType winTeam = gScore > nScore ? RenX::getTeam('G') : RenX::getTeam('N'); + 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); @@ -1779,9 +2235,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) 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); - player->name = newName; - if (RenX::Server::uuidMode == 1) - player->uuid = player->name; + setPlayerName(player, newName); onAction(); } } @@ -1890,20 +2344,14 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) if (steamid.equals("-----NO")) // RCONv2-2a { steamid = ""; - Jupiter::ReferenceString &teamToken = playerData.getToken(4, CListDelim); - if (teamToken.isEmpty()) - break; - team = getTeam(teamToken.get(0)); + team = getTeam(playerData.getToken(4, CListDelim)); name = playerData.gotoToken(5, CListDelim); } else { if (steamid.equals("-----NO-STEAM-----")) // RCONv2-2.5a steamid = ""; - Jupiter::ReferenceString &teamToken = playerData.getToken(3, CListDelim); - if (teamToken.isEmpty()) - break; - team = getTeam(teamToken.get(0)); + team = getTeam(playerData.getToken(3, CListDelim)); name = playerData.gotoToken(4, CListDelim); } @@ -2017,15 +2465,20 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) { RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(1, RenX::DelimC)); Jupiter::ReferenceString character = buff.getToken(2, RenX::DelimC); - for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnGrantCharacter(this, player, character); + fputs("Character: \"", stdout); + character.print(stdout); + puts("\""); + 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")) { - RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(1, RenX::DelimC)); + // Support dropped + /*RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(1, RenX::DelimC)); for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnGrantWeapon(this, player, buff.getToken(2, RenX::DelimC)); + xPlugins.get(i)->RenX_OnWeaponPurchase(this, player, buff.getToken(2, RenX::DelimC));*/ } else if (header.equals("spawn_vehicle")) { @@ -2034,24 +2487,20 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) { RenX::PlayerInfo *player = parseGetPlayerOrAdd(buff.getToken(3, RenX::DelimC)); for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnSpawnVehicle(this, player, buff.getToken(2, RenX::DelimC)); + xPlugins.get(i)->RenX_OnVehiclePurchase(this, player, buff.getToken(2, RenX::DelimC)); } else { - RenX::TeamType team; - if (tok1.isEmpty()) - team = TeamType::Other; - else - team = RenX::getTeam(tok1.get(0)); + RenX::TeamType team = RenX::getTeam(tok1); for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnSpawnVehicleNoOwner(this, team, buff.getToken(2, RenX::DelimC)); + 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_OnMinePlace(this, player, buff.getToken(2, RenX::DelimC)); + xPlugins.get(i)->RenX_OnDeploy(this, player, buff.getToken(2, RenX::DelimC)); } /*else if (header.equals("mlimit_inc")) { @@ -2072,11 +2521,11 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) killerData.data = kData.substring(1); victimData.type = vData[0]; victimData.data = vData.substring(1); - if (killerData.type == 1) // These are already handled in standard RCON logs; update models and move on. + if (killerData.type == 1) { RenX::PlayerInfo *player = parseGetPlayerOrAdd(killerData.data.gotoToken(1, ',')); player->character = RenX::getCharacter(killerData.data.getToken(0, ',')); - if (victimData.type == 1) + 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) { @@ -2084,12 +2533,27 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) 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 && victimData.data.size() != 0) + if (victimData.type == 2) { - TeamType victimTeam = RenX::getTeam(victimData.data.getToken(0, ',').get(0)); + 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); @@ -2097,18 +2561,22 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) } else if (killerData.data.size() != 0) // Non-player killer (log!) { - TeamType killerTeam = RenX::getTeam(killerData.data.getToken(0, ',').get(0)); + TeamType killerTeam = RenX::getTeam(killerData.data.getToken(0, ',')); killerData.data = killerData.data.gotoToken(1, ','); if (victimData.type == 1) // Non-player killed player { - RenX::PlayerInfo *player = parseGetPlayerOrAdd(victimData.data.gotoToken(1, ',')); - player->character = RenX::getCharacter(victimData.data.getToken(0, ',')); - for (size_t i = 0; i < xPlugins.size(); i++) - xPlugins.get(i)->RenX_OnKill(this, killerData.data, killerTeam, player, damageType); + 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, ',').get(0)); + TeamType victimTeam = RenX::getTeam(victimData.data.getToken(0, ',')); victimData.data = victimData.data.gotoToken(1, ','); ObjectType type; if (victimData.data.match("Rx_Building_*")) @@ -2137,6 +2605,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) buff.shiftRight(1); for (size_t i = 0; i < xPlugins.size(); i++) xPlugins.get(i)->RenX_OnCommand(this, buff); + this->commandListFormat.set(Jupiter::ReferenceString::empty); + this->lastCommand = Jupiter::ReferenceString::empty; buff.shiftLeft(1); break; @@ -2162,7 +2632,10 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) RenX::Server::updateClientList(); if (this->profile->disconnectOnGameOver == false) + { this->firstGame = true; + this->seamless = true; + } else if (this->firstGame == false) { this->firstAction = false; diff --git a/RenX.Core/RenX_Server.h b/RenX.Core/RenX_Server.h index adf29d5..7b70248 100644 --- a/RenX.Core/RenX_Server.h +++ b/RenX.Core/RenX_Server.h @@ -127,6 +127,13 @@ namespace RenX */ bool isFirstAction() const; + /** + * @brief Checks if the server travel mode is seamless. + * + * @return True if the server is using seamless travel, false otherwise. + */ + bool isSeamless() const; + /** * @brief Checks if a channel type is a public channel type. * @@ -285,6 +292,69 @@ namespace RenX */ bool updateClientList(); + /** + * @brief Forces the current game to end, if the server supports it. + * + * @return True on success, false otherwise. + */ + bool gameover(); + + /** + * @brief Forces the current game to end and changes the map, if the server supports it. + * + * @return True on success, false otherwise. + */ + bool setMap(const Jupiter::ReadableString &map); + + /** + * @brief Forces the current game to end, if the server supports it. + * + * @return True on success, false otherwise. + */ + bool loadMutator(const Jupiter::ReadableString &mutator); + + /** + * @brief Forces the current game to end, if the server supports it. + * + * @return True on success, false otherwise. + */ + bool unloadMutator(const Jupiter::ReadableString &mutator); + + /** + * @brief Forcefully ends the current vote, if the server supports it. + * + * @return True on success, false otherwise. + */ + bool cancelVote(const RenX::TeamType team); + + /** + * @brief Swaps the teams, if the server supports it. + * + * @return True on success, false otherwise. + */ + bool swapTeams(); + + /** + * @brief Starts a demo recording, if the server supports it. + * + * @return True on success, false otherwise. + */ + bool recordDemo(); + + /** + * @brief Mutes a player from the game chat, if the server supports it. + * + * @return True on success, false otherwise. + */ + bool mute(const RenX::PlayerInfo *player); + + /** + * @brief Allows a player to use the game chat, if the server supports it. + * + * @return True on success, false otherwise. + */ + bool unmute(const RenX::PlayerInfo *player); + /** * @brief Gives a player additional credits, if the server supports it. * @@ -307,19 +377,19 @@ namespace RenX * @brief Forces a player to change teams, if the server supports it. * * @param id ID of the player to give credits to - * @param options Options to pass to the command + * @param resetCredits True to reset the player's credits, false otherwise. * @return True on success, false otherwise. */ - bool changeTeam(int id, unsigned char options = 0x03); + bool changeTeam(int id, bool resetCredits = true); /** * @brief Forces a player to change teams, if the server supports it. * * @param player Player to change teams - * @param options Options to pass to the command + * @param resetCredits True to reset the player's credits, false otherwise. * @return True on success, false otherwise. */ - bool changeTeam(RenX::PlayerInfo *player, unsigned char options = 0x03); + bool changeTeam(RenX::PlayerInfo *player, bool resetCredits = true); /** * @brief Forces a player to change teams, if the server supports it. @@ -603,6 +673,7 @@ namespace RenX /** Tracking variables */ bool connected = false; + bool seamless = false; bool needsCList = false; bool silenceParts = false; bool silenceJoins = false; @@ -615,6 +686,7 @@ namespace RenX unsigned int xRconRevision = 0; time_t lastAttempt = 0; Jupiter::String lastLine; + Jupiter::StringS commandListFormat; Jupiter::StringS gameVersion; Jupiter::ArrayList commands; diff --git a/RenX.Core/RenX_ServerProfile.cpp b/RenX.Core/RenX_ServerProfile.cpp index f019a0a..6ab70ec 100644 --- a/RenX.Core/RenX_ServerProfile.cpp +++ b/RenX.Core/RenX_ServerProfile.cpp @@ -25,7 +25,7 @@ struct BaseProfile : RenX::ServerProfile privateMessages = true; disconnectOnGameOver = false; pidbug = false; - mustSanitize = true; + mustSanitize = false; tieFormat = 1; } } _baseProfile; @@ -37,6 +37,7 @@ struct OpenBeta1Profile : BaseProfile { supported = false; privateMessages = false; + mustSanitize = true; } } _openBeta1Profile; const RenX::ServerProfile *RenX::openBeta1Profile = &_openBeta1Profile; @@ -48,6 +49,7 @@ struct OpenBeta2Profile : BaseProfile privateMessages = false; pidbug = true; tieFormat = 0; + mustSanitize = true; } } _openBeta2Profile; const RenX::ServerProfile *RenX::openBeta2Profile = &_openBeta2Profile; @@ -57,6 +59,15 @@ 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; \ No newline at end of file diff --git a/RenX.Core/RenX_ServerProfile.h b/RenX.Core/RenX_ServerProfile.h index 0b7835e..f8012c1 100644 --- a/RenX.Core/RenX_ServerProfile.h +++ b/RenX.Core/RenX_ServerProfile.h @@ -44,6 +44,7 @@ namespace RenX 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 */ } diff --git a/RenX.Logging/RenX_Logging.cpp b/RenX.Logging/RenX_Logging.cpp index 0beace1..8cf4f10 100644 --- a/RenX.Logging/RenX_Logging.cpp +++ b/RenX.Logging/RenX_Logging.cpp @@ -37,14 +37,32 @@ void RenX_LoggingPlugin::init() RenX_LoggingPlugin::hostPagePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("HostPagePublic"), false); RenX_LoggingPlugin::otherChatPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("OtherChatPublic"), false); RenX_LoggingPlugin::deployPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DeployPublic"), true); + RenX_LoggingPlugin::mineDeployPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("MineDeployPublic"), false); RenX_LoggingPlugin::disarmPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DisarmPublic"), true); + RenX_LoggingPlugin::mineDisarmPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("MineDisarmPublic"), false); + RenX_LoggingPlugin::explodePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("ExplodePublic"), false); RenX_LoggingPlugin::suicidePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("SuicidePublic"), true); RenX_LoggingPlugin::killPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("KillPublic"), true); RenX_LoggingPlugin::diePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DiePublic"), true); RenX_LoggingPlugin::destroyPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DestroyPublic"), true); RenX_LoggingPlugin::capturePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("CapturePublic"), true); RenX_LoggingPlugin::neutralizePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("NeutralizePublic"), true); + RenX_LoggingPlugin::characterPurchasePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("CharacterPurchasePublic"), false); + RenX_LoggingPlugin::itemPurchasePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("ItemPurchasePublic"), false); + RenX_LoggingPlugin::weaponPurchasePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("WeaponPurchasePublic"), false); + RenX_LoggingPlugin::refillPurchasePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("RefillPurchasePublic"), false); + RenX_LoggingPlugin::vehiclePurchasePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("VehiclePurchasePublic"), false); + RenX_LoggingPlugin::vehicleSpawnPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("VehicleSpawnPublic"), true); + RenX_LoggingPlugin::spawnPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("SpawnPublic"), true); + RenX_LoggingPlugin::botJoinPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("BotJoinPublic"), true); + RenX_LoggingPlugin::vehicleCratePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("VehicleCratePublic"), false); + RenX_LoggingPlugin::deathCratePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DeathCratePublic"), false); + RenX_LoggingPlugin::moneyCratePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("MoneyCratePublic"), false); + RenX_LoggingPlugin::characterCratePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("CharacterCratePublic"), false); + RenX_LoggingPlugin::spyCratePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("SpyCratePublic"), false); + RenX_LoggingPlugin::refillCratePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("RefillCratePublic"), false); RenX_LoggingPlugin::stealPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("StealPublic"), true); + RenX_LoggingPlugin::donatePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DonatePublic"), true); RenX_LoggingPlugin::gamePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("GamePublic"), true); RenX_LoggingPlugin::gameOverPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("GameOverPublic"), true); RenX_LoggingPlugin::executePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("ExecutePublic"), false); @@ -62,13 +80,10 @@ void RenX_LoggingPlugin::init() RenX_LoggingPlugin::mapLoadPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("MapLoadPublic"), true); RenX_LoggingPlugin::mapPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("MapPublic"), false); RenX_LoggingPlugin::demoRecordPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("DemoRecordPublic"), 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::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::grantCharacterPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("GrantCharacterPublic"), false); - RenX_LoggingPlugin::spawnVehiclePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("SpawnVehiclePublic"), false); - RenX_LoggingPlugin::spawnVehicleNoOwnerPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("SpawnVehicleNoOwnerPublic"), true); - RenX_LoggingPlugin::minePlacePublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("MinePlacePublic"), false); 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::errorPublic = Jupiter::IRC::Client::Config->getBool(RenX_LoggingPlugin::getName(), STRING_LITERAL_AS_REFERENCE("ErrorPublic"), false); @@ -117,16 +132,34 @@ void RenX_LoggingPlugin::init() Jupiter::StringS::Format(IRCCOLOR "06[Other Chat]" IRCCOLOR " %.*s", RenX::tags->messageTag.size(), RenX::tags->messageTag.ptr())); RenX_LoggingPlugin::deployFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("DeployFormat"), - Jupiter::StringS::Format(IRCBOLD "%.*s" IRCBOLD " deployed a " IRCBOLD "%.*s" IRCBOLD, RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " deployed a " IRCBOLD IRCCOLOR "12%.*s" IRCBOLD, RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + + RenX_LoggingPlugin::mineDeployFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("MineDeployFormat"), + RenX_LoggingPlugin::deployFmt); RenX_LoggingPlugin::disarmFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("DisarmFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCBOLD " disarmed %.*s's " IRCBOLD "%.*s" IRCBOLD, RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimNameTag.size(), RenX::tags->victimNameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + + RenX_LoggingPlugin::mineDisarmFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("MineDisarmFormat"), + RenX_LoggingPlugin::disarmFmt); + + RenX_LoggingPlugin::disarmNoOwnerFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("DisarmNoOwnerFormat"), Jupiter::StringS::Format(IRCBOLD "%.*s" IRCBOLD " disarmed a " IRCBOLD "%.*s" IRCBOLD, RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + RenX_LoggingPlugin::mineDisarmNoOwnerFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("MineDisarmNoOwnerFormat"), + RenX_LoggingPlugin::disarmNoOwnerFmt); + + RenX_LoggingPlugin::explodeFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("ExplodeFormat"), + Jupiter::StringS::Format("%.*s" IRCCOLOR " detonated a " IRCCOLOR "07%.*s" IRCCOLOR ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->weaponTag.size(), RenX::tags->weaponTag.ptr())); + + RenX_LoggingPlugin::explodeNoOwnerFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("ExplodeMoOwnerFormat"), + Jupiter::StringS::Format("A " IRCCOLOR "07%.*s" IRCCOLOR " detonated.", RenX::tags->weaponTag.size(), RenX::tags->weaponTag.ptr())); + RenX_LoggingPlugin::suicideFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("SuicideFormat"), - Jupiter::StringS::Format("%.*s" IRCCOLOR " suicided (death by " IRCCOLOR "12%.*s" IRCCOLOR ").", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->weaponTag.size(), RenX::tags->weaponTag.ptr())); + Jupiter::StringS::Format("%.*s" IRCCOLOR " suicided (" IRCCOLOR "12%.*s" IRCCOLOR ").", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->weaponTag.size(), RenX::tags->weaponTag.ptr())); RenX_LoggingPlugin::killFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("KillFormat"), - Jupiter::StringS::Format("%.*s" IRCCOLOR " killed %.*s" IRCCOLOR " (" IRCCOLOR "12%.*s" IRCCOLOR ").", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimNameTag.size(), RenX::tags->victimNameTag.ptr(), RenX::tags->weaponTag.size(), RenX::tags->weaponTag.ptr())); + Jupiter::StringS::Format("%.*s" IRCCOLOR " killed %.*s" IRCCOLOR " (" IRCCOLOR "%.*s%.*s/%.*s" IRCCOLOR "vs" IRCCOLOR "%.*s%.*s" ").", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimNameTag.size(), RenX::tags->victimNameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->characterTag.size(), RenX::tags->characterTag.ptr(), RenX::tags->weaponTag.size(), RenX::tags->weaponTag.ptr(), RenX::tags->victimTeamColorTag.size(), RenX::tags->victimTeamColorTag.ptr(), RenX::tags->victimCharacterTag.size(), RenX::tags->victimCharacterTag.ptr())); RenX_LoggingPlugin::killFmt2 = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("KillFormat2"), Jupiter::StringS::Format(IRCCOLOR "%.*s%.*s" IRCCOLOR " killed %.*s" IRCCOLOR " (" IRCCOLOR "12%.*s" IRCCOLOR ").", RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimNameTag.size(), RenX::tags->victimNameTag.ptr(), RenX::tags->weaponTag.size(), RenX::tags->weaponTag.ptr())); @@ -156,16 +189,61 @@ void RenX_LoggingPlugin::init() Jupiter::StringS::Format(IRCCOLOR "%.*s%.*s" IRCCOLOR " destroyed a " IRCCOLOR "%.*s%.*s" IRCCOLOR " (" IRCCOLOR "12%.*s" IRCCOLOR ").", RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimTeamColorTag.size(), RenX::tags->victimTeamColorTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr(), RenX::tags->weaponTag.size(), RenX::tags->weaponTag.ptr())); RenX_LoggingPlugin::captureFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("CaptureFormat"), - Jupiter::StringS::Format(IRCBOLD "%.*s" IRCBOLD " captured the " IRCBOLD IRCCOLOR "%.*s%.*s" IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr(), RenX::tags->victimTeamColorTag.size(), RenX::tags->victimTeamColorTag.ptr())); + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " captured the " IRCBOLD IRCCOLOR "%.*s%.*s" IRCCOLOR IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimTeamColorTag.size(), RenX::tags->victimTeamColorTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); RenX_LoggingPlugin::neutralizeFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("NeutralizeFormat"), - Jupiter::StringS::Format(IRCBOLD "%.*s" IRCBOLD " neutralized the " IRCBOLD IRCCOLOR "%.*s%.*s" IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr(), RenX::tags->victimTeamColorTag.size(), RenX::tags->victimTeamColorTag.ptr())); + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " neutralized the " IRCBOLD IRCCOLOR "%.*s%.*s" IRCCOLOR IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimTeamColorTag.size(), RenX::tags->victimTeamColorTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + + RenX_LoggingPlugin::characterPurchaseFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("CharacterPurchaseFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " purchased a " IRCBOLD IRCCOLOR "%.*s%.*s" IRCCOLOR IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->victimCharacterTag.size(), RenX::tags->victimCharacterTag.ptr())); + + RenX_LoggingPlugin::itemPurchaseFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("ItemPurchaseFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " purchased a " IRCBOLD IRCCOLOR "%.*s%.*s" IRCCOLOR IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + + RenX_LoggingPlugin::weaponPurchaseFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("WeaponPurchaseFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " purchased a " IRCBOLD IRCCOLOR "%.*s%.*s" IRCCOLOR IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->weaponTag.size(), RenX::tags->weaponTag.ptr())); + + RenX_LoggingPlugin::refillPurchaseFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("RefillPurchaseFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " purchased a " IRCBOLD IRCCOLOR "%.*srefill" IRCCOLOR IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr())); + + RenX_LoggingPlugin::vehiclePurchaseFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("VehiclePurchaseFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " purchased a " IRCBOLD IRCCOLOR "%.*s%.*s" IRCCOLOR IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->victimVehicleTag.size(), RenX::tags->victimVehicleTag.ptr())); + + RenX_LoggingPlugin::vehicleSpawnFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("VehicleSpawnFormat"), + Jupiter::StringS::Format("A " IRCBOLD IRCCOLOR "%.*s%.*s" IRCCOLOR IRCBOLD " has spawned.", RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->vehicleTag.size(), RenX::tags->vehicleTag.ptr())); + + RenX_LoggingPlugin::spawnFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("SpawnFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " spawned as a " IRCCOLOR "%.*s%.*s.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->victimCharacterTag.size(), RenX::tags->victimCharacterTag.ptr())); + + RenX_LoggingPlugin::botJoinFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("BotJoinFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " online.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr())); + + RenX_LoggingPlugin::vehicleCrateFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("VehicleCrateFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " picked up a %.*s vehicle crate.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + + RenX_LoggingPlugin::deathCrateFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("DeathCrateFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " picked up a " IRCCOLOR "12death" IRCCOLOR " crate.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr())); + + RenX_LoggingPlugin::moneyCrateFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("MoneyCrateFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " picked up " IRCCOLOR "09%.*s credits" IRCCOLOR " from a " IRCCOLOR "12money" IRCCOLOR " crate.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + + RenX_LoggingPlugin::characterCrateFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("CharacterCrateFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " picked up a " IRCCOLOR "%.*s%.*s" IRCCOLOR " " IRCCOLOR "12character" IRCCOLOR " crate.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->victimCharacterTag.size(), RenX::tags->victimCharacterTag.ptr())); + + RenX_LoggingPlugin::spyCrateFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("SpyCrateFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " picked up a " IRCCOLOR "%.*s%.*s" IRCCOLOR " " IRCCOLOR "12spy" IRCCOLOR " crate.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimTeamColorTag.size(), RenX::tags->victimTeamColorTag.ptr(), RenX::tags->victimCharacterTag.size(), RenX::tags->victimCharacterTag.ptr())); + + RenX_LoggingPlugin::refillCrateFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("RefillCrateFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " picked up a " IRCCOLOR "%.*srefill" IRCCOLOR " crate.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr())); RenX_LoggingPlugin::stealFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("StealFormat"), - Jupiter::StringS::Format(IRCBOLD "%.*s" IRCBOLD IRCCOLOR " stole " IRCBOLD "%.*s" IRCBOLD "'s " IRCBOLD "%.*s" IRCBOLD "!", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimNameTag.size(), RenX::tags->victimNameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " stole " IRCBOLD "%.*s" IRCBOLD "'s " IRCBOLD "%.*s" IRCBOLD "!", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->victimNameTag.size(), RenX::tags->victimNameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); RenX_LoggingPlugin::stealNoOwnerFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("StealNoOwnerFormat"), - Jupiter::StringS::Format(IRCBOLD "%.*s" IRCBOLD IRCCOLOR " stole a " IRCBOLD IRCCOLOR "12%.*s" IRCBOLD "!", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " stole a " IRCBOLD IRCCOLOR "12%.*s" IRCBOLD "!", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr())); + + RenX_LoggingPlugin::donateFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("StealFormat"), + Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " donated " IRCCOLOR "09%.*s credits" IRCCOLOR " to " IRCBOLD "%.*s" IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.ptr(), RenX::tags->victimNameTag.size(), RenX::tags->victimNameTag.ptr())); RenX_LoggingPlugin::gameOverFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("GameOverFormat"), Jupiter::StringS::Format(IRCCOLOR "03[Game]" IRCCOLOR "%.*s The " IRCBOLD "%.*s" IRCBOLD " won by " IRCBOLD "%.*s" IRCBOLD, RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->messageTag.size(), RenX::tags->messageTag.ptr())); @@ -233,6 +311,9 @@ void RenX_LoggingPlugin::init() RenX_LoggingPlugin::rconDemoRecordFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("RCONDemoRecordFormat"), STRING_LITERAL_AS_REFERENCE(IRCCOLOR "07A demo recording has started.")); + RenX_LoggingPlugin::demoRecordStopFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("DemoRecordStopFormat"), + STRING_LITERAL_AS_REFERENCE(IRCCOLOR "07The demo recording has stopped.")); + RenX_LoggingPlugin::demoFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("DemoFormat"), Jupiter::StringS::Format(IRCCOLOR "06[Demo]" IRCCOLOR " %.*s", RenX::tags->messageTag.size(), RenX::tags->messageTag.ptr())); @@ -242,18 +323,6 @@ void RenX_LoggingPlugin::init() 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::grantCharacterFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("GrantCharacterFormat"), - Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " is now a " IRCBOLD IRCCOLOR "%.*s%.*s", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->victimCharacterTag.size(), RenX::tags->victimCharacterTag.ptr())); - - RenX_LoggingPlugin::spawnVehicleFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("SpawnVehicleFormat"), - Jupiter::StringS::Format(IRCBOLD "%.*s" IRCCOLOR IRCBOLD " purchased a " IRCBOLD IRCCOLOR "%.*s%.*s", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->victimVehicleTag.size(), RenX::tags->victimVehicleTag.ptr())); - - RenX_LoggingPlugin::spawnVehicleNoOwnerFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("SpawnVehicleNoOwnerFormat"), - Jupiter::StringS::Format("A " IRCBOLD IRCCOLOR "%.*s%.*s" IRCCOLOR IRCBOLD " has spawned.", RenX::tags->teamColorTag.size(), RenX::tags->teamColorTag.ptr(), RenX::tags->vehicleTag.size(), RenX::tags->vehicleTag.ptr())); - - RenX_LoggingPlugin::minePlaceFmt = Jupiter::IRC::Client::Config->get(this->getName(), STRING_LITERAL_AS_REFERENCE("MinePlaceFormat"), - Jupiter::StringS::Format(IRCCOLOR "07[C4] " IRCCOLOR IRCBOLD "%.*s" IRCCOLOR IRCBOLD " placed a " IRCBOLD IRCCOLOR "12%.*s", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->objectTag.size(), RenX::tags->objectTag.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())); @@ -284,7 +353,13 @@ void RenX_LoggingPlugin::init() RenX::sanitizeTags(teamChatFmt); RenX::sanitizeTags(otherChatFmt); RenX::sanitizeTags(deployFmt); + RenX::sanitizeTags(mineDeployFmt); RenX::sanitizeTags(disarmFmt); + RenX::sanitizeTags(mineDisarmFmt); + RenX::sanitizeTags(disarmNoOwnerFmt); + RenX::sanitizeTags(mineDisarmNoOwnerFmt); + RenX::sanitizeTags(explodeFmt); + RenX::sanitizeTags(explodeNoOwnerFmt); RenX::sanitizeTags(suicideFmt); RenX::sanitizeTags(dieFmt); RenX::sanitizeTags(dieFmt2); @@ -298,8 +373,23 @@ void RenX_LoggingPlugin::init() RenX::sanitizeTags(destroyVehicleFmt2); RenX::sanitizeTags(captureFmt); RenX::sanitizeTags(neutralizeFmt); + RenX::sanitizeTags(characterPurchaseFmt); + RenX::sanitizeTags(itemPurchaseFmt); + RenX::sanitizeTags(weaponPurchaseFmt); + RenX::sanitizeTags(refillPurchaseFmt); + RenX::sanitizeTags(vehiclePurchaseFmt); + RenX::sanitizeTags(vehicleSpawnFmt); + RenX::sanitizeTags(spawnFmt); + RenX::sanitizeTags(botJoinFmt); + RenX::sanitizeTags(vehicleCrateFmt); + RenX::sanitizeTags(deathCrateFmt); + RenX::sanitizeTags(moneyCrateFmt); + RenX::sanitizeTags(characterCrateFmt); + RenX::sanitizeTags(spyCrateFmt); + RenX::sanitizeTags(refillCrateFmt); RenX::sanitizeTags(stealFmt); RenX::sanitizeTags(stealNoOwnerFmt); + RenX::sanitizeTags(donateFmt); RenX::sanitizeTags(gameOverFmt); RenX::sanitizeTags(gameOverTieFmt); RenX::sanitizeTags(gameOverTieNoWinFmt); @@ -325,13 +415,10 @@ void RenX_LoggingPlugin::init() RenX::sanitizeTags(mapFmt); RenX::sanitizeTags(demoRecordFmt); RenX::sanitizeTags(rconDemoRecordFmt); + RenX::sanitizeTags(demoRecordStopFmt); RenX::sanitizeTags(demoFmt); RenX::sanitizeTags(logFmt); RenX::sanitizeTags(xVersionFmt); - RenX::sanitizeTags(grantCharacterFmt); - RenX::sanitizeTags(spawnVehicleFmt); - RenX::sanitizeTags(spawnVehicleNoOwnerFmt); - RenX::sanitizeTags(minePlaceFmt); RenX::sanitizeTags(xOtherFmt); RenX::sanitizeTags(commandFmt); RenX::sanitizeTags(errorFmt); @@ -536,12 +623,25 @@ void RenX_LoggingPlugin::RenX_OnOtherChat(RenX::Server *server, const Jupiter::R void RenX_LoggingPlugin::RenX_OnDeploy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &object) { logFuncType func; - if (RenX_LoggingPlugin::deployPublic) - func = &RenX::Server::sendLogChan; + Jupiter::String msg; + if (object.match("*Beacon")) + { + if (RenX_LoggingPlugin::deployPublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + msg = this->deployFmt; + } else - func = &RenX::Server::sendAdmChan; - - Jupiter::String msg = this->deployFmt; + { + if (RenX_LoggingPlugin::mineDeployPublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + msg = this->mineDeployFmt; + } if (msg.isEmpty() == false) { RenX::processTags(msg, server, player); @@ -550,18 +650,99 @@ void RenX_LoggingPlugin::RenX_OnDeploy(RenX::Server *server, const RenX::PlayerI } } +void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &object, const RenX::PlayerInfo *victim) +{ + logFuncType func; + Jupiter::String msg; + + if (object.match("*Beacon")) + { + if (RenX_LoggingPlugin::disarmPublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + msg = this->disarmFmt; + } + else + { + if (RenX_LoggingPlugin::mineDisarmPublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + msg = this->mineDisarmFmt; + } + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player, victim); + msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object)); + (server->*func)(msg); + } +} + void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &object) { logFuncType func; - if (RenX_LoggingPlugin::disarmPublic) + Jupiter::String msg; + + if (object.match("*Beacon")) + { + if (RenX_LoggingPlugin::disarmPublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + msg = this->disarmNoOwnerFmt; + } + else + { + if (RenX_LoggingPlugin::mineDisarmPublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + msg = this->mineDisarmNoOwnerFmt; + } + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnExplode(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &object) +{ + logFuncType func; + if (RenX_LoggingPlugin::explodePublic) func = &RenX::Server::sendLogChan; else func = &RenX::Server::sendAdmChan; - Jupiter::String msg = this->disarmFmt; + Jupiter::String msg = this->explodeFmt; if (msg.isEmpty() == false) { RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_WEAPON_TAG, RenX::translateName(object)); + msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnExplode(RenX::Server *server, const Jupiter::ReadableString &object) +{ + logFuncType func; + if (RenX_LoggingPlugin::explodePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->explodeNoOwnerFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server); + msg.replace(RenX::tags->INTERNAL_WEAPON_TAG, RenX::translateName(object)); msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object)); (server->*func)(msg); } @@ -660,7 +841,7 @@ void RenX_LoggingPlugin::RenX_OnDie(RenX::Server *server, const Jupiter::Readabl } } -void RenX_LoggingPlugin::RenX_OnDestroy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &objectName, const Jupiter::ReadableString &damageType, RenX::ObjectType type) +void RenX_LoggingPlugin::RenX_OnDestroy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &objectName, const RenX::TeamType &objectTeam, const Jupiter::ReadableString &damageType, RenX::ObjectType type) { logFuncType func; if (RenX_LoggingPlugin::destroyPublic) @@ -683,11 +864,10 @@ void RenX_LoggingPlugin::RenX_OnDestroy(RenX::Server *server, const RenX::Player } if (msg.isEmpty() == false) { - RenX::TeamType victimTeam = RenX::getEnemy(player->team); RenX::processTags(msg, server, player); - msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_COLOR_TAG, RenX::getTeamColor(victimTeam)); - msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_SHORT_TAG, RenX::getTeamName(victimTeam)); - msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_LONG_TAG, RenX::getFullTeamName(victimTeam)); + msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_COLOR_TAG, RenX::getTeamColor(objectTeam)); + msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_SHORT_TAG, RenX::getTeamName(objectTeam)); + msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_LONG_TAG, RenX::getFullTeamName(objectTeam)); msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(objectName)); msg.replace(RenX::tags->INTERNAL_WEAPON_TAG, RenX::translateName(damageType)); (server->*func)(msg); @@ -734,6 +914,247 @@ void RenX_LoggingPlugin::RenX_OnNeutralize(RenX::Server *server, const RenX::Pla } } +void RenX_LoggingPlugin::RenX_OnCharacterPurchase(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) +{ + logFuncType func; + if (RenX_LoggingPlugin::characterPurchasePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->characterPurchaseFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_VICTIM_CHARACTER_TAG, RenX::translateName(character)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnItemPurchase(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &item) +{ + logFuncType func; + if (RenX_LoggingPlugin::itemPurchasePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->itemPurchaseFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(item)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnWeaponPurchase(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &weapon) +{ + logFuncType func; + if (RenX_LoggingPlugin::weaponPurchasePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->weaponPurchaseFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_WEAPON_TAG, RenX::translateName(weapon)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnRefillPurchase(RenX::Server *server, const RenX::PlayerInfo *player) +{ + logFuncType func; + if (RenX_LoggingPlugin::refillPurchasePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->refillPurchaseFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnVehiclePurchase(RenX::Server *server, const RenX::PlayerInfo *owner, const Jupiter::ReadableString &vehicle) +{ + logFuncType func; + if (RenX_LoggingPlugin::vehiclePurchasePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->vehiclePurchaseFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, owner); + msg.replace(RenX::tags->INTERNAL_VICTIM_VEHICLE_TAG, RenX::translateName(vehicle)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnVehicleSpawn(RenX::Server *server, const RenX::TeamType &team, const Jupiter::ReadableString &vehicle) +{ + logFuncType func; + if (RenX_LoggingPlugin::vehicleSpawnPublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->vehicleSpawnFmt; + if (msg.isEmpty() == false) + { + RenX::TeamType otherTeam = RenX::getEnemy(team); + RenX::processTags(msg, server); + msg.replace(RenX::tags->INTERNAL_TEAM_COLOR_TAG, RenX::getTeamColor(team)); + msg.replace(RenX::tags->INTERNAL_TEAM_SHORT_TAG, RenX::getTeamName(team)); + msg.replace(RenX::tags->INTERNAL_TEAM_LONG_TAG, RenX::getFullTeamName(team)); + msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_COLOR_TAG, RenX::getTeamColor(otherTeam)); + msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_SHORT_TAG, RenX::getTeamName(otherTeam)); + msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_LONG_TAG, RenX::getFullTeamName(otherTeam)); + msg.replace(RenX::tags->INTERNAL_VEHICLE_TAG, RenX::translateName(vehicle)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnSpawn(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) +{ + logFuncType func; + if (RenX_LoggingPlugin::spawnPublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->spawnFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_VICTIM_CHARACTER_TAG, RenX::translateName(character)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnBotJoin(RenX::Server *server, const RenX::PlayerInfo *player) +{ + logFuncType func; + if (RenX_LoggingPlugin::botJoinPublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->botJoinFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnVehicleCrate(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &vehicle) +{ + logFuncType func; + if (RenX_LoggingPlugin::vehicleCratePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->vehicleCrateFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(vehicle)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnDeathCrate(RenX::Server *server, const RenX::PlayerInfo *player) +{ + logFuncType func; + if (RenX_LoggingPlugin::deathCratePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->deathCrateFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnMoneyCrate(RenX::Server *server, const RenX::PlayerInfo *player, int amount) +{ + logFuncType func; + if (RenX_LoggingPlugin::moneyCratePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->moneyCrateFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, Jupiter::StringS::Format("%d", amount)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnCharacterCrate(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) +{ + logFuncType func; + if (RenX_LoggingPlugin::characterCratePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->characterCrateFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_VICTIM_CHARACTER_TAG, RenX::translateName(character)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnSpyCrate(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) +{ + logFuncType func; + if (RenX_LoggingPlugin::spyCratePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->spyCrateFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + msg.replace(RenX::tags->INTERNAL_VICTIM_CHARACTER_TAG, RenX::translateName(character)); + (server->*func)(msg); + } +} + +void RenX_LoggingPlugin::RenX_OnRefillCrate(RenX::Server *server, const RenX::PlayerInfo *player) +{ + logFuncType func; + if (RenX_LoggingPlugin::refillCratePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->refillCrateFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, player); + (server->*func)(msg); + } +} + void RenX_LoggingPlugin::RenX_OnSteal(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &vehicle) { logFuncType func; @@ -768,6 +1189,23 @@ void RenX_LoggingPlugin::RenX_OnSteal(RenX::Server *server, const RenX::PlayerIn } } +void RenX_LoggingPlugin::RenX_OnDonate(RenX::Server *server, const RenX::PlayerInfo *donor, const RenX::PlayerInfo *player, double amount) +{ + logFuncType func; + if (RenX_LoggingPlugin::donatePublic) + func = &RenX::Server::sendLogChan; + else + func = &RenX::Server::sendAdmChan; + + Jupiter::String msg = this->donateFmt; + if (msg.isEmpty() == false) + { + RenX::processTags(msg, server, donor, player); + msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, Jupiter::StringS::Format("%.0f", amount)); + (server->*func)(msg); + } +} + void RenX_LoggingPlugin::RenX_OnDestroy(RenX::Server *server, const Jupiter::ReadableString &killer, const RenX::TeamType &killerTeam, const Jupiter::ReadableString &objectName, const RenX::TeamType &objectTeam, const Jupiter::ReadableString &damageType, RenX::ObjectType type) { logFuncType func; @@ -1124,6 +1562,8 @@ void RenX_LoggingPlugin::RenX_OnMapChange(RenX::Server *server, const Jupiter::R msg.replace(RenX::tags->INTERNAL_MESSAGE_TAG, map); (server->*func)(msg); } + if (server->isSeamless() == false) + server->sendLogChan(IRCCOLOR "07[Warning]" IRCCOLOR " This server is using non-seamless server travel; this bot will be disconnected."); } void RenX_LoggingPlugin::RenX_OnMapLoad(RenX::Server *server, const Jupiter::ReadableString &map) @@ -1193,32 +1633,31 @@ void RenX_LoggingPlugin::RenX_OnDemoRecord(RenX::Server *server, const Jupiter:: } } -void RenX_LoggingPlugin::RenX_OnDemo(RenX::Server *server, const Jupiter::ReadableString &raw) +void RenX_LoggingPlugin::RenX_OnDemoRecordStop(RenX::Server *server) { logFuncType func; - if (RenX_LoggingPlugin::demoPublic) + if (RenX_LoggingPlugin::demoRecordStopPublic) func = &RenX::Server::sendLogChan; else func = &RenX::Server::sendAdmChan; - Jupiter::String msg = this->demoFmt; + Jupiter::String msg = this->demoRecordStopFmt; if (msg.isEmpty() == false) { RenX::processTags(msg, server); - msg.replace(RenX::tags->INTERNAL_MESSAGE_TAG, raw); (server->*func)(msg); } } -void RenX_LoggingPlugin::RenX_OnLog(RenX::Server *server, const Jupiter::ReadableString &raw) +void RenX_LoggingPlugin::RenX_OnDemo(RenX::Server *server, const Jupiter::ReadableString &raw) { logFuncType func; - if (RenX_LoggingPlugin::logPublic) + if (RenX_LoggingPlugin::demoPublic) func = &RenX::Server::sendLogChan; else func = &RenX::Server::sendAdmChan; - - Jupiter::String msg = this->logFmt; + + Jupiter::String msg = this->demoFmt; if (msg.isEmpty() == false) { RenX::processTags(msg, server); @@ -1227,97 +1666,36 @@ void RenX_LoggingPlugin::RenX_OnLog(RenX::Server *server, const Jupiter::Readabl } } -void RenX_LoggingPlugin::RenX_XOnVersion(RenX::Server *server, unsigned int version) +void RenX_LoggingPlugin::RenX_OnLog(RenX::Server *server, const Jupiter::ReadableString &raw) { logFuncType func; - if (RenX_LoggingPlugin::xVersionPublic) + if (RenX_LoggingPlugin::logPublic) func = &RenX::Server::sendLogChan; else func = &RenX::Server::sendAdmChan; - - Jupiter::String msg = this->xVersionFmt; + + Jupiter::String msg = this->logFmt; 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_OnGrantCharacter(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) -{ - if (player->character.equals(RenX::getCharacter(character)) == false) - { - logFuncType func; - if (RenX_LoggingPlugin::grantCharacterPublic) - func = &RenX::Server::sendLogChan; - else - func = &RenX::Server::sendAdmChan; - - Jupiter::String msg = this->grantCharacterFmt; - if (msg.isEmpty() == false) - { - RenX::processTags(msg, server, player); - msg.replace(RenX::tags->INTERNAL_VICTIM_CHARACTER_TAG, RenX::translateName(character)); - (server->*func)(msg); - } - } -} - -void RenX_LoggingPlugin::RenX_OnSpawnVehicle(RenX::Server *server, const RenX::PlayerInfo *owner, const Jupiter::ReadableString &vehicle) -{ - logFuncType func; - if (RenX_LoggingPlugin::spawnVehiclePublic) - func = &RenX::Server::sendLogChan; - else - func = &RenX::Server::sendAdmChan; - - Jupiter::String msg = this->spawnVehicleFmt; - if (msg.isEmpty() == false) - { - RenX::processTags(msg, server, owner); - msg.replace(RenX::tags->INTERNAL_VICTIM_VEHICLE_TAG, RenX::translateName(vehicle)); + msg.replace(RenX::tags->INTERNAL_MESSAGE_TAG, raw); (server->*func)(msg); } } -void RenX_LoggingPlugin::RenX_OnSpawnVehicleNoOwner(RenX::Server *server, const RenX::TeamType &team, const Jupiter::ReadableString &vehicle) +void RenX_LoggingPlugin::RenX_XOnVersion(RenX::Server *server, unsigned int version) { logFuncType func; - if (RenX_LoggingPlugin::spawnVehicleNoOwnerPublic) + if (RenX_LoggingPlugin::xVersionPublic) func = &RenX::Server::sendLogChan; else func = &RenX::Server::sendAdmChan; - Jupiter::String msg = this->spawnVehicleNoOwnerFmt; + Jupiter::String msg = this->xVersionFmt; if (msg.isEmpty() == false) { - RenX::TeamType otherTeam = RenX::getEnemy(team); RenX::processTags(msg, server); - msg.replace(RenX::tags->INTERNAL_TEAM_COLOR_TAG, RenX::getTeamColor(team)); - msg.replace(RenX::tags->INTERNAL_TEAM_SHORT_TAG, RenX::getTeamName(team)); - msg.replace(RenX::tags->INTERNAL_TEAM_LONG_TAG, RenX::getFullTeamName(team)); - msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_COLOR_TAG, RenX::getTeamColor(otherTeam)); - msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_SHORT_TAG, RenX::getTeamName(otherTeam)); - msg.replace(RenX::tags->INTERNAL_VICTIM_TEAM_LONG_TAG, RenX::getFullTeamName(otherTeam)); - msg.replace(RenX::tags->INTERNAL_VEHICLE_TAG, RenX::translateName(vehicle)); - (server->*func)(msg); - } -} - -void RenX_LoggingPlugin::RenX_OnMinePlace(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &mine) -{ - logFuncType func; - if (RenX_LoggingPlugin::minePlacePublic) - func = &RenX::Server::sendLogChan; - else - func = &RenX::Server::sendAdmChan; - - Jupiter::String msg = this->minePlaceFmt; - if (msg.isEmpty() == false) - { - RenX::processTags(msg, server, player); - msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(mine)); + msg.replace(RenX::tags->INTERNAL_XRCON_VERSION_TAG, Jupiter::StringS::Format("%u", version)); (server->*func)(msg); } } diff --git a/RenX.Logging/RenX_Logging.h b/RenX.Logging/RenX_Logging.h index 0bba7c5..2ef23f1 100644 --- a/RenX.Logging/RenX_Logging.h +++ b/RenX.Logging/RenX_Logging.h @@ -38,18 +38,36 @@ public: // RenX::Plugin void RenX_OnOtherChat(RenX::Server *server, const Jupiter::ReadableString &raw) override; void RenX_OnDeploy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &object) override; + void RenX_OnDisarm(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &object, const RenX::PlayerInfo *victim) override; void RenX_OnDisarm(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &object) override; + void RenX_OnExplode(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &object) override; + void RenX_OnExplode(RenX::Server *server, const Jupiter::ReadableString &object) override; void RenX_OnSuicide(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &damageType) override; void RenX_OnKill(RenX::Server *server, const RenX::PlayerInfo *player, const RenX::PlayerInfo *victim, const Jupiter::ReadableString &damageType) override; void RenX_OnKill(RenX::Server *server, const Jupiter::ReadableString &killer, const RenX::TeamType &killerTeam, const RenX::PlayerInfo *victim, const Jupiter::ReadableString &damageType) override; void RenX_OnDie(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &damageType) override; void RenX_OnDie(RenX::Server *server, const Jupiter::ReadableString &object, const RenX::TeamType &objectTeam, const Jupiter::ReadableString &damageType) override; - void RenX_OnDestroy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &objectName, const Jupiter::ReadableString &damageType, RenX::ObjectType type) override; + void RenX_OnDestroy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &objectName, const RenX::TeamType &objectTeam, const Jupiter::ReadableString &damageType, RenX::ObjectType type) override; void RenX_OnDestroy(RenX::Server *server, const Jupiter::ReadableString &killer, const RenX::TeamType &killerTeam, const Jupiter::ReadableString &objectName, const RenX::TeamType &objectTeam, const Jupiter::ReadableString &damageType, RenX::ObjectType type) override; void RenX_OnCapture(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &building, const RenX::TeamType &oldTeam) override; void RenX_OnNeutralize(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &building, const RenX::TeamType &oldTeam) override; + void RenX_OnCharacterPurchase(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) override; + void RenX_OnItemPurchase(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &item) override; + void RenX_OnWeaponPurchase(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &weapon) override; + void RenX_OnRefillPurchase(RenX::Server *server, const RenX::PlayerInfo *player) override; + void RenX_OnVehiclePurchase(RenX::Server *server, const RenX::PlayerInfo *owner, const Jupiter::ReadableString &vehicle) override; + void RenX_OnVehicleSpawn(RenX::Server *server, const RenX::TeamType &team, const Jupiter::ReadableString &vehicle) override; + void RenX_OnSpawn(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) override; + void RenX_OnBotJoin(RenX::Server *server, const RenX::PlayerInfo *player) override; + void RenX_OnVehicleCrate(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &vehicle) override; + void RenX_OnDeathCrate(RenX::Server *server, const RenX::PlayerInfo *player) override; + void RenX_OnMoneyCrate(RenX::Server *server, const RenX::PlayerInfo *player, int amount) override; + void RenX_OnCharacterCrate(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) override; + void RenX_OnSpyCrate(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) override; + void RenX_OnRefillCrate(RenX::Server *server, const RenX::PlayerInfo *player) override; void RenX_OnSteal(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &vehicle) override; void RenX_OnSteal(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &vehicle, const RenX::PlayerInfo *victim) override; + void RenX_OnDonate(RenX::Server *server, const RenX::PlayerInfo *donor, const RenX::PlayerInfo *player, double amount) override; void RenX_OnGameOver(RenX::Server *server, RenX::WinType winType, const RenX::TeamType &team, int gScore, int nScore) override; void RenX_OnGame(RenX::Server *server, const Jupiter::ReadableString &raw) override; @@ -73,15 +91,12 @@ public: // RenX::Plugin void RenX_OnDemoRecord(RenX::Server *server, const RenX::PlayerInfo *player) override; void RenX_OnDemoRecord(RenX::Server *server, const Jupiter::ReadableString &user) override; + void RenX_OnDemoRecordStop(RenX::Server *server) override; void RenX_OnDemo(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_OnGrantCharacter(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &character) override; - void RenX_OnSpawnVehicle(RenX::Server *server, const RenX::PlayerInfo *owner, const Jupiter::ReadableString &vehicle) override; - void RenX_OnSpawnVehicleNoOwner(RenX::Server *server, const RenX::TeamType &team, const Jupiter::ReadableString &vehicle) override; - void RenX_OnMinePlace(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &mine) override; void RenX_XOnOther(RenX::Server *server, const Jupiter::ReadableString &raw) override; void RenX_OnCommand(RenX::Server *server, const Jupiter::ReadableString &raw) override; @@ -111,14 +126,32 @@ private: unsigned int hostPagePublic : 1; unsigned int otherChatPublic : 1; unsigned int deployPublic : 1; + unsigned int mineDeployPublic : 1; unsigned int disarmPublic : 1; + unsigned int mineDisarmPublic : 1; + unsigned int explodePublic : 1; unsigned int suicidePublic : 1; unsigned int killPublic : 1; unsigned int diePublic : 1; unsigned int destroyPublic : 1; unsigned int capturePublic : 1; unsigned int neutralizePublic : 1; + unsigned int characterPurchasePublic : 1; + unsigned int itemPurchasePublic : 1; + unsigned int weaponPurchasePublic : 1; + unsigned int refillPurchasePublic : 1; + unsigned int vehiclePurchasePublic : 1; + unsigned int vehicleSpawnPublic : 1; + unsigned int spawnPublic : 1; + unsigned int botJoinPublic : 1; + unsigned int vehicleCratePublic : 1; + unsigned int deathCratePublic : 1; + unsigned int moneyCratePublic : 1; + unsigned int characterCratePublic : 1; + unsigned int spyCratePublic : 1; + unsigned int refillCratePublic : 1; unsigned int stealPublic : 1; + unsigned int donatePublic : 1; unsigned int gameOverPublic : 1; unsigned int gamePublic : 1; unsigned int executePublic : 1; @@ -136,13 +169,10 @@ private: unsigned int mapLoadPublic : 1; unsigned int mapPublic : 1; unsigned int demoRecordPublic : 1; + unsigned int demoRecordStopPublic : 1; unsigned int demoPublic : 1; unsigned int logPublic : 1; unsigned int xVersionPublic : 1; - unsigned int grantCharacterPublic : 1; - unsigned int spawnVehiclePublic : 1; - unsigned int spawnVehicleNoOwnerPublic : 1; - unsigned int minePlacePublic : 1; unsigned int xOtherPublic : 1; unsigned int commandPublic : 1; unsigned int errorPublic : 1; @@ -162,7 +192,13 @@ private: Jupiter::StringS hostPageFmt; Jupiter::StringS otherChatFmt; Jupiter::StringS deployFmt; + Jupiter::StringS mineDeployFmt; Jupiter::StringS disarmFmt; + Jupiter::StringS mineDisarmFmt; + Jupiter::StringS disarmNoOwnerFmt; + Jupiter::StringS mineDisarmNoOwnerFmt; + Jupiter::StringS explodeFmt; + Jupiter::StringS explodeNoOwnerFmt; Jupiter::StringS suicideFmt; Jupiter::StringS dieFmt; Jupiter::StringS dieFmt2; @@ -176,8 +212,23 @@ private: Jupiter::StringS destroyVehicleFmt2; Jupiter::StringS captureFmt; Jupiter::StringS neutralizeFmt; + Jupiter::StringS characterPurchaseFmt; + Jupiter::StringS itemPurchaseFmt; + Jupiter::StringS weaponPurchaseFmt; + Jupiter::StringS refillPurchaseFmt; + Jupiter::StringS vehiclePurchaseFmt; + Jupiter::StringS vehicleSpawnFmt; + Jupiter::StringS spawnFmt; + Jupiter::StringS botJoinFmt; + Jupiter::StringS vehicleCrateFmt; + Jupiter::StringS deathCrateFmt; + Jupiter::StringS moneyCrateFmt; + Jupiter::StringS characterCrateFmt; + Jupiter::StringS spyCrateFmt; + Jupiter::StringS refillCrateFmt; Jupiter::StringS stealFmt; Jupiter::StringS stealNoOwnerFmt; + Jupiter::StringS donateFmt; Jupiter::StringS gameOverFmt; Jupiter::StringS gameOverTieFmt; Jupiter::StringS gameOverTieNoWinFmt; @@ -199,13 +250,10 @@ private: Jupiter::StringS mapLoadFmt; Jupiter::StringS mapFmt; Jupiter::StringS demoRecordFmt, rconDemoRecordFmt; + Jupiter::StringS demoRecordStopFmt; Jupiter::StringS demoFmt; Jupiter::StringS logFmt; Jupiter::StringS xVersionFmt; - Jupiter::StringS grantCharacterFmt; - Jupiter::StringS spawnVehicleFmt; - Jupiter::StringS spawnVehicleNoOwnerFmt; - Jupiter::StringS minePlaceFmt; Jupiter::StringS xOtherFmt; Jupiter::StringS commandFmt; Jupiter::StringS errorFmt; diff --git a/RenX.Medals/RenX_Medals.cpp b/RenX.Medals/RenX_Medals.cpp index 07fc0c6..e8c2a1e 100644 --- a/RenX.Medals/RenX_Medals.cpp +++ b/RenX.Medals/RenX_Medals.cpp @@ -226,7 +226,7 @@ void RenX_MedalsPlugin::RenX_OnGameOver(RenX::Server *server, RenX::WinType winT RenX_MedalsPlugin::medalsFile.sync(medalsFileName); } -void RenX_MedalsPlugin::RenX_OnDestroy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &objectName, const Jupiter::ReadableString &damageType, RenX::ObjectType type) +void RenX_MedalsPlugin::RenX_OnDestroy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &objectName, const RenX::TeamType &objectTeam, const Jupiter::ReadableString &damageType, RenX::ObjectType type) { if (type == RenX::ObjectType::Building) { diff --git a/RenX.Medals/RenX_Medals.h b/RenX.Medals/RenX_Medals.h index 0f04070..64e6c32 100644 --- a/RenX.Medals/RenX_Medals.h +++ b/RenX.Medals/RenX_Medals.h @@ -48,7 +48,7 @@ public: // RenX::Plugin void RenX_OnPlayerDelete(RenX::Server *server, const RenX::PlayerInfo *player) override; void RenX_OnJoin(RenX::Server *server, const RenX::PlayerInfo *player) override; void RenX_OnGameOver(RenX::Server *server, RenX::WinType winType, const RenX::TeamType &team, int gScore, int nScore) override; - void RenX_OnDestroy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &objectName, const Jupiter::ReadableString &damageType, RenX::ObjectType type) override; + void RenX_OnDestroy(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &objectName, const RenX::TeamType &objectTeam, const Jupiter::ReadableString &damageType, RenX::ObjectType type) override; RenX_MedalsPlugin(); ~RenX_MedalsPlugin();