diff --git a/Release/Plugins/RenX.Core.lib b/Release/Plugins/RenX.Core.lib
index 1d8d80e..c94365f 100644
Binary files a/Release/Plugins/RenX.Core.lib and b/Release/Plugins/RenX.Core.lib differ
diff --git a/RenX.Commands/RenX_Commands.cpp b/RenX.Commands/RenX_Commands.cpp
index bce56cf..44fdd35 100644
--- a/RenX.Commands/RenX_Commands.cpp
+++ b/RenX.Commands/RenX_Commands.cpp
@@ -781,7 +781,7 @@ void RotationIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString
Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
if (chan != nullptr)
{
- const Jupiter::ReadableString *map;
+ const RenX::Map *map;
int type = chan->getType();
Jupiter::String list;
size_t index = 0;
@@ -794,10 +794,10 @@ void RotationIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString
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);
+ 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);
+ list += " "_jrs + server->maps.get(index)->name;
}
if (index == 0)
source->sendMessage(channel, "No maps in rotation"_jrs);
@@ -838,7 +838,8 @@ void MapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &chan
if (server->isLogChanType(type))
{
match = true;
- source->sendMessage(channel, "Current Map: "_jrs + server->getMap());
+ const RenX::Map &map = server->getMap();
+ source->sendMessage(channel, "Current Map: "_jrs + map.name + "; GUID: "_jrs + RenX::formatGUID(map));
}
}
if (match == false)
diff --git a/RenX.Core/RenX.Core.vcxproj b/RenX.Core/RenX.Core.vcxproj
index d0ebcb1..db0db01 100644
--- a/RenX.Core/RenX.Core.vcxproj
+++ b/RenX.Core/RenX.Core.vcxproj
@@ -76,6 +76,7 @@
+
@@ -86,6 +87,7 @@
+
diff --git a/RenX.Core/RenX.Core.vcxproj.filters b/RenX.Core/RenX.Core.vcxproj.filters
index 09f1e2b..1c2ec70 100644
--- a/RenX.Core/RenX.Core.vcxproj.filters
+++ b/RenX.Core/RenX.Core.vcxproj.filters
@@ -53,6 +53,9 @@
Header Files
+
+ Header Files
+
@@ -76,5 +79,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/RenX.Core/RenX_Functions.cpp b/RenX.Core/RenX_Functions.cpp
index af09fde..2ae9db5 100644
--- a/RenX.Core/RenX_Functions.cpp
+++ b/RenX.Core/RenX_Functions.cpp
@@ -862,6 +862,11 @@ Jupiter::String RenX::getFormattedPlayerName(const RenX::PlayerInfo *player)
return r;
}
+Jupiter::StringS RenX::formatGUID(const RenX::Map &map)
+{
+ return Jupiter::StringS::Format("%.8llX%.8llX", map.guid[0], map.guid[1]);
+}
+
void RenX::sanitizeString(Jupiter::StringType &str)
{
if (str.isNotEmpty())
diff --git a/RenX.Core/RenX_Functions.h b/RenX.Core/RenX_Functions.h
index 9a4954d..24b807c 100644
--- a/RenX.Core/RenX_Functions.h
+++ b/RenX.Core/RenX_Functions.h
@@ -28,6 +28,7 @@
#include "Jupiter/INIFile.h"
#include "Jupiter/String.h"
#include "RenX.h"
+#include "RenX_Map.h"
namespace RenX
{
@@ -136,6 +137,14 @@ namespace RenX
*/
RENX_API Jupiter::String getFormattedPlayerName(const RenX::PlayerInfo *player);
+ /**
+ * @brief Creates a string containing a human-readable version of a map's GUID
+ *
+ * @param map Map containing the GUID to interpret
+ * @return Human-readable map GUID
+ */
+ RENX_API Jupiter::StringS formatGUID(const RenX::Map &map);
+
/**
* @brief Sanitizes a string into a RCON-ready state by replacing special
* characters with HTML-style character codes.
diff --git a/RenX.Core/RenX_Map.cpp b/RenX.Core/RenX_Map.cpp
new file mode 100644
index 0000000..67bc89a
--- /dev/null
+++ b/RenX.Core/RenX_Map.cpp
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 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
+ */
+
+#include "RenX_Map.h"
+
+RenX::Map::Map()
+{
+ RenX::Map::Map::guid[0] = 0ULL;
+ RenX::Map::Map::guid[1] = 0ULL;
+}
+
+RenX::Map::Map(const Jupiter::ReadableString &in_name) : Map()
+{
+ name = in_name;
+}
+
+RenX::Map::Map(const Jupiter::ReadableString &in_name, uint64_t in_guid[2]) : Map(in_name)
+{
+ RenX::Map::Map::guid[0] = in_guid[0];
+ RenX::Map::Map::guid[1] = in_guid[1];
+}
+
+bool RenX::Map::equals(const RenX::Map &map) const
+{
+ return RenX::Map::Map::guid[0] == map.guid[0] && RenX::Map::Map::guid[1] == map.guid[1];
+}
\ No newline at end of file
diff --git a/RenX.Core/RenX_Map.h b/RenX.Core/RenX_Map.h
new file mode 100644
index 0000000..1d80f12
--- /dev/null
+++ b/RenX.Core/RenX_Map.h
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 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
+ */
+
+#if !defined _RENX_MAP_H_HEADER
+#define _RENX_MAP_H_HEADER
+
+/**
+ * @file RenX_Map.h
+ * @brief Defines the RenX Map class
+ */
+
+#include "Jupiter/String.h"
+#include "RenX.h"
+
+/** DLL Linkage Nagging */
+#if defined _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+
+namespace RenX
+{
+ struct RENX_API Map
+ {
+ uint64_t guid[2];
+ Jupiter::StringS name;
+
+ bool equals(const RenX::Map &map) const;
+
+ Map();
+ Map(const Jupiter::ReadableString &in_name);
+ Map(const Jupiter::ReadableString &in_name, uint64_t in_guid[2]);
+ };
+}
+
+
+/** Re-enable warnings */
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // _RENX_MAP_H_HEADER
\ No newline at end of file
diff --git a/RenX.Core/RenX_Server.cpp b/RenX.Core/RenX_Server.cpp
index ae074e7..5da41b2 100644
--- a/RenX.Core/RenX_Server.cpp
+++ b/RenX.Core/RenX_Server.cpp
@@ -238,7 +238,7 @@ 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))
+ if (RenX::Server::maps.get(--index)->name.equalsi(name))
return true;
return false;
}
@@ -249,7 +249,7 @@ const Jupiter::ReadableString *RenX::Server::getMapName(const Jupiter::ReadableS
const Jupiter::ReadableString *map_name;
while (index != 0)
{
- map_name = RenX::Server::maps.get(--index);
+ map_name = &RenX::Server::maps.get(--index)->name;
if (map_name->findi(name) != Jupiter::INVALID_INDEX)
return map_name;
}
@@ -837,7 +837,7 @@ const Jupiter::ReadableString &RenX::Server::getName() const
return RenX::Server::serverName;
}
-const Jupiter::ReadableString &RenX::Server::getMap() const
+const RenX::Map &RenX::Server::getMap() const
{
return RenX::Server::map;
}
@@ -1599,15 +1599,32 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
else if (this->lastCommand.equalsi("ping"))
RenX::Server::awaitingPong = false;
else if (this->lastCommand.equalsi("map"))
- this->map = std::move(Jupiter::StringS::substring(line, 1));
+ {
+ // Map | Guid
+ this->map.name = tokens.getToken(0);
+ const Jupiter::ReferenceString guid_token = tokens.getToken(1);
+
+ if (guid_token.size() == 32U)
+ {
+ this->map.guid[0] = guid_token.substring(0U, 16U).asUnsignedLongLong(16);
+ this->map.guid[1] = guid_token.substring(16U).asUnsignedLongLong(16);
+ }
+ }
else if (this->lastCommand.equalsi("serverinfo"))
{
if (this->lastCommandParams.isEmpty())
{
- // "Port" | Port | "Name" | Name | "Level" | Level | "Players" | Players | "Bots" | Bots
+ // "Port" | Port | "Name" | Name | "Level" | Level | "Players" | Players | "Bots" | Bots | "LevelGUID" | Level GUID
this->port = static_cast(tokens.getToken(1).asUnsignedInt(10));
this->serverName = tokens.getToken(3);
- this->map = tokens.getToken(5);
+ this->map.name = tokens.getToken(5);
+
+ const Jupiter::ReferenceString guid_token = tokens.getToken(11);
+ if (guid_token.size() == 32U)
+ {
+ this->map.guid[0] = guid_token.substring(0U, 16U).asUnsignedLongLong(16);
+ this->map.guid[1] = guid_token.substring(16U).asUnsignedLongLong(16);
+ }
}
}
else if (this->lastCommand.equalsi("gameinfo"_jrs))
@@ -1647,10 +1664,22 @@ void RenX::Server::processLine(const Jupiter::ReadableString &line)
}
else if (this->lastCommand.equalsi("rotation"_jrs))
{
- // Map
- Jupiter::ReferenceString in_map = Jupiter::ReferenceString::substring(line, 1);
+ // Map | Guid
+ const Jupiter::ReadableString &in_map = tokens.getToken(0);
if (this->hasMapInRotation(in_map) == false)
- this->maps.add(new Jupiter::StringS(in_map));
+ {
+ const Jupiter::ReferenceString guid_token = tokens.getToken(1);
+
+ if (guid_token.size() == 32U)
+ {
+ RenX::Map *map = new RenX::Map(in_map);
+ map->guid[0] = guid_token.substring(0U, 16U).asUnsignedLongLong(16);
+ map->guid[1] = guid_token.substring(16U).asUnsignedLongLong(16);
+ this->maps.add(map);
+ }
+ else
+ this->maps.add(new RenX::Map(in_map));
+ }
}
else if (this->lastCommand.equalsi("changename"))
{
diff --git a/RenX.Core/RenX_Server.h b/RenX.Core/RenX_Server.h
index 4fa2ebc..10519fd 100644
--- a/RenX.Core/RenX_Server.h
+++ b/RenX.Core/RenX_Server.h
@@ -35,6 +35,7 @@
#include "Jupiter/Thinker.h"
#include "Jupiter/Rehash.h"
#include "RenX.h"
+#include "RenX_Map.h"
/** DLL Linkage Nagging */
#if defined _MSC_VER
@@ -86,7 +87,7 @@ namespace RenX
Jupiter::DLList players; /** A list of players in the server */
Jupiter::ArrayList buildings; /** A list of buildings in the server */
Jupiter::ArrayList mutators; /** A list of buildings the server is running */
- Jupiter::ArrayList maps; /** A list of maps in the server's rotation */
+ Jupiter::ArrayList maps; /** A list of maps in the server's rotation */
Jupiter::INIFile varData; /** This may be replaced later with a more dedicated type. */
/**
@@ -705,7 +706,7 @@ namespace RenX
*
* @return String containing the current map.
*/
- const Jupiter::ReadableString &getMap() const;
+ const RenX::Map &getMap() const;
/**
* @brief Fetches a command from the list.
@@ -949,9 +950,9 @@ namespace RenX
Jupiter::StringS rconUser;
Jupiter::StringS gameVersion;
Jupiter::StringS serverName;
- Jupiter::StringS map;
Jupiter::StringS lastCommand;
Jupiter::StringS lastCommandParams;
+ RenX::Map map;
Jupiter::TCPSocket sock;
Jupiter::ReadableString::TokenizeResult commandListFormat;
Jupiter::ArrayList commands;
diff --git a/RenX.Core/RenX_Tags.cpp b/RenX.Core/RenX_Tags.cpp
index e6c4c7e..d0a3e88 100644
--- a/RenX.Core/RenX_Tags.cpp
+++ b/RenX.Core/RenX_Tags.cpp
@@ -76,6 +76,7 @@ TagsImp::TagsImp()
this->INTERNAL_USER_TAG = this->getUniqueInternalTag();
this->INTERNAL_SERVER_NAME_TAG = this->getUniqueInternalTag();
this->INTERNAL_MAP_TAG = this->getUniqueInternalTag();
+ this->INTERNAL_MAP_GUID_TAG = this->getUniqueInternalTag();
this->INTERNAL_SERVER_HOSTNAME_TAG = this->getUniqueInternalTag();
this->INTERNAL_SERVER_PORT_TAG = this->getUniqueInternalTag();
this->INTERNAL_SOCKET_HOSTNAME_TAG = this->getUniqueInternalTag();
@@ -186,6 +187,7 @@ TagsImp::TagsImp()
this->userTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("UserTag"), STRING_LITERAL_AS_REFERENCE("{USER}"));
this->serverNameTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("ServerNameTag"), STRING_LITERAL_AS_REFERENCE("{SERVERNAME}"));
this->mapTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("MapTag"), STRING_LITERAL_AS_REFERENCE("{MAP}"));
+ this->mapGUIDTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("MapGUIDTag"), STRING_LITERAL_AS_REFERENCE("{MGUID}"));
this->serverHostnameTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("ServerHostnameTag"), STRING_LITERAL_AS_REFERENCE("{SERVERHOST}"));
this->serverPortTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("ServerPortTag"), STRING_LITERAL_AS_REFERENCE("{SERVERPORT}"));
this->socketHostnameTag = Jupiter::IRC::Client::Config->get(configSection, STRING_LITERAL_AS_REFERENCE("SocketHostnameTag"), STRING_LITERAL_AS_REFERENCE("{SOCKHOST}"));
@@ -336,7 +338,8 @@ void TagsImp::processTags(Jupiter::StringType &msg, const RenX::Server *server,
PROCESS_TAG(this->INTERNAL_RULES_TAG, server->getRules());
PROCESS_TAG(this->INTERNAL_USER_TAG, server->getUser());
PROCESS_TAG(this->INTERNAL_SERVER_NAME_TAG, server->getName());
- PROCESS_TAG(this->INTERNAL_MAP_TAG, server->getMap());
+ PROCESS_TAG(this->INTERNAL_MAP_TAG, server->getMap().name);
+ PROCESS_TAG(this->INTERNAL_MAP_GUID_TAG, RenX::formatGUID(server->getMap()));
PROCESS_TAG(this->INTERNAL_SERVER_HOSTNAME_TAG, server->getHostname());
PROCESS_TAG(this->INTERNAL_SERVER_PORT_TAG, Jupiter::StringS::Format("%u", server->getPort()));
PROCESS_TAG(this->INTERNAL_SOCKET_HOSTNAME_TAG, server->getSocketHostname());
@@ -454,6 +457,7 @@ void TagsImp::sanitizeTags(Jupiter::StringType &fmt)
fmt.replace(this->userTag, this->INTERNAL_USER_TAG);
fmt.replace(this->serverNameTag, this->INTERNAL_SERVER_NAME_TAG);
fmt.replace(this->mapTag, this->INTERNAL_MAP_TAG);
+ fmt.replace(this->mapGUIDTag, this->INTERNAL_MAP_GUID_TAG);
fmt.replace(this->serverHostnameTag, this->INTERNAL_SERVER_HOSTNAME_TAG);
fmt.replace(this->serverPortTag, this->INTERNAL_SERVER_PORT_TAG);
fmt.replace(this->socketHostnameTag, this->INTERNAL_SOCKET_HOSTNAME_TAG);
diff --git a/RenX.Core/RenX_Tags.h b/RenX.Core/RenX_Tags.h
index 9c56377..37bcded 100644
--- a/RenX.Core/RenX_Tags.h
+++ b/RenX.Core/RenX_Tags.h
@@ -61,6 +61,7 @@ namespace RenX
Jupiter::StringS INTERNAL_USER_TAG;
Jupiter::StringS INTERNAL_SERVER_NAME_TAG;
Jupiter::StringS INTERNAL_MAP_TAG;
+ Jupiter::StringS INTERNAL_MAP_GUID_TAG;
Jupiter::StringS INTERNAL_SERVER_HOSTNAME_TAG;
Jupiter::StringS INTERNAL_SERVER_PORT_TAG;
Jupiter::StringS INTERNAL_SOCKET_HOSTNAME_TAG;
@@ -171,6 +172,7 @@ namespace RenX
Jupiter::StringS userTag;
Jupiter::StringS serverNameTag;
Jupiter::StringS mapTag;
+ Jupiter::StringS mapGUIDTag;
Jupiter::StringS serverHostnameTag;
Jupiter::StringS serverPortTag;
Jupiter::StringS socketHostnameTag;