Browse Source

Update Jupiter submodule; adjust code accordingly

master
Jessica James 3 years ago
parent
commit
cfedcfb20c
  1. 26
      src/Bot/include/Console_Command.h
  2. 2
      src/Bot/include/IRC_Bot.h
  3. 4
      src/Bot/include/ServerManager.h
  4. 2
      src/Bot/src/Console_Command.cpp
  5. 36
      src/Bot/src/IRC_Bot.cpp
  6. 24
      src/Bot/src/Main.cpp
  7. 9
      src/Bot/src/ServerManager.cpp
  8. 2
      src/Jupiter
  9. 45
      src/Plugins/ChannelRelay/ChannelRelay.cpp
  10. 2
      src/Plugins/ChannelRelay/ChannelRelay.h
  11. 34
      src/Plugins/CoreCommands/CoreCommands.cpp
  12. 45
      src/Plugins/ExtraCommands/ExtraCommands.cpp
  13. 26
      src/Plugins/FunCommands/FunCommands.cpp
  14. 6
      src/Plugins/HTTPServer/HTTPServer.cpp
  15. 2
      src/Plugins/IRC.Core/IRC_Core.cpp
  16. 10
      src/Plugins/IRC.Core/IRC_Core.h
  17. 2
      src/Plugins/Plugin.Example/Example.h
  18. 4
      src/Plugins/PluginManager/PluginManager.cpp
  19. 5
      src/Plugins/RenX/RenX.Announcements/RenX_Announcements.cpp
  20. 832
      src/Plugins/RenX/RenX.Commands/RenX_Commands.cpp
  21. 14
      src/Plugins/RenX/RenX.Core/RenX_BanDatabase.cpp
  22. 8
      src/Plugins/RenX/RenX.Core/RenX_BanDatabase.h
  23. 4
      src/Plugins/RenX/RenX.Core/RenX_Core.h
  24. 2
      src/Plugins/RenX/RenX.Core/RenX_ExemptionDatabase.h
  25. 8
      src/Plugins/RenX/RenX.Core/RenX_Functions.cpp
  26. 2
      src/Plugins/RenX/RenX.Core/RenX_Functions.h
  27. 2
      src/Plugins/RenX/RenX.Core/RenX_LadderDatabase.cpp
  28. 8
      src/Plugins/RenX/RenX.Core/RenX_PlayerInfo.h
  29. 328
      src/Plugins/RenX/RenX.Core/RenX_Server.cpp
  30. 32
      src/Plugins/RenX/RenX.Core/RenX_Server.h
  31. 2
      src/Plugins/RenX/RenX.ExcessiveHeadshots/RenX_ExcessiveHeadshots.cpp
  32. 48
      src/Plugins/RenX/RenX.ExtraLogging/RenX_ExtraLogging.cpp
  33. 16
      src/Plugins/RenX/RenX.Greetings/RenX_Greetings.cpp
  34. 6
      src/Plugins/RenX/RenX.IRCJoin/RenX_IRCJoin.cpp
  35. 4
      src/Plugins/RenX/RenX.IRCJoin/RenX_IRCJoin.h
  36. 2
      src/Plugins/RenX/RenX.KickDupes/RenX_KickDupes.cpp
  37. 5
      src/Plugins/RenX/RenX.Ladder.Web/RenX_Ladder_Web.cpp
  38. 14
      src/Plugins/RenX/RenX.Ladder/RenX_Ladder.cpp
  39. 42
      src/Plugins/RenX/RenX.Logging/RenX_Logging.cpp
  40. 139
      src/Plugins/RenX/RenX.Medals/RenX_Medals.cpp
  41. 148
      src/Plugins/RenX/RenX.ModSystem/RenX_ModSystem.cpp
  42. 8
      src/Plugins/RenX/RenX.Relay/RenX_Relay.cpp
  43. 4
      src/Plugins/RenX/RenX.ServerList/RenX_ServerList.cpp
  44. 57
      src/Plugins/RenX/RenX.SetJoin/RenX_SetJoin.cpp
  45. 24
      src/Plugins/RenX/RenX.Warn/RenX_Warn.cpp
  46. 6
      src/Plugins/SetJoin/SetJoin.cpp
  47. 2
      src/Plugins/SetJoin/SetJoin.h

26
src/Bot/include/Console_Command.h

@ -72,7 +72,7 @@ public:
* @param trigger Trigger of the command to fetch. * @param trigger Trigger of the command to fetch.
* @return A console command if it exists, nullptr otherwise. * @return A console command if it exists, nullptr otherwise.
*/ */
JUPITER_BOT_API extern ConsoleCommand *getConsoleCommand(const Jupiter::ReadableString &trigger); JUPITER_BOT_API extern ConsoleCommand *getConsoleCommand(std::string_view trigger);
/** Console Command Macros */ /** Console Command Macros */
@ -103,23 +103,21 @@ public:
Generic_Command_As_Console_Command(); Generic_Command_As_Console_Command();
}; };
template <typename T> Generic_Command_As_Console_Command<T>::Generic_Command_As_Console_Command() : ConsoleCommand() template <typename T> Generic_Command_As_Console_Command<T>::Generic_Command_As_Console_Command() : ConsoleCommand() {
{
size_t index = 0; size_t index = 0;
while (index != T::instance.getTriggerCount()) while (index != T::instance.getTriggerCount()) {
this->addTrigger(T::instance.getTrigger(index++)); this->addTrigger(T::instance.getTrigger(index++));
}
} }
template<typename T> void Generic_Command_As_Console_Command<T>::trigger(const Jupiter::ReadableString &parameters) template<typename T> void Generic_Command_As_Console_Command<T>::trigger(const Jupiter::ReadableString &parameters) {
{ std::unique_ptr<Jupiter::GenericCommand::ResponseLine> response_line{ T::instance.trigger(parameters) };
Jupiter::GenericCommand::ResponseLine *del; while (response_line != nullptr) {
Jupiter::GenericCommand::ResponseLine *ret = T::instance.trigger(parameters); auto& out_stream = response_line->type == Jupiter::GenericCommand::DisplayType::PublicError
while (ret != nullptr) || response_line->type == Jupiter::GenericCommand::DisplayType::PrivateError ? std::cerr : std::cout;
{
ret->response.println(ret->type == Jupiter::GenericCommand::DisplayType::PublicError || ret->type == Jupiter::GenericCommand::DisplayType::PrivateError ? stderr : stdout); out_stream << response_line->response << std::endl;
del = ret; response_line.reset(response_line->next);
ret = ret->next;
delete del;
} }
} }

2
src/Bot/include/IRC_Bot.h

@ -112,7 +112,7 @@ public:
/** Overloaded events from Jupiter::IRC::Client */ /** Overloaded events from Jupiter::IRC::Client */
protected: protected:
void OnChat(const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &message); void OnChat(std::string_view channel, std::string_view nick, std::string_view message) override;
/** Private members for internal usage */ /** Private members for internal usage */
private: private:

4
src/Bot/include/ServerManager.h

@ -94,7 +94,7 @@ public:
* @param serverConfig Configuration section to match against. * @param serverConfig Configuration section to match against.
* @return Pointer to a matching server instance on success, nullptr otherwise. * @return Pointer to a matching server instance on success, nullptr otherwise.
*/ */
IRC_Bot *getServer(const Jupiter::ReadableString &serverConfig); IRC_Bot *getServer(std::string_view serverConfig);
/** /**
* @brief Fetches a server based on its index. * @brief Fetches a server based on its index.
@ -133,7 +133,7 @@ public:
* @param serverConfig Configuration section of the server to remove. * @param serverConfig Configuration section of the server to remove.
* @return True if a server was removed, false otherwise. * @return True if a server was removed, false otherwise.
*/ */
bool freeServer(const Jupiter::ReadableString &serverConfig); bool freeServer(std::string_view serverConfig);
/** /**
* @brief Returns the number of servers in the list. * @brief Returns the number of servers in the list.

2
src/Bot/src/Console_Command.cpp

@ -34,7 +34,7 @@ ConsoleCommand::~ConsoleCommand() {
} }
} }
ConsoleCommand* getConsoleCommand(const Jupiter::ReadableString &trigger) { ConsoleCommand* getConsoleCommand(std::string_view trigger) {
for (const auto& command : consoleCommands) { for (const auto& command : consoleCommands) {
if (command->matches(trigger)) { if (command->matches(trigger)) {
return command; return command;

36
src/Bot/src/IRC_Bot.cpp

@ -20,6 +20,7 @@
#include <cstring> #include <cstring>
#include <cctype> #include <cctype>
#include "jessilib/unicode.hpp" #include "jessilib/unicode.hpp"
#include "jessilib/word_split.hpp"
#include "Jupiter/Config.h" #include "Jupiter/Config.h"
#include "Jupiter/Plugin.h" #include "Jupiter/Plugin.h"
#include "Jupiter/Functions.h" #include "Jupiter/Functions.h"
@ -128,7 +129,7 @@ void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command) {
command = this->getCommand(tmp_key); command = this->getCommand(tmp_key);
if (command != nullptr && (in_command == nullptr || in_command == command)) { if (command != nullptr && (in_command == nullptr || in_command == command)) {
command->setAccessLevel(tmp_sub_key.asInt(), Jupiter::ReferenceString{entry.second}.asInt()); command->setAccessLevel(Jupiter::from_string<int>(tmp_sub_key), Jupiter::from_string<int>(entry.second));
} }
} }
else if (jessilib::starts_withi(tmp_sub_key, "Channel."sv)) { else if (jessilib::starts_withi(tmp_sub_key, "Channel."sv)) {
@ -137,14 +138,14 @@ void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command) {
// Assign access level to command (if command exists) // Assign access level to command (if command exists)
command = this->getCommand(tmp_key); command = this->getCommand(tmp_key);
if (command != nullptr && (in_command == nullptr || in_command == command)) if (command != nullptr && (in_command == nullptr || in_command == command))
command->setAccessLevel(tmp_sub_key, Jupiter::ReferenceString{entry.second}.asInt()); command->setAccessLevel(tmp_sub_key, Jupiter::from_string<int>(entry.second));
} }
} }
else { else {
// Assign access level to command (if command exists) // Assign access level to command (if command exists)
command = this->getCommand(entry.first); command = this->getCommand(entry.first);
if (command != nullptr && (in_command == nullptr || in_command == command)) if (command != nullptr && (in_command == nullptr || in_command == command))
command->setAccessLevel(Jupiter::ReferenceString{entry.second}.asInt()); command->setAccessLevel(Jupiter::from_string<int>(entry.second));
} }
}; };
}; };
@ -153,29 +154,22 @@ void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command) {
set_command_access_levels(getPrimaryConfigSection()); set_command_access_levels(getPrimaryConfigSection());
} }
void IRC_Bot::OnChat(const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &message) { void IRC_Bot::OnChat(std::string_view in_channel, std::string_view nick, std::string_view message) {
Channel *channel = this->getChannel(in_channel); Channel *channel = this->getChannel(in_channel);
if (channel != nullptr && channel->getType() >= 0) { if (channel != nullptr && channel->getType() >= 0) {
Jupiter::ReferenceString msg = message; std::string_view msg = message;
while (msg.isNotEmpty() && isspace(msg[0])) { while (!msg.empty() && isspace(msg[0])) {
msg.shiftRight(1); msg.remove_prefix(1);
} }
if (m_commandPrefix.size() <= msg.size()) { if (m_commandPrefix.size() <= msg.size()) {
bool matchesPrefix = true; bool matchesPrefix = jessilib::starts_withi(msg, m_commandPrefix);
size_t i;
for (i = 0; i != m_commandPrefix.size(); i++) {
if (toupper(msg.get(0)) != toupper(m_commandPrefix[i])) {
matchesPrefix = false;
break;
}
msg.shiftRight(1);
}
if (matchesPrefix) { if (matchesPrefix) {
Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(msg, 0, WHITESPACE);; // Strip off the prefix
Jupiter::ReferenceString parameters = Jupiter::ReferenceString::gotoWord(msg, 1, WHITESPACE); msg.remove_prefix(m_commandPrefix.size());
IRCCommand *cmd = getCommand(command);
auto message_split = jessilib::word_split_once_view(msg, WHITESPACE_SV);
IRCCommand *cmd = getCommand(message_split.first);
if (cmd != nullptr) { if (cmd != nullptr) {
IRCCommand::active_server = this; IRCCommand::active_server = this;
int command_access = cmd->getAccessLevel(channel); int command_access = cmd->getAccessLevel(channel);
@ -186,7 +180,7 @@ void IRC_Bot::OnChat(const Jupiter::ReadableString &in_channel, const Jupiter::R
this->sendNotice(nick, "Access Denied."_jrs); this->sendNotice(nick, "Access Denied."_jrs);
} }
else { else {
cmd->trigger(this, in_channel, nick, parameters); cmd->trigger(this, Jupiter::ReferenceString{in_channel}, Jupiter::ReferenceString{nick}, Jupiter::ReferenceString{message_split.second});
} }
IRCCommand::active_server = IRCCommand::selected_server; IRCCommand::active_server = IRCCommand::selected_server;

24
src/Bot/src/Main.cpp

@ -43,14 +43,16 @@ Jupiter::INIConfig o_config;
Jupiter::Config *Jupiter::g_config = &o_config; Jupiter::Config *Jupiter::g_config = &o_config;
std::chrono::steady_clock::time_point Jupiter::g_start_time = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point Jupiter::g_start_time = std::chrono::steady_clock::now();
#define INPUT_BUFFER_SIZE 2048 constexpr size_t INPUT_BUFFER_SIZE = 2048;
struct ConsoleInput { struct ConsoleInput {
Jupiter::String input; std::string input;
std::mutex input_mutex; std::mutex input_mutex;
bool awaiting_processing = false; bool awaiting_processing = false;
ConsoleInput() : input(INPUT_BUFFER_SIZE) {} ConsoleInput() {
input.reserve(INPUT_BUFFER_SIZE);
}
} console_input; } console_input;
void onTerminate() { void onTerminate() {
@ -127,7 +129,6 @@ void reinitialize_plugins() {
} // namespace Jupiter } // namespace Jupiter
[[noreturn]] void main_loop() { [[noreturn]] void main_loop() {
Jupiter::ReferenceString command;
size_t index; size_t index;
while (1) { while (1) {
index = 0; index = 0;
@ -144,14 +145,15 @@ void reinitialize_plugins() {
if (console_input.input_mutex.try_lock()) { if (console_input.input_mutex.try_lock()) {
if (console_input.awaiting_processing) { if (console_input.awaiting_processing) {
console_input.awaiting_processing = false; console_input.awaiting_processing = false;
command = Jupiter::ReferenceString::getWord(console_input.input, 0, WHITESPACE); auto input_split = jessilib::word_split_once_view(console_input.input, WHITESPACE_SV);
std::string_view command_name = input_split.first;
ConsoleCommand *cmd = getConsoleCommand(command); ConsoleCommand* command = getConsoleCommand(command_name);
if (cmd != nullptr) { if (command != nullptr) {
cmd->trigger(Jupiter::ReferenceString::gotoWord(console_input.input, 1, WHITESPACE)); command->trigger(Jupiter::ReferenceString{input_split.second});
} }
else { else {
printf("Error: Command \"%.*s\" not found." ENDL, static_cast<int>(command.size()), command.ptr()); printf("Error: Command \"%.*s\" not found." ENDL, static_cast<int>(command_name.size()), command_name.data());
} }
} }
console_input.input_mutex.unlock(); console_input.input_mutex.unlock();
@ -209,10 +211,10 @@ int main(int argc, const char **args) {
printf("Config loaded (%fms)." ENDL, time_taken); printf("Config loaded (%fms)." ENDL, time_taken);
if (plugins_directory.isEmpty()) if (plugins_directory.empty())
plugins_directory = o_config.get("PluginsDirectory"_jrs); plugins_directory = o_config.get("PluginsDirectory"_jrs);
if (configs_directory.isEmpty()) if (configs_directory.empty())
configs_directory = o_config.get("ConfigsDirectory"_jrs); configs_directory = o_config.get("ConfigsDirectory"_jrs);
if (plugins_directory.isNotEmpty()) { if (plugins_directory.isNotEmpty()) {

9
src/Bot/src/ServerManager.cpp

@ -16,6 +16,7 @@
* Written by Jessica James <jessica.aj@outlook.com> * Written by Jessica James <jessica.aj@outlook.com>
*/ */
#include "jessilib/unicode.hpp"
#include "Jupiter/Functions.h" #include "Jupiter/Functions.h"
#include "ServerManager.h" #include "ServerManager.h"
#include "IRC_Bot.h" #include "IRC_Bot.h"
@ -84,9 +85,9 @@ size_t ServerManager::syncCommands() {
return m_servers.size(); return m_servers.size();
} }
IRC_Bot *ServerManager::getServer(const Jupiter::ReadableString &serverConfig) { IRC_Bot *ServerManager::getServer(std::string_view serverConfig) {
for (const auto& server : m_servers) { for (const auto& server : m_servers) {
if (server->getConfigSection().equalsi(serverConfig)) { if (jessilib::equalsi(server->getConfigSection(), serverConfig)) {
return server.get(); return server.get();
} }
} }
@ -132,9 +133,9 @@ bool ServerManager::freeServer(IRC_Bot *server) {
return false; return false;
} }
bool ServerManager::freeServer(const Jupiter::ReadableString &serverConfig) { bool ServerManager::freeServer(std::string_view serverConfig) {
for (auto itr = m_servers.begin(); itr != m_servers.end(); ++itr) { for (auto itr = m_servers.begin(); itr != m_servers.end(); ++itr) {
if ((*itr)->getConfigSection().equalsi(serverConfig)) { if (jessilib::equalsi((*itr)->getConfigSection(), serverConfig)) {
m_servers.erase(itr); m_servers.erase(itr);
return true; return true;
} }

2
src/Jupiter

@ -1 +1 @@
Subproject commit 90165eead3d3bdbaf7403eb947a41b4a7513b161 Subproject commit 9db2fd92b8d7316d6b15a11b60c35036a010eaef

45
src/Plugins/ChannelRelay/ChannelRelay.cpp

@ -16,6 +16,7 @@
* Written by Jessica James <jessica.aj@outlook.com> * Written by Jessica James <jessica.aj@outlook.com>
*/ */
#include "jessilib/word_split.hpp"
#include "Jupiter/IRC_Client.h" #include "Jupiter/IRC_Client.h"
#include "Jupiter/String.hpp" #include "Jupiter/String.hpp"
#include "ServerManager.h" #include "ServerManager.h"
@ -23,51 +24,51 @@
#include "ChannelRelay.h" #include "ChannelRelay.h"
using namespace Jupiter::literals; using namespace Jupiter::literals;
using namespace std::literals;
bool ChannelRelayPlugin::initialize() bool ChannelRelayPlugin::initialize() {
{ std::string_view types_string = this->config.get("Types"_jrs);
Jupiter::ReferenceString str = this->config.get("Types"_jrs); std::vector<std::string_view> split_types = jessilib::word_split_view(types_string, WHITESPACE_SV);
unsigned int words = str.wordCount(WHITESPACE);
if (words == 0) if (split_types.empty()) {
return false; return false;
}
while (words != 0) for (const auto& type : split_types) {
ChannelRelayPlugin::types.concat(str.getWord(--words, WHITESPACE).asInt()); ChannelRelayPlugin::types.concat(Jupiter::asInt(type));
}
return true; return true;
} }
int ChannelRelayPlugin::OnRehash() int ChannelRelayPlugin::OnRehash() {
{
Jupiter::Plugin::OnRehash(); Jupiter::Plugin::OnRehash();
ChannelRelayPlugin::types.erase(); ChannelRelayPlugin::types.erase();
return this->initialize() ? 0 : -1; return this->initialize() ? 0 : -1;
} }
void ChannelRelayPlugin::OnChat(Jupiter::IRC::Client *server, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &message) void ChannelRelayPlugin::OnChat(Jupiter::IRC::Client *server, std::string_view channel, std::string_view nick, std::string_view message) {
{
Jupiter::IRC::Client::Channel *chan = server->getChannel(channel); Jupiter::IRC::Client::Channel *chan = server->getChannel(channel);
if (chan != nullptr) if (chan != nullptr) {
{
int type = chan->getType(); int type = chan->getType();
if (ChannelRelayPlugin::types.contains(type)) if (ChannelRelayPlugin::types.find(type) != std::string_view::npos) {
{
size_t serverCount = serverManager->size(); size_t serverCount = serverManager->size();
char prefix = chan->getUserPrefix(nick); char prefix = chan->getUserPrefix(nick);
Jupiter::String str; std::string user_string;
if (prefix == 0) { user_string = "<"sv;
str = "<"_jrs + nick + "> "_jrs + message; if (prefix != 0) {
} user_string += prefix;
else {
str = "<"_jrs + prefix + nick + "> "_jrs + message;
} }
user_string += nick;
user_string += "> "sv;
user_string += message;
while (serverCount != 0) { while (serverCount != 0) {
auto server = serverManager->getServer(--serverCount); auto server = serverManager->getServer(--serverCount);
for (auto& channel : server->getChannels()) { for (auto& channel : server->getChannels()) {
if (channel.second.getType() == type && &channel.second != chan) { if (channel.second.getType() == type && &channel.second != chan) {
server->sendMessage(channel.second.getName(), str); server->sendMessage(channel.second.getName(), user_string);
} }
} }
} }

2
src/Plugins/ChannelRelay/ChannelRelay.h

@ -25,7 +25,7 @@
class ChannelRelayPlugin : public Jupiter::Plugin class ChannelRelayPlugin : public Jupiter::Plugin
{ {
public: // Jupiter::Plugin public: // Jupiter::Plugin
void OnChat(Jupiter::IRC::Client *server, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &message) override; void OnChat(Jupiter::IRC::Client *server, std::string_view channel, std::string_view nick, std::string_view message) override;
int OnRehash() override; int OnRehash() override;
virtual bool initialize() override; virtual bool initialize() override;

34
src/Plugins/CoreCommands/CoreCommands.cpp

@ -17,6 +17,7 @@
*/ */
#include <cstring> #include <cstring>
#include "jessilib/word_split.hpp"
#include "Jupiter/Functions.h" #include "Jupiter/Functions.h"
#include "CoreCommands.h" #include "CoreCommands.h"
#include "IRC_Bot.h" #include "IRC_Bot.h"
@ -30,7 +31,7 @@ HelpConsoleCommand::HelpConsoleCommand() {
} }
void HelpConsoleCommand::trigger(const Jupiter::ReadableString &parameters) { void HelpConsoleCommand::trigger(const Jupiter::ReadableString &parameters) {
if (parameters.isEmpty()) { if (parameters.empty()) {
std::cout << "Supported commands:"; std::cout << "Supported commands:";
for (const auto& command : consoleCommands) { for (const auto& command : consoleCommands) {
std::cout << ' ' << command->getTrigger(); std::cout << ' ' << command->getTrigger();
@ -41,14 +42,14 @@ void HelpConsoleCommand::trigger(const Jupiter::ReadableString &parameters) {
return; return;
} }
Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE); auto command_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
ConsoleCommand *cmd = getConsoleCommand(command); ConsoleCommand *cmd = getConsoleCommand(command_split.first);
if (cmd == nullptr) { if (cmd == nullptr) {
printf("Error: Command \"%.*s\" not found." ENDL, static_cast<int>(command.size()), command.ptr()); std::cout << "Error: Command \"" << command_split.first << "\" not found." << std::endl;
return; return;
} }
cmd->getHelp(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)).println(stdout); std::cout << std::string_view{cmd->getHelp(Jupiter::ReferenceString{command_split.second})} << std::endl;
} }
const Jupiter::ReadableString &HelpConsoleCommand::getHelp(const Jupiter::ReadableString &) { const Jupiter::ReadableString &HelpConsoleCommand::getHelp(const Jupiter::ReadableString &) {
@ -69,25 +70,22 @@ void HelpIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &in_
if (channel != nullptr) if (channel != nullptr)
{ {
int access = source->getAccessLevel(*channel, nick); int access = source->getAccessLevel(*channel, nick);
if (parameters.isEmpty()) if (parameters.empty()) {
{ for (int i = 0; i <= access; i++) {
for (int i = 0; i <= access; i++)
{
auto cmds = source->getAccessCommands(channel, i); auto cmds = source->getAccessCommands(channel, i);
if (cmds.size() != 0) if (cmds.size() != 0) {
{
Jupiter::StringL triggers = source->getTriggers(cmds); Jupiter::StringL triggers = source->getTriggers(cmds);
if (triggers.size() >= 0) if (triggers.size() >= 0) {
source->sendNotice(nick, Jupiter::StringS::Format("Access level %d commands: %.*s", i, triggers.size(), triggers.ptr())); source->sendNotice(nick, Jupiter::StringS::Format("Access level %d commands: %.*s", i, triggers.size(), triggers.ptr()));
} }
} }
}
source->sendNotice(nick, "For command-specific help, use: help <command>"_jrs); source->sendNotice(nick, "For command-specific help, use: help <command>"_jrs);
} }
else else {
{ auto command_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
IRCCommand *cmd = source->getCommand(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE)); IRCCommand *cmd = source->getCommand(command_split.first);
if (cmd) if (cmd) {
{
int command_access = cmd->getAccessLevel(channel); int command_access = cmd->getAccessLevel(channel);
if (command_access < 0) if (command_access < 0)
@ -95,7 +93,7 @@ void HelpIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &in_
else if (access < command_access) else if (access < command_access)
source->sendNotice(nick, "Access Denied."_jrs); source->sendNotice(nick, "Access Denied."_jrs);
else else
source->sendNotice(nick, cmd->getHelp(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE))); source->sendNotice(nick, cmd->getHelp(Jupiter::ReferenceString{command_split.second}));
} }
else source->sendNotice(nick, "Error: Command not found."_jrs); else source->sendNotice(nick, "Error: Command not found."_jrs);
} }

45
src/Plugins/ExtraCommands/ExtraCommands.cpp

@ -17,11 +17,13 @@
*/ */
#include <cstring> #include <cstring>
#include "jessilib/word_split.hpp"
#include "Jupiter/Functions.h" #include "Jupiter/Functions.h"
#include "ExtraCommands.h" #include "ExtraCommands.h"
#include "IRC_Bot.h" #include "IRC_Bot.h"
using namespace Jupiter::literals; using namespace Jupiter::literals;
using namespace std::literals;
// Select Command // Select Command
@ -33,11 +35,11 @@ SelectGenericCommand::SelectGenericCommand()
Jupiter::GenericCommand::ResponseLine *SelectGenericCommand::trigger(const Jupiter::ReadableString &parameters) Jupiter::GenericCommand::ResponseLine *SelectGenericCommand::trigger(const Jupiter::ReadableString &parameters)
{ {
if (parameters.isEmpty()) if (parameters.empty())
{ {
if (IRCCommand::selected_server == nullptr) if (IRCCommand::selected_server == nullptr)
return new Jupiter::GenericCommand::ResponseLine("No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicSuccess); return new Jupiter::GenericCommand::ResponseLine("No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicSuccess);
return new Jupiter::GenericCommand::ResponseLine(IRCCommand::selected_server->getConfigSection() + " is currently selected."_jrs, GenericCommand::DisplayType::PublicSuccess); return new Jupiter::GenericCommand::ResponseLine(std::string{IRCCommand::selected_server->getConfigSection()} + " is currently selected."s, GenericCommand::DisplayType::PublicSuccess);
} }
if (IRCCommand::active_server == IRCCommand::selected_server) if (IRCCommand::active_server == IRCCommand::selected_server)
IRCCommand::active_server = nullptr; IRCCommand::active_server = nullptr;
@ -48,7 +50,7 @@ Jupiter::GenericCommand::ResponseLine *SelectGenericCommand::trigger(const Jupit
if (IRCCommand::active_server == nullptr) if (IRCCommand::active_server == nullptr)
IRCCommand::active_server = IRCCommand::selected_server; IRCCommand::active_server = IRCCommand::selected_server;
return new Jupiter::GenericCommand::ResponseLine(IRCCommand::selected_server->getConfigSection() + " is now selected."_jrs, GenericCommand::DisplayType::PublicSuccess); return new Jupiter::GenericCommand::ResponseLine(std::string{IRCCommand::selected_server->getConfigSection()} + " is now selected."s, GenericCommand::DisplayType::PublicSuccess);
} }
const Jupiter::ReadableString &SelectGenericCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &SelectGenericCommand::getHelp(const Jupiter::ReadableString &)
@ -77,7 +79,7 @@ Jupiter::GenericCommand::ResponseLine *DeselectGenericCommand::trigger(const Jup
if (IRCCommand::selected_server == nullptr) if (IRCCommand::selected_server == nullptr)
return new Jupiter::GenericCommand::ResponseLine("No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicSuccess); return new Jupiter::GenericCommand::ResponseLine("No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicSuccess);
Jupiter::GenericCommand::ResponseLine *ret = new Jupiter::GenericCommand::ResponseLine(IRCCommand::selected_server->getConfigSection() + " has been deselected."_jrs, GenericCommand::DisplayType::PublicSuccess); Jupiter::GenericCommand::ResponseLine *ret = new Jupiter::GenericCommand::ResponseLine(std::string{IRCCommand::selected_server->getConfigSection()} + " has been deselected."s, GenericCommand::DisplayType::PublicSuccess);
IRCCommand::selected_server = nullptr; IRCCommand::selected_server = nullptr;
IRCCommand::active_server = IRCCommand::selected_server; IRCCommand::active_server = IRCCommand::selected_server;
return ret; return ret;
@ -110,7 +112,7 @@ Jupiter::GenericCommand::ResponseLine *RawGenericCommand::trigger(const Jupiter:
else else
return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError);
if (parameters.isEmpty()) if (parameters.empty())
return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: raw <message>"_jrs, GenericCommand::DisplayType::PrivateError); return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: raw <message>"_jrs, GenericCommand::DisplayType::PrivateError);
server->send(parameters); server->send(parameters);
@ -145,10 +147,11 @@ Jupiter::GenericCommand::ResponseLine *IRCMessageGenericCommand::trigger(const J
else else
return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError);
if (parameters.wordCount(WHITESPACE) < 3) auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
if (parameters_split.second.empty())
return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: ircmsg <destination> <message>"_jrs, GenericCommand::DisplayType::PrivateError); return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: ircmsg <destination> <message>"_jrs, GenericCommand::DisplayType::PrivateError);
server->sendMessage(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE), Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)); server->sendMessage(Jupiter::ReferenceString{parameters_split.first}, Jupiter::ReferenceString{parameters_split.second});
return new Jupiter::GenericCommand::ResponseLine("Message successfully sent."_jrs, GenericCommand::DisplayType::PublicSuccess); return new Jupiter::GenericCommand::ResponseLine("Message successfully sent."_jrs, GenericCommand::DisplayType::PublicSuccess);
} }
@ -178,13 +181,16 @@ Jupiter::GenericCommand::ResponseLine *JoinGenericCommand::trigger(const Jupiter
else else
return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError);
if (parameters.isEmpty()) if (parameters.empty())
return new Jupiter::GenericCommand::ResponseLine("Error: Too Few Parameters. Syntax: join <channel> [password]"_jrs, GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine("Error: Too Few Parameters. Syntax: join <channel> [password]"_jrs, GenericCommand::DisplayType::PublicError);
if (parameters.wordCount(WHITESPACE) == 1) auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
if (parameters_split.second.empty()) {
server->joinChannel(parameters); server->joinChannel(parameters);
else }
server->joinChannel(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE), Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)); else {
server->joinChannel(parameters_split.first, parameters_split.second);
}
return new Jupiter::GenericCommand::ResponseLine("Request to join channel has been sent."_jrs, GenericCommand::DisplayType::PublicSuccess); return new Jupiter::GenericCommand::ResponseLine("Request to join channel has been sent."_jrs, GenericCommand::DisplayType::PublicSuccess);
} }
@ -215,13 +221,16 @@ Jupiter::GenericCommand::ResponseLine *PartGenericCommand::trigger(const Jupiter
else else
return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError);
if (parameters.isEmpty()) if (parameters.empty())
return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: part <channel> [message]"_jrs, GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: part <channel> [message]"_jrs, GenericCommand::DisplayType::PublicError);
if (parameters.wordCount(WHITESPACE) == 1) auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
if (parameters_split.second.empty()) {
server->partChannel(parameters); server->partChannel(parameters);
else }
server->partChannel(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE), Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)); else {
server->partChannel(parameters_split.first, parameters_split.second);
}
return new Jupiter::GenericCommand::ResponseLine("Part command successfuly sent."_jrs, GenericCommand::DisplayType::PublicSuccess); return new Jupiter::GenericCommand::ResponseLine("Part command successfuly sent."_jrs, GenericCommand::DisplayType::PublicSuccess);
} }
@ -252,8 +261,8 @@ Jupiter::GenericCommand::ResponseLine *DebugInfoGenericCommand::trigger(const Ju
else else
return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine("Error: No IRC server is currently selected."_jrs, GenericCommand::DisplayType::PublicError);
Jupiter::GenericCommand::ResponseLine *ret = new Jupiter::GenericCommand::ResponseLine("Prefixes: "_jrs + server->getPrefixes(), GenericCommand::DisplayType::PublicSuccess); Jupiter::GenericCommand::ResponseLine *ret = new Jupiter::GenericCommand::ResponseLine("Prefixes: "s += server->getPrefixes(), GenericCommand::DisplayType::PublicSuccess);
Jupiter::GenericCommand::ResponseLine *line = new Jupiter::GenericCommand::ResponseLine("Prefix Modes: "_jrs + server->getPrefixModes(), GenericCommand::DisplayType::PublicSuccess); Jupiter::GenericCommand::ResponseLine *line = new Jupiter::GenericCommand::ResponseLine("Prefix Modes: "s += server->getPrefixModes(), GenericCommand::DisplayType::PublicSuccess);
ret->next = line; ret->next = line;
line->next = new Jupiter::GenericCommand::ResponseLine(Jupiter::StringS::Format("Outputting data for %u channels...", server->getChannelCount()), GenericCommand::DisplayType::PublicSuccess); line->next = new Jupiter::GenericCommand::ResponseLine(Jupiter::StringS::Format("Outputting data for %u channels...", server->getChannelCount()), GenericCommand::DisplayType::PublicSuccess);
line = line->next; line = line->next;
@ -313,7 +322,7 @@ IRCConnectGenericCommand::IRCConnectGenericCommand()
Jupiter::GenericCommand::ResponseLine *IRCConnectGenericCommand::trigger(const Jupiter::ReadableString &parameters) Jupiter::GenericCommand::ResponseLine *IRCConnectGenericCommand::trigger(const Jupiter::ReadableString &parameters)
{ {
if (parameters.isEmpty()) if (parameters.empty())
{ {
IRC_Bot *server; IRC_Bot *server;
if (IRCCommand::selected_server != nullptr) if (IRCCommand::selected_server != nullptr)

26
src/Plugins/FunCommands/FunCommands.cpp

@ -17,6 +17,8 @@
*/ */
#include <cstring> #include <cstring>
#include "jessilib/word_split.hpp"
#include "jessilib/unicode.hpp"
#include "Jupiter/Functions.h" #include "Jupiter/Functions.h"
#include "Jupiter/Socket.h" #include "Jupiter/Socket.h"
#include "FunCommands.h" #include "FunCommands.h"
@ -157,25 +159,25 @@ ResolveGenericCommand::ResolveGenericCommand()
this->addTrigger("resolve"_jrs); this->addTrigger("resolve"_jrs);
} }
Jupiter::GenericCommand::ResponseLine *ResolveGenericCommand::trigger(const Jupiter::ReadableString &parameters) Jupiter::GenericCommand::ResponseLine *ResolveGenericCommand::trigger(const Jupiter::ReadableString &parameters) {
{ auto command_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
unsigned int count = parameters.wordCount(WHITESPACE); if (command_split.second.empty()) {
if (count <= 1)
return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: resolve <hostname|ip> <address>"_jrs, GenericCommand::DisplayType::PrivateError); return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: resolve <hostname|ip> <address>"_jrs, GenericCommand::DisplayType::PrivateError);
}
Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE); std::string_view subcommand = command_split.first;
if (command.equalsi("hostname"_jrs) || command.equalsi("host"_jrs)) if (jessilib::equalsi(subcommand, "hostname"sv)
|| jessilib::equalsi(subcommand, "host"sv))
{ {
Jupiter::ReferenceString resolved = Jupiter::Socket::resolveHostname(static_cast<std::string>(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)).c_str(), 0); Jupiter::ReferenceString resolved = Jupiter::Socket::resolveHostname(static_cast<std::string>(command_split.second).c_str(), 0);
if (resolved.isEmpty()) if (resolved.empty())
return new Jupiter::GenericCommand::ResponseLine("Error: Unable to resolve."_jrs, GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine("Error: Unable to resolve."_jrs, GenericCommand::DisplayType::PublicError);
return new Jupiter::GenericCommand::ResponseLine(resolved, GenericCommand::DisplayType::PublicSuccess); return new Jupiter::GenericCommand::ResponseLine(resolved, GenericCommand::DisplayType::PublicSuccess);
} }
else if (command.equalsi("ip"_jrs)) else if (jessilib::equalsi(subcommand, "ip"sv))
{ {
Jupiter::ReferenceString resolved = Jupiter::Socket::resolveAddress(static_cast<std::string>(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)).c_str(), 0); Jupiter::ReferenceString resolved = Jupiter::Socket::resolveAddress(static_cast<std::string>(command_split.second).c_str(), 0);
if (resolved.isEmpty()) if (resolved.empty())
return new Jupiter::GenericCommand::ResponseLine("Error: Unable to resolve."_jrs, GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine("Error: Unable to resolve."_jrs, GenericCommand::DisplayType::PublicError);
return new Jupiter::GenericCommand::ResponseLine(resolved, GenericCommand::DisplayType::PublicSuccess); return new Jupiter::GenericCommand::ResponseLine(resolved, GenericCommand::DisplayType::PublicSuccess);
} }

6
src/Plugins/HTTPServer/HTTPServer.cpp

@ -19,10 +19,10 @@
#include "HTTPServer.h" #include "HTTPServer.h"
using namespace Jupiter::literals; using namespace Jupiter::literals;
using namespace std::literals;
bool HTTPServerPlugin::initialize() bool HTTPServerPlugin::initialize() {
{ return HTTPServerPlugin::server.bind(this->config.get("BindAddress"_jrs, "0.0.0.0"sv), this->config.get<uint16_t>("BindPort"_jrs, 80));
return HTTPServerPlugin::server.bind(this->config.get("BindAddress"_jrs, "0.0.0.0"_jrs), this->config.get<uint16_t>("BindPort"_jrs, 80));
} }
int HTTPServerPlugin::think() int HTTPServerPlugin::think()

2
src/Plugins/IRC.Core/IRC_Core.cpp

@ -37,7 +37,7 @@ bool IRCCorePlugin::initialize() {
if (!serverList.empty()) { if (!serverList.empty()) {
serverManager->setConfig(this->config); serverManager->setConfig(this->config);
auto server_entries = jessilib::word_split(serverList, WHITESPACE_SV); auto server_entries = jessilib::word_split_view(serverList, WHITESPACE_SV);
for (const auto& entry : server_entries) { for (const auto& entry : server_entries) {
serverManager->addServer(entry); serverManager->addServer(entry);
} }

10
src/Plugins/IRC.Core/IRC_Core.h

@ -28,29 +28,29 @@ public:
/** /**
* @brief Initializes the plugin * @brief Initializes the plugin
*/ */
virtual bool initialize() override; bool initialize() override;
/** /**
* @brief Called when there is a rehash * @brief Called when there is a rehash
* *
* @return 0 always. * @return 0 always.
*/ */
virtual int OnRehash() override; int OnRehash() override;
/** /**
* @brief Cycles through IRC servers for new data * @brief Cycles through IRC servers for new data
*/ */
virtual int think() override; int think() override;
/** /**
* @brief This is called when a GenericCommand is instantiated. * @brief This is called when a GenericCommand is instantiated.
*/ */
virtual void OnGenericCommandAdd(Jupiter::GenericCommand &command); void OnGenericCommandAdd(Jupiter::GenericCommand &command) override;
/** /**
* @brief This is called when a GenericCommand is deleted. * @brief This is called when a GenericCommand is deleted.
*/ */
virtual void OnGenericCommandRemove(Jupiter::GenericCommand &command); void OnGenericCommandRemove(Jupiter::GenericCommand &command) override;
/** /**
* @brief Destructor for the IRCCorPlugin class * @brief Destructor for the IRCCorPlugin class

2
src/Plugins/Plugin.Example/Example.h

@ -15,7 +15,7 @@
class ExamplePlugin : public Jupiter::Plugin class ExamplePlugin : public Jupiter::Plugin
{ {
public: public:
void OnConnect(Jupiter::IRC::Client *server); void OnConnect(Jupiter::IRC::Client *server) override;
}; };
// Example IRC Command Declaration // Example IRC Command Declaration

4
src/Plugins/PluginManager/PluginManager.cpp

@ -35,8 +35,9 @@ PluginGenericCommand::PluginGenericCommand() {
} }
Jupiter::GenericCommand::ResponseLine *PluginGenericCommand::trigger(const Jupiter::ReadableString &parameters) { Jupiter::GenericCommand::ResponseLine *PluginGenericCommand::trigger(const Jupiter::ReadableString &parameters) {
auto parameters_view = static_cast<std::string_view>(parameters);
Jupiter::GenericCommand::ResponseLine *result = new Jupiter::GenericCommand::ResponseLine(); Jupiter::GenericCommand::ResponseLine *result = new Jupiter::GenericCommand::ResponseLine();
if (parameters.isEmpty() || parameters.matchi("list*")) { if (parameters_view.empty() || jessilib::starts_withi(parameters_view, "list"sv)) {
Jupiter::GenericCommand::ResponseLine *line = result->set(Jupiter::String::Format("There are %u plugins loaded:", Jupiter::plugins.size()), GenericCommand::DisplayType::PublicSuccess); Jupiter::GenericCommand::ResponseLine *line = result->set(Jupiter::String::Format("There are %u plugins loaded:", Jupiter::plugins.size()), GenericCommand::DisplayType::PublicSuccess);
for (auto& plugin : Jupiter::plugins) { for (auto& plugin : Jupiter::plugins) {
line->next = new Jupiter::GenericCommand::ResponseLine(plugin->getName(), GenericCommand::DisplayType::PublicSuccess); line->next = new Jupiter::GenericCommand::ResponseLine(plugin->getName(), GenericCommand::DisplayType::PublicSuccess);
@ -57,7 +58,6 @@ Jupiter::GenericCommand::ResponseLine *PluginGenericCommand::trigger(const Jupit
return static_cast<Jupiter::Plugin*>(nullptr); return static_cast<Jupiter::Plugin*>(nullptr);
}; };
auto parameters_view = static_cast<std::string_view>(parameters);
auto split_params = jessilib::word_split_once_view(parameters_view, WHITESPACE_SV); auto split_params = jessilib::word_split_once_view(parameters_view, WHITESPACE_SV);
if (jessilib::starts_withi(parameters_view, "load "sv)) { if (jessilib::starts_withi(parameters_view, "load "sv)) {
if (Jupiter::Plugin::load(split_params.second) == nullptr) { if (Jupiter::Plugin::load(split_params.second) == nullptr) {

5
src/Plugins/RenX/RenX.Announcements/RenX_Announcements.cpp

@ -23,6 +23,7 @@
#include "RenX_Tags.h" #include "RenX_Tags.h"
using namespace Jupiter::literals; using namespace Jupiter::literals;
using namespace std::literals;
RenX_AnnouncementsPlugin pluginInstance; RenX_AnnouncementsPlugin pluginInstance;
@ -74,9 +75,9 @@ int RenX_AnnouncementsPlugin::OnRehash()
bool RenX_AnnouncementsPlugin::initialize() bool RenX_AnnouncementsPlugin::initialize()
{ {
RenX_AnnouncementsPlugin::random = this->config.get<bool>("Random"_jrs); RenX_AnnouncementsPlugin::random = this->config.get<bool>("Random"sv);
RenX_AnnouncementsPlugin::announcementsFile.load(this->config.get("File"_jrs, "Announcements.txt"_jrs)); RenX_AnnouncementsPlugin::announcementsFile.load(this->config.get("File"sv, "Announcements.txt"s));
if (RenX_AnnouncementsPlugin::announcementsFile.getLineCount() == 0) if (RenX_AnnouncementsPlugin::announcementsFile.getLineCount() == 0)
{ {
fputs("[RenX.Announcements] ERROR: No announcements loaded." ENDL, stderr); fputs("[RenX.Announcements] ERROR: No announcements loaded." ENDL, stderr);

832
src/Plugins/RenX/RenX.Commands/RenX_Commands.cpp

File diff suppressed because it is too large

14
src/Plugins/RenX/RenX.Core/RenX_BanDatabase.cpp

@ -168,7 +168,7 @@ void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo &player
entry->steamid = player.steamid; entry->steamid = player.steamid;
entry->ip = player.ip32; entry->ip = player.ip32;
entry->prefix_length = 32U; entry->prefix_length = 32U;
if (player.hwid.span('0') != player.hwid.size()) { if (player.hwid.find_first_not_of('0') != std::string::npos) {
entry->hwid = player.hwid; entry->hwid = player.hwid;
} }
if (player.rdns_thread.joinable()) if (player.rdns_thread.joinable())
@ -190,7 +190,7 @@ void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo &player
write(m_entries.back().get()); write(m_entries.back().get());
} }
void RenX::BanDatabase::add(const Jupiter::ReadableString &name, uint32_t ip, uint8_t prefix_length, uint64_t steamid, const Jupiter::ReadableString &hwid, const Jupiter::ReadableString &rdns, std::string_view banner, std::string_view reason, std::chrono::seconds length, uint16_t flags) { void RenX::BanDatabase::add(std::string name, uint32_t ip, uint8_t prefix_length, uint64_t steamid, std::string hwid, std::string rdns, std::string banner, std::string reason, std::chrono::seconds length, uint16_t flags) {
std::unique_ptr<Entry> entry = std::make_unique<Entry>(); std::unique_ptr<Entry> entry = std::make_unique<Entry>();
entry->set_active(); entry->set_active();
entry->flags |= flags; entry->flags |= flags;
@ -199,11 +199,11 @@ void RenX::BanDatabase::add(const Jupiter::ReadableString &name, uint32_t ip, ui
entry->steamid = steamid; entry->steamid = steamid;
entry->ip = ip; entry->ip = ip;
entry->prefix_length = prefix_length; entry->prefix_length = prefix_length;
entry->hwid = hwid; entry->hwid = std::move(hwid);
entry->rdns = rdns; entry->rdns = std::move(rdns);
entry->name = name; entry->name = std::move(name);
entry->banner = banner; entry->banner = std::move(banner);
entry->reason = reason; entry->reason = std::move(reason);
m_entries.push_back(std::move(entry)); m_entries.push_back(std::move(entry));
write(m_entries.back().get()); write(m_entries.back().get());

8
src/Plugins/RenX/RenX.Core/RenX_BanDatabase.h

@ -87,9 +87,9 @@ namespace RenX
uint64_t steamid /** SteamID of the banned player */; uint64_t steamid /** SteamID of the banned player */;
uint32_t ip /** IPv4 address of the banned player */; uint32_t ip /** IPv4 address of the banned player */;
uint8_t prefix_length /** Prefix length for the IPv4 address block */; uint8_t prefix_length /** Prefix length for the IPv4 address block */;
Jupiter::StringS hwid; /** Hardware ID of the banned player */ std::string hwid; /** Hardware ID of the banned player */
Jupiter::StringS rdns /** RDNS of the banned player */; std::string rdns /** RDNS of the banned player */;
Jupiter::StringS name /** Name of the banned player */; std::string name /** Name of the banned player */;
std::string banner /** Name of the user who initiated the ban */; std::string banner /** Name of the user who initiated the ban */;
std::string reason /** Reason the player was banned */; std::string reason /** Reason the player was banned */;
VarDataTableType varData; /** Variable entry data */ VarDataTableType varData; /** Variable entry data */
@ -158,7 +158,7 @@ namespace RenX
* @param reason Reason the player is getting banned * @param reason Reason the player is getting banned
* @param length Duration of the ban * @param length Duration of the ban
*/ */
void add(const Jupiter::ReadableString &name, uint32_t ip, uint8_t prefix_length, uint64_t steamid, const Jupiter::ReadableString &hwid, const Jupiter::ReadableString &rdns, std::string_view banner, std::string_view reason, std::chrono::seconds length, uint16_t flags = RenX::BanDatabase::Entry::FLAG_TYPE_GAME); void add(std::string name, uint32_t ip, uint8_t prefix_length, uint64_t steamid, std::string hwid, std::string rdns, std::string banner, std::string reason, std::chrono::seconds length, uint16_t flags = RenX::BanDatabase::Entry::FLAG_TYPE_GAME);
/** /**
* @brief Upgrades the ban database to the current write_version. * @brief Upgrades the ban database to the current write_version.

4
src/Plugins/RenX/RenX.Core/RenX_Core.h

@ -58,14 +58,14 @@ namespace RenX
* *
* @return Result of Jupiter::Plugin::Think(). * @return Result of Jupiter::Plugin::Think().
*/ */
virtual int think(); int think() override;
/** /**
* @brief Initializes RenX.Core * @brief Initializes RenX.Core
* *
* @return True. * @return True.
*/ */
virtual bool initialize() override; bool initialize() override;
/** /**
* @brief Sends a command to all servers of a specific type. * @brief Sends a command to all servers of a specific type.

2
src/Plugins/RenX/RenX.Core/RenX_ExemptionDatabase.h

@ -81,7 +81,7 @@ namespace RenX
uint64_t steamid /** SteamID of the exempted player */; uint64_t steamid /** SteamID of the exempted player */;
uint32_t ip /** IPv4 address of the exempted player */; uint32_t ip /** IPv4 address of the exempted player */;
uint8_t prefix_length /** Prefix length for the IPv4 address block */; uint8_t prefix_length /** Prefix length for the IPv4 address block */;
Jupiter::StringS setter /** Name of the user who added the exemption */; std::string setter /** Name of the user who added the exemption */;
static const uint8_t FLAG_ACTIVE = 0x80; static const uint8_t FLAG_ACTIVE = 0x80;
static const uint8_t FLAG_USE_IP = 0x40; static const uint8_t FLAG_USE_IP = 0x40;

8
src/Plugins/RenX/RenX.Core/RenX_Functions.cpp

@ -495,7 +495,7 @@ const Jupiter::ReferenceString &translateCharacter(Jupiter::ReferenceString &obj
std::string_view RenX::translateName(std::string_view obj) std::string_view RenX::translateName(std::string_view obj)
{ {
if (obj.empty()) if (obj.empty())
return Jupiter::ReferenceString::empty; return ""_jrs;
Jupiter::ReferenceString iniTranslation = RenX::getCore()->getConfig()["Name"_jrs].get(Jupiter::ReferenceString{obj}); Jupiter::ReferenceString iniTranslation = RenX::getCore()->getConfig()["Name"_jrs].get(Jupiter::ReferenceString{obj});
if (iniTranslation.isNotEmpty()) if (iniTranslation.isNotEmpty())
@ -912,11 +912,11 @@ double RenX::getHeadshotKillRatio(const RenX::PlayerInfo &player)
return static_cast<double>(player.headshots) / static_cast<double>(player.kills); return static_cast<double>(player.headshots) / static_cast<double>(player.kills);
} }
Jupiter::String RenX::escapifyRCON(std::string_view str) std::string RenX::escapifyRCON(std::string_view str) {
{
const char *ptr = str.data(); const char *ptr = str.data();
size_t length = str.size(); size_t length = str.size();
Jupiter::String result(str.size() + 32); std::string result;
result.reserve(str.size() + 32);
uint16_t value; uint16_t value;
while (length != 0) while (length != 0)

2
src/Plugins/RenX/RenX.Core/RenX_Functions.h

@ -187,7 +187,7 @@ namespace RenX
* @param str String to escapify * @param str String to escapify
* @return Escapified version of str. * @return Escapified version of str.
*/ */
RENX_API Jupiter::String escapifyRCON(std::string_view str); RENX_API std::string escapifyRCON(std::string_view str);
/** Constant variables */ /** Constant variables */
RENX_API extern const char DelimC; /** RCON message deliminator */ RENX_API extern const char DelimC; /** RCON message deliminator */

2
src/Plugins/RenX/RenX.Core/RenX_LadderDatabase.cpp

@ -597,7 +597,7 @@ void RenX::LadderDatabase::updateLadder(RenX::Server &server, const RenX::TeamTy
getEntries(), getEntries(),
static_cast<double>(sort_duration.count()) * (static_cast<double>(std::chrono::steady_clock::duration::period::num) / static_cast<double>(std::chrono::steady_clock::duration::period::den) * static_cast<double>(std::chrono::seconds::duration::period::den / std::chrono::seconds::duration::period::num)), static_cast<double>(sort_duration.count()) * (static_cast<double>(std::chrono::steady_clock::duration::period::num) / static_cast<double>(std::chrono::steady_clock::duration::period::den) * static_cast<double>(std::chrono::seconds::duration::period::den / std::chrono::seconds::duration::period::num)),
static_cast<double>(write_duration.count()) * (static_cast<double>(std::chrono::steady_clock::duration::period::num) / static_cast<double>(std::chrono::steady_clock::duration::period::den) * static_cast<double>(std::chrono::seconds::duration::period::den / std::chrono::seconds::duration::period::num))); static_cast<double>(write_duration.count()) * (static_cast<double>(std::chrono::steady_clock::duration::period::num) / static_cast<double>(std::chrono::steady_clock::duration::period::den) * static_cast<double>(std::chrono::seconds::duration::period::den / std::chrono::seconds::duration::period::num)));
str.println(stdout); std::cout << std::string_view{str} << std::endl;
server.sendLogChan(str); server.sendLogChan(str);
} }
} }

8
src/Plugins/RenX/RenX.Core/RenX_PlayerInfo.h

@ -50,13 +50,13 @@ namespace RenX
// TODO: Add backpack // TODO: Add backpack
std::string name; std::string name;
Jupiter::StringS ip; std::string ip;
Jupiter::StringS adminType; Jupiter::StringS adminType;
Jupiter::StringS uuid; std::string uuid;
Jupiter::StringS character; Jupiter::StringS character;
Jupiter::StringS vehicle; Jupiter::StringS vehicle;
Jupiter::StringS rdns; std::string rdns;
Jupiter::StringS hwid; std::string hwid;
std::mutex rdns_mutex; std::mutex rdns_mutex;
uint64_t steamid = 0; uint64_t steamid = 0;
uint32_t ip32 = 0; uint32_t ip32 = 0;

328
src/Plugins/RenX/RenX.Core/RenX_Server.cpp

@ -80,7 +80,7 @@ int RenX::Server::think() {
} }
// Fire player indentified event if ready // Fire player indentified event if ready
if (node->hwid.isNotEmpty()) { if (!node->hwid.empty()) {
for (auto plugin : RenX::getCore()->getPlugins()) { for (auto plugin : RenX::getCore()->getPlugins()) {
plugin->RenX_OnPlayerIdentify(*this, *node); plugin->RenX_OnPlayerIdentify(*this, *node);
} }
@ -293,11 +293,11 @@ int RenX::Server::sendAdminMessage(const Jupiter::ReadableString &message) {
return sendSocket("camsg "_jrs + RenX::escapifyRCON(message) + '\n'); return sendSocket("camsg "_jrs + RenX::escapifyRCON(message) + '\n');
} }
int RenX::Server::sendAdminMessage(const RenX::PlayerInfo &player, const Jupiter::ReadableString &message) { int RenX::Server::sendAdminMessage(const RenX::PlayerInfo &player, std::string_view message) {
return sendSocket("cpamsg pid"_jrs + Jupiter::StringS::Format("%d ", player.id) + RenX::escapifyRCON(message) + '\n'); return sendSocket("cpamsg pid"_jrs + Jupiter::StringS::Format("%d ", player.id) + RenX::escapifyRCON(message) + '\n');
} }
int RenX::Server::sendWarnMessage(const RenX::PlayerInfo &player, const Jupiter::ReadableString &message) { int RenX::Server::sendWarnMessage(const RenX::PlayerInfo &player, std::string_view message) {
return sendSocket("cwarn pid"_jrs + Jupiter::StringS::Format("%d ", player.id) + RenX::escapifyRCON(message) + '\n'); return sendSocket("cwarn pid"_jrs + Jupiter::StringS::Format("%d ", player.id) + RenX::escapifyRCON(message) + '\n');
} }
@ -335,11 +335,11 @@ std::string_view RenX::Server::getMapName(std::string_view name) const {
return {}; return {};
} }
const Jupiter::ReadableString &RenX::Server::getCurrentRCONCommand() const { std::string_view RenX::Server::getCurrentRCONCommand() const {
return m_lastCommand; return m_lastCommand;
} }
const Jupiter::ReadableString &RenX::Server::getCurrentRCONCommandParameters() const { std::string_view RenX::Server::getCurrentRCONCommandParameters() const {
return m_lastCommandParams; return m_lastCommandParams;
} }
@ -390,7 +390,7 @@ RenX::PlayerInfo *RenX::Server::getPlayer(int id) const {
return nullptr; return nullptr;
} }
RenX::PlayerInfo *RenX::Server::getPlayerByName(const Jupiter::ReadableString &name) const { RenX::PlayerInfo *RenX::Server::getPlayerByName(std::string_view name) const {
if (this->players.size() == 0) { if (this->players.size() == 0) {
return nullptr; return nullptr;
} }
@ -403,22 +403,21 @@ RenX::PlayerInfo *RenX::Server::getPlayerByName(const Jupiter::ReadableString &n
} }
// Try player ID // Try player ID
Jupiter::ReferenceString idToken = name; if (jessilib::starts_withi(name, "Player"sv)) {
if (name.matchi("Player?*")) { name.remove_prefix(6);
idToken.shiftRight(6);
} }
else if (name.matchi("pid?*")) { else if (jessilib::starts_withi(name, "pid"sv)) {
idToken.shiftRight(3); name.remove_prefix(3);
} }
else { else {
return nullptr; return nullptr;
} }
int id = idToken.asInt(10); int id = Jupiter::asInt(name, 10);
return getPlayer(id); return getPlayer(id);
} }
RenX::PlayerInfo *RenX::Server::getPlayerByPartName(const Jupiter::ReadableString &partName) const { RenX::PlayerInfo *RenX::Server::getPlayerByPartName(std::string_view partName) const {
if (this->players.size() == 0) if (this->players.size() == 0)
return nullptr; return nullptr;
@ -448,7 +447,7 @@ Jupiter::StringS RenX::Server::formatSteamID(const RenX::PlayerInfo &player) con
Jupiter::StringS RenX::Server::formatSteamID(uint64_t id) const { Jupiter::StringS RenX::Server::formatSteamID(uint64_t id) const {
if (id == 0) if (id == 0)
return Jupiter::ReferenceString::empty; return ""_jrs;
switch (m_steamFormat) switch (m_steamFormat)
{ {
@ -471,33 +470,33 @@ Jupiter::StringS RenX::Server::formatSteamID(uint64_t id) const {
} }
} }
void RenX::Server::kickPlayer(int id, const Jupiter::ReadableString &in_reason) { void RenX::Server::kickPlayer(int id, std::string_view in_reason) {
Jupiter::String reason = RenX::escapifyRCON(in_reason); std::string reason = RenX::escapifyRCON(in_reason);
if (reason.isEmpty()) if (reason.empty())
sendSocket(Jupiter::StringS::Format("ckick pid%d\n", id)); sendSocket(Jupiter::StringS::Format("ckick pid%d\n", id));
else else
sendSocket(Jupiter::StringS::Format("ckick pid%d %.*s\n", id, reason.size(), reason.ptr())); sendSocket(Jupiter::StringS::Format("ckick pid%d %.*s\n", id, reason.size(), reason.data()));
} }
void RenX::Server::kickPlayer(const RenX::PlayerInfo &player, const Jupiter::ReadableString &reason) { void RenX::Server::kickPlayer(const RenX::PlayerInfo &player, std::string_view reason) {
if ((player.exemption_flags & RenX::ExemptionDatabase::Entry::FLAG_TYPE_KICK) == 0) { if ((player.exemption_flags & RenX::ExemptionDatabase::Entry::FLAG_TYPE_KICK) == 0) {
kickPlayer(player.id, reason); kickPlayer(player.id, reason);
} }
} }
void RenX::Server::forceKickPlayer(int id, const Jupiter::ReadableString &in_reason) { void RenX::Server::forceKickPlayer(int id, std::string_view in_reason) {
Jupiter::String reason = RenX::escapifyRCON(in_reason); std::string reason = RenX::escapifyRCON(in_reason);
if (reason.isEmpty()) { if (reason.empty()) {
sendSocket(Jupiter::StringS::Format("cfkick pid%d You were kicked from the server.\n", id)); sendSocket(Jupiter::StringS::Format("cfkick pid%d You were kicked from the server.\n", id));
return; return;
} }
sendSocket(Jupiter::StringS::Format("cfkick pid%d %.*s\n", id, reason.size(), reason.ptr())); sendSocket(Jupiter::StringS::Format("cfkick pid%d %.*s\n", id, reason.size(), reason.data()));
} }
void RenX::Server::forceKickPlayer(const RenX::PlayerInfo &player, const Jupiter::ReadableString &reason) { void RenX::Server::forceKickPlayer(const RenX::PlayerInfo &player, std::string_view reason) {
if ((player.exemption_flags & RenX::ExemptionDatabase::Entry::FLAG_TYPE_KICK) == 0) { if ((player.exemption_flags & RenX::ExemptionDatabase::Entry::FLAG_TYPE_KICK) == 0) {
forceKickPlayer(player.id, reason); forceKickPlayer(player.id, reason);
} }
@ -554,9 +553,9 @@ void RenX::Server::banCheck(RenX::PlayerInfo &player) {
if ((m_localSteamBan && entry->steamid != 0 && entry->steamid == player.steamid) if ((m_localSteamBan && entry->steamid != 0 && entry->steamid == player.steamid)
|| (m_localIPBan && entry->ip != 0 && (entry->ip & netmask) == (player.ip32 & netmask)) || (m_localIPBan && entry->ip != 0 && (entry->ip & netmask) == (player.ip32 & netmask))
|| (m_localHWIDBan && entry->hwid.isNotEmpty() && entry->hwid == player.hwid) || (m_localHWIDBan && !entry->hwid.empty() && entry->hwid == player.hwid)
|| (m_localRDNSBan && entry->rdns.isNotEmpty() && entry->is_rdns_ban() && player.rdns_thread.joinable() == false && player.rdns.match(entry->rdns)) || (m_localRDNSBan && !entry->rdns.empty() && entry->is_rdns_ban() && !player.rdns_thread.joinable() && player.rdns.find(entry->rdns) != std::string::npos)
|| (m_localNameBan && entry->name.isNotEmpty() && entry->name.equalsi(player.name))) { || (m_localNameBan && !entry->name.empty() && jessilib::equalsi(entry->name, player.name))) {
player.ban_flags |= entry->flags; player.ban_flags |= entry->flags;
if (entry->is_type_game()) if (entry->is_type_game())
handle_type(entry.get(), 0); handle_type(entry.get(), 0);
@ -1052,12 +1051,12 @@ size_t RenX::Server::getCommandCount() const {
return m_commands.size(); return m_commands.size();
} }
RenX::GameCommand *RenX::Server::triggerCommand(const Jupiter::ReadableString &trigger, RenX::PlayerInfo &player, const Jupiter::ReadableString &parameters) { RenX::GameCommand *RenX::Server::triggerCommand(std::string_view trigger, RenX::PlayerInfo &player, std::string_view parameters) {
RenX::GameCommand::active_server = this; RenX::GameCommand::active_server = this;
for (const auto& command : m_commands) { for (const auto& command : m_commands) {
if (command->matches(trigger)) { if (command->matches(trigger)) {
if (player.access >= command->getAccessLevel()) { if (player.access >= command->getAccessLevel()) {
command->trigger(this, &player, parameters); command->trigger(this, &player, Jupiter::ReferenceString{parameters});
} }
else { else {
sendMessage(player, "Access Denied."_jrs); sendMessage(player, "Access Denied."_jrs);
@ -1065,7 +1064,7 @@ RenX::GameCommand *RenX::Server::triggerCommand(const Jupiter::ReadableString &t
// TODO: avoiding modifying behavior for now, but this probably doesn't need to be called on access denied // TODO: avoiding modifying behavior for now, but this probably doesn't need to be called on access denied
for (const auto& plugin : getCore()->getPlugins()) { for (const auto& plugin : getCore()->getPlugins()) {
plugin->RenX_OnCommandTriggered(*this, trigger, player, parameters, *command); plugin->RenX_OnCommandTriggered(*this, Jupiter::ReferenceString{trigger}, player, Jupiter::ReferenceString{parameters}, *command);
} }
return command.get(); return command.get();
@ -1084,7 +1083,7 @@ void RenX::Server::addCommand(RenX::GameCommand* in_command) {
if (m_commandAccessLevels != nullptr) { if (m_commandAccessLevels != nullptr) {
std::string_view accessLevel = m_commandAccessLevels->get(command->getTrigger()); std::string_view accessLevel = m_commandAccessLevels->get(command->getTrigger());
if (!accessLevel.empty()) { if (!accessLevel.empty()) {
access_level = Jupiter::ReferenceString{accessLevel}.asInt(); access_level = Jupiter::from_string<int>(accessLevel);
if (access_level < 0) { // Disabled command if (access_level < 0) { // Disabled command
return; return;
} }
@ -1138,15 +1137,15 @@ RenX::Server::uuid_func RenX::Server::getUUIDFunction() const {
return m_calc_uuid; return m_calc_uuid;
} }
void RenX::Server::setUUID(RenX::PlayerInfo &player, const Jupiter::ReadableString &uuid) { void RenX::Server::setUUID(RenX::PlayerInfo &player, std::string_view uuid) {
for (const auto& plugin : getCore()->getPlugins()) { for (const auto& plugin : getCore()->getPlugins()) {
plugin->RenX_OnPlayerUUIDChange(*this, player, uuid); plugin->RenX_OnPlayerUUIDChange(*this, player, Jupiter::ReferenceString{uuid});
} }
player.uuid = uuid; player.uuid = uuid;
} }
bool RenX::Server::setUUIDIfDifferent(RenX::PlayerInfo &player, const Jupiter::ReadableString &uuid) { bool RenX::Server::setUUIDIfDifferent(RenX::PlayerInfo &player, std::string_view uuid) {
if (player.uuid == uuid) { if (player.uuid == uuid) {
return false; return false;
} }
@ -1284,8 +1283,11 @@ void RenX::Server::sendLogChan(const Jupiter::ReadableString &msg) const {
void resolve_rdns(RenX::PlayerInfo *player) { void resolve_rdns(RenX::PlayerInfo *player) {
player->rdns_mutex.lock(); player->rdns_mutex.lock();
// TODO: don't do this
char *resolved = Jupiter::Socket::resolveHostname_alloc(static_cast<std::string>(player->ip).c_str(), 0); char *resolved = Jupiter::Socket::resolveHostname_alloc(static_cast<std::string>(player->ip).c_str(), 0);
player->rdns.capture(resolved, strlen(resolved)); player->rdns = resolved;
delete[] resolved;
player->rdns_mutex.unlock(); player->rdns_mutex.unlock();
} }
@ -1305,7 +1307,7 @@ void process_escape_sequences(std::string& out_string) {
} }
void RenX::Server::processLine(const Jupiter::ReadableString &line) { void RenX::Server::processLine(const Jupiter::ReadableString &line) {
if (line.isEmpty()) if (line.empty())
return; return;
auto& xPlugins = RenX::getCore()->getPlugins(); auto& xPlugins = RenX::getCore()->getPlugins();
@ -1432,8 +1434,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
Jupiter::ReferenceString idToken = player_tokens[1]; Jupiter::ReferenceString idToken = player_tokens[1];
result.name = player_tokens[2]; result.name = player_tokens[2];
result.team = RenX::getTeam(player_tokens[0]); result.team = RenX::getTeam(player_tokens[0]);
if (idToken.isNotEmpty() && idToken.get(0) == 'b') if (idToken.isNotEmpty() && idToken[0] == 'b') {
{
idToken.shiftRight(1); idToken.shiftRight(1);
result.isBot = true; result.isBot = true;
result.isPlayer = true; result.isPlayer = true;
@ -1446,7 +1447,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
result.isBot = false; result.isBot = false;
result.isPlayer = true; result.isPlayer = true;
} }
result.id = idToken.asInt(10); result.id = Jupiter::asInt(idToken, 10);
return result; return result;
}; };
@ -1471,7 +1472,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
auto getPlayerOrAdd = [&](const Jupiter::ReadableString &name, int id, RenX::TeamType team, bool isBot, uint64_t steamid, const Jupiter::ReadableString &ip, const Jupiter::ReadableString &hwid) auto getPlayerOrAdd = [&](const Jupiter::ReadableString &name, int id, RenX::TeamType team, bool isBot, uint64_t steamid, const Jupiter::ReadableString &ip, const Jupiter::ReadableString &hwid)
{ {
if (id == 0) { if (id == 0) {
if (name.isEmpty()) { if (name.empty()) {
// Bad parse; return null player // Bad parse; return null player
static RenX::PlayerInfo s_null_player; static RenX::PlayerInfo s_null_player;
return &s_null_player; return &s_null_player;
@ -1537,7 +1538,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
} }
recalcUUID = true; recalcUUID = true;
} }
if (player->hwid.isEmpty() && hwid.isNotEmpty()) if (player->hwid.empty() && hwid.isNotEmpty())
{ {
player->hwid = hwid; player->hwid = hwid;
recalcUUID = true; recalcUUID = true;
@ -1568,15 +1569,15 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
auto parseGetPlayerOrAdd = [&parsePlayerData, &getPlayerOrAdd, this](const Jupiter::ReadableString &token) auto parseGetPlayerOrAdd = [&parsePlayerData, &getPlayerOrAdd, this](const Jupiter::ReadableString &token)
{ {
auto parsed_token = parsePlayerData(token); auto parsed_token = parsePlayerData(token);
if (parsed_token.id == 0 && parsed_token.name.isEmpty()) { if (parsed_token.id == 0 && parsed_token.name.empty()) {
sendAdmChan(IRCCOLOR "04[Error]" IRCCOLOR" Failed to parse player token: %.*s", token.size(), token.ptr()); sendAdmChan(IRCCOLOR "04[Error]" IRCCOLOR" Failed to parse player token: %.*s", token.size(), token.ptr());
} }
return getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, 0U, Jupiter::ReferenceString::empty, Jupiter::ReferenceString::empty); return getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, 0U, ""_jrs, ""_jrs);
}; };
auto gotoToken = [&line, &tokens, this](size_t index) auto gotoToken = [&line, &tokens, this](size_t index)
{ {
if (index >= tokens.size()) if (index >= tokens.size())
return Jupiter::ReferenceString::empty; return ""_jrs;
const char delim = getVersion() >= 4 ? RenX::DelimC : RenX::DelimC3; const char delim = getVersion() >= 4 ? RenX::DelimC : RenX::DelimC3;
const char *itr = line.ptr(); const char *itr = line.ptr();
@ -1606,7 +1607,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
switch (header) switch (header)
{ {
case 'r': case 'r':
if (m_lastCommand.equalsi("clientlist"_jrs)) if (jessilib::equalsi(m_lastCommand, "clientlist"sv))
{ {
// ID | IP | Steam ID | Admin Status | Team | Name // ID | IP | Steam ID | Admin Status | Team | Name
if (tokens[0].isNotEmpty()) if (tokens[0].isNotEmpty())
@ -1622,23 +1623,23 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
{ {
isBot = true; isBot = true;
tokens[0].shiftRight(1); tokens[0].shiftRight(1);
id = tokens[0].asInt(); id = Jupiter::from_string<int>(tokens[0]);
tokens[0].shiftLeft(1); tokens[0].shiftLeft(1);
} }
else else
id = tokens[0].asInt(); id = Jupiter::from_string<int>(tokens[0]);
if (steamToken != "-----NO-STEAM-----") if (steamToken != "-----NO-STEAM-----")
steamid = steamToken.asUnsignedLongLong(); steamid = Jupiter::from_string<uint64_t>(steamToken);
team = RenX::getTeam(teamToken); team = RenX::getTeam(teamToken);
if (adminToken.equalsi("None"_jrs)) if (adminToken.equalsi("None"_jrs))
getPlayerOrAdd(getToken(5), id, team, isBot, steamid, getToken(1), Jupiter::ReferenceString::empty); getPlayerOrAdd(getToken(5), id, team, isBot, steamid, getToken(1), ""_jrs);
else else
getPlayerOrAdd(getToken(5), id, team, isBot, steamid, getToken(1), Jupiter::ReferenceString::empty)->adminType = adminToken; getPlayerOrAdd(getToken(5), id, team, isBot, steamid, getToken(1), ""_jrs)->adminType = adminToken;
} }
} }
else if (m_lastCommand.equalsi("clientvarlist"_jrs)) else if (jessilib::equalsi(m_lastCommand, "clientvarlist"sv))
{ {
if (m_commandListFormat.empty()) { if (m_commandListFormat.empty()) {
consume_tokens_as_command_list_format(); consume_tokens_as_command_list_format();
@ -1676,19 +1677,19 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
value = table_get("KILLS"_jrs); value = table_get("KILLS"_jrs);
if (value != nullptr) if (value != nullptr)
player->kills = value->asUnsignedInt(); player->kills = Jupiter::from_string<unsigned int>(*value);
value = table_get("DEATHS"_jrs); value = table_get("DEATHS"_jrs);
if (value != nullptr) if (value != nullptr)
player->deaths = value->asUnsignedInt(); player->deaths = Jupiter::from_string<unsigned int>(*value);
value = table_get("SCORE"_jrs); value = table_get("SCORE"_jrs);
if (value != nullptr) if (value != nullptr)
player->score = value->asDouble(); player->score = Jupiter::from_string<double>(*value);
value = table_get("CREDITS"_jrs); value = table_get("CREDITS"_jrs);
if (value != nullptr) if (value != nullptr)
player->credits = value->asDouble(); player->credits = Jupiter::from_string<double>(*value);
value = table_get("CHARACTER"_jrs); value = table_get("CHARACTER"_jrs);
if (value != nullptr) if (value != nullptr)
@ -1700,7 +1701,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
value = table_get("PING"_jrs); value = table_get("PING"_jrs);
if (value != nullptr) if (value != nullptr)
player->ping = value->asUnsignedInt(); player->ping = Jupiter::from_string<unsigned short>(*value);
value = table_get("ADMIN"_jrs); value = table_get("ADMIN"_jrs);
if (value != nullptr) if (value != nullptr)
@ -1715,9 +1716,9 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
if (value != nullptr) { if (value != nullptr) {
auto parsed_token = parsePlayerData(*value); auto parsed_token = parsePlayerData(*value);
parse(getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, false, parse(getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, false,
table_get_ref("STEAM"_jrs, Jupiter::ReferenceString::empty).asUnsignedLongLong(), Jupiter::from_string<unsigned long long>(table_get_ref("STEAM"_jrs, ""_jrs)),
table_get_ref("IP"_jrs, Jupiter::ReferenceString::empty), table_get_ref("IP"_jrs, ""_jrs),
table_get_ref("HWID"_jrs, Jupiter::ReferenceString::empty))); table_get_ref("HWID"_jrs, ""_jrs)));
} }
else else
{ {
@ -1726,21 +1727,21 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
if (value != nullptr) if (value != nullptr)
{ {
RenX::PlayerInfo *player = getPlayer(value->asInt()); RenX::PlayerInfo *player = getPlayer(Jupiter::from_string<int>(*value));
if (player != nullptr) if (player != nullptr)
{ {
if (player->name.empty()) if (player->name.empty())
{ {
player->name = table_get_ref("NAME"_jrs, Jupiter::ReferenceString::empty); player->name = table_get_ref("NAME"_jrs, ""_jrs);
process_escape_sequences(player->name); process_escape_sequences(player->name);
} }
if (player->ip.isEmpty()) if (player->ip.empty())
player->ip = table_get_ref("IP"_jrs, Jupiter::ReferenceString::empty); player->ip = table_get_ref("IP"_jrs, ""_jrs);
if (player->hwid.isEmpty()) if (player->hwid.empty())
player->hwid = table_get_ref("HWID"_jrs, Jupiter::ReferenceString::empty); player->hwid = table_get_ref("HWID"_jrs, ""_jrs);
if (player->steamid == 0) if (player->steamid == 0)
{ {
uint64_t steamid = table_get_ref("STEAM"_jrs, Jupiter::ReferenceString::empty).asUnsignedLongLong(); uint64_t steamid = Jupiter::from_string<uint64_t>(table_get_ref("STEAM"_jrs, ""_jrs));
if (steamid != 0) if (steamid != 0)
{ {
player->steamid = steamid; player->steamid = steamid;
@ -1750,7 +1751,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
value = table_get("TEAMNUM"_jrs); value = table_get("TEAMNUM"_jrs);
if (value != nullptr) if (value != nullptr)
player->team = RenX::getTeam(value->asInt()); player->team = RenX::getTeam(Jupiter::from_string<int>(*value));
else else
{ {
value = table_get("TEAM"_jrs); value = table_get("TEAM"_jrs);
@ -1768,13 +1769,13 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
RenX::PlayerInfo *player = getPlayerByName(*name); RenX::PlayerInfo *player = getPlayerByName(*name);
if (player != nullptr) if (player != nullptr)
{ {
if (player->ip.isEmpty()) if (player->ip.empty())
player->ip = table_get_ref("IP"_jrs, Jupiter::ReferenceString::empty); player->ip = table_get_ref("IP"_jrs, ""_jrs);
if (player->hwid.isEmpty()) if (player->hwid.empty())
player->hwid = table_get_ref("HWID"_jrs, Jupiter::ReferenceString::empty); player->hwid = table_get_ref("HWID"_jrs, ""_jrs);
if (player->steamid == 0) if (player->steamid == 0)
{ {
uint64_t steamid = table_get_ref("STEAM"_jrs, Jupiter::ReferenceString::empty).asUnsignedLongLong(); uint64_t steamid = Jupiter::from_string<uint64_t>(table_get_ref("STEAM"_jrs, ""_jrs));
if (steamid != 0) if (steamid != 0)
{ {
player->steamid = steamid; player->steamid = steamid;
@ -1784,7 +1785,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
value = table_get("TEAMNUM"_jrs); value = table_get("TEAMNUM"_jrs);
if (value != nullptr) if (value != nullptr)
player->team = RenX::getTeam(value->asInt()); player->team = RenX::getTeam(Jupiter::from_string<int>(*value));
else else
{ {
value = table_get("TEAM"_jrs); value = table_get("TEAM"_jrs);
@ -1799,7 +1800,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
} }
} }
} }
else if (m_lastCommand.equalsi("botlist")) { else if (jessilib::equalsi(m_lastCommand, "botlist"sv)) {
// Team,ID,Name // Team,ID,Name
if (m_commandListFormat.empty()) { if (m_commandListFormat.empty()) {
consume_tokens_as_command_list_format(); consume_tokens_as_command_list_format();
@ -1808,7 +1809,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
parseGetPlayerOrAdd(tokens[0]); parseGetPlayerOrAdd(tokens[0]);
} }
} }
else if (m_lastCommand.equalsi("botvarlist")) { else if (jessilib::equalsi(m_lastCommand, "botvarlist"sv)) {
if (m_commandListFormat.empty()) { if (m_commandListFormat.empty()) {
consume_tokens_as_command_list_format(); consume_tokens_as_command_list_format();
} }
@ -1845,19 +1846,19 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
value = table_get("KILLS"_jrs); value = table_get("KILLS"_jrs);
if (value != nullptr) if (value != nullptr)
player->kills = value->asUnsignedInt(); player->kills = Jupiter::from_string<unsigned int>(*value);
value = table_get("DEATHS"_jrs); value = table_get("DEATHS"_jrs);
if (value != nullptr) if (value != nullptr)
player->deaths = value->asUnsignedInt(); player->deaths = Jupiter::from_string<unsigned int>(*value);
value = table_get("SCORE"_jrs); value = table_get("SCORE"_jrs);
if (value != nullptr) if (value != nullptr)
player->score = value->asDouble(); player->score = Jupiter::from_string<double>(*value);
value = table_get("CREDITS"_jrs); value = table_get("CREDITS"_jrs);
if (value != nullptr) if (value != nullptr)
player->credits = value->asDouble(); player->credits = Jupiter::from_string<double>(*value);
value = table_get("CHARACTER"_jrs); value = table_get("CHARACTER"_jrs);
if (value != nullptr) if (value != nullptr)
@ -1871,7 +1872,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
if (value != nullptr) { if (value != nullptr) {
auto parsed_token = parsePlayerData(*value); auto parsed_token = parsePlayerData(*value);
parse(getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, true, 0ULL, parse(getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, true, 0ULL,
Jupiter::ReferenceString::empty, Jupiter::ReferenceString::empty)); ""_jrs, ""_jrs));
} }
else else
{ {
@ -1880,18 +1881,18 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
if (value != nullptr) if (value != nullptr)
{ {
RenX::PlayerInfo *player = getPlayer(value->asInt()); RenX::PlayerInfo *player = getPlayer(Jupiter::from_string<int>(*value));
if (player != nullptr) if (player != nullptr)
{ {
if (player->name.empty()) if (player->name.empty())
{ {
player->name = table_get_ref("NAME"_jrs, Jupiter::ReferenceString::empty); player->name = table_get_ref("NAME"_jrs, ""_jrs);
process_escape_sequences(player->name); process_escape_sequences(player->name);
} }
value = table_get("TEAMNUM"_jrs); value = table_get("TEAMNUM"_jrs);
if (value != nullptr) if (value != nullptr)
player->team = RenX::getTeam(value->asInt()); player->team = RenX::getTeam(Jupiter::from_string<int>(*value));
else else
{ {
value = table_get("TEAM"_jrs); value = table_get("TEAM"_jrs);
@ -1909,7 +1910,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
{ {
value = table_get("TEAMNUM"_jrs); value = table_get("TEAMNUM"_jrs);
if (value != nullptr) if (value != nullptr)
player->team = RenX::getTeam(value->asInt()); player->team = RenX::getTeam(Jupiter::from_string<int>(*value));
else else
{ {
value = table_get("TEAM"_jrs); value = table_get("TEAM"_jrs);
@ -1924,13 +1925,14 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
} }
} }
} }
else if (m_lastCommand.equalsi("binfo") || m_lastCommand.equalsi("buildinginfo") || m_lastCommand.equalsi("blist") || m_lastCommand.equalsi("buildinglist")) else if (jessilib::equalsi(m_lastCommand, "binfo"sv)
{ || jessilib::equalsi(m_lastCommand, "buildinginfo"sv)
|| jessilib::equalsi(m_lastCommand, "blist"sv)
|| jessilib::equalsi(m_lastCommand, "buildinglist"sv)) {
if (m_commandListFormat.empty()) { if (m_commandListFormat.empty()) {
consume_tokens_as_command_list_format(); consume_tokens_as_command_list_format();
} }
else else {
{
/* /*
lRCONCommand;DevBotexecuted:binfo lRCONCommand;DevBotexecuted:binfo
rBuildingHealthMaxHealthArmor MaxArmor TeamCapturable Destroyed rBuildingHealthMaxHealthArmor MaxArmor TeamCapturable Destroyed
@ -1963,11 +1965,11 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
value = table_get("Health"_jrs); value = table_get("Health"_jrs);
if (value != nullptr) if (value != nullptr)
building->health = value->asInt(10); building->health = Jupiter::from_string<int>(*value);
value = table_get("MaxHealth"_jrs); value = table_get("MaxHealth"_jrs);
if (value != nullptr) if (value != nullptr)
building->max_health = value->asInt(10); building->max_health = Jupiter::from_string<int>(*value);
value = table_get("Team"_jrs); value = table_get("Team"_jrs);
if (value != nullptr) if (value != nullptr)
@ -1975,78 +1977,77 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
value = table_get("Capturable"_jrs); value = table_get("Capturable"_jrs);
if (value != nullptr) if (value != nullptr)
building->capturable = value->asBool(); building->capturable = Jupiter::from_string<bool>(*value);
value = table_get("Destroyed"_jrs); value = table_get("Destroyed"_jrs);
if (value != nullptr) if (value != nullptr)
building->destroyed = value->asBool(); building->destroyed = Jupiter::from_string<bool>(*value);
value = table_get("Armor"_jrs); value = table_get("Armor"_jrs);
if (value != nullptr) if (value != nullptr)
building->armor = value->asInt(10); building->armor = Jupiter::from_string<int>(*value);
value = table_get("MaxArmor"_jrs); value = table_get("MaxArmor"_jrs);
if (value != nullptr) if (value != nullptr)
building->max_armor = value->asInt(10); building->max_armor = Jupiter::from_string<int>(*value);
} }
} }
} }
else if (m_lastCommand.equalsi("ping")) else if (jessilib::equalsi(m_lastCommand, "ping"sv))
{ {
if (getToken(1) == "srv_init_done"sv) if (getToken(1) == "srv_init_done"sv)
finished_connecting(); finished_connecting();
else else
m_awaitingPong = false; m_awaitingPong = false;
} }
else if (m_lastCommand.equalsi("map")) else if (jessilib::equalsi(m_lastCommand, "map"sv))
{ {
// Map | Guid // Map | Guid
m_map.name = getToken(0); m_map.name = getToken(0);
const Jupiter::ReferenceString guid_token = getToken(1); const Jupiter::ReferenceString guid_token = getToken(1);
if (guid_token.size() == 32U) if (guid_token.size() == 32U) {
{ m_map.guid[0] = Jupiter::asUnsignedLongLong(guid_token.substring(size_t{ 0 }, 16U), 16);
m_map.guid[0] = guid_token.substring(size_t{ 0 }, 16U).asUnsignedLongLong(16); m_map.guid[1] = Jupiter::asUnsignedLongLong(guid_token.substring(16U), 16);
m_map.guid[1] = guid_token.substring(16U).asUnsignedLongLong(16);
} }
} }
else if (m_lastCommand.equalsi("serverinfo")) else if (jessilib::equalsi(m_lastCommand, "serverinfo"sv))
{ {
if (m_lastCommandParams.isEmpty()) if (m_lastCommandParams.empty())
{ {
// "Port"�| Port |�"Name" |�Name |�"Level"�| Level | "Players" | Players�| "Bots" | Bots | "LevelGUID" | Level GUID // "Port"�| Port |�"Name" |�Name |�"Level"�| Level | "Players" | Players�| "Bots" | Bots | "LevelGUID" | Level GUID
m_port = static_cast<unsigned short>(getToken(1).asUnsignedInt(10)); m_port = Jupiter::from_string<unsigned short>(getToken(1));
m_serverName = getToken(3); m_serverName = getToken(3);
m_map.name = getToken(5); m_map.name = getToken(5);
const Jupiter::ReferenceString guid_token = getToken(11); const Jupiter::ReferenceString guid_token = getToken(11);
if (guid_token.size() == 32U) if (guid_token.size() == 32U)
{ {
m_map.guid[0] = guid_token.substring(size_t{ 0 }, 16U).asUnsignedLongLong(16); m_map.guid[0] = Jupiter::asUnsignedLongLong(guid_token.substring(size_t{ 0 }, 16U), 16);
m_map.guid[1] = guid_token.substring(16U).asUnsignedLongLong(16); m_map.guid[1] = Jupiter::asUnsignedLongLong(guid_token.substring(16U), 16);
} }
} }
} }
else if (m_lastCommand.equalsi("gameinfo"_jrs)) else if (jessilib::equalsi(m_lastCommand, "gameinfo"sv))
{ {
if (m_lastCommandParams.isEmpty()) if (m_lastCommandParams.empty())
{ {
// "PlayerLimit" | PlayerLimit | "VehicleLimit" | VehicleLimit | "MineLimit" | MineLimit | "TimeLimit" | TimeLimit | "bPassworded" | bPassworded | "bSteamRequired" | bSteamRequired | "bPrivateMessageTeamOnly" | bPrivateMessageTeamOnly | "bAllowPrivateMessaging" | bAllowPrivateMessaging | "TeamMode" | TeamMode | "bSpawnCrates" | bSpawnCrates | "CrateRespawnAfterPickup" | CrateRespawnAfterPickup | bIsCompetitive | "bIsCompetitive" // "PlayerLimit" | PlayerLimit | "VehicleLimit" | VehicleLimit | "MineLimit" | MineLimit | "TimeLimit" | TimeLimit | "bPassworded" | bPassworded | "bSteamRequired" | bSteamRequired | "bPrivateMessageTeamOnly" | bPrivateMessageTeamOnly | "bAllowPrivateMessaging" | bAllowPrivateMessaging | "TeamMode" | TeamMode | "bSpawnCrates" | bSpawnCrates | "CrateRespawnAfterPickup" | CrateRespawnAfterPickup | bIsCompetitive | "bIsCompetitive"
m_playerLimit = getToken(1).asInt(); m_playerLimit = Jupiter::from_string<int>(getToken(1));
m_vehicleLimit = getToken(3).asInt(); m_vehicleLimit = Jupiter::from_string<int>(getToken(3));
m_mineLimit = getToken(5).asInt(); m_mineLimit = Jupiter::from_string<int>(getToken(5));
m_timeLimit = getToken(7).asInt(); m_timeLimit = Jupiter::from_string<int>(getToken(7));
m_passworded = getToken(9).asBool(); m_passworded = Jupiter::from_string<bool>(getToken(9));
m_steamRequired = getToken(11).asBool(); m_steamRequired = Jupiter::from_string<bool>(getToken(11));
m_privateMessageTeamOnly = getToken(13).asBool(); m_privateMessageTeamOnly = Jupiter::from_string<bool>(getToken(13));
m_allowPrivateMessaging = getToken(15).asBool(); m_allowPrivateMessaging = Jupiter::from_string<bool>(getToken(15));
m_team_mode = m_rconVersion >= 4 ? getToken(17).asInt() : true; m_team_mode = m_rconVersion >= 4 ? Jupiter::from_string<int>(getToken(17)) : true;
m_spawnCrates = getToken(19).asBool(); m_spawnCrates = Jupiter::from_string<bool>(getToken(19));
m_crateRespawnAfterPickup = getToken(21).asDouble(); m_crateRespawnAfterPickup = Jupiter::from_string<double>(getToken(21));
if (m_rconVersion >= 4) if (m_rconVersion >= 4)
{ {
m_competitive = getToken(23).asBool(); m_competitive = Jupiter::from_string<bool>(getToken(23));
const Jupiter::ReadableString &match_state_token = getToken(25); const Jupiter::ReadableString &match_state_token = getToken(25);
if (match_state_token.equalsi("PendingMatch"_jrs)) if (match_state_token.equalsi("PendingMatch"_jrs))
@ -2060,12 +2061,12 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
else // Unknown state -- assume it's in progress else // Unknown state -- assume it's in progress
m_match_state = 1; m_match_state = 1;
m_botsEnabled = getToken(27).asBool(); m_botsEnabled = Jupiter::from_string<bool>(getToken(27));
m_game_type = getToken(29).asInt(); m_game_type = Jupiter::from_string<int>(getToken(29));
} }
} }
} }
else if (m_lastCommand.equalsi("mutatorlist"_jrs)) { else if (jessilib::equalsi(m_lastCommand, "mutatorlist"sv)) {
// "The following mutators are loaded:" [ | Mutator [ | Mutator [ ... ] ] ] // "The following mutators are loaded:" [ | Mutator [ | Mutator [ ... ] ] ]
if (tokens.size() == 1) { if (tokens.size() == 1) {
m_pure = true; m_pure = true;
@ -2080,7 +2081,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
RenX::Server::mutators.emplace_back(tokens[index]); RenX::Server::mutators.emplace_back(tokens[index]);
} }
} }
else if (m_lastCommand.equalsi("rotation"_jrs)) { else if (jessilib::equalsi(m_lastCommand, "rotation"sv)) {
// Map | Guid // Map | Guid
const Jupiter::ReadableString &in_map = getToken(0); const Jupiter::ReadableString &in_map = getToken(0);
if (hasMapInRotation(in_map) == false) { if (hasMapInRotation(in_map) == false) {
@ -2088,12 +2089,12 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
const Jupiter::ReferenceString guid_token = getToken(1); const Jupiter::ReferenceString guid_token = getToken(1);
if (guid_token.size() == 32U) { if (guid_token.size() == 32U) {
this->maps.back().guid[0] = guid_token.substring(size_t{ 0 }, 16U).asUnsignedLongLong(16); this->maps.back().guid[0] = Jupiter::asUnsignedLongLong(guid_token.substring(size_t{ 0 }, 16U), 16);
this->maps.back().guid[1] = guid_token.substring(16U).asUnsignedLongLong(16); this->maps.back().guid[1] = Jupiter::asUnsignedLongLong(guid_token.substring(16U), 16);
} }
} }
} }
else if (m_lastCommand.equalsi("changename")) { else if (jessilib::equalsi(m_lastCommand, "changename"sv)) {
RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(0)); RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(0));
Jupiter::StringS newName = getToken(2); Jupiter::StringS newName = getToken(2);
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
@ -2111,7 +2112,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
// Object (Beacon/Mine) | Player | "on" | Surface // Object (Beacon/Mine) | Player | "on" | Surface
RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(4)); RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(4));
Jupiter::ReferenceString objectType = getToken(2); Jupiter::ReferenceString objectType = getToken(2);
if (objectType.match("*Beacon")) if (objectType.ends_with("Beacon"))
++player->beaconPlacements; ++player->beaconPlacements;
else if (objectType == "Rx_Weapon_DeployedProxyC4"sv) else if (objectType == "Rx_Weapon_DeployedProxyC4"sv)
++player->proxy_placements; ++player->proxy_placements;
@ -2125,7 +2126,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
// Object (Beacon/Mine) | "by" | Player | "owned by" | Owner // Object (Beacon/Mine) | "by" | Player | "owned by" | Owner
RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(4)); RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(4));
Jupiter::ReferenceString objectType = getToken(2); Jupiter::ReferenceString objectType = getToken(2);
if (objectType.match("*Beacon")) if (objectType.ends_with("Beacon"))
++player->beaconDisarms; ++player->beaconDisarms;
else if (objectType == "Rx_Weapon_DeployedProxyC4"sv) else if (objectType == "Rx_Weapon_DeployedProxyC4"sv)
++player->proxy_disarms; ++player->proxy_disarms;
@ -2332,7 +2333,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
} }
else if (type == "money"sv) else if (type == "money"sv)
{ {
int amount = getToken(3).asInt(); int amount = Jupiter::from_string<int>(getToken(3));
RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(5)); RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(5));
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
plugin->RenX_OnMoneyCrate(*this, *player, amount); plugin->RenX_OnMoneyCrate(*this, *player, amount);
@ -2416,7 +2417,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
// "player" | Player | "by" | Killer Player | "with" | Damage Type // "player" | Player | "by" | Killer Player | "with" | Damage Type
// "player" | Player | "died by" | Damage Type // "player" | Player | "died by" | Damage Type
// "player" | Player | "suicide by" | Damage Type // "player" | Player | "suicide by" | Damage Type
// NOTE: Filter these out when Player.isEmpty(). // NOTE: Filter these out when Player.empty().
Jupiter::ReferenceString playerToken = getToken(3); Jupiter::ReferenceString playerToken = getToken(3);
if (playerToken.isNotEmpty()) if (playerToken.isNotEmpty())
{ {
@ -2438,7 +2439,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
else else
{ {
player->deaths++; player->deaths++;
RenX::PlayerInfo *killer = getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, 0, Jupiter::ReferenceString::empty, Jupiter::ReferenceString::empty); RenX::PlayerInfo *killer = getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, 0, ""_jrs, ""_jrs);
killer->kills++; killer->kills++;
if (damageType == "Rx_DmgType_Headshot"sv) { if (damageType == "Rx_DmgType_Headshot"sv) {
killer->headshots++; killer->headshots++;
@ -2465,7 +2466,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
plugin->RenX_OnSuicide(*this, *player, damageType); plugin->RenX_OnSuicide(*this, *player, damageType);
} }
} }
player->character = Jupiter::ReferenceString::empty; player->character = ""_jrs;
} }
onAction(); onAction();
} }
@ -2525,7 +2526,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
} }
} }
else { else {
RenX::PlayerInfo *player = getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, 0, Jupiter::ReferenceString::empty, Jupiter::ReferenceString::empty); RenX::PlayerInfo *player = getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, 0, ""_jrs, ""_jrs);
switch (type) switch (type)
{ {
case RenX::ObjectType::Vehicle: case RenX::ObjectType::Vehicle:
@ -2569,7 +2570,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
// Amount | "to" | Recipient | "by" | Donor // Amount | "to" | Recipient | "by" | Donor
if (getToken(5) == "by"sv) if (getToken(5) == "by"sv)
{ {
double amount = getToken(2).asDouble(); double amount = Jupiter::from_string<double>(getToken(2));
RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(4)); RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(4));
RenX::PlayerInfo *donor = parseGetPlayerOrAdd(getToken(6)); RenX::PlayerInfo *donor = parseGetPlayerOrAdd(getToken(6));
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
@ -2606,8 +2607,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
winType = WinType::Surrender; winType = WinType::Surrender;
TeamType team = RenX::getTeam(getToken(3)); TeamType team = RenX::getTeam(getToken(3));
int gScore = Jupiter::ReferenceString(jessilib::split_once_view(getToken(5), '=').second).asInt(); int gScore = Jupiter::from_string<int>(jessilib::split_once_view(getToken(5), '=').second);
int nScore = Jupiter::ReferenceString(jessilib::split_once_view(getToken(6), '=').second).asInt(); int nScore = Jupiter::from_string<int>(jessilib::split_once_view(getToken(6), '=').second);
onPreGameOver(winType, team, gScore, nScore); onPreGameOver(winType, team, gScore, nScore);
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
@ -2615,8 +2616,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
} }
} }
else if (winTieToken == "tie"sv) { else if (winTieToken == "tie"sv) {
int gScore = Jupiter::ReferenceString(jessilib::split_once_view(getToken(4), '=').second).asInt(); int gScore = Jupiter::from_string<int>(jessilib::split_once_view(getToken(4), '=').second);
int nScore = Jupiter::ReferenceString(jessilib::split_once_view(getToken(5), '=').second).asInt(); int nScore = Jupiter::from_string<int>(jessilib::split_once_view(getToken(5), '=').second);
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
plugin->RenX_OnGameOver(*this, RenX::WinType::Tie, RenX::TeamType::None, gScore, nScore); plugin->RenX_OnGameOver(*this, RenX::WinType::Tie, RenX::TeamType::None, gScore, nScore);
} }
@ -2772,7 +2773,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
{ {
// New format // New format
if (getToken(7) == "steamid"sv) if (getToken(7) == "steamid"sv)
steamid = getToken(8).asUnsignedLongLong(); steamid = Jupiter::from_string<uint64_t>(getToken(8));
player = getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, steamid, getToken(4), getToken(6)); player = getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, steamid, getToken(4), getToken(6));
} }
@ -2780,9 +2781,9 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
{ {
// Old format // Old format
if (getToken(5) == "steamid"sv) if (getToken(5) == "steamid"sv)
steamid = getToken(6).asUnsignedLongLong(); steamid = Jupiter::from_string<uint64_t>(getToken(6));
player = getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, steamid, getToken(4), Jupiter::ReferenceString::empty); player = getPlayerOrAdd(parsed_token.name, parsed_token.id, parsed_token.team, parsed_token.isBot, steamid, getToken(4), ""_jrs);
} }
if (steamid != 0ULL && default_ladder_database != nullptr && (player->ban_flags & RenX::BanDatabase::Entry::FLAG_TYPE_LADDER) == 0) if (steamid != 0ULL && default_ladder_database != nullptr && (player->ban_flags & RenX::BanDatabase::Entry::FLAG_TYPE_LADDER) == 0)
@ -2814,7 +2815,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
// Player | "joined" | Team | "score" | Score | "last round score" | Score | "time" | Timestamp // Player | "joined" | Team | "score" | Score | "last round score" | Score | "time" | Timestamp
// Player | "joined" | Team | "left" | Old Team | "score" | Score | "last round score" | Score | "time" | Timestamp // Player | "joined" | Team | "left" | Old Team | "score" | Score | "last round score" | Score | "time" | Timestamp
RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(2)); RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(2));
player->character = Jupiter::ReferenceString::empty; player->character = ""_jrs;
if (getToken(5) == "left"sv) if (getToken(5) == "left"sv)
{ {
RenX::TeamType oldTeam = RenX::getTeam(getToken(6)); RenX::TeamType oldTeam = RenX::getTeam(getToken(6));
@ -2842,7 +2843,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
plugin->RenX_OnHWID(*this, *player); plugin->RenX_OnHWID(*this, *player);
} }
if (player->rdns.isNotEmpty()) { if (!player->rdns.empty()) {
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
plugin->RenX_OnPlayerIdentify(*this, *player); plugin->RenX_OnPlayerIdentify(*this, *player);
} }
@ -2889,11 +2890,11 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
else if (subHeader == "ChangeID;"sv) else if (subHeader == "ChangeID;"sv)
{ {
// "to" | New ID | "from" | Old ID // "to" | New ID | "from" | Old ID
int oldID = getToken(5).asInt(); int oldID = Jupiter::from_string<int>(getToken(5));
RenX::PlayerInfo *player = getPlayer(oldID); RenX::PlayerInfo *player = getPlayer(oldID);
if (player != nullptr) if (player != nullptr)
{ {
player->id = getToken(3).asInt(); player->id = Jupiter::from_string<int>(getToken(3));
if (player->isBot == false) if (player->isBot == false)
banCheck(*player); banCheck(*player);
@ -2916,7 +2917,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
{ {
RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(2)); RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(2));
if (player != nullptr) if (player != nullptr)
player->global_rank = getToken(3).asUnsignedInt(); player->global_rank = Jupiter::from_string<unsigned int>(getToken(3));
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
plugin->RenX_OnRank(*this, *player); plugin->RenX_OnRank(*this, *player);
@ -2928,7 +2929,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
// Player | true/false // Player | true/false
RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(2)); RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(2));
if (player != nullptr) if (player != nullptr)
player->is_dev = getToken(3).asBool(); player->is_dev = Jupiter::from_string<bool>(getToken(3));
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
plugin->RenX_OnDev(*this, *player); plugin->RenX_OnDev(*this, *player);
@ -2948,7 +2949,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(2)); RenX::PlayerInfo *player = parseGetPlayerOrAdd(getToken(2));
Jupiter::ReferenceString message = gotoToken(3); Jupiter::ReferenceString message = gotoToken(3);
RenX::GameCommand *command = triggerCommand(Jupiter::ReferenceString::getWord(message, 0, WHITESPACE), *player, Jupiter::ReferenceString::gotoWord(message, 1, WHITESPACE)); auto command_split = jessilib::word_split_once_view(std::string_view{message}, WHITESPACE_SV);
RenX::GameCommand *command = triggerCommand(command_split.first, *player, command_split.second);
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
plugin->RenX_OnPlayerCommand(*this, *player, message, command); plugin->RenX_OnPlayerCommand(*this, *player, message, command);
@ -2970,17 +2972,17 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
std::string_view user = getToken(2); std::string_view user = getToken(2);
if (getToken(3) == "executed:"sv) if (getToken(3) == "executed:"sv)
{ {
Jupiter::ReferenceString command = gotoToken(4); Jupiter::ReferenceString command_line = gotoToken(4);
Jupiter::ReferenceString cmd = command.getWord(0, " "); auto split_command_line = jessilib::word_split_once_view(command_line, ' ');
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
plugin->RenX_OnExecute(*this, Jupiter::ReferenceString{user}, command); plugin->RenX_OnExecute(*this, Jupiter::ReferenceString{user}, command_line);
} }
if (m_rconUser == user) if (m_rconUser == user)
{ {
m_lastCommand = cmd; m_lastCommand = split_command_line.first;
m_lastCommandParams = command.gotoWord(1, " "); m_lastCommandParams = split_command_line.second;
} }
} }
} }
@ -3217,8 +3219,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
else else
victim = TeamType::Other; victim = TeamType::Other;
int amount = getToken(9).asInt(10); int amount = Jupiter::from_string<int>(getToken(9));
int skill = getToken(11).asInt(10); int skill = Jupiter::from_string<int>(getToken(11));
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
plugin->RenX_OnVoteAddBots(*this, team, *player, victim, amount, skill); plugin->RenX_OnVoteAddBots(*this, team, *player, victim, amount, skill);
@ -3257,7 +3259,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
else else
victim = TeamType::Other; victim = TeamType::Other;
int amount = getToken(9).asInt(10); int amount = Jupiter::from_string<int>(getToken(9));
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
plugin->RenX_OnVoteRemoveBots(*this, team, *player, victim, amount); plugin->RenX_OnVoteRemoveBots(*this, team, *player, victim, amount);
@ -3322,7 +3324,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
if (votes_token.size() > 4) if (votes_token.size() > 4)
{ {
votes_token.shiftRight(4); votes_token.shiftRight(4);
yesVotes = votes_token.asInt(); yesVotes = Jupiter::from_string<int>(votes_token);
} }
int noVotes = 0; int noVotes = 0;
@ -3330,7 +3332,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
if (votes_token.size() > 3) if (votes_token.size() > 3)
{ {
votes_token.shiftRight(3); votes_token.shiftRight(3);
noVotes = votes_token.asInt(); noVotes = Jupiter::from_string<int>(votes_token);
} }
for (const auto& plugin : xPlugins) { for (const auto& plugin : xPlugins) {
@ -3484,8 +3486,8 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
plugin->RenX_OnCommand(*this, raw); plugin->RenX_OnCommand(*this, raw);
} }
m_commandListFormat.clear(); m_commandListFormat.clear();
m_lastCommand = Jupiter::ReferenceString::empty; m_lastCommand = ""_jrs;
m_lastCommandParams = Jupiter::ReferenceString::empty; m_lastCommandParams = ""_jrs;
} }
break; break;
@ -3501,7 +3503,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
case 'v': case 'v':
{ {
Jupiter::ReferenceString raw = Jupiter::ReferenceString::substring(line, 1); Jupiter::ReferenceString raw = Jupiter::ReferenceString::substring(line, 1);
m_rconVersion = raw.asInt(10); m_rconVersion = Jupiter::asInt(raw, 10);
if (m_rconVersion >= 3) if (m_rconVersion >= 3)
{ {
@ -3509,10 +3511,10 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line) {
m_gameVersion = raw.substring(3); m_gameVersion = raw.substring(3);
else // New format: 004 | Game Version Number | Game Version else // New format: 004 | Game Version Number | Game Version
{ {
m_gameVersionNumber = getToken(1).asInt(10); m_gameVersionNumber = Jupiter::asInt(getToken(1), 10);
m_gameVersion = getToken(2); m_gameVersion = getToken(2);
if (m_gameVersion.isEmpty()) if (m_gameVersion.empty())
{ {
sendLogChan(STRING_LITERAL_AS_REFERENCE(IRCCOLOR "04[Error]" IRCCOLOR " Disconnected from Renegade-X server (Protocol Error).")); sendLogChan(STRING_LITERAL_AS_REFERENCE(IRCCOLOR "04[Error]" IRCCOLOR " Disconnected from Renegade-X server (Protocol Error)."));
disconnect(RenX::DisconnectReason::ProtocolError); disconnect(RenX::DisconnectReason::ProtocolError);

32
src/Plugins/RenX/RenX.Core/RenX_Server.h

@ -266,7 +266,7 @@ namespace RenX
* @param message Message to send in-game. * @param message Message to send in-game.
* @return The number of bytes sent on success, less than or equal to zero otherwise. * @return The number of bytes sent on success, less than or equal to zero otherwise.
*/ */
int sendAdminMessage(const RenX::PlayerInfo &player, const Jupiter::ReadableString &message); int sendAdminMessage(const RenX::PlayerInfo &player, std::string_view message);
/** /**
* @brief Sends an in-game warning message to a player in the server. * @brief Sends an in-game warning message to a player in the server.
@ -275,7 +275,7 @@ namespace RenX
* @param message Message to send in-game. * @param message Message to send in-game.
* @return The number of bytes sent on success, less than or equal to zero otherwise. * @return The number of bytes sent on success, less than or equal to zero otherwise.
*/ */
int sendWarnMessage(const RenX::PlayerInfo &player, const Jupiter::ReadableString &message); int sendWarnMessage(const RenX::PlayerInfo &player, std::string_view message);
/** /**
* @brief Sends data to the server. * @brief Sends data to the server.
@ -314,14 +314,14 @@ namespace RenX
* *
* @return RCON command last executed. * @return RCON command last executed.
*/ */
const Jupiter::ReadableString &getCurrentRCONCommand() const; std::string_view getCurrentRCONCommand() const;
/** /**
* @brief Fetches the parameters of the RCON command currently being processed. * @brief Fetches the parameters of the RCON command currently being processed.
* *
* @return Parameters of last RCON command last executed. * @return Parameters of last RCON command last executed.
*/ */
const Jupiter::ReadableString &getCurrentRCONCommandParameters() const; std::string_view getCurrentRCONCommandParameters() const;
/** /**
* @brief Calculates the time since match start. * @brief Calculates the time since match start.
@ -369,7 +369,7 @@ namespace RenX
* @param name Name of the player. * @param name Name of the player.
* @return A player's data on success, nullptr otherwise. * @return A player's data on success, nullptr otherwise.
*/ */
RenX::PlayerInfo *getPlayerByName(const Jupiter::ReadableString &name) const; RenX::PlayerInfo *getPlayerByName(std::string_view name) const;
/** /**
* @brief Fetches a player's data, based on part of their name. * @brief Fetches a player's data, based on part of their name.
@ -377,7 +377,7 @@ namespace RenX
* @param name Name of the player. * @param name Name of the player.
* @return A player's data on success, nullptr otherwise. * @return A player's data on success, nullptr otherwise.
*/ */
RenX::PlayerInfo *getPlayerByPartName(const Jupiter::ReadableString &partName) const; RenX::PlayerInfo *getPlayerByPartName(std::string_view partName) const;
/** /**
* @brief Fetches a player's data, based on part of their name. * @brief Fetches a player's data, based on part of their name.
@ -409,28 +409,28 @@ namespace RenX
* *
* @param id Player ID of the player to kick. * @param id Player ID of the player to kick.
*/ */
void kickPlayer(int id, const Jupiter::ReadableString &reason); void kickPlayer(int id, std::string_view reason);
/** /**
* @brief Kicks a player from the server. * @brief Kicks a player from the server.
* *
* @param player Data of the player to kick. * @param player Data of the player to kick.
*/ */
void kickPlayer(const RenX::PlayerInfo &player, const Jupiter::ReadableString &reason); void kickPlayer(const RenX::PlayerInfo &player, std::string_view reason);
/** /**
* @brief Kicks a player from the server. * @brief Kicks a player from the server.
* *
* @param id Player ID of the player to kick. * @param id Player ID of the player to kick.
*/ */
void forceKickPlayer(int id, const Jupiter::ReadableString &reason); void forceKickPlayer(int id, std::string_view reason);
/** /**
* @brief Kicks a player from the server. * @brief Kicks a player from the server.
* *
* @param player Data of the player to kick. * @param player Data of the player to kick.
*/ */
void forceKickPlayer(const RenX::PlayerInfo &player, const Jupiter::ReadableString &reason); void forceKickPlayer(const RenX::PlayerInfo &player, std::string_view reason);
/** /**
* @brief Checks if any players are in the ban list, and kicks any players listed. * @brief Checks if any players are in the ban list, and kicks any players listed.
@ -880,7 +880,7 @@ namespace RenX
* @param parameters Parameters to pass to the command * @param parameters Parameters to pass to the command
* @return Command executed if a match is found, nullptr otherwise. * @return Command executed if a match is found, nullptr otherwise.
*/ */
RenX::GameCommand *triggerCommand(const Jupiter::ReadableString &trigger, RenX::PlayerInfo &player, const Jupiter::ReadableString &parameters); RenX::GameCommand *triggerCommand(std::string_view trigger, RenX::PlayerInfo &player, std::string_view parameters);
/** /**
* @brief Adds a command to the server's game command list. * @brief Adds a command to the server's game command list.
@ -935,7 +935,7 @@ namespace RenX
* @param player Player with UUID to change * @param player Player with UUID to change
* @param uuid Player's new UUID * @param uuid Player's new UUID
*/ */
void setUUID(RenX::PlayerInfo &player, const Jupiter::ReadableString &uuid); void setUUID(RenX::PlayerInfo &player, std::string_view uuid);
/** /**
* @brief Changes a player's UUID only if it is different than their current UUID * @brief Changes a player's UUID only if it is different than their current UUID
@ -944,7 +944,7 @@ namespace RenX
* @param uuid Player's new UUID * @param uuid Player's new UUID
* @return True if the UUIDs did not match, false otherwise. * @return True if the UUIDs did not match, false otherwise.
*/ */
bool setUUIDIfDifferent(RenX::PlayerInfo &player, const Jupiter::ReadableString &uuid); bool setUUIDIfDifferent(RenX::PlayerInfo &player, std::string_view uuid);
/** /**
* @brief Checks if reverse DNS resolution is occuring for players. * @brief Checks if reverse DNS resolution is occuring for players.
@ -1112,10 +1112,10 @@ namespace RenX
std::chrono::steady_clock::time_point m_gameover_time; std::chrono::steady_clock::time_point m_gameover_time;
std::string m_lastLine; std::string m_lastLine;
Jupiter::StringS m_rconUser; Jupiter::StringS m_rconUser;
Jupiter::StringS m_gameVersion; std::string m_gameVersion;
Jupiter::StringS m_serverName; Jupiter::StringS m_serverName;
Jupiter::StringS m_lastCommand; std::string m_lastCommand;
Jupiter::StringS m_lastCommandParams; std::string m_lastCommandParams;
RenX::Map m_map; RenX::Map m_map;
Jupiter::TCPSocket m_sock; Jupiter::TCPSocket m_sock;
std::vector<std::string> m_commandListFormat; std::vector<std::string> m_commandListFormat;

2
src/Plugins/RenX/RenX.ExcessiveHeadshots/RenX_ExcessiveHeadshots.cpp

@ -60,7 +60,7 @@ void RenX_ExcessiveHeadshotsPlugin::RenX_OnKill(RenX::Server &server, const RenX
server.banPlayer(player, "Jupiter Bot"_jrs, "Aimbot detected"_jrs); server.banPlayer(player, "Jupiter Bot"_jrs, "Aimbot detected"_jrs);
server.sendPubChan(IRCCOLOR "13[Aimbot]" IRCCOLOR " %.*s was banned from the server! Kills: %u - Deaths: %u - Headshots: %u", player.name.size(), player.name.data(), player.kills, player.deaths, player.headshots); server.sendPubChan(IRCCOLOR "13[Aimbot]" IRCCOLOR " %.*s was banned from the server! Kills: %u - Deaths: %u - Headshots: %u", player.name.size(), player.name.data(), player.kills, player.deaths, player.headshots);
const Jupiter::ReadableString &steamid = server.formatSteamID(player); const Jupiter::ReadableString &steamid = server.formatSteamID(player);
server.sendAdmChan(IRCCOLOR "13[Aimbot]" IRCCOLOR " %.*s was banned from the server! Kills: %u - Deaths: %u - Headshots: %u - IP: " IRCBOLD "%.*s" IRCBOLD " - Steam ID: " IRCBOLD "%.*s" IRCBOLD, player.name.size(), player.name.data(), player.kills, player.deaths, player.headshots, player.ip.size(), player.ip.ptr(), steamid.size(), steamid.ptr()); server.sendAdmChan(IRCCOLOR "13[Aimbot]" IRCCOLOR " %.*s was banned from the server! Kills: %u - Deaths: %u - Headshots: %u - IP: " IRCBOLD "%.*s" IRCBOLD " - Steam ID: " IRCBOLD "%.*s" IRCBOLD, player.name.size(), player.name.data(), player.kills, player.deaths, player.headshots, player.ip.size(), player.ip.data(), steamid.size(), steamid.ptr());
} }
} }
} }

48
src/Plugins/RenX/RenX.ExtraLogging/RenX_ExtraLogging.cpp

@ -45,8 +45,7 @@ int RenX_ExtraLoggingPlugin::OnRehash()
return this->initialize() ? 0 : -1; return this->initialize() ? 0 : -1;
} }
bool RenX_ExtraLoggingPlugin::initialize() bool RenX_ExtraLoggingPlugin::initialize() {
{
RenX_ExtraLoggingPlugin::filePrefix = this->config.get("FilePrefix"_jrs, Jupiter::StringS::Format("[%.*s] %.*s", RenX::tags->timeTag.size(), RenX::tags->timeTag.ptr(), RenX::tags->serverPrefixTag.size(), RenX::tags->serverPrefixTag.ptr())); RenX_ExtraLoggingPlugin::filePrefix = this->config.get("FilePrefix"_jrs, Jupiter::StringS::Format("[%.*s] %.*s", RenX::tags->timeTag.size(), RenX::tags->timeTag.ptr(), RenX::tags->serverPrefixTag.size(), RenX::tags->serverPrefixTag.ptr()));
RenX_ExtraLoggingPlugin::consolePrefix = this->config.get("ConsolePrefix"_jrs, RenX_ExtraLoggingPlugin::filePrefix); RenX_ExtraLoggingPlugin::consolePrefix = this->config.get("ConsolePrefix"_jrs, RenX_ExtraLoggingPlugin::filePrefix);
RenX_ExtraLoggingPlugin::newDayFmt = this->config.get("NewDayFormat"_jrs, Jupiter::StringS::Format("Time: %.*s %.*s", RenX::tags->timeTag.size(), RenX::tags->timeTag.ptr(), RenX::tags->dateTag.size(), RenX::tags->dateTag.ptr())); RenX_ExtraLoggingPlugin::newDayFmt = this->config.get("NewDayFormat"_jrs, Jupiter::StringS::Format("Time: %.*s %.*s", RenX::tags->timeTag.size(), RenX::tags->timeTag.ptr(), RenX::tags->dateTag.size(), RenX::tags->dateTag.ptr()));
@ -57,14 +56,13 @@ bool RenX_ExtraLoggingPlugin::initialize()
RenX::sanitizeTags(RenX_ExtraLoggingPlugin::consolePrefix); RenX::sanitizeTags(RenX_ExtraLoggingPlugin::consolePrefix);
RenX::sanitizeTags(RenX_ExtraLoggingPlugin::newDayFmt); RenX::sanitizeTags(RenX_ExtraLoggingPlugin::newDayFmt);
if (!logFile.empty()) if (!logFile.empty()) {
{
RenX_ExtraLoggingPlugin::file = fopen(logFile.c_str(), "a+b"); RenX_ExtraLoggingPlugin::file = fopen(logFile.c_str(), "a+b");
if (RenX_ExtraLoggingPlugin::file != nullptr && RenX_ExtraLoggingPlugin::newDayFmt.isNotEmpty()) if (RenX_ExtraLoggingPlugin::file != nullptr && RenX_ExtraLoggingPlugin::newDayFmt.isNotEmpty()) {
{
Jupiter::String line = RenX_ExtraLoggingPlugin::newDayFmt; Jupiter::String line = RenX_ExtraLoggingPlugin::newDayFmt;
RenX::processTags(line); RenX::processTags(line);
line.println(RenX_ExtraLoggingPlugin::file); fwrite(line.ptr(), sizeof(char), line.size(), file);
fputs("\r\n", file);
} }
} }
else else
@ -73,10 +71,8 @@ bool RenX_ExtraLoggingPlugin::initialize()
return RenX_ExtraLoggingPlugin::file != nullptr || RenX_ExtraLoggingPlugin::printToConsole; return RenX_ExtraLoggingPlugin::file != nullptr || RenX_ExtraLoggingPlugin::printToConsole;
} }
int RenX_ExtraLoggingPlugin::think() int RenX_ExtraLoggingPlugin::think() {
{ if (RenX_ExtraLoggingPlugin::file != nullptr && RenX_ExtraLoggingPlugin::newDayFmt.isNotEmpty()) {
if (RenX_ExtraLoggingPlugin::file != nullptr && RenX_ExtraLoggingPlugin::newDayFmt.isNotEmpty())
{
time_t current_time = time(nullptr); time_t current_time = time(nullptr);
int currentDay = localtime(&current_time)->tm_yday; int currentDay = localtime(&current_time)->tm_yday;
if (currentDay != RenX_ExtraLoggingPlugin::day) if (currentDay != RenX_ExtraLoggingPlugin::day)
@ -84,36 +80,34 @@ int RenX_ExtraLoggingPlugin::think()
RenX_ExtraLoggingPlugin::day = currentDay; RenX_ExtraLoggingPlugin::day = currentDay;
Jupiter::String line = RenX_ExtraLoggingPlugin::newDayFmt; Jupiter::String line = RenX_ExtraLoggingPlugin::newDayFmt;
RenX::processTags(line); RenX::processTags(line);
line.println(RenX_ExtraLoggingPlugin::file); fwrite(line.ptr(), sizeof(char), line.size(), file);
fputs("\r\n", file);
} }
} }
return 0; return 0;
} }
void RenX_ExtraLoggingPlugin::RenX_OnRaw(RenX::Server &server, const Jupiter::ReadableString &raw) void RenX_ExtraLoggingPlugin::RenX_OnRaw(RenX::Server &server, const Jupiter::ReadableString &raw) {
{ if (RenX_ExtraLoggingPlugin::printToConsole) {
if (RenX_ExtraLoggingPlugin::printToConsole) if (RenX_ExtraLoggingPlugin::consolePrefix.isNotEmpty()) {
{ Jupiter::StringS cPrefix = RenX_ExtraLoggingPlugin::consolePrefix;
if (RenX_ExtraLoggingPlugin::filePrefix.isNotEmpty())
{
Jupiter::StringS cPrefix = RenX_ExtraLoggingPlugin::filePrefix;
RenX::processTags(cPrefix, &server); RenX::processTags(cPrefix, &server);
cPrefix.print(stdout); fwrite(cPrefix.ptr(), sizeof(char), cPrefix.size(), stdout);
fputc(' ', stdout); fputc(' ', stdout);
} }
raw.println(stdout); fwrite(raw.ptr(), sizeof(char), raw.size(), stdout);
fputs("\r\n", stdout);
} }
if (RenX_ExtraLoggingPlugin::file != nullptr) if (RenX_ExtraLoggingPlugin::file != nullptr) {
{ if (RenX_ExtraLoggingPlugin::filePrefix.isNotEmpty()) {
if (RenX_ExtraLoggingPlugin::filePrefix.isNotEmpty())
{
Jupiter::StringS fPrefix = RenX_ExtraLoggingPlugin::filePrefix; Jupiter::StringS fPrefix = RenX_ExtraLoggingPlugin::filePrefix;
RenX::processTags(fPrefix, &server); RenX::processTags(fPrefix, &server);
fPrefix.print(RenX_ExtraLoggingPlugin::file); fwrite(fPrefix.ptr(), sizeof(char), fPrefix.size(), file);
fputc(' ', RenX_ExtraLoggingPlugin::file); fputc(' ', RenX_ExtraLoggingPlugin::file);
} }
raw.println(RenX_ExtraLoggingPlugin::file); fwrite(raw.ptr(), sizeof(char), raw.size(), file);
fputs("\r\n", file);
fflush(RenX_ExtraLoggingPlugin::file); fflush(RenX_ExtraLoggingPlugin::file);
} }
} }

16
src/Plugins/RenX/RenX.Greetings/RenX_Greetings.cpp

@ -23,10 +23,11 @@
#include "RenX_Tags.h" #include "RenX_Tags.h"
using namespace Jupiter::literals; using namespace Jupiter::literals;
using namespace std::literals;
void RenX_GreetingsPlugin::RenX_OnJoin(RenX::Server &server, const RenX::PlayerInfo &player) { void RenX_GreetingsPlugin::RenX_OnJoin(RenX::Server &server, const RenX::PlayerInfo &player) {
auto sendMessage = [&](const Jupiter::ReadableString &m) { auto sendMessage = [&](const std::string& raw_message) {
Jupiter::String msg = m; Jupiter::String msg = raw_message;
RenX::sanitizeTags(msg); RenX::sanitizeTags(msg);
RenX::processTags(msg, &server, &player); RenX::processTags(msg, &server, &player);
@ -66,11 +67,12 @@ int RenX_GreetingsPlugin::OnRehash() {
} }
bool RenX_GreetingsPlugin::initialize() { bool RenX_GreetingsPlugin::initialize() {
m_sendPrivate = this->config.get<bool>("SendPrivate"_jrs, true); m_sendPrivate = this->config.get<bool>("SendPrivate"sv, true);
m_sendMode = this->config.get<unsigned int>("SendMode"_jrs, 0); m_sendMode = this->config.get<unsigned int>("SendMode"sv, 0);
m_greetingsFile.load(this->config.get("GreetingsFile"_jrs, "RenX.Greetings.txt"_jrs)); m_greetingsFile.load(this->config.get("GreetingsFile"sv, "RenX.Greetings.txt"s));
if (m_greetingsFile.getLineCount() == 0) if (m_greetingsFile.getLineCount() == 0) {
m_greetingsFile.addData("Please notify the server administrator to properly configure or disable server greetings.\r\n"_jrs); m_greetingsFile.addData("Please notify the server administrator to properly configure or disable server greetings.\r\n"sv);
}
m_lastLine = m_greetingsFile.getLineCount() - 1; m_lastLine = m_greetingsFile.getLineCount() - 1;
return true; return true;

6
src/Plugins/RenX/RenX.IRCJoin/RenX_IRCJoin.cpp

@ -41,7 +41,7 @@ bool RenX_IRCJoinPlugin::initialize()
return true; return true;
} }
void RenX_IRCJoinPlugin::OnJoin(Jupiter::IRC::Client *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick) void RenX_IRCJoinPlugin::OnJoin(Jupiter::IRC::Client *source, std::string_view channel, std::string_view nick)
{ {
if (RenX_IRCJoinPlugin::joinFmt.isNotEmpty()) if (RenX_IRCJoinPlugin::joinFmt.isNotEmpty())
{ {
@ -67,7 +67,7 @@ void RenX_IRCJoinPlugin::OnJoin(Jupiter::IRC::Client *source, const Jupiter::Rea
} }
} }
void RenX_IRCJoinPlugin::OnPart(Jupiter::IRC::Client *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &reason) void RenX_IRCJoinPlugin::OnPart(Jupiter::IRC::Client *source, std::string_view channel, std::string_view nick, std::string_view reason)
{ {
if (RenX_IRCJoinPlugin::partFmt.isNotEmpty()) if (RenX_IRCJoinPlugin::partFmt.isNotEmpty())
{ {
@ -79,7 +79,7 @@ void RenX_IRCJoinPlugin::OnPart(Jupiter::IRC::Client *source, const Jupiter::Rea
int type = source->getChannel(channel)->getType(); int type = source->getChannel(channel)->getType();
Jupiter::String msg; Jupiter::String msg;
if (reason.isEmpty()) if (reason.empty())
msg = RenX_IRCJoinPlugin::partFmtNoReason; msg = RenX_IRCJoinPlugin::partFmtNoReason;
else else
msg = RenX_IRCJoinPlugin::partFmt; msg = RenX_IRCJoinPlugin::partFmt;

4
src/Plugins/RenX/RenX.IRCJoin/RenX_IRCJoin.h

@ -26,8 +26,8 @@
class RenX_IRCJoinPlugin : public RenX::Plugin class RenX_IRCJoinPlugin : public RenX::Plugin
{ {
public: // Jupiter::Plugin public: // Jupiter::Plugin
void OnJoin(Jupiter::IRC::Client *source, const Jupiter::ReadableString &chan, const Jupiter::ReadableString &nick) override; void OnJoin(Jupiter::IRC::Client *source, std::string_view chan, std::string_view nick) override;
void OnPart(Jupiter::IRC::Client *source, const Jupiter::ReadableString &chan, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &reason) override; void OnPart(Jupiter::IRC::Client *source, std::string_view chan, std::string_view nick, std::string_view reason) override;
virtual bool initialize() override; virtual bool initialize() override;
int OnRehash() override; int OnRehash() override;

2
src/Plugins/RenX/RenX.KickDupes/RenX_KickDupes.cpp

@ -32,7 +32,7 @@ bool RenX_KickDupesPlugin::initialize() {
void RenX_KickDupesPlugin::RenX_OnPlayerIdentify(RenX::Server &in_server, const RenX::PlayerInfo &in_player) { void RenX_KickDupesPlugin::RenX_OnPlayerIdentify(RenX::Server &in_server, const RenX::PlayerInfo &in_player) {
// Safety checks // Safety checks
if (in_player.hwid.isEmpty()) { if (in_player.hwid.empty()) {
// Somehow, the player's identified without any HWID. TODO: log this // Somehow, the player's identified without any HWID. TODO: log this
return; return;
} }

5
src/Plugins/RenX/RenX.Ladder.Web/RenX_Ladder_Web.cpp

@ -180,8 +180,9 @@ Jupiter::String generate_database_selector(RenX::LadderDatabase *db, const Jupit
result += db->getName(); result += db->getName();
result += "</option>"_jrs; result += "</option>"_jrs;
} }
else if (RenX::ladder_databases.size() == 0) else if (RenX::ladder_databases.size() == 0) {
return Jupiter::String::empty; return {};
}
for (const auto& database : RenX::ladder_databases) { for (const auto& database : RenX::ladder_databases) {
if (database != db) { if (database != db) {

14
src/Plugins/RenX/RenX.Ladder/RenX_Ladder.cpp

@ -17,6 +17,7 @@
*/ */
#include <cinttypes> #include <cinttypes>
#include "jessilib/unicode.hpp"
#include "Console_Command.h" #include "Console_Command.h"
#include "RenX_Ladder.h" #include "RenX_Ladder.h"
#include "RenX_Server.h" #include "RenX_Server.h"
@ -63,10 +64,10 @@ void RenX_LadderPlugin::RenX_OnGameOver(RenX::Server &server, RenX::WinType winT
} }
void RenX_LadderPlugin::RenX_OnCommand(RenX::Server &server, const Jupiter::ReadableString &) { void RenX_LadderPlugin::RenX_OnCommand(RenX::Server &server, const Jupiter::ReadableString &) {
if (server.getCurrentRCONCommand().equalsi("clientvarlist"_jrs)) { if (jessilib::equalsi(server.getCurrentRCONCommand(), "clientvarlist"sv)) {
if (server.varData[this->name].get("w"_jrs, "0"_jrs) == "1"sv) { if (server.varData[this->name].get("w"_jrs, "0"_jrs) == "1"sv) {
server.varData[this->name].set("w"sv, "0"s); server.varData[this->name].set("w"sv, "0"s);
RenX::TeamType team = static_cast<RenX::TeamType>(server.varData[this->name].get("t"_jrs, "\0"_jrs).get(0)); RenX::TeamType team = static_cast<RenX::TeamType>(server.varData[this->name].get("t"_jrs, "\0"_jrs)[0]);
for (const auto& database : RenX::ladder_databases) { for (const auto& database : RenX::ladder_databases) {
database->updateLadder(server, team); database->updateLadder(server, team);
} }
@ -98,7 +99,7 @@ LadderGenericCommand::LadderGenericCommand() {
} }
Jupiter::GenericCommand::ResponseLine *LadderGenericCommand::trigger(const Jupiter::ReadableString &parameters) { Jupiter::GenericCommand::ResponseLine *LadderGenericCommand::trigger(const Jupiter::ReadableString &parameters) {
if (parameters.isEmpty()) { if (parameters.empty()) {
return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: ladder <name | rank>"_jrs, GenericCommand::DisplayType::PrivateError); return new Jupiter::GenericCommand::ResponseLine("Error: Too few parameters. Syntax: ladder <name | rank>"_jrs, GenericCommand::DisplayType::PrivateError);
} }
@ -108,8 +109,9 @@ Jupiter::GenericCommand::ResponseLine *LadderGenericCommand::trigger(const Jupit
RenX::LadderDatabase::Entry *entry; RenX::LadderDatabase::Entry *entry;
size_t rank; size_t rank;
if (parameters.span("0123456789"_jrs) == parameters.size()) { std::string_view parameters_view = parameters;
rank = parameters.asUnsignedInt(10); if (parameters_view.find_first_not_of("0123456789"sv) == std::string_view::npos) {
rank = Jupiter::asUnsignedInt(parameters_view, 10);
if (rank == 0) if (rank == 0)
return new Jupiter::GenericCommand::ResponseLine("Error: Invalid parameters"_jrs, GenericCommand::DisplayType::PrivateError); return new Jupiter::GenericCommand::ResponseLine("Error: Invalid parameters"_jrs, GenericCommand::DisplayType::PrivateError);
@ -154,7 +156,7 @@ void LadderGameCommand::create() {
} }
void LadderGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) { void LadderGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
if (parameters.isEmpty()) { if (parameters.empty()) {
if (player->steamid != 0) { if (player->steamid != 0) {
if (RenX::default_ladder_database != nullptr) { if (RenX::default_ladder_database != nullptr) {
std::pair<RenX::LadderDatabase::Entry *, size_t> pair = RenX::default_ladder_database->getPlayerEntryAndIndex(player->steamid); std::pair<RenX::LadderDatabase::Entry *, size_t> pair = RenX::default_ladder_database->getPlayerEntryAndIndex(player->steamid);

42
src/Plugins/RenX/RenX.Logging/RenX_Logging.cpp

@ -112,7 +112,7 @@ bool RenX_LoggingPlugin::initialize()
/** Event formats */ /** Event formats */
RenX_LoggingPlugin::playerRDNSFmt = this->config.get("PlayerRDNSFormat"_jrs, RenX_LoggingPlugin::playerRDNSFmt = this->config.get("PlayerRDNSFormat"_jrs,
Jupiter::ReferenceString::empty); ""_jrs);
RenX_LoggingPlugin::playerIdentifyFmt = this->config.get("PlayerIdentifyFormat"_jrs, RenX_LoggingPlugin::playerIdentifyFmt = this->config.get("PlayerIdentifyFormat"_jrs,
Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " (" IRCBOLD "%.*s" IRCBOLD ") joined the game fighting for the %.*s from " IRCBOLD "%.*s" IRCBOLD " (" IRCBOLD "%.*s" IRCBOLD ") with HWID " IRCBOLD "%.*s" IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->steamTag.size(), RenX::tags->steamTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->ipTag.size(), RenX::tags->ipTag.ptr(), RenX::tags->rdnsTag.size(), RenX::tags->rdnsTag.ptr(), RenX::tags->hwidTag.size(), RenX::tags->hwidTag.ptr())); Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " (" IRCBOLD "%.*s" IRCBOLD ") joined the game fighting for the %.*s from " IRCBOLD "%.*s" IRCBOLD " (" IRCBOLD "%.*s" IRCBOLD ") with HWID " IRCBOLD "%.*s" IRCBOLD ".", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->steamTag.size(), RenX::tags->steamTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr(), RenX::tags->ipTag.size(), RenX::tags->ipTag.ptr(), RenX::tags->rdnsTag.size(), RenX::tags->rdnsTag.ptr(), RenX::tags->hwidTag.size(), RenX::tags->hwidTag.ptr()));
@ -121,10 +121,10 @@ bool RenX_LoggingPlugin::initialize()
Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s!", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr())); Jupiter::StringS::Format(IRCCOLOR "12[Join] " IRCBOLD "%.*s" IRCBOLD " joined the game fighting for the %.*s!", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr()));
RenX_LoggingPlugin::joinAdminFmt = this->config.get("JoinAdminFormat"_jrs, RenX_LoggingPlugin::joinAdminFmt = this->config.get("JoinAdminFormat"_jrs,
Jupiter::ReferenceString::empty); ""_jrs);
RenX_LoggingPlugin::joinNoSteamAdminFmt = this->config.get("JoinNoSteamAdminFormat"_jrs, RenX_LoggingPlugin::joinNoSteamAdminFmt = this->config.get("JoinNoSteamAdminFormat"_jrs,
Jupiter::ReferenceString::empty); ""_jrs);
RenX_LoggingPlugin::partFmt = this->config.get("PartFormat"_jrs, RenX_LoggingPlugin::partFmt = this->config.get("PartFormat"_jrs,
Jupiter::StringS::Format(IRCCOLOR "12[Part] " IRCBOLD "%.*s" IRCBOLD " left the %.*s.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr())); Jupiter::StringS::Format(IRCCOLOR "12[Part] " IRCBOLD "%.*s" IRCBOLD " left the %.*s.", RenX::tags->nameTag.size(), RenX::tags->nameTag.ptr(), RenX::tags->teamLongTag.size(), RenX::tags->teamLongTag.ptr()));
@ -998,12 +998,10 @@ 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) void RenX_LoggingPlugin::RenX_OnDeploy(RenX::Server &server, const RenX::PlayerInfo &player, const Jupiter::ReadableString &object) {
{
logFuncType func; logFuncType func;
Jupiter::String msg; Jupiter::String msg;
if (object.match("*Beacon")) if (std::string_view{object}.ends_with("Beacon")) {
{
if (RenX_LoggingPlugin::deployPublic) if (RenX_LoggingPlugin::deployPublic)
func = &RenX::Server::sendLogChan; func = &RenX::Server::sendLogChan;
else else
@ -1011,8 +1009,7 @@ void RenX_LoggingPlugin::RenX_OnDeploy(RenX::Server &server, const RenX::PlayerI
msg = this->deployFmt; msg = this->deployFmt;
} }
else else {
{
if (RenX_LoggingPlugin::mineDeployPublic) if (RenX_LoggingPlugin::mineDeployPublic)
func = &RenX::Server::sendLogChan; func = &RenX::Server::sendLogChan;
else else
@ -1020,8 +1017,7 @@ void RenX_LoggingPlugin::RenX_OnDeploy(RenX::Server &server, const RenX::PlayerI
msg = this->mineDeployFmt; msg = this->mineDeployFmt;
} }
if (msg.isNotEmpty()) if (msg.isNotEmpty()) {
{
RenX::processTags(msg, &server, &player); RenX::processTags(msg, &server, &player);
msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object)); msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object));
(server.*func)(msg); (server.*func)(msg);
@ -1045,13 +1041,11 @@ void RenX_LoggingPlugin::RenX_OnOverMine(RenX::Server &server, const RenX::Playe
} }
} }
void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server &server, const RenX::PlayerInfo &player, const Jupiter::ReadableString &object, const RenX::PlayerInfo &victim) void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server &server, const RenX::PlayerInfo &player, const Jupiter::ReadableString &object, const RenX::PlayerInfo &victim) {
{
logFuncType func; logFuncType func;
Jupiter::String msg; Jupiter::String msg;
if (object.match("*Beacon")) if (std::string_view{object}.ends_with("Beacon")) {
{
if (RenX_LoggingPlugin::disarmPublic) if (RenX_LoggingPlugin::disarmPublic)
func = &RenX::Server::sendLogChan; func = &RenX::Server::sendLogChan;
else else
@ -1059,8 +1053,7 @@ void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server &server, const RenX::PlayerI
msg = this->disarmFmt; msg = this->disarmFmt;
} }
else else {
{
if (RenX_LoggingPlugin::mineDisarmPublic) if (RenX_LoggingPlugin::mineDisarmPublic)
func = &RenX::Server::sendLogChan; func = &RenX::Server::sendLogChan;
else else
@ -1068,21 +1061,18 @@ void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server &server, const RenX::PlayerI
msg = this->mineDisarmFmt; msg = this->mineDisarmFmt;
} }
if (msg.isNotEmpty()) if (msg.isNotEmpty()) {
{
RenX::processTags(msg, &server, &player, &victim); RenX::processTags(msg, &server, &player, &victim);
msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object)); msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object));
(server.*func)(msg); (server.*func)(msg);
} }
} }
void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server &server, const RenX::PlayerInfo &player, const Jupiter::ReadableString &object) void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server &server, const RenX::PlayerInfo &player, const Jupiter::ReadableString &object) {
{
logFuncType func; logFuncType func;
Jupiter::String msg; Jupiter::String msg;
if (object.match("*Beacon")) if (std::string_view{object}.ends_with("Beacon")) {
{
if (RenX_LoggingPlugin::disarmPublic) if (RenX_LoggingPlugin::disarmPublic)
func = &RenX::Server::sendLogChan; func = &RenX::Server::sendLogChan;
else else
@ -1090,8 +1080,7 @@ void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server &server, const RenX::PlayerI
msg = this->disarmNoOwnerFmt; msg = this->disarmNoOwnerFmt;
} }
else else {
{
if (RenX_LoggingPlugin::mineDisarmPublic) if (RenX_LoggingPlugin::mineDisarmPublic)
func = &RenX::Server::sendLogChan; func = &RenX::Server::sendLogChan;
else else
@ -1099,8 +1088,7 @@ void RenX_LoggingPlugin::RenX_OnDisarm(RenX::Server &server, const RenX::PlayerI
msg = this->mineDisarmNoOwnerFmt; msg = this->mineDisarmNoOwnerFmt;
} }
if (msg.isNotEmpty()) if (msg.isNotEmpty()) {
{
RenX::processTags(msg, &server, &player); RenX::processTags(msg, &server, &player);
msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object)); msg.replace(RenX::tags->INTERNAL_OBJECT_TAG, RenX::translateName(object));
(server.*func)(msg); (server.*func)(msg);

139
src/Plugins/RenX/RenX.Medals/RenX_Medals.cpp

@ -17,6 +17,8 @@
*/ */
#include <ctime> #include <ctime>
#include "jessilib/word_split.hpp"
#include "jessilib/unicode.hpp"
#include "Jupiter/Timer.h" #include "Jupiter/Timer.h"
#include "Jupiter/IRC_Client.h" #include "Jupiter/IRC_Client.h"
#include "RenX_Medals.h" #include "RenX_Medals.h"
@ -45,15 +47,11 @@ RenX_MedalsPlugin::~RenX_MedalsPlugin()
size_t sCount = core->getServerCount(); size_t sCount = core->getServerCount();
RenX::Server *server; RenX::Server *server;
for (size_t i = 0; i < sCount; i++) for (size_t i = 0; i < sCount; i++) {
{
server = core->getServer(i); server = core->getServer(i);
if (server->players.size() != 0) if (server->players.size() != 0) {
{ for (auto node = server->players.begin(); node != server->players.end(); ++node) {
for (auto node = server->players.begin(); node != server->players.end(); ++node) if (!node->uuid.empty() && !node->isBot) {
{
if (node->uuid.isNotEmpty() && node->isBot == false)
{
RenX_MedalsPlugin::medalsFile[node->uuid].set("Recs"_jrs, node->varData[this->getName()].get("Recs"sv, ""s)); RenX_MedalsPlugin::medalsFile[node->uuid].set("Recs"_jrs, node->varData[this->getName()].get("Recs"sv, ""s));
RenX_MedalsPlugin::medalsFile[node->uuid].set("Noobs"_jrs, node->varData[this->getName()].get("Noobs"sv, ""s)); RenX_MedalsPlugin::medalsFile[node->uuid].set("Noobs"_jrs, node->varData[this->getName()].get("Noobs"sv, ""s));
} }
@ -98,64 +96,52 @@ void congratPlayer(unsigned int, void *params)
delete congratPlayerData; delete congratPlayerData;
} }
void RenX_MedalsPlugin::RenX_SanitizeTags(Jupiter::StringType &fmt) void RenX_MedalsPlugin::RenX_SanitizeTags(Jupiter::StringType &fmt) {
{
fmt.replace(RenX_MedalsPlugin::recsTag, this->INTERNAL_RECS_TAG); fmt.replace(RenX_MedalsPlugin::recsTag, this->INTERNAL_RECS_TAG);
fmt.replace(RenX_MedalsPlugin::noobTag, this->INTERNAL_NOOB_TAG); fmt.replace(RenX_MedalsPlugin::noobTag, this->INTERNAL_NOOB_TAG);
fmt.replace(RenX_MedalsPlugin::worthTag, this->INTERNAL_WORTH_TAG); fmt.replace(RenX_MedalsPlugin::worthTag, this->INTERNAL_WORTH_TAG);
} }
void RenX_MedalsPlugin::RenX_ProcessTags(Jupiter::StringType &msg, const RenX::Server *server, const RenX::PlayerInfo *player, const RenX::PlayerInfo *, const RenX::BuildingInfo *) void RenX_MedalsPlugin::RenX_ProcessTags(Jupiter::StringType &msg, const RenX::Server *server, const RenX::PlayerInfo *player, const RenX::PlayerInfo *, const RenX::BuildingInfo *) {
{ if (player != nullptr) {
if (player != nullptr)
{
const Jupiter::ReadableString &recs = RenX_MedalsPlugin::medalsFile.get(player->uuid, "Recs"_jrs); const Jupiter::ReadableString &recs = RenX_MedalsPlugin::medalsFile.get(player->uuid, "Recs"_jrs);
const Jupiter::ReadableString &noobs = RenX_MedalsPlugin::medalsFile.get(player->uuid, "Noobs"_jrs); const Jupiter::ReadableString &noobs = RenX_MedalsPlugin::medalsFile.get(player->uuid, "Noobs"_jrs);
msg.replace(this->INTERNAL_RECS_TAG, recs); msg.replace(this->INTERNAL_RECS_TAG, recs);
msg.replace(this->INTERNAL_NOOB_TAG, noobs); msg.replace(this->INTERNAL_NOOB_TAG, noobs);
msg.replace(this->INTERNAL_WORTH_TAG, Jupiter::StringS::Format("%d", recs.asInt() - noobs.asInt())); msg.replace(this->INTERNAL_WORTH_TAG, Jupiter::StringS::Format("%d", Jupiter::from_string<int>(recs) - Jupiter::from_string<int>(noobs)));
} }
} }
void RenX_MedalsPlugin::RenX_OnPlayerCreate(RenX::Server &, const RenX::PlayerInfo &player) void RenX_MedalsPlugin::RenX_OnPlayerCreate(RenX::Server &, const RenX::PlayerInfo &player) {
{ if (!player.uuid.empty() && player.isBot == false) {
if (player.uuid.isNotEmpty() && player.isBot == false)
{
player.varData[this->getName()].set("Recs"sv, RenX_MedalsPlugin::medalsFile.get(player.uuid, "Recs"s)); player.varData[this->getName()].set("Recs"sv, RenX_MedalsPlugin::medalsFile.get(player.uuid, "Recs"s));
player.varData[this->getName()].set("Noobs"sv, RenX_MedalsPlugin::medalsFile.get(player.uuid, "Noobs"s)); player.varData[this->getName()].set("Noobs"sv, RenX_MedalsPlugin::medalsFile.get(player.uuid, "Noobs"s));
} }
} }
void RenX_MedalsPlugin::RenX_OnPlayerDelete(RenX::Server &, const RenX::PlayerInfo &player) void RenX_MedalsPlugin::RenX_OnPlayerDelete(RenX::Server &, const RenX::PlayerInfo &player) {
{ if (!player.uuid.empty() && player.isBot == false) {
if (player.uuid.isNotEmpty() && player.isBot == false)
{
RenX_MedalsPlugin::medalsFile[player.uuid].set("Recs"_jrs, player.varData[this->getName()].get("Recs"sv, ""s)); RenX_MedalsPlugin::medalsFile[player.uuid].set("Recs"_jrs, player.varData[this->getName()].get("Recs"sv, ""s));
RenX_MedalsPlugin::medalsFile[player.uuid].set("Noobs"_jrs, player.varData[this->getName()].get("Noobs"sv, ""s)); RenX_MedalsPlugin::medalsFile[player.uuid].set("Noobs"_jrs, player.varData[this->getName()].get("Noobs"sv, ""s));
} }
} }
void RenX_MedalsPlugin::RenX_OnJoin(RenX::Server &server, const RenX::PlayerInfo &player) void RenX_MedalsPlugin::RenX_OnJoin(RenX::Server &server, const RenX::PlayerInfo &player) {
{ if (!player.uuid.empty() && player.isBot == false && server.isMatchInProgress()) {
if (player.uuid.isNotEmpty() && player.isBot == false && server.isMatchInProgress())
{
int worth = getWorth(player); int worth = getWorth(player);
Jupiter::Config *section = RenX_MedalsPlugin::config.getSection(RenX_MedalsPlugin::firstSection); Jupiter::Config *section = RenX_MedalsPlugin::config.getSection(RenX_MedalsPlugin::firstSection);
if (section != nullptr) if (section != nullptr) {
{
while (section->get<int>("MaxRecs"_jrs, INT_MAX) < worth) while (section->get<int>("MaxRecs"_jrs, INT_MAX) < worth)
if ((section = RenX_MedalsPlugin::config.getSection(section->get("NextSection"_jrs))) == nullptr) if ((section = RenX_MedalsPlugin::config.getSection(section->get("NextSection"_jrs))) == nullptr)
return; // No matching section found. return; // No matching section found.
size_t table_size = section->getTable().size(); size_t table_size = section->getTable().size();
if (table_size != 0) if (table_size != 0) {
{
std::string_view msg = section->get(Jupiter::StringS::Format("%u", (rand() % table_size) + 1)); std::string_view msg = section->get(Jupiter::StringS::Format("%u", (rand() % table_size) + 1));
if (!msg.empty()) if (!msg.empty()) {
{
Jupiter::StringS tagged_msg = static_cast<Jupiter::ReferenceString>(msg); Jupiter::StringS tagged_msg = static_cast<Jupiter::ReferenceString>(msg);
RenX::sanitizeTags(tagged_msg); RenX::sanitizeTags(tagged_msg);
RenX::processTags(tagged_msg, &server, &player); RenX::processTags(tagged_msg, &server, &player);
@ -193,7 +179,7 @@ void RenX_MedalsPlugin::RenX_OnGameOver(RenX::Server &server, RenX::WinType winT
CongratPlayerData *congratPlayerData; CongratPlayerData *congratPlayerData;
/** +1 for best score */ /** +1 for best score */
if (bestScore->uuid.isNotEmpty() && bestScore->isBot == false && bestScore->score > 0) if (!bestScore->uuid.empty() && bestScore->isBot == false && bestScore->score > 0)
{ {
addRec(*bestScore); addRec(*bestScore);
@ -205,7 +191,7 @@ void RenX_MedalsPlugin::RenX_OnGameOver(RenX::Server &server, RenX::WinType winT
} }
/** +1 for most kills */ /** +1 for most kills */
if (mostKills->uuid.isNotEmpty() && mostKills->isBot == false && mostKills->kills > 0) if (!mostKills->uuid.empty() && mostKills->isBot == false && mostKills->kills > 0)
{ {
addRec(*mostKills); addRec(*mostKills);
@ -217,7 +203,7 @@ void RenX_MedalsPlugin::RenX_OnGameOver(RenX::Server &server, RenX::WinType winT
} }
/** +1 for most Vehicle kills */ /** +1 for most Vehicle kills */
if (mostVehicleKills->uuid.isNotEmpty() && mostVehicleKills->isBot == false && mostVehicleKills->vehicleKills > 0) if (!mostVehicleKills->uuid.empty() && mostVehicleKills->isBot == false && mostVehicleKills->vehicleKills > 0)
{ {
addRec(*mostVehicleKills); addRec(*mostVehicleKills);
@ -229,7 +215,7 @@ void RenX_MedalsPlugin::RenX_OnGameOver(RenX::Server &server, RenX::WinType winT
} }
/** +1 for best K/D ratio */ /** +1 for best K/D ratio */
if (bestKD->uuid.isNotEmpty() && bestKD->isBot == false && RenX::getKillDeathRatio(*bestKD) > 1.0) if (!bestKD->uuid.empty() && bestKD->isBot == false && RenX::getKillDeathRatio(*bestKD) > 1.0)
{ {
addRec(*bestKD); addRec(*bestKD);
@ -324,16 +310,16 @@ void RecsGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, co
source->sendMessage(*player, Jupiter::StringS::Format("[Archive] %.*s has %u and %u n00bs. Their worth: %d", section->getName().size(), section->getName().c_str(), recs, noobs, recs - noobs)); source->sendMessage(*player, Jupiter::StringS::Format("[Archive] %.*s has %u and %u n00bs. Their worth: %d", section->getName().size(), section->getName().c_str(), recs, noobs, recs - noobs));
} }
} }
else if (target->uuid.isEmpty()) else if (target->uuid.empty())
source->sendMessage(*player, "Error: Player is not using steam."_jrs); source->sendMessage(*player, "Error: Player is not using steam."_jrs);
else if (target->isBot) else if (target->isBot)
source->sendMessage(*player, "Error: Bots do not have any recommendations."_jrs); source->sendMessage(*player, "Error: Bots do not have any recommendations."_jrs);
else if (target == player) else if (target == player)
RecsGameCommand::trigger(source, player, Jupiter::ReferenceString::empty); RecsGameCommand::trigger(source, player, ""_jrs);
else else
source->sendMessage(*player, Jupiter::StringS::Format("%.*s has %lu and %lu n00bs. Their worth: %d", target->name.size(), target->name.data(), getRecs(*target), getNoobs(*target), getWorth(*target))); source->sendMessage(*player, Jupiter::StringS::Format("%.*s has %lu and %lu n00bs. Their worth: %d", target->name.size(), target->name.data(), getRecs(*target), getNoobs(*target), getWorth(*target)));
} }
else if (player->uuid.isEmpty()) else if (player->uuid.empty())
source->sendMessage(*player, "Error: You are not using steam."_jrs); source->sendMessage(*player, "Error: You are not using steam."_jrs);
else else
source->sendMessage(*player, Jupiter::StringS::Format("%.*s, you have %lu recs and %lu n00bs. Your worth: %d", player->name.size(), player->name.data(), getRecs(*player), getNoobs(*player), getWorth(*player))); source->sendMessage(*player, Jupiter::StringS::Format("%.*s, you have %lu recs and %lu n00bs. Your worth: %d", player->name.size(), player->name.data(), getRecs(*player), getNoobs(*player), getWorth(*player)));
@ -355,28 +341,30 @@ void RecGameCommand::create()
this->addTrigger("recommend"_jrs); this->addTrigger("recommend"_jrs);
} }
void RecGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) void RecGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
{ auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
if (parameters.isNotEmpty()) if (!parameters_split.first.empty()) {
{
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters); RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
if (target == nullptr) if (target == nullptr) {
target = source->getPlayerByPartName(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE)); target = source->getPlayerByPartName(parameters_split.first);
if (target == nullptr) }
if (target == nullptr) {
source->sendMessage(*player, "Error: Player not found! Syntax: rec <player>"_jrs); source->sendMessage(*player, "Error: Player not found! Syntax: rec <player>"_jrs);
else if (target->uuid.isEmpty()) }
else if (target->uuid.empty()) {
source->sendMessage(*player, "Error: Player is not using steam."_jrs); source->sendMessage(*player, "Error: Player is not using steam."_jrs);
else if (target->isBot) }
else if (target->isBot) {
source->sendMessage(*player, "Error: Bots can not receive recommendations."_jrs); source->sendMessage(*player, "Error: Bots can not receive recommendations."_jrs);
else if (target == player) }
{ else if (target == player) {
addNoob(*player); addNoob(*player);
source->sendMessage(*player, "You can't recommend yourself, you noob! (+1 noob)"_jrs); source->sendMessage(*player, "You can't recommend yourself, you noob! (+1 noob)"_jrs);
} }
else if (player->varData["RenX.Medals"_jrs].get("gr"_jrs) != nullptr && player->adminType.isEmpty()) else if (!player->varData["RenX.Medals"_jrs].get("gr"_jrs).empty() && player->adminType.empty()) {
source->sendMessage(*player, "You can only give one recommendation per game."_jrs); source->sendMessage(*player, "You can only give one recommendation per game."_jrs);
else }
{ else {
addRec(*target); addRec(*target);
source->sendMessage(Jupiter::StringS::Format("%.*s has recommended %.*s!", player->name.size(), player->name.data(), target->name.size(), target->name.data())); source->sendMessage(Jupiter::StringS::Format("%.*s has recommended %.*s!", player->name.size(), player->name.data(), target->name.size(), target->name.data()));
player->varData["RenX.Medals"_jrs].set("gr"_jrs, "1"s); player->varData["RenX.Medals"_jrs].set("gr"_jrs, "1"s);
@ -387,7 +375,7 @@ void RecGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, con
const Jupiter::ReadableString &RecGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &RecGameCommand::getHelp(const Jupiter::ReadableString &)
{ {
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Recommends a player for their gameplay. Syntax: rec [player]"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Recommends a player for their gameplay. Syntax: rec <player> [reason]");
return defaultHelp; return defaultHelp;
} }
@ -401,23 +389,26 @@ void NoobGameCommand::create()
this->addTrigger("n00b"_jrs); this->addTrigger("n00b"_jrs);
} }
void NoobGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) void NoobGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
{ auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
if (parameters.isNotEmpty()) if (!parameters_split.first.empty()) {
{
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters); RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
if (target == nullptr) if (target == nullptr) {
target = source->getPlayerByPartName(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE)); target = source->getPlayerByPartName(parameters_split.first);
if (target == nullptr) }
if (target == nullptr) {
source->sendMessage(*player, "Error: Player not found! Syntax: noob [player]"_jrs); source->sendMessage(*player, "Error: Player not found! Syntax: noob [player]"_jrs);
else if (target->uuid.isEmpty()) }
else if (target->uuid.empty()) {
source->sendMessage(*player, "Error: Player is not using steam."_jrs); source->sendMessage(*player, "Error: Player is not using steam."_jrs);
else if (target->isBot) }
else if (target->isBot) {
source->sendMessage(*player, "Error: Bots can not receive n00bs."_jrs); source->sendMessage(*player, "Error: Bots can not receive n00bs."_jrs);
else if (player->varData["RenX.Medals"_jrs].get("gn"_jrs) != nullptr && player->adminType.isEmpty()) }
else if (player->varData["RenX.Medals"_jrs].get("gn"_jrs) != nullptr && player->adminType.empty()) {
source->sendMessage(*player, "You can only give one noob per game."_jrs); source->sendMessage(*player, "You can only give one noob per game."_jrs);
else }
{ else {
addNoob(*target); addNoob(*target);
source->sendMessage(Jupiter::StringS::Format("%.*s has noob'd %.*s!", player->name.size(), player->name.data(), target->name.size(), target->name.data())); source->sendMessage(Jupiter::StringS::Format("%.*s has noob'd %.*s!", player->name.size(), player->name.data(), target->name.size(), target->name.data()));
player->varData["RenX.Medals"_jrs].set("gn"_jrs, "1"s); player->varData["RenX.Medals"_jrs].set("gn"_jrs, "1"s);
@ -434,16 +425,16 @@ const Jupiter::ReadableString &NoobGameCommand::getHelp(const Jupiter::ReadableS
GAME_COMMAND_INIT(NoobGameCommand) GAME_COMMAND_INIT(NoobGameCommand)
void addRec(const RenX::PlayerInfo &player, int amount) void addRec(const RenX::PlayerInfo &player, int amount) {
{ if (!jessilib::starts_withi(player.uuid, "Player"sv) && !player.isBot) {
if (player.uuid.matchi("Player*") == false && player.isBot == false)
player.varData[pluginInstance.getName()].set("Recs"_jrs, static_cast<std::string>(Jupiter::StringS::Format("%u", getRecs(player) + amount))); player.varData[pluginInstance.getName()].set("Recs"_jrs, static_cast<std::string>(Jupiter::StringS::Format("%u", getRecs(player) + amount)));
}
} }
void addNoob(const RenX::PlayerInfo &player, int amount) void addNoob(const RenX::PlayerInfo &player, int amount) {
{ if (!jessilib::starts_withi(player.uuid, "Player"sv) && !player.isBot) {
if (player.uuid.matchi("Player*") == false && player.isBot == false) player.varData[pluginInstance.getName()].set("Noobs"_jrs,static_cast<std::string>(Jupiter::StringS::Format("%u", getNoobs(player) + amount)));
player.varData[pluginInstance.getName()].set("Noobs"_jrs, static_cast<std::string>(Jupiter::StringS::Format("%u", getNoobs(player) + amount))); }
} }
unsigned long getRecs(const RenX::PlayerInfo &player) unsigned long getRecs(const RenX::PlayerInfo &player)

148
src/Plugins/RenX/RenX.ModSystem/RenX_ModSystem.cpp

@ -17,6 +17,7 @@
*/ */
#include "jessilib/unicode.hpp" #include "jessilib/unicode.hpp"
#include "jessilib/word_split.hpp"
#include "Jupiter/IRC_Client.h" #include "Jupiter/IRC_Client.h"
#include "IRC_Bot.h" #include "IRC_Bot.h"
#include "RenX_ModSystem.h" #include "RenX_ModSystem.h"
@ -56,8 +57,7 @@ bool RenX_ModSystemPlugin::initialize() {
std::string groupName = this->config.get("Default"_jrs, ""s); std::string groupName = this->config.get("Default"_jrs, ""s);
while (!groupName.empty()) while (!groupName.empty()) {
{
// Add group // Add group
groups.emplace_back(); groups.emplace_back();
group = &groups.back(); group = &groups.back();
@ -104,6 +104,11 @@ bool RenX_ModSystemPlugin::initialize() {
groupName = this->config.get(groupName); groupName = this->config.get(groupName);
} }
if (groups.empty()) {
// No groups configured; don't load further
return false;
}
RenX::Core *core = RenX::getCore(); RenX::Core *core = RenX::getCore();
size_t server_count = core->getServerCount(); size_t server_count = core->getServerCount();
RenX::Server *server; RenX::Server *server;
@ -162,24 +167,21 @@ int RenX_ModSystemPlugin::auth(RenX::Server &server, const RenX::PlayerInfo &pla
return 0; return 0;
const ModGroup *group; const ModGroup *group;
if (player.uuid.isNotEmpty()) if (!player.uuid.empty()) {
{
Jupiter::Config *section = this->config.getSection(player.uuid); Jupiter::Config *section = this->config.getSection(player.uuid);
if (section != nullptr) if (section != nullptr) {
{
std::string_view groupName = section->get("Group"_jrs); std::string_view groupName = section->get("Group"_jrs);
if (groupName.empty()) if (groupName.empty()) {
group = &RenX_ModSystemPlugin::groups.front(); group = &RenX_ModSystemPlugin::groups.front();
else }
{ else {
group = getGroupByName(groupName); group = getGroupByName(groupName);
if (group == nullptr) if (group == nullptr)
group = &RenX_ModSystemPlugin::groups.front(); group = &RenX_ModSystemPlugin::groups.front();
} }
auto sectionAuth = [&] auto sectionAuth = [&] {
{
player.varData[this->name].set("Group"_jrs, group->name); player.varData[this->name].set("Group"_jrs, group->name);
player.formatNamePrefix = section->get("Prefix"_jrs, group->prefix); player.formatNamePrefix = section->get("Prefix"_jrs, group->prefix);
player.gamePrefix = section->get("GamePrefix"_jrs, group->gamePrefix); player.gamePrefix = section->get("GamePrefix"_jrs, group->gamePrefix);
@ -210,7 +212,7 @@ int RenX_ModSystemPlugin::auth(RenX::Server &server, const RenX::PlayerInfo &pla
bool autoAuthSteam_l = section->get<bool>("AutoAuthSteam"_jrs, group->autoAuthSteam); bool autoAuthSteam_l = section->get<bool>("AutoAuthSteam"_jrs, group->autoAuthSteam);
bool autoAuthIP_l = section->get<bool>("AutoAuthIP"_jrs, group->autoAuthIP); bool autoAuthIP_l = section->get<bool>("AutoAuthIP"_jrs, group->autoAuthIP);
uint64_t steamid = Jupiter::ReferenceString{section->get("SteamID"_jrs)}.asUnsignedLongLong(); uint64_t steamid = Jupiter::from_string<uint64_t>(section->get("SteamID"sv));
std::string_view ip = section->get("LastIP"_jrs); std::string_view ip = section->get("LastIP"_jrs);
std::string_view name = section->get("Name"_jrs); std::string_view name = section->get("Name"_jrs);
@ -346,12 +348,13 @@ RenX_ModSystemPlugin::~RenX_ModSystemPlugin() {
} }
void RenX_ModSystemPlugin::RenX_OnPlayerCreate(RenX::Server &server, const RenX::PlayerInfo &player) { void RenX_ModSystemPlugin::RenX_OnPlayerCreate(RenX::Server &server, const RenX::PlayerInfo &player) {
if (player.isBot == false) if (!player.isBot) {
auth(server, player, true); auth(server, player, true);
}
} }
void RenX_ModSystemPlugin::RenX_OnPlayerDelete(RenX::Server &server, const RenX::PlayerInfo &player) { void RenX_ModSystemPlugin::RenX_OnPlayerDelete(RenX::Server &server, const RenX::PlayerInfo &player) {
if (RenX_ModSystemPlugin::groups.size() != 0 && player.isBot == false && player.uuid.isNotEmpty()) { if (RenX_ModSystemPlugin::groups.size() != 0 && !player.isBot && !player.uuid.empty()) {
Jupiter::Config *section = this->config.getSection(player.uuid); Jupiter::Config *section = this->config.getSection(player.uuid);
if (section != nullptr) { if (section != nullptr) {
section->set("SteamID"_jrs, static_cast<std::string>(Jupiter::StringS::Format("%llu", player.steamid))); section->set("SteamID"_jrs, static_cast<std::string>(Jupiter::StringS::Format("%llu", player.steamid)));
@ -556,43 +559,41 @@ void ATMIRCCommand::create()
void ATMIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) void ATMIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters)
{ {
if (parameters.isEmpty()) if (parameters.empty()) {
this->trigger(source, channel, nick, nick); this->trigger(source, channel, nick, nick);
else }
{ else {
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
if (chan != nullptr) if (chan != nullptr) {
{
RenX::Server *server; RenX::Server *server;
RenX::PlayerInfo *player; RenX::PlayerInfo *player;
RenX_ModSystemPlugin::ModGroup *group = pluginInstance.getDefaultATMGroup(); RenX_ModSystemPlugin::ModGroup *group = pluginInstance.getDefaultATMGroup();
int type = chan->getType(); int type = chan->getType();
bool serverMatch = false; bool serverMatch = false;
Jupiter::ReferenceString playerName = parameters; std::string_view playerName = parameters;
if (isdigit(parameters.get(0))) if (isdigit(parameters[0])) {
{ auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
int index = parameters.asInt(); int index = Jupiter::asInt(parameters_split.first);
if (index < 0 || index >= static_cast<int>(pluginInstance.groups.size())) if (index < 0 || index >= static_cast<int>(pluginInstance.groups.size())) {
source->sendNotice(nick, "Warning: Invalid group index. Ingoring parameter..."_jrs); source->sendNotice(nick, "Warning: Invalid group index. Ingoring parameter..."_jrs);
else if (index == 0) }
{ else if (index == 0) {
source->sendNotice(nick, "Error: Default group is not valid for this command. Use \"deauth\" to deauthorize a player."_jrs); source->sendNotice(nick, "Error: Default group is not valid for this command. Use \"deauth\" to deauthorize a player."sv);
return; return;
} }
else else {
{
group = pluginInstance.getGroupByIndex(index); group = pluginInstance.getGroupByIndex(index);
if (group->access > source->getAccessLevel(channel, nick)) if (group->access > source->getAccessLevel(channel, nick)) {
{
group = pluginInstance.getDefaultATMGroup(); group = pluginInstance.getDefaultATMGroup();
source->sendNotice(nick, "Warning: You can not authorize an access level higher than yourself. Ignoring parameter..."_jrs); source->sendNotice(nick, "Warning: You can not authorize an access level higher than yourself. Ignoring parameter..."sv);
} }
playerName = playerName.gotoWord(1, WHITESPACE); playerName = parameters_split.second;
if (playerName.isEmpty()) if (playerName.empty()) {
playerName = nick; playerName = nick;
} }
} }
}
if (group == nullptr) if (group == nullptr)
source->sendNotice(nick, "Error: Invalid group."_jrs); source->sendNotice(nick, "Error: Invalid group."_jrs);
else else
@ -640,52 +641,48 @@ void AddIRCCommand::create()
this->setAccessLevel(5); this->setAccessLevel(5);
} }
void AddIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) void AddIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) {
{ auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
if (parameters.wordCount(WHITESPACE) < 2) if (parameters_split.second.empty()) {
source->sendNotice(nick, "Error: Too few parameters. Syntax: add <level> <player>"_jrs); source->sendNotice(nick, "Error: Too few parameters. Syntax: add <level> <player>"_jrs);
else return;
{ }
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
if (chan != nullptr) if (chan != nullptr) {
{
RenX::Server *server; RenX::Server *server;
RenX::PlayerInfo *player; RenX::PlayerInfo *player;
RenX_ModSystemPlugin::ModGroup *group = nullptr; RenX_ModSystemPlugin::ModGroup *group = nullptr;
int type = chan->getType(); int type = chan->getType();
bool serverMatch = false; bool serverMatch = false;
Jupiter::ReferenceString playerName = parameters; std::string_view playerName = parameters;
if (isdigit(parameters.get(0))) if (isdigit(parameters[0])) {
{ auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
int index = parameters.asInt(); int index = Jupiter::asInt(parameters_split.first);
if (index < 0 || index >= static_cast<int>(pluginInstance.groups.size())) if (index < 0 || index >= static_cast<int>(pluginInstance.groups.size())) {
source->sendNotice(nick, "Error: Invalid group index."_jrs); source->sendNotice(nick, "Error: Invalid group index."_jrs);
else }
{ else {
group = pluginInstance.getGroupByIndex(index); group = pluginInstance.getGroupByIndex(index);
playerName = playerName.gotoWord(1, WHITESPACE); playerName = parameters_split.second;
} }
} }
if (group == nullptr) if (group == nullptr)
source->sendNotice(nick, "Error: Invalid group."_jrs); source->sendNotice(nick, "Error: Invalid group."_jrs);
else else {
{ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++) {
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
{
server = RenX::getCore()->getServer(i); server = RenX::getCore()->getServer(i);
if (server->isLogChanType(type)) if (server->isLogChanType(type)) {
{
serverMatch = true; serverMatch = true;
player = server->getPlayerByPartName(playerName); player = server->getPlayerByPartName(playerName);
if (player == nullptr) if (player == nullptr)
source->sendNotice(nick, "Error: Player not found."_jrs); source->sendNotice(nick, "Error: Player not found."_jrs);
else if (player->isBot) else if (player->isBot)
source->sendNotice(nick, "Error: A bot can not be a moderator."_jrs); source->sendNotice(nick, "Error: A bot can not be a moderator."_jrs);
else if (player->uuid.isEmpty()) else if (player->uuid.empty())
source->sendNotice(nick, "Error: Player has no UUID."_jrs); source->sendNotice(nick, "Error: Player has no UUID."_jrs);
else else {
{
pluginInstance.resetAccess(*player); pluginInstance.resetAccess(*player);
if (pluginInstance.set(*player, *group)) if (pluginInstance.set(*player, *group))
source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been added to group \"%.*s\"", player->name.size(), player->name.data(), group->name.size(), group->name.data())); source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been added to group \"%.*s\"", player->name.size(), player->name.data(), group->name.size(), group->name.data()));
@ -699,7 +696,6 @@ void AddIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &chan
source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs); source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
} }
} }
}
} }
const Jupiter::ReadableString &AddIRCCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &AddIRCCommand::getHelp(const Jupiter::ReadableString &)
@ -724,7 +720,7 @@ void DelIRCCommand::create()
void DelIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) void DelIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters)
{ {
std::string_view parameters_view = parameters; std::string_view parameters_view = parameters;
if (parameters.isEmpty()) if (parameters.empty())
source->sendNotice(nick, "Error: Too few parameters. Syntax: del <player>"_jrs); source->sendNotice(nick, "Error: Too few parameters. Syntax: del <player>"_jrs);
else else
{ {
@ -960,37 +956,33 @@ void ATMGameCommand::create()
this->setAccessLevel(3); this->setAccessLevel(3);
} }
void ATMGameCommand::trigger(RenX::Server *server, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) void ATMGameCommand::trigger(RenX::Server *server, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
{ auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
if (parameters.isNotEmpty()) if (!parameters_split.first.empty()) {
{
RenX::PlayerInfo *target; RenX::PlayerInfo *target;
RenX_ModSystemPlugin::ModGroup *group = pluginInstance.getDefaultATMGroup(); RenX_ModSystemPlugin::ModGroup *group = pluginInstance.getDefaultATMGroup();
Jupiter::ReferenceString playerName = parameters; std::string_view playerName = parameters;
if (isdigit(parameters.get(0)) && parameters.wordCount(WHITESPACE) > 1) if (isdigit(parameters[0]) && !parameters_split.second.empty()) {
{ auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
int index = parameters.asInt(); int index = Jupiter::asInt(parameters_split.first);
if (index < 0 || index >= static_cast<int>(pluginInstance.groups.size())) if (index < 0 || index >= static_cast<int>(pluginInstance.groups.size())) {
server->sendMessage(*player, "Warning: Invalid group index. Ingoring parameter..."_jrs); server->sendMessage(*player, "Warning: Invalid group index. Ingoring parameter..."_jrs);
else if (index == 0) }
{ else if (index == 0) {
server->sendMessage(*player, "Error: Default group is not valid for this command. Use \"deauth\" to deauthorize a player."_jrs); server->sendMessage(*player, "Error: Default group is not valid for this command. Use \"deauth\" to deauthorize a player."_jrs);
return; return;
} }
else else {
{
group = pluginInstance.getGroupByIndex(index); group = pluginInstance.getGroupByIndex(index);
if (group->access > player->access) if (group->access > player->access) {
{
group = pluginInstance.getDefaultATMGroup(); group = pluginInstance.getDefaultATMGroup();
server->sendMessage(*player, "Warning: You can not authorize an access level higher than yourself. Ignoring parameter..."_jrs); server->sendMessage(*player, "Warning: You can not authorize an access level higher than yourself. Ignoring parameter..."_jrs);
} }
playerName = playerName.gotoWord(1, WHITESPACE); playerName = parameters_split.second;
} }
} }
if (group != nullptr) if (group != nullptr) {
{
target = server->getPlayerByPartName(playerName); target = server->getPlayerByPartName(playerName);
if (target == nullptr) if (target == nullptr)
server->sendMessage(*player, "Error: Player not found."_jrs); server->sendMessage(*player, "Error: Player not found."_jrs);

8
src/Plugins/RenX/RenX.Relay/RenX_Relay.cpp

@ -14,6 +14,7 @@
#include "fmt/format.h" // TODO: replace with <format> later #include "fmt/format.h" // TODO: replace with <format> later
#include <charconv> #include <charconv>
#include "jessilib/split.hpp" #include "jessilib/split.hpp"
#include "jessilib/word_split.hpp"
#include "Jupiter/IRC.h" #include "Jupiter/IRC.h"
#include "RenX_Functions.h" #include "RenX_Functions.h"
#include "RenX_Server.h" #include "RenX_Server.h"
@ -177,10 +178,9 @@ bool RenX_RelayPlugin::initialize() {
m_default_settings = get_settings(config); m_default_settings = get_settings(config);
Jupiter::ReferenceString upstreams_list = config.get("Upstreams"_jrs, ""_jrs); std::string_view upstreams_list = config.get("Upstreams"_jrs, ""sv);
unsigned int upstream_count = upstreams_list.wordCount(WHITESPACE); std::vector<std::string_view> upstream_names = jessilib::word_split_view(upstreams_list, WHITESPACE_SV);
for (unsigned int word_index = 0; word_index != upstream_count; ++word_index) { for (auto upstream_name : upstream_names) {
auto upstream_name = Jupiter::ReferenceString::getWord(upstreams_list, word_index, WHITESPACE);
auto upstream_config = config.getSection(upstream_name); auto upstream_config = config.getSection(upstream_name);
if (upstream_config == nullptr) { if (upstream_config == nullptr) {
upstream_config = &config; upstream_config = &config;

4
src/Plugins/RenX/RenX.ServerList/RenX_ServerList.cpp

@ -170,7 +170,7 @@ Jupiter::StringS RenX_ServerListPlugin::server_as_json(const RenX::Server &serve
Jupiter::String server_json_block(128); Jupiter::String server_json_block(128);
ListServerInfo serverInfo = getListServerInfo(server); ListServerInfo serverInfo = getListServerInfo(server);
if (serverInfo.hostname.isEmpty()) { if (serverInfo.hostname.empty()) {
server_json_block = "null"; server_json_block = "null";
return server_json_block; return server_json_block;
} }
@ -183,7 +183,7 @@ Jupiter::StringS RenX_ServerListPlugin::server_as_json(const RenX::Server &serve
Jupiter::String server_prefix = jsonify(serverInfo.namePrefix); Jupiter::String server_prefix = jsonify(serverInfo.namePrefix);
// Some members we only include if they're populated // Some members we only include if they're populated
if (!server_prefix.isEmpty()) { if (!server_prefix.empty()) {
server_prefix = R"json("NamePrefix":")json"_jrs + server_prefix + "\","_jrs; server_prefix = R"json("NamePrefix":")json"_jrs + server_prefix + "\","_jrs;
} }

57
src/Plugins/RenX/RenX.SetJoin/RenX_SetJoin.cpp

@ -23,10 +23,8 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
void RenX_SetJoinPlugin::RenX_OnJoin(RenX::Server &server, const RenX::PlayerInfo &player) void RenX_SetJoinPlugin::RenX_OnJoin(RenX::Server &server, const RenX::PlayerInfo &player) {
{ if (!player.uuid.empty() && server.isMatchInProgress()) {
if (player.uuid.isNotEmpty() && server.isMatchInProgress())
{
std::string_view setjoin = RenX_SetJoinPlugin::setjoin_file.get(player.uuid); std::string_view setjoin = RenX_SetJoinPlugin::setjoin_file.get(player.uuid);
if (!setjoin.empty()) if (!setjoin.empty())
server.sendMessage(Jupiter::StringS::Format("[%.*s] %.*s", player.name.size(), player.name.data(), setjoin.size(), setjoin.data())); server.sendMessage(Jupiter::StringS::Format("[%.*s] %.*s", player.name.size(), player.name.data(), setjoin.size(), setjoin.data()));
@ -38,16 +36,13 @@ RenX_SetJoinPlugin pluginInstance;
// ViewJoin Game Command // ViewJoin Game Command
void ViewJoinGameCommand::create() void ViewJoinGameCommand::create() {
{
this->addTrigger("viewjoin"_jrs); this->addTrigger("viewjoin"_jrs);
this->addTrigger("vjoin"_jrs); this->addTrigger("vjoin"_jrs);
} }
void ViewJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) void ViewJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
{ if (!player->uuid.empty()) {
if (player->uuid.isNotEmpty())
{
std::string_view setjoin = pluginInstance.setjoin_file.get(player->uuid); std::string_view setjoin = pluginInstance.setjoin_file.get(player->uuid);
if (!setjoin.empty()) if (!setjoin.empty())
@ -59,8 +54,7 @@ void ViewJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player
source->sendMessage(*player, "Error: A setjoin message requires steam."_jrs); source->sendMessage(*player, "Error: A setjoin message requires steam."_jrs);
} }
const Jupiter::ReadableString &ViewJoinGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &ViewJoinGameCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays your join message. Syntax: viewjoin"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays your join message. Syntax: viewjoin");
return defaultHelp; return defaultHelp;
} }
@ -69,16 +63,13 @@ GAME_COMMAND_INIT(ViewJoinGameCommand)
// ShowJoin Game Command // ShowJoin Game Command
void ShowJoinGameCommand::create() void ShowJoinGameCommand::create() {
{
this->addTrigger("showjoin"_jrs); this->addTrigger("showjoin"_jrs);
this->addTrigger("shjoin"_jrs); this->addTrigger("shjoin"_jrs);
} }
void ShowJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) void ShowJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
{ if (!player->uuid.empty()) {
if (player->uuid.isNotEmpty())
{
std::string_view setjoin = pluginInstance.setjoin_file.get(player->uuid); std::string_view setjoin = pluginInstance.setjoin_file.get(player->uuid);
if (!setjoin.empty()) if (!setjoin.empty())
@ -90,8 +81,7 @@ void ShowJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player
source->sendMessage(*player, "Error: A setjoin message requires steam."_jrs); source->sendMessage(*player, "Error: A setjoin message requires steam."_jrs);
} }
const Jupiter::ReadableString &ShowJoinGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &ShowJoinGameCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays your join message. Syntax: showjoin"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays your join message. Syntax: showjoin");
return defaultHelp; return defaultHelp;
} }
@ -108,10 +98,8 @@ void DelJoinGameCommand::create()
this->addTrigger("rjoin"_jrs); this->addTrigger("rjoin"_jrs);
} }
void DelJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &) void DelJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &) {
{ if (!player->uuid.empty()) {
if (player->uuid.isNotEmpty())
{
if (pluginInstance.setjoin_file.remove(player->uuid)) if (pluginInstance.setjoin_file.remove(player->uuid))
source->sendMessage(*player, Jupiter::StringS::Format("%.*s, your join message has been removed.", player->name.size(), player->name.data())); source->sendMessage(*player, Jupiter::StringS::Format("%.*s, your join message has been removed.", player->name.size(), player->name.data()));
else else
@ -121,8 +109,7 @@ void DelJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player,
source->sendMessage(*player, "Error: A setjoin message requires steam."_jrs); source->sendMessage(*player, "Error: A setjoin message requires steam."_jrs);
} }
const Jupiter::ReadableString &DelJoinGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &DelJoinGameCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Removes your automatic join message. Syntax: deljoin"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Removes your automatic join message. Syntax: deljoin");
return defaultHelp; return defaultHelp;
} }
@ -131,18 +118,14 @@ GAME_COMMAND_INIT(DelJoinGameCommand)
// SetJoin Game Command // SetJoin Game Command
void SetJoinGameCommand::create() void SetJoinGameCommand::create() {
{
this->addTrigger("setjoin"_jrs); this->addTrigger("setjoin"_jrs);
this->addTrigger("sjoin"_jrs); this->addTrigger("sjoin"_jrs);
} }
void SetJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) void SetJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
{ if (!player->uuid.empty()) {
if (player->uuid.isNotEmpty()) if (!parameters.empty()) {
{
if (parameters.isNotEmpty())
{
pluginInstance.setjoin_file.set(player->uuid, static_cast<std::string>(parameters)); pluginInstance.setjoin_file.set(player->uuid, static_cast<std::string>(parameters));
pluginInstance.setjoin_file.write(); pluginInstance.setjoin_file.write();
source->sendMessage(*player, Jupiter::StringS::Format("%.*s, your join message is now: %.*s", player->name.size(), player->name.data(), parameters.size(), parameters.ptr())); source->sendMessage(*player, Jupiter::StringS::Format("%.*s, your join message is now: %.*s", player->name.size(), player->name.data(), parameters.size(), parameters.ptr()));
@ -152,15 +135,13 @@ void SetJoinGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player,
else source->sendMessage(*player, "Error: A setjoin message requires steam."_jrs); else source->sendMessage(*player, "Error: A setjoin message requires steam."_jrs);
} }
const Jupiter::ReadableString &SetJoinGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &SetJoinGameCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sets an automatic join message. Syntax: setjoin [message]"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sets an automatic join message. Syntax: setjoin [message]");
return defaultHelp; return defaultHelp;
} }
GAME_COMMAND_INIT(SetJoinGameCommand) GAME_COMMAND_INIT(SetJoinGameCommand)
extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() {
{
return &pluginInstance; return &pluginInstance;
} }

24
src/Plugins/RenX/RenX.Warn/RenX_Warn.cpp

@ -16,6 +16,7 @@
* Written by Jessica James <jessica.aj@outlook.com> * Written by Jessica James <jessica.aj@outlook.com>
*/ */
#include "jessilib/word_split.hpp"
#include "IRC_Bot.h" #include "IRC_Bot.h"
#include "RenX_Server.h" #include "RenX_Server.h"
#include "RenX_PlayerInfo.h" #include "RenX_PlayerInfo.h"
@ -48,7 +49,8 @@ void WarnIRCCommand::create() {
} }
void WarnIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) { void WarnIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) {
if (parameters.wordCount(WHITESPACE) < 2) { auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
if (parameters_split.second.empty()) {
source->sendNotice(nick, "Error: Too Few Parameters. Syntax: Warn <Player> <Reason>"_jrs); source->sendNotice(nick, "Error: Too Few Parameters. Syntax: Warn <Player> <Reason>"_jrs);
return; return;
} }
@ -64,8 +66,8 @@ void WarnIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &cha
return; return;
} }
Jupiter::ReferenceString name = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE); std::string_view name = parameters_split.first;
Jupiter::ReferenceString reason = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE); std::string_view reason = parameters_split.second;
RenX::PlayerInfo *player; RenX::PlayerInfo *player;
for (const auto& server : servers) { for (const auto& server : servers) {
@ -81,13 +83,13 @@ void WarnIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &cha
break; break;
default: default:
server->banPlayer(*player, "Jupiter Bot/RenX.Warn"_jrs, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns), std::chrono::seconds(pluginInstance.m_warnAction)); server->banPlayer(*player, "Jupiter Bot/RenX.Warn"_jrs, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns), std::chrono::seconds(pluginInstance.m_warnAction));
source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been banned from the server for exceeding the warning limit (%d warnings).", player->name.size(), player->name.data(), reason.size(), reason.ptr(), warns)); source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been banned from the server for exceeding the warning limit (%d warnings).", player->name.size(), player->name.data(), reason.size(), reason.data(), warns));
break; break;
} }
} }
else { else {
player->varData[pluginInstance.getName()].set(WARNS_KEY, std::to_string(warns)); player->varData[pluginInstance.getName()].set(WARNS_KEY, std::to_string(warns));
server->sendWarnMessage(*player, Jupiter::StringS::Format("You have been warned by %.*s@IRC for: %.*s. You have %d warnings.", nick.size(), nick.ptr(), reason.size(), reason.ptr(), warns)); server->sendWarnMessage(*player, Jupiter::StringS::Format("You have been warned by %.*s@IRC for: %.*s. You have %d warnings.", nick.size(), nick.ptr(), reason.size(), reason.data(), warns));
source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", player->name.size(), player->name.data(), warns)); source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", player->name.size(), player->name.data(), warns));
} }
} }
@ -112,7 +114,7 @@ void PardonIRCCommand::create() {
} }
void PardonIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) { void PardonIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) {
if (parameters.isEmpty()) { if (parameters.empty()) {
// TODO: this doesn't make sense // TODO: this doesn't make sense
this->trigger(source, channel, nick, nick); this->trigger(source, channel, nick, nick);
return; return;
@ -158,11 +160,13 @@ void WarnGameCommand::create() {
} }
void WarnGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) { void WarnGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
if (parameters.wordCount(WHITESPACE) >= 2) { auto parameters_split = jessilib::word_split_once_view(std::string_view{parameters}, WHITESPACE_SV);
Jupiter::ReferenceString name = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE); if (!parameters_split.second.empty()) {
std::string_view name = parameters_split.first;
std::string_view reason = parameters_split.second;
RenX::PlayerInfo *target = source->getPlayerByPartName(name); RenX::PlayerInfo *target = source->getPlayerByPartName(name);
if (target != nullptr) { if (target != nullptr) {
Jupiter::ReferenceString reason = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE);
int warns = target->varData[pluginInstance.getName()].get<int>(WARNS_KEY) + 1; int warns = target->varData[pluginInstance.getName()].get<int>(WARNS_KEY) + 1;
if (warns > pluginInstance.m_maxWarns) { if (warns > pluginInstance.m_maxWarns) {
switch (pluginInstance.m_warnAction) switch (pluginInstance.m_warnAction)
@ -179,7 +183,7 @@ void WarnGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, co
} }
else { else {
target->varData[pluginInstance.getName()].set(WARNS_KEY, std::to_string(warns)); target->varData[pluginInstance.getName()].set(WARNS_KEY, std::to_string(warns));
source->sendWarnMessage(*target, Jupiter::StringS::Format("You have been warned by %.*s for: %.*s. You have %d warnings.", player->name.size(), player->name.data(), reason.size(), reason.ptr(), warns)); source->sendWarnMessage(*target, Jupiter::StringS::Format("You have been warned by %.*s for: %.*s. You have %d warnings.", player->name.size(), player->name.data(), reason.size(), reason.data(), warns));
source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", target->name.size(), target->name.data(), warns)); source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", target->name.size(), target->name.data(), warns));
} }
} }

6
src/Plugins/SetJoin/SetJoin.cpp

@ -23,13 +23,13 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
void SetJoinPlugin::OnJoin(Jupiter::IRC::Client *server, const Jupiter::ReadableString &chan, const Jupiter::ReadableString &nick) void SetJoinPlugin::OnJoin(Jupiter::IRC::Client *server, std::string_view chan, std::string_view nick)
{ {
std::string_view setjoin = this->config[server->getConfigSection()].get(nick); std::string_view setjoin = this->config[server->getConfigSection()].get(nick);
if (setjoin.empty()) if (setjoin.empty())
server->sendNotice(nick, "No setjoin has been set for you. To set one, use the !setjoin command"_jrs); server->sendNotice(nick, "No setjoin has been set for you. To set one, use the !setjoin command"_jrs);
else else
server->sendMessage(chan, Jupiter::StringS::Format(IRCBOLD IRCCOLOR "07[%.*s]" IRCCOLOR IRCBOLD ": %.*s", nick.size(), nick.ptr(), setjoin.size(), setjoin.data())); server->sendMessage(chan, Jupiter::StringS::Format(IRCBOLD IRCCOLOR "07[%.*s]" IRCCOLOR IRCBOLD ": %.*s", nick.size(), nick.data(), setjoin.size(), setjoin.data()));
} }
SetJoinPlugin pluginInstance; SetJoinPlugin pluginInstance;
@ -70,7 +70,7 @@ void ViewJoinIRCCommand::create()
void ViewJoinIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) void ViewJoinIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters)
{ {
const Jupiter::ReadableString &target = parameters.isEmpty() ? nick : parameters; const Jupiter::ReadableString &target = parameters.empty() ? nick : parameters;
std::string_view setjoin = pluginInstance.setjoin_file[source->getConfigSection()].get(target); std::string_view setjoin = pluginInstance.setjoin_file[source->getConfigSection()].get(target);
if (setjoin.empty()) if (setjoin.empty())

2
src/Plugins/SetJoin/SetJoin.h

@ -27,7 +27,7 @@ class SetJoinPlugin : public Jupiter::Plugin
public: public:
Jupiter::Config &setjoin_file = Jupiter::Plugin::config; Jupiter::Config &setjoin_file = Jupiter::Plugin::config;
void OnJoin(Jupiter::IRC::Client *server, const Jupiter::ReadableString &chan, const Jupiter::ReadableString &nick) override; void OnJoin(Jupiter::IRC::Client *server, std::string_view chan, std::string_view nick) override;
}; };
GENERIC_IRC_COMMAND(SetJoinIRCCommand) GENERIC_IRC_COMMAND(SetJoinIRCCommand)

Loading…
Cancel
Save