Browse Source

Remove ArrayList; update Jupiter submodule; various stylistic cleanups

release/1.1
Jessica James 3 years ago
parent
commit
3b4d7ac12a
  1. 7
      src/Bot/include/Console_Command.h
  2. 28
      src/Bot/include/IRC_Bot.h
  3. 18
      src/Bot/include/IRC_Command.h
  4. 14
      src/Bot/include/ServerManager.h
  5. 35
      src/Bot/src/Console_Command.cpp
  6. 166
      src/Bot/src/IRC_Bot.cpp
  7. 164
      src/Bot/src/IRC_Command.cpp
  8. 121
      src/Bot/src/Main.cpp
  9. 163
      src/Bot/src/ServerManager.cpp
  10. 2
      src/Jupiter
  11. 69
      src/Plugins/CoreCommands/CoreCommands.cpp
  12. 39
      src/Plugins/IRC.Core/IRC_Core.cpp
  13. 4
      src/Plugins/IRC.Core/IRC_Core.h
  14. 63
      src/Plugins/PluginManager/PluginManager.cpp
  15. 1284
      src/Plugins/RenX/RenX.Commands/RenX_Commands.cpp
  16. 10
      src/Plugins/RenX/RenX.Commands/RenX_Commands.h
  17. 152
      src/Plugins/RenX/RenX.Core/RenX_BanDatabase.cpp
  18. 16
      src/Plugins/RenX/RenX.Core/RenX_BanDatabase.h
  19. 185
      src/Plugins/RenX/RenX.Core/RenX_Core.cpp
  20. 25
      src/Plugins/RenX/RenX.Core/RenX_Core.h
  21. 139
      src/Plugins/RenX/RenX.Core/RenX_ExemptionDatabase.cpp
  22. 15
      src/Plugins/RenX/RenX.Core/RenX_ExemptionDatabase.h
  23. 82
      src/Plugins/RenX/RenX.Core/RenX_GameCommand.cpp
  24. 6
      src/Plugins/RenX/RenX.Core/RenX_GameCommand.h
  25. 398
      src/Plugins/RenX/RenX.Core/RenX_LadderDatabase.cpp
  26. 29
      src/Plugins/RenX/RenX.Core/RenX_LadderDatabase.h
  27. 397
      src/Plugins/RenX/RenX.Core/RenX_Plugin.cpp
  28. 2682
      src/Plugins/RenX/RenX.Core/RenX_Server.cpp
  29. 166
      src/Plugins/RenX/RenX.Core/RenX_Server.h
  30. 14
      src/Plugins/RenX/RenX.Core/RenX_Tags.cpp
  31. 56
      src/Plugins/RenX/RenX.Greetings/RenX_Greetings.cpp
  32. 10
      src/Plugins/RenX/RenX.Greetings/RenX_Greetings.h
  33. 201
      src/Plugins/RenX/RenX.Ladder.Web/RenX_Ladder_Web.cpp
  34. 88
      src/Plugins/RenX/RenX.Ladder/RenX_Ladder.cpp
  35. 24
      src/Plugins/RenX/RenX.Listen/RenX_Listen.cpp
  36. 15
      src/Plugins/RenX/RenX.Medals/RenX_Medals.cpp
  37. 168
      src/Plugins/RenX/RenX.ModSystem/RenX_ModSystem.cpp
  38. 20
      src/Plugins/RenX/RenX.ModSystem/RenX_ModSystem.h
  39. 344
      src/Plugins/RenX/RenX.ServerList/RenX_ServerList.cpp
  40. 8
      src/Plugins/RenX/RenX.ServerList/RenX_ServerList.h
  41. 213
      src/Plugins/RenX/RenX.Warn/RenX_Warn.cpp
  42. 6
      src/Plugins/RenX/RenX.Warn/RenX_Warn.h

7
src/Bot/include/Console_Command.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2015 Jessica James. * Copyright (C) 2013-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -25,7 +25,6 @@
*/ */
#include "Jupiter/GenericCommand.h" #include "Jupiter/GenericCommand.h"
#include "Jupiter/ArrayList.h"
#include "Jupiter_Bot.h" #include "Jupiter_Bot.h"
class ConsoleCommand; class ConsoleCommand;
@ -36,8 +35,8 @@ class ConsoleCommand;
#pragma warning(disable: 4251) #pragma warning(disable: 4251)
#endif #endif
/** Console command list */ /** Console command list; weak pointers */
JUPITER_BOT_API extern Jupiter::ArrayList<ConsoleCommand> *consoleCommands; JUPITER_BOT_API extern std::vector<ConsoleCommand*>& consoleCommands;
/** /**
* @brief Provides the basis for console commands. * @brief Provides the basis for console commands.

28
src/Bot/include/IRC_Bot.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2016 Jessica James. * Copyright (C) 2013-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -26,7 +26,6 @@
#include "Jupiter_Bot.h" #include "Jupiter_Bot.h"
#include "Jupiter/IRC_Client.h" #include "Jupiter/IRC_Client.h"
#include "Jupiter/ArrayList.h"
#include "Jupiter/Rehash.h" #include "Jupiter/Rehash.h"
#include "Jupiter/String.hpp" #include "Jupiter/String.hpp"
@ -64,14 +63,6 @@ public:
*/ */
bool freeCommand(const Jupiter::ReadableString &trigger); bool freeCommand(const Jupiter::ReadableString &trigger);
/**
* @brief Gets the index of a command.
*
* @param trigger Trigger of the command to find.
* @return Index of the first match for the trigger if found, -1 otherwise.
*/
int getCommandIndex(const Jupiter::ReadableString &trigger) const;
/** /**
* @return Gets a command. * @return Gets a command.
* *
@ -81,21 +72,21 @@ public:
IRCCommand *getCommand(const Jupiter::ReadableString &trigger) const; IRCCommand *getCommand(const Jupiter::ReadableString &trigger) const;
/** /**
* @brief Creates and returns an ArrayList of IRC Commands with a specified access level. * @brief Creates and returns a vector of IRC Commands with a specified access level.
* *
* @param chan Channel which access levels are set. * @param chan Channel which access levels are set.
* @param access Access level to match. * @param access Access level to match.
* @return An ArrayList containing pointers to all of the matching commands. * @return Vector containing pointers to all of the matching commands.
*/ */
Jupiter::ArrayList<IRCCommand> getAccessCommands(Jupiter::IRC::Client::Channel *chan, int access); std::vector<IRCCommand*> getAccessCommands(Jupiter::IRC::Client::Channel *chan, int access);
/** /**
* @brief Gets the triggers of all the commands in an ArrayList, and adds them to a space-deliminated string. * @brief Gets the triggers of all the commands in a vector, and adds them to a space-deliminated string.
* *
* @param cmds Commands to construct the string with. * @param cmds Commands to construct the string with.
* @return A string containing the triggers of the commands in a space-deliminated list. * @return A string containing the triggers of the commands in a space-deliminated list.
*/ */
static Jupiter::StringL getTriggers(Jupiter::ArrayList<IRCCommand> &cmds); static Jupiter::StringL getTriggers(std::vector<IRCCommand*> &cmds);
/** /**
* @brief Reloads some settings. * @brief Reloads some settings.
@ -115,6 +106,9 @@ public:
/** Destructor for IRC_Bot */ /** Destructor for IRC_Bot */
~IRC_Bot(); ~IRC_Bot();
IRC_Bot& operator=(const IRC_Bot&) = delete;
IRC_Bot(const IRC_Bot&) = delete;
/** Overloaded events from Jupiter::IRC::Client */ /** Overloaded events from Jupiter::IRC::Client */
protected: protected:
@ -122,8 +116,8 @@ protected:
/** Private members for internal usage */ /** Private members for internal usage */
private: private:
Jupiter::ArrayList<IRCCommand> commands; std::vector<std::unique_ptr<IRCCommand>> m_commands;
Jupiter::StringS commandPrefix; Jupiter::StringS m_commandPrefix;
}; };
/** Re-enable warnings */ /** Re-enable warnings */

18
src/Bot/include/IRC_Command.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2016 Jessica James. * Copyright (C) 2013-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -26,7 +26,6 @@
#include "Jupiter/GenericCommand.h" #include "Jupiter/GenericCommand.h"
#include "Jupiter/IRC_Client.h" #include "Jupiter/IRC_Client.h"
#include "Jupiter/ArrayList.h"
#include "Jupiter/String.hpp" #include "Jupiter/String.hpp"
#include "Jupiter_Bot.h" #include "Jupiter_Bot.h"
#include "ServerManager.h" #include "ServerManager.h"
@ -41,7 +40,7 @@ class IRCCommand;
#endif #endif
/** IRC Master Command List */ /** IRC Master Command List */
JUPITER_BOT_API extern Jupiter::ArrayList<IRCCommand> *IRCMasterCommandList; JUPITER_BOT_API extern std::vector<IRCCommand*>& IRCMasterCommandList;
/** /**
* @brief Provides the basis for IRC commands. * @brief Provides the basis for IRC commands.
@ -152,21 +151,20 @@ public:
/** Private members */ /** Private members */
private: private:
int access; /** Default access level */ int m_access; /** Default access level */
struct TypeAccessPair // Both of these vector sets could just be maps
{ struct TypeAccessPair {
int type; int type;
int access; int access;
}; };
Jupiter::ArrayList<IRCCommand::TypeAccessPair> types; /** Access levels for channel types */ std::vector<IRCCommand::TypeAccessPair> m_types; /** Access levels for channel types */
struct ChannelAccessPair struct ChannelAccessPair {
{
Jupiter::StringS channel; Jupiter::StringS channel;
int access; int access;
}; };
Jupiter::ArrayList<IRCCommand::ChannelAccessPair> channels; /** Access levels for specific channels */ std::vector<IRCCommand::ChannelAccessPair> m_channels; /** Access levels for specific channels */
}; };
class JUPITER_BOT_API GenericCommandWrapperIRCCommand : public IRCCommand class JUPITER_BOT_API GenericCommandWrapperIRCCommand : public IRCCommand

14
src/Bot/include/ServerManager.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -24,9 +24,9 @@
* @brief Provides a system for controlling and affecting multiple IRC connections simultaneously. * @brief Provides a system for controlling and affecting multiple IRC connections simultaneously.
*/ */
#include <memory>
#include "Jupiter_Bot.h" #include "Jupiter_Bot.h"
#include "Jupiter/Thinker.h" #include "Jupiter/Thinker.h"
#include "Jupiter/ArrayList.h"
#include "Jupiter/Readable_String.h" #include "Jupiter/Readable_String.h"
/** Forward declarations */ /** Forward declarations */
@ -161,12 +161,16 @@ public:
*/ */
virtual ~ServerManager(); virtual ~ServerManager();
ServerManager() = default;
ServerManager& operator=(const ServerManager&) = delete;
ServerManager(const ServerManager&) = delete;
private: private:
/** Underlying ArrayList of servers */ /** Underlying vector of servers */
Jupiter::ArrayList<IRC_Bot> servers; std::vector<std::unique_ptr<IRC_Bot>> m_servers;
/** Config to read data from */ /** Config to read data from */
Jupiter::Config *m_config = Jupiter::g_config; Jupiter::Config* m_config = Jupiter::g_config;
}; };
/** Pointer to an instance of the server manager. Note: DO NOT DELETE OR FREE THIS POINTER. */ /** Pointer to an instance of the server manager. Note: DO NOT DELETE OR FREE THIS POINTER. */

35
src/Bot/src/Console_Command.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2015 Jessica James. * Copyright (C) 2013-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -18,33 +18,28 @@
#include "Console_Command.h" #include "Console_Command.h"
Jupiter::ArrayList<ConsoleCommand> _consoleCommands; std::vector<ConsoleCommand*> g_consoleCommands;
Jupiter::ArrayList<ConsoleCommand> *consoleCommands = &_consoleCommands; std::vector<ConsoleCommand*>& consoleCommands = g_consoleCommands;
ConsoleCommand::ConsoleCommand() ConsoleCommand::ConsoleCommand() {
{ consoleCommands.push_back(this);
consoleCommands->add(this);
} }
ConsoleCommand::~ConsoleCommand() ConsoleCommand::~ConsoleCommand() {
{ for (auto itr = consoleCommands.begin(); itr != consoleCommands.end(); ++itr) {
for (size_t i = 0; i != consoleCommands->size(); i++) if (*itr == this) {
{ consoleCommands.erase(itr);
if (consoleCommands->get(i) == this)
{
consoleCommands->remove(i);
break; break;
} }
} }
} }
ConsoleCommand *getConsoleCommand(const Jupiter::ReadableString &trigger) ConsoleCommand* getConsoleCommand(const Jupiter::ReadableString &trigger) {
{ for (const auto& command : consoleCommands) {
for (size_t i = 0; i != consoleCommands->size(); i++) if (command->matches(trigger)) {
{ return command;
ConsoleCommand *cmd = consoleCommands->get(i); }
if (cmd->matches(trigger))
return cmd;
} }
return nullptr; return nullptr;
} }

166
src/Bot/src/IRC_Bot.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2017 Jessica James. * Copyright (C) 2013-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -27,94 +27,85 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
IRC_Bot::IRC_Bot(Jupiter::Config *in_primary_section, Jupiter::Config *in_secondary_section) : Client(in_primary_section, in_secondary_section) IRC_Bot::IRC_Bot(Jupiter::Config *in_primary_section, Jupiter::Config *in_secondary_section)
{ : Client(in_primary_section, in_secondary_section) {
IRC_Bot::commandPrefix = this->readConfigValue("Prefix"_jrs); m_commandPrefix = this->readConfigValue("Prefix"_jrs);
for (size_t i = 0; i != IRCMasterCommandList->size(); i++) for (const auto& command : IRCMasterCommandList) {
IRC_Bot::commands.add(IRCMasterCommandList->get(i)->copy()); m_commands.emplace_back(command->copy());
}
IRC_Bot::setCommandAccessLevels(); setCommandAccessLevels();
} }
IRC_Bot::~IRC_Bot() IRC_Bot::~IRC_Bot() {
{ if (IRCCommand::selected_server == this) {
if (IRCCommand::selected_server == this)
IRCCommand::selected_server = nullptr; IRCCommand::selected_server = nullptr;
if (IRCCommand::active_server == this) }
IRCCommand::active_server = IRCCommand::selected_server;
IRC_Bot::commands.emptyAndDelete(); if (IRCCommand::active_server == this) {
IRCCommand::active_server = IRCCommand::selected_server;
}
} }
void IRC_Bot::addCommand(IRCCommand *in_command) void IRC_Bot::addCommand(IRCCommand *in_command) {
{ m_commands.emplace_back(in_command);
IRC_Bot::commands.add(in_command); setCommandAccessLevels(in_command);
IRC_Bot::setCommandAccessLevels(in_command);
} }
bool IRC_Bot::freeCommand(const Jupiter::ReadableString &trigger) bool IRC_Bot::freeCommand(const Jupiter::ReadableString &trigger) {
{ for (auto itr = m_commands.begin(); itr != m_commands.end(); ++itr) {
for (size_t i = 0; i != IRC_Bot::commands.size(); i++) if ((*itr)->matches(trigger)) {
{ m_commands.erase(itr);
if (IRC_Bot::commands.get(i)->matches(trigger))
{
delete IRC_Bot::commands.remove(i);
return true; return true;
} }
} }
return false; return false;
} }
int IRC_Bot::getCommandIndex(const Jupiter::ReadableString &trigger) const IRCCommand* IRC_Bot::getCommand(const Jupiter::ReadableString &trigger) const {
{ for (const auto& command : m_commands) {
for (size_t i = 0; i != IRC_Bot::commands.size(); i++) if (command->matches(trigger)) {
if (IRC_Bot::commands.get(i)->matches(trigger)) return command.get();
return i; }
return -1; }
}
IRCCommand *IRC_Bot::getCommand(const Jupiter::ReadableString &trigger) const return nullptr;
{
int i = IRC_Bot::getCommandIndex(trigger);
if (i < 0) return nullptr;
return IRC_Bot::commands.get(i);
} }
Jupiter::ArrayList<IRCCommand> IRC_Bot::getAccessCommands(Jupiter::IRC::Client::Channel *chan, int access) std::vector<IRCCommand*> IRC_Bot::getAccessCommands(Jupiter::IRC::Client::Channel *chan, int access) {
{ std::vector<IRCCommand*> result;
Jupiter::ArrayList<IRCCommand> r; for (const auto& command : m_commands) {
for (size_t i = 0; i != IRC_Bot::commands.size(); i++) if (command->getAccessLevel(chan) == access) {
{ result.push_back(command.get());
IRCCommand *cmd = IRC_Bot::commands.get(i); }
if (cmd->getAccessLevel(chan) == access)
r.add(cmd);
} }
return r;
return result;
} }
Jupiter::StringL IRC_Bot::getTriggers(Jupiter::ArrayList<IRCCommand> &cmds) // TODO: This isn't really needed on here
{ Jupiter::StringL IRC_Bot::getTriggers(std::vector<IRCCommand*> &commands) {
Jupiter::StringL r; Jupiter::StringL result;
for (size_t i = 0; i < cmds.size(); i++) for (const auto& command : commands) {
{ result += command->getTrigger();
r += cmds[i]->getTrigger(); result += ' ';
r += ' ';
} }
return r;
return result;
} }
void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command) void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command) {
{ auto set_command_access_levels = [this, in_command](Jupiter::Config *in_section) {
auto set_command_access_levels = [this, in_command](Jupiter::Config *in_section) if (in_section == nullptr) {
{
if (in_section == nullptr)
return; return;
}
Jupiter::Config *section = in_section->getSection("Commands"_jrs); Jupiter::Config *section = in_section->getSection("Commands"_jrs);
if (section == nullptr) {
if (section == nullptr)
return; return;
}
for (auto& entry : section->getTable()) { for (auto& entry : section->getTable()) {
size_t tmp_index; size_t tmp_index;
@ -122,8 +113,7 @@ void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command)
IRCCommand *command; IRCCommand *command;
tmp_index = entry.first.find('.'); tmp_index = entry.first.find('.');
if (tmp_index != Jupiter::INVALID_INDEX) if (tmp_index != Jupiter::INVALID_INDEX) {
{
// non-default access assignment // non-default access assignment
tmp_key.set(entry.first.ptr(), tmp_index); tmp_key.set(entry.first.ptr(), tmp_index);
@ -131,16 +121,15 @@ void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command)
tmp_sub_key = entry.first; tmp_sub_key = entry.first;
tmp_sub_key.shiftRight(tmp_index + 1); tmp_sub_key.shiftRight(tmp_index + 1);
if (tmp_sub_key.findi("Type."_jrs) == 0) if (tmp_sub_key.findi("Type."_jrs) == 0) {
{
tmp_sub_key.shiftRight(5); // shift beyond "Type." tmp_sub_key.shiftRight(5); // shift beyond "Type."
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(), entry.second.asInt()); command->setAccessLevel(tmp_sub_key.asInt(), entry.second.asInt());
}
} }
else if (tmp_sub_key.findi("Channel."_jrs) == 0) else if (tmp_sub_key.findi("Channel."_jrs) == 0) {
{
tmp_sub_key.shiftRight(8); // shift beyond "Channel." tmp_sub_key.shiftRight(8); // shift beyond "Channel."
// Assign access level to command (if command exists) // Assign access level to command (if command exists)
@ -149,8 +138,7 @@ void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command)
command->setAccessLevel(tmp_sub_key, entry.second.asInt()); command->setAccessLevel(tmp_sub_key, entry.second.asInt());
} }
} }
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))
@ -159,48 +147,46 @@ void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command)
}; };
}; };
set_command_access_levels(this->getSecondaryConfigSection()); set_command_access_levels(getSecondaryConfigSection());
set_command_access_levels(this->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(const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &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; Jupiter::ReferenceString msg = message;
while (msg.isNotEmpty() && isspace(msg[0])) while (msg.isNotEmpty() && isspace(msg[0])) {
msg.shiftRight(1); msg.shiftRight(1);
}
if (IRC_Bot::commandPrefix.size() <= msg.size()) if (m_commandPrefix.size() <= msg.size()) {
{
bool matchesPrefix = true; bool matchesPrefix = true;
size_t i; size_t i;
for (i = 0; i != IRC_Bot::commandPrefix.size(); i++) for (i = 0; i != m_commandPrefix.size(); i++) {
{ if (toupper(msg.get(0)) != toupper(m_commandPrefix[i])) {
if (toupper(msg.get(0)) != toupper(IRC_Bot::commandPrefix[i]))
{
matchesPrefix = false; matchesPrefix = false;
break; break;
} }
msg.shiftRight(1); msg.shiftRight(1);
} }
if (matchesPrefix) if (matchesPrefix) {
{
Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(msg, 0, WHITESPACE);; Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(msg, 0, WHITESPACE);;
Jupiter::ReferenceString parameters = Jupiter::ReferenceString::gotoWord(msg, 1, WHITESPACE); Jupiter::ReferenceString parameters = Jupiter::ReferenceString::gotoWord(msg, 1, WHITESPACE);
IRCCommand *cmd = IRC_Bot::getCommand(command); IRCCommand *cmd = getCommand(command);
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);
if (command_access < 0) if (command_access < 0) {
this->sendNotice(nick, "Error: Command disabled."_jrs); this->sendNotice(nick, "Error: Command disabled."_jrs);
else if (Jupiter::IRC::Client::getAccessLevel(*channel, nick) < command_access) }
else if (Jupiter::IRC::Client::getAccessLevel(*channel, nick) < command_access) {
this->sendNotice(nick, "Access Denied."_jrs); this->sendNotice(nick, "Access Denied."_jrs);
else }
else {
cmd->trigger(this, in_channel, nick, parameters); cmd->trigger(this, in_channel, nick, parameters);
}
IRCCommand::active_server = IRCCommand::selected_server; IRCCommand::active_server = IRCCommand::selected_server;
} }
} }

164
src/Bot/src/IRC_Command.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2016 Jessica James. * Copyright (C) 2013-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -18,42 +18,37 @@
#include "IRC_Command.h" #include "IRC_Command.h"
Jupiter::ArrayList<IRCCommand> _IRCMasterCommandList; std::vector<IRCCommand*> g_IRCMasterCommandList;
Jupiter::ArrayList<IRCCommand> *IRCMasterCommandList = &_IRCMasterCommandList; std::vector<IRCCommand*>& IRCMasterCommandList = g_IRCMasterCommandList;
/** IRCCommand */ /** IRCCommand */
IRCCommand::IRCCommand() IRCCommand::IRCCommand() {
{ m_access = 0;
IRCCommand::access = 0; IRCMasterCommandList.push_back(this);
IRCMasterCommandList->add(this);
} }
IRCCommand::IRCCommand(const IRCCommand &command) IRCCommand::IRCCommand(const IRCCommand &command) {
{ m_access = command.m_access;
IRCCommand::access = command.access;
size_t i;
for (i = 0; i < command.channels.size(); i++) for (const auto& channel : command.m_channels) {
IRCCommand::channels.add(new IRCCommand::ChannelAccessPair(*command.channels.get(i))); m_channels.emplace_back(channel);
}
for (i = 0; i < command.types.size(); i++) for (const auto& type : command.m_types) {
IRCCommand::types.add(new IRCCommand::TypeAccessPair(*command.types.get(i))); m_types.emplace_back(type);
}
} }
IRCCommand::~IRCCommand() IRCCommand::~IRCCommand() {
{ // Remove any weak references to this
for (size_t i = 0; i != IRCMasterCommandList->size(); i++) for (auto itr = IRCMasterCommandList.begin(); itr != IRCMasterCommandList.end(); ++itr) {
{ if (*itr == this) {
if (IRCMasterCommandList->get(i) == this)
{
serverManager->removeCommand(this); serverManager->removeCommand(this);
IRCMasterCommandList->remove(i); IRCMasterCommandList.erase(itr);
break; break;
} }
} }
IRCCommand::channels.emptyAndDelete();
IRCCommand::types.emptyAndDelete();
} }
IRC_Bot *IRCCommand::active_server = nullptr; IRC_Bot *IRCCommand::active_server = nullptr;
@ -61,102 +56,92 @@ IRC_Bot *IRCCommand::selected_server = nullptr;
// IRC Command Functions // IRC Command Functions
int IRCCommand::getAccessLevel() int IRCCommand::getAccessLevel() {
{ return m_access;
return IRCCommand::access;
} }
int IRCCommand::getAccessLevel(int type) int IRCCommand::getAccessLevel(int type) {
{ for (const auto& pair : m_types) {
for (size_t i = 0; i != IRCCommand::types.size(); i++) if (pair.type == type) {
if (IRCCommand::types.get(i)->type == type) return pair.access;
return IRCCommand::types.get(i)->access; }
return IRCCommand::access; }
return m_access;
} }
int IRCCommand::getAccessLevel(const Jupiter::ReadableString &channel) int IRCCommand::getAccessLevel(const Jupiter::ReadableString &channel) {
{ for (const auto& pair : m_channels) {
IRCCommand::ChannelAccessPair *pair; if (pair.channel.equalsi(channel)) {
for (size_t i = 0; i != IRCCommand::channels.size(); i++) return pair.access;
{ }
pair = IRCCommand::channels.get(i);
if (pair->channel.equalsi(channel))
return pair->access;
} }
return IRCCommand::access;
return m_access;
} }
int IRCCommand::getAccessLevel(Jupiter::IRC::Client::Channel *channel) int IRCCommand::getAccessLevel(Jupiter::IRC::Client::Channel *channel) {
{ for (const auto& pair : m_channels) {
IRCCommand::ChannelAccessPair *pair; if (pair.channel.equalsi(channel->getName())) {
for (size_t i = 0; i != IRCCommand::channels.size(); i++) return pair.access;
{ }
pair = IRCCommand::channels.get(i);
if (pair->channel.equalsi(channel->getName()))
return pair->access;
} }
for (size_t i = 0; i != IRCCommand::types.size(); i++) for (const auto& pair : m_types) {
if (IRCCommand::types.get(i)->type == channel->getType()) if (pair.type == channel->getType()) {
return IRCCommand::types.get(i)->access; return pair.access;
}
}
return IRCCommand::access; return m_access;
} }
void IRCCommand::setAccessLevel(int accessLevel) void IRCCommand::setAccessLevel(int accessLevel) {
{ m_access = accessLevel;
IRCCommand::access = accessLevel;
} }
void IRCCommand::setAccessLevel(int type, int accessLevel) void IRCCommand::setAccessLevel(int type, int accessLevel) {
{ m_types.push_back({type, accessLevel});
IRCCommand::TypeAccessPair *pair = new IRCCommand::TypeAccessPair();
pair->type = type;
pair->access = accessLevel;
IRCCommand::types.add(pair);
} }
void IRCCommand::setAccessLevel(const Jupiter::ReadableString &channel, int accessLevel) void IRCCommand::setAccessLevel(const Jupiter::ReadableString &channel, int accessLevel) {
{ m_channels.push_back({ channel, accessLevel });
IRCCommand::ChannelAccessPair *pair = new IRCCommand::ChannelAccessPair();
pair->channel = channel;
pair->access = accessLevel;
IRCCommand::channels.add(pair);
} }
void IRCCommand::create() void IRCCommand::create() {
{
} }
/** GenericCommandWrapperIRCCommand */ /** GenericCommandWrapperIRCCommand */
GenericCommandWrapperIRCCommand::GenericCommandWrapperIRCCommand(const GenericCommandWrapperIRCCommand &in_command) : IRCCommand(in_command) GenericCommandWrapperIRCCommand::GenericCommandWrapperIRCCommand(const GenericCommandWrapperIRCCommand &in_command)
{ : IRCCommand(in_command) {
GenericCommandWrapperIRCCommand::m_command = in_command.m_command; m_command = in_command.m_command;
// Copy triggers // Copy triggers
for (size_t index = 0; index != GenericCommandWrapperIRCCommand::m_command->getTriggerCount(); ++index) for (size_t index = 0; index != m_command->getTriggerCount(); ++index) {
this->addTrigger(GenericCommandWrapperIRCCommand::m_command->getTrigger(index)); this->addTrigger(m_command->getTrigger(index));
}
} }
GenericCommandWrapperIRCCommand::GenericCommandWrapperIRCCommand(Jupiter::GenericCommand &in_command) : IRCCommand() GenericCommandWrapperIRCCommand::GenericCommandWrapperIRCCommand(Jupiter::GenericCommand &in_command)
{ : IRCCommand() {
GenericCommandWrapperIRCCommand::m_command = &in_command; m_command = &in_command;
// Copy triggers // Copy triggers
for (size_t index = 0; index != GenericCommandWrapperIRCCommand::m_command->getTriggerCount(); ++index) for (size_t index = 0; index != m_command->getTriggerCount(); ++index) {
this->addTrigger(GenericCommandWrapperIRCCommand::m_command->getTrigger(index)); this->addTrigger(m_command->getTrigger(index));
}
if (serverManager != nullptr) if (serverManager != nullptr) {
serverManager->addCommand(this); serverManager->addCommand(this);
}
} }
// GenericCommandWrapperIRCCommand functions // GenericCommandWrapperIRCCommand functions
void GenericCommandWrapperIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &in_nick, const Jupiter::ReadableString &in_parameters) void GenericCommandWrapperIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &in_nick, const Jupiter::ReadableString &in_parameters) {
{
Jupiter::GenericCommand::ResponseLine *del; Jupiter::GenericCommand::ResponseLine *del;
Jupiter::GenericCommand::ResponseLine *result = GenericCommandWrapperIRCCommand::m_command->trigger(in_parameters); Jupiter::GenericCommand::ResponseLine *result = m_command->trigger(in_parameters);
while (result != nullptr) while (result != nullptr)
{ {
@ -181,17 +166,14 @@ void GenericCommandWrapperIRCCommand::trigger(IRC_Bot *source, const Jupiter::Re
} }
} }
const Jupiter::ReadableString &GenericCommandWrapperIRCCommand::getHelp(const Jupiter::ReadableString &parameters) const Jupiter::ReadableString &GenericCommandWrapperIRCCommand::getHelp(const Jupiter::ReadableString &parameters) {
{
return GenericCommandWrapperIRCCommand::m_command->getHelp(parameters); return GenericCommandWrapperIRCCommand::m_command->getHelp(parameters);
} }
IRCCommand *GenericCommandWrapperIRCCommand::copy() IRCCommand *GenericCommandWrapperIRCCommand::copy() {
{
return new GenericCommandWrapperIRCCommand(*this); return new GenericCommandWrapperIRCCommand(*this);
} }
const Jupiter::GenericCommand &GenericCommandWrapperIRCCommand::getGenericCommand() const const Jupiter::GenericCommand &GenericCommandWrapperIRCCommand::getGenericCommand() const {
{
return *GenericCommandWrapperIRCCommand::m_command; return *GenericCommandWrapperIRCCommand::m_command;
} }

121
src/Bot/src/Main.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2013-2017 Jessica James. * Copyright (C) 2013-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -44,8 +44,7 @@ std::chrono::steady_clock::time_point Jupiter::g_start_time = std::chrono::stead
#define INPUT_BUFFER_SIZE 2048 #define INPUT_BUFFER_SIZE 2048
struct ConsoleInput struct ConsoleInput {
{
Jupiter::String input; Jupiter::String input;
std::mutex input_mutex; std::mutex input_mutex;
bool awaiting_processing = false; bool awaiting_processing = false;
@ -53,23 +52,19 @@ struct ConsoleInput
ConsoleInput() : input(INPUT_BUFFER_SIZE) {} ConsoleInput() : input(INPUT_BUFFER_SIZE) {}
} console_input; } console_input;
void onTerminate() void onTerminate() {
{
puts("Terminate signal received..."); puts("Terminate signal received...");
} }
void onExit() void onExit() {
{
puts("Exit signal received; Cleaning up..."); puts("Exit signal received; Cleaning up...");
Jupiter::Socket::cleanup(); Jupiter::Socket::cleanup();
puts("Clean-up complete. Closing..."); puts("Clean-up complete. Closing...");
} }
void inputLoop() void inputLoop() {
{
std::string input; std::string input;
while (ftell(stdin) != -1 || errno != EBADF) while (ftell(stdin) != -1 || errno != EBADF) {
{
std::getline(std::cin, input); std::getline(std::cin, input);
check_input_processing: check_input_processing:
@ -88,13 +83,45 @@ void inputLoop()
} }
} }
int main(int argc, const char **args) [[noreturn]] void main_loop() {
{ Jupiter::ReferenceString command;
size_t index;
while (1) {
index = 0;
while (index < Jupiter::plugins.size()) {
if (Jupiter::plugins[index]->shouldRemove() || Jupiter::plugins[index]->think() != 0) {
Jupiter::Plugin::free(index);
}
else {
++index;
}
}
Jupiter::Timer::check();
if (console_input.input_mutex.try_lock()) {
if (console_input.awaiting_processing) {
console_input.awaiting_processing = false;
command = Jupiter::ReferenceString::getWord(console_input.input, 0, WHITESPACE);
ConsoleCommand *cmd = getConsoleCommand(command);
if (cmd != nullptr) {
cmd->trigger(Jupiter::ReferenceString::gotoWord(console_input.input, 1, WHITESPACE));
}
else {
printf("Error: Command \"%.*s\" not found." ENDL, command.size(), command.ptr());
}
}
console_input.input_mutex.unlock();
}
std::this_thread::sleep_for((std::chrono::milliseconds(1)));
}
}
int main(int argc, const char **args) {
atexit(onExit); atexit(onExit);
std::set_terminate(onTerminate); std::set_terminate(onTerminate);
std::thread inputThread(inputLoop); std::thread inputThread(inputLoop);
Jupiter::ReferenceString command, plugins_directory, configs_directory; Jupiter::ReferenceString plugins_directory, configs_directory;
size_t index;
#if defined SIGPIPE #if defined SIGPIPE
std::signal(SIGPIPE, SIG_IGN); std::signal(SIGPIPE, SIG_IGN);
@ -110,10 +137,8 @@ int main(int argc, const char **args)
puts(Jupiter::copyright); puts(Jupiter::copyright);
const char *configFileName = "Config.ini"; const char *configFileName = "Config.ini";
for (int i = 1; i < argc; i++) for (int i = 1; i < argc; i++) {
{ if ("-help"_jrs.equalsi(args[i])) {
if ("-help"_jrs.equalsi(args[i]))
{
puts("Help coming soon, to a theatre near you!"); puts("Help coming soon, to a theatre near you!");
return 0; return 0;
} }
@ -132,8 +157,7 @@ int main(int argc, const char **args)
std::chrono::steady_clock::time_point load_start = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point load_start = std::chrono::steady_clock::now();
puts("Loading config file..."); puts("Loading config file...");
if (!o_config.read(configFileName)) if (!o_config.read(configFileName)) {
{
puts("Unable to read config file. Closing..."); puts("Unable to read config file. Closing...");
exit(0); exit(0);
} }
@ -148,14 +172,12 @@ int main(int argc, const char **args)
if (configs_directory.isEmpty()) if (configs_directory.isEmpty())
configs_directory = o_config.get("ConfigsDirectory"_jrs); configs_directory = o_config.get("ConfigsDirectory"_jrs);
if (plugins_directory.isNotEmpty()) if (plugins_directory.isNotEmpty()) {
{
Jupiter::Plugin::setDirectory(plugins_directory); Jupiter::Plugin::setDirectory(plugins_directory);
printf("Plugins will be loaded from \"%.*s\"." ENDL, plugins_directory.size(), plugins_directory.ptr()); printf("Plugins will be loaded from \"%.*s\"." ENDL, plugins_directory.size(), plugins_directory.ptr());
} }
if (configs_directory.isNotEmpty()) if (configs_directory.isNotEmpty()) {
{
Jupiter::Plugin::setConfigDirectory(configs_directory); Jupiter::Plugin::setConfigDirectory(configs_directory);
printf("Plugin configs will be loaded from \"%.*s\"." ENDL, configs_directory.size(), configs_directory.ptr()); printf("Plugin configs will be loaded from \"%.*s\"." ENDL, configs_directory.size(), configs_directory.ptr());
} }
@ -164,16 +186,14 @@ int main(int argc, const char **args)
const Jupiter::ReadableString &pluginList = o_config.get("Plugins"_jrs); const Jupiter::ReadableString &pluginList = o_config.get("Plugins"_jrs);
if (pluginList.isEmpty()) if (pluginList.isEmpty())
puts("No plugins to load!"); puts("No plugins to load!");
else else {
{
// initialize plugins // initialize plugins
unsigned int nPlugins = pluginList.wordCount(WHITESPACE); unsigned int nPlugins = pluginList.wordCount(WHITESPACE);
printf("Attempting to load %u plugins..." ENDL, nPlugins); printf("Attempting to load %u plugins..." ENDL, nPlugins);
bool load_success; bool load_success;
for (unsigned int i = 0; i < nPlugins; i++) for (unsigned int i = 0; i < nPlugins; i++) {
{
Jupiter::ReferenceString plugin = Jupiter::ReferenceString::getWord(pluginList, i, WHITESPACE); Jupiter::ReferenceString plugin = Jupiter::ReferenceString::getWord(pluginList, i, WHITESPACE);
load_start = std::chrono::steady_clock::now(); load_start = std::chrono::steady_clock::now();
@ -187,43 +207,20 @@ int main(int argc, const char **args)
} }
// OnPostInitialize // OnPostInitialize
for (index = 0; index != Jupiter::plugins->size(); ++index) for (const auto& plugin : Jupiter::plugins) {
Jupiter::plugins->get(index)->OnPostInitialize(); plugin->OnPostInitialize();
}
} }
printf("Initialization completed in %f milliseconds." ENDL, static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - Jupiter::g_start_time).count()) / 1000.0 ); printf("Initialization completed in %f milliseconds." ENDL, static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - Jupiter::g_start_time).count()) / 1000.0 );
if (consoleCommands->size() > 0) if (!consoleCommands.empty()) {
printf("%zu Console Commands have been initialized%s" ENDL, consoleCommands->size(), getConsoleCommand("help"_jrs) == nullptr ? "." : "; type \"help\" for more information."); printf("%zu Console Commands have been initialized%s" ENDL, consoleCommands.size(), getConsoleCommand("help"_jrs) == nullptr ? "." : "; type \"help\" for more information.");
if (IRCMasterCommandList->size() > 0)
printf("%zu IRC Commands have been loaded into the master list." ENDL, IRCMasterCommandList->size());
while (1)
{
index = 0;
while (index < Jupiter::plugins->size())
if (Jupiter::plugins->get(index)->shouldRemove() || Jupiter::plugins->get(index)->think() != 0)
Jupiter::Plugin::free(index);
else
++index;
Jupiter::Timer::check();
if (console_input.input_mutex.try_lock())
{
if (console_input.awaiting_processing)
{
console_input.awaiting_processing = false;
command = Jupiter::ReferenceString::getWord(console_input.input, 0, WHITESPACE);
ConsoleCommand *cmd = getConsoleCommand(command);
if (cmd != nullptr)
cmd->trigger(Jupiter::ReferenceString::gotoWord(console_input.input, 1, WHITESPACE));
else
printf("Error: Command \"%.*s\" not found." ENDL, command.size(), command.ptr());
}
console_input.input_mutex.unlock();
}
std::this_thread::sleep_for((std::chrono::milliseconds(1)));
} }
if (!IRCMasterCommandList.empty()) {
printf("%zu IRC Commands have been loaded into the master list." ENDL, IRCMasterCommandList.size());
}
main_loop();
return 0; return 0;
} }

163
src/Bot/src/ServerManager.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2016 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -23,148 +23,129 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
ServerManager _serverManager; ServerManager g_serverManager;
ServerManager *serverManager = &_serverManager; ServerManager *serverManager = &g_serverManager;
int ServerManager::think() int ServerManager::think() {
{ for (auto itr = m_servers.begin(); itr != m_servers.end();) {
for (size_t i = 0; i < ServerManager::servers.size(); i++) if ((*itr)->think() != 0) {
{ itr = m_servers.erase(itr + 1);
IRC_Bot *server = ServerManager::servers.get(i); continue;
if (server->think() != 0) delete ServerManager::servers.remove(i); }
++itr;
} }
return ServerManager::servers.size() != 0;
return m_servers.size() != 0;
} }
size_t ServerManager::addCommand(IRCCommand *command) size_t ServerManager::addCommand(IRCCommand *command) {
{ for (const auto& server : m_servers) {
for (size_t i = 0; i != ServerManager::servers.size(); i++)
{
IRC_Bot *server = ServerManager::servers.get(i);
server->addCommand(command->copy()); server->addCommand(command->copy());
} }
return ServerManager::servers.size();
return m_servers.size();
} }
size_t ServerManager::removeCommand(IRCCommand *command) size_t ServerManager::removeCommand(IRCCommand *command) {
{ size_t result = 0;
size_t r = 0; for (const auto& server : m_servers) {
for (size_t i = 0; i != ServerManager::servers.size(); i++) if (server->freeCommand(command->getTrigger())) {
{ ++result;
IRC_Bot *server = ServerManager::servers.get(i); }
if (server->freeCommand(command->getTrigger())) r++;
} }
return r;
return result;
} }
size_t ServerManager::removeCommand(const Jupiter::ReadableString &command) size_t ServerManager::removeCommand(const Jupiter::ReadableString &command) {
{ size_t result = 0;
size_t r = 0; for (const auto& server : m_servers) {
for (size_t i = 0; i != ServerManager::servers.size(); i++) if (server->freeCommand(command)) {
{ ++result;
IRC_Bot *server = ServerManager::servers.get(i); }
if (server->freeCommand(command)) r++;
} }
return r;
}
void ServerManager::OnConfigRehash() return result;
{ }
IRC_Bot *server;
for (size_t index = 0; index != ServerManager::servers.size(); ++index)
{
server = ServerManager::servers.get(index);
void ServerManager::OnConfigRehash() {
for (const auto& server : m_servers) {
server->setPrimaryConfigSection(m_config->getSection(server->getConfigSection())); server->setPrimaryConfigSection(m_config->getSection(server->getConfigSection()));
server->setSecondaryConfigSection(m_config->getSection("Defualt"_jrs)); server->setSecondaryConfigSection(m_config->getSection("Defualt"_jrs));
server->setCommandAccessLevels(); server->setCommandAccessLevels();
} }
} }
size_t ServerManager::syncCommands() size_t ServerManager::syncCommands() {
{ for (const auto& server : m_servers) {
for (size_t i = 0; i != ServerManager::servers.size(); i++)
{
IRC_Bot *server = ServerManager::servers.get(i);
server->setCommandAccessLevels(); server->setCommandAccessLevels();
} }
return ServerManager::servers.size();
return m_servers.size();
} }
IRC_Bot *ServerManager::getServer(const Jupiter::ReadableString &serverConfig) IRC_Bot *ServerManager::getServer(const Jupiter::ReadableString &serverConfig) {
{ for (const auto& server : m_servers) {
for (size_t i = 0; i != ServerManager::servers.size(); i++) if (server->getConfigSection().equalsi(serverConfig)) {
{ return server.get();
IRC_Bot *server = ServerManager::servers.get(i); }
if (server->getConfigSection().equalsi(serverConfig)) return server;
} }
return nullptr; return nullptr;
} }
IRC_Bot *ServerManager::getServer(size_t serverIndex) IRC_Bot *ServerManager::getServer(size_t serverIndex) {
{ if (serverIndex < m_servers.size()) {
if (serverIndex < ServerManager::servers.size()) return ServerManager::servers.get(serverIndex); return m_servers[serverIndex].get();
}
return nullptr; return nullptr;
} }
bool ServerManager::addServer(const Jupiter::ReadableString &serverConfig) bool ServerManager::addServer(const Jupiter::ReadableString &serverConfig) {
{ auto server = std::make_unique<IRC_Bot>(m_config->getSection(serverConfig), m_config->getSection("Default"_jrs));
IRC_Bot *server = new IRC_Bot(m_config->getSection(serverConfig), m_config->getSection("Default"_jrs)); if (server->connect()) {
if (server->connect()) m_servers.push_back(std::move(server));
{
ServerManager::servers.add(server);
return true; return true;
} }
else
{ return false;
delete server;
return false;
}
} }
bool ServerManager::freeServer(size_t serverIndex) bool ServerManager::freeServer(size_t serverIndex) {
{ if (serverIndex < m_servers.size()) {
if (serverIndex < ServerManager::servers.size()) m_servers.erase(m_servers.begin() + serverIndex);
{
delete ServerManager::servers.remove(serverIndex);
return true; return true;
} }
return false; return false;
} }
bool ServerManager::freeServer(IRC_Bot *server) bool ServerManager::freeServer(IRC_Bot *server) {
{ for (auto itr = m_servers.begin(); itr != m_servers.end(); ++itr) {
for (size_t i = 0; i != ServerManager::servers.size(); i++) if (itr->get() == server) {
{ m_servers.erase(itr);
if (ServerManager::servers.get(i) == server)
{
delete ServerManager::servers.remove(i);
return true; return true;
} }
} }
return false; return false;
} }
bool ServerManager::freeServer(const Jupiter::ReadableString &serverConfig) bool ServerManager::freeServer(const Jupiter::ReadableString &serverConfig) {
{ for (auto itr = m_servers.begin(); itr != m_servers.end(); ++itr) {
for (size_t i = 0; i != ServerManager::servers.size(); i++) if ((*itr)->getConfigSection().equalsi(serverConfig)) {
{ m_servers.erase(itr);
IRC_Bot *server = ServerManager::servers.get(i);
if (server->getConfigSection().equalsi(serverConfig))
{
delete ServerManager::servers.remove(i);
return true; return true;
} }
} }
return false; return false;
} }
size_t ServerManager::size() size_t ServerManager::size() {
{ return m_servers.size();
return ServerManager::servers.size();
} }
ServerManager::~ServerManager() ServerManager::~ServerManager() {
{
ServerManager::servers.emptyAndDelete();
} }

2
src/Jupiter

@ -1 +1 @@
Subproject commit 22d6097d595330b5dccd6d322d4f09bf8dd4ca41 Subproject commit 3a11bda36d30ce285604928ece72418af7fb921d

69
src/Plugins/CoreCommands/CoreCommands.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -18,7 +18,6 @@
#include <cstring> #include <cstring>
#include "Jupiter/Functions.h" #include "Jupiter/Functions.h"
#include "Jupiter/ArrayList.h"
#include "CoreCommands.h" #include "CoreCommands.h"
#include "IRC_Bot.h" #include "IRC_Bot.h"
@ -26,37 +25,33 @@ using namespace Jupiter::literals;
// Help Console Command // Help Console Command
HelpConsoleCommand::HelpConsoleCommand() HelpConsoleCommand::HelpConsoleCommand() {
{
this->addTrigger(STRING_LITERAL_AS_REFERENCE("help")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("help"));
} }
void HelpConsoleCommand::trigger(const Jupiter::ReadableString &parameters) void HelpConsoleCommand::trigger(const Jupiter::ReadableString &parameters) {
{ if (parameters.isEmpty()) {
if (parameters.isEmpty())
{
fputs("Supported commands:", stdout); fputs("Supported commands:", stdout);
for (size_t i = 0; i != consoleCommands->size(); i++) for (const auto& command : consoleCommands) {
{
fputc(' ', stdout); fputc(' ', stdout);
consoleCommands->get(i)->getTrigger().print(stdout); command->getTrigger().print(stdout);
} }
printf(ENDL "%s - %s" ENDL, Jupiter::version, Jupiter::copyright); printf(ENDL "%s - %s" ENDL, Jupiter::version, Jupiter::copyright);
puts("For command-specific help, use: help <command>"); puts("For command-specific help, use: help <command>");
return;
} }
else
{ Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE); ConsoleCommand *cmd = getConsoleCommand(command);
ConsoleCommand *cmd = getConsoleCommand(command); if (cmd == nullptr) {
if (cmd != nullptr) printf("Error: Command \"%.*s\" not found." ENDL, command.size(), command.ptr());
cmd->getHelp(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)).println(stdout); return;
else
printf("Error: Command \"%.*s\" not found." ENDL, command.size(), command.ptr());
} }
cmd->getHelp(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)).println(stdout);
} }
const Jupiter::ReadableString &HelpConsoleCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &HelpConsoleCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Lists commands, or sends command-specific help. Syntax: help [command]"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Lists commands, or sends command-specific help. Syntax: help [command]");
return defaultHelp; return defaultHelp;
} }
@ -65,13 +60,11 @@ CONSOLE_COMMAND_INIT(HelpConsoleCommand)
// Help IRC Command. // Help IRC Command.
void HelpIRCCommand::create() void HelpIRCCommand::create() {
{
this->addTrigger("help"_jrs); this->addTrigger("help"_jrs);
} }
void HelpIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) void HelpIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &in_channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &parameters) {
{
Jupiter::IRC::Client::Channel *channel = source->getChannel(in_channel); Jupiter::IRC::Client::Channel *channel = source->getChannel(in_channel);
if (channel != nullptr) if (channel != nullptr)
{ {
@ -80,7 +73,7 @@ void HelpIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &in_
{ {
for (int i = 0; i <= access; i++) for (int i = 0; i <= access; i++)
{ {
Jupiter::ArrayList<IRCCommand> 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);
@ -109,8 +102,7 @@ void HelpIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &in_
} }
} }
const Jupiter::ReadableString &HelpIRCCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &HelpIRCCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Syntax: help [command]"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Syntax: help [command]");
return defaultHelp; return defaultHelp;
} }
@ -119,8 +111,7 @@ IRC_COMMAND_INIT(HelpIRCCommand)
// Version Command // Version Command
VersionGenericCommand::VersionGenericCommand() VersionGenericCommand::VersionGenericCommand() {
{
this->addTrigger(STRING_LITERAL_AS_REFERENCE("version")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("version"));
this->addTrigger(STRING_LITERAL_AS_REFERENCE("versioninfo")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("versioninfo"));
this->addTrigger(STRING_LITERAL_AS_REFERENCE("copyright")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("copyright"));
@ -129,15 +120,13 @@ VersionGenericCommand::VersionGenericCommand()
this->addTrigger(STRING_LITERAL_AS_REFERENCE("clientinfo")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("clientinfo"));
} }
Jupiter::GenericCommand::ResponseLine *VersionGenericCommand::trigger(const Jupiter::ReadableString &parameters) Jupiter::GenericCommand::ResponseLine *VersionGenericCommand::trigger(const Jupiter::ReadableString &parameters) {
{
Jupiter::GenericCommand::ResponseLine *ret = new Jupiter::GenericCommand::ResponseLine("Version: "_jrs + Jupiter::ReferenceString(Jupiter::version), GenericCommand::DisplayType::PublicSuccess); Jupiter::GenericCommand::ResponseLine *ret = new Jupiter::GenericCommand::ResponseLine("Version: "_jrs + Jupiter::ReferenceString(Jupiter::version), GenericCommand::DisplayType::PublicSuccess);
ret->next = new Jupiter::GenericCommand::ResponseLine(Jupiter::ReferenceString(Jupiter::copyright), GenericCommand::DisplayType::PublicSuccess); ret->next = new Jupiter::GenericCommand::ResponseLine(Jupiter::ReferenceString(Jupiter::copyright), GenericCommand::DisplayType::PublicSuccess);
return ret; return ret;
} }
const Jupiter::ReadableString &VersionGenericCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &VersionGenericCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays version and copyright information"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays version and copyright information");
return defaultHelp; return defaultHelp;
} }
@ -147,13 +136,11 @@ GENERIC_COMMAND_AS_CONSOLE_COMMAND(VersionGenericCommand)
// Rehash Command // Rehash Command
RehashGenericCommand::RehashGenericCommand() RehashGenericCommand::RehashGenericCommand() {
{
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rehash")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("rehash"));
} }
Jupiter::GenericCommand::ResponseLine *RehashGenericCommand::trigger(const Jupiter::ReadableString &parameters) Jupiter::GenericCommand::ResponseLine *RehashGenericCommand::trigger(const Jupiter::ReadableString &parameters) {
{
unsigned int r = Jupiter::rehash(); unsigned int r = Jupiter::rehash();
if (r == 0) if (r == 0)
@ -162,8 +149,7 @@ Jupiter::GenericCommand::ResponseLine *RehashGenericCommand::trigger(const Jupit
return new Jupiter::GenericCommand::ResponseLine(Jupiter::StringS::Format("%u of %u objects failed to successfully rehash.", r, Jupiter::getRehashableCount()), GenericCommand::DisplayType::PublicError); return new Jupiter::GenericCommand::ResponseLine(Jupiter::StringS::Format("%u of %u objects failed to successfully rehash.", r, Jupiter::getRehashableCount()), GenericCommand::DisplayType::PublicError);
} }
const Jupiter::ReadableString &RehashGenericCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &RehashGenericCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Rehashes configuration data from a file. Syntax: rehash [file]"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Rehashes configuration data from a file. Syntax: rehash [file]");
return defaultHelp; return defaultHelp;
} }
@ -174,7 +160,6 @@ GENERIC_COMMAND_AS_CONSOLE_COMMAND(RehashGenericCommand)
// Plugin instantiation and entry point. // Plugin instantiation and entry point.
CoreCommandsPlugin pluginInstance; CoreCommandsPlugin pluginInstance;
extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() {
{
return &pluginInstance; return &pluginInstance;
} }

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016 Jessica James. * Copyright (C) 2016-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -23,57 +23,48 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
IRCCorePlugin::~IRCCorePlugin() IRCCorePlugin::~IRCCorePlugin() {
{
IRCCorePlugin::m_wrapped_commands.emptyAndDelete();
} }
bool IRCCorePlugin::initialize() bool IRCCorePlugin::initialize() {
{
const Jupiter::ReadableString &serverList = this->config.get("Servers"_jrs); const Jupiter::ReadableString &serverList = this->config.get("Servers"_jrs);
if (serverList != nullptr) if (serverList != nullptr) {
{
serverManager->setConfig(this->config); serverManager->setConfig(this->config);
unsigned int server_count = serverList.wordCount(WHITESPACE); unsigned int server_count = serverList.wordCount(WHITESPACE);
for (unsigned int index = 0; index != server_count; ++index) for (unsigned int index = 0; index != server_count; ++index) {
serverManager->addServer(Jupiter::ReferenceString::getWord(serverList, index, WHITESPACE)); serverManager->addServer(Jupiter::ReferenceString::getWord(serverList, index, WHITESPACE));
}
} }
return true; return true;
} }
int IRCCorePlugin::OnRehash() int IRCCorePlugin::OnRehash() {
{
Jupiter::Plugin::OnRehash(); Jupiter::Plugin::OnRehash();
serverManager->OnConfigRehash(); serverManager->OnConfigRehash();
return 0; return 0;
} }
int IRCCorePlugin::think() int IRCCorePlugin::think() {
{
serverManager->think(); serverManager->think();
return 0; return 0;
} }
void IRCCorePlugin::OnGenericCommandAdd(Jupiter::GenericCommand &in_command) void IRCCorePlugin::OnGenericCommandAdd(Jupiter::GenericCommand &in_command) {
{ m_wrapped_commands.emplace_back(in_command);
IRCCorePlugin::m_wrapped_commands.add(new GenericCommandWrapperIRCCommand(in_command));
} }
void IRCCorePlugin::OnGenericCommandRemove(Jupiter::GenericCommand &in_command) void IRCCorePlugin::OnGenericCommandRemove(Jupiter::GenericCommand &in_command) {
{ for (auto itr = m_wrapped_commands.begin(); itr != m_wrapped_commands.end(); ++itr) {
for (size_t index = 0; index != IRCCorePlugin::m_wrapped_commands.size(); ++index) if (&itr->getGenericCommand() == &in_command) {
if (&IRCCorePlugin::m_wrapped_commands.get(index)->getGenericCommand() == &in_command) m_wrapped_commands.erase(itr);
{
delete IRCCorePlugin::m_wrapped_commands.remove(index);
return; return;
} }
}
} }
// Plugin instantiation and entry point. // Plugin instantiation and entry point.
IRCCorePlugin pluginInstance; IRCCorePlugin pluginInstance;

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016 Jessica James. * Copyright (C) 2016-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -58,7 +58,7 @@ public:
~IRCCorePlugin(); ~IRCCorePlugin();
private: private:
Jupiter::ArrayList<GenericCommandWrapperIRCCommand> m_wrapped_commands; std::vector<GenericCommandWrapperIRCCommand> m_wrapped_commands;
}; };
#endif // _IRC_CORE_H_HEADER #endif // _IRC_CORE_H_HEADER

63
src/Plugins/PluginManager/PluginManager.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2016 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -23,45 +23,47 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
// Plugin Generic Command // Plugin Generic Command
PluginGenericCommand::PluginGenericCommand() PluginGenericCommand::PluginGenericCommand() {
{
this->addTrigger(STRING_LITERAL_AS_REFERENCE("plugin")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("plugin"));
this->addTrigger(STRING_LITERAL_AS_REFERENCE("plugins")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("plugins"));
this->addTrigger(STRING_LITERAL_AS_REFERENCE("module")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("module"));
this->addTrigger(STRING_LITERAL_AS_REFERENCE("modules")); this->addTrigger(STRING_LITERAL_AS_REFERENCE("modules"));
} }
Jupiter::GenericCommand::ResponseLine *PluginGenericCommand::trigger(const Jupiter::ReadableString &parameters) Jupiter::GenericCommand::ResponseLine *PluginGenericCommand::trigger(const Jupiter::ReadableString &parameters) {
{ Jupiter::GenericCommand::ResponseLine *result = new Jupiter::GenericCommand::ResponseLine();
Jupiter::GenericCommand::ResponseLine *ret = new Jupiter::GenericCommand::ResponseLine(); if (parameters.isEmpty() || parameters.matchi("list*")) {
if (parameters.isEmpty() || parameters.matchi("list*")) 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) {
Jupiter::GenericCommand::ResponseLine *line = ret->set(Jupiter::String::Format("There are %u plugins loaded:", Jupiter::plugins->size()), GenericCommand::DisplayType::PublicSuccess); line->next = new Jupiter::GenericCommand::ResponseLine(plugin->getName(), GenericCommand::DisplayType::PublicSuccess);
for (size_t i = 0; i != Jupiter::plugins->size(); i++)
{
line->next = new Jupiter::GenericCommand::ResponseLine(Jupiter::plugins->get(i)->getName(), GenericCommand::DisplayType::PublicSuccess);
line = line->next; line = line->next;
} }
return ret;
return result;
} }
if (parameters.matchi("load *")) if (parameters.matchi("load *")) {
{ if (Jupiter::Plugin::load(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)) == nullptr) {
if (Jupiter::Plugin::load(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)) == nullptr) return result->set("Error: Failed to load plugin."_jrs, GenericCommand::DisplayType::PublicError);
return ret->set("Error: Failed to load plugin."_jrs, GenericCommand::DisplayType::PublicError); }
else
return ret->set("Plugin successfully loaded."_jrs, GenericCommand::DisplayType::PublicSuccess); return result->set("Plugin successfully loaded."_jrs, GenericCommand::DisplayType::PublicSuccess);
} }
if (parameters.matchi("unload *")) if (parameters.matchi("unload *"))
{ {
Jupiter::ReferenceString pluginName = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE); Jupiter::ReferenceString pluginName = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE);
if (Jupiter::Plugin::get(pluginName) == nullptr) if (Jupiter::Plugin::get(pluginName) == nullptr) {
return ret->set("Error: Plugin does not exist."_jrs, GenericCommand::DisplayType::PublicError); return result->set("Error: Plugin does not exist."_jrs, GenericCommand::DisplayType::PublicError);
if (Jupiter::Plugin::free(pluginName) == false) }
return ret->set("Error: Failed to unload plugin."_jrs, GenericCommand::DisplayType::PublicError);
return ret->set("Plugin successfully unloaded."_jrs, GenericCommand::DisplayType::PublicSuccess); if (Jupiter::Plugin::free(pluginName) == false) {
return result->set("Error: Failed to unload plugin."_jrs, GenericCommand::DisplayType::PublicError);
}
return result->set("Plugin successfully unloaded."_jrs, GenericCommand::DisplayType::PublicSuccess);
} }
return ret->set("Error: Invalid Syntax. Syntax: plugin {[list], <load> <plugin>, <unload> <plugin>}"_jrs, GenericCommand::DisplayType::PrivateError); return result->set("Error: Invalid Syntax. Syntax: plugin {[list], <load> <plugin>, <unload> <plugin>}"_jrs, GenericCommand::DisplayType::PrivateError);
} }
const Jupiter::ReadableString &PluginGenericCommand::getHelp(const Jupiter::ReadableString &parameters) const Jupiter::ReadableString &PluginGenericCommand::getHelp(const Jupiter::ReadableString &parameters)
@ -71,12 +73,17 @@ const Jupiter::ReadableString &PluginGenericCommand::getHelp(const Jupiter::Read
static STRING_LITERAL_AS_NAMED_REFERENCE(listHelp, "Lists all of the plugins currently loaded. Syntax: plugin [list]"); static STRING_LITERAL_AS_NAMED_REFERENCE(listHelp, "Lists all of the plugins currently loaded. Syntax: plugin [list]");
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Manages plugins. Syntax: plugin {[list], <load> <plugin>, <unload> <plugin>}"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Manages plugins. Syntax: plugin {[list], <load> <plugin>, <unload> <plugin>}");
if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("load"))) if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("load"))) {
return loadHelp; return loadHelp;
if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("unload"))) }
if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("unload"))) {
return unloadHelp; return unloadHelp;
if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("list"))) }
if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("list"))) {
return listHelp; return listHelp;
}
return defaultHelp; return defaultHelp;
} }

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

File diff suppressed because it is too large

10
src/Plugins/RenX/RenX.Commands/RenX_Commands.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -47,10 +47,10 @@ public:
private: private:
std::chrono::seconds m_defaultTempBanTime; std::chrono::seconds m_defaultTempBanTime;
std::chrono::seconds m_maxTempBanTime; std::chrono::seconds m_maxTempBanTime;
Jupiter::StringS playerInfoFormat; Jupiter::StringS m_playerInfoFormat;
Jupiter::StringS adminPlayerInfoFormat; Jupiter::StringS m_adminPlayerInfoFormat;
Jupiter::StringS buildingInfoFormat; Jupiter::StringS m_buildingInfoFormat;
Jupiter::StringS staffTitle; Jupiter::StringS m_staffTitle;
}; };
GENERIC_CONSOLE_COMMAND(RawRCONConsoleCommand) GENERIC_CONSOLE_COMMAND(RawRCONConsoleCommand)

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -32,15 +32,15 @@ RenX::BanDatabase &RenX::defaultBanDatabase = _banDatabase;
void RenX::BanDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos) void RenX::BanDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos)
{ {
if (RenX::BanDatabase::read_version < 3U) if (m_read_version < 3U)
return; // incompatible database version return; // incompatible database version
RenX::BanDatabase::Entry *entry = new RenX::BanDatabase::Entry(); std::unique_ptr<Entry> entry = std::make_unique<Entry>();
entry->pos = pos; entry->pos = pos;
// Read data from buffer to entry // Read data from buffer to entry
entry->flags = buffer.pop<uint16_t>(); entry->flags = buffer.pop<uint16_t>();
if (RenX::BanDatabase::read_version >= 4U) if (m_read_version >= 4U)
{ {
entry->timestamp = std::chrono::system_clock::time_point(std::chrono::seconds(buffer.pop<uint64_t>())); entry->timestamp = std::chrono::system_clock::time_point(std::chrono::seconds(buffer.pop<uint64_t>()));
entry->length = std::chrono::seconds(buffer.pop<uint64_t>()); entry->length = std::chrono::seconds(buffer.pop<uint64_t>());
@ -53,7 +53,7 @@ void RenX::BanDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fp
entry->steamid = buffer.pop<uint64_t>(); entry->steamid = buffer.pop<uint64_t>();
entry->ip = buffer.pop<uint32_t>(); entry->ip = buffer.pop<uint32_t>();
entry->prefix_length = buffer.pop<uint8_t>(); entry->prefix_length = buffer.pop<uint8_t>();
if (this->read_version >= 5U) if (m_read_version >= 5U)
entry->hwid = buffer.pop<Jupiter::String_Strict, char>(); entry->hwid = buffer.pop<Jupiter::String_Strict, char>();
entry->rdns = buffer.pop<Jupiter::String_Strict, char>(); entry->rdns = buffer.pop<Jupiter::String_Strict, char>();
entry->name = buffer.pop<Jupiter::String_Strict, char>(); entry->name = buffer.pop<Jupiter::String_Strict, char>();
@ -61,78 +61,72 @@ void RenX::BanDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fp
entry->reason = buffer.pop<Jupiter::String_Strict, char>(); entry->reason = buffer.pop<Jupiter::String_Strict, char>();
// Read varData from buffer to entry // Read varData from buffer to entry
for (size_t varData_entries = buffer.pop<size_t>(); varData_entries != 0; --varData_entries) for (size_t varData_entries = buffer.pop<size_t>(); varData_entries != 0; --varData_entries) {
entry->varData[buffer.pop<Jupiter::String_Strict, char>()] = buffer.pop<Jupiter::String_Strict, char>(); entry->varData[buffer.pop<Jupiter::String_Strict, char>()] = buffer.pop<Jupiter::String_Strict, char>();
}
RenX::BanDatabase::entries.add(entry); m_entries.push_back(std::move(entry));
} }
void RenX::BanDatabase::process_header(FILE *file) void RenX::BanDatabase::process_header(FILE *file)
{ {
int chr = fgetc(file); int chr = fgetc(file);
if (chr != EOF) if (chr != EOF)
RenX::BanDatabase::read_version = chr; m_read_version = chr;
} }
void RenX::BanDatabase::create_header(FILE *file) void RenX::BanDatabase::create_header(FILE *file)
{ {
fputc(RenX::BanDatabase::write_version, file); fputc(m_write_version, file);
} }
void RenX::BanDatabase::process_file_finish(FILE *file) void RenX::BanDatabase::process_file_finish(FILE *file) {
{ if (m_read_version < 3) {
if (RenX::BanDatabase::read_version < 3) if (freopen(m_filename.c_str(), "wb", file) == nullptr) {
{
if (freopen(RenX::BanDatabase::filename.c_str(), "wb", file) == nullptr)
puts("FATAL ERROR: UNABLE TO REMOVE UNSUPPORTED BAN DATABASE FILE VERSION"); puts("FATAL ERROR: UNABLE TO REMOVE UNSUPPORTED BAN DATABASE FILE VERSION");
else return;
{
puts("Warning: Unsupported ban database file version. The database will be removed and rewritten.");
this->create_header(file);
fgetpos(file, std::addressof(RenX::BanDatabase::eof));
RenX::BanDatabase::read_version = RenX::BanDatabase::write_version;
} }
puts("Warning: Unsupported ban database file version. The database will be removed and rewritten.");
create_header(file);
fgetpos(file, std::addressof(m_eof));
m_read_version = m_write_version;
return; return;
} }
else if (RenX::BanDatabase::read_version < RenX::BanDatabase::write_version) else if (m_read_version < m_write_version) {
{ if (freopen(m_filename.c_str(), "wb", file) != nullptr) {
if (freopen(RenX::BanDatabase::filename.c_str(), "wb", file) != nullptr)
{
this->create_header(file); this->create_header(file);
for (size_t index = 0; index != RenX::BanDatabase::entries.size(); ++index) for (const auto& entry : m_entries) {
RenX::BanDatabase::write(RenX::BanDatabase::entries.get(index), file); write(entry.get(), file);
}
} }
} }
fgetpos(file, std::addressof(RenX::BanDatabase::eof)); fgetpos(file, std::addressof(m_eof));
} }
void RenX::BanDatabase::upgrade_database() void RenX::BanDatabase::upgrade_database() {
{ FILE *file = fopen(m_filename.c_str(), "wb");
FILE *file = fopen(RenX::BanDatabase::filename.c_str(), "wb"); if (file != nullptr) {
if (file != nullptr)
{
this->create_header(file); this->create_header(file);
for (size_t index = 0; index != RenX::BanDatabase::entries.size(); ++index) for (const auto& entry : m_entries) {
RenX::BanDatabase::write(RenX::BanDatabase::entries.get(index), file); write(entry.get(), file);
}
fclose(file); fclose(file);
} }
} }
void RenX::BanDatabase::write(RenX::BanDatabase::Entry *entry) void RenX::BanDatabase::write(Entry* entry) {
{ FILE *file = fopen(m_filename.c_str(), "r+b");
FILE *file = fopen(filename.c_str(), "r+b"); fsetpos(file, std::addressof(m_eof));
fsetpos(file, std::addressof(RenX::BanDatabase::eof)); if (file != nullptr) {
if (file != nullptr) write(entry, file);
{
RenX::BanDatabase::write(entry, file);
fclose(file); fclose(file);
} }
} }
void RenX::BanDatabase::write(RenX::BanDatabase::Entry *entry, FILE *file) void RenX::BanDatabase::write(Entry* entry, FILE *file) {
{
Jupiter::DataBuffer buffer; Jupiter::DataBuffer buffer;
fgetpos(file, &entry->pos); fgetpos(file, &entry->pos);
@ -160,12 +154,11 @@ void RenX::BanDatabase::write(RenX::BanDatabase::Entry *entry, FILE *file)
// push buffer to file // push buffer to file
buffer.push_to(file); buffer.push_to(file);
fgetpos(file, std::addressof(RenX::BanDatabase::eof)); fgetpos(file, std::addressof(m_eof));
} }
void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo &player, const Jupiter::ReadableString &banner, const Jupiter::ReadableString &reason, std::chrono::seconds length, uint16_t flags) void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo &player, const Jupiter::ReadableString &banner, const Jupiter::ReadableString &reason, std::chrono::seconds length, uint16_t flags) {
{ std::unique_ptr<Entry> entry = std::make_unique<Entry>();
Entry *entry = new Entry();
if (flags != 0) { if (flags != 0) {
entry->set_active(); entry->set_active();
entry->flags |= flags; entry->flags |= flags;
@ -187,18 +180,18 @@ void RenX::BanDatabase::add(RenX::Server *server, const RenX::PlayerInfo &player
// add plugin data // add plugin data
Jupiter::String pluginData; Jupiter::String pluginData;
Jupiter::ArrayList<RenX::Plugin> &xPlugins = *RenX::getCore()->getPlugins(); for (Plugin* plugin : RenX::getCore()->getPlugins()) {
for (size_t i = 0; i < xPlugins.size(); i++) if (plugin->RenX_OnBan(*server, player, pluginData)) {
if (xPlugins.get(i)->RenX_OnBan(*server, player, pluginData)) entry->varData[plugin->getName()] = pluginData;
entry->varData[xPlugins.get(i)->getName()] = pluginData; }
}
entries.add(entry); m_entries.push_back(std::move(entry));
RenX::BanDatabase::write(entry); 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, const Jupiter::ReadableString &banner, Jupiter::ReadableString &reason, std::chrono::seconds length, uint16_t flags) 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, const Jupiter::ReadableString &banner, Jupiter::ReadableString &reason, std::chrono::seconds length, uint16_t flags) {
{ std::unique_ptr<Entry> entry = std::make_unique<Entry>();
Entry *entry = new Entry();
entry->set_active(); entry->set_active();
entry->flags |= flags; entry->flags |= flags;
entry->timestamp = std::chrono::system_clock::now(); entry->timestamp = std::chrono::system_clock::now();
@ -212,19 +205,20 @@ void RenX::BanDatabase::add(const Jupiter::ReadableString &name, uint32_t ip, ui
entry->banner = banner; entry->banner = banner;
entry->reason = reason; entry->reason = reason;
entries.add(entry); m_entries.push_back(std::move(entry));
RenX::BanDatabase::write(entry); write(m_entries.back().get());
} }
bool RenX::BanDatabase::deactivate(size_t index) bool RenX::BanDatabase::deactivate(size_t index) {
{ const auto& entry = m_entries[index];
RenX::BanDatabase::Entry *entry = RenX::BanDatabase::entries.get(index); return deactivate(entry.get());
if (entry->is_active()) }
{
bool RenX::BanDatabase::deactivate(Entry* entry) {
if (entry->is_active()) {
entry->unset_active(); entry->unset_active();
FILE *file = fopen(RenX::BanDatabase::filename.c_str(), "r+b"); FILE *file = fopen(m_filename.c_str(), "r+b");
if (file != nullptr) if (file != nullptr) {
{
fsetpos(file, &entry->pos); fsetpos(file, &entry->pos);
fseek(file, sizeof(size_t), SEEK_CUR); fseek(file, sizeof(size_t), SEEK_CUR);
fwrite(std::addressof(entry->flags), sizeof(entry->flags), 1, file); fwrite(std::addressof(entry->flags), sizeof(entry->flags), 1, file);
@ -235,28 +229,22 @@ bool RenX::BanDatabase::deactivate(size_t index)
return false; return false;
} }
uint8_t RenX::BanDatabase::getVersion() const uint8_t RenX::BanDatabase::getVersion() const {
{ return m_write_version;
return RenX::BanDatabase::write_version;
} }
const std::string &RenX::BanDatabase::getFileName() const const std::string &RenX::BanDatabase::getFileName() const {
{ return m_filename;
return RenX::BanDatabase::filename;
} }
const Jupiter::ArrayList<RenX::BanDatabase::Entry> &RenX::BanDatabase::getEntries() const const std::vector<std::unique_ptr<RenX::BanDatabase::Entry>>& RenX::BanDatabase::getEntries() const {
{ return m_entries;
return RenX::BanDatabase::entries;
} }
bool RenX::BanDatabase::initialize() bool RenX::BanDatabase::initialize() {
{ m_filename = static_cast<std::string>(RenX::getCore()->getConfig().get("BanDB"_jrs, "Bans.db"_jrs));
RenX::BanDatabase::filename = static_cast<std::string>(RenX::getCore()->getConfig().get("BanDB"_jrs, "Bans.db"_jrs)); return this->process_file(m_filename);
return this->process_file(filename);
} }
RenX::BanDatabase::~BanDatabase() RenX::BanDatabase::~BanDatabase() {
{
RenX::BanDatabase::entries.emptyAndDelete();
} }

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -23,7 +23,6 @@
#include <unordered_map> #include <unordered_map>
#include "Jupiter/Database.h" #include "Jupiter/Database.h"
#include "Jupiter/String.hpp" #include "Jupiter/String.hpp"
#include "Jupiter/ArrayList.h"
#include "RenX.h" #include "RenX.h"
/** DLL Linkage Nagging */ /** DLL Linkage Nagging */
@ -188,6 +187,7 @@ namespace RenX
* @param True if the entry was active and is now inactive, false otherwise. * @param True if the entry was active and is now inactive, false otherwise.
*/ */
bool deactivate(size_t index); bool deactivate(size_t index);
bool deactivate(Entry* entry);
/** /**
* @brief Fetches the version of the database file. * @brief Fetches the version of the database file.
@ -208,19 +208,19 @@ namespace RenX
* *
* @return List of entries * @return List of entries
*/ */
const Jupiter::ArrayList<RenX::BanDatabase::Entry> &getEntries() const; const std::vector<std::unique_ptr<Entry>>& getEntries() const;
virtual bool initialize(); virtual bool initialize();
~BanDatabase(); ~BanDatabase();
private: private:
/** Database version */ /** Database version */
const uint8_t write_version = 5U; const uint8_t m_write_version = 5U;
uint8_t read_version = write_version; uint8_t m_read_version = m_write_version;
fpos_t eof; fpos_t m_eof;
std::string filename; std::string m_filename;
Jupiter::ArrayList<RenX::BanDatabase::Entry> entries; std::vector<std::unique_ptr<Entry>> m_entries;
}; };
RENX_API extern RenX::BanDatabase *banDatabase; RENX_API extern RenX::BanDatabase *banDatabase;

185
src/Plugins/RenX/RenX.Core/RenX_Core.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -34,158 +34,157 @@ using namespace Jupiter::literals;
RenX::Core pluginInstance; RenX::Core pluginInstance;
RenX::Core *RenXInstance = &pluginInstance; RenX::Core *RenXInstance = &pluginInstance;
RenX::Core *RenX::getCore() RenX::Core *RenX::getCore() {
{
return &pluginInstance; return &pluginInstance;
} }
bool RenX::Core::initialize() bool RenX::Core::initialize() {
{
RenX::banDatabase->initialize(); RenX::banDatabase->initialize();
RenX::exemptionDatabase->initialize(); RenX::exemptionDatabase->initialize();
RenX::tags->initialize(); RenX::tags->initialize();
RenX::initTranslations(this->config); RenX::initTranslations(this->config);
const Jupiter::ReadableString &serverList = this->config.get("Servers"_jrs); const Jupiter::ReadableString &serverList = this->config.get("Servers"_jrs);
RenX::Core::commandsFile.read(this->config.get("CommandsFile"_jrs, "RenXGameCommands.ini"_jrs)); m_commandsFile.read(this->config.get("CommandsFile"_jrs, "RenXGameCommands.ini"_jrs));
unsigned int wc = serverList.wordCount(WHITESPACE); unsigned int wc = serverList.wordCount(WHITESPACE);
RenX::Server *server; std::unique_ptr<RenX::Server> server;
for (unsigned int i = 0; i != wc; i++) for (unsigned int i = 0; i != wc; i++) {
{ server = std::make_unique<RenX::Server>(Jupiter::ReferenceString::getWord(serverList, i, WHITESPACE));
server = new RenX::Server(Jupiter::ReferenceString::getWord(serverList, i, WHITESPACE));
if (server->connect() == false) if (server->connect() == false) {
{
fprintf(stderr, "[RenX] ERROR: Failed to connect to %.*s on port %u. Error code: %d" ENDL, server->getHostname().size(), server->getHostname().c_str(), server->getPort(), Jupiter::Socket::getLastError()); fprintf(stderr, "[RenX] ERROR: Failed to connect to %.*s on port %u. Error code: %d" ENDL, server->getHostname().size(), server->getHostname().c_str(), server->getPort(), Jupiter::Socket::getLastError());
delete server; continue;
} }
else RenX::Core::addServer(server);
addServer(std::move(server));
} }
return true; return true;
} }
RenX::Core::~Core() RenX::Core::~Core() {
{
RenX::Core::servers.emptyAndDelete();
} }
size_t RenX::Core::send(int type, const Jupiter::ReadableString &msg) size_t RenX::Core::send(int type, const Jupiter::ReadableString &msg) {
{
size_t result = 0; size_t result = 0;
RenX::Server *server;
for (size_t i = 0; i != RenX::Core::servers.size(); i++) for (auto& server : m_servers) {
{ if (server->isLogChanType(type) && server->send(msg) > 0) {
server = RenX::Core::getServer(i);
if (server->isLogChanType(type) && server->send(msg) > 0)
++result; ++result;
}
} }
return result; return result;
} }
void RenX::Core::addServer(RenX::Server *server) void RenX::Core::addServer(std::unique_ptr<RenX::Server> server) {
{ m_servers.push_back(std::move(server));
RenX::Core::servers.add(server);
} }
size_t RenX::Core::getServerIndex(RenX::Server *server) size_t RenX::Core::getServerIndex(RenX::Server *server) {
{ for (size_t index = 0; index != m_servers.size(); ++index) {
for (size_t index = 0; index != RenX::Core::servers.size(); ++index) if (server == m_servers[index].get()) {
if (server == RenX::Core::servers.get(index))
return index; return index;
}
}
return Jupiter::INVALID_INDEX; return Jupiter::INVALID_INDEX;
} }
RenX::Server *RenX::Core::getServer(size_t index) RenX::Server* RenX::Core::getServer(size_t index) {
{ if (index > m_servers.size()) {
return RenX::Core::servers.get(index); return nullptr;
}
return m_servers[index].get();
} }
Jupiter::ArrayList<RenX::Server> RenX::Core::getServers() std::vector<RenX::Server*> RenX::Core::getServers() {
{ std::vector<RenX::Server*> result;
return RenX::Core::servers;
for (const auto& server : m_servers) {
result.push_back(server.get());
}
return result;
} }
Jupiter::ArrayList<RenX::Server> RenX::Core::getServers(int type) std::vector<RenX::Server*> RenX::Core::getServers(int type) {
{ std::vector<RenX::Server*> result;
Jupiter::ArrayList<RenX::Server> r;
RenX::Server *server; for (const auto& server : m_servers) {
for (size_t i = 0; i != RenX::Core::servers.size(); i++) if (server->isLogChanType(type)) {
{ result.push_back(server.get());
server = RenX::Core::servers.get(i); }
if (server != nullptr && server->isLogChanType(type))
r.add(server);
} }
return r;
return result;
} }
void RenX::Core::removeServer(unsigned int index) void RenX::Core::removeServer(unsigned int index) {
{ if (index < m_servers.size()) {
delete RenX::Core::servers.remove(index); m_servers.erase(m_servers.begin() + index);
}
} }
size_t RenX::Core::removeServer(RenX::Server *server) size_t RenX::Core::removeServer(RenX::Server *server) {
{ for (auto itr = m_servers.begin(); itr != m_servers.end(); ++itr) {
size_t index = RenX::Core::getServerIndex(server); if (itr->get() == server) {
size_t index = m_servers.end() - itr;
if (index != Jupiter::INVALID_INDEX) m_servers.erase(itr);
delete RenX::Core::servers.remove(index); return index;
}
}
return index; return Jupiter::INVALID_INDEX;
} }
bool RenX::Core::hasServer(RenX::Server *server) bool RenX::Core::hasServer(RenX::Server* in_server) {
{ for (const auto& server : m_servers) {
size_t index = RenX::Core::servers.size(); if (server.get() == in_server) {
while (index != 0)
if (server == RenX::Core::servers.get(--index))
return true; return true;
}
}
return false; return false;
} }
size_t RenX::Core::getServerCount() size_t RenX::Core::getServerCount() {
{ return m_servers.size();
return RenX::Core::servers.size();
} }
Jupiter::ArrayList<RenX::Plugin> *RenX::Core::getPlugins() std::vector<RenX::Plugin*>& RenX::Core::getPlugins() {
{ return m_plugins;
return &(RenX::Core::plugins);
} }
Jupiter::Config &RenX::Core::getCommandsFile() Jupiter::Config &RenX::Core::getCommandsFile() {
{ return m_commandsFile;
return RenX::Core::commandsFile;
} }
size_t RenX::Core::addCommand(RenX::GameCommand *command) size_t RenX::Core::addCommand(RenX::GameCommand *command) {
{ for (const auto& server : m_servers) {
for (size_t index = 0; index != RenX::Core::servers.size(); ++index) server->addCommand(command->copy());
RenX::Core::servers.get(index)->addCommand(command->copy()); }
return RenX::Core::servers.size(); return m_servers.size();
} }
void RenX::Core::banCheck() void RenX::Core::banCheck() {
{ for (const auto& server : m_servers) {
for (size_t index = 0; index != RenX::Core::servers.size(); ++index) server->banCheck();
RenX::Core::servers.get(index)->banCheck(); }
} }
int RenX::Core::think() int RenX::Core::think() {
{ for (auto itr = m_servers.begin(); itr != m_servers.end();) {
size_t index = 0; if ((*itr)->think() != 0) {
while (index < RenX::Core::servers.size()) itr = m_servers.erase(itr + 1);
if (RenX::Core::servers.get(index)->think() != 0) continue;
delete RenX::Core::servers.remove(index); }
else ++index; ++itr;
}
return Jupiter::Plugin::think(); return Jupiter::Plugin::think();
} }
@ -199,8 +198,10 @@ extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin()
// Unload // Unload
extern "C" JUPITER_EXPORT void unload(void) extern "C" JUPITER_EXPORT void unload(void) {
{ auto& plugins = pluginInstance.getPlugins();
while (pluginInstance.getPlugins()->size() > 0) while (!plugins.empty()) {
Jupiter::Plugin::free(pluginInstance.getPlugins()->remove(0)); Jupiter::Plugin::free(plugins.back());
plugins.pop_back();
}
} }

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -27,6 +27,7 @@
#include "Jupiter/Plugin.h" #include "Jupiter/Plugin.h"
#include "Jupiter/Config.h" #include "Jupiter/Config.h"
#include "RenX.h" #include "RenX.h"
#include "RenX_Server.h"
/** DLL Linkage Nagging */ /** DLL Linkage Nagging */
#if defined _MSC_VER #if defined _MSC_VER
@ -80,7 +81,7 @@ namespace RenX
* *
* @param server Server to add to the list. * @param server Server to add to the list.
*/ */
void addServer(RenX::Server *server); void addServer(std::unique_ptr<RenX::Server> server);
/** /**
* @brief Fetches a server's index. * @brief Fetches a server's index.
@ -103,15 +104,15 @@ namespace RenX
* *
* @return Copy of the list of servers. * @return Copy of the list of servers.
*/ */
Jupiter::ArrayList<RenX::Server> getServers(); std::vector<RenX::Server*> getServers();
/** /**
* @brief Constructs a list of servers based on their type. * @brief Constructs a list of servers based on their type.
* *
* @param type Type of servers to fetch. * @param type Type of servers to fetch.
* @return ArrayList of servers with the same type. * @return vector of servers with the same type.
*/ */
Jupiter::ArrayList<RenX::Server> getServers(int type); std::vector<RenX::Server*> getServers(int type);
/** /**
* @brief Removes a server based on its index. * @brief Removes a server based on its index.
@ -146,9 +147,9 @@ namespace RenX
/** /**
* @brief Fetches the Renegade-X plugins currently loaded. * @brief Fetches the Renegade-X plugins currently loaded.
* *
* @return ArrayList containing pointers to the plugins. * @return vector containing pointers to the plugins.
*/ */
Jupiter::ArrayList<RenX::Plugin> *getPlugins(); std::vector<RenX::Plugin*>& getPlugins();
/** /**
* @brief Fetches the commands settings file. * @brief Fetches the commands settings file.
@ -175,11 +176,15 @@ namespace RenX
*/ */
~Core(); ~Core();
Core() = default;
Core(const Core&) = delete;
Core& operator=(const Core&) = delete;
private: private:
/** Inaccessible private members */ /** Inaccessible private members */
Jupiter::ArrayList<RenX::Server> servers; std::vector<std::unique_ptr<RenX::Server>> m_servers;
Jupiter::ArrayList<RenX::Plugin> plugins; std::vector<RenX::Plugin*> m_plugins;
Jupiter::INIConfig commandsFile; Jupiter::INIConfig m_commandsFile;
}; };
RENX_API Core *getCore(); RENX_API Core *getCore();

139
src/Plugins/RenX/RenX.Core/RenX_ExemptionDatabase.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016-2017 Jessica James. * Copyright (C) 2016-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -25,13 +25,12 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
RenX::ExemptionDatabase _exemptionDatabase; RenX::ExemptionDatabase g_exemptionDatabase;
RenX::ExemptionDatabase *RenX::exemptionDatabase = &_exemptionDatabase; RenX::ExemptionDatabase *RenX::exemptionDatabase = &g_exemptionDatabase;
RenX::ExemptionDatabase &RenX::defaultExemptionDatabase = _exemptionDatabase; RenX::ExemptionDatabase &RenX::defaultExemptionDatabase = g_exemptionDatabase;
void RenX::ExemptionDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos) void RenX::ExemptionDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos) {
{ std::unique_ptr<Entry> entry = std::make_unique<Entry>();
RenX::ExemptionDatabase::Entry *entry = new RenX::ExemptionDatabase::Entry();
entry->pos = pos; entry->pos = pos;
// Read data from buffer to entry // Read data from buffer to entry
@ -43,52 +42,45 @@ void RenX::ExemptionDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *fi
entry->prefix_length = buffer.pop<uint8_t>(); entry->prefix_length = buffer.pop<uint8_t>();
entry->setter = buffer.pop<Jupiter::String_Strict, char>(); entry->setter = buffer.pop<Jupiter::String_Strict, char>();
RenX::ExemptionDatabase::entries.add(entry); m_entries.push_back(std::move(entry));
} }
void RenX::ExemptionDatabase::process_header(FILE *file) void RenX::ExemptionDatabase::process_header(FILE *file) {
{
int chr = fgetc(file); int chr = fgetc(file);
if (chr != EOF) if (chr != EOF)
RenX::ExemptionDatabase::read_version = chr; m_read_version = chr;
} }
void RenX::ExemptionDatabase::create_header(FILE *file) void RenX::ExemptionDatabase::create_header(FILE *file) {
{ fputc(m_write_version, file);
fputc(RenX::ExemptionDatabase::write_version, file);
} }
void RenX::ExemptionDatabase::process_file_finish(FILE *file) void RenX::ExemptionDatabase::process_file_finish(FILE *file) {
{ fgetpos(file, std::addressof(m_eof));
fgetpos(file, std::addressof(RenX::ExemptionDatabase::eof));
} }
void RenX::ExemptionDatabase::upgrade_database() void RenX::ExemptionDatabase::upgrade_database() {
{ FILE *file = fopen(m_filename.c_str(), "wb");
FILE *file = fopen(RenX::ExemptionDatabase::filename.c_str(), "wb"); if (file != nullptr) {
if (file != nullptr)
{
this->create_header(file); this->create_header(file);
for (size_t index = 0; RenX::ExemptionDatabase::entries.size(); ++index) for (size_t index = 0; m_entries.size(); ++index) {
RenX::ExemptionDatabase::write(RenX::ExemptionDatabase::entries.get(index), file); write(m_entries[index].get(), file);
}
fclose(file); fclose(file);
} }
} }
void RenX::ExemptionDatabase::write(RenX::ExemptionDatabase::Entry *entry) void RenX::ExemptionDatabase::write(RenX::ExemptionDatabase::Entry *entry) {
{ FILE *file = fopen(m_filename.c_str(), "r+b");
FILE *file = fopen(filename.c_str(), "r+b"); fsetpos(file, std::addressof(m_eof));
fsetpos(file, std::addressof(RenX::ExemptionDatabase::eof)); if (file != nullptr) {
if (file != nullptr) write(entry, file);
{
RenX::ExemptionDatabase::write(entry, file);
fclose(file); fclose(file);
} }
} }
void RenX::ExemptionDatabase::write(RenX::ExemptionDatabase::Entry *entry, FILE *file) void RenX::ExemptionDatabase::write(RenX::ExemptionDatabase::Entry *entry, FILE *file) {
{
Jupiter::DataBuffer buffer; Jupiter::DataBuffer buffer;
fgetpos(file, &entry->pos); fgetpos(file, &entry->pos);
@ -103,17 +95,15 @@ void RenX::ExemptionDatabase::write(RenX::ExemptionDatabase::Entry *entry, FILE
// push buffer to file // push buffer to file
buffer.push_to(file); buffer.push_to(file);
fgetpos(file, std::addressof(RenX::ExemptionDatabase::eof)); fgetpos(file, std::addressof(m_eof));
} }
void RenX::ExemptionDatabase::add(RenX::Server &, const RenX::PlayerInfo &player, const Jupiter::ReadableString &setter, std::chrono::seconds length, uint8_t flags) void RenX::ExemptionDatabase::add(RenX::Server &, const RenX::PlayerInfo &player, const Jupiter::ReadableString &setter, std::chrono::seconds length, uint8_t flags) {
{ add(player.ip32, 32U, player.steamid, setter, length, flags);
RenX::ExemptionDatabase::add(player.ip32, 32U, player.steamid, setter, length, flags);
} }
void RenX::ExemptionDatabase::add(uint32_t ip, uint8_t prefix_length, uint64_t steamid, const Jupiter::ReadableString &setter, std::chrono::seconds length, uint8_t flags) void RenX::ExemptionDatabase::add(uint32_t ip, uint8_t prefix_length, uint64_t steamid, const Jupiter::ReadableString &setter, std::chrono::seconds length, uint8_t flags) {
{ std::unique_ptr<Entry> entry = std::make_unique<Entry>();
Entry *entry = new Entry();
entry->set_active(); entry->set_active();
entry->flags |= flags; entry->flags |= flags;
entry->timestamp = std::chrono::system_clock::now(); entry->timestamp = std::chrono::system_clock::now();
@ -123,19 +113,16 @@ void RenX::ExemptionDatabase::add(uint32_t ip, uint8_t prefix_length, uint64_t s
entry->prefix_length = prefix_length; entry->prefix_length = prefix_length;
entry->setter = setter; entry->setter = setter;
entries.add(entry); m_entries.push_back(std::move(entry));
RenX::ExemptionDatabase::write(entry); write(m_entries.back().get());
} }
bool RenX::ExemptionDatabase::deactivate(size_t index) bool RenX::ExemptionDatabase::deactivate(size_t index) {
{ Entry* entry = m_entries[index].get();
RenX::ExemptionDatabase::Entry *entry = RenX::ExemptionDatabase::entries.get(index); if (entry->is_active()) {
if (entry->is_active())
{
entry->unset_active(); entry->unset_active();
FILE *file = fopen(RenX::ExemptionDatabase::filename.c_str(), "r+b"); FILE *file = fopen(m_filename.c_str(), "r+b");
if (file != nullptr) if (file != nullptr) {
{
fsetpos(file, &entry->pos); fsetpos(file, &entry->pos);
fseek(file, sizeof(size_t), SEEK_CUR); fseek(file, sizeof(size_t), SEEK_CUR);
fwrite(std::addressof(entry->flags), sizeof(entry->flags), 1, file); fwrite(std::addressof(entry->flags), sizeof(entry->flags), 1, file);
@ -146,51 +133,43 @@ bool RenX::ExemptionDatabase::deactivate(size_t index)
return false; return false;
} }
void RenX::ExemptionDatabase::exemption_check(RenX::PlayerInfo &player) void RenX::ExemptionDatabase::exemption_check(RenX::PlayerInfo &player) {
{ Entry* entry;
RenX::ExemptionDatabase::Entry *entry;
uint32_t netmask; uint32_t netmask;
size_t index = RenX::ExemptionDatabase::entries.size(); size_t index = m_entries.size();
while (index != 0) while (index != 0) {
{ entry = m_entries[--index].get();
entry = RenX::ExemptionDatabase::entries.get(--index); if (entry->is_active()) {
if (entry->is_active()) if (entry->length == std::chrono::seconds::zero() || entry->timestamp + entry->length < std::chrono::system_clock::now()) {
{
if (entry->length == std::chrono::seconds::zero() || entry->timestamp + entry->length < std::chrono::system_clock::now())
{
netmask = Jupiter_prefix_length_to_netmask(entry->prefix_length); netmask = Jupiter_prefix_length_to_netmask(entry->prefix_length);
if ((player.steamid != 0 && entry->steamid == player.steamid) // SteamID exemption if ((player.steamid != 0 && entry->steamid == player.steamid) // SteamID exemption
|| (player.ip32 != 0U && (player.ip32 & netmask) == (entry->ip & netmask))) // IP address exemption || (player.ip32 != 0U && (player.ip32 & netmask) == (entry->ip & netmask))) { // IP address exemption
player.exemption_flags |= entry->flags; player.exemption_flags |= entry->flags;
}
}
else {
deactivate(index);
} }
else
RenX::ExemptionDatabase::deactivate(index);
} }
} }
} }
uint8_t RenX::ExemptionDatabase::getVersion() const uint8_t RenX::ExemptionDatabase::getVersion() const {
{ return m_write_version;
return RenX::ExemptionDatabase::write_version;
} }
const std::string &RenX::ExemptionDatabase::getFileName() const const std::string &RenX::ExemptionDatabase::getFileName() const {
{ return m_filename;
return RenX::ExemptionDatabase::filename;
} }
const Jupiter::ArrayList<RenX::ExemptionDatabase::Entry> &RenX::ExemptionDatabase::getEntries() const const std::vector<std::unique_ptr<RenX::ExemptionDatabase::Entry>>& RenX::ExemptionDatabase::getEntries() const {
{ return m_entries;
return RenX::ExemptionDatabase::entries;
} }
bool RenX::ExemptionDatabase::initialize() bool RenX::ExemptionDatabase::initialize() {
{ m_filename = static_cast<std::string>(RenX::getCore()->getConfig().get("ExemptionDB"_jrs, "Exemptions.db"_jrs));
RenX::ExemptionDatabase::filename = static_cast<std::string>(RenX::getCore()->getConfig().get("ExemptionDB"_jrs, "Exemptions.db"_jrs)); return this->process_file(m_filename);
return this->process_file(filename);
} }
RenX::ExemptionDatabase::~ExemptionDatabase() RenX::ExemptionDatabase::~ExemptionDatabase() {
{
RenX::ExemptionDatabase::entries.emptyAndDelete();
} }

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016-2017 Jessica James. * Copyright (C) 2016-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -23,7 +23,6 @@
#include <chrono> #include <chrono>
#include "Jupiter/Database.h" #include "Jupiter/Database.h"
#include "Jupiter/String.hpp" #include "Jupiter/String.hpp"
#include "Jupiter/ArrayList.h"
#include "RenX.h" #include "RenX.h"
/** DLL Linkage Nagging */ /** DLL Linkage Nagging */
@ -179,19 +178,19 @@ namespace RenX
* *
* @return List of entries * @return List of entries
*/ */
const Jupiter::ArrayList<RenX::ExemptionDatabase::Entry> &getEntries() const; const std::vector<std::unique_ptr<RenX::ExemptionDatabase::Entry>>& getEntries() const;
virtual bool initialize(); virtual bool initialize();
~ExemptionDatabase(); ~ExemptionDatabase();
private: private:
/** Database version */ /** Database version */
const uint8_t write_version = 0U; const uint8_t m_write_version = 0U;
uint8_t read_version = write_version; uint8_t m_read_version = m_write_version;
fpos_t eof; fpos_t m_eof;
std::string filename; std::string m_filename;
Jupiter::ArrayList<RenX::ExemptionDatabase::Entry> entries; std::vector<std::unique_ptr<RenX::ExemptionDatabase::Entry>> m_entries;
}; };
RENX_API extern RenX::ExemptionDatabase *exemptionDatabase; RENX_API extern RenX::ExemptionDatabase *exemptionDatabase;

82
src/Plugins/RenX/RenX.Core/RenX_GameCommand.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -19,95 +19,83 @@
#include "RenX_GameCommand.h" #include "RenX_GameCommand.h"
#include "RenX_Server.h" #include "RenX_Server.h"
Jupiter::ArrayList<RenX::GameCommand> _GameMasterCommandList; std::vector<RenX::GameCommand*> g_GameMasterCommandList;
Jupiter::ArrayList<RenX::GameCommand> *RenX::GameMasterCommandList = &_GameMasterCommandList; std::vector<RenX::GameCommand*> &RenX::GameMasterCommandList = g_GameMasterCommandList;
RenX::Server *RenX::GameCommand::active_server = nullptr; RenX::Server *RenX::GameCommand::active_server = nullptr;
RenX::Server *RenX::GameCommand::selected_server = nullptr; RenX::Server *RenX::GameCommand::selected_server = nullptr;
RenX::GameCommand::GameCommand(std::nullptr_t) RenX::GameCommand::GameCommand(std::nullptr_t) {
{
} }
RenX::GameCommand::GameCommand(const RenX::GameCommand &command) RenX::GameCommand::GameCommand(const RenX::GameCommand &command) {
{
//RenX::GameMasterCommandList->add(this); //RenX::GameMasterCommandList->add(this);
} }
RenX::GameCommand::GameCommand() RenX::GameCommand::GameCommand() {
{ RenX::GameMasterCommandList.push_back(this);
RenX::GameMasterCommandList->add(this);
} }
RenX::GameCommand::~GameCommand() RenX::GameCommand::~GameCommand() {
{
RenX::Core *core = RenX::getCore(); RenX::Core *core = RenX::getCore();
for (size_t command_index = 0; command_index != RenX::GameMasterCommandList->size(); ++command_index) for (auto itr = RenX::GameMasterCommandList.begin(); itr != RenX::GameMasterCommandList.end(); ++itr) {
{ if (*itr == this) {
if (RenX::GameMasterCommandList->get(command_index) == this)
{
RenX::Server *server; RenX::Server *server;
for (size_t server_index = 0; server_index != core->getServerCount(); ++server_index) for (size_t server_index = 0; server_index != core->getServerCount(); ++server_index) {
{
server = core->getServer(server_index); server = core->getServer(server_index);
if (server != nullptr) if (server != nullptr) {
server->removeCommand(this->getTrigger()); server->removeCommand(this->getTrigger());
}
} }
RenX::GameMasterCommandList->remove(command_index); RenX::GameMasterCommandList.erase(itr);
break; break;
} }
} }
} }
int RenX::GameCommand::getAccessLevel() int RenX::GameCommand::getAccessLevel() {
{
return RenX::GameCommand::access; return RenX::GameCommand::access;
} }
void RenX::GameCommand::setAccessLevel(int accessLevel) void RenX::GameCommand::setAccessLevel(int accessLevel) {
{
RenX::GameCommand::access = accessLevel; RenX::GameCommand::access = accessLevel;
} }
// Basic Game Command // Basic Game Command
RenX::BasicGameCommand::BasicGameCommand() : RenX::GameCommand(nullptr) RenX::BasicGameCommand::BasicGameCommand() : RenX::GameCommand(nullptr) {
{
} }
RenX::BasicGameCommand::BasicGameCommand(BasicGameCommand &c) : RenX::GameCommand(c) RenX::BasicGameCommand::BasicGameCommand(BasicGameCommand &c) : RenX::GameCommand(c) {
{
} }
RenX::BasicGameCommand::BasicGameCommand(const Jupiter::ReadableString &in_trigger, const Jupiter::ReadableString &in_message, const Jupiter::ReadableString &in_help_message) : RenX::GameCommand(nullptr) RenX::BasicGameCommand::BasicGameCommand(const Jupiter::ReadableString &in_trigger, const Jupiter::ReadableString &in_message, const Jupiter::ReadableString &in_help_message)
{ : RenX::GameCommand(nullptr) {
this->addTrigger(in_trigger); this->addTrigger(in_trigger);
RenX::BasicGameCommand::message = in_message; m_message = in_message;
RenX::BasicGameCommand::help_message = in_help_message; m_help_message = in_help_message;
} }
void RenX::BasicGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) void RenX::BasicGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
{ source->sendMessage(m_message);
source->sendMessage(RenX::BasicGameCommand::message);
} }
const Jupiter::ReadableString &RenX::BasicGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &RenX::BasicGameCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Returns a basic text string."); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Returns a basic text string.");
if (RenX::BasicGameCommand::help_message.isEmpty()) if (m_help_message.isEmpty()) {
return defaultHelp; return defaultHelp;
return RenX::BasicGameCommand::help_message; }
return m_help_message;
} }
RenX::BasicGameCommand *RenX::BasicGameCommand::copy() RenX::BasicGameCommand *RenX::BasicGameCommand::copy() {
{ RenX::BasicGameCommand* result = new RenX::BasicGameCommand(*this);
RenX::BasicGameCommand *r = new RenX::BasicGameCommand(*this); result->m_message = m_message;
r->message = RenX::BasicGameCommand::message; result->m_help_message = m_help_message;
r->help_message = RenX::BasicGameCommand::help_message; return result;
return r;
} }
void RenX::BasicGameCommand::create() void RenX::BasicGameCommand::create() {
{
} }

6
src/Plugins/RenX/RenX.Core/RenX_GameCommand.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2015 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -43,7 +43,7 @@ namespace RenX
class GameCommand; class GameCommand;
/** Master command list */ /** Master command list */
RENX_API extern Jupiter::ArrayList<GameCommand> *GameMasterCommandList; RENX_API extern std::vector<GameCommand*>& GameMasterCommandList;
/** /**
* @brief Provides an extendable interface from which in-game commands can be created. * @brief Provides an extendable interface from which in-game commands can be created.
@ -133,7 +133,7 @@ namespace RenX
BasicGameCommand(const Jupiter::ReadableString &trigger, const Jupiter::ReadableString &in_message, const Jupiter::ReadableString &in_help_message); BasicGameCommand(const Jupiter::ReadableString &trigger, const Jupiter::ReadableString &in_message, const Jupiter::ReadableString &in_help_message);
private: private:
Jupiter::StringS message, help_message; Jupiter::StringS m_message, m_help_message;
}; };
} }

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2015-2017 Jessica James. * Copyright (C) 2015-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -22,50 +22,47 @@
#include "RenX_BanDatabase.h" #include "RenX_BanDatabase.h"
RenX::LadderDatabase *RenX::default_ladder_database = nullptr; RenX::LadderDatabase *RenX::default_ladder_database = nullptr;
Jupiter::ArrayList<RenX::LadderDatabase> _ladder_databases; std::vector<RenX::LadderDatabase*> g_ladder_databases;
Jupiter::ArrayList<RenX::LadderDatabase> &RenX::ladder_databases = _ladder_databases; std::vector<RenX::LadderDatabase*>& RenX::ladder_databases = g_ladder_databases;
RenX::LadderDatabase::LadderDatabase() RenX::LadderDatabase::LadderDatabase() {
{ g_ladder_databases.push_back(this);
_ladder_databases.add(this);
if (RenX::default_ladder_database == nullptr) if (RenX::default_ladder_database == nullptr) {
RenX::default_ladder_database = this; RenX::default_ladder_database = this;
}
} }
RenX::LadderDatabase::LadderDatabase(const Jupiter::ReadableString &in_name) : LadderDatabase() RenX::LadderDatabase::LadderDatabase(const Jupiter::ReadableString &in_name) : LadderDatabase() {
{
RenX::LadderDatabase::setName(in_name); RenX::LadderDatabase::setName(in_name);
} }
RenX::LadderDatabase::~LadderDatabase() RenX::LadderDatabase::~LadderDatabase() {
{ while (m_head != nullptr) {
while (RenX::LadderDatabase::head != nullptr) m_end = m_head;
{ m_head = m_head->next;
RenX::LadderDatabase::end = RenX::LadderDatabase::head; delete m_end;
RenX::LadderDatabase::head = RenX::LadderDatabase::head->next;
delete RenX::LadderDatabase::end;
} }
for (size_t index = 0; index != _ladder_databases.size(); ++index) for (auto itr = g_ladder_databases.begin(); itr != g_ladder_databases.end(); ++itr) {
if (_ladder_databases.get(index) == this) if (*itr == this) {
{ g_ladder_databases.erase(itr);
_ladder_databases.remove(index);
break; break;
} }
}
if (RenX::default_ladder_database == this) if (RenX::default_ladder_database == this) {
{ if (g_ladder_databases.empty()) {
if (_ladder_databases.size() == 0)
RenX::default_ladder_database = nullptr; RenX::default_ladder_database = nullptr;
else }
RenX::default_ladder_database = _ladder_databases.get(0); else {
RenX::default_ladder_database = g_ladder_databases[0];
}
} }
} }
void RenX::LadderDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos) void RenX::LadderDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file, fpos_t pos) {
{ Entry *entry = new Entry();
RenX::LadderDatabase::Entry *entry = new RenX::LadderDatabase::Entry();
// read data from buffer to entry // read data from buffer to entry
entry->steam_id = buffer.pop<uint64_t>(); entry->steam_id = buffer.pop<uint64_t>();
@ -80,13 +77,13 @@ void RenX::LadderDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file,
entry->total_captures = buffer.pop<uint32_t>(); entry->total_captures = buffer.pop<uint32_t>();
entry->total_game_time = buffer.pop<uint32_t>(); entry->total_game_time = buffer.pop<uint32_t>();
entry->total_games = buffer.pop<uint32_t>(); entry->total_games = buffer.pop<uint32_t>();
if (this->read_version == 0) if (m_read_version == 0)
{ {
entry->total_gdi_games = buffer.pop<uint32_t>(); entry->total_gdi_games = buffer.pop<uint32_t>();
entry->total_nod_games = buffer.pop<uint32_t>(); entry->total_nod_games = buffer.pop<uint32_t>();
} }
entry->total_wins = buffer.pop<uint32_t>(); entry->total_wins = buffer.pop<uint32_t>();
if (this->read_version == 0) if (m_read_version == 0)
{ {
entry->total_gdi_wins = buffer.pop<uint32_t>(); entry->total_gdi_wins = buffer.pop<uint32_t>();
entry->total_nod_wins = buffer.pop<uint32_t>(); entry->total_nod_wins = buffer.pop<uint32_t>();
@ -96,7 +93,7 @@ void RenX::LadderDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file,
entry->total_proxy_placements = buffer.pop<uint32_t>(); entry->total_proxy_placements = buffer.pop<uint32_t>();
entry->total_proxy_disarms = buffer.pop<uint32_t>(); entry->total_proxy_disarms = buffer.pop<uint32_t>();
if (this->read_version > 0) if (m_read_version > 0)
{ {
entry->total_gdi_games = buffer.pop<uint32_t>(); entry->total_gdi_games = buffer.pop<uint32_t>();
entry->total_gdi_wins = buffer.pop<uint32_t>(); entry->total_gdi_wins = buffer.pop<uint32_t>();
@ -149,194 +146,199 @@ void RenX::LadderDatabase::process_data(Jupiter::DataBuffer &buffer, FILE *file,
entry->most_recent_name = buffer.pop<Jupiter::String_Strict, char>(); entry->most_recent_name = buffer.pop<Jupiter::String_Strict, char>();
// push data to list // push data to list
if (RenX::LadderDatabase::head == nullptr) if (m_head == nullptr) {
{ m_head = entry;
RenX::LadderDatabase::head = entry; m_end = m_head;
RenX::LadderDatabase::end = RenX::LadderDatabase::head;
} }
else else {
{ m_end->next = entry;
RenX::LadderDatabase::end->next = entry; entry->prev = m_end;
entry->prev = end; m_end = entry;
end = entry;
} }
entry->rank = ++RenX::LadderDatabase::entries; entry->rank = ++m_entries;
} }
void RenX::LadderDatabase::process_header(FILE *file) void RenX::LadderDatabase::process_header(FILE *file) {
{
int chr = fgetc(file); int chr = fgetc(file);
if (chr != EOF) if (chr != EOF) {
RenX::LadderDatabase::read_version = chr; m_read_version = chr;
}
} }
void RenX::LadderDatabase::create_header(FILE *file) void RenX::LadderDatabase::create_header(FILE *file) {
{ fputc(m_write_version, file);
fputc(RenX::LadderDatabase::write_version, file);
} }
void RenX::LadderDatabase::process_file_finish(FILE *file) void RenX::LadderDatabase::process_file_finish(FILE *file) {
{ if (m_read_version != m_write_version) {
if (RenX::LadderDatabase::read_version != RenX::LadderDatabase::write_version)
{
puts("Notice: Ladder database is out of date; upgrading..."); puts("Notice: Ladder database is out of date; upgrading...");
std::chrono::steady_clock::duration write_duration; std::chrono::steady_clock::duration write_duration;
std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();
RenX::LadderDatabase::write(this->getFilename()); write(this->getFilename());
write_duration = std::chrono::steady_clock::now() - start_time; write_duration = std::chrono::steady_clock::now() - start_time;
printf("Ladder database upgrade completed in %f seconds", 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))); printf("Ladder database upgrade completed in %f seconds", 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)));
RenX::LadderDatabase::read_version = RenX::LadderDatabase::write_version; m_read_version = m_write_version;
} }
} }
RenX::LadderDatabase::Entry *RenX::LadderDatabase::getHead() const RenX::LadderDatabase::Entry *RenX::LadderDatabase::getHead() const {
{ return m_head;
return RenX::LadderDatabase::head;
} }
RenX::LadderDatabase::Entry *RenX::LadderDatabase::getPlayerEntry(uint64_t steamid) const RenX::LadderDatabase::Entry *RenX::LadderDatabase::getPlayerEntry(uint64_t steamid) const {
{ for (Entry *itr = m_head; itr != nullptr; itr = itr->next) {
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next) if (itr->steam_id == steamid) {
if (itr->steam_id == steamid)
return itr; return itr;
}
}
return nullptr; return nullptr;
} }
std::pair<RenX::LadderDatabase::Entry *, size_t> RenX::LadderDatabase::getPlayerEntryAndIndex(uint64_t steamid) const std::pair<RenX::LadderDatabase::Entry *, size_t> RenX::LadderDatabase::getPlayerEntryAndIndex(uint64_t steamid) const {
{
size_t index = 0; size_t index = 0;
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next, ++index) for (Entry *itr = m_head; itr != nullptr; itr = itr->next, ++index) {
if (itr->steam_id == steamid) if (itr->steam_id == steamid) {
return std::pair<RenX::LadderDatabase::Entry *, size_t>(itr, index); return std::pair<Entry*, size_t>(itr, index);
return std::pair<RenX::LadderDatabase::Entry *, size_t>(nullptr, Jupiter::INVALID_INDEX); }
}
return std::pair<Entry*, size_t>(nullptr, Jupiter::INVALID_INDEX);
} }
RenX::LadderDatabase::Entry *RenX::LadderDatabase::getPlayerEntryByName(const Jupiter::ReadableString &name) const RenX::LadderDatabase::Entry *RenX::LadderDatabase::getPlayerEntryByName(const Jupiter::ReadableString &name) const {
{ for (Entry *itr = m_head; itr != nullptr; itr = itr->next) {
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next) if (itr->most_recent_name.equalsi(name)) {
if (itr->most_recent_name.equalsi(name))
return itr; return itr;
}
}
return nullptr; return nullptr;
} }
std::pair<RenX::LadderDatabase::Entry *, size_t> RenX::LadderDatabase::getPlayerEntryAndIndexByName(const Jupiter::ReadableString &name) const std::pair<RenX::LadderDatabase::Entry *, size_t> RenX::LadderDatabase::getPlayerEntryAndIndexByName(const Jupiter::ReadableString &name) const {
{
size_t index = 0; size_t index = 0;
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next, ++index) for (Entry *itr = m_head; itr != nullptr; itr = itr->next, ++index) {
if (itr->most_recent_name.equalsi(name)) if (itr->most_recent_name.equalsi(name)) {
return std::pair<RenX::LadderDatabase::Entry *, size_t>(itr, index); return std::pair<Entry*, size_t>(itr, index);
return std::pair<RenX::LadderDatabase::Entry *, size_t>(nullptr, Jupiter::INVALID_INDEX); }
}
return std::pair<Entry*, size_t>(nullptr, Jupiter::INVALID_INDEX);
} }
RenX::LadderDatabase::Entry *RenX::LadderDatabase::getPlayerEntryByPartName(const Jupiter::ReadableString &name) const RenX::LadderDatabase::Entry *RenX::LadderDatabase::getPlayerEntryByPartName(const Jupiter::ReadableString &name) const {
{ for (Entry *itr = m_head; itr != nullptr; itr = itr->next) {
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next) if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) {
if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX)
return itr; return itr;
}
}
return nullptr; return nullptr;
} }
std::pair<RenX::LadderDatabase::Entry *, size_t> RenX::LadderDatabase::getPlayerEntryAndIndexByPartName(const Jupiter::ReadableString &name) const std::pair<RenX::LadderDatabase::Entry *, size_t> RenX::LadderDatabase::getPlayerEntryAndIndexByPartName(const Jupiter::ReadableString &name) const {
{
size_t index = 0; size_t index = 0;
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next, ++index) for (Entry *itr = m_head; itr != nullptr; itr = itr->next, ++index) {
if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) {
return std::pair<RenX::LadderDatabase::Entry *, size_t>(itr, index); return std::pair<RenX::LadderDatabase::Entry*, size_t>(itr, index);
return std::pair<RenX::LadderDatabase::Entry *, size_t>(nullptr, Jupiter::INVALID_INDEX); }
}
return std::pair<Entry *, size_t>(nullptr, Jupiter::INVALID_INDEX);
} }
std::forward_list<RenX::LadderDatabase::Entry> RenX::LadderDatabase::getPlayerEntriesByPartName(const Jupiter::ReadableString &name, size_t max) const std::forward_list<RenX::LadderDatabase::Entry> RenX::LadderDatabase::getPlayerEntriesByPartName(const Jupiter::ReadableString &name, size_t max) const {
{ std::forward_list<Entry> list;
std::forward_list<RenX::LadderDatabase::Entry> list; if (max == 0) {
if (max == 0) for (Entry *itr = m_head; itr != nullptr; itr = itr->next) {
{ if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) {
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next)
if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX)
list.emplace_front(*itr); list.emplace_front(*itr);
}
}
} }
else else {
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next) for (Entry* itr = m_head; itr != nullptr; itr = itr->next) {
if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) {
{
list.emplace_front(*itr); list.emplace_front(*itr);
if (--max == 0) if (--max == 0) {
return list; return list;
}
} }
}
}
return list; return list;
} }
std::forward_list<std::pair<RenX::LadderDatabase::Entry, size_t>> RenX::LadderDatabase::getPlayerEntriesAndIndexByPartName(const Jupiter::ReadableString &name, size_t max) const std::forward_list<std::pair<RenX::LadderDatabase::Entry, size_t>> RenX::LadderDatabase::getPlayerEntriesAndIndexByPartName(const Jupiter::ReadableString &name, size_t max) const {
{ std::forward_list<std::pair<Entry, size_t>> list;
std::forward_list<std::pair<RenX::LadderDatabase::Entry, size_t>> list;
size_t index = 0; size_t index = 0;
if (max == 0) if (max == 0)
{ {
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next, ++index) for (Entry *itr = m_head; itr != nullptr; itr = itr->next, ++index) {
if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) {
list.emplace_front(*itr, index); list.emplace_front(*itr, index);
}
}
} }
else else {
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next, ++index) for (Entry* itr = m_head; itr != nullptr; itr = itr->next, ++index) {
if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) if (itr->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) {
{
list.emplace_front(*itr, index); list.emplace_front(*itr, index);
if (--max) if (--max) {
return list; return list;
}
} }
}
}
return list; return list;
} }
RenX::LadderDatabase::Entry *RenX::LadderDatabase::getPlayerEntryByIndex(size_t index) const RenX::LadderDatabase::Entry *RenX::LadderDatabase::getPlayerEntryByIndex(size_t index) const {
{ for (Entry *itr = m_head; itr != nullptr; itr = itr->next, --index) {
for (RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; itr != nullptr; itr = itr->next, --index) if (index == 0) {
if (index == 0)
return itr; return itr;
}
}
return nullptr; return nullptr;
} }
size_t RenX::LadderDatabase::getEntries() const size_t RenX::LadderDatabase::getEntries() const {
{ return m_entries;
return RenX::LadderDatabase::entries;
} }
std::chrono::steady_clock::time_point RenX::LadderDatabase::getLastSortTime() const std::chrono::steady_clock::time_point RenX::LadderDatabase::getLastSortTime() const {
{ return m_last_sort;
return RenX::LadderDatabase::last_sort;
} }
void RenX::LadderDatabase::append(RenX::LadderDatabase::Entry *entry) void RenX::LadderDatabase::append(Entry *entry) {
{ ++m_entries;
++RenX::LadderDatabase::entries; if (m_head == nullptr) {
if (RenX::LadderDatabase::head == nullptr) m_head = entry;
{ m_end = m_head;
RenX::LadderDatabase::head = entry;
RenX::LadderDatabase::end = RenX::LadderDatabase::head;
return; return;
} }
RenX::LadderDatabase::end->next = entry; m_end->next = entry;
entry->prev = RenX::LadderDatabase::end; entry->prev = m_end;
RenX::LadderDatabase::end = entry; m_end = entry;
} }
void RenX::LadderDatabase::write(const std::string &filename) void RenX::LadderDatabase::write(const std::string &filename) {
{ return write(filename.c_str());
return RenX::LadderDatabase::write(filename.c_str());
} }
void RenX::LadderDatabase::write(const char *filename) void RenX::LadderDatabase::write(const char *filename) {
{ if (m_entries != 0)
if (RenX::LadderDatabase::entries != 0)
{ {
FILE *file = fopen(filename, "wb"); FILE *file = fopen(filename, "wb");
if (file != nullptr) if (file != nullptr)
{ {
size_t rank = 0; size_t rank = 0;
Jupiter::DataBuffer buffer; Jupiter::DataBuffer buffer;
RenX::LadderDatabase::create_header(file); create_header(file);
RenX::LadderDatabase::Entry *entry = RenX::LadderDatabase::head; Entry *entry = m_head;
while (entry != nullptr) while (entry != nullptr)
{ {
// update rank // update rank
@ -421,42 +423,38 @@ void RenX::LadderDatabase::write(const char *filename)
} }
} }
void RenX::LadderDatabase::sort_entries() void RenX::LadderDatabase::sort_entries() {
{ if (m_entries <= 1) {
if (RenX::LadderDatabase::entries <= 1)
return; return;
}
RenX::LadderDatabase::Entry *itr = RenX::LadderDatabase::head; Entry *itr = m_head;
RenX::LadderDatabase::Entry *itr2, *ptr; Entry *itr2, *ptr;
// iterate forward (search for out-of-order content) // iterate forward (search for out-of-order content)
while (itr->next != nullptr) while (itr->next != nullptr) {
{
// out-of-order content found // out-of-order content found
if (itr->next->total_score > itr->total_score) if (itr->next->total_score > itr->total_score) {
{
// pull content out // pull content out
ptr = itr->next; ptr = itr->next;
itr->next = ptr->next; itr->next = ptr->next;
if (itr->next != nullptr) if (itr->next != nullptr) {
itr->next->prev = itr; itr->next->prev = itr;
}
// iterate backwards from our iterator, and insert // iterate backwards from our iterator, and insert
itr2 = itr; itr2 = itr;
while (true) while (true) {
{ if (itr2->prev == nullptr) {
if (itr2->prev == nullptr)
{
// push ptr to head // push ptr to head
ptr->next = itr2; ptr->next = itr2;
ptr->prev = nullptr; ptr->prev = nullptr;
itr2->prev = ptr; itr2->prev = ptr;
RenX::LadderDatabase::head = ptr; m_head = ptr;
break; break;
} }
itr2 = itr2->prev; itr2 = itr2->prev;
if (itr2->total_score > ptr->total_score) if (itr2->total_score > ptr->total_score) {
{
// insert ptr after itr2 // insert ptr after itr2
ptr->next = itr2->next; ptr->next = itr2->next;
ptr->next->prev = ptr; ptr->next->prev = ptr;
@ -466,33 +464,30 @@ void RenX::LadderDatabase::sort_entries()
} }
} }
} }
else // continue iterating else { // continue iterating
itr = itr->next; itr = itr->next;
}
} }
RenX::LadderDatabase::end = itr; m_end = itr;
RenX::LadderDatabase::last_sort = std::chrono::steady_clock::now(); m_last_sort = std::chrono::steady_clock::now();
} }
void RenX::LadderDatabase::updateLadder(RenX::Server &server, const RenX::TeamType &team) void RenX::LadderDatabase::updateLadder(RenX::Server &server, const RenX::TeamType &team) {
{ if (server.players.size() != server.getBotCount()) {
if (server.players.size() != server.getBotCount())
{
// call the PreUpdateLadder event // call the PreUpdateLadder event
if (this->OnPreUpdateLadder != nullptr) if (this->OnPreUpdateLadder != nullptr) {
this->OnPreUpdateLadder(*this, server, team); this->OnPreUpdateLadder(*this, server, team);
}
// update player stats in memory // update player stats in memory
RenX::LadderDatabase::Entry *entry; Entry *entry;
for (auto player = server.players.begin(); player != server.players.end(); ++player) for (auto player = server.players.begin(); player != server.players.end(); ++player) {
{ if (player->steamid != 0 && (player->ban_flags & RenX::BanDatabase::Entry::FLAG_TYPE_LADDER) == 0) {
if (player->steamid != 0 && (player->ban_flags & RenX::BanDatabase::Entry::FLAG_TYPE_LADDER) == 0) entry = getPlayerEntry(player->steamid);
{ if (entry == nullptr) {
entry = RenX::LadderDatabase::getPlayerEntry(player->steamid); entry = new Entry();
if (entry == nullptr) append(entry);
{
entry = new RenX::LadderDatabase::Entry();
RenX::LadderDatabase::append(entry);
entry->steam_id = player->steamid; entry->steam_id = player->steamid;
} }
@ -512,8 +507,7 @@ void RenX::LadderDatabase::updateLadder(RenX::Server &server, const RenX::TeamTy
entry->total_proxy_disarms += player->proxy_disarms; entry->total_proxy_disarms += player->proxy_disarms;
++entry->total_games; ++entry->total_games;
switch (player->team) switch (player->team) {
{
case RenX::TeamType::GDI: case RenX::TeamType::GDI:
++entry->total_gdi_games; ++entry->total_gdi_games;
if (player->team == team) if (player->team == team)
@ -560,10 +554,10 @@ void RenX::LadderDatabase::updateLadder(RenX::Server &server, const RenX::TeamTy
break; break;
} }
auto set_if_greater = [](uint32_t &src, const uint32_t &cmp) auto set_if_greater = [](uint32_t &src, const uint32_t &cmp) {
{ if (cmp > src) {
if (cmp > src)
src = cmp; src = cmp;
}
}; };
set_if_greater(entry->top_score, static_cast<uint32_t>(player->score)); set_if_greater(entry->top_score, static_cast<uint32_t>(player->score));
@ -588,18 +582,18 @@ void RenX::LadderDatabase::updateLadder(RenX::Server &server, const RenX::TeamTy
// sort new stats // sort new stats
std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();
RenX::LadderDatabase::sort_entries(); sort_entries();
std::chrono::steady_clock::duration sort_duration = std::chrono::steady_clock::now() - start_time; std::chrono::steady_clock::duration sort_duration = std::chrono::steady_clock::now() - start_time;
// write new stats // write new stats
start_time = std::chrono::steady_clock::now(); start_time = std::chrono::steady_clock::now();
RenX::LadderDatabase::write(this->getFilename()); write(this->getFilename());
std::chrono::steady_clock::duration write_duration = std::chrono::steady_clock::now() - start_time; std::chrono::steady_clock::duration write_duration = std::chrono::steady_clock::now() - start_time;
if (RenX::LadderDatabase::output_times) if (m_output_times)
{ {
Jupiter::StringS str = Jupiter::StringS::Format("Ladder: %zu entries sorted in %f seconds; Database written in %f seconds." ENDL, Jupiter::StringS str = Jupiter::StringS::Format("Ladder: %zu entries sorted in %f seconds; Database written in %f seconds." ENDL,
RenX::LadderDatabase::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); str.println(stdout);
@ -608,38 +602,32 @@ void RenX::LadderDatabase::updateLadder(RenX::Server &server, const RenX::TeamTy
} }
} }
void RenX::LadderDatabase::erase() void RenX::LadderDatabase::erase() {
{ if (m_head != nullptr) {
if (RenX::LadderDatabase::head != nullptr) m_entries = 0;
{ while (m_head->next != nullptr) {
RenX::LadderDatabase::entries = 0; m_head = m_head->next;
while (RenX::LadderDatabase::head->next != nullptr) delete m_head->prev;
{
RenX::LadderDatabase::head = head->next;
delete head->prev;
} }
delete RenX::LadderDatabase::head;
RenX::LadderDatabase::head = nullptr; delete m_head;
RenX::LadderDatabase::end = nullptr; m_head = nullptr;
m_end = nullptr;
} }
} }
const Jupiter::ReadableString &RenX::LadderDatabase::getName() const const Jupiter::ReadableString &RenX::LadderDatabase::getName() const {
{ return m_name;
return RenX::LadderDatabase::name;
} }
void RenX::LadderDatabase::setName(const Jupiter::ReadableString &in_name) void RenX::LadderDatabase::setName(const Jupiter::ReadableString &in_name) {
{ m_name = in_name;
RenX::LadderDatabase::name = in_name;
} }
bool RenX::LadderDatabase::getOutputTimes() const bool RenX::LadderDatabase::getOutputTimes() const {
{ return m_output_times;
return RenX::LadderDatabase::output_times;
} }
void RenX::LadderDatabase::setOutputTimes(bool in_output_times) void RenX::LadderDatabase::setOutputTimes(bool in_output_times) {
{ m_output_times = in_output_times;
RenX::LadderDatabase::output_times = in_output_times;
} }

29
src/Plugins/RenX/RenX.Core/RenX_LadderDatabase.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2015-2017 Jessica James. * Copyright (C) 2015-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -23,7 +23,6 @@
#include <forward_list> #include <forward_list>
#include "Jupiter/Database.h" #include "Jupiter/Database.h"
#include "Jupiter/String.hpp" #include "Jupiter/String.hpp"
#include "Jupiter/ArrayList.h"
#include "RenX.h" #include "RenX.h"
/** DLL Linkage Nagging */ /** DLL Linkage Nagging */
@ -32,12 +31,10 @@
#pragma warning(disable: 4251) #pragma warning(disable: 4251)
#endif #endif
namespace RenX namespace RenX {
{
class Server; class Server;
class RENX_API LadderDatabase : public Jupiter::Database class RENX_API LadderDatabase : public Jupiter::Database {
{
public: // Jupiter::Database public: // Jupiter::Database
/** /**
@ -228,19 +225,19 @@ namespace RenX
private: private:
/** Database version */ /** Database version */
const uint8_t write_version = 1; const uint8_t m_write_version = 1;
uint8_t read_version = write_version; uint8_t m_read_version = m_write_version;
bool output_times = false; bool m_output_times = false;
Jupiter::StringS name; Jupiter::StringS m_name;
std::chrono::steady_clock::time_point last_sort = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point m_last_sort = std::chrono::steady_clock::now();
size_t entries = 0; size_t m_entries = 0;
Entry *head = nullptr; Entry* m_head = nullptr;
Entry *end = nullptr; Entry* m_end = nullptr;
}; };
RENX_API extern RenX::LadderDatabase *default_ladder_database; RENX_API extern RenX::LadderDatabase *default_ladder_database;
RENX_API extern Jupiter::ArrayList<RenX::LadderDatabase> &ladder_databases; RENX_API extern std::vector<RenX::LadderDatabase*>& ladder_databases;
} }
/** Re-enable warnings */ /** Re-enable warnings */

397
src/Plugins/RenX/RenX.Core/RenX_Plugin.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -19,649 +19,520 @@
#include "RenX_Plugin.h" #include "RenX_Plugin.h"
#include "RenX_Core.h" #include "RenX_Core.h"
RenX::Plugin::Plugin() RenX::Plugin::Plugin() {
{ RenX::getCore()->getPlugins().push_back(this);
RenX::getCore()->getPlugins()->add(this);
} }
RenX::Plugin::~Plugin() RenX::Plugin::~Plugin() {
{ auto& renx_plugins = RenX::getCore()->getPlugins();
for (size_t i = 0; i != RenX::getCore()->getPlugins()->size(); i++) for (auto itr = renx_plugins.begin(); itr != renx_plugins.end(); ++itr) {
{ if (*itr == this) {
if (RenX::getCore()->getPlugins()->get(i) == this) RenX::getCore()->getPlugins().erase(itr);
{
RenX::getCore()->getPlugins()->remove(i);
break; break;
} }
} }
} }
void RenX::Plugin::RenX_SanitizeTags(Jupiter::StringType &) void RenX::Plugin::RenX_SanitizeTags(Jupiter::StringType &) {
{
return; return;
} }
void RenX::Plugin::RenX_ProcessTags(Jupiter::StringType &, const Server *, const PlayerInfo *, const PlayerInfo *, const BuildingInfo *) void RenX::Plugin::RenX_ProcessTags(Jupiter::StringType &, const Server *, const PlayerInfo *, const PlayerInfo *, const BuildingInfo *) {
{
return; return;
} }
void RenX::Plugin::RenX_OnPlayerCreate(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnPlayerCreate(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnPlayerDelete(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnPlayerDelete(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnPlayerUUIDChange(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnPlayerUUIDChange(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnPlayerRDNS(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnPlayerRDNS(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnPlayerIdentify(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnPlayerIdentify(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnServerCreate(Server &) void RenX::Plugin::RenX_OnServerCreate(Server &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnServerFullyConnected(Server &) void RenX::Plugin::RenX_OnServerFullyConnected(Server &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnServerDisconnect(Server &, RenX::DisconnectReason) void RenX::Plugin::RenX_OnServerDisconnect(Server &, RenX::DisconnectReason) {
{
return; return;
} }
bool RenX::Plugin::RenX_OnBan(Server &, const PlayerInfo &, Jupiter::StringType &) bool RenX::Plugin::RenX_OnBan(Server &, const PlayerInfo &, Jupiter::StringType &) {
{
return false; return false;
} }
void RenX::Plugin::RenX_OnCommandTriggered(Server& server, const Jupiter::ReadableString& trigger, RenX::PlayerInfo& player, const Jupiter::ReadableString& parameters, GameCommand& command) void RenX::Plugin::RenX_OnCommandTriggered(Server& server, const Jupiter::ReadableString& trigger, RenX::PlayerInfo& player, const Jupiter::ReadableString& parameters, GameCommand& command) {
{
return; return;
} }
void RenX::Plugin::RenX_OnJoin(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnJoin(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnPart(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnPart(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnKick(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnKick(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnNameChange(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnNameChange(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnTeamChange(Server &, const PlayerInfo &, const TeamType &) void RenX::Plugin::RenX_OnTeamChange(Server &, const PlayerInfo &, const TeamType &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnHWID(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnHWID(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnIDChange(Server &, const PlayerInfo &, int) void RenX::Plugin::RenX_OnIDChange(Server &, const PlayerInfo &, int) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDev(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnDev(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnRank(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnRank(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnExecute(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnExecute(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnPlayerCommand(Server &, const PlayerInfo &, const Jupiter::ReadableString &, GameCommand *) void RenX::Plugin::RenX_OnPlayerCommand(Server &, const PlayerInfo &, const Jupiter::ReadableString &, GameCommand *) {
{
return; return;
} }
void RenX::Plugin::RenX_OnSpeedHack(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnSpeedHack(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnPlayer(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnPlayer(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnChat(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnChat(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnTeamChat(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnTeamChat(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnRadioChat(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnRadioChat(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnHostChat(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnHostChat(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnHostPage(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnHostPage(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnAdminMessage(Server &server, const PlayerInfo &player, const Jupiter::ReadableString &message) void RenX::Plugin::RenX_OnAdminMessage(Server &server, const PlayerInfo &player, const Jupiter::ReadableString &message) {
{
return; return;
} }
void RenX::Plugin::RenX_OnWarnMessage(Server &server, const PlayerInfo &player, const Jupiter::ReadableString &message) void RenX::Plugin::RenX_OnWarnMessage(Server &server, const PlayerInfo &player, const Jupiter::ReadableString &message) {
{
return; return;
} }
void RenX::Plugin::RenX_OnAdminPMessage(Server &server, const PlayerInfo &player, const PlayerInfo &target, const Jupiter::ReadableString &message) void RenX::Plugin::RenX_OnAdminPMessage(Server &server, const PlayerInfo &player, const PlayerInfo &target, const Jupiter::ReadableString &message) {
{
return; return;
} }
void RenX::Plugin::RenX_OnWarnPMessage(Server &server, const PlayerInfo &player, const PlayerInfo &target, const Jupiter::ReadableString &message) void RenX::Plugin::RenX_OnWarnPMessage(Server &server, const PlayerInfo &player, const PlayerInfo &target, const Jupiter::ReadableString &message) {
{
return; return;
} }
void RenX::Plugin::RenX_OnHostAdminMessage(Server &server, const Jupiter::ReadableString &message) void RenX::Plugin::RenX_OnHostAdminMessage(Server &server, const Jupiter::ReadableString &message) {
{
return; return;
} }
void RenX::Plugin::RenX_OnHostAdminPMessage(Server &server, const PlayerInfo &player, const Jupiter::ReadableString &message) void RenX::Plugin::RenX_OnHostAdminPMessage(Server &server, const PlayerInfo &player, const Jupiter::ReadableString &message) {
{
return; return;
} }
void RenX::Plugin::RenX_OnHostWarnMessage(Server &server, const Jupiter::ReadableString &message) void RenX::Plugin::RenX_OnHostWarnMessage(Server &server, const Jupiter::ReadableString &message) {
{
return; return;
} }
void RenX::Plugin::RenX_OnHostWarnPMessage(Server &server, const PlayerInfo &player, const Jupiter::ReadableString &message) void RenX::Plugin::RenX_OnHostWarnPMessage(Server &server, const PlayerInfo &player, const Jupiter::ReadableString &message) {
{
return; return;
} }
void RenX::Plugin::RenX_OnOtherChat(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnOtherChat(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDeploy(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnDeploy(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnOverMine(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnOverMine(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDisarm(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnDisarm(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDisarm(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const PlayerInfo &) void RenX::Plugin::RenX_OnDisarm(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnExplode(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnExplode(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnExplode(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnExplode(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnSuicide(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnSuicide(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnKill(Server &, const PlayerInfo &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnKill(Server &, const PlayerInfo &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnKill(Server &, const Jupiter::ReadableString &, const TeamType &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnKill(Server &, const Jupiter::ReadableString &, const TeamType &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDie(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnDie(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDie(Server &, const Jupiter::ReadableString &, const TeamType &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnDie(Server &, const Jupiter::ReadableString &, const TeamType &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDestroy(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const TeamType &, const Jupiter::ReadableString &, ObjectType) void RenX::Plugin::RenX_OnDestroy(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const TeamType &, const Jupiter::ReadableString &, ObjectType) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDestroy(Server &, const Jupiter::ReadableString &, const TeamType &, const Jupiter::ReadableString &, const TeamType &, const Jupiter::ReadableString &, ObjectType) void RenX::Plugin::RenX_OnDestroy(Server &, const Jupiter::ReadableString &, const TeamType &, const Jupiter::ReadableString &, const TeamType &, const Jupiter::ReadableString &, ObjectType) {
{
return; return;
} }
void RenX::Plugin::RenX_OnCapture(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const TeamType &) void RenX::Plugin::RenX_OnCapture(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const TeamType &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnNeutralize(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const TeamType &) void RenX::Plugin::RenX_OnNeutralize(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const TeamType &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnCharacterPurchase(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnCharacterPurchase(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnItemPurchase(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnItemPurchase(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnWeaponPurchase(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnWeaponPurchase(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnRefillPurchase(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnRefillPurchase(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVehiclePurchase(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnVehiclePurchase(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVehicleSpawn(Server &, const TeamType &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnVehicleSpawn(Server &, const TeamType &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnSpawn(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnSpawn(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnBotJoin(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnBotJoin(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVehicleCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnVehicleCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnTSVehicleCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnTSVehicleCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnRAVehicleCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnRAVehicleCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDeathCrate(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnDeathCrate(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnMoneyCrate(Server &, const PlayerInfo &, int) void RenX::Plugin::RenX_OnMoneyCrate(Server &, const PlayerInfo &, int) {
{
return; return;
} }
void RenX::Plugin::RenX_OnCharacterCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnCharacterCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnSpyCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnSpyCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnRefillCrate(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnRefillCrate(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnTimeBombCrate(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnTimeBombCrate(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnSpeedCrate(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnSpeedCrate(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnNukeCrate(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnNukeCrate(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnAbductionCrate(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnAbductionCrate(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnUnspecifiedCrate(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnUnspecifiedCrate(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnOtherCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnOtherCrate(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnSteal(Server &, const PlayerInfo &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnSteal(Server &, const PlayerInfo &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnSteal(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const PlayerInfo &) void RenX::Plugin::RenX_OnSteal(Server &, const PlayerInfo &, const Jupiter::ReadableString &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDonate(Server &, const PlayerInfo &, const PlayerInfo &, double) void RenX::Plugin::RenX_OnDonate(Server &, const PlayerInfo &, const PlayerInfo &, double) {
{
return; return;
} }
void RenX::Plugin::RenX_OnGameOver(Server &, RenX::WinType, const TeamType &, int, int) void RenX::Plugin::RenX_OnGameOver(Server &, RenX::WinType, const TeamType &, int, int) {
{
return; return;
} }
void RenX::Plugin::RenX_OnGame(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnGame(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnExecute(Server &, const Jupiter::ReadableString &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnExecute(Server &, const Jupiter::ReadableString &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnSubscribe(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnSubscribe(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnUnsubscribe(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnUnsubscribe(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnBlock(Server &, const Jupiter::ReadableString &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnBlock(Server &, const Jupiter::ReadableString &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnConnect(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnConnect(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnAuthenticate(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnAuthenticate(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnBan(Server &, const Jupiter::ReadableString &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnBan(Server &, const Jupiter::ReadableString &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnInvalidPassword(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnInvalidPassword(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDrop(Server &, const Jupiter::ReadableString &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnDrop(Server &, const Jupiter::ReadableString &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDisconnect(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnDisconnect(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnStopListen(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnStopListen(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnResumeListen(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnResumeListen(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnWarning(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnWarning(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnRCON(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnRCON(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnAdminLogin(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnAdminLogin(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnAdminGrant(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnAdminGrant(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnAdminLogout(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnAdminLogout(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnAdmin(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnAdmin(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteAddBots(Server &, const TeamType &, const PlayerInfo &, const TeamType &, int, int) void RenX::Plugin::RenX_OnVoteAddBots(Server &, const TeamType &, const PlayerInfo &, const TeamType &, int, int) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteChangeMap(Server &, const TeamType &, const PlayerInfo &) void RenX::Plugin::RenX_OnVoteChangeMap(Server &, const TeamType &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteKick(Server &, const TeamType &, const PlayerInfo &, const PlayerInfo &) void RenX::Plugin::RenX_OnVoteKick(Server &, const TeamType &, const PlayerInfo &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteMineBan(Server &, const TeamType &, const PlayerInfo &, const PlayerInfo &) void RenX::Plugin::RenX_OnVoteMineBan(Server &, const TeamType &, const PlayerInfo &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteRemoveBots(Server &, const TeamType &, const PlayerInfo &, const TeamType &, int) void RenX::Plugin::RenX_OnVoteRemoveBots(Server &, const TeamType &, const PlayerInfo &, const TeamType &, int) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteRestartMap(Server &, const TeamType &, const PlayerInfo &) void RenX::Plugin::RenX_OnVoteRestartMap(Server &, const TeamType &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteSurrender(Server &, const TeamType &, const PlayerInfo &) void RenX::Plugin::RenX_OnVoteSurrender(Server &, const TeamType &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteSurvey(Server &, const TeamType &, const PlayerInfo &, const Jupiter::ReadableString &text) void RenX::Plugin::RenX_OnVoteSurvey(Server &, const TeamType &, const PlayerInfo &, const Jupiter::ReadableString &text) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteOther(Server &, const TeamType &, const Jupiter::ReadableString &, const PlayerInfo &) void RenX::Plugin::RenX_OnVoteOther(Server &, const TeamType &, const Jupiter::ReadableString &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteOver(Server &, const TeamType &, const Jupiter::ReadableString &, bool, int, int) void RenX::Plugin::RenX_OnVoteOver(Server &, const TeamType &, const Jupiter::ReadableString &, bool, int, int) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVoteCancel(Server &, const TeamType &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnVoteCancel(Server &, const TeamType &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVote(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnVote(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnMapChange(Server &, const Jupiter::ReadableString &, bool) void RenX::Plugin::RenX_OnMapChange(Server &, const Jupiter::ReadableString &, bool) {
{
return; return;
} }
void RenX::Plugin::RenX_OnMapLoad(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnMapLoad(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnMapStart(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnMapStart(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnMap(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnMap(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDemoRecord(Server &, const PlayerInfo &) void RenX::Plugin::RenX_OnDemoRecord(Server &, const PlayerInfo &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDemoRecord(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnDemoRecord(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDemoRecordStop(Server &) void RenX::Plugin::RenX_OnDemoRecordStop(Server &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnDemo(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnDemo(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnLog(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnLog(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnCommand(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnCommand(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnError(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnError(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnVersion(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnVersion(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnAuthorized(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnAuthorized(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnOther(Server &, char, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnOther(Server &, char, const Jupiter::ReadableString &) {
{
return; return;
} }
void RenX::Plugin::RenX_OnRaw(Server &, const Jupiter::ReadableString &) void RenX::Plugin::RenX_OnRaw(Server &, const Jupiter::ReadableString &) {
{
return; return;
} }

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

File diff suppressed because it is too large

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -27,7 +27,6 @@
#include <chrono> #include <chrono>
#include <list> #include <list>
#include "Jupiter/TCPSocket.h" #include "Jupiter/TCPSocket.h"
#include "Jupiter/ArrayList.h"
#include "Jupiter/String.hpp" #include "Jupiter/String.hpp"
#include "Jupiter/Config.h" #include "Jupiter/Config.h"
#include "Jupiter/Thinker.h" #include "Jupiter/Thinker.h"
@ -83,9 +82,9 @@ namespace RenX
public: // RenX::Server public: // RenX::Server
std::list<RenX::PlayerInfo> players; /** A list of players in the server */ std::list<RenX::PlayerInfo> players; /** A list of players in the server */
Jupiter::ArrayList<RenX::BuildingInfo> buildings; /** A list of buildings in the server */ std::vector<std::unique_ptr<RenX::BuildingInfo>> buildings; /** A list of buildings in the server */
Jupiter::ArrayList<Jupiter::StringS> mutators; /** A list of buildings the server is running */ std::vector<Jupiter::StringS> mutators; /** A list of buildings the server is running */
Jupiter::ArrayList<RenX::Map> maps; /** A list of maps in the server's rotation */ std::vector<RenX::Map> maps; /** A list of maps in the server's rotation */
Jupiter::Config varData; /** Variable data. */ Jupiter::Config varData; /** Variable data. */
/** /**
@ -1068,89 +1067,90 @@ namespace RenX
void startPing(); void startPing();
/** Tracking variables */ /** Tracking variables */
bool gameover_when_empty = false; bool m_gameover_when_empty = false;
bool gameover_pending = false; bool m_gameover_pending = false;
bool pure = false; bool m_pure = false;
bool connected = false; bool m_connected = false;
bool subscribed = false; bool m_subscribed = false;
bool fully_connected = false; bool m_fully_connected = false;
bool seamless = false; bool m_seamless = false;
bool firstKill = false; bool m_firstKill = false;
bool firstDeath = false; bool m_firstDeath = false;
bool firstAction = false; bool m_firstAction = false;
bool awaitingPong = false; bool m_awaitingPong = false;
bool passworded = false; bool m_passworded = false;
bool steamRequired = false; bool m_steamRequired = false;
bool privateMessageTeamOnly = false; bool m_privateMessageTeamOnly = false;
bool allowPrivateMessaging = true; bool m_allowPrivateMessaging = true;
bool spawnCrates = true; bool m_spawnCrates = true;
bool botsEnabled = true; bool m_botsEnabled = true;
bool competitive = false; bool m_competitive = false;
bool devBot = false; bool m_devBot = false;
bool reliable = false; bool m_reliable = false;
bool m_ranked = false; bool m_ranked = false;
// TODO: Why aren't these enums?
int m_team_mode = 3; /** 0 = static, 1 = swap, 2 = random swap, 3 = shuffle, 4 = traditional (assign as players connect) */ int m_team_mode = 3; /** 0 = static, 1 = swap, 2 = random swap, 3 = shuffle, 4 = traditional (assign as players connect) */
int match_state = 1; /** 0 = pending, 1 = in progress, 2 = over, 3 = travelling */ int m_match_state = 1; /** 0 = pending, 1 = in progress, 2 = over, 3 = travelling */
int m_game_type = 1; /** < 0 = Invalid, 0 = Main Menu, 1 = Rx_Game, 2 = TS_Game, > 2 = Unassigned */ int m_game_type = 1; /** < 0 = Invalid, 0 = Main Menu, 1 = Rx_Game, 2 = TS_Game, > 2 = Unassigned */
int attempts = 0; int m_attempts = 0;
int playerLimit = 0; int m_playerLimit = 0;
int vehicleLimit = 0; int m_vehicleLimit = 0;
int mineLimit = 0; int m_mineLimit = 0;
int timeLimit = 0; int m_timeLimit = 0;
size_t bot_count = 0; size_t m_bot_count = 0;
size_t player_rdns_resolutions_pending = 0; size_t m_player_rdns_resolutions_pending = 0;
unsigned int rconVersion = 0; unsigned int m_rconVersion = 0;
unsigned int gameVersionNumber = 0; unsigned int m_gameVersionNumber = 0;
double crateRespawnAfterPickup = 0.0; double m_crateRespawnAfterPickup = 0.0;
uuid_func calc_uuid; uuid_func m_calc_uuid;
std::chrono::steady_clock::time_point lastAttempt = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point m_lastAttempt = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point gameStart = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point m_gameStart = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point lastClientListUpdate = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point m_lastClientListUpdate = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point lastBuildingListUpdate = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point m_lastBuildingListUpdate = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point lastActivity = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point m_lastActivity = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point lastSendActivity = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point m_lastSendActivity = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point gameover_time; std::chrono::steady_clock::time_point m_gameover_time;
Jupiter::String lastLine; Jupiter::String m_lastLine;
Jupiter::StringS rconUser; Jupiter::StringS m_rconUser;
Jupiter::StringS gameVersion; Jupiter::StringS m_gameVersion;
Jupiter::StringS serverName; Jupiter::StringS m_serverName;
Jupiter::StringS lastCommand; Jupiter::StringS m_lastCommand;
Jupiter::StringS lastCommandParams; Jupiter::StringS m_lastCommandParams;
RenX::Map map; RenX::Map m_map;
Jupiter::TCPSocket sock; Jupiter::TCPSocket m_sock;
Jupiter::ReadableString::TokenizeResult<Jupiter::String_Strict> commandListFormat; Jupiter::ReadableString::TokenizeResult<Jupiter::String_Strict> m_commandListFormat;
Jupiter::ArrayList<RenX::GameCommand> commands; std::vector<std::unique_ptr<RenX::GameCommand>> m_commands;
/** Configuration variables */ /** Configuration variables */
bool rconBan; bool m_rconBan;
bool localBan; bool m_localBan;
bool localSteamBan; bool m_localSteamBan;
bool localIPBan; bool m_localIPBan;
bool localHWIDBan; bool m_localHWIDBan;
bool localRDNSBan; bool m_localRDNSBan;
bool localNameBan; bool m_localNameBan;
bool neverSay; bool m_neverSay;
bool resolve_player_rdns; bool m_resolve_player_rdns;
unsigned short port; unsigned short m_port;
int logChanType; int m_logChanType;
int adminLogChanType; int m_adminLogChanType;
int maxAttempts; int m_maxAttempts;
int steamFormat; /** 16 = hex, 10 = base 10, 8 = octal, -2 = SteamID 2, -3 = SteamID 3 */ int m_steamFormat; /** 16 = hex, 10 = base 10, 8 = octal, -2 = SteamID 2, -3 = SteamID 3 */
std::chrono::milliseconds delay; std::chrono::milliseconds m_delay;
std::chrono::milliseconds clientUpdateRate; std::chrono::milliseconds m_clientUpdateRate;
std::chrono::milliseconds buildingUpdateRate; std::chrono::milliseconds m_buildingUpdateRate;
std::chrono::milliseconds pingRate; std::chrono::milliseconds m_pingRate;
std::chrono::milliseconds pingTimeoutThreshold; std::chrono::milliseconds m_pingTimeoutThreshold;
std::string clientHostname; std::string m_clientHostname;
std::string hostname; std::string m_hostname;
Jupiter::StringS pass; Jupiter::StringS m_pass;
Jupiter::StringS configSection; Jupiter::StringS m_configSection;
Jupiter::StringS rules; Jupiter::StringS m_rules;
Jupiter::StringS ban_from_str; Jupiter::StringS m_ban_from_str;
Jupiter::StringS IRCPrefix; Jupiter::StringS m_IRCPrefix;
Jupiter::StringS CommandPrefix; Jupiter::StringS m_CommandPrefix;
Jupiter::Config *commandAccessLevels; Jupiter::Config* m_commandAccessLevels;
Jupiter::Config *commandAliases; Jupiter::Config* m_commandAliases;
}; };
} }

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2015-2017 Jessica James. * Copyright (C) 2015-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -581,9 +581,9 @@ void TagsImp::processTags(Jupiter::StringType &msg, const RenX::Server *server,
PROCESS_TAG(this->INTERNAL_BUILDING_TEAM_LONG_TAG, RenX::getFullTeamName(building->team)); PROCESS_TAG(this->INTERNAL_BUILDING_TEAM_LONG_TAG, RenX::getFullTeamName(building->team));
} }
Jupiter::ArrayList<RenX::Plugin> &xPlugins = *RenX::getCore()->getPlugins(); for (const auto& plugin : RenX::getCore()->getPlugins()) {
for (index = 0; index < xPlugins.size(); ++index) plugin->RenX_ProcessTags(msg, server, player, victim, building);
xPlugins.get(index)->RenX_ProcessTags(msg, server, player, victim, building); }
} }
void TagsImp::processTags(Jupiter::StringType &msg, const RenX::LadderDatabase::Entry &entry) void TagsImp::processTags(Jupiter::StringType &msg, const RenX::LadderDatabase::Entry &entry)
@ -867,9 +867,9 @@ void TagsImp::sanitizeTags(Jupiter::StringType &fmt)
fmt.replace(this->winScoreTag, this->INTERNAL_WIN_SCORE_TAG); fmt.replace(this->winScoreTag, this->INTERNAL_WIN_SCORE_TAG);
fmt.replace(this->loseScoreTag, this->INTERNAL_LOSE_SCORE_TAG); fmt.replace(this->loseScoreTag, this->INTERNAL_LOSE_SCORE_TAG);
Jupiter::ArrayList<RenX::Plugin> &xPlugins = *RenX::getCore()->getPlugins(); for (const auto& plugin : RenX::getCore()->getPlugins()) {
for (size_t i = 0; i < xPlugins.size(); i++) plugin->RenX_SanitizeTags(fmt);
xPlugins.get(i)->RenX_SanitizeTags(fmt); }
} }
const Jupiter::ReadableString &TagsImp::getUniqueInternalTag() const Jupiter::ReadableString &TagsImp::getUniqueInternalTag()

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -24,36 +24,33 @@
using namespace Jupiter::literals; using namespace Jupiter::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 Jupiter::ReadableString &m)
{
Jupiter::String msg = m; Jupiter::String msg = m;
RenX::sanitizeTags(msg); RenX::sanitizeTags(msg);
RenX::processTags(msg, &server, &player); RenX::processTags(msg, &server, &player);
if (this->sendPrivate) if (m_sendPrivate)
server.sendMessage(player, msg); server.sendMessage(player, msg);
else else
server.sendMessage(msg); server.sendMessage(msg);
}; };
if (player.isBot == false && server.isMatchInProgress())
{ if (player.isBot == false && server.isMatchInProgress()) {
switch (RenX_GreetingsPlugin::sendMode) switch (m_sendMode) {
{
case 0: case 0:
RenX_GreetingsPlugin::lastLine = rand() % RenX_GreetingsPlugin::greetingsFile.getLineCount(); m_lastLine = rand() % m_greetingsFile.getLineCount();
sendMessage(RenX_GreetingsPlugin::greetingsFile.getLine(RenX_GreetingsPlugin::lastLine)); sendMessage(m_greetingsFile.getLine(m_lastLine));
break; break;
case 1: case 1:
if (++RenX_GreetingsPlugin::lastLine == RenX_GreetingsPlugin::greetingsFile.getLineCount()) if (++m_lastLine == m_greetingsFile.getLineCount())
RenX_GreetingsPlugin::lastLine = 0; m_lastLine = 0;
sendMessage(RenX_GreetingsPlugin::greetingsFile.getLine(RenX_GreetingsPlugin::lastLine)); sendMessage(m_greetingsFile.getLine(m_lastLine));
break; break;
case 2: case 2:
for (RenX_GreetingsPlugin::lastLine = 0; RenX_GreetingsPlugin::lastLine != RenX_GreetingsPlugin::greetingsFile.getLineCount(); RenX_GreetingsPlugin::lastLine++) for (m_lastLine = 0; m_lastLine != m_greetingsFile.getLineCount(); m_lastLine++)
sendMessage(RenX_GreetingsPlugin::greetingsFile.getLine(RenX_GreetingsPlugin::lastLine)); sendMessage(m_greetingsFile.getLine(m_lastLine));
break; break;
default: default:
return; return;
@ -61,22 +58,20 @@ void RenX_GreetingsPlugin::RenX_OnJoin(RenX::Server &server, const RenX::PlayerI
} }
} }
int RenX_GreetingsPlugin::OnRehash() int RenX_GreetingsPlugin::OnRehash() {
{
RenX::Plugin::OnRehash(); RenX::Plugin::OnRehash();
RenX_GreetingsPlugin::greetingsFile.unload(); m_greetingsFile.unload();
return RenX_GreetingsPlugin::initialize() ? 0 : -1; return initialize() ? 0 : -1;
} }
bool RenX_GreetingsPlugin::initialize() bool RenX_GreetingsPlugin::initialize() {
{ m_sendPrivate = this->config.get<bool>("SendPrivate"_jrs, true);
RenX_GreetingsPlugin::sendPrivate = this->config.get<bool>("SendPrivate"_jrs, true); m_sendMode = this->config.get<unsigned int>("SendMode"_jrs, 0);
RenX_GreetingsPlugin::sendMode = this->config.get<unsigned int>("SendMode"_jrs, 0); m_greetingsFile.load(this->config.get("GreetingsFile"_jrs, "RenX.Greetings.txt"_jrs));
RenX_GreetingsPlugin::greetingsFile.load(this->config.get("GreetingsFile"_jrs, "RenX.Greetings.txt"_jrs)); if (m_greetingsFile.getLineCount() == 0)
if (RenX_GreetingsPlugin::greetingsFile.getLineCount() == 0) m_greetingsFile.addData("Please notify the server administrator to properly configure or disable server greetings.\r\n"_jrs);
RenX_GreetingsPlugin::greetingsFile.addData("Please notify the server administrator to properly configure or disable server greetings.\r\n"_jrs); m_lastLine = m_greetingsFile.getLineCount() - 1;
RenX_GreetingsPlugin::lastLine = RenX_GreetingsPlugin::greetingsFile.getLineCount() - 1;
return true; return true;
} }
@ -84,7 +79,6 @@ bool RenX_GreetingsPlugin::initialize()
// Plugin instantiation and entry point. // Plugin instantiation and entry point.
RenX_GreetingsPlugin pluginInstance; RenX_GreetingsPlugin pluginInstance;
extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() {
{
return &pluginInstance; return &pluginInstance;
} }

10
src/Plugins/RenX/RenX.Greetings/RenX_Greetings.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -35,10 +35,10 @@ public: // Jupiter::Plugin
int OnRehash() override; int OnRehash() override;
private: private:
bool sendPrivate; bool m_sendPrivate;
unsigned int lastLine; size_t m_lastLine;
unsigned int sendMode = 0; /** 0 = Send greetings randomly, 1 = Send greetings sequentially, 2 = Send all greetings */ unsigned int m_sendMode = 0; /** 0 = Send greetings randomly, 1 = Send greetings sequentially, 2 = Send all greetings */
Jupiter::File greetingsFile; Jupiter::File m_greetingsFile;
}; };
#endif // _RENX_GREETING_H_HEADER #endif // _RENX_GREETING_H_HEADER

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016 Jessica James. * Copyright (C) 2016-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -25,8 +25,7 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
bool RenX_Ladder_WebPlugin::initialize() bool RenX_Ladder_WebPlugin::initialize() {
{
RenX_Ladder_WebPlugin::ladder_page_name = this->config.get("LadderPageName"_jrs, ""_jrs); RenX_Ladder_WebPlugin::ladder_page_name = this->config.get("LadderPageName"_jrs, ""_jrs);
RenX_Ladder_WebPlugin::search_page_name = this->config.get("SearchPageName"_jrs, "search"_jrs); RenX_Ladder_WebPlugin::search_page_name = this->config.get("SearchPageName"_jrs, "search"_jrs);
RenX_Ladder_WebPlugin::profile_page_name = this->config.get("ProfilePageName"_jrs, "profile"_jrs); RenX_Ladder_WebPlugin::profile_page_name = this->config.get("ProfilePageName"_jrs, "profile"_jrs);
@ -38,37 +37,35 @@ bool RenX_Ladder_WebPlugin::initialize()
/** Initialize content */ /** Initialize content */
Jupiter::HTTP::Server &server = getHTTPServer(); Jupiter::HTTP::Server &server = getHTTPServer();
Jupiter::HTTP::Server::Content *content = new Jupiter::HTTP::Server::Content(RenX_Ladder_WebPlugin::ladder_page_name, handle_ladder_page); std::unique_ptr<Jupiter::HTTP::Server::Content> content = std::make_unique<Jupiter::HTTP::Server::Content>(RenX_Ladder_WebPlugin::ladder_page_name, handle_ladder_page);
content->language = &Jupiter::HTTP::Content::Language::ENGLISH; content->language = &Jupiter::HTTP::Content::Language::ENGLISH;
content->type = &Jupiter::HTTP::Content::Type::Text::HTML; content->type = &Jupiter::HTTP::Content::Type::Text::HTML;
content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8; content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8;
server.hook(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, content); server.hook(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, std::move(content));
content = new Jupiter::HTTP::Server::Content(RenX_Ladder_WebPlugin::search_page_name, handle_search_page); content = std::make_unique<Jupiter::HTTP::Server::Content>(RenX_Ladder_WebPlugin::search_page_name, handle_search_page);
content->language = &Jupiter::HTTP::Content::Language::ENGLISH; content->language = &Jupiter::HTTP::Content::Language::ENGLISH;
content->type = &Jupiter::HTTP::Content::Type::Text::HTML; content->type = &Jupiter::HTTP::Content::Type::Text::HTML;
content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8; content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8;
server.hook(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, content); server.hook(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, std::move(content));
content = new Jupiter::HTTP::Server::Content(RenX_Ladder_WebPlugin::profile_page_name, handle_profile_page); content = std::make_unique<Jupiter::HTTP::Server::Content>(RenX_Ladder_WebPlugin::profile_page_name, handle_profile_page);
content->language = &Jupiter::HTTP::Content::Language::ENGLISH; content->language = &Jupiter::HTTP::Content::Language::ENGLISH;
content->type = &Jupiter::HTTP::Content::Type::Text::HTML; content->type = &Jupiter::HTTP::Content::Type::Text::HTML;
content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8; content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8;
server.hook(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, content); server.hook(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, std::move(content));
return true; return true;
} }
RenX_Ladder_WebPlugin::~RenX_Ladder_WebPlugin() RenX_Ladder_WebPlugin::~RenX_Ladder_WebPlugin() {
{
Jupiter::HTTP::Server &server = getHTTPServer(); Jupiter::HTTP::Server &server = getHTTPServer();
server.remove(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, RenX_Ladder_WebPlugin::ladder_page_name); server.remove(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, RenX_Ladder_WebPlugin::ladder_page_name);
server.remove(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, RenX_Ladder_WebPlugin::search_page_name); server.remove(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, RenX_Ladder_WebPlugin::search_page_name);
server.remove(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, RenX_Ladder_WebPlugin::profile_page_name); server.remove(RenX_Ladder_WebPlugin::web_hostname, RenX_Ladder_WebPlugin::web_path, RenX_Ladder_WebPlugin::profile_page_name);
} }
void RenX_Ladder_WebPlugin::init() void RenX_Ladder_WebPlugin::init() {
{
FILE *file; FILE *file;
int chr; int chr;
@ -95,11 +92,9 @@ void RenX_Ladder_WebPlugin::init()
RenX_Ladder_WebPlugin::ladder_table_footer.erase(); RenX_Ladder_WebPlugin::ladder_table_footer.erase();
/** Load header */ /** Load header */
if (!RenX_Ladder_WebPlugin::web_header_filename.empty()) if (!RenX_Ladder_WebPlugin::web_header_filename.empty()) {
{
file = fopen(RenX_Ladder_WebPlugin::web_header_filename.c_str(), "rb"); file = fopen(RenX_Ladder_WebPlugin::web_header_filename.c_str(), "rb");
if (file != nullptr) if (file != nullptr) {
{
while ((chr = fgetc(file)) != EOF) while ((chr = fgetc(file)) != EOF)
RenX_Ladder_WebPlugin::header += chr; RenX_Ladder_WebPlugin::header += chr;
fclose(file); fclose(file);
@ -107,11 +102,9 @@ void RenX_Ladder_WebPlugin::init()
} }
/** Load footer */ /** Load footer */
if (!RenX_Ladder_WebPlugin::web_footer_filename.empty()) if (!RenX_Ladder_WebPlugin::web_footer_filename.empty()) {
{
file = fopen(RenX_Ladder_WebPlugin::web_footer_filename.c_str(), "rb"); file = fopen(RenX_Ladder_WebPlugin::web_footer_filename.c_str(), "rb");
if (file != nullptr) if (file != nullptr) {
{
while ((chr = fgetc(file)) != EOF) while ((chr = fgetc(file)) != EOF)
RenX_Ladder_WebPlugin::footer += chr; RenX_Ladder_WebPlugin::footer += chr;
fclose(file); fclose(file);
@ -119,11 +112,9 @@ void RenX_Ladder_WebPlugin::init()
} }
/** Load profile */ /** Load profile */
if (!RenX_Ladder_WebPlugin::web_profile_filename.empty()) if (!RenX_Ladder_WebPlugin::web_profile_filename.empty()) {
{
file = fopen(RenX_Ladder_WebPlugin::web_profile_filename.c_str(), "rb"); file = fopen(RenX_Ladder_WebPlugin::web_profile_filename.c_str(), "rb");
if (file != nullptr) if (file != nullptr) {
{
while ((chr = fgetc(file)) != EOF) while ((chr = fgetc(file)) != EOF)
RenX_Ladder_WebPlugin::entry_profile += chr; RenX_Ladder_WebPlugin::entry_profile += chr;
RenX::sanitizeTags(RenX_Ladder_WebPlugin::entry_profile); RenX::sanitizeTags(RenX_Ladder_WebPlugin::entry_profile);
@ -132,11 +123,9 @@ void RenX_Ladder_WebPlugin::init()
} }
/** Load table header */ /** Load table header */
if (!RenX_Ladder_WebPlugin::web_ladder_table_header_filename.empty()) if (!RenX_Ladder_WebPlugin::web_ladder_table_header_filename.empty()) {
{
file = fopen(RenX_Ladder_WebPlugin::web_ladder_table_header_filename.c_str(), "rb"); file = fopen(RenX_Ladder_WebPlugin::web_ladder_table_header_filename.c_str(), "rb");
if (file != nullptr) if (file != nullptr) {
{
while ((chr = fgetc(file)) != EOF) while ((chr = fgetc(file)) != EOF)
RenX_Ladder_WebPlugin::ladder_table_header += chr; RenX_Ladder_WebPlugin::ladder_table_header += chr;
fclose(file); fclose(file);
@ -144,11 +133,9 @@ void RenX_Ladder_WebPlugin::init()
} }
/** Load table footer */ /** Load table footer */
if (!RenX_Ladder_WebPlugin::web_ladder_table_footer_filename.empty()) if (!RenX_Ladder_WebPlugin::web_ladder_table_footer_filename.empty()) {
{
file = fopen(RenX_Ladder_WebPlugin::web_ladder_table_footer_filename.c_str(), "rb"); file = fopen(RenX_Ladder_WebPlugin::web_ladder_table_footer_filename.c_str(), "rb");
if (file != nullptr) if (file != nullptr) {
{
while ((chr = fgetc(file)) != EOF) while ((chr = fgetc(file)) != EOF)
RenX_Ladder_WebPlugin::ladder_table_footer += chr; RenX_Ladder_WebPlugin::ladder_table_footer += chr;
fclose(file); fclose(file);
@ -156,8 +143,7 @@ void RenX_Ladder_WebPlugin::init()
} }
} }
int RenX_Ladder_WebPlugin::OnRehash() int RenX_Ladder_WebPlugin::OnRehash() {
{
RenX::Plugin::OnRehash(); RenX::Plugin::OnRehash();
this->init(); this->init();
return 0; return 0;
@ -167,14 +153,11 @@ int RenX_Ladder_WebPlugin::OnRehash()
RenX_Ladder_WebPlugin pluginInstance; RenX_Ladder_WebPlugin pluginInstance;
/** Search bar */ /** Search bar */
Jupiter::String generate_search(RenX::LadderDatabase *db) Jupiter::String generate_search(RenX::LadderDatabase *db) {
{
Jupiter::String result(256); Jupiter::String result(256);
result = R"database-search(<form action="search" method="get" class="leaderboard-search"><input type="text" class="leaderboard-search-input" name="name" size="30" placeholder="Player name" value=""/>)database-search"_jrs; result = R"database-search(<form action="search" method="get" class="leaderboard-search"><input type="text" class="leaderboard-search-input" name="name" size="30" placeholder="Player name" value=""/>)database-search"_jrs;
if (db != nullptr && db != RenX::default_ladder_database) if (db != nullptr && db != RenX::default_ladder_database) {
{
result += R"database-search(<input type="hidden" name="database" value=")database-search"_jrs; result += R"database-search(<input type="hidden" name="database" value=")database-search"_jrs;
result += db->getName(); result += db->getName();
result += R"database-search("/>)database-search"_jrs; result += R"database-search("/>)database-search"_jrs;
@ -184,14 +167,11 @@ Jupiter::String generate_search(RenX::LadderDatabase *db)
} }
/** Database selector */ /** Database selector */
Jupiter::String generate_database_selector(RenX::LadderDatabase *db, const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) Jupiter::String generate_database_selector(RenX::LadderDatabase *db, const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) {
{
RenX::LadderDatabase *db_ptr;
Jupiter::String result(256); Jupiter::String result(256);
result = R"database-select(<form method="get" class="database-select-form"><select name="database" class="database-select">)database-select"_jrs; result = R"database-select(<form method="get" class="database-select-form"><select name="database" class="database-select">)database-select"_jrs;
if (db != nullptr) if (db != nullptr) {
{
result += "<option value=\""_jrs; result += "<option value=\""_jrs;
result += db->getName(); result += db->getName();
result += "\">"_jrs; result += "\">"_jrs;
@ -201,23 +181,18 @@ Jupiter::String generate_database_selector(RenX::LadderDatabase *db, const Jupit
else if (RenX::ladder_databases.size() == 0) else if (RenX::ladder_databases.size() == 0)
return Jupiter::String::empty; return Jupiter::String::empty;
for (size_t index = 0; index != RenX::ladder_databases.size(); ++index) for (const auto& database : RenX::ladder_databases) {
{ if (database != db) {
db_ptr = RenX::ladder_databases.get(index);
if (db_ptr != db)
{
db_ptr = RenX::ladder_databases.get(index);
result += "<option value=\""_jrs; result += "<option value=\""_jrs;
result += db_ptr->getName(); result += database->getName();
result += "\">"_jrs; result += "\">"_jrs;
result += db_ptr->getName(); result += database->getName();
result += "</option>"_jrs; result += "</option>"_jrs;
} }
} }
auto value = query_params.find("id"_jrs); auto value = query_params.find("id"_jrs);
if (value != query_params.end()) if (value != query_params.end()) {
{
result += R"html(<input type="hidden" name="id" value=")html"_jrs; result += R"html(<input type="hidden" name="id" value=")html"_jrs;
result += value->second; result += value->second;
result += R"html("/>)html"_jrs; result += R"html("/>)html"_jrs;
@ -228,8 +203,7 @@ Jupiter::String generate_database_selector(RenX::LadderDatabase *db, const Jupit
} }
/** Page buttons */ /** Page buttons */
Jupiter::String generate_page_buttons(RenX::LadderDatabase *db) Jupiter::String generate_page_buttons(RenX::LadderDatabase *db) {
{
Jupiter::String result(256); Jupiter::String result(256);
size_t entry_count = db->getEntries(); size_t entry_count = db->getEntries();
size_t entries_per_page = pluginInstance.getEntriesPerPage(); size_t entries_per_page = pluginInstance.getEntriesPerPage();
@ -237,13 +211,11 @@ Jupiter::String generate_page_buttons(RenX::LadderDatabase *db)
result = R"html(<div id="leaderboard-paging">)html"_jrs; result = R"html(<div id="leaderboard-paging">)html"_jrs;
size_t entry_index = 0, page_index = 1; size_t entry_index = 0, page_index = 1;
while (entry_index < entry_count) while (entry_index < entry_count) {
{
// Add page // Add page
result += R"html(<span class="leaderboard-page"><a href="?start=)html"_jrs; result += R"html(<span class="leaderboard-page"><a href="?start=)html"_jrs;
result += Jupiter::StringS::Format("%u", entry_index); result += Jupiter::StringS::Format("%u", entry_index);
if (db != RenX::default_ladder_database) if (db != RenX::default_ladder_database) {
{
result += "&database="_jrs; result += "&database="_jrs;
result += db->getName(); result += db->getName();
} }
@ -262,22 +234,23 @@ Jupiter::String generate_page_buttons(RenX::LadderDatabase *db)
/** Ladder page */ /** Ladder page */
Jupiter::String RenX_Ladder_WebPlugin::generate_entry_table(RenX::LadderDatabase *db, uint8_t format, size_t index, size_t count) Jupiter::String RenX_Ladder_WebPlugin::generate_entry_table(RenX::LadderDatabase *db, uint8_t format, size_t index, size_t count) {
{ if (db->getEntries() == 0) { // No ladder data
if (db->getEntries() == 0) // No ladder data
return Jupiter::String("Error: No ladder data"_jrs); return Jupiter::String("Error: No ladder data"_jrs);
}
if (index >= db->getEntries() || count == 0) // Invalid entry range if (index >= db->getEntries() || count == 0) { // Invalid entry range
return Jupiter::String("Error: Invalid range"_jrs); return Jupiter::String("Error: Invalid range"_jrs);
}
if (index + count > db->getEntries()) // Invalid entry range; use valid portion of range if (index + count > db->getEntries()) { // Invalid entry range; use valid portion of range
count = db->getEntries() - index; count = db->getEntries() - index;
}
RenX::LadderDatabase::Entry *node = db->getHead(); RenX::LadderDatabase::Entry *node = db->getHead();
// iterate to requested index // iterate to requested index
while (index != 0) while (index != 0) {
{
node = node->next; node = node->next;
--index; --index;
} }
@ -285,13 +258,13 @@ Jupiter::String RenX_Ladder_WebPlugin::generate_entry_table(RenX::LadderDatabase
// table header // table header
Jupiter::String result(2048); Jupiter::String result(2048);
if ((format & this->FLAG_INCLUDE_DATA_HEADER) != 0) // Data Header if ((format & this->FLAG_INCLUDE_DATA_HEADER) != 0) { // Data Header
result = RenX_Ladder_WebPlugin::ladder_table_header; result = RenX_Ladder_WebPlugin::ladder_table_header;
}
// append rows // append rows
Jupiter::String row(256); Jupiter::String row(256);
while (count != 0) while (count != 0) {
{
row = RenX_Ladder_WebPlugin::entry_table_row; row = RenX_Ladder_WebPlugin::entry_table_row;
row.replace(RenX::tags->INTERNAL_OBJECT_TAG, db->getName()); row.replace(RenX::tags->INTERNAL_OBJECT_TAG, db->getName());
RenX::processTags(row, *node); RenX::processTags(row, *node);
@ -300,8 +273,9 @@ Jupiter::String RenX_Ladder_WebPlugin::generate_entry_table(RenX::LadderDatabase
--count; --count;
} }
if ((format & this->FLAG_INCLUDE_DATA_FOOTER) != 0) // Data footer if ((format & this->FLAG_INCLUDE_DATA_FOOTER) != 0) { // Data footer
result += RenX_Ladder_WebPlugin::ladder_table_footer; result += RenX_Ladder_WebPlugin::ladder_table_footer;
}
// search buttons // search buttons
result += generate_page_buttons(db); result += generate_page_buttons(db);
@ -309,8 +283,7 @@ Jupiter::String RenX_Ladder_WebPlugin::generate_entry_table(RenX::LadderDatabase
return result; return result;
} }
Jupiter::String *RenX_Ladder_WebPlugin::generate_ladder_page(RenX::LadderDatabase *db, uint8_t format, size_t index, size_t count, const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) Jupiter::String *RenX_Ladder_WebPlugin::generate_ladder_page(RenX::LadderDatabase *db, uint8_t format, size_t index, size_t count, const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) {
{
Jupiter::String *result = new Jupiter::String(2048); Jupiter::String *result = new Jupiter::String(2048);
if ((format & this->FLAG_INCLUDE_PAGE_HEADER) != 0) // Header if ((format & this->FLAG_INCLUDE_PAGE_HEADER) != 0) // Header
@ -334,8 +307,7 @@ Jupiter::String *RenX_Ladder_WebPlugin::generate_ladder_page(RenX::LadderDatabas
// include_header | include_footer | include_any_headers | include_any_footers // include_header | include_footer | include_any_headers | include_any_footers
/** Search page */ /** Search page */
Jupiter::String *RenX_Ladder_WebPlugin::generate_search_page(RenX::LadderDatabase *db, uint8_t format, size_t start_index, size_t count, const Jupiter::ReadableString &name, const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) Jupiter::String *RenX_Ladder_WebPlugin::generate_search_page(RenX::LadderDatabase *db, uint8_t format, size_t start_index, size_t count, const Jupiter::ReadableString &name, const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) {
{
Jupiter::String *result = new Jupiter::String(2048); Jupiter::String *result = new Jupiter::String(2048);
if ((format & this->FLAG_INCLUDE_PAGE_HEADER) != 0) // Header if ((format & this->FLAG_INCLUDE_PAGE_HEADER) != 0) // Header
@ -347,8 +319,7 @@ Jupiter::String *RenX_Ladder_WebPlugin::generate_search_page(RenX::LadderDatabas
if ((format & this->FLAG_INCLUDE_SELECTOR) != 0) // Selector if ((format & this->FLAG_INCLUDE_SELECTOR) != 0) // Selector
result->concat(generate_database_selector(db, query_params)); result->concat(generate_database_selector(db, query_params));
if (db->getEntries() == 0) // No ladder data if (db->getEntries() == 0) { // No ladder data
{
result->concat("Error: No ladder data"_jrs); result->concat("Error: No ladder data"_jrs);
if ((format & this->FLAG_INCLUDE_PAGE_FOOTER) != 0) // Footer if ((format & this->FLAG_INCLUDE_PAGE_FOOTER) != 0) // Footer
@ -363,10 +334,8 @@ Jupiter::String *RenX_Ladder_WebPlugin::generate_search_page(RenX::LadderDatabas
// append rows // append rows
Jupiter::String row(256); Jupiter::String row(256);
RenX::LadderDatabase::Entry *node = db->getHead(); RenX::LadderDatabase::Entry *node = db->getHead();
while (node != nullptr) while (node != nullptr) {
{ if (node->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) { // match found
if (node->most_recent_name.findi(name) != Jupiter::INVALID_INDEX) // match found
{
row = RenX_Ladder_WebPlugin::entry_table_row; row = RenX_Ladder_WebPlugin::entry_table_row;
row.replace(RenX::tags->INTERNAL_OBJECT_TAG, db->getName()); row.replace(RenX::tags->INTERNAL_OBJECT_TAG, db->getName());
RenX::processTags(row, *node); RenX::processTags(row, *node);
@ -385,8 +354,7 @@ Jupiter::String *RenX_Ladder_WebPlugin::generate_search_page(RenX::LadderDatabas
} }
/** Profile page */ /** Profile page */
Jupiter::String *RenX_Ladder_WebPlugin::generate_profile_page(RenX::LadderDatabase *db, uint8_t format, uint64_t steam_id, const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) Jupiter::String *RenX_Ladder_WebPlugin::generate_profile_page(RenX::LadderDatabase *db, uint8_t format, uint64_t steam_id, const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) {
{
Jupiter::String *result = new Jupiter::String(2048); Jupiter::String *result = new Jupiter::String(2048);
if ((format & this->FLAG_INCLUDE_PAGE_HEADER) != 0) if ((format & this->FLAG_INCLUDE_PAGE_HEADER) != 0)
@ -398,8 +366,7 @@ Jupiter::String *RenX_Ladder_WebPlugin::generate_profile_page(RenX::LadderDataba
if ((format & this->FLAG_INCLUDE_SELECTOR) != 0) // Selector if ((format & this->FLAG_INCLUDE_SELECTOR) != 0) // Selector
result->concat(generate_database_selector(db, query_params)); result->concat(generate_database_selector(db, query_params));
if (db->getEntries() == 0) // No ladder data if (db->getEntries() == 0) { // No ladder data
{
result->concat("Error: No ladder data"_jrs); result->concat("Error: No ladder data"_jrs);
if ((format & this->FLAG_INCLUDE_PAGE_FOOTER) != 0) // Footer if ((format & this->FLAG_INCLUDE_PAGE_FOOTER) != 0) // Footer
@ -409,17 +376,16 @@ Jupiter::String *RenX_Ladder_WebPlugin::generate_profile_page(RenX::LadderDataba
} }
RenX::LadderDatabase::Entry *entry = db->getHead(); RenX::LadderDatabase::Entry *entry = db->getHead();
while (entry != nullptr) while (entry != nullptr) {
{
if (entry->steam_id == steam_id) // match found if (entry->steam_id == steam_id) // match found
break; break;
entry = entry->next; entry = entry->next;
} }
if (entry == nullptr) if (entry == nullptr) {
result->concat("Error: Player not found"_jrs); result->concat("Error: Player not found"_jrs);
else }
{ else {
Jupiter::String profile_data(RenX_Ladder_WebPlugin::entry_profile); Jupiter::String profile_data(RenX_Ladder_WebPlugin::entry_profile);
RenX::processTags(profile_data, *entry); RenX::processTags(profile_data, *entry);
result->concat(profile_data); result->concat(profile_data);
@ -452,44 +418,40 @@ Jupiter::String *RenX_Ladder_WebPlugin::generate_profile_page(RenX::LadderDataba
/** Content functions */ /** Content functions */
Jupiter::ReadableString *generate_no_db_page(const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) Jupiter::ReadableString *generate_no_db_page(const Jupiter::HTTP::HTMLFormResponse::TableType &query_params) {
{
Jupiter::String *result = new Jupiter::String(pluginInstance.header); Jupiter::String *result = new Jupiter::String(pluginInstance.header);
if (RenX::ladder_databases.size() != 0) if (RenX::ladder_databases.size() != 0) {
{
result->concat(generate_search(nullptr)); result->concat(generate_search(nullptr));
result->concat(generate_database_selector(nullptr, query_params)); result->concat(generate_database_selector(nullptr, query_params));
result->concat("Error: No such database exists"_jrs); result->concat("Error: No such database exists"_jrs);
} }
else else {
result->concat("Error: No ladder databases loaded"_jrs); result->concat("Error: No ladder databases loaded"_jrs);
}
result->concat(pluginInstance.footer); result->concat(pluginInstance.footer);
return result; return result;
} }
Jupiter::ReadableString *handle_ladder_page(const Jupiter::ReadableString &query_string) Jupiter::ReadableString *handle_ladder_page(const Jupiter::ReadableString &query_string) {
{
Jupiter::HTTP::HTMLFormResponse html_form_response(query_string); Jupiter::HTTP::HTMLFormResponse html_form_response(query_string);
RenX::LadderDatabase *db = RenX::default_ladder_database; RenX::LadderDatabase *db = RenX::default_ladder_database;
size_t start_index = 0, count = pluginInstance.getEntriesPerPage(); size_t start_index = 0, count = pluginInstance.getEntriesPerPage();
uint8_t format = 0xFF; uint8_t format = 0xFF;
if (html_form_response.table.size() != 0) if (html_form_response.table.size() != 0) {
{
format = html_form_response.tableGetCast<uint8_t>("format"_jrs, format); format = html_form_response.tableGetCast<uint8_t>("format"_jrs, format);
start_index = html_form_response.tableGetCast<size_t>("start"_jrs, start_index); start_index = html_form_response.tableGetCast<size_t>("start"_jrs, start_index);
count = html_form_response.tableGetCast<size_t>("count"_jrs, count); count = html_form_response.tableGetCast<size_t>("count"_jrs, count);
const Jupiter::ReadableString &db_name = html_form_response.tableGet("database"_jrs, Jupiter::ReferenceString::empty); const Jupiter::ReadableString &db_name = html_form_response.tableGet("database"_jrs, Jupiter::ReferenceString::empty);
if (db_name.isNotEmpty()) if (db_name.isNotEmpty()) {
{
db = nullptr; db = nullptr;
for (size_t index = 0; index != RenX::ladder_databases.size(); ++index) for (const auto& database : RenX::ladder_databases) {
if (RenX::ladder_databases.get(index)->getName().equalsi(db_name)) if (database->getName().equalsi(db_name)) {
{ db = database;
db = RenX::ladder_databases.get(index);
break; break;
} }
}
} }
} }
@ -499,31 +461,28 @@ Jupiter::ReadableString *handle_ladder_page(const Jupiter::ReadableString &query
return pluginInstance.generate_ladder_page(db, format, start_index, count, html_form_response.table); return pluginInstance.generate_ladder_page(db, format, start_index, count, html_form_response.table);
} }
Jupiter::ReadableString *handle_search_page(const Jupiter::ReadableString &query_string) Jupiter::ReadableString *handle_search_page(const Jupiter::ReadableString &query_string) {
{
Jupiter::HTTP::HTMLFormResponse html_form_response(query_string); Jupiter::HTTP::HTMLFormResponse html_form_response(query_string);
RenX::LadderDatabase *db = RenX::default_ladder_database; RenX::LadderDatabase *db = RenX::default_ladder_database;
uint8_t format = 0xFF; uint8_t format = 0xFF;
size_t start_index = 0, count = pluginInstance.getEntriesPerPage(); size_t start_index = 0, count = pluginInstance.getEntriesPerPage();
Jupiter::ReferenceString name; Jupiter::ReferenceString name;
if (html_form_response.table.size() != 0) if (html_form_response.table.size() != 0) {
{
format = html_form_response.tableGetCast<uint8_t>("format"_jrs, format); format = html_form_response.tableGetCast<uint8_t>("format"_jrs, format);
start_index = html_form_response.tableGetCast<size_t>("start"_jrs, start_index); start_index = html_form_response.tableGetCast<size_t>("start"_jrs, start_index);
count = html_form_response.tableGetCast<size_t>("count"_jrs, count); count = html_form_response.tableGetCast<size_t>("count"_jrs, count);
name = html_form_response.tableGet("name"_jrs, name); name = html_form_response.tableGet("name"_jrs, name);
const Jupiter::ReadableString &db_name = html_form_response.tableGet("database"_jrs, Jupiter::ReferenceString::empty); const Jupiter::ReadableString &db_name = html_form_response.tableGet("database"_jrs, Jupiter::ReferenceString::empty);
if (db_name.isNotEmpty()) if (db_name.isNotEmpty()) {
{
db = nullptr; db = nullptr;
for (size_t index = 0; index != RenX::ladder_databases.size(); ++index) for (const auto& database : RenX::ladder_databases) {
if (RenX::ladder_databases.get(index)->getName().equalsi(db_name)) if (database->getName().equalsi(db_name)) {
{ db = database;
db = RenX::ladder_databases.get(index);
break; break;
} }
}
} }
} }
@ -552,12 +511,12 @@ Jupiter::ReadableString *handle_profile_page(const Jupiter::ReadableString &quer
if (db_name.isNotEmpty()) if (db_name.isNotEmpty())
{ {
db = nullptr; db = nullptr;
for (size_t index = 0; index != RenX::ladder_databases.size(); ++index) for (const auto& database : RenX::ladder_databases) {
if (RenX::ladder_databases.get(index)->getName().equalsi(db_name)) if (database->getName().equalsi(db_name)) {
{ db = database;
db = RenX::ladder_databases.get(index);
break; break;
} }
}
} }
} }

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2015-2017 Jessica James. * Copyright (C) 2015-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -25,8 +25,7 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
bool RenX_LadderPlugin::initialize() bool RenX_LadderPlugin::initialize() {
{
RenX_LadderPlugin::only_pure = this->config.get<bool>("OnlyPure"_jrs, false); RenX_LadderPlugin::only_pure = this->config.get<bool>("OnlyPure"_jrs, false);
int mlcpno = this->config.get<int>("MaxLadderCommandPartNameOutput"_jrs, 5); int mlcpno = this->config.get<int>("MaxLadderCommandPartNameOutput"_jrs, 5);
if (mlcpno < 0) if (mlcpno < 0)
@ -45,18 +44,16 @@ bool RenX_LadderPlugin::initialize()
return true; return true;
} }
void RenX_LadderPlugin::RenX_OnServerFullyConnected(RenX::Server &server) void RenX_LadderPlugin::RenX_OnServerFullyConnected(RenX::Server &server) {
{ if (this->only_pure == false || server.isPure()) {
if (this->only_pure == false || server.isPure())
server.setRanked(true); server.setRanked(true);
}
} }
/** Wait until the client list has been updated to update the ladder */ /** Wait until the client list has been updated to update the ladder */
void RenX_LadderPlugin::RenX_OnGameOver(RenX::Server &server, RenX::WinType winType, const RenX::TeamType &team, int gScore, int nScore) void RenX_LadderPlugin::RenX_OnGameOver(RenX::Server &server, RenX::WinType winType, const RenX::TeamType &team, int gScore, int nScore) {
{ if (server.isRanked() && server.isReliable() && server.players.size() != server.getBotCount()) {
if (server.isRanked() && server.isReliable() && server.players.size() != server.getBotCount())
{
char chr = static_cast<char>(team); char chr = static_cast<char>(team);
server.varData[this->name].set("t"_jrs, Jupiter::ReferenceString(&chr, 1)); server.varData[this->name].set("t"_jrs, Jupiter::ReferenceString(&chr, 1));
server.varData[this->name].set("w"_jrs, "1"_jrs); server.varData[this->name].set("w"_jrs, "1"_jrs);
@ -64,22 +61,19 @@ 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 (server.getCurrentRCONCommand().equalsi("clientvarlist"_jrs)) if (server.varData[this->name].get("w"_jrs, "0"_jrs).equals("1")) {
{
if (server.varData[this->name].get("w"_jrs, "0"_jrs).equals("1"))
{
server.varData[this->name].set("w"_jrs, "0"_jrs); server.varData[this->name].set("w"_jrs, "0"_jrs);
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).get(0));
for (size_t index = 0; index != RenX::ladder_databases.size(); ++index) for (const auto& database : RenX::ladder_databases) {
RenX::ladder_databases.get(index)->updateLadder(server, team); database->updateLadder(server, team);
}
} }
} }
} }
size_t RenX_LadderPlugin::getMaxLadderCommandPartNameOutput() const size_t RenX_LadderPlugin::getMaxLadderCommandPartNameOutput() const {
{
return RenX_LadderPlugin::max_ladder_command_part_name_output; return RenX_LadderPlugin::max_ladder_command_part_name_output;
} }
@ -88,31 +82,29 @@ RenX_LadderPlugin pluginInstance;
/** Ladder Commands */ /** Ladder Commands */
Jupiter::StringS FormatLadderResponse(RenX::LadderDatabase::Entry *entry, size_t rank) Jupiter::StringS FormatLadderResponse(RenX::LadderDatabase::Entry *entry, size_t rank) {
{
return Jupiter::StringS::Format("#%" PRIuPTR ": \"%.*s\" - Score: %" PRIu64 " - Kills: %" PRIu32 " - Deaths: %" PRIu32 " - KDR: %.2f - SPM: %.2f", rank, entry->most_recent_name.size(), entry->most_recent_name.ptr(), entry->total_score, entry->total_kills, entry->total_deaths, static_cast<double>(entry->total_kills) / (entry->total_deaths == 0 ? 1 : static_cast<double>(entry->total_deaths)), static_cast<double>(entry->total_score) / (entry->total_game_time == 0 ? 1.0 : static_cast<double>(entry->total_game_time)) * 60.0); return Jupiter::StringS::Format("#%" PRIuPTR ": \"%.*s\" - Score: %" PRIu64 " - Kills: %" PRIu32 " - Deaths: %" PRIu32 " - KDR: %.2f - SPM: %.2f", rank, entry->most_recent_name.size(), entry->most_recent_name.ptr(), entry->total_score, entry->total_kills, entry->total_deaths, static_cast<double>(entry->total_kills) / (entry->total_deaths == 0 ? 1 : static_cast<double>(entry->total_deaths)), static_cast<double>(entry->total_score) / (entry->total_game_time == 0 ? 1.0 : static_cast<double>(entry->total_game_time)) * 60.0);
} }
// Ladder Command // Ladder Command
LadderGenericCommand::LadderGenericCommand() LadderGenericCommand::LadderGenericCommand() {
{
this->addTrigger("ladder"_jrs); this->addTrigger("ladder"_jrs);
this->addTrigger("rank"_jrs); this->addTrigger("rank"_jrs);
} }
Jupiter::GenericCommand::ResponseLine *LadderGenericCommand::trigger(const Jupiter::ReadableString &parameters) Jupiter::GenericCommand::ResponseLine *LadderGenericCommand::trigger(const Jupiter::ReadableString &parameters) {
{ if (parameters.isEmpty()) {
if (parameters.isEmpty())
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);
}
if (RenX::default_ladder_database == nullptr) if (RenX::default_ladder_database == nullptr) {
return new Jupiter::GenericCommand::ResponseLine("Error: No default ladder database specified."_jrs, GenericCommand::DisplayType::PrivateError); return new Jupiter::GenericCommand::ResponseLine("Error: No default ladder database specified."_jrs, GenericCommand::DisplayType::PrivateError);
}
RenX::LadderDatabase::Entry *entry; RenX::LadderDatabase::Entry *entry;
size_t rank; size_t rank;
if (parameters.span("0123456789"_jrs) == parameters.size()) if (parameters.span("0123456789"_jrs) == parameters.size()) {
{
rank = parameters.asUnsignedInt(10); rank = parameters.asUnsignedInt(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);
@ -133,8 +125,7 @@ Jupiter::GenericCommand::ResponseLine *LadderGenericCommand::trigger(const Jupit
Jupiter::GenericCommand::ResponseLine *response_end = response_head; Jupiter::GenericCommand::ResponseLine *response_end = response_head;
list.pop_front(); list.pop_front();
while (list.empty() == false) while (list.empty() == false) {
{
std::pair<RenX::LadderDatabase::Entry, size_t> &pair = list.front(); std::pair<RenX::LadderDatabase::Entry, size_t> &pair = list.front();
response_end->next = new Jupiter::GenericCommand::ResponseLine(FormatLadderResponse(std::addressof(pair.first), pair.second + 1), GenericCommand::DisplayType::PrivateSuccess); response_end->next = new Jupiter::GenericCommand::ResponseLine(FormatLadderResponse(std::addressof(pair.first), pair.second + 1), GenericCommand::DisplayType::PrivateSuccess);
response_end = response_end->next; response_end = response_end->next;
@ -143,8 +134,7 @@ Jupiter::GenericCommand::ResponseLine *LadderGenericCommand::trigger(const Jupit
return response_head; return response_head;
} }
const Jupiter::ReadableString &LadderGenericCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &LadderGenericCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Fetches ladder information about a player. Syntax: ladder <name | rank>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Fetches ladder information about a player. Syntax: ladder <name | rank>");
return defaultHelp; return defaultHelp;
} }
@ -154,23 +144,19 @@ GENERIC_COMMAND_AS_CONSOLE_COMMAND(LadderGenericCommand)
// Ladder Game Command // Ladder Game Command
void LadderGameCommand::create() void LadderGameCommand::create() {
{
this->addTrigger("ladder"_jrs); this->addTrigger("ladder"_jrs);
this->addTrigger("rank"_jrs); this->addTrigger("rank"_jrs);
} }
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.isEmpty()) if (player->steamid != 0) {
{ if (RenX::default_ladder_database != nullptr) {
if (player->steamid != 0)
{
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);
if (pair.first != nullptr) if (pair.first != nullptr) {
source->sendMessage(FormatLadderResponse(pair.first, pair.second + 1)); source->sendMessage(FormatLadderResponse(pair.first, pair.second + 1));
}
else else
source->sendMessage(*player, "Error: You have no ladder data. Get started by sticking around until the end of the match!"_jrs); source->sendMessage(*player, "Error: You have no ladder data. Get started by sticking around until the end of the match!"_jrs);
} }
@ -180,12 +166,10 @@ void LadderGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player,
else else
source->sendMessage(*player, "Error: You have no ladder data, because you're not using Steam."_jrs); source->sendMessage(*player, "Error: You have no ladder data, because you're not using Steam."_jrs);
} }
else else {
{
Jupiter::GenericCommand::ResponseLine *response = LadderGenericCommand_instance.trigger(parameters); Jupiter::GenericCommand::ResponseLine *response = LadderGenericCommand_instance.trigger(parameters);
Jupiter::GenericCommand::ResponseLine *ptr; Jupiter::GenericCommand::ResponseLine *ptr;
while (response != nullptr) while (response != nullptr) {
{
source->sendMessage(*player, response->response); source->sendMessage(*player, response->response);
ptr = response; ptr = response;
response = response->next; response = response->next;
@ -194,15 +178,13 @@ void LadderGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player,
} }
} }
const Jupiter::ReadableString &LadderGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &LadderGameCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays ladder information about yourself, or another player. Syntax: ladder [name / rank]"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays ladder information about yourself, or another player. Syntax: ladder [name / rank]");
return defaultHelp; return defaultHelp;
} }
GAME_COMMAND_INIT(LadderGameCommand) GAME_COMMAND_INIT(LadderGameCommand)
extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() {
{
return &pluginInstance; return &pluginInstance;
} }

24
src/Plugins/RenX/RenX.Listen/RenX_Listen.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2015-2016 Jessica James. * Copyright (C) 2015-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -23,13 +23,11 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
RenX_ListenPlugin::~RenX_ListenPlugin() RenX_ListenPlugin::~RenX_ListenPlugin() {
{
RenX_ListenPlugin::socket.close(); RenX_ListenPlugin::socket.close();
} }
bool RenX_ListenPlugin::initialize() bool RenX_ListenPlugin::initialize() {
{
uint16_t port = this->config.get<uint16_t>("Port"_jrs, 21337); uint16_t port = this->config.get<uint16_t>("Port"_jrs, 21337);
const Jupiter::ReadableString &address = this->config.get("Address"_jrs, "0.0.0.0"_jrs); const Jupiter::ReadableString &address = this->config.get("Address"_jrs, "0.0.0.0"_jrs);
RenX_ListenPlugin::serverSection = this->config.get("ServerSection"_jrs, this->getName()); RenX_ListenPlugin::serverSection = this->config.get("ServerSection"_jrs, this->getName());
@ -37,31 +35,27 @@ bool RenX_ListenPlugin::initialize()
return RenX_ListenPlugin::socket.bind(static_cast<std::string>(address).c_str(), port, true) && RenX_ListenPlugin::socket.setBlocking(false); return RenX_ListenPlugin::socket.bind(static_cast<std::string>(address).c_str(), port, true) && RenX_ListenPlugin::socket.setBlocking(false);
} }
int RenX_ListenPlugin::think() int RenX_ListenPlugin::think() {
{
Jupiter::Socket *sock = socket.accept(); Jupiter::Socket *sock = socket.accept();
if (sock != nullptr) if (sock != nullptr) {
{
sock->setBlocking(false); sock->setBlocking(false);
RenX::Server *server = new RenX::Server(std::move(*sock), RenX_ListenPlugin::serverSection); std::unique_ptr<RenX::Server> server = std::make_unique<RenX::Server>(std::move(*sock), RenX_ListenPlugin::serverSection);
printf("Incoming server connected from %.*s:%u" ENDL, server->getSocketHostname().size(), server->getSocketHostname().c_str(), server->getSocketPort()); printf("Incoming server connected from %.*s:%u" ENDL, server->getSocketHostname().size(), server->getSocketHostname().c_str(), server->getSocketPort());
server->sendLogChan("Incoming server connected from " IRCCOLOR "12%.*s:%u", server->getSocketHostname().size(), server->getSocketHostname().c_str(), server->getSocketPort()); server->sendLogChan("Incoming server connected from " IRCCOLOR "12%.*s:%u", server->getSocketHostname().size(), server->getSocketHostname().c_str(), server->getSocketPort());
RenX::getCore()->addServer(server); RenX::getCore()->addServer(std::move(server));
delete sock; delete sock;
} }
return 0; return 0;
} }
int RenX_ListenPlugin::OnRehash() int RenX_ListenPlugin::OnRehash() {
{
RenX::Plugin::OnRehash(); RenX::Plugin::OnRehash();
uint16_t port = this->config.get<uint16_t>("Port"_jrs, 21337); uint16_t port = this->config.get<uint16_t>("Port"_jrs, 21337);
const Jupiter::ReadableString &address = this->config.get("Address"_jrs, "0.0.0.0"_jrs); const Jupiter::ReadableString &address = this->config.get("Address"_jrs, "0.0.0.0"_jrs);
RenX_ListenPlugin::serverSection = this->config.get("ServerSection"_jrs, this->getName()); RenX_ListenPlugin::serverSection = this->config.get("ServerSection"_jrs, this->getName());
if (port != RenX_ListenPlugin::socket.getBoundPort() || address.equals(RenX_ListenPlugin::socket.getBoundHostname()) == false) if (port != RenX_ListenPlugin::socket.getBoundPort() || address.equals(RenX_ListenPlugin::socket.getBoundHostname()) == false) {
{
puts("Notice: The Renegade-X listening socket has been changed!"); puts("Notice: The Renegade-X listening socket has been changed!");
RenX_ListenPlugin::socket.close(); RenX_ListenPlugin::socket.close();
return RenX_ListenPlugin::socket.bind(static_cast<std::string>(address).c_str(), port, true) == false || RenX_ListenPlugin::socket.setBlocking(false) == false; return RenX_ListenPlugin::socket.bind(static_cast<std::string>(address).c_str(), port, true) == false || RenX_ListenPlugin::socket.setBlocking(false) == false;

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -276,15 +276,12 @@ void RenX_MedalsPlugin::init()
RenX_MedalsPlugin::worthTag = RenX_MedalsPlugin::config.get("WorthTag"_jrs, "{WORTH}"_jrs); RenX_MedalsPlugin::worthTag = RenX_MedalsPlugin::config.get("WorthTag"_jrs, "{WORTH}"_jrs);
RenX::Core *core = RenX::getCore(); RenX::Core *core = RenX::getCore();
unsigned int sCount = core->getServerCount(); size_t server_count = core->getServerCount();
RenX::Server *server; RenX::Server *server;
for (unsigned int i = 0; i < sCount; i++) for (size_t index = 0; index < server_count; ++index) {
{ server = core->getServer(index);
server = core->getServer(i); if (server->players.size() != server->getBotCount()) {
if (server->players.size() != server->getBotCount()) for (auto node = server->players.begin(); node != server->players.end(); ++node) {
{
for (auto node = server->players.begin(); node != server->players.end(); ++node)
{
node->varData[this->getName()].set("Recs"_jrs, RenX_MedalsPlugin::medalsFile[node->name].get("Recs"_jrs)); node->varData[this->getName()].set("Recs"_jrs, RenX_MedalsPlugin::medalsFile[node->name].get("Recs"_jrs));
node->varData[this->getName()].set("Noobs"_jrs, RenX_MedalsPlugin::medalsFile[node->name].get("Noobs"_jrs)); node->varData[this->getName()].set("Noobs"_jrs, RenX_MedalsPlugin::medalsFile[node->name].get("Noobs"_jrs));
} }

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -26,17 +26,16 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
bool RenX_ModSystemPlugin::initialize() bool RenX_ModSystemPlugin::initialize() {
{ m_lockSteam = this->config.get<bool>("LockSteam"_jrs, true);
RenX_ModSystemPlugin::lockSteam = this->config.get<bool>("LockSteam"_jrs, true); m_lockIP = this->config.get<bool>("LockIP"_jrs, false);
RenX_ModSystemPlugin::lockIP = this->config.get<bool>("LockIP"_jrs, false); m_lockName = this->config.get<bool>("LockName"_jrs, false);
RenX_ModSystemPlugin::lockName = this->config.get<bool>("LockName"_jrs, false); m_kickLockMismatch = this->config.get<bool>("KickLockMismatch"_jrs, true);
RenX_ModSystemPlugin::kickLockMismatch = this->config.get<bool>("KickLockMismatch"_jrs, true); m_autoAuthSteam = this->config.get<bool>("AutoAuthSteam"_jrs, true);
RenX_ModSystemPlugin::autoAuthSteam = this->config.get<bool>("AutoAuthSteam"_jrs, true); m_autoAuthIP = this->config.get<bool>("AutoAuthIP"_jrs, false);
RenX_ModSystemPlugin::autoAuthIP = this->config.get<bool>("AutoAuthIP"_jrs, false); m_atmDefault = this->config.get("ATMDefault"_jrs);
RenX_ModSystemPlugin::atmDefault = this->config.get("ATMDefault"_jrs); m_moderatorGroup = this->config.get("Moderator"_jrs, "Moderator"_jrs);
RenX_ModSystemPlugin::moderatorGroup = this->config.get("Moderator"_jrs, "Moderator"_jrs); m_administratorGroup = this->config.get("Administrator"_jrs, "Administrator"_jrs);
RenX_ModSystemPlugin::administratorGroup = this->config.get("Administrator"_jrs, "Administrator"_jrs);
ModGroup *group; ModGroup *group;
Jupiter::ReferenceString dotLockSteam = ".LockSteam"; Jupiter::ReferenceString dotLockSteam = ".LockSteam";
@ -60,27 +59,27 @@ bool RenX_ModSystemPlugin::initialize()
group->name = groupName; group->name = groupName;
groupName += dotLockSteam; groupName += dotLockSteam;
group->lockSteam = this->config.get<bool>(groupName, RenX_ModSystemPlugin::lockSteam); group->lockSteam = this->config.get<bool>(groupName, m_lockSteam);
groupName.truncate(dotLockSteam.size()); groupName.truncate(dotLockSteam.size());
groupName += dotLockIP; groupName += dotLockIP;
group->lockIP = this->config.get<bool>(groupName, RenX_ModSystemPlugin::lockIP); group->lockIP = this->config.get<bool>(groupName, m_lockIP);
groupName.truncate(dotLockIP.size()); groupName.truncate(dotLockIP.size());
groupName += dotLockName; groupName += dotLockName;
group->lockName = this->config.get<bool>(groupName, RenX_ModSystemPlugin::lockName); group->lockName = this->config.get<bool>(groupName, m_lockName);
groupName.truncate(dotLockName.size()); groupName.truncate(dotLockName.size());
groupName += dotKickLockMismatch; groupName += dotKickLockMismatch;
group->kickLockMismatch = this->config.get<bool>(groupName, RenX_ModSystemPlugin::kickLockMismatch); group->kickLockMismatch = this->config.get<bool>(groupName, m_kickLockMismatch);
groupName.truncate(dotKickLockMismatch.size()); groupName.truncate(dotKickLockMismatch.size());
groupName += dotAutoAuthSteam; groupName += dotAutoAuthSteam;
group->autoAuthSteam = this->config.get<bool>(groupName, RenX_ModSystemPlugin::autoAuthSteam); group->autoAuthSteam = this->config.get<bool>(groupName, m_autoAuthSteam);
groupName.truncate(dotAutoAuthSteam.size()); groupName.truncate(dotAutoAuthSteam.size());
groupName += dotAutoAuthIP; groupName += dotAutoAuthIP;
group->autoAuthIP = this->config.get<bool>(groupName, RenX_ModSystemPlugin::autoAuthIP); group->autoAuthIP = this->config.get<bool>(groupName, m_autoAuthIP);
groupName.truncate(dotAutoAuthIP.size()); groupName.truncate(dotAutoAuthIP.size());
groupName += dotAccess; groupName += dotAccess;
@ -101,38 +100,37 @@ bool RenX_ModSystemPlugin::initialize()
} }
RenX::Core *core = RenX::getCore(); RenX::Core *core = RenX::getCore();
unsigned int total = core->getServerCount(); size_t server_count = core->getServerCount();
RenX::Server *server; RenX::Server *server;
while (total != 0) while (server_count != 0) {
{ server = core->getServer(--server_count);
server = core->getServer(--total); if (server->players.size() != server->getBotCount()) {
if (server->players.size() != server->getBotCount()) for (auto node = server->players.begin(); node != server->players.end(); ++node) {
for (auto node = server->players.begin(); node != server->players.end(); ++node) auth(*server, *node, true);
RenX_ModSystemPlugin::auth(*server, *node, true); }
}
} }
return true; return true;
} }
unsigned int RenX_ModSystemPlugin::logoutAllMods(RenX::Server &server) unsigned int RenX_ModSystemPlugin::logoutAllMods(RenX::Server &server) {
{
if (server.players.size() == 0) if (server.players.size() == 0)
return 0; return 0;
unsigned int total = 0; unsigned int total = 0;
for (auto node = server.players.begin(); node != server.players.end(); ++node) for (auto node = server.players.begin(); node != server.players.end(); ++node)
if (RenX_ModSystemPlugin::resetAccess(*node)) if (resetAccess(*node))
total++; total++;
return total; return total;
} }
bool RenX_ModSystemPlugin::resetAccess(RenX::PlayerInfo &player) bool RenX_ModSystemPlugin::resetAccess(RenX::PlayerInfo &player) {
{
int oAccess = player.access; int oAccess = player.access;
if (player.adminType.equals("administrator")) if (player.adminType.equals("administrator"))
{ {
ModGroup *group = RenX_ModSystemPlugin::getGroupByName(RenX_ModSystemPlugin::administratorGroup); ModGroup *group = getGroupByName(m_administratorGroup);
if (group == nullptr) if (group == nullptr)
player.access = 2; player.access = 2;
else else
@ -140,7 +138,7 @@ bool RenX_ModSystemPlugin::resetAccess(RenX::PlayerInfo &player)
} }
else if (player.adminType.equals("moderator")) else if (player.adminType.equals("moderator"))
{ {
ModGroup *group = RenX_ModSystemPlugin::getGroupByName(RenX_ModSystemPlugin::moderatorGroup); ModGroup *group = getGroupByName(m_moderatorGroup);
if (group == nullptr) if (group == nullptr)
player.access = 1; player.access = 1;
else else
@ -154,8 +152,7 @@ bool RenX_ModSystemPlugin::resetAccess(RenX::PlayerInfo &player)
return player.access != oAccess; return player.access != oAccess;
} }
int RenX_ModSystemPlugin::auth(RenX::Server &server, const RenX::PlayerInfo &player, bool checkAuto, bool forceAuth) const int RenX_ModSystemPlugin::auth(RenX::Server &server, const RenX::PlayerInfo &player, bool checkAuto, bool forceAuth) const {
{
if (player.isBot) if (player.isBot)
return 0; return 0;
@ -171,7 +168,7 @@ int RenX_ModSystemPlugin::auth(RenX::Server &server, const RenX::PlayerInfo &pla
group = &RenX_ModSystemPlugin::groups.front(); group = &RenX_ModSystemPlugin::groups.front();
else else
{ {
group = RenX_ModSystemPlugin::getGroupByName(groupName); group = getGroupByName(groupName);
if (group == nullptr) if (group == nullptr)
group = &RenX_ModSystemPlugin::groups.front(); group = &RenX_ModSystemPlugin::groups.front();
} }
@ -232,8 +229,7 @@ int RenX_ModSystemPlugin::auth(RenX::Server &server, const RenX::PlayerInfo &pla
return player.access = group->access; return player.access = group->access;
} }
void RenX_ModSystemPlugin::tempAuth(RenX::Server &server, const RenX::PlayerInfo &player, const ModGroup *group, bool notify) const void RenX_ModSystemPlugin::tempAuth(RenX::Server &server, const RenX::PlayerInfo &player, const ModGroup *group, bool notify) const {
{
if (group == nullptr) if (group == nullptr)
group = this->getDefaultGroup(); group = this->getDefaultGroup();
@ -246,8 +242,7 @@ void RenX_ModSystemPlugin::tempAuth(RenX::Server &server, const RenX::PlayerInfo
server.sendMessage(player, Jupiter::StringS::Format("You have been authorized into group \"%.*s\", with access level %u.", group->name.size(), group->name.ptr(), player.access)); server.sendMessage(player, Jupiter::StringS::Format("You have been authorized into group \"%.*s\", with access level %u.", group->name.size(), group->name.ptr(), player.access));
} }
bool RenX_ModSystemPlugin::set(RenX::PlayerInfo &player, RenX_ModSystemPlugin::ModGroup &group) bool RenX_ModSystemPlugin::set(RenX::PlayerInfo &player, ModGroup &group) {
{
bool r = this->config[player.uuid].set("Group"_jrs, group.name); bool r = this->config[player.uuid].set("Group"_jrs, group.name);
this->config[player.uuid].set("SteamID"_jrs, Jupiter::StringS::Format("%llu", player.steamid)); this->config[player.uuid].set("SteamID"_jrs, Jupiter::StringS::Format("%llu", player.steamid));
this->config[player.uuid].set("LastIP"_jrs, player.ip); this->config[player.uuid].set("LastIP"_jrs, player.ip);
@ -261,8 +256,7 @@ bool RenX_ModSystemPlugin::removeModSection(const Jupiter::ReadableString& secti
return config.removeSection(section) && config.write(); return config.removeSection(section) && config.write();
} }
RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getGroupByName(const Jupiter::ReadableString &name, ModGroup *defaultGroup) const RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getGroupByName(const Jupiter::ReadableString &name, ModGroup *defaultGroup) const {
{
if (RenX_ModSystemPlugin::groups.size() != 0) if (RenX_ModSystemPlugin::groups.size() != 0)
for (auto node = this->groups.begin(); node != this->groups.end(); ++node) for (auto node = this->groups.begin(); node != this->groups.end(); ++node)
if (node->name.equalsi(name)) if (node->name.equalsi(name))
@ -271,8 +265,7 @@ RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getGroupByName(const Jupit
return defaultGroup; return defaultGroup;
} }
RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getGroupByAccess(int access, ModGroup *defaultGroup) const RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getGroupByAccess(int access, ModGroup *defaultGroup) const {
{
if (RenX_ModSystemPlugin::groups.size() != 0) if (RenX_ModSystemPlugin::groups.size() != 0)
for (auto node = this->groups.begin(); node != this->groups.end(); ++node) for (auto node = this->groups.begin(); node != this->groups.end(); ++node)
if (node->access == access) if (node->access == access)
@ -281,8 +274,7 @@ RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getGroupByAccess(int acces
return defaultGroup; return defaultGroup;
} }
RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getGroupByIndex(size_t index) const RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getGroupByIndex(size_t index) const {
{
if (RenX_ModSystemPlugin::groups.size() != 0) if (RenX_ModSystemPlugin::groups.size() != 0)
for (auto node = this->groups.begin(); node != this->groups.end(); ++node) for (auto node = this->groups.begin(); node != this->groups.end(); ++node)
if (index-- == 0) if (index-- == 0)
@ -291,56 +283,44 @@ RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getGroupByIndex(size_t ind
return nullptr; return nullptr;
} }
int RenX_ModSystemPlugin::getConfigAccess(const Jupiter::ReadableString &uuid) const int RenX_ModSystemPlugin::getConfigAccess(const Jupiter::ReadableString &uuid) const {
{
Jupiter::Config *section = this->config.getSection(uuid); Jupiter::Config *section = this->config.getSection(uuid);
if (section == nullptr) if (section == nullptr)
return RenX_ModSystemPlugin::groups.front().access; return RenX_ModSystemPlugin::groups.front().access;
//for (auto node = this->groups.begin(); node != this->groups.end(); ++node) //for (auto node = this->groups.begin(); node != this->groups.end(); ++node)
return section->get<int>("Access"_jrs, return section->get<int>("Access"_jrs, getGroupByName(section->get("Group"_jrs),const_cast<ModGroup *>(&groups.front()))->access);
RenX_ModSystemPlugin::getGroupByName(section->get("Group"_jrs),
const_cast<ModGroup *>(&groups.front()))->access);
} }
size_t RenX_ModSystemPlugin::getGroupCount() const size_t RenX_ModSystemPlugin::getGroupCount() const {
{
return RenX_ModSystemPlugin::groups.size(); return RenX_ModSystemPlugin::groups.size();
} }
RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getDefaultGroup() const RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getDefaultGroup() const {
{
return const_cast<ModGroup *>(&RenX_ModSystemPlugin::groups.front()); return const_cast<ModGroup *>(&RenX_ModSystemPlugin::groups.front());
} }
RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getDefaultATMGroup() const RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getDefaultATMGroup() const {
{ return getGroupByName(m_atmDefault);
return RenX_ModSystemPlugin::getGroupByName(RenX_ModSystemPlugin::atmDefault);
} }
RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getModeratorGroup() const RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getModeratorGroup() const {
{ return getGroupByName(m_moderatorGroup);
return RenX_ModSystemPlugin::getGroupByName(RenX_ModSystemPlugin::moderatorGroup);
} }
RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getAdministratorGroup() const RenX_ModSystemPlugin::ModGroup *RenX_ModSystemPlugin::getAdministratorGroup() const {
{ return getGroupByName(m_administratorGroup);
return RenX_ModSystemPlugin::getGroupByName(RenX_ModSystemPlugin::administratorGroup);
} }
RenX_ModSystemPlugin::~RenX_ModSystemPlugin() RenX_ModSystemPlugin::~RenX_ModSystemPlugin() {
{
RenX::Core *core = RenX::getCore(); RenX::Core *core = RenX::getCore();
unsigned int total = core->getServerCount(); size_t server_count = core->getServerCount();
RenX::Server *server; RenX::Server *server;
while (total != 0) while (server_count != 0) {
{ server = core->getServer(--server_count);
server = core->getServer(--total); if (server->players.size() != server->getBotCount()) {
if (server->players.size() != server->getBotCount()) for (auto node = server->players.begin(); node != server->players.end(); ++node) {
for (auto node = server->players.begin(); node != server->players.end(); ++node) if (node->isBot == false) {
{
if (node->isBot == false)
{
node->varData[RenX_ModSystemPlugin::name].remove("Group"_jrs); node->varData[RenX_ModSystemPlugin::name].remove("Group"_jrs);
node->gamePrefix.truncate(node->gamePrefix.size()); node->gamePrefix.truncate(node->gamePrefix.size());
node->formatNamePrefix.truncate(node->formatNamePrefix.size()); node->formatNamePrefix.truncate(node->formatNamePrefix.size());
@ -352,24 +332,21 @@ RenX_ModSystemPlugin::~RenX_ModSystemPlugin()
node->access = 0; node->access = 0;
} }
} }
}
} }
RenX_ModSystemPlugin::groups.clear(); RenX_ModSystemPlugin::groups.clear();
} }
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 == false)
RenX_ModSystemPlugin::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 == false && player.uuid.isNotEmpty())
{
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, Jupiter::StringS::Format("%llu", player.steamid)); section->set("SteamID"_jrs, Jupiter::StringS::Format("%llu", player.steamid));
section->set("LastIP"_jrs, player.ip); section->set("LastIP"_jrs, player.ip);
section->set("Name"_jrs, player.name); section->set("Name"_jrs, player.name);
@ -377,42 +354,39 @@ void RenX_ModSystemPlugin::RenX_OnPlayerDelete(RenX::Server &server, const RenX:
} }
} }
void RenX_ModSystemPlugin::RenX_OnIDChange(RenX::Server &server, const RenX::PlayerInfo &player, int oldID) void RenX_ModSystemPlugin::RenX_OnIDChange(RenX::Server &server, const RenX::PlayerInfo &player, int oldID) {
{ if (player.access != 0 && server.isDevBot()) {
if (player.access != 0 && server.isDevBot())
server.sendData(Jupiter::StringS::Format("d%d\n", player.id)); server.sendData(Jupiter::StringS::Format("d%d\n", player.id));
}
} }
void RenX_ModSystemPlugin::RenX_OnAdminLogin(RenX::Server &server, const RenX::PlayerInfo &player) void RenX_ModSystemPlugin::RenX_OnAdminLogin(RenX::Server &server, const RenX::PlayerInfo &player) {
{
ModGroup *group = nullptr; ModGroup *group = nullptr;
if (player.adminType.equals("administrator")) if (player.adminType.equals("administrator"))
group = RenX_ModSystemPlugin::getGroupByName(RenX_ModSystemPlugin::administratorGroup); group = getGroupByName(m_administratorGroup);
else if (player.adminType.equals("moderator")) else if (player.adminType.equals("moderator"))
group = RenX_ModSystemPlugin::getGroupByName(RenX_ModSystemPlugin::moderatorGroup); group = getGroupByName(m_moderatorGroup);
if (group != nullptr && player.access < group->access) if (group != nullptr && player.access < group->access)
player.access = group->access; player.access = group->access;
} }
void RenX_ModSystemPlugin::RenX_OnAdminGrant(RenX::Server &server, const RenX::PlayerInfo &player) void RenX_ModSystemPlugin::RenX_OnAdminGrant(RenX::Server &server, const RenX::PlayerInfo &player) {
{ RenX_OnAdminLogin(server, player);
RenX_ModSystemPlugin::RenX_OnAdminLogin(server, player);
} }
void RenX_ModSystemPlugin::RenX_OnAdminLogout(RenX::Server &server, const RenX::PlayerInfo &player) void RenX_ModSystemPlugin::RenX_OnAdminLogout(RenX::Server &server, const RenX::PlayerInfo &player) {
{
ModGroup *group = nullptr; ModGroup *group = nullptr;
int access = RenX_ModSystemPlugin::groups.size() == 0 ? 0 : RenX_ModSystemPlugin::groups.front().access; int access = RenX_ModSystemPlugin::groups.size() == 0 ? 0 : RenX_ModSystemPlugin::groups.front().access;
if (player.adminType.equals("administrator")) if (player.adminType.equals("administrator"))
{ {
access = 2; access = 2;
group = RenX_ModSystemPlugin::getGroupByName(RenX_ModSystemPlugin::administratorGroup); group = getGroupByName(m_administratorGroup);
} }
else if (player.adminType.equals("moderator")) else if (player.adminType.equals("moderator"))
{ {
access = 1; access = 1;
group = RenX_ModSystemPlugin::getGroupByName(RenX_ModSystemPlugin::moderatorGroup); group = getGroupByName(m_moderatorGroup);
} }
if (group != nullptr) if (group != nullptr)
access = group->access; access = group->access;

20
src/Plugins/RenX/RenX.ModSystem/RenX_ModSystem.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -105,15 +105,15 @@ public: // Jupiter::Plugin
int OnRehash() override; int OnRehash() override;
private: private:
bool lockSteam; bool m_lockSteam;
bool lockIP; bool m_lockIP;
bool lockName; bool m_lockName;
bool kickLockMismatch; bool m_kickLockMismatch;
bool autoAuthSteam; bool m_autoAuthSteam;
bool autoAuthIP; bool m_autoAuthIP;
Jupiter::StringS atmDefault; Jupiter::StringS m_atmDefault;
Jupiter::StringS moderatorGroup; Jupiter::StringS m_moderatorGroup;
Jupiter::StringS administratorGroup; Jupiter::StringS m_administratorGroup;
}; };
GENERIC_IRC_COMMAND(AuthIRCCommand) GENERIC_IRC_COMMAND(AuthIRCCommand)

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016-2017 Jessica James. * Copyright (C) 2016-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -33,97 +33,33 @@ static STRING_LITERAL_AS_NAMED_REFERENCE(CONTENT_TYPE_APPLICATION_JSON, "applica
const Jupiter::ReferenceString server_list_game_header = "<html><body>"_jrs; const Jupiter::ReferenceString server_list_game_header = "<html><body>"_jrs;
const Jupiter::ReferenceString server_list_game_footer = "\n</body></html>"_jrs; const Jupiter::ReferenceString server_list_game_footer = "\n</body></html>"_jrs;
Jupiter::String jsonify(const Jupiter::ReadableString &in_str) // TODO: can probably replace with some of the jessilib stuff
{ Jupiter::String jsonify(const Jupiter::ReadableString &in_str) {
const unsigned char *ptr = reinterpret_cast<const unsigned char *>(in_str.ptr()); const unsigned char *ptr = reinterpret_cast<const unsigned char *>(in_str.ptr());
const unsigned char *end_ptr = ptr + in_str.size(); const unsigned char *end_ptr = ptr + in_str.size();
Jupiter::String result(in_str.size()); Jupiter::String result(in_str.size());
while (ptr < end_ptr) while (ptr < end_ptr) {
{ if (*ptr == '\\') { // backslash
if (*ptr == '\\') // backslash
{
result += '\\'; result += '\\';
result += '\\'; result += '\\';
} }
else if (*ptr == '\"') // quotation else if (*ptr == '\"') { // quotation
{
result += '\\'; result += '\\';
result += '\"'; result += '\"';
} }
else if (*ptr < 0x20) // control characters else if (*ptr < 0x20) { // control characters
result.aformat("\\u%04x", *ptr); result.aformat("\\u%04x", *ptr);
else if ((*ptr & 0x80) != 0) // UTF-8 sequence; copy to bypass above processing
{
result += *ptr;
if ((*ptr & 0x40) != 0)
{
// this is a 2+ byte sequence
if ((*ptr & 0x20) != 0)
{
// this is a 3+ byte sequence
if ((*ptr & 0x10) != 0)
{
// this is a 4 byte sequnce
result += *++ptr;
}
result += *++ptr;
}
result += *++ptr;
}
}
else // Character in standard ASCII table
result += *ptr;
++ptr;
}
return result;
}
Jupiter::String sanitize_game(const Jupiter::ReadableString &in_str)
{
const unsigned char *ptr = reinterpret_cast<const unsigned char *>(in_str.ptr());
const unsigned char *end_ptr = ptr + in_str.size();
Jupiter::String result(in_str.size());
while (ptr < end_ptr != 0)
{
if (*ptr == '\\') // backslash
{
result += '\\';
result += '\\';
} }
else if (*ptr == '\"') // quotation else if ((*ptr & 0x80) != 0) { // UTF-8 sequence; copy to bypass above processing
{
result += '\\';
result += '\"';
}
else if (*ptr < 0x20) // control characters
result.aformat("\\u%04x", *ptr);
else if (*ptr == '~') // Game server list control character
result += "\\u007E"_jrs;
else if (*ptr == ';') // Game server list control character
result += "\\u003B"_jrs;
else if ((*ptr & 0x80) != 0) // UTF-8 sequence; copy to bypass above processing
{
result += *ptr; result += *ptr;
if ((*ptr & 0x40) != 0) {
if ((*ptr & 0x40) != 0)
{
// this is a 2+ byte sequence // this is a 2+ byte sequence
if ((*ptr & 0x20) != 0) if ((*ptr & 0x20) != 0) {
{
// this is a 3+ byte sequence // this is a 3+ byte sequence
if ((*ptr & 0x10) != 0) if ((*ptr & 0x10) != 0) {
{
// this is a 4 byte sequnce // this is a 4 byte sequnce
result += *++ptr; result += *++ptr;
} }
@ -134,8 +70,9 @@ Jupiter::String sanitize_game(const Jupiter::ReadableString &in_str)
result += *++ptr; result += *++ptr;
} }
} }
else // Character in standard ASCII table else { // Character in standard ASCII table
result += *ptr; result += *ptr;
}
++ptr; ++ptr;
} }
@ -143,69 +80,67 @@ Jupiter::String sanitize_game(const Jupiter::ReadableString &in_str)
return result; return result;
} }
bool RenX_ServerListPlugin::initialize() bool RenX_ServerListPlugin::initialize() {
{ m_web_hostname = this->config.get("Hostname"_jrs, ""_jrs);
RenX_ServerListPlugin::web_hostname = this->config.get("Hostname"_jrs, ""_jrs); m_web_path = this->config.get("Path"_jrs, "/"_jrs);
RenX_ServerListPlugin::web_path = this->config.get("Path"_jrs, "/"_jrs); m_server_list_page_name = this->config.get("ServersPageName"_jrs, "servers"_jrs);
RenX_ServerListPlugin::server_list_page_name = this->config.get("ServersPageName"_jrs, "servers"_jrs); m_server_list_long_page_name = this->config.get("HumanServersPageName"_jrs, "servers_long"_jrs);
RenX_ServerListPlugin::server_list_long_page_name = this->config.get("HumanServersPageName"_jrs, "servers_long"_jrs); m_server_page_name = this->config.get("ServerPageName"_jrs, "server"_jrs);
RenX_ServerListPlugin::server_page_name = this->config.get("ServerPageName"_jrs, "server"_jrs); m_metadata_page_name = this->config.get("MetadataPageName"_jrs, "metadata"_jrs);
RenX_ServerListPlugin::metadata_page_name = this->config.get("MetadataPageName"_jrs, "metadata"_jrs); m_metadata_prometheus_page_name = this->config.get("MetadataPrometheusPageName"_jrs, "metadata_prometheus"_jrs);
RenX_ServerListPlugin::metadata_prometheus_page_name = this->config.get("MetadataPrometheusPageName"_jrs, "metadata_prometheus"_jrs);
/** Initialize content */ /** Initialize content */
Jupiter::HTTP::Server &server = getHTTPServer(); Jupiter::HTTP::Server &server = getHTTPServer();
// Server list page // Server list page
Jupiter::HTTP::Server::Content *content = new Jupiter::HTTP::Server::Content(RenX_ServerListPlugin::server_list_page_name, handle_server_list_page); std::unique_ptr<Jupiter::HTTP::Server::Content> content = std::make_unique<Jupiter::HTTP::Server::Content>(m_server_list_page_name, handle_server_list_page);
content->language = &Jupiter::HTTP::Content::Language::ENGLISH; content->language = &Jupiter::HTTP::Content::Language::ENGLISH;
content->type = &CONTENT_TYPE_APPLICATION_JSON; content->type = &CONTENT_TYPE_APPLICATION_JSON;
content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8; content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8;
content->free_result = false; content->free_result = false;
server.hook(RenX_ServerListPlugin::web_hostname, RenX_ServerListPlugin::web_path, content); server.hook(m_web_hostname, m_web_path, std::move(content));
// Server list (long) page // Server list (long) page
content = new Jupiter::HTTP::Server::Content(RenX_ServerListPlugin::server_list_long_page_name, handle_server_list_long_page); content = std::make_unique<Jupiter::HTTP::Server::Content>(m_server_list_long_page_name, handle_server_list_long_page);
content->language = &Jupiter::HTTP::Content::Language::ENGLISH; content->language = &Jupiter::HTTP::Content::Language::ENGLISH;
content->type = &CONTENT_TYPE_APPLICATION_JSON; content->type = &CONTENT_TYPE_APPLICATION_JSON;
content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8; content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8;
content->free_result = true; content->free_result = true;
server.hook(RenX_ServerListPlugin::web_hostname, RenX_ServerListPlugin::web_path, content); server.hook(m_web_hostname, m_web_path, std::move(content));
// Server page (GUIDs) // Server page (GUIDs)
content = new Jupiter::HTTP::Server::Content(RenX_ServerListPlugin::server_page_name, handle_server_page); content = std::make_unique<Jupiter::HTTP::Server::Content>(m_server_page_name, handle_server_page);
content->language = &Jupiter::HTTP::Content::Language::ENGLISH; content->language = &Jupiter::HTTP::Content::Language::ENGLISH;
content->type = &CONTENT_TYPE_APPLICATION_JSON; content->type = &CONTENT_TYPE_APPLICATION_JSON;
content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8; content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8;
content->free_result = true; content->free_result = true;
server.hook(RenX_ServerListPlugin::web_hostname, RenX_ServerListPlugin::web_path, content); server.hook(m_web_hostname, m_web_path, std::move(content));
// Metadata page // Metadata page
content = new Jupiter::HTTP::Server::Content(RenX_ServerListPlugin::metadata_page_name, handle_metadata_page); content = std::make_unique<Jupiter::HTTP::Server::Content>(m_metadata_page_name, handle_metadata_page);
content->language = &Jupiter::HTTP::Content::Language::ENGLISH; content->language = &Jupiter::HTTP::Content::Language::ENGLISH;
content->type = &CONTENT_TYPE_APPLICATION_JSON; content->type = &CONTENT_TYPE_APPLICATION_JSON;
content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8; content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8;
content->free_result = false; content->free_result = false;
server.hook(RenX_ServerListPlugin::web_hostname, RenX_ServerListPlugin::web_path, content); server.hook(m_web_hostname, m_web_path, std::move(content));
// Metadata page // Metadata page
content = new Jupiter::HTTP::Server::Content(RenX_ServerListPlugin::metadata_prometheus_page_name, handle_metadata_prometheus_page); content = std::make_unique<Jupiter::HTTP::Server::Content>(m_metadata_prometheus_page_name, handle_metadata_prometheus_page);
content->language = &Jupiter::HTTP::Content::Language::ENGLISH; content->language = &Jupiter::HTTP::Content::Language::ENGLISH;
content->type = &CONTENT_TYPE_APPLICATION_JSON; content->type = &CONTENT_TYPE_APPLICATION_JSON;
content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8; content->charset = &Jupiter::HTTP::Content::Type::Text::Charset::UTF8;
content->free_result = false; content->free_result = false;
server.hook(RenX_ServerListPlugin::web_hostname, RenX_ServerListPlugin::web_path, content); server.hook(m_web_hostname, m_web_path, std::move(content));
this->updateServerList(); this->updateServerList();
return true; return true;
} }
RenX_ServerListPlugin::~RenX_ServerListPlugin() RenX_ServerListPlugin::~RenX_ServerListPlugin() {
{
Jupiter::HTTP::Server &server = getHTTPServer(); Jupiter::HTTP::Server &server = getHTTPServer();
server.remove(RenX_ServerListPlugin::web_hostname, RenX_ServerListPlugin::web_path, RenX_ServerListPlugin::server_list_page_name); server.remove(m_web_hostname, m_web_path, m_server_list_page_name);
server.remove(RenX_ServerListPlugin::web_hostname, RenX_ServerListPlugin::web_path, RenX_ServerListPlugin::server_list_long_page_name); server.remove(m_web_hostname, m_web_path, m_server_list_long_page_name);
server.remove(RenX_ServerListPlugin::web_hostname, RenX_ServerListPlugin::web_path, RenX_ServerListPlugin::server_page_name); server.remove(m_web_hostname, m_web_path, m_server_page_name);
} }
size_t RenX_ServerListPlugin::getListedPlayerCount(const RenX::Server& server) { size_t RenX_ServerListPlugin::getListedPlayerCount(const RenX::Server& server) {
@ -213,28 +148,23 @@ size_t RenX_ServerListPlugin::getListedPlayerCount(const RenX::Server& server) {
return std::min(server.activePlayers(false).size(), player_limit); return std::min(server.activePlayers(false).size(), player_limit);
} }
Jupiter::ReadableString *RenX_ServerListPlugin::getServerListJSON() Jupiter::ReadableString *RenX_ServerListPlugin::getServerListJSON() {
{ return &m_server_list_json;
return &server_list_json;
} }
Jupiter::ReadableString *RenX_ServerListPlugin::getMetadataJSON() Jupiter::ReadableString *RenX_ServerListPlugin::getMetadataJSON() {
{ return &m_metadata_json;
return &metadata_json;
} }
Jupiter::ReadableString *RenX_ServerListPlugin::getMetadataPrometheus() Jupiter::ReadableString *RenX_ServerListPlugin::getMetadataPrometheus() {
{ return &m_metadata_prometheus;
return &metadata_prometheus;
} }
constexpr const char *json_bool_as_cstring(bool in) constexpr const char *json_bool_as_cstring(bool in) {
{
return in ? "true" : "false"; return in ? "true" : "false";
} }
Jupiter::StringS RenX_ServerListPlugin::server_as_json(const RenX::Server &server) Jupiter::StringS RenX_ServerListPlugin::server_as_json(const RenX::Server &server) {
{
Jupiter::String server_json_block(128); Jupiter::String server_json_block(128);
ListServerInfo serverInfo = getListServerInfo(server); ListServerInfo serverInfo = getListServerInfo(server);
@ -301,8 +231,7 @@ Jupiter::StringS RenX_ServerListPlugin::server_as_json(const RenX::Server &serve
return server_json_block; return server_json_block;
} }
Jupiter::StringS RenX_ServerListPlugin::server_as_long_json(const RenX::Server &server) Jupiter::StringS RenX_ServerListPlugin::server_as_long_json(const RenX::Server &server) {
{
Jupiter::String server_json_block(128); Jupiter::String server_json_block(128);
ListServerInfo serverInfo = getListServerInfo(server); ListServerInfo serverInfo = getListServerInfo(server);
@ -381,22 +310,20 @@ Jupiter::StringS RenX_ServerListPlugin::server_as_long_json(const RenX::Server &
server_hostname.size(), server_hostname.ptr()); server_hostname.size(), server_hostname.ptr());
// Level Rotation // Level Rotation
if (server.maps.size() != 0) if (server.maps.size() != 0) {
{
server_json_block += ",\n\t\t\"Levels\": ["_jrs; server_json_block += ",\n\t\t\"Levels\": ["_jrs;
server_json_block += "\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs; server_json_block += "\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs;
server_json_block += jsonify(server.maps.get(0)->name); server_json_block += jsonify(server.maps[0].name);
server_json_block += "\",\n\t\t\t\t\"GUID\": \""_jrs; server_json_block += "\",\n\t\t\t\t\"GUID\": \""_jrs;
server_json_block += RenX::formatGUID(*server.maps.get(0)); server_json_block += RenX::formatGUID(server.maps[0]);
server_json_block += "\"\n\t\t\t}"_jrs; server_json_block += "\"\n\t\t\t}"_jrs;
for (size_t index = 1; index != server.maps.size(); ++index) for (size_t index = 1; index != server.maps.size(); ++index) {
{
server_json_block += ",\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs; server_json_block += ",\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs;
server_json_block += jsonify(server.maps.get(index)->name); server_json_block += jsonify(server.maps[index].name);
server_json_block += "\",\n\t\t\t\t\"GUID\": \""_jrs; server_json_block += "\",\n\t\t\t\t\"GUID\": \""_jrs;
server_json_block += RenX::formatGUID(*server.maps.get(index)); server_json_block += RenX::formatGUID(server.maps[index]);
server_json_block += "\"\n\t\t\t}"_jrs; server_json_block += "\"\n\t\t\t}"_jrs;
} }
@ -404,18 +331,16 @@ Jupiter::StringS RenX_ServerListPlugin::server_as_long_json(const RenX::Server &
} }
// Mutators // Mutators
if (server.mutators.size() != 0) if (server.mutators.size() != 0) {
{
server_json_block += ",\n\t\t\"Mutators\": ["_jrs; server_json_block += ",\n\t\t\"Mutators\": ["_jrs;
server_json_block += "\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs; server_json_block += "\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs;
server_json_block += jsonify(*server.mutators.get(0)); server_json_block += jsonify(server.mutators[0]);
server_json_block += "\"\n\t\t\t}"_jrs; server_json_block += "\"\n\t\t\t}"_jrs;
for (size_t index = 1; index != server.mutators.size(); ++index) for (size_t index = 1; index != server.mutators.size(); ++index) {
{
server_json_block += ",\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs; server_json_block += ",\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs;
server_json_block += jsonify(*server.mutators.get(index)); server_json_block += jsonify(server.mutators[index]);
server_json_block += "\"\n\t\t\t}"_jrs; server_json_block += "\"\n\t\t\t}"_jrs;
} }
@ -423,8 +348,7 @@ Jupiter::StringS RenX_ServerListPlugin::server_as_long_json(const RenX::Server &
} }
// Player List // Player List
if (activePlayers.size() != 0) if (activePlayers.size() != 0) {
{
server_json_block += ",\n\t\t\"PlayerList\": ["_jrs; server_json_block += ",\n\t\t\"PlayerList\": ["_jrs;
auto node = activePlayers.begin(); auto node = activePlayers.begin();
@ -436,8 +360,7 @@ Jupiter::StringS RenX_ServerListPlugin::server_as_long_json(const RenX::Server &
++node; ++node;
// Add remaining players to JSON // Add remaining players to JSON
while (node != activePlayers.end()) while (node != activePlayers.end()) {
{
server_json_block += ",\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs; server_json_block += ",\n\t\t\t{\n\t\t\t\t\"Name\": \""_jrs;
server_json_block += jsonify((*node)->name); server_json_block += jsonify((*node)->name);
server_json_block += "\"\n\t\t\t}"_jrs; server_json_block += "\"\n\t\t\t}"_jrs;
@ -452,45 +375,40 @@ Jupiter::StringS RenX_ServerListPlugin::server_as_long_json(const RenX::Server &
return server_json_block; return server_json_block;
} }
void RenX_ServerListPlugin::addServerToServerList(RenX::Server &server) void RenX_ServerListPlugin::addServerToServerList(RenX::Server &server) {
{
Jupiter::String server_json_block(256); Jupiter::String server_json_block(256);
// append to server_list_json // append to server_list_json
server_json_block = server_as_json(server); server_json_block = server_as_json(server);
if (RenX_ServerListPlugin::server_list_json.size() <= 2) if (m_server_list_json.size() <= 2) {
{ m_server_list_json = '[';
RenX_ServerListPlugin::server_list_json = '[';
} }
else else {
{ m_server_list_json.truncate(1); // remove trailing ']'.
RenX_ServerListPlugin::server_list_json.truncate(1); // remove trailing ']'. m_server_list_json += ',';
RenX_ServerListPlugin::server_list_json += ',';
} }
RenX_ServerListPlugin::server_list_json += server_json_block; m_server_list_json += server_json_block;
RenX_ServerListPlugin::server_list_json += ']'; m_server_list_json += ']';
server_json_block.erase(); server_json_block.erase();
// add to individual listing // add to individual listing
server_json_block = '{'; server_json_block = '{';
if (server.maps.size() != 0) if (server.maps.size() != 0) {
{
server_json_block += "\"Levels\":["_jrs; server_json_block += "\"Levels\":["_jrs;
server_json_block += "{\"Name\":\""_jrs; server_json_block += "{\"Name\":\""_jrs;
server_json_block += jsonify(server.maps.get(0)->name); server_json_block += jsonify(server.maps[0].name);
server_json_block += "\",\"GUID\":\""_jrs; server_json_block += "\",\"GUID\":\""_jrs;
server_json_block += RenX::formatGUID(*server.maps.get(0)); server_json_block += RenX::formatGUID(server.maps[0]);
server_json_block += "\"}"_jrs; server_json_block += "\"}"_jrs;
for (size_t index = 1; index != server.maps.size(); ++index) for (size_t index = 1; index != server.maps.size(); ++index) {
{
server_json_block += ",{\"Name\":\""_jrs; server_json_block += ",{\"Name\":\""_jrs;
server_json_block += jsonify(server.maps.get(index)->name); server_json_block += jsonify(server.maps[index].name);
server_json_block += "\",\"GUID\":\""_jrs; server_json_block += "\",\"GUID\":\""_jrs;
server_json_block += RenX::formatGUID(*server.maps.get(index)); server_json_block += RenX::formatGUID(server.maps[index]);
server_json_block += "\"}"_jrs; server_json_block += "\"}"_jrs;
} }
@ -498,20 +416,18 @@ void RenX_ServerListPlugin::addServerToServerList(RenX::Server &server)
} }
// Mutators // Mutators
if (server.mutators.size() != 0) if (server.mutators.size() != 0) {
{
if (server.maps.size() != 0) if (server.maps.size() != 0)
server_json_block += ","_jrs; server_json_block += ","_jrs;
server_json_block += "\"Mutators\":["_jrs; server_json_block += "\"Mutators\":["_jrs;
server_json_block += "{\"Name\":\""_jrs; server_json_block += "{\"Name\":\""_jrs;
server_json_block += jsonify(*server.mutators.get(0)); server_json_block += jsonify(server.mutators[0]);
server_json_block += "\"}"_jrs; server_json_block += "\"}"_jrs;
for (size_t index = 1; index != server.mutators.size(); ++index) for (size_t index = 1; index != server.mutators.size(); ++index) {
{
server_json_block += ",{\"Name\":\""_jrs; server_json_block += ",{\"Name\":\""_jrs;
server_json_block += jsonify(*server.mutators.get(index)); server_json_block += jsonify(server.mutators[index]);
server_json_block += "\"}"_jrs; server_json_block += "\"}"_jrs;
} }
@ -519,14 +435,12 @@ void RenX_ServerListPlugin::addServerToServerList(RenX::Server &server)
} }
// Player List // Player List
if (server.players.size() != 0 && server.players.size() != server.getBotCount()) if (server.players.size() != 0 && server.players.size() != server.getBotCount()) {
{
server_json_block += ",\"PlayerList\":["_jrs; server_json_block += ",\"PlayerList\":["_jrs;
auto node = server.players.begin(); auto node = server.players.begin();
if (node != server.players.end()) if (node != server.players.end()) {
{
server_json_block += "{\"Name\":\""_jrs; server_json_block += "{\"Name\":\""_jrs;
server_json_block += jsonify(node->name); server_json_block += jsonify(node->name);
server_json_block += "\", \"isBot\":"_jrs; server_json_block += "\", \"isBot\":"_jrs;
@ -538,8 +452,7 @@ void RenX_ServerListPlugin::addServerToServerList(RenX::Server &server)
++node; ++node;
} }
while (node != server.players.end()) while (node != server.players.end()) {
{
server_json_block += ",{\"Name\":\""_jrs; server_json_block += ",{\"Name\":\""_jrs;
server_json_block += jsonify(node->name); server_json_block += jsonify(node->name);
server_json_block += "\", \"isBot\":"_jrs; server_json_block += "\", \"isBot\":"_jrs;
@ -562,63 +475,57 @@ void RenX_ServerListPlugin::addServerToServerList(RenX::Server &server)
updateMetadata(); updateMetadata();
} }
void RenX_ServerListPlugin::updateServerList() void RenX_ServerListPlugin::updateServerList() {
{ const auto& servers = RenX::getCore()->getServers();
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers();
size_t index = 0; size_t index = 0;
RenX::Server *server; RenX::Server *server;
// regenerate server_list_json // regenerate server_list_json
RenX_ServerListPlugin::server_list_json = '['; m_server_list_json = '[';
while (index != servers.size()) while (index != servers.size()) {
{ server = servers[index];
server = servers.get(index); if (server->isConnected() && server->isFullyConnected()) {
if (server->isConnected() && server->isFullyConnected()) m_server_list_json += server_as_json(*server);
{
RenX_ServerListPlugin::server_list_json += server_as_json(*server);
++index; ++index;
break; break;
} }
++index; ++index;
} }
while (index != servers.size()) while (index != servers.size()) {
{ server = servers[index];
server = servers.get(index); if (server->isConnected() && server->isFullyConnected()) {
if (server->isConnected() && server->isFullyConnected()) m_server_list_json += ',';
{ m_server_list_json += server_as_json(*server);
RenX_ServerListPlugin::server_list_json += ',';
RenX_ServerListPlugin::server_list_json += server_as_json(*server);
} }
++index; ++index;
} }
RenX_ServerListPlugin::server_list_json += ']'; m_server_list_json += ']';
// Also update metadata so that it reflects any changes // Also update metadata so that it reflects any changes
updateMetadata(); updateMetadata();
} }
void RenX_ServerListPlugin::updateMetadata() { void RenX_ServerListPlugin::updateMetadata() {
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(); const auto& servers = RenX::getCore()->getServers();
unsigned int server_count{}; unsigned int server_count{};
unsigned int player_count{}; unsigned int player_count{};
for (size_t index = 0; index != servers.size(); ++index) for (size_t index = 0; index != servers.size(); ++index) {
{ RenX::Server* server = servers[index];
RenX::Server* server = servers.get(index);
if (server->isConnected() && server->isFullyConnected()) { if (server->isConnected() && server->isFullyConnected()) {
++server_count; ++server_count;
player_count += getListedPlayerCount(*server); player_count += getListedPlayerCount(*server);
} }
} }
metadata_json.format(R"json({"player_count":%u,"server_count":%u})json", m_metadata_json.format(R"json({"player_count":%u,"server_count":%u})json",
player_count, server_count); player_count, server_count);
metadata_prometheus.format("player_count %u\nserver_count %u\n", m_metadata_prometheus.format("player_count %u\nserver_count %u\n",
player_count, server_count); player_count, server_count);
} }
@ -669,46 +576,39 @@ RenX_ServerListPlugin::ListServerInfo RenX_ServerListPlugin::getListServerInfo(c
return result; return result;
} }
void RenX_ServerListPlugin::RenX_OnServerFullyConnected(RenX::Server &server) void RenX_ServerListPlugin::RenX_OnServerFullyConnected(RenX::Server &server) {
{
this->addServerToServerList(server); this->addServerToServerList(server);
} }
void RenX_ServerListPlugin::RenX_OnServerDisconnect(RenX::Server &server, RenX::DisconnectReason) void RenX_ServerListPlugin::RenX_OnServerDisconnect(RenX::Server &server, RenX::DisconnectReason) {
{
this->updateServerList(); this->updateServerList();
// remove from individual listing // remove from individual listing
server.varData[this->name].remove("j"_jrs); server.varData[this->name].remove("j"_jrs);
} }
void RenX_ServerListPlugin::RenX_OnJoin(RenX::Server &, const RenX::PlayerInfo &) void RenX_ServerListPlugin::RenX_OnJoin(RenX::Server &, const RenX::PlayerInfo &) {
{
this->updateServerList(); this->updateServerList();
} }
void RenX_ServerListPlugin::RenX_OnPart(RenX::Server &server, const RenX::PlayerInfo &) void RenX_ServerListPlugin::RenX_OnPart(RenX::Server &server, const RenX::PlayerInfo &) {
{
if (server.isTravelling() == false || server.isSeamless()) if (server.isTravelling() == false || server.isSeamless())
this->updateServerList(); this->updateServerList();
} }
void RenX_ServerListPlugin::RenX_OnMapLoad(RenX::Server &server, const Jupiter::ReadableString &map) void RenX_ServerListPlugin::RenX_OnMapLoad(RenX::Server &server, const Jupiter::ReadableString &map) {
{
this->updateServerList(); this->updateServerList();
} }
// Plugin instantiation and entry point. // Plugin instantiation and entry point.
RenX_ServerListPlugin pluginInstance; RenX_ServerListPlugin pluginInstance;
Jupiter::ReadableString *handle_server_list_page(const Jupiter::ReadableString &) Jupiter::ReadableString *handle_server_list_page(const Jupiter::ReadableString &) {
{
return pluginInstance.getServerListJSON(); return pluginInstance.getServerListJSON();
} }
Jupiter::ReadableString *handle_server_list_long_page(const Jupiter::ReadableString &) Jupiter::ReadableString *handle_server_list_long_page(const Jupiter::ReadableString &) {
{ const auto& servers = RenX::getCore()->getServers();
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers();
size_t index = 0; size_t index = 0;
RenX::Server *server; RenX::Server *server;
Jupiter::String *server_list_long_json = new Jupiter::String(256 * servers.size()); Jupiter::String *server_list_long_json = new Jupiter::String(256 * servers.size());
@ -717,11 +617,9 @@ Jupiter::ReadableString *handle_server_list_long_page(const Jupiter::ReadableStr
*server_list_long_json = "["_jrs; *server_list_long_json = "["_jrs;
while (index != servers.size()) while (index != servers.size()) {
{ server = servers[index];
server = servers.get(index); if (server->isConnected() && server->isFullyConnected()) {
if (server->isConnected() && server->isFullyConnected())
{
*server_list_long_json += "\n\t"_jrs; *server_list_long_json += "\n\t"_jrs;
*server_list_long_json += pluginInstance.server_as_long_json(*server); *server_list_long_json += pluginInstance.server_as_long_json(*server);
++index; ++index;
@ -729,11 +627,9 @@ Jupiter::ReadableString *handle_server_list_long_page(const Jupiter::ReadableStr
} }
++index; ++index;
} }
while (index != servers.size()) while (index != servers.size()) {
{ server = servers[index];
server = servers.get(index); if (server->isConnected() && server->isFullyConnected()) {
if (server->isConnected() && server->isFullyConnected())
{
*server_list_long_json += ",\n\t"_jrs; *server_list_long_json += ",\n\t"_jrs;
*server_list_long_json += pluginInstance.server_as_long_json(*server); *server_list_long_json += pluginInstance.server_as_long_json(*server);
} }
@ -745,8 +641,7 @@ Jupiter::ReadableString *handle_server_list_long_page(const Jupiter::ReadableStr
return server_list_long_json; return server_list_long_json;
} }
Jupiter::ReadableString *handle_server_page(const Jupiter::ReadableString &query_string) Jupiter::ReadableString *handle_server_page(const Jupiter::ReadableString &query_string) {
{
Jupiter::HTTP::HTMLFormResponse html_form_response(query_string); Jupiter::HTTP::HTMLFormResponse html_form_response(query_string);
Jupiter::ReferenceString address; Jupiter::ReferenceString address;
int port = 0; int port = 0;
@ -757,22 +652,20 @@ Jupiter::ReadableString *handle_server_page(const Jupiter::ReadableString &query
if (html_form_response.table.size() < 2) if (html_form_response.table.size() < 2)
return new Jupiter::ReferenceString(); return new Jupiter::ReferenceString();
if (html_form_response.table.size() != 0) if (html_form_response.table.size() != 0) {
{
address = html_form_response.tableGet("ip"_jrs, address); address = html_form_response.tableGet("ip"_jrs, address);
port = html_form_response.tableGetCast<int>("port"_jrs, port); port = html_form_response.tableGetCast<int>("port"_jrs, port);
} }
// search for server // search for server
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(); const auto& servers = RenX::getCore()->getServers();
size_t index = 0; size_t index = 0;
while (true) while (true) {
{
if (index == servers.size()) if (index == servers.size())
return new Jupiter::ReferenceString(); return new Jupiter::ReferenceString();
server = servers.get(index); server = servers[index];
if (address.equals(pluginInstance.getListServerAddress(*server)) && server->getPort() == port) if (address.equals(pluginInstance.getListServerAddress(*server)) && server->getPort() == port)
break; break;
@ -783,17 +676,14 @@ Jupiter::ReadableString *handle_server_page(const Jupiter::ReadableString &query
return new Jupiter::ReferenceString(server->varData[pluginInstance.getName()].get("j"_jrs)); return new Jupiter::ReferenceString(server->varData[pluginInstance.getName()].get("j"_jrs));
} }
Jupiter::ReadableString *handle_metadata_page(const Jupiter::ReadableString&) Jupiter::ReadableString *handle_metadata_page(const Jupiter::ReadableString&) {
{
return pluginInstance.getMetadataJSON(); return pluginInstance.getMetadataJSON();
} }
Jupiter::ReadableString *handle_metadata_prometheus_page(const Jupiter::ReadableString&) Jupiter::ReadableString *handle_metadata_prometheus_page(const Jupiter::ReadableString&) {
{
return pluginInstance.getMetadataPrometheus(); return pluginInstance.getMetadataPrometheus();
} }
extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() {
{
return &pluginInstance; return &pluginInstance;
} }

8
src/Plugins/RenX/RenX.ServerList/RenX_ServerList.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016-2017 Jessica James. * Copyright (C) 2016-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -58,9 +58,9 @@ public: // RenX::Plugin
void RenX_OnMapLoad(RenX::Server &server, const Jupiter::ReadableString &map) override; void RenX_OnMapLoad(RenX::Server &server, const Jupiter::ReadableString &map) override;
private: private:
Jupiter::StringS server_list_json, metadata_json, metadata_prometheus; Jupiter::StringS m_server_list_json, m_metadata_json, m_metadata_prometheus;
Jupiter::StringS web_hostname, web_path; Jupiter::StringS m_web_hostname, m_web_path;
Jupiter::StringS server_list_page_name, server_list_long_page_name, server_page_name, metadata_page_name, metadata_prometheus_page_name; Jupiter::StringS m_server_list_page_name, m_server_list_long_page_name, m_server_page_name, m_metadata_page_name, m_metadata_prometheus_page_name;
}; };
Jupiter::ReadableString *handle_server_list_page(const Jupiter::ReadableString &); Jupiter::ReadableString *handle_server_list_page(const Jupiter::ReadableString &);

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

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2017 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -23,15 +23,13 @@
using namespace Jupiter::literals; using namespace Jupiter::literals;
bool RenX_WarnPlugin::initialize() bool RenX_WarnPlugin::initialize() {
{ m_maxWarns = this->config.get<int>("MaxWarns"_jrs, 3);
RenX_WarnPlugin::maxWarns = this->config.get<int>("MaxWarns"_jrs, 3); m_warnAction = this->config.get<int>("MaxAction"_jrs, -1);
RenX_WarnPlugin::warnAction = this->config.get<int>("MaxAction"_jrs, -1);
return true; return true;
} }
int RenX_WarnPlugin::OnRehash() int RenX_WarnPlugin::OnRehash() {
{
RenX::Plugin::OnRehash(); RenX::Plugin::OnRehash();
return this->initialize() ? 0 : -1; return this->initialize() ? 0 : -1;
} }
@ -43,71 +41,61 @@ STRING_LITERAL_AS_NAMED_REFERENCE(WARNS_KEY, "w");
// Warn IRC Command // Warn IRC Command
void WarnIRCCommand::create() void WarnIRCCommand::create() {
{
this->addTrigger("warn"_jrs); this->addTrigger("warn"_jrs);
this->addTrigger("w"_jrs); this->addTrigger("w"_jrs);
this->setAccessLevel(2); this->setAccessLevel(2);
} }
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) {
if (parameters.wordCount(WHITESPACE) >= 2) source->sendNotice(nick, "Error: Too Few Parameters. Syntax: Warn <Player> <Reason>"_jrs);
{ return;
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); }
if (chan != nullptr)
{ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(chan->getType()); if (chan == nullptr) {
if (servers.size() != 0) return;
{ }
Jupiter::ReferenceString name = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
Jupiter::ReferenceString reason = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE); const auto& servers = RenX::getCore()->getServers(chan->getType());
if (servers.empty()) {
RenX::PlayerInfo *player; source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
RenX::Server *server; return;
for (size_t i = 0; i != servers.size(); i++) }
{
server = servers.get(i); Jupiter::ReferenceString name = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
if (server != nullptr) Jupiter::ReferenceString reason = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE);
{
player = server->getPlayerByPartName(name); RenX::PlayerInfo *player;
if (player != nullptr) for (const auto& server : servers) {
{ if (server != nullptr) {
int warns = player->varData[pluginInstance.getName()].get<int>(WARNS_KEY) + 1; player = server->getPlayerByPartName(name);
if (warns > pluginInstance.maxWarns) if (player != nullptr) {
{ int warns = player->varData[pluginInstance.getName()].get<int>(WARNS_KEY) + 1;
switch (pluginInstance.warnAction) if (warns > pluginInstance.m_maxWarns) {
{ switch (pluginInstance.m_warnAction) {
case -1: case -1:
server->kickPlayer(*player, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns)); server->kickPlayer(*player, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns));
source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been kicked from the server for exceeding the warning limit (%d warnings).", player->name.size(), player->name.ptr(), warns)); source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been kicked from the server for exceeding the warning limit (%d warnings).", player->name.size(), player->name.ptr(), warns));
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.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.ptr(), 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.ptr(), reason.size(), reason.ptr(), warns));
break; break;
}
}
else
{
player->varData[pluginInstance.getName()].set(WARNS_KEY, Jupiter::StringS::Format("%d", 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));
source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", player->name.size(), player->name.ptr(), warns));
}
}
} }
} }
else {
player->varData[pluginInstance.getName()].set(WARNS_KEY, Jupiter::StringS::Format("%d", 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));
source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", player->name.size(), player->name.ptr(), warns));
}
} }
else
source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
} }
} }
else
source->sendNotice(nick, "Error: Too Few Parameters. Syntax: Warn <Player> <Reason>"_jrs);
} }
const Jupiter::ReadableString &WarnIRCCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &WarnIRCCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Warns a player. Syntax: Warn <Player> <Reason>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Warns a player. Syntax: Warn <Player> <Reason>");
return defaultHelp; return defaultHelp;
} }
@ -116,51 +104,45 @@ IRC_COMMAND_INIT(WarnIRCCommand)
// Pardon IRC Command // Pardon IRC Command
void PardonIRCCommand::create() void PardonIRCCommand::create() {
{
this->addTrigger("pardon"_jrs); this->addTrigger("pardon"_jrs);
this->addTrigger("forgive"_jrs); this->addTrigger("forgive"_jrs);
this->addTrigger("unwarn"_jrs); this->addTrigger("unwarn"_jrs);
this->setAccessLevel(2); this->setAccessLevel(2);
} }
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.isNotEmpty()) // TODO: this doesn't make sense
{ this->trigger(source, channel, nick, nick);
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel); return;
if (chan != nullptr) }
{
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(chan->getType()); Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
if (servers.size() != 0) if (chan == nullptr) {
{ return;
RenX::PlayerInfo *player; }
RenX::Server *server;
for (size_t i = 0; i != servers.size(); i++) const auto& servers = RenX::getCore()->getServers(chan->getType());
{ if (servers.empty()) {
server = servers.get(i); source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
if (server != nullptr) return;
{ }
player = server->getPlayerByPartName(parameters);
if (player != nullptr) RenX::PlayerInfo *player;
{ for (const auto& server : servers) {
player->varData[pluginInstance.getName()].remove(WARNS_KEY); if (server != nullptr) {
server->sendMessage(*player, Jupiter::StringS::Format("You have been pardoned by %.*s@IRC; your warnings have been reset.", nick.size(), nick.ptr())); player = server->getPlayerByPartName(parameters);
source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been pardoned; their warnings have been reset.", player->name.size(), player->name.ptr())); if (player != nullptr) {
} player->varData[pluginInstance.getName()].remove(WARNS_KEY);
} server->sendMessage(*player, Jupiter::StringS::Format("You have been pardoned by %.*s@IRC; your warnings have been reset.", nick.size(), nick.ptr()));
} source->sendNotice(nick, Jupiter::StringS::Format("%.*s has been pardoned; their warnings have been reset.", player->name.size(), player->name.ptr()));
} }
else
source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
} }
} }
else
this->trigger(source, channel, nick, nick);
} }
const Jupiter::ReadableString &PardonIRCCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &PardonIRCCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Resets a player's warnings. Syntax: Pardon <Player>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Resets a player's warnings. Syntax: Pardon <Player>");
return defaultHelp; return defaultHelp;
} }
@ -169,39 +151,33 @@ IRC_COMMAND_INIT(PardonIRCCommand)
// Warn Game Command // Warn Game Command
void WarnGameCommand::create() void WarnGameCommand::create() {
{
this->addTrigger("warn"_jrs); this->addTrigger("warn"_jrs);
this->addTrigger("w"_jrs); this->addTrigger("w"_jrs);
this->setAccessLevel(1); this->setAccessLevel(1);
} }
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) {
if (parameters.wordCount(WHITESPACE) >= 2)
{
Jupiter::ReferenceString name = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE); Jupiter::ReferenceString name = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
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); 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.maxWarns) if (warns > pluginInstance.m_maxWarns) {
{ switch (pluginInstance.m_warnAction)
switch (pluginInstance.warnAction)
{ {
case -1: case -1:
source->kickPlayer(*target, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns)); source->kickPlayer(*target, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns));
source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been kicked from the server for exceeding the warning limit (%d warnings).", target->name.size(), target->name.ptr(), warns)); source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been kicked from the server for exceeding the warning limit (%d warnings).", target->name.size(), target->name.ptr(), warns));
break; break;
default: default:
source->banPlayer(*target, "Jupiter Bot/RenX.Warn"_jrs, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns), std::chrono::seconds(pluginInstance.warnAction)); source->banPlayer(*target, "Jupiter Bot/RenX.Warn"_jrs, Jupiter::StringS::Format("Warning limit reached (%d warnings)", warns), std::chrono::seconds(pluginInstance.m_warnAction));
source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been banned from the server for exceeding the warning limit (%d warnings).", target->name.size(), target->name.ptr(), warns)); source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been banned from the server for exceeding the warning limit (%d warnings).", target->name.size(), target->name.ptr(), warns));
break; break;
} }
} }
else else {
{
target->varData[pluginInstance.getName()].set(WARNS_KEY, Jupiter::StringS::Format("%d", warns)); target->varData[pluginInstance.getName()].set(WARNS_KEY, Jupiter::StringS::Format("%d", warns));
source->sendWarnMessage(*target, Jupiter::StringS::Format("You have been warned by %.*s for: %.*s. You have %d warnings.", player->name.size(), player->name.ptr(), 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.ptr(), reason.size(), reason.ptr(), warns));
source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", target->name.size(), target->name.ptr(), warns)); source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been warned; they now have %d warnings.", target->name.size(), target->name.ptr(), warns));
@ -212,8 +188,7 @@ void WarnGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, co
source->sendMessage(*player, "Error: Too few parameters. Syntax: Warn <Player> <Reason>"_jrs); source->sendMessage(*player, "Error: Too few parameters. Syntax: Warn <Player> <Reason>"_jrs);
} }
const Jupiter::ReadableString &WarnGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &WarnGameCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Warns a player. Syntax: Warn <Player> <Reason>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Warns a player. Syntax: Warn <Player> <Reason>");
return defaultHelp; return defaultHelp;
} }
@ -222,21 +197,17 @@ GAME_COMMAND_INIT(WarnGameCommand)
// Pardon Game Command // Pardon Game Command
void PardonGameCommand::create() void PardonGameCommand::create() {
{
this->addTrigger("pardon"_jrs); this->addTrigger("pardon"_jrs);
this->addTrigger("forgive"_jrs); this->addTrigger("forgive"_jrs);
this->addTrigger("unwarn"_jrs); this->addTrigger("unwarn"_jrs);
this->setAccessLevel(1); this->setAccessLevel(1);
} }
void PardonGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) void PardonGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString &parameters) {
{ if (parameters.isNotEmpty()) {
if (parameters.isNotEmpty())
{
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters); RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
if (target != nullptr) if (target != nullptr) {
{
target->varData[pluginInstance.getName()].remove(WARNS_KEY); target->varData[pluginInstance.getName()].remove(WARNS_KEY);
source->sendMessage(*target, Jupiter::StringS::Format("You have been pardoned by %.*s@IRC; your warnings have been reset.", player->name.size(), player->name.ptr())); source->sendMessage(*target, Jupiter::StringS::Format("You have been pardoned by %.*s@IRC; your warnings have been reset.", player->name.size(), player->name.ptr()));
source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been pardoned; their warnings have been reset.", target->name.size(), target->name.ptr())); source->sendMessage(*player, Jupiter::StringS::Format("%.*s has been pardoned; their warnings have been reset.", target->name.size(), target->name.ptr()));
@ -246,15 +217,13 @@ void PardonGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player,
this->trigger(source, player, player->name); this->trigger(source, player, player->name);
} }
const Jupiter::ReadableString &PardonGameCommand::getHelp(const Jupiter::ReadableString &) const Jupiter::ReadableString &PardonGameCommand::getHelp(const Jupiter::ReadableString &) {
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Resets a player's warnings. Syntax: Pardon <Player>"); static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Resets a player's warnings. Syntax: Pardon <Player>");
return defaultHelp; return defaultHelp;
} }
GAME_COMMAND_INIT(PardonGameCommand) GAME_COMMAND_INIT(PardonGameCommand)
extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() extern "C" JUPITER_EXPORT Jupiter::Plugin *getPlugin() {
{
return &pluginInstance; return &pluginInstance;
} }

6
src/Plugins/RenX/RenX.Warn/RenX_Warn.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2014-2016 Jessica James. * Copyright (C) 2014-2021 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -31,8 +31,8 @@ public: // Jupiter::Plugin
virtual bool initialize() override; virtual bool initialize() override;
int OnRehash() override; int OnRehash() override;
int maxWarns; int m_maxWarns;
int warnAction; /** -1 = kick; 0 = perm ban; other = temp ban */ int m_warnAction; /** -1 = kick; 0 = perm ban; other = temp ban */
}; };
GENERIC_IRC_COMMAND(WarnIRCCommand) GENERIC_IRC_COMMAND(WarnIRCCommand)

Loading…
Cancel
Save