summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MCServer/Plugins/Debuggers/Debuggers.lua2
-rw-r--r--src/ClientHandle.cpp12
-rw-r--r--src/ClientHandle.h14
-rw-r--r--src/Protocol/Protocol17x.cpp13
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp2
-rw-r--r--src/Server.cpp7
-rw-r--r--src/Server.h8
-rw-r--r--src/StringUtils.cpp28
-rw-r--r--src/StringUtils.h5
9 files changed, 86 insertions, 5 deletions
diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua
index 0e7e647d5..66e06cb72 100644
--- a/MCServer/Plugins/Debuggers/Debuggers.lua
+++ b/MCServer/Plugins/Debuggers/Debuggers.lua
@@ -1502,7 +1502,7 @@ function OnPlayerJoined(a_Player)
-- Test composite chat chaining:
a_Player:SendMessage(cCompositeChat()
:AddTextPart("Hello, ")
- :AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2")
+ :AddUrlPart(a_Player:GetName(), "http://www.mc-server.org", "u@2")
:AddSuggestCommandPart(", and welcome.", "/help", "u")
:AddRunCommandPart(" SetDay", "/time set 0")
)
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 170498037..4a3a3c250 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -312,8 +312,16 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID,
ASSERT(m_Player == NULL);
m_Username = a_Name;
- m_UUID = a_UUID;
- m_Properties = a_Properties;
+
+ // Only assign UUID and properties if not already pre-assigned (BungeeCord sends those in the Handshake packet):
+ if (m_UUID.empty())
+ {
+ m_UUID = a_UUID;
+ }
+ if (m_Properties.empty())
+ {
+ m_Properties = a_Properties;
+ }
// Send login success (if the protocol supports it):
m_Protocol->SendLoginSuccess();
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 74e89deee..3d0995636 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -64,15 +64,27 @@ public:
const AString & GetIPString(void) const { return m_IPString; } // tolua_export
+ /** Sets the IP string that the client is using. Overrides the IP string that was read from the socket.
+ Used mainly by BungeeCord compatibility code. */
+ void SetIPString(const AString & a_IPString) { m_IPString = a_IPString; }
+
cPlayer * GetPlayer(void) { return m_Player; } // tolua_export
/** Returns the player's UUID, as used by the protocol, in the short form (no dashes) */
const AString & GetUUID(void) const { return m_UUID; } // tolua_export
- void SetUUID(const AString & a_UUID) { m_UUID = a_UUID; }
+ /** Sets the player's UUID, as used by the protocol. Short UUID form (no dashes) is expected.
+ Used mainly by BungeeCord compatibility code - when authenticating is done on the BungeeCord server
+ and the results are passed to MCS running in offline mode. */
+ void SetUUID(const AString & a_UUID) { ASSERT(a_UUID.size() == 32); m_UUID = a_UUID; }
const Json::Value & GetProperties(void) const { return m_Properties; }
+ /** Sets the player's properties, such as skin image and signature.
+ Used mainly by BungeeCord compatibility code - property querying is done on the BungeeCord server
+ and the results are passed to MCS running in offline mode. */
+ void SetProperties(const Json::Value & a_Properties) { m_Properties = a_Properties; }
+
/** Generates an UUID based on the username stored for this client, and stores it in the m_UUID member.
This is used for the offline (non-auth) mode, when there's no UUID source.
Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same.
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index f07f6a928..7d80e79fb 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -100,6 +100,19 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd
m_IsEncrypted(false),
m_LastSentDimension(dimNotSet)
{
+ // BungeeCord handling:
+ // If BC is setup with ip_forward == true, it sends additional data in the login packet's ServerAddress field:
+ // hostname\00ip-address\00uuid\00profile-properties-as-json
+ AStringVector Params;
+ if (cRoot::Get()->GetServer()->ShouldAllowBungeeCord() && SplitZeroTerminatedStrings(a_ServerAddress, Params) && (Params.size() == 4))
+ {
+ LOGD("Player at %s connected via BungeeCord", Params[1].c_str());
+ m_ServerAddress = Params[0];
+ m_Client->SetIPString(Params[1]);
+ m_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2]));
+ m_Client->SetProperties(Params[3]);
+ }
+
// Create the comm log file, if so requested:
if (g_ShouldLogCommIn || g_ShouldLogCommOut)
{
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp
index 8b395230a..d836291c3 100644
--- a/src/Protocol/ProtocolRecognizer.cpp
+++ b/src/Protocol/ProtocolRecognizer.cpp
@@ -27,7 +27,7 @@
cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) :
super(a_Client),
m_Protocol(NULL),
- m_Buffer(512)
+ m_Buffer(8192) // We need a larger buffer to support BungeeCord - it sends one huge packet at the start
{
}
diff --git a/src/Server.cpp b/src/Server.cpp
index 069e2a169..969ffd693 100644
--- a/src/Server.cpp
+++ b/src/Server.cpp
@@ -259,6 +259,13 @@ bool cServer::InitServer(cIniFile & a_SettingsIni)
m_ServerID = sid.str();
m_ServerID.resize(16, '0');
}
+
+ // Check if both BungeeCord and online mode are on, if so, warn the admin:
+ m_ShouldAllowBungeeCord = a_SettingsIni.GetValueSetB("Authentication", "AllowBungeeCord", false);
+ if (m_ShouldAllowBungeeCord && m_ShouldAuthenticate)
+ {
+ LOGWARNING("WARNING: BungeeCord is allowed and server set to online mode. This is unsafe and will not work properly. Disable either authentication or BungeeCord in settings.ini.");
+ }
m_ShouldLoadOfflinePlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadOfflinePlayerData", false);
m_ShouldLoadNamedPlayerData = a_SettingsIni.GetValueSetB("PlayerData", "LoadNamedPlayerData", true);
diff --git a/src/Server.h b/src/Server.h
index f20e6932f..6d659fa40 100644
--- a/src/Server.h
+++ b/src/Server.h
@@ -131,6 +131,11 @@ public: // tolua_export
Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */
bool ShouldLoadNamedPlayerData(void) const { return m_ShouldLoadNamedPlayerData; }
+ /** Returns true if BungeeCord logins (that specify the player's UUID) are allowed.
+ Read from settings, admins should set this to true only when they chain to BungeeCord,
+ it makes the server vulnerable to identity theft through direct connections. */
+ bool ShouldAllowBungeeCord(void) const { return m_ShouldAllowBungeeCord; }
+
private:
friend class cRoot; // so cRoot can create and destroy cServer
@@ -230,6 +235,9 @@ private:
This allows a seamless transition from name-based to UUID-based player storage.
Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */
bool m_ShouldLoadNamedPlayerData;
+
+ /** True if BungeeCord handshake packets (with player UUID) should be accepted. */
+ bool m_ShouldAllowBungeeCord;
cServer(void);
diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp
index 5f88cbf64..73147eebc 100644
--- a/src/StringUtils.cpp
+++ b/src/StringUtils.cpp
@@ -869,3 +869,31 @@ void SetBEInt(char * a_Mem, Int32 a_Value)
+
+bool SplitZeroTerminatedStrings(const AString & a_Strings, AStringVector & a_Output)
+{
+ a_Output.clear();
+ size_t size = a_Strings.size();
+ size_t start = 0;
+ bool res = false;
+ for (size_t i = 0; i < size; i++)
+ {
+ if (a_Strings[i] == 0)
+ {
+ a_Output.push_back(a_Strings.substr(start, i - start));
+ start = i + 1;
+ res = true;
+ }
+ }
+ if (start < size)
+ {
+ a_Output.push_back(a_Strings.substr(start, size - start));
+ res = true;
+ }
+
+ return res;
+}
+
+
+
+
diff --git a/src/StringUtils.h b/src/StringUtils.h
index 72a90a8c2..a76894d05 100644
--- a/src/StringUtils.h
+++ b/src/StringUtils.h
@@ -99,6 +99,11 @@ extern int GetBEInt(const char * a_Mem);
/// Writes four bytes to the specified memory location so that they interpret as BigEndian int
extern void SetBEInt(char * a_Mem, Int32 a_Value);
+/** Splits a string that has embedded \0 characters, on those characters.
+a_Output is first cleared and then each separate string is pushed back into a_Output.
+Returns true if there are at least two strings in a_Output (there was at least one \0 separator). */
+extern bool SplitZeroTerminatedStrings(const AString & a_Strings, AStringVector & a_Output);
+
/// Parses any integer type. Checks bounds and returns errors out of band.
template <class T>
bool StringToInteger(const AString & a_str, T & a_Num)