Browse Source

RenX.Core:

* Map rotation is now tracked.
* Changed more types from time_t
* Player data is now reset on "MAP Changing;" instead of "GAME MatchEnd;"
RenX.Commands:
* Added "Rotation", "Mutators", and "Map" IRC commands.
* "setmap" now takes partial map names.
RenX.HybridUUID: Corrected plugin name
RenX.NicknameUUID: Corrected plugin name
pull/3/head
JustinAJ 9 years ago
parent
commit
e30caeb947
  1. BIN
      Release/Plugins/RenX.Core.lib
  2. 145
      RenX.Commands/RenX_Commands.cpp
  3. 3
      RenX.Commands/RenX_Commands.h
  4. 73
      RenX.Core/RenX_Server.cpp
  5. 39
      RenX.Core/RenX_Server.h
  6. 2
      RenX.HybridUUID/RenX_HybridUUID.h
  7. 2
      RenX.NicknameUUID/RenX_NicknameUUID.h

BIN
Release/Plugins/RenX.Core.lib

Binary file not shown.

145
RenX.Commands/RenX_Commands.cpp

@ -716,12 +716,143 @@ void BuildingInfoIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableStr
const Jupiter::ReadableString &BuildingInfoIRCCommand::getHelp(const Jupiter::ReadableString &)
{
static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Gets information about a player. Syntax: PlayerInfo <Player>");
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 &parameters)
{
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 &parameters)
{
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
if (chan != nullptr)
{
const Jupiter::ReadableString *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().equalsi(*map))
list += STRING_LITERAL_AS_REFERENCE(" " IRCBOLD "[") + *server->maps.get(index) + STRING_LITERAL_AS_REFERENCE("]" IRCBOLD);
else
list += " "_jrs + *server->maps.get(index);
}
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 &parameters)
{
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;
source->sendMessage(channel, "Current Map: "_jrs + server->getMap());
}
}
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)
// Steam IRC Command
void SteamIRCCommand::create()
@ -1269,19 +1400,21 @@ void SetMapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &c
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
if (chan != nullptr)
{
const Jupiter::ReadableString *map_name = 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;
if (server->setMap(parameters) == false)
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Server does not support setmap."));
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 (match == false)
if (map_name == nullptr)
source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
}
}

3
RenX.Commands/RenX_Commands.h

@ -62,6 +62,9 @@ GENERIC_IRC_COMMAND(PlayersIRCCommand)
GENERIC_IRC_COMMAND(PlayerTableIRCCommand)
GENERIC_IRC_COMMAND(PlayerInfoIRCCommand)
GENERIC_IRC_COMMAND(BuildingInfoIRCCommand)
GENERIC_IRC_COMMAND(MutatorsIRCCommand)
GENERIC_IRC_COMMAND(RotationIRCCommand)
GENERIC_IRC_COMMAND(MapIRCCommand)
GENERIC_IRC_COMMAND(SteamIRCCommand)
GENERIC_IRC_COMMAND(KillDeathRatioIRCCommand)
GENERIC_IRC_COMMAND(ShowModsIRCCommand)

73
RenX.Core/RenX_Server.cpp

@ -37,7 +37,7 @@ int RenX::Server::think()
{
if (RenX::Server::maxAttempts < 0 || RenX::Server::attempts < RenX::Server::maxAttempts)
{
if (time(0) >= RenX::Server::lastAttempt + RenX::Server::delay)
if (std::chrono::steady_clock::now() >= RenX::Server::lastAttempt + RenX::Server::delay)
{
if (RenX::Server::connect())
RenX::Server::sendLogChan(IRCCOLOR "03[RenX]" IRCCOLOR " Socket successfully reconnected to Renegade-X server.");
@ -243,6 +243,28 @@ RenX::BuildingInfo *RenX::Server::getBuildingByName(const Jupiter::ReadableStrin
return nullptr;
}
bool RenX::Server::hasMapInRotation(const Jupiter::ReadableString &name) const
{
size_t index = RenX::Server::maps.size();
while (index != 0)
if (RenX::Server::maps.get(--index)->equalsi(name))
return true;
return false;
}
const Jupiter::ReadableString *RenX::Server::getMapName(const Jupiter::ReadableString &name) const
{
size_t index = RenX::Server::maps.size();
const Jupiter::ReadableString *map_name;
while (index != 0)
{
map_name = RenX::Server::maps.get(--index);
if (map_name->findi(name) != Jupiter::INVALID_INDEX)
return map_name;
}
return nullptr;
}
const Jupiter::ReadableString &RenX::Server::getCurrentRCONCommand() const
{
return RenX::Server::lastCommand;
@ -621,12 +643,12 @@ unsigned short RenX::Server::getSocketPort() const
return RenX::Server::sock.getPort();
}
time_t RenX::Server::getLastAttempt() const
std::chrono::steady_clock::time_point RenX::Server::getLastAttempt() const
{
return RenX::Server::lastAttempt;
}
time_t RenX::Server::getDelay() const
std::chrono::milliseconds RenX::Server::getDelay() const
{
return RenX::Server::delay;
}
@ -924,7 +946,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
}
}
};
auto onPostGameOver = [this](RenX::WinType winType, RenX::TeamType team, int gScore, int nScore)
auto onMapChange = [this]()
{
this->firstAction = false;
this->firstKill = false;
@ -1440,15 +1462,31 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
{
if (this->lastCommandParams.isEmpty())
{
// "Port" | Port | "Name" | Name | "Passworded" | "True"/"False" | "Level" | Level
// "Port" | Port | "Name" | Name | "Level" | Level | "Players" | Players | "Bots" | Bots
buff.shiftRight(1);
this->port = static_cast<unsigned short>(buff.getToken(1, RenX::DelimC).asUnsignedInt(10));
this->serverName = buff.getToken(3, RenX::DelimC);
this->passworded = buff.getToken(5, RenX::DelimC).asBool();
this->map = buff.getToken(7, RenX::DelimC);
this->map = buff.getToken(5, RenX::DelimC);
buff.shiftLeft(1);
}
}
else if (this->lastCommand.equalsi("gameinfo"_jrs))
{
// "PlayerLimit" | PlayerLimit | "VehicleLimit" | VehicleLimit | "MineLimit" | MineLimit | "TimeLimit" | TimeLimit | "bPassworded" | bPassworded | "bSteamRequired" | bSteamRequired | "bPrivateMessageTeamOnly" | bPrivateMessageTeamOnly | "bAllowPrivateMessaging" | bAllowPrivateMessaging | "bAutoBalanceTeams" | bAutoBalanceTeams | "bSpawnCrates" | bSpawnCrates | "CrateRespawnAfterPickup" | CrateRespawnAfterPickup
buff.shiftRight(1);
this->playerLimit = buff.getToken(1, RenX::DelimC).asInt();
this->vehicleLimit = buff.getToken(3, RenX::DelimC).asInt();
this->mineLimit = buff.getToken(5, RenX::DelimC).asInt();
this->timeLimit = buff.getToken(7, RenX::DelimC).asInt();
this->passworded = buff.getToken(9, RenX::DelimC).asBool();
this->steamRequired = buff.getToken(11, RenX::DelimC).asBool();
this->privateMessageTeamOnly = buff.getToken(13, RenX::DelimC).asBool();
this->allowPrivateMessaging = buff.getToken(15, RenX::DelimC).asBool();
this->autoBalanceTeams = buff.getToken(17, RenX::DelimC).asBool();
this->spawnCrates = buff.getToken(19, RenX::DelimC).asBool();
this->crateRespawnAfterPickup = buff.getToken(21, RenX::DelimC).asDouble();
buff.shiftLeft(1);
}
else if (this->lastCommand.equalsi("mutatorlist"_jrs))
{
// "The following mutators are loaded:" [ | Mutator [ | Mutator [ ... ] ] ]
@ -1466,6 +1504,14 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
}
buff.shiftLeft(1);
}
else if (this->lastCommand.equalsi("rotation"_jrs))
{
// Map
buff.shiftRight(1);
if (this->hasMapInRotation(buff) == false)
this->maps.add(new Jupiter::StringS(buff));
buff.shiftLeft(1);
}
else if (this->lastCommand.equalsi("changename"))
{
buff.shiftRight(1);
@ -1475,6 +1521,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnNameChange(this, player, newName);
player->name = newName;
buff.shiftLeft(1);
}
break;
case 'l':
@ -1939,7 +1986,6 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
onPreGameOver(winType, team, gScore, nScore);
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnGameOver(this, winType, team, gScore, nScore);
onPostGameOver(winType, team, gScore, nScore);
}
else if (winTieToken.equals("tie"))
{
@ -1947,7 +1993,6 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
int nScore = buff.getToken(5, RenX::DelimC).getToken(1, '=').asInt();
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnGameOver(this, RenX::WinType::Tie, RenX::TeamType::None, gScore, nScore);
onPostGameOver(WinType::Tie, RenX::TeamType::None, gScore, nScore);
}
}
else
@ -2365,6 +2410,7 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
for (size_t i = 0; i < xPlugins.size(); i++)
xPlugins.get(i)->RenX_OnMapChange(this, map, seamless);
this->map = map;
onMapChange();
}
else if (subHeader.equals("Loaded;"))
{
@ -2466,7 +2512,9 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
{
RenX::Server::sock.send("s\n"_jrs);
RenX::Server::send("serverinfo"_jrs);
RenX::Server::send("gameinfo"_jrs);
RenX::Server::send("mutatorlist"_jrs);
RenX::Server::send("rotation"_jrs);
RenX::Server::fetchClientList();
RenX::Server::updateBuildingList();
@ -2518,7 +2566,7 @@ void RenX::Server::disconnect(RenX::DisconnectReason reason)
bool RenX::Server::connect()
{
RenX::Server::lastAttempt = time(0);
RenX::Server::lastAttempt = std::chrono::steady_clock::now();
if (RenX::Server::sock.connect(RenX::Server::hostname.c_str(), RenX::Server::port, RenX::Server::clientHostname.isEmpty() ? nullptr : RenX::Server::clientHostname.c_str()))
{
RenX::Server::sock.setBlocking(false);
@ -2550,6 +2598,9 @@ void RenX::Server::wipeData()
xPlugins.get(index)->RenX_OnPlayerDelete(this, player);
delete player;
}
RenX::Server::buildings.emptyAndDelete();
RenX::Server::mutators.emptyAndDelete();
RenX::Server::maps.emptyAndDelete();
RenX::Server::awaitingPong = false;
RenX::Server::rconVersion = 0;
RenX::Server::rconUser.truncate(RenX::Server::rconUser.size());
@ -2603,7 +2654,7 @@ void RenX::Server::init()
RenX::Server::setPrefix(Jupiter::IRC::Client::Config->get(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("IRCPrefix")));
RenX::Server::rules = Jupiter::IRC::Client::Config->get(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("Rules"), STRING_LITERAL_AS_REFERENCE("Anarchy!"));
RenX::Server::delay = Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("ReconnectDelay"), 10);
RenX::Server::delay = std::chrono::milliseconds(Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("ReconnectDelay"), 10000));
RenX::Server::maxAttempts = Jupiter::IRC::Client::Config->getInt(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("MaxReconnectAttempts"), -1);
RenX::Server::rconBan = Jupiter::IRC::Client::Config->getBool(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("RCONBan"), false);
RenX::Server::localSteamBan = Jupiter::IRC::Client::Config->getBool(RenX::Server::configSection, STRING_LITERAL_AS_REFERENCE("LocalSteamBan"), true);

39
RenX.Core/RenX_Server.h

@ -85,6 +85,7 @@ namespace RenX
Jupiter::DLList<RenX::PlayerInfo> players; /** A list of players in the server */
Jupiter::ArrayList<RenX::BuildingInfo> buildings; /** A list of buildings in the server */
Jupiter::ArrayList<Jupiter::StringS> mutators; /** A list of buildings the server is running */
Jupiter::ArrayList<Jupiter::StringS> maps; /** A list of maps in the server's rotation */
Jupiter::INIFile varData; /** This may be replaced later with a more dedicated type. */
/**
@ -208,6 +209,22 @@ namespace RenX
*/
RenX::BuildingInfo *getBuildingByName(const Jupiter::ReadableString &name) const;
/**
* @brief Checks if a map name is in the rotation.
*
* @param name Name of map to search for
* @return True if the map exists, false otherwise.
*/
bool hasMapInRotation(const Jupiter::ReadableString &name) const;
/**
* @brief Searches for a map based on a part of its name.
*
* @param name Part of the map's name to search for
* @return A map's full name if it exists, nullptr otherwise.
*/
const Jupiter::ReadableString *getMapName(const Jupiter::ReadableString &name) const;
/**
* @brief Fetches the RCON command currently being processed.
*
@ -609,14 +626,14 @@ namespace RenX
*
* @return Time of the last connection attempt.
*/
time_t getLastAttempt() const;
std::chrono::steady_clock::time_point getLastAttempt() const;
/**
* @brief Fetches the time delay between connection attempts.
*
* @return Time delay between connection attempts.
*/
time_t getDelay() const;
std::chrono::milliseconds getDelay() const;
/**
* @brief Checks if the server has a game password.
@ -856,7 +873,6 @@ namespace RenX
bool pure = false;
bool connected = false;
bool seamless = false;
bool passworded = false;
bool needsCList = false;
bool silenceParts = false;
bool silenceJoins = false;
@ -865,9 +881,20 @@ namespace RenX
bool firstDeath = false;
bool firstAction = false;
bool awaitingPong = false;
unsigned int rconVersion = 0;
time_t lastAttempt = 0;
bool passworded = false;
bool steamRequired = false;
bool privateMessageTeamOnly = false;
bool allowPrivateMessaging = true;
bool autoBalanceTeams = true;
bool spawnCrates = true;
int attempts = 0;
int playerLimit = 0;
int vehicleLimit = 0;
int mineLimit = 0;
int timeLimit = 0;
unsigned int rconVersion = 0;
double crateRespawnAfterPickup = 0.0;
std::chrono::steady_clock::time_point lastAttempt = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point gameStart = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point lastClientListUpdate = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point lastBuildingListUpdate = std::chrono::steady_clock::now();
@ -881,8 +908,8 @@ namespace RenX
unsigned short port;
int logChanType;
int adminLogChanType;
time_t delay;
int maxAttempts;
std::chrono::milliseconds delay;
std::chrono::milliseconds clientUpdateRate;
std::chrono::milliseconds buildingUpdateRate;
std::chrono::milliseconds pingRate;

2
RenX.HybridUUID/RenX_HybridUUID.h

@ -34,7 +34,7 @@ public: // Jupiter::Plugin
~RenX_HybridUUIDPlugin();
private:
STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX_TemplatePlugin");
STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.HybridUUID");
};
#endif // _RENX_HYBRIDUUID_H_HEADER

2
RenX.NicknameUUID/RenX_NicknameUUID.h

@ -34,7 +34,7 @@ public: // Jupiter::Plugin
~RenX_NicknameUUIDPlugin();
private:
STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX_TemplatePlugin");
STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.NicknameUUID");
};
#endif // _RENX_NICKNAMEUUID_H_HEADER
Loading…
Cancel
Save