You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3635 lines
127 KiB
3635 lines
127 KiB
/**
|
|
* Copyright (C) 2014-2016 Jessica James.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
* Written by Jessica James <jessica.aj@outlook.com>
|
|
*/
|
|
|
|
#include <functional>
|
|
#include "Jupiter/Functions.h"
|
|
#include "Jupiter/SLList.h"
|
|
#include "IRC_Bot.h"
|
|
#include "RenX_Commands.h"
|
|
#include "RenX_Core.h"
|
|
#include "RenX_Server.h"
|
|
#include "RenX_PlayerInfo.h"
|
|
#include "RenX_BuildingInfo.h"
|
|
#include "RenX_Functions.h"
|
|
#include "RenX_BanDatabase.h"
|
|
#include "RenX_ExemptionDatabase.h"
|
|
#include "RenX_Tags.h"
|
|
|
|
using namespace Jupiter::literals;
|
|
|
|
inline bool togglePhasing(RenX::Server *server, bool newState)
|
|
{
|
|
server->varData.set(STRING_LITERAL_AS_REFERENCE("RenX.Commands"), STRING_LITERAL_AS_REFERENCE("phasing"), newState ? STRING_LITERAL_AS_REFERENCE("true") : STRING_LITERAL_AS_REFERENCE("false"));
|
|
return newState;
|
|
}
|
|
|
|
inline bool togglePhasing(RenX::Server *server)
|
|
{
|
|
return togglePhasing(server, !server->varData.getBool(STRING_LITERAL_AS_REFERENCE("RenX.Commands"), STRING_LITERAL_AS_REFERENCE("phasing"), false));
|
|
}
|
|
|
|
inline void onDie(RenX::Server *server, const RenX::PlayerInfo *player)
|
|
{
|
|
if (player->isBot && server->varData.getBool(STRING_LITERAL_AS_REFERENCE("RenX.Commands"), STRING_LITERAL_AS_REFERENCE("phasing"), false))
|
|
server->kickPlayer(player, Jupiter::StringS::empty);
|
|
}
|
|
|
|
void RenX_CommandsPlugin::RenX_OnSuicide(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &)
|
|
{
|
|
onDie(server, player);
|
|
}
|
|
|
|
void RenX_CommandsPlugin::RenX_OnKill(RenX::Server *server, const RenX::PlayerInfo *, const RenX::PlayerInfo *victim, const Jupiter::ReadableString &)
|
|
{
|
|
onDie(server, victim);
|
|
}
|
|
|
|
void RenX_CommandsPlugin::RenX_OnDie(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &)
|
|
{
|
|
onDie(server, player);
|
|
}
|
|
|
|
bool RenX_CommandsPlugin::initialize()
|
|
{
|
|
RenX_CommandsPlugin::_defaultTempBanTime = std::chrono::seconds(this->config.getLongLong(Jupiter::ReferenceString::empty, STRING_LITERAL_AS_REFERENCE("TBanTime"), 86400));
|
|
RenX_CommandsPlugin::playerInfoFormat = this->config.get(Jupiter::ReferenceString::empty, STRING_LITERAL_AS_REFERENCE("PlayerInfoFormat"), STRING_LITERAL_AS_REFERENCE(IRCCOLOR "03[Player Info]" IRCCOLOR "{TCOLOR} Name: " IRCBOLD "{RNAME}" IRCBOLD " - ID: {ID} - Team: " IRCBOLD "{TEAML}" IRCBOLD " - Vehicle Kills: {VEHICLEKILLS} - Building Kills {BUILDINGKILLS} - Kills {KILLS} - Deaths: {DEATHS} - KDR: {KDR} - Access: {ACCESS}"));
|
|
RenX_CommandsPlugin::adminPlayerInfoFormat = this->config.get(Jupiter::ReferenceString::empty, STRING_LITERAL_AS_REFERENCE("AdminPlayerInfoFormat"), Jupiter::StringS::Format("%.*s - IP: " IRCBOLD "{IP}" IRCBOLD " - HWID: " IRCBOLD "{HWID}" IRCBOLD " - RDNS: " IRCBOLD "{RDNS}" IRCBOLD " - Steam ID: " IRCBOLD "{STEAM}", RenX_CommandsPlugin::playerInfoFormat.size(), RenX_CommandsPlugin::playerInfoFormat.ptr()));
|
|
RenX_CommandsPlugin::buildingInfoFormat = this->config.get(Jupiter::ReferenceString::empty, STRING_LITERAL_AS_REFERENCE("BuildingInfoFormat"), STRING_LITERAL_AS_REFERENCE(IRCCOLOR) + RenX::tags->buildingTeamColorTag + RenX::tags->buildingNameTag + STRING_LITERAL_AS_REFERENCE(IRCCOLOR " - " IRCCOLOR "07") + RenX::tags->buildingHealthPercentageTag + STRING_LITERAL_AS_REFERENCE("%"));
|
|
RenX_CommandsPlugin::staffTitle = this->config.get(Jupiter::ReferenceString::empty, STRING_LITERAL_AS_REFERENCE("StaffTitle"), STRING_LITERAL_AS_REFERENCE("Moderator"));
|
|
|
|
RenX::sanitizeTags(RenX_CommandsPlugin::playerInfoFormat);
|
|
RenX::sanitizeTags(RenX_CommandsPlugin::adminPlayerInfoFormat);
|
|
RenX::sanitizeTags(RenX_CommandsPlugin::buildingInfoFormat);
|
|
return true;
|
|
}
|
|
|
|
int RenX_CommandsPlugin::OnRehash()
|
|
{
|
|
return this->initialize() ? 0 : -1;
|
|
}
|
|
|
|
std::chrono::seconds RenX_CommandsPlugin::getTBanTime() const
|
|
{
|
|
return RenX_CommandsPlugin::_defaultTempBanTime;
|
|
}
|
|
|
|
const Jupiter::ReadableString &RenX_CommandsPlugin::getPlayerInfoFormat() const
|
|
{
|
|
return RenX_CommandsPlugin::playerInfoFormat;
|
|
}
|
|
|
|
const Jupiter::ReadableString &RenX_CommandsPlugin::getAdminPlayerInfoFormat() const
|
|
{
|
|
return RenX_CommandsPlugin::adminPlayerInfoFormat;
|
|
}
|
|
|
|
const Jupiter::ReadableString &RenX_CommandsPlugin::getBuildingInfoFormat() const
|
|
{
|
|
return RenX_CommandsPlugin::buildingInfoFormat;
|
|
}
|
|
|
|
const Jupiter::ReadableString &RenX_CommandsPlugin::getStaffTitle() const
|
|
{
|
|
return RenX_CommandsPlugin::staffTitle;
|
|
}
|
|
|
|
// Plugin instantiation and entry point.
|
|
RenX_CommandsPlugin pluginInstance;
|
|
|
|
/** Console Commands */
|
|
|
|
// RawRCON Console Command
|
|
|
|
RawRCONConsoleCommand::RawRCONConsoleCommand()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rrcon"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rawrcon"));
|
|
}
|
|
|
|
void RawRCONConsoleCommand::trigger(const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::StringS msg = parameters;
|
|
msg += '\n';
|
|
int i = RenX::getCore()->getServerCount();
|
|
if (i == 0)
|
|
puts("Error: Not connected to any Renegade X servers.");
|
|
else if (parameters.isNotEmpty())
|
|
while (--i >= 0)
|
|
RenX::getCore()->getServer(i)->sendData(msg);
|
|
else
|
|
puts("Error: Too Few Parameters. Syntax: rcon <input>");
|
|
}
|
|
|
|
const Jupiter::ReadableString &RawRCONConsoleCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends data over the Renegade X server's rcon connection. Syntax: rrcon <data>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
CONSOLE_COMMAND_INIT(RawRCONConsoleCommand)
|
|
|
|
// RCON Console Command
|
|
|
|
RCONConsoleCommand::RCONConsoleCommand()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rcon"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("renx"));
|
|
}
|
|
|
|
void RCONConsoleCommand::trigger(const Jupiter::ReadableString ¶meters)
|
|
{
|
|
int i = RenX::getCore()->getServerCount();
|
|
if (i == 0)
|
|
puts("Error: Not connected to any Renegade X servers.");
|
|
else if (parameters != nullptr)
|
|
while (--i >= 0)
|
|
RenX::getCore()->getServer(i)->send(parameters);
|
|
else
|
|
puts("Error: Too Few Parameters. Syntax: rcon <input>");
|
|
}
|
|
|
|
const Jupiter::ReadableString &RCONConsoleCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Executes a command over the Renegade X server's rcon connection. Syntax: rcon <input>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
CONSOLE_COMMAND_INIT(RCONConsoleCommand)
|
|
|
|
/** IRC Commands */
|
|
|
|
// Msg IRC Command
|
|
|
|
void MsgIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("msg"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("say"));
|
|
}
|
|
|
|
void MsgIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
int type = source->getChannel(channel)->getType();
|
|
Jupiter::StringL msg;
|
|
char prefix = source->getChannel(channel)->getUserPrefix(nick);
|
|
if (prefix != '\0')
|
|
msg += prefix;
|
|
msg += nick;
|
|
msg += "@IRC: ";
|
|
msg += parameters;
|
|
|
|
prefix = '\0'; // Reusing prefix to check if a match is ever found.
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
server->sendMessage(msg);
|
|
prefix = 1;
|
|
}
|
|
}
|
|
if (prefix == '\0')
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: Msg <Message>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &MsgIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message in - game.Syntax: Msg <Message>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(MsgIRCCommand)
|
|
|
|
// PMsg IRC Command
|
|
|
|
void PMsgIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("pmsg"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("psay"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("page"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("ppage"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void PMsgIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.wordCount(WHITESPACE) >= 2)
|
|
{
|
|
int type = source->getChannel(channel)->getType();
|
|
Jupiter::ReferenceString name = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
|
|
RenX::PlayerInfo *player;
|
|
Jupiter::StringL msg;
|
|
char prefix = source->getChannel(channel)->getUserPrefix(nick);
|
|
if (prefix != '\0')
|
|
msg += prefix;
|
|
msg += nick;
|
|
msg += "@IRC: ";
|
|
msg += Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE);
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
player = server->getPlayerByPartName(name);
|
|
if (player != nullptr)
|
|
server->sendMessage(player, msg);
|
|
else source->sendNotice(nick, Jupiter::StringS::Format("Error: Player \"%.*s\" not found.", name.size(), name.ptr()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: PMsg <Player> <Message>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &PMsgIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message in - game.Syntax: PMsg <Player> <Message>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(PMsgIRCCommand)
|
|
|
|
// Host Msg IRC Command
|
|
|
|
void HostMsgIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("hmsg"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("hsay"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("hostmessage"));
|
|
this->setAccessLevel(4);
|
|
}
|
|
|
|
void HostMsgIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
int type = source->getChannel(channel)->getType();
|
|
|
|
bool success = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
success = server->sendMessage(parameters) > 0;
|
|
}
|
|
if (!success)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: hmsg <Message>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &HostMsgIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message in-game. Syntax: hmsg <Message>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(HostMsgIRCCommand)
|
|
|
|
// Players IRC Command
|
|
|
|
void PlayersIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("players"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("pl"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("playerlist"));
|
|
}
|
|
|
|
const size_t STRING_LENGTH = 240;
|
|
|
|
void PlayersIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &)
|
|
{
|
|
int type = source->getChannel(channel)->getType();
|
|
|
|
// Team colors
|
|
const Jupiter::ReadableString &gTeamColor = RenX::getTeamColor(RenX::TeamType::GDI);
|
|
const Jupiter::ReadableString &nTeamColor = RenX::getTeamColor(RenX::TeamType::Nod);
|
|
const Jupiter::ReadableString &oTeamColor = RenX::getTeamColor(RenX::TeamType::Other);
|
|
|
|
// Team names
|
|
const Jupiter::ReadableString &gTeam = RenX::getTeamName(RenX::TeamType::GDI);
|
|
const Jupiter::ReadableString &nTeam = RenX::getTeamName(RenX::TeamType::Nod);
|
|
const Jupiter::ReadableString &oTeam = RenX::getTeamName(RenX::TeamType::Other);
|
|
|
|
bool noServers = true;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
noServers = false;
|
|
if (server->players.size() != server->getBotCount())
|
|
{
|
|
// End string containers
|
|
Jupiter::DLList<Jupiter::String> gStrings;
|
|
Jupiter::DLList<Jupiter::String> nStrings;
|
|
Jupiter::DLList<Jupiter::String> oStrings;
|
|
|
|
Jupiter::StringL *gCurrent = nullptr;
|
|
Jupiter::StringL *nCurrent = nullptr;
|
|
Jupiter::StringL *oCurrent = nullptr;
|
|
|
|
// Team player counters
|
|
unsigned int gTotal = 0;
|
|
unsigned int nTotal = 0;
|
|
unsigned int oTotal = 0;
|
|
|
|
// Bot counters
|
|
unsigned int gBots = 0;
|
|
unsigned int nBots = 0;
|
|
unsigned int oBots = 0;
|
|
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
if (node->data != nullptr)
|
|
{
|
|
Jupiter::String &name = RenX::getFormattedPlayerName(node->data);
|
|
if (name.size() > STRING_LENGTH - 32) continue; // Name will be too long to send.
|
|
|
|
switch (node->data->team)
|
|
{
|
|
case RenX::TeamType::Nod:
|
|
if (nCurrent == nullptr || nCurrent->size() + name.size() > STRING_LENGTH)
|
|
{
|
|
nCurrent = new Jupiter::StringL(STRING_LENGTH);
|
|
nCurrent->format(IRCCOLOR "%.*s[%.*s]: " IRCBOLD "%.*s" IRCBOLD, nTeamColor.size(), nTeamColor.ptr(), nTeam.size(), nTeam.ptr(), name.size(), name.ptr());
|
|
nStrings.add(nCurrent);
|
|
}
|
|
else nCurrent->aformat(IRCCOLOR ", " IRCBOLD "%.*s" IRCBOLD, name.size(), name.ptr());
|
|
nTotal++;
|
|
if (node->data->isBot)
|
|
nBots++;
|
|
break;
|
|
case RenX::TeamType::GDI:
|
|
if (gCurrent == nullptr || gCurrent->size() + name.size() > STRING_LENGTH)
|
|
{
|
|
gCurrent = new Jupiter::StringL(STRING_LENGTH);
|
|
gCurrent->format(IRCCOLOR "%.*s[%.*s]: " IRCBOLD "%.*s" IRCBOLD, gTeamColor.size(), gTeamColor.ptr(), gTeam.size(), gTeam.ptr(), name.size(), name.ptr());
|
|
gStrings.add(gCurrent);
|
|
}
|
|
else gCurrent->aformat(IRCCOLOR ", " IRCBOLD "%.*s" IRCBOLD, name.size(), name.ptr());
|
|
gTotal++;
|
|
if (node->data->isBot)
|
|
gBots++;
|
|
break;
|
|
default:
|
|
if (oCurrent == nullptr || oCurrent->size() + name.size() > STRING_LENGTH)
|
|
{
|
|
oCurrent = new Jupiter::StringL(STRING_LENGTH);
|
|
oCurrent->format(IRCCOLOR "%.*s[%.*s]: " IRCBOLD "%.*s" IRCBOLD, oTeamColor.size(), oTeamColor.ptr(), oTeam.size(), oTeam.ptr(), name.size(), name.ptr());
|
|
oStrings.add(oCurrent);
|
|
}
|
|
else oCurrent->aformat(IRCCOLOR ", " IRCBOLD "%.*s" IRCBOLD, name.size(), name.ptr());
|
|
oTotal++;
|
|
if (node->data->isBot)
|
|
oBots++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
Jupiter::StringL *outString;
|
|
while (gStrings.size() != 0)
|
|
{
|
|
outString = gStrings.remove(0U);
|
|
source->sendMessage(channel, *outString);
|
|
delete outString;
|
|
}
|
|
while (nStrings.size() != 0)
|
|
{
|
|
outString = nStrings.remove(0U);
|
|
source->sendMessage(channel, *outString);
|
|
delete outString;
|
|
}
|
|
while (oStrings.size() != 0)
|
|
{
|
|
outString = oStrings.remove(0U);
|
|
source->sendMessage(channel, *outString);
|
|
delete outString;
|
|
}
|
|
|
|
Jupiter::StringL out;
|
|
out.format(IRCCOLOR "03Total Players" IRCCOLOR ": %u", server->players.size());
|
|
if (gBots + nBots + oBots > 0)
|
|
out.aformat(" (%u bots)", gBots + nBots + oBots);
|
|
if (gTotal > 0)
|
|
{
|
|
out.aformat(IRCCOLOR "02 | " IRCCOLOR "%.*s%.*s" IRCCOLOR ": %u", gTeamColor.size(), gTeamColor.ptr(), gTeam.size(), gTeam.ptr(), gTotal);
|
|
if (gBots > 0)
|
|
out.aformat(" (%u bots)", gBots);
|
|
}
|
|
if (nTotal > 0)
|
|
{
|
|
out.aformat(IRCCOLOR "02 | " IRCCOLOR "%.*s%.*s" IRCCOLOR ": %u", nTeamColor.size(), nTeamColor.ptr(), nTeam.size(), nTeam.ptr(), nTotal);
|
|
if (nBots > 0)
|
|
out.aformat(" (%u bots)", nBots);
|
|
}
|
|
if (oTotal > 0)
|
|
{
|
|
out.aformat(IRCCOLOR "02 | " IRCCOLOR "%.*s%.*s" IRCCOLOR ": %u", oTeamColor.size(), oTeamColor.ptr(), oTeam.size(), oTeam.ptr(), oTotal);
|
|
if (oBots > 0)
|
|
out.aformat(" (%u bots)", oBots);
|
|
}
|
|
source->sendMessage(channel, out);
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("No players are in-game."));
|
|
}
|
|
}
|
|
if (noServers)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
|
|
const Jupiter::ReadableString &PlayersIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Lists the players currently in-game. Syntax: Players");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(PlayersIRCCommand)
|
|
|
|
// PlayerTable IRC Command
|
|
void PlayerTableIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("pt"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("playertable"));
|
|
}
|
|
|
|
void PlayerTableIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &)
|
|
{
|
|
int type = source->getChannel(channel)->getType();
|
|
|
|
// Team colors
|
|
const Jupiter::ReadableString &gTeamColor = RenX::getTeamColor(RenX::TeamType::GDI);
|
|
const Jupiter::ReadableString &nTeamColor = RenX::getTeamColor(RenX::TeamType::Nod);
|
|
const Jupiter::ReadableString &oTeamColor = RenX::getTeamColor(RenX::TeamType::Other);
|
|
|
|
// Team names
|
|
const Jupiter::ReadableString &gTeam = RenX::getTeamName(RenX::TeamType::GDI);
|
|
const Jupiter::ReadableString &nTeam = RenX::getTeamName(RenX::TeamType::Nod);
|
|
const Jupiter::ReadableString &oTeam = RenX::getTeamName(RenX::TeamType::Other);
|
|
|
|
bool noServers = true;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
noServers = false;
|
|
if (server->players.size() != server->getBotCount())
|
|
{
|
|
Jupiter::SLList<RenX::PlayerInfo> gPlayers;
|
|
Jupiter::SLList<RenX::PlayerInfo> nPlayers;
|
|
Jupiter::SLList<RenX::PlayerInfo> oPlayers;
|
|
|
|
STRING_LITERAL_AS_NAMED_REFERENCE(NICK_COL_HEADER, "Nickname");
|
|
size_t maxNickLen = 8;
|
|
int highID = 999;
|
|
double highScore = 99999.0;
|
|
double highCredits = 9999999.0;
|
|
|
|
RenX::PlayerInfo *player;
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
if (player != nullptr && player->isBot == false)
|
|
{
|
|
if (player->name.size() > maxNickLen)
|
|
maxNickLen = player->name.size();
|
|
|
|
if (player->id > highID)
|
|
highID = player->id;
|
|
|
|
if (player->score > highScore)
|
|
highScore = player->score;
|
|
|
|
if (player->credits > highCredits)
|
|
highCredits = player->credits;
|
|
|
|
switch (player->team)
|
|
{
|
|
case RenX::TeamType::GDI:
|
|
gPlayers.add(player);
|
|
break;
|
|
case RenX::TeamType::Nod:
|
|
nPlayers.add(player);
|
|
break;
|
|
default:
|
|
oPlayers.add(player);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
size_t idColLen = 1, scoreColLen = 1, creditColLen = 1;
|
|
|
|
while ((highID /= 10) > 0)
|
|
++idColLen;
|
|
|
|
while ((highScore /= 10) >= 1.0)
|
|
++scoreColLen;
|
|
|
|
while ((highCredits /= 10) >= 1.0)
|
|
++creditColLen;
|
|
|
|
if (server->isAdminLogChanType(type))
|
|
source->sendMessage(channel, Jupiter::StringS::Format(IRCUNDERLINE IRCCOLOR "03%*.*s | %*s | %*s | %*s | IP Address", maxNickLen, NICK_COL_HEADER.size(), NICK_COL_HEADER.ptr(), idColLen, "ID", scoreColLen, "Score", creditColLen, "Credits"));
|
|
else
|
|
source->sendMessage(channel, Jupiter::StringS::Format(IRCUNDERLINE IRCCOLOR "03%*.*s | %*s | %*s | %*s", maxNickLen, NICK_COL_HEADER.size(), NICK_COL_HEADER.ptr(), idColLen, "ID", scoreColLen, "Score", creditColLen, "Credits"));
|
|
|
|
auto output_player = [server, type, source, &channel, maxNickLen, idColLen, scoreColLen, creditColLen](RenX::PlayerInfo *player, const Jupiter::ReadableString &color)
|
|
{
|
|
if (server->isAdminLogChanType(type))
|
|
source->sendMessage(channel, Jupiter::StringS::Format(IRCCOLOR "%.*s%*.*s" IRCCOLOR " " IRCCOLOR "03|" IRCCOLOR " %*d " IRCCOLOR "03|" IRCCOLOR " %*.0f " IRCCOLOR "03|" IRCCOLOR " %*.0f " IRCCOLOR "03|" IRCNORMAL " %.*s", color.size(), color.ptr(), maxNickLen, player->name.size(), player->name.ptr(), idColLen, player->id, scoreColLen, player->score, creditColLen, player->credits, player->ip.size(), player->ip.ptr()));
|
|
else
|
|
source->sendMessage(channel, Jupiter::StringS::Format(IRCCOLOR "%.*s%*.*s" IRCCOLOR " " IRCCOLOR "03|" IRCCOLOR " %*d " IRCCOLOR "03|" IRCCOLOR " %*.0f " IRCCOLOR "03|" IRCCOLOR " %*.0f", color.size(), color.ptr(), maxNickLen, player->name.size(), player->name.ptr(), idColLen, player->id, scoreColLen, player->score, creditColLen, player->credits));
|
|
};
|
|
|
|
for (Jupiter::SLList<RenX::PlayerInfo>::Node *node = gPlayers.getNode(0); node != nullptr; node = node->next)
|
|
output_player(node->data, gTeamColor);
|
|
|
|
for (Jupiter::SLList<RenX::PlayerInfo>::Node *node = nPlayers.getNode(0); node != nullptr; node = node->next)
|
|
output_player(node->data, nTeamColor);
|
|
|
|
for (Jupiter::SLList<RenX::PlayerInfo>::Node *node = oPlayers.getNode(0); node != nullptr; node = node->next)
|
|
output_player(node->data, oTeamColor);
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("No players are in-game."));
|
|
}
|
|
}
|
|
if (noServers)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
|
|
const Jupiter::ReadableString &PlayerTableIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Generates a table of all the players in-game. Syntax: PT");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(PlayerTableIRCCommand)
|
|
|
|
// PlayerInfo IRC Command
|
|
|
|
void PlayerInfoIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("playerinfo"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("pi"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("player"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("pinfo"));
|
|
}
|
|
|
|
void PlayerInfoIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
Jupiter::StringL msg;
|
|
RenX::Server *server;
|
|
const Jupiter::ReadableString &player_info_format = source->getAccessLevel(channel, nick) > 1 ? pluginInstance.getAdminPlayerInfoFormat() : pluginInstance.getPlayerInfoFormat();
|
|
size_t index = 0;
|
|
Jupiter::DLList<RenX::PlayerInfo>::Node *node;
|
|
|
|
if (parameters.isEmpty()) // List all players
|
|
while (index != RenX::getCore()->getServerCount())
|
|
{
|
|
server = RenX::getCore()->getServer(index++);
|
|
if (server->isLogChanType(type) && server->players.size() != 0)
|
|
{
|
|
for (node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
msg = player_info_format;
|
|
RenX::processTags(msg, server, player);
|
|
source->sendMessage(channel, msg);
|
|
}
|
|
}
|
|
}
|
|
else // List all partial matches
|
|
while (index != RenX::getCore()->getServerCount())
|
|
{
|
|
server = RenX::getCore()->getServer(index++);
|
|
if (server->isLogChanType(type) && server->players.size() != 0)
|
|
{
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
if (player->name.findi(parameters) != Jupiter::INVALID_INDEX)
|
|
{
|
|
msg = player_info_format;
|
|
RenX::processTags(msg, server, player);
|
|
source->sendMessage(channel, msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (msg.isEmpty())
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &PlayerInfoIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Gets information about a player. Syntax: PlayerInfo [Player]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(PlayerInfoIRCCommand)
|
|
|
|
// BuildingInfo IRC Command
|
|
|
|
void BuildingInfoIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("binfo"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("bi"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("buildinginfo"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("building"));
|
|
}
|
|
|
|
void BuildingInfoIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
bool seenStrip;
|
|
Jupiter::SLList<Jupiter::String> gStrings;
|
|
Jupiter::SLList<Jupiter::String> nStrings;
|
|
Jupiter::SLList<Jupiter::String> oStrings;
|
|
Jupiter::SLList<Jupiter::String> cStrings;
|
|
Jupiter::String *str = nullptr;
|
|
RenX::BuildingInfo *building;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
seenStrip = false;
|
|
for (size_t index = 0; index != server->buildings.size(); ++index)
|
|
{
|
|
building = server->buildings.get(index);
|
|
if (building->name.find("Rx_Building_Air"_jrs) == 0)
|
|
{
|
|
if (seenStrip)
|
|
continue;
|
|
|
|
seenStrip = true;
|
|
}
|
|
str = new Jupiter::String(pluginInstance.getBuildingInfoFormat());
|
|
RenX::processTags(*str, server, nullptr, nullptr, building);
|
|
if (building->capturable)
|
|
cStrings.add(str);
|
|
else if (building->team == RenX::TeamType::GDI)
|
|
gStrings.add(str);
|
|
else if (building->team == RenX::TeamType::Nod)
|
|
nStrings.add(str);
|
|
else
|
|
oStrings.add(str);
|
|
}
|
|
while (gStrings.size() != 0)
|
|
{
|
|
str = gStrings.remove(0);
|
|
source->sendMessage(channel, *str);
|
|
delete str;
|
|
}
|
|
while (nStrings.size() != 0)
|
|
{
|
|
str = nStrings.remove(0);
|
|
source->sendMessage(channel, *str);
|
|
delete str;
|
|
}
|
|
while (oStrings.size() != 0)
|
|
{
|
|
str = oStrings.remove(0);
|
|
source->sendMessage(channel, *str);
|
|
delete str;
|
|
}
|
|
while (cStrings.size() != 0)
|
|
{
|
|
str = cStrings.remove(0);
|
|
source->sendMessage(channel, *str);
|
|
delete str;
|
|
}
|
|
}
|
|
}
|
|
if (str == nullptr)
|
|
source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &BuildingInfoIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Provides a list of buildings, and the status of each one. Syntax: BuildingInfo");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(BuildingInfoIRCCommand)
|
|
|
|
// Mutators IRC Command
|
|
|
|
void MutatorsIRCCommand::create()
|
|
{
|
|
this->addTrigger("mutators"_jrs);
|
|
this->addTrigger("mutator"_jrs);
|
|
}
|
|
|
|
void MutatorsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
Jupiter::String list;
|
|
size_t index = 0;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
list = STRING_LITERAL_AS_REFERENCE(IRCCOLOR "03[Mutators]" IRCNORMAL);
|
|
for (index = 0; index != server->mutators.size(); ++index)
|
|
list += " "_jrs + *server->mutators.get(index);
|
|
if (index == 0)
|
|
source->sendMessage(channel, "No mutators loaded"_jrs);
|
|
else
|
|
source->sendMessage(channel, list);
|
|
}
|
|
}
|
|
if (list.isEmpty())
|
|
source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &MutatorsIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Provides a list of mutators being used. Syntax: Mutators");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(MutatorsIRCCommand)
|
|
|
|
// Rotation IRC Command
|
|
|
|
void RotationIRCCommand::create()
|
|
{
|
|
this->addTrigger("rotation"_jrs);
|
|
this->addTrigger("maprotation"_jrs);
|
|
this->addTrigger("maps"_jrs);
|
|
this->addTrigger("rot"_jrs);
|
|
}
|
|
|
|
void RotationIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
const RenX::Map *map;
|
|
int type = chan->getType();
|
|
Jupiter::String list;
|
|
size_t index = 0;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
list = STRING_LITERAL_AS_REFERENCE(IRCCOLOR "03[Rotation]" IRCNORMAL);
|
|
for (index = 0; index != server->maps.size(); ++index)
|
|
{
|
|
map = server->maps.get(index);
|
|
if (server->getMap().name.equalsi(map->name))
|
|
list += STRING_LITERAL_AS_REFERENCE(" " IRCBOLD "[") + server->maps.get(index)->name + STRING_LITERAL_AS_REFERENCE("]" IRCBOLD);
|
|
else
|
|
list += " "_jrs + server->maps.get(index)->name;
|
|
}
|
|
if (index == 0)
|
|
source->sendMessage(channel, "No maps in rotation"_jrs);
|
|
else
|
|
source->sendMessage(channel, list);
|
|
}
|
|
}
|
|
if (list.isEmpty())
|
|
source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &RotationIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Provides a list of maps in the server rotation. Syntax: Rotation");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(RotationIRCCommand)
|
|
|
|
// Map IRC Command
|
|
|
|
void MapIRCCommand::create()
|
|
{
|
|
this->addTrigger("map"_jrs);
|
|
}
|
|
|
|
void MapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
bool match = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
const RenX::Map &map = server->getMap();
|
|
source->sendMessage(channel, "Current Map: "_jrs + map.name + "; GUID: "_jrs + RenX::formatGUID(map));
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &MapIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Fetches the current map. Syntax: Map");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(MapIRCCommand)
|
|
|
|
// GameInfo IRC Command
|
|
|
|
void GameInfoIRCCommand::create()
|
|
{
|
|
this->addTrigger("gameinfo"_jrs);
|
|
this->addTrigger("gi"_jrs);
|
|
this->addTrigger("serverinfo"_jrs);
|
|
this->addTrigger("si"_jrs);
|
|
}
|
|
|
|
void GameInfoIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
bool match = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
const RenX::Map &map = server->getMap();
|
|
std::chrono::seconds time = std::chrono::duration_cast<std::chrono::seconds>(server->getGameTime());
|
|
source->sendMessage(channel, IRCCOLOR "03[GameInfo] "_jrs IRCCOLOR + server->getGameVersion());
|
|
source->sendMessage(channel, IRCCOLOR "03[GameInfo] " IRCCOLOR "10Map" IRCCOLOR ": "_jrs + map.name + "; " IRCCOLOR "10GUID" IRCCOLOR ": "_jrs + RenX::formatGUID(map));
|
|
source->sendMessage(channel, Jupiter::StringS::Format(IRCCOLOR "03[GameInfo] " IRCCOLOR "10Elapsed time" IRCCOLOR ": %.2lld:%.2lld:%.2lld", time.count() / 3600, (time.count() % 3600) / 60, time.count() % 60));
|
|
source->sendMessage(channel, Jupiter::StringS::Format(IRCCOLOR "03[GameInfo] " IRCCOLOR "There are " IRCCOLOR "10%d" IRCCOLOR " players online.", server->players.size()));
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendMessage(channel, "Error: Channel not attached to any connected Renegade X servers."_jrs);
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &GameInfoIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Returns information about the game in progress. Syntax: GameInfo");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(GameInfoIRCCommand)
|
|
|
|
// Steam IRC Command
|
|
|
|
void SteamIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("steam"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void SteamIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::StringL msg;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type) && server->players.size() != 0)
|
|
{
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
if (player->name.findi(parameters) != Jupiter::INVALID_INDEX)
|
|
{
|
|
Jupiter::String &playerName = RenX::getFormattedPlayerName(player);
|
|
msg.format(IRCCOLOR "03[Steam] " IRCCOLOR "%.*s (ID: %d) ", playerName.size(), playerName.ptr(), player->id);
|
|
if (player->steamid != 0)
|
|
{
|
|
msg += "is using steam ID " IRCBOLD;
|
|
msg += server->formatSteamID(player);
|
|
msg.aformat(IRCBOLD "; Steam Profile: " IRCBOLD "https://steamcommunity.com/profiles/%llu" IRCBOLD, player->steamid);
|
|
}
|
|
else msg += "is not using steam.";
|
|
source->sendMessage(channel, msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
else
|
|
{
|
|
unsigned int total;
|
|
unsigned int realPlayers;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type) && server->players.size() != 0)
|
|
{
|
|
total = 0;
|
|
realPlayers = 0;
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
if (player->isBot == false)
|
|
{
|
|
realPlayers++;
|
|
if (player->steamid != 0)
|
|
total++;
|
|
}
|
|
}
|
|
if (realPlayers != 0)
|
|
source->sendMessage(channel, Jupiter::StringS::Format("%.2f%% (%u/%u) of players are using Steam.", ((double)total * 100) / ((double)realPlayers), total, realPlayers));
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("No players are in-game."));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &SteamIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Fetches steam usage information. Syntax: Steam [Player]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(SteamIRCCommand)
|
|
|
|
// Kill-Death Ratio IRC Command
|
|
|
|
void KillDeathRatioIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kills"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("deaths"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kdr"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("killdeathraio"));
|
|
}
|
|
|
|
void KillDeathRatioIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
Jupiter::StringL msg;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type) && server->players.size() != 0)
|
|
{
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
if (player->name.findi(parameters) != Jupiter::INVALID_INDEX)
|
|
{
|
|
Jupiter::String &playerName = RenX::getFormattedPlayerName(player);
|
|
msg.format(IRCBOLD "%.*s" IRCBOLD IRCCOLOR ": Kills: %u - Deaths: %u - KDR: %.2f", playerName.size(), playerName.ptr(), player->kills, player->deaths, static_cast<double>(player->kills) / (player->deaths == 0 ? 1.0f : static_cast<double>(player->deaths)));
|
|
source->sendMessage(channel, msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: Kills <Player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &KillDeathRatioIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Gets a player's kills and deaths. Syntax: Kills <Player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(KillDeathRatioIRCCommand)
|
|
|
|
// ShowMods IRC Command
|
|
|
|
void ShowModsIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("showstaff"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("showmods"));
|
|
}
|
|
|
|
extern ModsGameCommand ModsGameCommand_instance;
|
|
|
|
void ShowModsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
bool sent = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
ModsGameCommand_instance.trigger(server, nullptr, Jupiter::ReferenceString::empty);
|
|
sent = true;
|
|
}
|
|
}
|
|
if (sent == false)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &ShowModsIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message, displaying in-game staff. Syntax: showstaff");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(ShowModsIRCCommand)
|
|
|
|
// Mods IRC Command
|
|
|
|
void ModsIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("staff"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("mods"));
|
|
}
|
|
|
|
void ModsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.equalsi("show")) ShowModsIRCCommand_instance.trigger(source, channel, nick, parameters);
|
|
else
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
Jupiter::StringL msg;
|
|
const Jupiter::ReadableString &staff_word = pluginInstance.getStaffTitle();
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
msg = "";
|
|
if (server->players.size() != 0)
|
|
{
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
if (player->isBot == false && (player->adminType.isNotEmpty() || (player->access != 0 && (player->gamePrefix.isNotEmpty() || player->formatNamePrefix.isNotEmpty()))))
|
|
{
|
|
if (msg.isNotEmpty())
|
|
msg += ", ";
|
|
else msg += staff_word + "s in-game: "_jrs;
|
|
msg += player->gamePrefix;
|
|
msg += player->name;
|
|
}
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
msg = "No "_jrs + staff_word + "s are in-game."_jrs;
|
|
source->sendMessage(channel, msg);
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &ModsIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message, displaying in-game staff. Syntax: staff [show]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(ModsIRCCommand)
|
|
|
|
// ShowRules IRC Command
|
|
|
|
void ShowRulesIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("showrules"));
|
|
}
|
|
|
|
void ShowRulesIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
Jupiter::StringL msg;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
msg = "Rules: ";
|
|
msg += server->getRules();
|
|
server->sendMessage(msg);
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &ShowRulesIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message, displaying the in-game rules. Syntax: showrules");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(ShowRulesIRCCommand)
|
|
|
|
// Rules IRC Command
|
|
|
|
void RulesIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rules"));
|
|
}
|
|
|
|
void RulesIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.equalsi("show")) ShowRulesIRCCommand_instance.trigger(source, channel, nick, parameters);
|
|
else
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
Jupiter::StringL msg;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
msg = IRCCOLOR "11[Rules]" IRCCOLOR " ";
|
|
msg += server->getRules();
|
|
source->sendMessage(channel, msg);
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &RulesIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays the in-game rules. Syntax: rules [show]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(RulesIRCCommand)
|
|
|
|
// Reconnect IRC Command
|
|
|
|
void ReconnectIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("reconnect"));
|
|
this->setAccessLevel(3);
|
|
}
|
|
|
|
void ReconnectIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
Jupiter::StringS msg;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
if (server->reconnect(RenX::DisconnectReason::Triggered)) msg.set("Connection established");
|
|
else msg.format("[RenX] ERROR: Failed to connect to %.*s on port %u." ENDL, server->getHostname().size(), server->getHostname().ptr(), server->getPort());
|
|
source->sendMessage(channel, msg);
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
{
|
|
// We didn't connect anywhere!!
|
|
msg.set("ERROR: No servers found to connect to.");
|
|
source->sendMessage(channel, msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &ReconnectIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Resets the RCON connection. Syntax: Reconnect");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(ReconnectIRCCommand)
|
|
|
|
// GameOver IRC Command
|
|
|
|
void GameOverIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("gameover"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("endmap"));
|
|
this->setAccessLevel(3);
|
|
}
|
|
|
|
void GameOverIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
bool match = false;
|
|
std::chrono::seconds delay;
|
|
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
if (parameters.equalsi("empty"_jrs))
|
|
server->gameoverWhenEmpty();
|
|
else if (parameters.equalsi("if empty"_jrs))
|
|
{
|
|
if (server->players.size() == server->getBotCount())
|
|
server->gameover();
|
|
}
|
|
else if (parameters.equalsi("now"_jrs))
|
|
server->gameover();
|
|
else if (parameters.equalsi("stop"_jrs) || parameters.equalsi("cancel"_jrs))
|
|
{
|
|
if (server->gameoverStop())
|
|
server->sendMessage("Notice: The scheduled gameover has been cancelled."_jrs);
|
|
else
|
|
source->sendNotice(nick, "Error: There is no gameover scheduled."_jrs);
|
|
}
|
|
else
|
|
{
|
|
if (parameters.isEmpty())
|
|
delay = std::chrono::seconds(10);
|
|
else
|
|
delay = std::chrono::seconds(parameters.asLongLong());
|
|
|
|
server->sendMessage(Jupiter::StringS::Format("Notice: This server will gameover in %lld seconds.", static_cast<long long>(delay.count())));
|
|
server->gameover(delay);
|
|
}
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &GameOverIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Forcefully ends the game in progress. Syntax: Gameover [NOW | STOP | [If] Empty | Seconds = 10]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(GameOverIRCCommand)
|
|
|
|
// SetMap IRC Command
|
|
|
|
void SetMapIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("setmap"));
|
|
this->setAccessLevel(4);
|
|
}
|
|
|
|
void SetMapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
const Jupiter::ReadableString *map_name = nullptr;
|
|
int type = chan->getType();
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
map_name = server->getMapName(parameters);
|
|
if (map_name == nullptr)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Map not in rotation."));
|
|
else if (server->setMap(*map_name) == false)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Transmission error."));
|
|
}
|
|
}
|
|
if (map_name == nullptr)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: setmap <map>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &SetMapIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Ends the game immediately. Syntax: setmap <map>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(SetMapIRCCommand)
|
|
|
|
// Mute IRC Command
|
|
|
|
void MuteIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("mute"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void MuteIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
bool match = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
player = server->getPlayerByPartName(parameters);
|
|
if (player != nullptr)
|
|
{
|
|
server->mute(player);
|
|
source->sendMessage(channel, RenX::getFormattedPlayerName(player) + STRING_LITERAL_AS_REFERENCE(IRCCOLOR " has been muted."));
|
|
}
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: mute <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &MuteIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Mutes a player. Syntax: mute <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(MuteIRCCommand)
|
|
|
|
// UnMute IRC Command
|
|
|
|
void UnMuteIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("unmute"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void UnMuteIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
bool match = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
player = server->getPlayerByPartName(parameters);
|
|
if (player != nullptr)
|
|
{
|
|
server->unmute(player);
|
|
source->sendMessage(channel, RenX::getFormattedPlayerName(player) + STRING_LITERAL_AS_REFERENCE(IRCCOLOR " has been unmuted."));
|
|
}
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: unmute <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &UnMuteIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Unmutes a player. Syntax: unmute <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(UnMuteIRCCommand)
|
|
|
|
// Kill IRC Command
|
|
|
|
void KillIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kill"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void KillIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
bool match = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
player = server->getPlayerByPartName(parameters);
|
|
if (player != nullptr)
|
|
server->kill(player);
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: kill <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &KillIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kills a player. Syntax: kill <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(KillIRCCommand)
|
|
|
|
// Disarm IRC Command
|
|
|
|
void DisarmIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarm"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void DisarmIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
bool match = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
player = server->getPlayerByPartName(parameters);
|
|
if (player != nullptr)
|
|
{
|
|
if (server->disarm(player))
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("All deployables (c4, beacons, etc) belonging to ") + RenX::getFormattedPlayerName(player) + STRING_LITERAL_AS_REFERENCE(IRCCOLOR " have been disarmed."));
|
|
else
|
|
source->sendMessage(channel, "Error: Server does not support disarms."_jrs);
|
|
}
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: disarm <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &DisarmIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Disarms all of a player's deployed objects. Syntax: disarm <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(DisarmIRCCommand)
|
|
|
|
// DisarmC4 IRC Command
|
|
|
|
void DisarmC4IRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarmc4"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void DisarmC4IRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
bool match = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
player = server->getPlayerByPartName(parameters);
|
|
if (player != nullptr)
|
|
{
|
|
if (server->disarmC4(player))
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("All C4 belonging to ") + RenX::getFormattedPlayerName(player) + STRING_LITERAL_AS_REFERENCE(IRCCOLOR " have been disarmed."));
|
|
else
|
|
source->sendMessage(channel, "Error: Server does not support disarms."_jrs);
|
|
}
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: disarmC4 <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &DisarmC4IRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Disarms all of a player's deployed C4s. Syntax: disarmc4 <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(DisarmC4IRCCommand)
|
|
|
|
// DisarmBeacon IRC Command
|
|
|
|
void DisarmBeaconIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarmb"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarmbeacon"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarmbeacons"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void DisarmBeaconIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
bool match = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
player = server->getPlayerByPartName(parameters);
|
|
if (player != nullptr)
|
|
{
|
|
if (server->disarmBeacon(player))
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("All beacons belonging to ") + RenX::getFormattedPlayerName(player) + STRING_LITERAL_AS_REFERENCE(IRCCOLOR " have been disarmed."));
|
|
else
|
|
source->sendMessage(channel, "Error: Server does not support disarms."_jrs);
|
|
}
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: disarmb <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &DisarmBeaconIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Disarms all of a player's deployed beacons. Syntax: disarmb <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(DisarmBeaconIRCCommand)
|
|
|
|
// MineBan IRC Command
|
|
|
|
void MineBanIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("mineban"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void MineBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
RenX::PlayerInfo *player;
|
|
bool match = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type))
|
|
{
|
|
match = true;
|
|
player = server->getPlayerByPartName(parameters);
|
|
if (player != nullptr)
|
|
{
|
|
server->mineBan(player);
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Player can no longer place mines."));
|
|
}
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
if (match == false)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: mineban <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &MineBanIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Bans a player from mining for 1 game (or until they leave). Syntax: mineban <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(MineBanIRCCommand)
|
|
|
|
// Kick IRC Command
|
|
|
|
void KickIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kick"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("qkick"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("k"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void KickIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(chan->getType());
|
|
if (servers.size() != 0)
|
|
{
|
|
RenX::PlayerInfo *player;
|
|
RenX::Server *server;
|
|
unsigned int kicks = 0;
|
|
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
|
|
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
|
|
for (size_t i = 0; i != servers.size(); i++)
|
|
{
|
|
server = servers.get(i);
|
|
if (server != nullptr)
|
|
{
|
|
player = server->getPlayerByPartName(name);
|
|
if (player != nullptr)
|
|
{
|
|
server->kickPlayer(player, reason);
|
|
++kicks;
|
|
}
|
|
}
|
|
}
|
|
source->sendMessage(channel, Jupiter::StringS::Format("%u players kicked.", kicks));
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: Kick <Player> [Reason]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &KickIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks a player from the game. Syntax: Kick <Player> [Reason]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(KickIRCCommand)
|
|
|
|
/** Ban IRC Commands */
|
|
|
|
// BanSearch IRC Command
|
|
|
|
void BanSearchIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("bansearch"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("bsearch"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("banfind"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("bfind"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("banlogs"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("blogs"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void BanSearchIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
auto entries = RenX::banDatabase->getEntries();
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
if (entries.size() == 0)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("The ban database is empty!"));
|
|
else
|
|
{
|
|
RenX::BanDatabase::Entry *entry;
|
|
Jupiter::ReferenceString params = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE);
|
|
std::function<bool(unsigned int)> isMatch = [&](unsigned int type_l) -> bool
|
|
{
|
|
switch (type_l)
|
|
{
|
|
default:
|
|
case 0: // ANY
|
|
return isMatch(1) || isMatch(2) || isMatch(3) || isMatch(4);
|
|
case 1: // ALL
|
|
return true;
|
|
case 2: // IP
|
|
return entry->ip == params.asUnsignedInt();
|
|
case 3: // HWID
|
|
return entry->hwid.equals(params);
|
|
case 4: // RDNS
|
|
return entry->rdns.equals(params);
|
|
case 5: // STEAM
|
|
return entry->steamid == params.asUnsignedLongLong();
|
|
case 6: // NAME
|
|
return entry->name.equalsi(params);
|
|
case 7: // BANNER
|
|
return entry->banner.equalsi(params);
|
|
case 8: // ACTIVE
|
|
return params.asBool() == entry->is_active();
|
|
}
|
|
};
|
|
|
|
unsigned int type;
|
|
Jupiter::ReferenceString type_str = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
|
|
if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("all")) || type_str.equals('*'))
|
|
type = 1;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("ip")))
|
|
type = 2;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("hwid")))
|
|
type = 3;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("rdns")))
|
|
type = 4;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("steam")))
|
|
type = 5;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("name")))
|
|
type = 6;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("banner")))
|
|
type = 7;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("active")))
|
|
type = 8;
|
|
else
|
|
{
|
|
type = 0;
|
|
params = parameters;
|
|
}
|
|
|
|
Jupiter::String out(256);
|
|
Jupiter::String types(64);
|
|
char timeStr[256];
|
|
for (size_t i = 0; i != entries.size(); i++)
|
|
{
|
|
entry = entries.get(i);
|
|
if (isMatch(type))
|
|
{
|
|
Jupiter::StringS &ip_str = Jupiter::Socket::ntop4(entry->ip);
|
|
strftime(timeStr, sizeof(timeStr), "%b %d %Y, %H:%M:%S", localtime(std::addressof<const time_t>(std::chrono::system_clock::to_time_t(entry->timestamp))));
|
|
|
|
if ((entry->flags & 0x7FFF) == 0)
|
|
types = " NULL;"_jrs;
|
|
else
|
|
{
|
|
types.erase();
|
|
if (entry->is_rdns_ban())
|
|
types += " rdns"_jrs;
|
|
if (entry->is_type_game())
|
|
types += " game"_jrs;
|
|
if (entry->is_type_chat())
|
|
types += " chat"_jrs;
|
|
if (entry->is_type_bot())
|
|
types += " bot"_jrs;
|
|
if (entry->is_type_vote())
|
|
types += " vote"_jrs;
|
|
if (entry->is_type_mine())
|
|
types += " mine"_jrs;
|
|
if (entry->is_type_ladder())
|
|
types += " ladder"_jrs;
|
|
if (entry->is_type_alert())
|
|
types += " alert"_jrs;
|
|
types += ";"_jrs;
|
|
}
|
|
|
|
out.format("ID: %lu (" IRCCOLOR "%sactive" IRCCOLOR "); Date: %s; IP: %.*s/%u; HWID: %.*s; Steam: %llu; Types:%.*s Name: %.*s; Banner: %.*s",
|
|
i, entry->is_active() ? "12" : "04in", timeStr, ip_str.size(), ip_str.ptr(), entry->prefix_length, entry->hwid.size(), entry->hwid.ptr(), entry->steamid,
|
|
types.size(), types.ptr(), entry->name.size(), entry->name.ptr(), entry->banner.size(), entry->banner.ptr());
|
|
|
|
if (entry->rdns.isNotEmpty())
|
|
{
|
|
out.concat("; RDNS: "_jrs);
|
|
out.concat(entry->rdns);
|
|
}
|
|
if (entry->reason.isNotEmpty())
|
|
{
|
|
out.concat("; Reason: "_jrs);
|
|
out.concat(entry->reason);
|
|
}
|
|
source->sendNotice(nick, out);
|
|
}
|
|
}
|
|
if (out.isEmpty())
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("No matches found."));
|
|
}
|
|
}
|
|
else
|
|
source->sendNotice(nick, Jupiter::StringS::Format("There are a total of %u entries in the ban database.", entries.size()));
|
|
}
|
|
|
|
const Jupiter::ReadableString &BanSearchIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Searches the ban database for an entry. Syntax: bsearch [ip/rdns/steam/name/banner/active/any/all = any] <player ip/steam/name/banner>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(BanSearchIRCCommand)
|
|
|
|
// TempBan IRC Command
|
|
|
|
void TempBanIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("tban"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("tb"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("tempban"));
|
|
this->setAccessLevel(3);
|
|
}
|
|
|
|
void TempBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(chan->getType());
|
|
if (servers.size() != 0)
|
|
{
|
|
RenX::PlayerInfo *player;
|
|
RenX::Server *server;
|
|
unsigned int kicks = 0;
|
|
Jupiter::ReferenceString name = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
|
|
Jupiter::ReferenceString reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE) : "No reason"_jrs;
|
|
Jupiter::String banner(nick.size() + 4);
|
|
banner += nick;
|
|
banner += "@IRC";
|
|
for (size_t i = 0; i != servers.size(); i++)
|
|
{
|
|
server = servers.get(i);
|
|
if (server != nullptr)
|
|
{
|
|
player = server->getPlayerByPartName(name);
|
|
if (player != nullptr)
|
|
{
|
|
server->banPlayer(player, banner, reason, pluginInstance.getTBanTime());
|
|
kicks++;
|
|
}
|
|
}
|
|
}
|
|
source->sendMessage(channel, Jupiter::StringS::Format("%u players kicked.", kicks));
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: TempBan <Player> [Reason]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &TempBanIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and temporarily bans a player from the game. Syntax: TempBan <Player> [Reason]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(TempBanIRCCommand)
|
|
|
|
// KickBan IRC Command
|
|
|
|
void KickBanIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kickban"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kb"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("ban"));
|
|
this->setAccessLevel(4);
|
|
}
|
|
|
|
void KickBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(chan->getType());
|
|
if (servers.size() != 0)
|
|
{
|
|
RenX::PlayerInfo *player;
|
|
RenX::Server *server;
|
|
unsigned int kicks = 0;
|
|
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
|
|
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
|
|
Jupiter::String banner(nick.size() + 4);
|
|
banner += nick;
|
|
banner += "@IRC";
|
|
for (size_t i = 0; i != servers.size(); i++)
|
|
{
|
|
server = servers.get(i);
|
|
if (server != nullptr)
|
|
{
|
|
player = server->getPlayerByPartName(name);
|
|
if (player != nullptr)
|
|
{
|
|
server->banPlayer(player, banner, reason);
|
|
kicks++;
|
|
}
|
|
}
|
|
}
|
|
if (kicks == 0)
|
|
source->sendMessage(channel, "Player \""_jrs + name + "\" not found."_jrs);
|
|
else
|
|
{
|
|
source->sendMessage(channel, Jupiter::StringS::Format("%u players kicked.", kicks));
|
|
RenX::getCore()->banCheck();
|
|
}
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: KickBan <Player> [Reason]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &KickBanIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and bans a player from the game. Syntax: KickBan <Player> [Reason]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(KickBanIRCCommand)
|
|
|
|
// AddBan IRC Command
|
|
|
|
#define ADDBAN_WHITESPACE " \t="
|
|
|
|
void AddBanIRCCommand::create()
|
|
{
|
|
this->addTrigger("addban"_jrs);
|
|
this->addTrigger("banadd"_jrs);
|
|
this->setAccessLevel(4);
|
|
}
|
|
|
|
void AddBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
size_t words = parameters.wordCount(ADDBAN_WHITESPACE);
|
|
if (words == 0)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: KickBan <Player> [Reason]"));
|
|
else if (words == 1)
|
|
KickBanIRCCommand_instance.trigger(source, channel, nick, parameters);
|
|
else
|
|
{
|
|
size_t index = 0;
|
|
Jupiter::ReferenceString name;
|
|
Jupiter::CStringS ip_str;
|
|
uint32_t ip = 0U;
|
|
uint8_t prefix_length = 32U;
|
|
uint64_t steamid = 0U;
|
|
Jupiter::ReferenceString hwid;
|
|
Jupiter::StringS rdns;
|
|
Jupiter::String banner = nick + "@IRC"_jrs;
|
|
Jupiter::ReferenceString reason = "No reason"_jrs;
|
|
std::chrono::seconds duration(0);
|
|
uint16_t flags = 0;
|
|
|
|
Jupiter::ReferenceString word;
|
|
while (index != words)
|
|
{
|
|
word = Jupiter::ReferenceString::getWord(parameters, index++, ADDBAN_WHITESPACE);
|
|
|
|
if (word.equalsi("Name"_jrs) || word.equalsi("Nick"_jrs) || word.equalsi("Nickname"_jrs) || word.equalsi("Username"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
name = Jupiter::ReferenceString::getWord(parameters, index++, ADDBAN_WHITESPACE);
|
|
}
|
|
else if (word.equalsi("IP"_jrs) || word.equalsi("IPAddress"_jrs) || word.equalsi("Address"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
ip_str = Jupiter::ReferenceString::getWord(parameters, index++, ADDBAN_WHITESPACE);
|
|
}
|
|
else if (word.equalsi("Steam"_jrs) || word.equalsi("SteamID"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
steamid = Jupiter::ReferenceString::getWord(parameters, index++, ADDBAN_WHITESPACE).asUnsignedLongLong();
|
|
}
|
|
else if (word.equalsi("HWID"_jrs) || word.equalsi("HardwareID"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
hwid = Jupiter::ReferenceString::getWord(parameters, index++, ADDBAN_WHITESPACE);
|
|
}
|
|
else if (word.equalsi("RDNS"_jrs) || word.equalsi("DNS"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
rdns = Jupiter::ReferenceString::getWord(parameters, index++, ADDBAN_WHITESPACE);
|
|
}
|
|
else if (word.equalsi("Reason"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
reason = Jupiter::ReferenceString::gotoWord(parameters, index++, ADDBAN_WHITESPACE);
|
|
break;
|
|
}
|
|
else if (word.equalsi("Duration"_jrs) || word.equalsi("Length"_jrs) || word.equalsi("Time"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
duration = std::chrono::seconds(Jupiter::ReferenceString::getWord(parameters, index++, ADDBAN_WHITESPACE).asUnsignedLongLong());
|
|
}
|
|
else if (word.equalsi("Game"_jrs))
|
|
flags |= RenX::BanDatabase::Entry::FLAG_TYPE_GAME;
|
|
else if (word.equalsi("Chat"_jrs))
|
|
flags |= RenX::BanDatabase::Entry::FLAG_TYPE_CHAT;
|
|
else if (word.equalsi("Bot"_jrs) || word.equalsi("Command"_jrs))
|
|
flags |= RenX::BanDatabase::Entry::FLAG_TYPE_BOT;
|
|
else if (word.equalsi("Vote"_jrs) || word.equalsi("Poll"_jrs))
|
|
flags |= RenX::BanDatabase::Entry::FLAG_TYPE_VOTE;
|
|
else if (word.equalsi("Mine"_jrs))
|
|
flags |= RenX::BanDatabase::Entry::FLAG_TYPE_MINE;
|
|
else if (word.equalsi("Ladder"_jrs))
|
|
flags |= RenX::BanDatabase::Entry::FLAG_TYPE_LADDER;
|
|
else if (word.equalsi("Alert"_jrs))
|
|
flags |= RenX::BanDatabase::Entry::FLAG_TYPE_ALERT;
|
|
else
|
|
{
|
|
source->sendNotice(nick, "ERROR: Unknown token: "_jrs + word);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Default to Game type
|
|
if (flags == 0)
|
|
flags = RenX::BanDatabase::Entry::FLAG_TYPE_GAME;
|
|
|
|
index = ip_str.find('/');
|
|
if (index != JUPITER_INVALID_INDEX)
|
|
{
|
|
Jupiter::ReferenceString prefix_length_str(ip_str.c_str() + index + 1);
|
|
prefix_length = prefix_length_str.asUnsignedInt();
|
|
if (prefix_length == 0)
|
|
prefix_length = 32U;
|
|
ip_str.truncate(prefix_length_str.size() + 1);
|
|
}
|
|
ip = Jupiter::Socket::pton4(ip_str.c_str());
|
|
|
|
if (rdns.isEmpty())
|
|
Jupiter::Socket::resolveHostname(ip_str.c_str(), 0);
|
|
else
|
|
flags |= RenX::BanDatabase::Entry::FLAG_USE_RDNS;
|
|
|
|
RenX::banDatabase->add(name, ip, prefix_length, steamid, hwid, rdns, banner, reason, duration, flags);
|
|
RenX::getCore()->banCheck();
|
|
source->sendMessage(channel, Jupiter::StringS::Format("Ban added to the database with ID #%u", RenX::banDatabase->getEntries().size() - 1));
|
|
}
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: AddBan <Key> <Value> [...]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &AddBanIRCCommand::getHelp(const Jupiter::ReadableString ¶meters)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Adds a ban entry to the ban list. Use \"help addban keys\" for a list of input keys. Syntax: AddBan <Key> <Value> [<Key> <Value> ...]");
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(keyHelp, "Valueless keys (flags): Game, Chat, Bot, Vote, Mine, Ladder, Alert; Value-paired keys: Name, IP, Steam, RDNS, Duration, Reason (MUST BE LAST)");
|
|
if (parameters.isNotEmpty() && parameters.equalsi("keys"_jrs))
|
|
return keyHelp;
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(AddBanIRCCommand)
|
|
|
|
// UnBan IRC Command
|
|
|
|
void UnBanIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("unban"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("deban"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("uban"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("dban"));
|
|
this->setAccessLevel(4);
|
|
}
|
|
|
|
void UnBanIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
size_t index = static_cast<size_t>(parameters.asUnsignedLongLong());
|
|
if (index < RenX::banDatabase->getEntries().size())
|
|
{
|
|
if (RenX::banDatabase->deactivate(index))
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Ban deactivated."));
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Ban not active."));
|
|
}
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Invalid ban ID; please find the ban ID using \"bansearch\"."));
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: unban <Ban ID>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &UnBanIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Deactivates a ban. Syntax: unban <Ban ID>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(UnBanIRCCommand)
|
|
|
|
/** Exemption IRC Commands */
|
|
|
|
// ExemptionSearch IRC Command
|
|
|
|
void ExemptionSearchIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("exemptionsearch"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("esearch"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("exemptionfind"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("efind"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("exemptionlogs"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("elogs"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void ExemptionSearchIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
auto entries = RenX::exemptionDatabase->getEntries();
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
if (entries.size() == 0)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("The exemption database is empty!"));
|
|
else
|
|
{
|
|
RenX::ExemptionDatabase::Entry *entry;
|
|
Jupiter::ReferenceString params = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE);
|
|
std::function<bool(unsigned int)> isMatch = [&](unsigned int type_l) -> bool
|
|
{
|
|
switch (type_l)
|
|
{
|
|
default:
|
|
case 0: // ANY
|
|
return isMatch(1) || isMatch(2) || isMatch(3) || isMatch(4);
|
|
case 1: // ALL
|
|
return true;
|
|
case 2: // IP
|
|
return entry->ip == params.asUnsignedInt();
|
|
case 3: // STEAM
|
|
return entry->steamid == params.asUnsignedLongLong();
|
|
case 4: // SETTER
|
|
return entry->setter.equalsi(params);
|
|
case 5: // ACTIVE
|
|
return params.asBool() == entry->is_active();
|
|
}
|
|
};
|
|
|
|
unsigned int type;
|
|
Jupiter::ReferenceString type_str = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
|
|
if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("all")) || type_str.equals('*'))
|
|
type = 1;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("ip")))
|
|
type = 2;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("steam")))
|
|
type = 3;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("setter")))
|
|
type = 4;
|
|
else if (type_str.equalsi(STRING_LITERAL_AS_REFERENCE("active")))
|
|
type = 5;
|
|
else
|
|
{
|
|
type = 0;
|
|
params = parameters;
|
|
}
|
|
|
|
Jupiter::String out(256);
|
|
Jupiter::String types(64);
|
|
char timeStr[256];
|
|
for (size_t i = 0; i != entries.size(); i++)
|
|
{
|
|
entry = entries.get(i);
|
|
if (isMatch(type))
|
|
{
|
|
Jupiter::StringS &ip_str = Jupiter::Socket::ntop4(entry->ip);
|
|
strftime(timeStr, sizeof(timeStr), "%b %d %Y, %H:%M:%S", localtime(std::addressof<const time_t>(std::chrono::system_clock::to_time_t(entry->timestamp))));
|
|
|
|
if ((entry->flags & 0xFF) == 0)
|
|
types = " NULL;"_jrs;
|
|
else
|
|
{
|
|
types.erase();
|
|
if (entry->is_type_kick())
|
|
types += " kick"_jrs;
|
|
if (entry->is_type_ban())
|
|
types += " ban"_jrs;
|
|
if (entry->is_ip_exemption())
|
|
types += " ip"_jrs;
|
|
types += ";"_jrs;
|
|
}
|
|
|
|
out.format("ID: %lu (%sactive); Date: %s; IP: %.*s/%u; Steam: %llu; Types:%.*s Setter: %.*s",
|
|
i, entry->is_active() ? "" : "in", timeStr, ip_str.size(), ip_str.ptr(), entry->prefix_length, entry->steamid,
|
|
types.size(), types.ptr(), entry->setter.size(), entry->setter.ptr());
|
|
|
|
source->sendNotice(nick, out);
|
|
}
|
|
}
|
|
if (out.isEmpty())
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("No matches found."));
|
|
}
|
|
}
|
|
else
|
|
source->sendNotice(nick, Jupiter::StringS::Format("There are a total of %u entries in the exemption database.", entries.size()));
|
|
}
|
|
|
|
const Jupiter::ReadableString &ExemptionSearchIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Searches the exemption database for an entry. Syntax: esearch [ip/steam/setter/active/any/all = any] <player ip/steam/setter>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(ExemptionSearchIRCCommand)
|
|
|
|
// BanExempt IRC Command
|
|
|
|
void BanExemptIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("banexempt"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("bexempt"));
|
|
this->setAccessLevel(4);
|
|
}
|
|
|
|
void BanExemptIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(chan->getType());
|
|
if (servers.size() != 0)
|
|
{
|
|
RenX::PlayerInfo *player;
|
|
RenX::Server *server;
|
|
unsigned int exemptions = 0;
|
|
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
|
|
Jupiter::String setter(nick.size() + 4);
|
|
setter += nick;
|
|
setter += "@IRC";
|
|
for (size_t i = 0; i != servers.size(); i++)
|
|
{
|
|
server = servers.get(i);
|
|
if (server != nullptr)
|
|
{
|
|
player = server->getPlayerByPartName(name);
|
|
if (player != nullptr)
|
|
{
|
|
if (player->steamid != 0LL)
|
|
RenX::exemptionDatabase->add(server, player, setter, std::chrono::seconds::zero(), RenX::ExemptionDatabase::Entry::FLAG_TYPE_BAN);
|
|
else
|
|
RenX::exemptionDatabase->add(server, player, setter, std::chrono::seconds::zero(), RenX::ExemptionDatabase::Entry::FLAG_TYPE_BAN | RenX::ExemptionDatabase::Entry::FLAG_USE_IP);
|
|
++exemptions;
|
|
}
|
|
}
|
|
}
|
|
if (exemptions == 0)
|
|
source->sendMessage(channel, "Player \""_jrs + name + "\" not found."_jrs);
|
|
else
|
|
{
|
|
source->sendMessage(channel, Jupiter::StringS::Format("%u players added.", exemptions));
|
|
}
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: BanExempt <Player> [Reason]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &BanExemptIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Exempts a player from bans using their SteamID, or their IP address if they have none. Syntax: BanExempt <Player> [Reason]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(BanExemptIRCCommand)
|
|
|
|
// KickExempt IRC Command
|
|
|
|
void KickExemptIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kickexempt"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kexempt"));
|
|
this->setAccessLevel(4);
|
|
}
|
|
|
|
void KickExemptIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(chan->getType());
|
|
if (servers.size() != 0)
|
|
{
|
|
RenX::PlayerInfo *player;
|
|
RenX::Server *server;
|
|
unsigned int exemptions = 0;
|
|
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
|
|
Jupiter::String setter(nick.size() + 4);
|
|
setter += nick;
|
|
setter += "@IRC";
|
|
for (size_t i = 0; i != servers.size(); i++)
|
|
{
|
|
server = servers.get(i);
|
|
if (server != nullptr)
|
|
{
|
|
player = server->getPlayerByPartName(name);
|
|
if (player != nullptr)
|
|
{
|
|
if (player->steamid != 0LL)
|
|
RenX::exemptionDatabase->add(server, player, setter, std::chrono::seconds::zero(), RenX::ExemptionDatabase::Entry::FLAG_TYPE_BAN | RenX::ExemptionDatabase::Entry::FLAG_TYPE_KICK);
|
|
else
|
|
RenX::exemptionDatabase->add(server, player, setter, std::chrono::seconds::zero(), RenX::ExemptionDatabase::Entry::FLAG_TYPE_BAN | RenX::ExemptionDatabase::Entry::FLAG_TYPE_KICK | RenX::ExemptionDatabase::Entry::FLAG_USE_IP);
|
|
++exemptions;
|
|
}
|
|
}
|
|
}
|
|
if (exemptions == 0)
|
|
source->sendMessage(channel, "Player \""_jrs + name + "\" not found."_jrs);
|
|
else
|
|
{
|
|
source->sendMessage(channel, Jupiter::StringS::Format("%u players added.", exemptions));
|
|
}
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: KickExempt <Player> [Reason]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &KickExemptIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Exempts a player from kicks and bans using their SteamID, or their IP address if they have none. Syntax: KickExempt <Player> [Reason]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(KickExemptIRCCommand)
|
|
|
|
// AddExemption IRC Command
|
|
|
|
#define ADDEXEMPTION_WHITESPACE " \t="
|
|
|
|
void AddExemptionIRCCommand::create()
|
|
{
|
|
this->addTrigger("addexemption"_jrs);
|
|
this->addTrigger("exemptionadd"_jrs);
|
|
this->addTrigger("exempt"_jrs);
|
|
this->setAccessLevel(4);
|
|
}
|
|
|
|
void AddExemptionIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
size_t words = parameters.wordCount(ADDEXEMPTION_WHITESPACE);
|
|
if (words == 0)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: BanExempt <Player> [Reason]"));
|
|
else if (words == 1)
|
|
BanExemptIRCCommand_instance.trigger(source, channel, nick, parameters);
|
|
else
|
|
{
|
|
size_t index = 0;
|
|
Jupiter::CStringS ip_str;
|
|
uint32_t ip = 0U;
|
|
uint8_t prefix_length = 32U;
|
|
uint64_t steamid = 0U;
|
|
Jupiter::String setter = nick + "@IRC"_jrs;
|
|
std::chrono::seconds duration = std::chrono::seconds::zero();
|
|
uint8_t flags = 0;
|
|
|
|
Jupiter::ReferenceString word;
|
|
while (index != words)
|
|
{
|
|
word = Jupiter::ReferenceString::getWord(parameters, index++, ADDEXEMPTION_WHITESPACE);
|
|
|
|
if (word.equalsi("IP"_jrs) || word.equalsi("IPAddress"_jrs) || word.equalsi("Address"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
ip_str = Jupiter::ReferenceString::getWord(parameters, index++, ADDEXEMPTION_WHITESPACE);
|
|
}
|
|
else if (word.equalsi("Steam"_jrs) || word.equalsi("SteamID"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
steamid = Jupiter::ReferenceString::getWord(parameters, index++, ADDEXEMPTION_WHITESPACE).asUnsignedLongLong();
|
|
}
|
|
else if (word.equalsi("Duration"_jrs) || word.equalsi("Length"_jrs) || word.equalsi("Time"_jrs))
|
|
{
|
|
if (index == words)
|
|
{
|
|
source->sendNotice(nick, "ERROR: No value specified for token: "_jrs + word);
|
|
return;
|
|
}
|
|
|
|
duration = std::chrono::seconds(Jupiter::ReferenceString::getWord(parameters, index++, ADDEXEMPTION_WHITESPACE).asUnsignedLongLong());
|
|
}
|
|
else if (word.equalsi("Ban"_jrs))
|
|
flags |= RenX::ExemptionDatabase::Entry::FLAG_TYPE_BAN;
|
|
else if (word.equalsi("Kick"_jrs))
|
|
flags |= RenX::ExemptionDatabase::Entry::FLAG_TYPE_KICK;
|
|
else
|
|
{
|
|
source->sendNotice(nick, "ERROR: Unknown token: "_jrs + word);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Default to Ban type
|
|
if (flags == 0)
|
|
flags = RenX::ExemptionDatabase::Entry::FLAG_TYPE_BAN;
|
|
|
|
if (ip_str.isNotEmpty())
|
|
{
|
|
index = ip_str.find('/');
|
|
if (index != JUPITER_INVALID_INDEX)
|
|
{
|
|
Jupiter::ReferenceString prefix_length_str(ip_str.c_str() + index + 1);
|
|
prefix_length = prefix_length_str.asUnsignedInt();
|
|
if (prefix_length == 0)
|
|
prefix_length = 32U;
|
|
ip_str.truncate(prefix_length_str.size() + 1);
|
|
}
|
|
ip = Jupiter::Socket::pton4(ip_str.c_str());
|
|
|
|
if (ip != 0)
|
|
flags |= RenX::ExemptionDatabase::Entry::FLAG_USE_IP;
|
|
}
|
|
|
|
if ((flags & RenX::ExemptionDatabase::Entry::FLAG_USE_IP) == 0 && steamid == 0ULL)
|
|
source->sendNotice(nick, "Pointless exemption detected -- no IP or SteamID specified"_jrs);
|
|
else
|
|
{
|
|
RenX::exemptionDatabase->add(ip, prefix_length, steamid, setter, duration, flags);
|
|
source->sendMessage(channel, Jupiter::StringS::Format("Exemption added to the database with ID #%u", RenX::exemptionDatabase->getEntries().size() - 1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: AddExemption <Key> <Value> [...]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &AddExemptionIRCCommand::getHelp(const Jupiter::ReadableString ¶meters)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Adds an exemption entry to the exemption list. Use \"help addexemption keys\" for a list of input keys. Syntax: AddExemption <Key> <Value> [<Key> <Value> ...]");
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(keyHelp, "Valueless keys (flags): Ban, Kick; Value-paired keys: IP, Steam, Duration");
|
|
if (parameters.isNotEmpty() && parameters.equalsi("keys"_jrs))
|
|
return keyHelp;
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(AddExemptionIRCCommand)
|
|
|
|
// UnExempt IRC Command
|
|
|
|
void UnExemptIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("unexempt"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("deexempt"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("uexempt"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("dexempt"));
|
|
this->setAccessLevel(4);
|
|
}
|
|
|
|
void UnExemptIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
size_t index = static_cast<size_t>(parameters.asUnsignedLongLong());
|
|
if (index < RenX::exemptionDatabase->getEntries().size())
|
|
{
|
|
if (RenX::exemptionDatabase->deactivate(index))
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Exemption deactivated."));
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Exemption not active."));
|
|
}
|
|
else
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Invalid exemption ID; please find the exemption ID using \"esearch\"."));
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: unexempt <Exemption ID>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &UnExemptIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Deactivates an exemption. Syntax: unexempt <Exemption ID>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(UnExemptIRCCommand)
|
|
|
|
// AddBots IRC Command
|
|
|
|
void AddBotsIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("addbots"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("addbot"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void AddBotsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(source->getChannel(channel)->getType());
|
|
if (servers.size() != 0)
|
|
{
|
|
int amount = 1;
|
|
if (parameters.isNotEmpty())
|
|
amount = parameters.asInt();
|
|
if (amount != 0)
|
|
{
|
|
RenX::Server *server;
|
|
Jupiter::StringL cmd;
|
|
RenX::TeamType team = RenX::getTeam(Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE));
|
|
|
|
switch (team)
|
|
{
|
|
case RenX::TeamType::GDI:
|
|
cmd = "addredbots ";
|
|
break;
|
|
case RenX::TeamType::Nod:
|
|
cmd = "addbluebots ";
|
|
break;
|
|
case RenX::TeamType::None:
|
|
case RenX::TeamType::Other:
|
|
cmd = "addbots ";
|
|
break;
|
|
}
|
|
|
|
for (size_t i = 0, extra; i != servers.size(); i++)
|
|
{
|
|
server = servers.get(i);
|
|
if (server != nullptr)
|
|
{
|
|
extra = cmd.aformat("%u", amount);
|
|
server->send(cmd);
|
|
cmd -= extra;
|
|
}
|
|
server->sendMessage(Jupiter::StringS::Format("%u bots have been added to the server.", amount));
|
|
}
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Invalid amount entered. Amount must be a positive integer."));
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &AddBotsIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Adds bots to the game. Syntax: AddBots [Amount=1] [Team]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(AddBotsIRCCommand)
|
|
|
|
// KillBots IRC Command
|
|
|
|
void KillBotsIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("killbots"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("killbot"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void KillBotsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(chan->getType());
|
|
if (servers.size() != 0)
|
|
{
|
|
RenX::Server *server;
|
|
|
|
for (size_t i = 0; i != servers.size(); i++)
|
|
{
|
|
server = servers.get(i);
|
|
server->send(STRING_LITERAL_AS_REFERENCE("killbots"));
|
|
server->sendMessage(STRING_LITERAL_AS_REFERENCE("All bots have been removed from the server."));
|
|
}
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &KillBotsIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Removes all bots from the game. Syntax: KillBots");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(KillBotsIRCCommand)
|
|
|
|
// PhaseBots IRC Command
|
|
|
|
void PhaseBotsIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("phasebots"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("phasebot"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void PhaseBotsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
Jupiter::ArrayList<RenX::Server> servers = RenX::getCore()->getServers(chan->getType());
|
|
if (servers.size() != 0)
|
|
{
|
|
RenX::Server *server;
|
|
|
|
for (size_t i = 0; i != servers.size(); i++)
|
|
{
|
|
server = servers.get(i);
|
|
if (parameters.isEmpty())
|
|
{
|
|
if (togglePhasing(server))
|
|
server->sendMessage(STRING_LITERAL_AS_REFERENCE("Bot phasing has been enabled."));
|
|
else server->sendMessage(STRING_LITERAL_AS_REFERENCE("Bot phasing has been disabled."));
|
|
}
|
|
else if (parameters.equalsi("true") || parameters.equalsi("on") || parameters.equalsi("start") || parameters.equalsi("1"))
|
|
{
|
|
togglePhasing(server, true);
|
|
server->sendMessage(STRING_LITERAL_AS_REFERENCE("Bot phasing has been enabled."));
|
|
}
|
|
else
|
|
{
|
|
togglePhasing(server, false);
|
|
server->sendMessage(STRING_LITERAL_AS_REFERENCE("Bot phasing has been disabled."));
|
|
}
|
|
}
|
|
}
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &PhaseBotsIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Toggles the phasing of bots from the game by kicking them after death. Syntax: PhaseBots [on/off]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(PhaseBotsIRCCommand)
|
|
|
|
// RCON IRC Command
|
|
|
|
void RCONIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rcon"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("renx"));
|
|
this->setAccessLevel(5);
|
|
}
|
|
|
|
void RCONIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters != nullptr)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
unsigned int r = RenX::getCore()->send(chan->getType(), parameters);
|
|
if (r > 0)
|
|
source->sendMessage(channel, Jupiter::StringS::Format("Command sent to %u servers.", r));
|
|
else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: rcon <input>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &RCONIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends data to the Renegade X server's rcon. Syntax: rcon <input>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(RCONIRCCommand)
|
|
|
|
// Refund IRC Command
|
|
|
|
void RefundIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("refund"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("givecredits"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("gc"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("money"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("credits"));
|
|
this->setAccessLevel(3);
|
|
}
|
|
|
|
void RefundIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.wordCount(WHITESPACE) >= 2)
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
Jupiter::ReferenceString playerName = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
|
|
double credits = Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE).asDouble();
|
|
RenX::PlayerInfo *player;
|
|
Jupiter::StringL msg;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type) && server->players.size() != 0)
|
|
{
|
|
player = server->getPlayerByPartName(playerName);
|
|
if (player != nullptr)
|
|
{
|
|
if (server->giveCredits(player, credits))
|
|
{
|
|
msg.format("You have been refunded %.0f credits by %.*s.", credits, nick.size(), nick.ptr());
|
|
server->sendMessage(player, msg);
|
|
msg.format("%.*s has been refunded %.0f credits.", player->name.size(), player->name.ptr(), credits);
|
|
}
|
|
else
|
|
msg.set("Error: Server does not support refunds.");
|
|
source->sendMessage(channel, msg);
|
|
}
|
|
}
|
|
}
|
|
if (msg.isEmpty()) source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: refund <player> <amount>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &RefundIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Refunds a player's credits. Syntax: refund <player> <amount>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(RefundIRCCommand)
|
|
|
|
// Team-Change IRC Command
|
|
|
|
void TeamChangeIRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("team"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("tc"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("ftc"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("forcetc"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("teamchange"));
|
|
this->setAccessLevel(3);
|
|
}
|
|
|
|
void TeamChangeIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
Jupiter::ReferenceString playerName = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
|
|
RenX::PlayerInfo *player;
|
|
bool playerFound = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type) && server->players.size() != 0)
|
|
{
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
if (player->name.findi(playerName) != Jupiter::INVALID_INDEX)
|
|
{
|
|
playerFound = true;
|
|
if (server->changeTeam(player) == false)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Server does not support team changing."));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (playerFound == false)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: team <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &TeamChangeIRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Changes a player's team. Syntax: team <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(TeamChangeIRCCommand)
|
|
|
|
// TeamChange2 IRC Command
|
|
|
|
void TeamChange2IRCCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("team2"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("tc2"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("ftc2"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("forcetc2"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("teamchange2"));
|
|
this->setAccessLevel(3);
|
|
}
|
|
|
|
void TeamChange2IRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
|
|
if (chan != nullptr)
|
|
{
|
|
int type = chan->getType();
|
|
Jupiter::ReferenceString playerName = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
|
|
RenX::PlayerInfo *player;
|
|
bool playerFound = false;
|
|
for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
|
|
{
|
|
RenX::Server *server = RenX::getCore()->getServer(i);
|
|
if (server->isLogChanType(type) && server->players.size() != 0)
|
|
{
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
if (player->name.findi(playerName) != Jupiter::INVALID_INDEX)
|
|
{
|
|
playerFound = true;
|
|
if (server->changeTeam(player, false) == false)
|
|
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Server does not support team changing."));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (playerFound == false)
|
|
source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
}
|
|
}
|
|
else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: team2 <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &TeamChange2IRCCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Changes a player's team, without resetting their credits. Syntax: team2 <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
IRC_COMMAND_INIT(TeamChange2IRCCommand)
|
|
|
|
/** Game Commands */
|
|
|
|
// Help Game Command
|
|
|
|
void HelpGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("help"));
|
|
}
|
|
|
|
void HelpGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
RenX::GameCommand *cmd;
|
|
unsigned int cmdCount = 0;
|
|
auto getAccessCommands = [&](int accessLevel)
|
|
{
|
|
Jupiter::String list;
|
|
unsigned int i = 0;
|
|
while (i != source->getCommandCount())
|
|
{
|
|
cmd = source->getCommand(i++);
|
|
if (cmd->getAccessLevel() == accessLevel)
|
|
{
|
|
cmdCount++;
|
|
list.format("Access level %d commands: %.*s", accessLevel, cmd->getTrigger().size(), cmd->getTrigger().ptr());
|
|
break;
|
|
}
|
|
}
|
|
while (i != source->getCommandCount())
|
|
{
|
|
cmd = source->getCommand(i++);
|
|
if (cmd->getAccessLevel() == accessLevel)
|
|
{
|
|
cmdCount++;
|
|
list += ", ";
|
|
list += cmd->getTrigger();
|
|
}
|
|
}
|
|
return list;
|
|
};
|
|
if (parameters.wordCount(WHITESPACE) == 0)
|
|
{
|
|
for (int i = 0; i <= player->access; i++)
|
|
{
|
|
Jupiter::ReadableString &msg = getAccessCommands(i);
|
|
if (msg.isNotEmpty())
|
|
source->sendMessage(player, getAccessCommands(i));
|
|
}
|
|
if (cmdCount == 0)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("No listed commands available."));
|
|
}
|
|
else
|
|
{
|
|
cmd = source->getCommand(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE));
|
|
if (cmd != nullptr)
|
|
{
|
|
if (player->access >= cmd->getAccessLevel())
|
|
source->sendMessage(player, cmd->getHelp(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)));
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Access Denied."));
|
|
}
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Command not found."));
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &HelpGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Lists commands, or sends command-specific help. Syntax: help [command]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(HelpGameCommand)
|
|
|
|
// Mods Game Command
|
|
|
|
void ModsGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("staff"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("mods"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("showmods"));
|
|
}
|
|
|
|
void ModsGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *, const Jupiter::ReadableString &)
|
|
{
|
|
RenX::PlayerInfo *player;
|
|
Jupiter::StringL msg;
|
|
const Jupiter::ReadableString &staff_word = pluginInstance.getStaffTitle();
|
|
for (Jupiter::DLList<RenX::PlayerInfo>::Node *node = source->players.getNode(0); node != nullptr; node = node->next)
|
|
{
|
|
player = node->data;
|
|
if (player->isBot == false && (player->adminType.isNotEmpty() || (player->access != 0 && (player->gamePrefix.isNotEmpty() || player->formatNamePrefix.isNotEmpty()))))
|
|
{
|
|
if (msg.isEmpty())
|
|
msg = staff_word + "s in-game: "_jrs;
|
|
else
|
|
msg += ", ";
|
|
msg += player->gamePrefix;
|
|
msg += player->name;
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
{
|
|
msg += "No "_jrs + staff_word + "s are in-game"_jrs;
|
|
RenX::GameCommand *cmd = source->getCommand(STRING_LITERAL_AS_REFERENCE("modrequest"));
|
|
if (cmd != nullptr)
|
|
msg.aformat("; please use \"%.*s%.*s\" if you require assistance.", source->getCommandPrefix().size(), source->getCommandPrefix().ptr(), cmd->getTrigger().size(), cmd->getTrigger().ptr());
|
|
else msg += '.';
|
|
}
|
|
source->sendMessage(msg);
|
|
}
|
|
|
|
const Jupiter::ReadableString &ModsGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays in-game staff. Syntax: staff");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(ModsGameCommand)
|
|
|
|
// Rules Game Command
|
|
|
|
void RulesGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rules"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rule"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("showrules"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("showrule"));
|
|
}
|
|
|
|
void RulesGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
source->sendMessage(Jupiter::StringS::Format("Rules: %.*s", source->getRules().size(), source->getRules().ptr()));
|
|
}
|
|
|
|
const Jupiter::ReadableString &RulesGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays the rules for this server. Syntax: rules");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(RulesGameCommand)
|
|
|
|
// Mod Request Game Command
|
|
|
|
void ModRequestGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("modrequest"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("requestmod"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("mod"));
|
|
}
|
|
|
|
void ModRequestGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
const Jupiter::ReadableString &staff_word = pluginInstance.getStaffTitle();
|
|
size_t serverCount = serverManager->size();
|
|
IRC_Bot *server;
|
|
Jupiter::IRC::Client::Channel *channel;
|
|
unsigned int channelCount;
|
|
unsigned int messageCount = 0;
|
|
Jupiter::String &fmtName = RenX::getFormattedPlayerName(player);
|
|
Jupiter::StringL msg = Jupiter::StringL::Format(IRCCOLOR "12[%.*s Request] " IRCCOLOR IRCBOLD "%.*s" IRCBOLD IRCCOLOR "07 has requested assistance in-game; please look in ", staff_word.size(), staff_word.ptr(), fmtName.size(), fmtName.ptr());
|
|
Jupiter::StringS msg2 = Jupiter::StringS::Format(IRCCOLOR "12[%.*s Request] " IRCCOLOR IRCBOLD "%.*s" IRCBOLD IRCCOLOR "07 has requested assistance in-game!" IRCCOLOR, staff_word.size(), staff_word.ptr(), fmtName.size(), fmtName.ptr());
|
|
for (size_t server_index = 0; server_index < serverCount; ++server_index)
|
|
{
|
|
server = serverManager->getServer(server_index);
|
|
channelCount = server->getChannelCount();
|
|
for (unsigned int b = 0; b < channelCount; b++)
|
|
{
|
|
channel = server->getChannel(b);
|
|
if (source->isLogChanType(channel->getType()))
|
|
{
|
|
server->sendMessage(channel->getName(), msg2);
|
|
msg += channel->getName();
|
|
for (unsigned int c = 0; c < channel->getUserCount(); c++)
|
|
{
|
|
if (channel->getUserPrefix(c) != 0 && channel->getUser(c)->getNickname().equals(server->getNickname()) == false)
|
|
{
|
|
server->sendMessage(channel->getUser(c)->getUser()->getNickname(), msg);
|
|
messageCount++;
|
|
}
|
|
}
|
|
msg -= channel->getName().size();
|
|
}
|
|
}
|
|
}
|
|
source->sendMessage(player, Jupiter::StringS::Format("A total of %u %.*ss have been notified of your assistance request.", messageCount, staff_word.size(), staff_word.ptr()));
|
|
}
|
|
|
|
const Jupiter::ReadableString &ModRequestGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Notifies staff on IRC that assistance is required. Syntax: modRequest");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(ModRequestGameCommand)
|
|
|
|
// Kill Game Command
|
|
|
|
void KillGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kill"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void KillGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
|
|
if (target == nullptr)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
else if (target->access >= player->access)
|
|
source->sendMessage(player, "Error: You can not kill higher level "_jrs + pluginInstance.getStaffTitle() + "s."_jrs);
|
|
else
|
|
{
|
|
source->kill(target);
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been killed."));
|
|
}
|
|
}
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: kill <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &KillGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kills a player in the game. Syntax: kill <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(KillGameCommand)
|
|
|
|
// Disarm Game Command
|
|
|
|
void DisarmGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarm"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void DisarmGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
|
|
if (target == nullptr)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
else if (target->access >= player->access)
|
|
source->sendMessage(player, "Error: You can not disarm higher level "_jrs + pluginInstance.getStaffTitle() + "s."_jrs);
|
|
else if (source->disarm(target) == false)
|
|
source->sendMessage(player, "Error: Server does not support disarms."_jrs);
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been disarmed."));
|
|
}
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: disarm <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &DisarmGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Disarms all of a player's deployed objects in the game. Syntax: disarm <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(DisarmGameCommand)
|
|
|
|
// DisarmC4 Game Command
|
|
|
|
void DisarmC4GameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarmc4"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void DisarmC4GameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
|
|
if (target == nullptr)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
else if (target->access >= player->access)
|
|
source->sendMessage(player, "Error: You can not disarm higher level "_jrs + pluginInstance.getStaffTitle() + "s."_jrs);
|
|
else if (source->disarmC4(target) == false)
|
|
source->sendMessage(player, "Error: Server does not support disarms."_jrs);
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been disarmed."));
|
|
}
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: disarmc4 <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &DisarmC4GameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Disarms all of a player's deployed mines in the game. Syntax: disarmc4 <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(DisarmC4GameCommand)
|
|
|
|
// DisarmBeacon Game Command
|
|
|
|
void DisarmBeaconGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarmb"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarmbeacon"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("disarmbeacons"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void DisarmBeaconGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
|
|
if (target == nullptr)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
else if (target->access >= player->access)
|
|
source->sendMessage(player, "Error: You can not disarm higher level "_jrs + pluginInstance.getStaffTitle() + "s."_jrs);
|
|
else if (source->disarmBeacon(target) == false)
|
|
source->sendMessage(player, "Error: Server does not support disarms."_jrs);
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been disarmed."));
|
|
}
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: disarmb <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &DisarmBeaconGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Disarms all of a player's deployed beacons in the game. Syntax: disarmb <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(DisarmBeaconGameCommand)
|
|
|
|
// MineBan Game Command
|
|
|
|
void MineBanGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("mineban"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void MineBanGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
RenX::PlayerInfo *target = source->getPlayerByPartName(parameters);
|
|
if (target == nullptr)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
else if (target->access >= player->access)
|
|
source->sendMessage(player, "Error: You can not mine-ban higher level "_jrs + pluginInstance.getStaffTitle() + "s."_jrs);
|
|
else
|
|
{
|
|
source->mineBan(target);
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player can no longer place mines."));
|
|
}
|
|
}
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: mineban <player>"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &MineBanGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Bans a player from mining for 1 game (or until they leave). Syntax: mineban <player>");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(MineBanGameCommand)
|
|
|
|
// Kick Game Command
|
|
|
|
void KickGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kick"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("qkick"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("k"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void KickGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
|
|
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
|
|
RenX::PlayerInfo *target = source->getPlayerByPartName(name);
|
|
if (target == nullptr)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
else if (player == target)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: You can not kick yourself."));
|
|
else if (target->access >= player->access)
|
|
source->sendMessage(player, "Error: You can not kick higher level "_jrs + pluginInstance.getStaffTitle() + "s."_jrs);
|
|
else
|
|
{
|
|
source->kickPlayer(target, reason);
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been kicked from the game."));
|
|
}
|
|
}
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: kick <player> [Reason]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &KickGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks a player from the game. Syntax: kick <player> [Reason]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(KickGameCommand)
|
|
|
|
// TempBan Game Command
|
|
|
|
void TempBanGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("tban"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("tempbank"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("tb"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void TempBanGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
|
|
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
|
|
RenX::PlayerInfo *target = source->getPlayerByPartName(name);
|
|
if (target == nullptr)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
else if (player == target)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: You can not ban yourself."));
|
|
else if (target->access >= player->access)
|
|
source->sendMessage(player, "Error: You can not ban higher level "_jrs + pluginInstance.getStaffTitle() + "s."_jrs);
|
|
else
|
|
{
|
|
source->banPlayer(target, player->name, reason, pluginInstance.getTBanTime());
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been temporarily banned and kicked from the game."));
|
|
}
|
|
}
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: tban <player> [Reason]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &TempBanGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and temporarily bans a player from the game. Syntax: tban <player> [Reason]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(TempBanGameCommand)
|
|
|
|
// KickBan Game Command
|
|
|
|
void KickBanGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("ban"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kickban"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kb"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("b"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void KickBanGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isNotEmpty())
|
|
{
|
|
Jupiter::StringS name = Jupiter::StringS::getWord(parameters, 0, WHITESPACE);
|
|
Jupiter::StringS reason = parameters.wordCount(WHITESPACE) > 1 ? Jupiter::StringS::gotoWord(parameters, 1, WHITESPACE) : STRING_LITERAL_AS_REFERENCE("No reason");
|
|
RenX::PlayerInfo *target = source->getPlayerByPartName(name);
|
|
if (target == nullptr)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
|
|
else if (player == target)
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: You can not ban yourself."));
|
|
else if (target->access >= player->access)
|
|
source->sendMessage(player, "Error: You can not ban higher level "_jrs + pluginInstance.getStaffTitle() + "s."_jrs);
|
|
else
|
|
{
|
|
source->banPlayer(target, player->name, reason);
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Player has been banned and kicked from the game."));
|
|
RenX::getCore()->banCheck();
|
|
}
|
|
}
|
|
else
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Error: Too few parameters. Syntax: ban <player> [reason]"));
|
|
}
|
|
|
|
const Jupiter::ReadableString &KickBanGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Kicks and bans a player from the game. Syntax: ban <player> [reason]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(KickBanGameCommand)
|
|
|
|
// AddBots Game Command
|
|
|
|
void AddBotsGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("addbots"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("abots"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("addbot"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("abot"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void AddBotsGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
RenX::TeamType team = RenX::getTeam(Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE));
|
|
|
|
Jupiter::StringS cmd;
|
|
switch (team)
|
|
{
|
|
case RenX::TeamType::GDI:
|
|
cmd = "addredbots ";
|
|
break;
|
|
case RenX::TeamType::Nod:
|
|
cmd = "addbluebots ";
|
|
break;
|
|
default:
|
|
case RenX::TeamType::None:
|
|
case RenX::TeamType::Other:
|
|
cmd = "addbots ";
|
|
break;
|
|
}
|
|
|
|
unsigned int amount;
|
|
if (parameters.isEmpty())
|
|
amount = 1;
|
|
else
|
|
amount = parameters.asUnsignedInt();
|
|
cmd += Jupiter::StringS::Format("%u", amount);
|
|
|
|
source->send(cmd);
|
|
source->sendMessage(player, Jupiter::StringS::Format("%u bots have been added to the server.", amount));
|
|
}
|
|
|
|
const Jupiter::ReadableString &AddBotsGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Adds bots to the game. Syntax: addbots [amount=1] [team]");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(AddBotsGameCommand)
|
|
|
|
// KillBots Game Command
|
|
|
|
void KillBotsGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("killbots"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("kbots"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rembots"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("rbots"));
|
|
this->setAccessLevel(2);
|
|
}
|
|
|
|
void KillBotsGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
source->send(STRING_LITERAL_AS_REFERENCE("killbots"));
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("All bots have been removed from the server."));
|
|
}
|
|
|
|
const Jupiter::ReadableString &KillBotsGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Removes all bots from the game. Syntax: killbots");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(KillBotsGameCommand)
|
|
|
|
// PhaseBots Game Command
|
|
|
|
void PhaseBotsGameCommand::create()
|
|
{
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("phasebots"));
|
|
this->addTrigger(STRING_LITERAL_AS_REFERENCE("pbots"));
|
|
this->setAccessLevel(1);
|
|
}
|
|
|
|
void PhaseBotsGameCommand::trigger(RenX::Server *source, RenX::PlayerInfo *player, const Jupiter::ReadableString ¶meters)
|
|
{
|
|
if (parameters.isEmpty())
|
|
{
|
|
if (togglePhasing(source))
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Bot phasing has been enabled."));
|
|
else source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Bot phasing has been disabled."));
|
|
}
|
|
else if (parameters.equalsi("true") || parameters.equalsi("on") || parameters.equalsi("start") || parameters.equalsi("1"))
|
|
{
|
|
togglePhasing(source, true);
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Bot phasing has been enabled."));
|
|
}
|
|
else
|
|
{
|
|
togglePhasing(source, false);
|
|
source->sendMessage(player, STRING_LITERAL_AS_REFERENCE("Bot phasing has been disabled."));
|
|
}
|
|
}
|
|
|
|
const Jupiter::ReadableString &PhaseBotsGameCommand::getHelp(const Jupiter::ReadableString &)
|
|
{
|
|
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Removes all bots from the game. Syntax: phasebots");
|
|
return defaultHelp;
|
|
}
|
|
|
|
GAME_COMMAND_INIT(PhaseBotsGameCommand)
|
|
|
|
extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
|
|
{
|
|
return &pluginInstance;
|
|
}
|
|
|