Add cUUID class (#3871)
This commit is contained in:
parent
86d52c3e17
commit
f4f2fc7c3d
@ -1463,7 +1463,7 @@ end
|
||||
{
|
||||
{
|
||||
Name = "UUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
@ -1472,7 +1472,7 @@ end
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false.",
|
||||
Notes = "Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes).",
|
||||
},
|
||||
Kick =
|
||||
{
|
||||
@ -8485,10 +8485,9 @@ a_Player:OpenWindow(Window);
|
||||
<p>
|
||||
All the functions are static, call them using the <code>cMojangAPI:Function()</code> convention.</p>
|
||||
<p>
|
||||
Mojang uses two formats for UUIDs, short and dashed. Cuberite works with short UUIDs internally, but
|
||||
will convert to dashed UUIDs where needed - in the protocol login for example. The MakeUUIDShort()
|
||||
and MakeUUIDDashed() functions are provided for plugins to use for conversion between the two
|
||||
formats.</p>
|
||||
Mojang uses two formats for UUIDs, short and dashed. Cuberite will accept either format for any
|
||||
functions taking a UUID. The MakeUUIDShort() and MakeUUIDDashed() functions are provided for plugins
|
||||
to use for conversion between the two formats.</p>
|
||||
<p>
|
||||
This class will cache values returned by the API service. The cache will hold the values for 7 days
|
||||
by default, after that, they will no longer be available. This is in order to not let the server get
|
||||
@ -8509,10 +8508,10 @@ a_Player:OpenWindow(Window);
|
||||
},
|
||||
{
|
||||
Name = "UUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Notes = "Adds the specified PlayerName-to-UUID mapping into the cache, with current timestamp. Accepts both short or dashed UUIDs. ",
|
||||
Notes = "Adds the specified PlayerName-to-UUID mapping into the cache, with current timestamp.",
|
||||
},
|
||||
GetPlayerNameFromUUID =
|
||||
{
|
||||
@ -8521,7 +8520,7 @@ a_Player:OpenWindow(Window);
|
||||
{
|
||||
{
|
||||
Name = "UUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
{
|
||||
Name = "UseOnlyCached",
|
||||
@ -8592,7 +8591,7 @@ a_Player:OpenWindow(Window);
|
||||
{
|
||||
{
|
||||
Name = "UUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
@ -8602,7 +8601,7 @@ a_Player:OpenWindow(Window);
|
||||
Type = "string",
|
||||
},
|
||||
},
|
||||
Notes = "Converts the UUID to a dashed format (\"01234567-8901-2345-6789-012345678901\"). Accepts both dashed or short UUIDs. Logs a warning and returns an empty string if UUID format not recognized.",
|
||||
Notes = "Converts the UUID to a dashed format (\"01234567-8901-2345-6789-012345678901\"). An alias for cUUID:ToLongString()",
|
||||
},
|
||||
MakeUUIDShort =
|
||||
{
|
||||
@ -8611,7 +8610,7 @@ a_Player:OpenWindow(Window);
|
||||
{
|
||||
{
|
||||
Name = "UUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
@ -8621,7 +8620,7 @@ a_Player:OpenWindow(Window);
|
||||
Type = "string",
|
||||
},
|
||||
},
|
||||
Notes = "Converts the UUID to a short format (without dashes, \"01234567890123456789012345678901\"). Accepts both dashed or short UUIDs. Logs a warning and returns an empty string if UUID format not recognized.",
|
||||
Notes = "Converts the UUID to a short format (without dashes, \"01234567890123456789012345678901\"). An alias for cUUID:ToShortString()",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -11181,7 +11180,7 @@ a_Player:OpenWindow(Window);
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
{
|
||||
Name = "CallbackFunction",
|
||||
@ -12441,6 +12440,135 @@ end
|
||||
},
|
||||
},
|
||||
},
|
||||
cUUID =
|
||||
{
|
||||
Desc = [[
|
||||
Class representing a Universally Unique Identifier.
|
||||
Note that all Cuberite's API functions that take a cUUID parameter will also
|
||||
accept a string in its place, as long as that string can be converted to a cUUID
|
||||
(using the {{#FromString_1|cUUID:FromString}} function).
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
constructor =
|
||||
{
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Notes = "Constructs a nil-valued UUID (all zeros)",
|
||||
},
|
||||
Compare =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Other",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Notes = [[
|
||||
Compares this UUID with the specified Other UUID, Returns:
|
||||
0 when equal to Other,
|
||||
< 0 when less than Other,
|
||||
> 0 when greater than Other
|
||||
]],
|
||||
},
|
||||
IsNil =
|
||||
{
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if this contains the \"nil\" UUID with all bits set to 0",
|
||||
},
|
||||
FromString =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "StringUUID",
|
||||
Type = "string",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Tries to interpret the string as a short or long form UUID and assign from it. On error, returns false and does not set the value.",
|
||||
},
|
||||
ToShortString =
|
||||
{
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "string",
|
||||
},
|
||||
},
|
||||
Notes = "Converts the UUID to a short form string (i.e without dashes).",
|
||||
},
|
||||
ToLongString =
|
||||
{
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "string",
|
||||
},
|
||||
},
|
||||
Notes = "Converts the UUID to a long form string (i.e with dashes).",
|
||||
},
|
||||
Version =
|
||||
{
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Notes = "Returns the version number of the UUID.",
|
||||
},
|
||||
Variant =
|
||||
{
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Notes = "Returns the variant number of the UUID",
|
||||
},
|
||||
GenerateVersion3 =
|
||||
{
|
||||
IsStatic = true,
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Name",
|
||||
Type = "string",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Notes = "Generates a version 3, variant 1 UUID based on the md5 hash of Name."
|
||||
},
|
||||
},
|
||||
},
|
||||
cWebPlugin =
|
||||
{
|
||||
Desc = "",
|
||||
|
@ -258,7 +258,7 @@ return
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
@ -276,7 +276,7 @@ return
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
@ -303,7 +303,7 @@ return
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
@ -322,7 +322,7 @@ return
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
@ -340,7 +340,7 @@ return
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
@ -502,7 +502,7 @@ return
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
@ -604,7 +604,7 @@ return
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
},
|
||||
Notes = "Removes the player's rank; the player's left without a rank. Note that this doesn't change the {{cPlayer}} instances for the already connected players, you need to update all the instances manually. No action if the player has no rank assigned to them already.",
|
||||
@ -699,7 +699,7 @@ return
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
{
|
||||
Name = "PlayerName",
|
||||
|
@ -18,7 +18,7 @@ return
|
||||
Each world runs several separate threads used for various housekeeping purposes, the most important
|
||||
of those is the Tick thread. This thread updates the game logic 20 times per second, and it is
|
||||
the thread where all the gameplay actions are evaluated. Liquid physics, entity interactions,
|
||||
player ovement etc., all are applied in this thread.</p>
|
||||
player movement etc., all are applied in this thread.</p>
|
||||
<p>
|
||||
Additional threads include the generation thread (generates new chunks as needed, storage thread
|
||||
(saves and loads chunk from the disk), lighting thread (updates block light values) and the
|
||||
@ -901,7 +901,7 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
|
||||
{
|
||||
{
|
||||
Name = "PlayerUUID",
|
||||
Type = "string",
|
||||
Type = "cUUID",
|
||||
},
|
||||
{
|
||||
Name = "CallbackFunction",
|
||||
|
@ -29,6 +29,7 @@ set_exe_flags()
|
||||
set(SHARED_SRC
|
||||
../../src/ByteBuffer.cpp
|
||||
../../src/StringUtils.cpp
|
||||
../../src/UUID.cpp
|
||||
../../src/PolarSSL++/AesCfb128Decryptor.cpp
|
||||
../../src/PolarSSL++/AesCfb128Encryptor.cpp
|
||||
../../src/PolarSSL++/CryptoKey.cpp
|
||||
@ -41,6 +42,7 @@ set(SHARED_SRC
|
||||
set(SHARED_HDR
|
||||
../../src/ByteBuffer.h
|
||||
../../src/StringUtils.h
|
||||
../../src/UUID.h
|
||||
../../src/PolarSSL++/AesCfb128Decryptor.h
|
||||
../../src/PolarSSL++/AesCfb128Encryptor.h
|
||||
../../src/PolarSSL++/CryptoKey.h
|
||||
|
@ -17,13 +17,15 @@ inheritance doesn't work properly (#1789).
|
||||
$#include "../Globals.h"
|
||||
|
||||
// Typedefs from Globals.h, so that we don't have to process that file:
|
||||
typedef long long Int64;
|
||||
typedef int Int32;
|
||||
typedef short Int16;
|
||||
typedef signed long long Int64;
|
||||
typedef signed int Int32;
|
||||
typedef signed short Int16;
|
||||
typedef signed char Int8;
|
||||
|
||||
typedef unsigned long long UInt64;
|
||||
typedef unsigned int UInt32;
|
||||
typedef unsigned short UInt16;
|
||||
typedef unsigned char UInt8;
|
||||
|
||||
|
||||
$cfile "../Vector3.h"
|
||||
@ -69,6 +71,7 @@ $cfile "../MapManager.h"
|
||||
$cfile "../Scoreboard.h"
|
||||
$cfile "../Statistics.h"
|
||||
$cfile "../Protocol/MojangAPI.h"
|
||||
$cfile "../UUID.h"
|
||||
|
||||
// Entities:
|
||||
$cfile "../Entities/Entity.h"
|
||||
|
@ -139,6 +139,7 @@ set(BINDING_DEPENDENCIES
|
||||
../StringUtils.h
|
||||
../Tracer.h
|
||||
../UI/Window.h
|
||||
../UUID.h
|
||||
../Vector3.h
|
||||
../WebAdmin.h
|
||||
../World.h
|
||||
|
@ -20,6 +20,7 @@ extern "C"
|
||||
#include "../Entities/Entity.h"
|
||||
#include "../BlockEntities/BlockEntity.h"
|
||||
#include "../DeadlockDetect.h"
|
||||
#include "../UUID.h"
|
||||
|
||||
|
||||
|
||||
@ -1410,6 +1411,40 @@ bool cLuaState::GetStackValue(int a_StackPos, float & a_ReturnedVal)
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, cUUID & a_Value)
|
||||
{
|
||||
if (lua_isnil(m_LuaState, a_StackPos))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tolua_Error tolua_Err;
|
||||
if (tolua_isusertype(m_LuaState, a_StackPos, "cUUID", 0, &tolua_Err))
|
||||
{
|
||||
// Found a cUUID, copy into output value
|
||||
cUUID * PtrUUID = nullptr;
|
||||
GetStackValue(a_StackPos, PtrUUID);
|
||||
if (PtrUUID == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
a_Value = *PtrUUID;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to get a string and parse as a UUID into the output
|
||||
AString StrUUID;
|
||||
if (!GetStackValue(a_StackPos, StrUUID))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return a_Value.FromString(StrUUID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cLuaState::cStackValue cLuaState::WalkToValue(const AString & a_Name)
|
||||
{
|
||||
// There needs to be at least one value on the stack:
|
||||
@ -1785,6 +1820,47 @@ bool cLuaState::CheckParamFunctionOrNil(int a_StartParam, int a_EndParam)
|
||||
|
||||
|
||||
|
||||
bool cLuaState::CheckParamUUID(int a_StartParam, int a_EndParam)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
|
||||
if (a_EndParam < 0)
|
||||
{
|
||||
a_EndParam = a_StartParam;
|
||||
}
|
||||
|
||||
cUUID tempUUID;
|
||||
AString tempStr;
|
||||
// Accept either a cUUID or a string that contains a valid UUID
|
||||
for (int i = a_StartParam; i <= a_EndParam; ++i)
|
||||
{
|
||||
tolua_Error err;
|
||||
if (tolua_isusertype(m_LuaState, i, "cUUID", 0, &err) && !lua_isnil(m_LuaState, i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!tolua_iscppstring(m_LuaState, i, 0, &err))
|
||||
{
|
||||
ApiParamError("Failed to read parameter #%d. UUID expected, got %s", i, GetTypeText(i).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check string is a valid UUID
|
||||
GetStackValue(i, tempStr);
|
||||
if (!tempUUID.FromString(tempStr))
|
||||
{
|
||||
ApiParamError("Failed to read parameter #%d. UUID expected, got non-UUID string:\n\t\"%s\"", i, tempStr.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::CheckParamEnd(int a_Param)
|
||||
{
|
||||
tolua_Error tolua_err;
|
||||
|
@ -659,6 +659,7 @@ public:
|
||||
bool GetStackValue(int a_StackPos, eBlockFace & a_Value);
|
||||
bool GetStackValue(int a_StackPos, eWeather & a_Value);
|
||||
bool GetStackValue(int a_StackPos, float & a_ReturnedVal);
|
||||
bool GetStackValue(int a_StackPos, cUUID & a_Value);
|
||||
|
||||
// template to catch all of the various c++ integral types without overload conflicts
|
||||
template <class T>
|
||||
@ -787,6 +788,10 @@ public:
|
||||
/** Returns true if the specified parameters on the stack are functions or nils; also logs warning if not */
|
||||
bool CheckParamFunctionOrNil(int a_StartParam, int a_EndParam = -1);
|
||||
|
||||
/** Returns true if the specified parameters on the stack are UUIDs; also logs warning if not
|
||||
Accepts either cUUID instances or strings that contain UUIDs */
|
||||
bool CheckParamUUID(int a_StartParam, int a_EndParam = -1);
|
||||
|
||||
/** Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters) */
|
||||
bool CheckParamEnd(int a_Param);
|
||||
|
||||
|
@ -1665,6 +1665,28 @@ static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlayer_GetUUID(lua_State * tolua_S)
|
||||
{
|
||||
// Check the params:
|
||||
cLuaState L(tolua_S);
|
||||
if (!L.CheckParamSelf("cPlayer"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
cPlayer * Self = nullptr;
|
||||
L.GetStackValue(1, Self);
|
||||
|
||||
// Return the UUID as a string
|
||||
L.Push(Self->GetUUID().ToShortString());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <
|
||||
class OBJTYPE,
|
||||
void (OBJTYPE::*SetCallback)(cLuaState::cCallbackPtr && a_CallbackFn)
|
||||
@ -2318,7 +2340,7 @@ static int tolua_cClientHandle_SendPluginMessage(lua_State * L)
|
||||
{
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserType(1, "cClientHandle") ||
|
||||
!S.CheckParamSelf("cClientHandle") ||
|
||||
!S.CheckParamString(2, 3) ||
|
||||
!S.CheckParamEnd(4)
|
||||
)
|
||||
@ -2343,13 +2365,145 @@ static int tolua_cClientHandle_SendPluginMessage(lua_State * L)
|
||||
|
||||
|
||||
|
||||
static int tolua_cClientHandle_GetUUID(lua_State * tolua_S)
|
||||
{
|
||||
// Check the params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamSelf("cClientHandle") ||
|
||||
!L.CheckParamEnd(2)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
cClientHandle * Self;
|
||||
L.GetStackValue(1, Self);
|
||||
|
||||
// Return the UUID as a string:
|
||||
L.Push(Self->GetUUID().ToShortString());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cClientHandle_GenerateOfflineUUID(lua_State * tolua_S)
|
||||
{
|
||||
// Check the params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamStaticSelf("cClientHandle") ||
|
||||
!L.CheckParamString(2) ||
|
||||
!L.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString Username;
|
||||
L.GetStackValue(2, Username);
|
||||
|
||||
// Return the UUID as a string:
|
||||
L.Push(cClientHandle::GenerateOfflineUUID(Username).ToShortString());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cClientHandle_IsUUIDOnline(lua_State * tolua_S)
|
||||
{
|
||||
// Check the params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamStaticSelf("cClientHandle") ||
|
||||
!L.CheckParamUUID(2) ||
|
||||
!L.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
cUUID UUID;
|
||||
L.GetStackValue(2, UUID);
|
||||
|
||||
// Return the result:
|
||||
L.Push(cClientHandle::IsUUIDOnline(UUID));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cMobHeadEntity_SetOwner(lua_State * tolua_S)
|
||||
{
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamSelf("cMobHeadEntity") ||
|
||||
!L.CheckParamUUID(2) ||
|
||||
!L.CheckParamString(3, 5) ||
|
||||
!L.CheckParamEnd(6)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Get the params:
|
||||
cMobHeadEntity * Self;
|
||||
cUUID OwnerUUID;
|
||||
AString OwnerName, OwnerTexture, OwnerTextureSignature;
|
||||
L.GetStackValues(1, Self, OwnerUUID, OwnerName, OwnerTexture, OwnerTextureSignature);
|
||||
|
||||
// Set the owner:
|
||||
Self->SetOwner(OwnerUUID, OwnerName, OwnerTexture, OwnerTextureSignature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cMobHeadEntity_GetOwnerUUID(lua_State * tolua_S)
|
||||
{
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamSelf("cMobHeadEntity") ||
|
||||
!L.CheckParamEnd(2)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
cMobHeadEntity * Self;
|
||||
L.GetStackValue(1, Self);
|
||||
|
||||
// Return the UUID as a string:
|
||||
cUUID Owner = Self->GetOwnerUUID();
|
||||
L.Push(Owner.IsNil() ? AString{} : Owner.ToShortString());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cMojangAPI_AddPlayerNameToUUIDMapping(lua_State * L)
|
||||
{
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cMojangAPI") ||
|
||||
!S.CheckParamStaticSelf("cMojangAPI") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamString(3) ||
|
||||
!S.CheckParamUUID(3) ||
|
||||
!S.CheckParamEnd(4)
|
||||
)
|
||||
{
|
||||
@ -2357,9 +2511,9 @@ static int tolua_cMojangAPI_AddPlayerNameToUUIDMapping(lua_State * L)
|
||||
}
|
||||
|
||||
// Retrieve the parameters:
|
||||
AString UUID, PlayerName;
|
||||
S.GetStackValue(2, PlayerName);
|
||||
S.GetStackValue(3, UUID);
|
||||
AString PlayerName;
|
||||
cUUID UUID;
|
||||
S.GetStackValues(2, PlayerName, UUID);
|
||||
|
||||
// Store in the cache:
|
||||
cRoot::Get()->GetMojangAPI().AddPlayerNameToUUIDMapping(PlayerName, UUID);
|
||||
@ -2374,15 +2528,15 @@ static int tolua_cMojangAPI_GetPlayerNameFromUUID(lua_State * L)
|
||||
{
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cMojangAPI") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cMojangAPI") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(4)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
AString UUID;
|
||||
cUUID UUID;
|
||||
S.GetStackValue(2, UUID);
|
||||
|
||||
// If the UseOnlyCached param was given, read it; default to false
|
||||
@ -2407,7 +2561,7 @@ static int tolua_cMojangAPI_GetUUIDFromPlayerName(lua_State * L)
|
||||
{
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cMojangAPI") ||
|
||||
!S.CheckParamStaticSelf("cMojangAPI") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamEnd(4)
|
||||
)
|
||||
@ -2426,9 +2580,9 @@ static int tolua_cMojangAPI_GetUUIDFromPlayerName(lua_State * L)
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
// Return the UUID:
|
||||
AString UUID = cRoot::Get()->GetMojangAPI().GetUUIDFromPlayerName(PlayerName, ShouldUseCacheOnly);
|
||||
S.Push(UUID);
|
||||
// Return the UUID as a string:
|
||||
cUUID UUID = cRoot::Get()->GetMojangAPI().GetUUIDFromPlayerName(PlayerName, ShouldUseCacheOnly);
|
||||
S.Push(UUID.IsNil() ? AString{} : UUID.ToShortString());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2440,7 +2594,7 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L)
|
||||
{
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cMojangAPI") ||
|
||||
!S.CheckParamStaticSelf("cMojangAPI") ||
|
||||
!S.CheckParamTable(2) ||
|
||||
!S.CheckParamEnd(4)
|
||||
)
|
||||
@ -2476,23 +2630,23 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L)
|
||||
lua_newtable(L);
|
||||
|
||||
// Get the UUIDs:
|
||||
AStringVector UUIDs = cRoot::Get()->GetMojangAPI().GetUUIDsFromPlayerNames(PlayerNames, ShouldUseCacheOnly);
|
||||
auto UUIDs = cRoot::Get()->GetMojangAPI().GetUUIDsFromPlayerNames(PlayerNames, ShouldUseCacheOnly);
|
||||
if (UUIDs.size() != PlayerNames.size())
|
||||
{
|
||||
// A hard error has occured while processing the request, no UUIDs were returned. Return an empty table:
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Convert to output table, PlayerName -> UUID:
|
||||
// Convert to output table, PlayerName -> UUID string:
|
||||
size_t len = UUIDs.size();
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (UUIDs[i].empty())
|
||||
if (UUIDs[i].IsNil())
|
||||
{
|
||||
// No UUID was provided for PlayerName[i], skip it in the resulting table
|
||||
continue;
|
||||
}
|
||||
lua_pushlstring(L, UUIDs[i].c_str(), UUIDs[i].length());
|
||||
S.Push(UUIDs[i].ToShortString());
|
||||
lua_setfield(L, 3, PlayerNames[i].c_str());
|
||||
}
|
||||
return 1;
|
||||
@ -2504,13 +2658,13 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L)
|
||||
|
||||
static int tolua_cMojangAPI_MakeUUIDDashed(lua_State * L)
|
||||
{
|
||||
// Function signature: cMojangAPI:MakeUUIDDashed(UUID) -> string
|
||||
// Function now non-existant but kept for API compatibility
|
||||
|
||||
// Check params:
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cMojangAPI") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cMojangAPI") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -2518,11 +2672,11 @@ static int tolua_cMojangAPI_MakeUUIDDashed(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString UUID;
|
||||
cUUID UUID;
|
||||
S.GetStackValue(2, UUID);
|
||||
|
||||
// Push the result:
|
||||
S.Push(cRoot::Get()->GetMojangAPI().MakeUUIDDashed(UUID));
|
||||
S.Push(UUID.ToLongString());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2532,13 +2686,13 @@ static int tolua_cMojangAPI_MakeUUIDDashed(lua_State * L)
|
||||
|
||||
static int tolua_cMojangAPI_MakeUUIDShort(lua_State * L)
|
||||
{
|
||||
// Function signature: cMojangAPI:MakeUUIDShort(UUID) -> string
|
||||
// Function now non-existant but kept for API compatibility
|
||||
|
||||
// Check params:
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cMojangAPI") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -2546,11 +2700,11 @@ static int tolua_cMojangAPI_MakeUUIDShort(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString UUID;
|
||||
cUUID UUID;
|
||||
S.GetStackValue(2, UUID);
|
||||
|
||||
// Push the result:
|
||||
S.Push(cRoot::Get()->GetMojangAPI().MakeUUIDShort(UUID));
|
||||
S.Push(UUID.ToShortString());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3053,6 +3207,66 @@ static int tolua_cLuaWindow_new_local(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cRoot_DoWithPlayerByUUID(lua_State * tolua_S)
|
||||
{
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamSelf("cRoot") ||
|
||||
!L.CheckParamUUID(2) ||
|
||||
!L.CheckParamFunction(3) ||
|
||||
!L.CheckParamEnd(4)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
class cCallback :
|
||||
public cPlayerListCallback
|
||||
{
|
||||
public:
|
||||
cCallback(cLuaState & a_LuaState) :
|
||||
m_LuaState(a_LuaState)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Item(cPlayer * a_Player) override
|
||||
{
|
||||
bool ret = false;
|
||||
m_LuaState.Call(m_FnRef, a_Player, cLuaState::Return, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cLuaState & m_LuaState;
|
||||
cLuaState::cRef m_FnRef;
|
||||
} Callback(L);
|
||||
|
||||
// Get parameters:
|
||||
cRoot * Self;
|
||||
cUUID PlayerUUID;
|
||||
L.GetStackValues(1, Self, PlayerUUID, Callback.m_FnRef);
|
||||
|
||||
if (PlayerUUID.IsNil())
|
||||
{
|
||||
return L.ApiParamError("Expected a non-nil UUID for parameter #1");
|
||||
}
|
||||
if (!Callback.m_FnRef.IsValid())
|
||||
{
|
||||
return L.ApiParamError("Expected a valid callback function for parameter #2");
|
||||
}
|
||||
|
||||
// Call the function:
|
||||
bool res = Self->DoWithPlayerByUUID(PlayerUUID, Callback);
|
||||
|
||||
// Push the result as the return value:
|
||||
L.Push(res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cRoot_GetBuildCommitID(lua_State * tolua_S)
|
||||
{
|
||||
cLuaState L(tolua_S);
|
||||
@ -3791,9 +4005,12 @@ void cManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cClientHandle");
|
||||
tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE);
|
||||
tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE);
|
||||
tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage);
|
||||
tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE);
|
||||
tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE);
|
||||
tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage);
|
||||
tolua_function(tolua_S, "GetUUID", tolua_cClientHandle_GetUUID);
|
||||
tolua_function(tolua_S, "GenerateOfflineUUID", tolua_cClientHandle_GenerateOfflineUUID);
|
||||
tolua_function(tolua_S, "IsUUIDOnline", tolua_cClientHandle_IsUUIDOnline);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cColor");
|
||||
@ -3881,6 +4098,11 @@ void cManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "DoWithMap", DoWithID<cMapManager, cMap, &cMapManager::DoWithMap>);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cMobHeadEntity");
|
||||
tolua_function(tolua_S, "SetOwner", tolua_cMobHeadEntity_SetOwner);
|
||||
tolua_function(tolua_S, "GetOwnerUUID", tolua_cMobHeadEntity_GetOwnerUUID);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cMojangAPI");
|
||||
tolua_function(tolua_S, "AddPlayerNameToUUIDMapping", tolua_cMojangAPI_AddPlayerNameToUUIDMapping);
|
||||
tolua_function(tolua_S, "GetPlayerNameFromUUID", tolua_cMojangAPI_GetPlayerNameFromUUID);
|
||||
@ -3894,6 +4116,7 @@ void cManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "GetPermissions", tolua_cPlayer_GetPermissions);
|
||||
tolua_function(tolua_S, "GetRestrictions", tolua_cPlayer_GetRestrictions);
|
||||
tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches);
|
||||
tolua_function(tolua_S, "GetUUID", tolua_cPlayer_GetUUID);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cPlugin");
|
||||
@ -3923,8 +4146,8 @@ void cManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cRoot");
|
||||
tolua_function(tolua_S, "DoWithPlayerByUUID", tolua_cRoot_DoWithPlayerByUUID);
|
||||
tolua_function(tolua_S, "FindAndDoWithPlayer", DoWith <cRoot, cPlayer, &cRoot::FindAndDoWithPlayer>);
|
||||
tolua_function(tolua_S, "DoWithPlayerByUUID", DoWith <cRoot, cPlayer, &cRoot::DoWithPlayerByUUID>);
|
||||
tolua_function(tolua_S, "ForEachPlayer", ForEach<cRoot, cPlayer, &cRoot::ForEachPlayer>);
|
||||
tolua_function(tolua_S, "ForEachWorld", ForEach<cRoot, cWorld, &cRoot::ForEachWorld>);
|
||||
tolua_function(tolua_S, "GetBrewingRecipe", tolua_cRoot_GetBrewingRecipe);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "../Root.h"
|
||||
#include "tolua++/include/tolua++.h"
|
||||
#include "LuaState.h"
|
||||
#include "UUID.h"
|
||||
|
||||
|
||||
|
||||
@ -266,7 +267,7 @@ static int tolua_cRankManager_GetAllPlayerUUIDs(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamEnd(2)
|
||||
)
|
||||
{
|
||||
@ -274,10 +275,18 @@ static int tolua_cRankManager_GetAllPlayerUUIDs(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the player uuid's:
|
||||
AStringVector Players = cRoot::Get()->GetRankManager()->GetAllPlayerUUIDs();
|
||||
std::vector<cUUID> Players = cRoot::Get()->GetRankManager()->GetAllPlayerUUIDs();
|
||||
|
||||
// Convert to string UUIDs
|
||||
std::vector<AString> StrUUIDs;
|
||||
StrUUIDs.reserve(Players.size());
|
||||
for (const auto & UUID : Players)
|
||||
{
|
||||
StrUUIDs.push_back(UUID.ToShortString());
|
||||
}
|
||||
|
||||
// Push the results:
|
||||
S.Push(Players);
|
||||
S.Push(StrUUIDs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -430,8 +439,8 @@ static int tolua_cRankManager_GetPlayerGroups(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -439,7 +448,7 @@ static int tolua_cRankManager_GetPlayerGroups(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString PlayerUUID;
|
||||
cUUID PlayerUUID;
|
||||
S.GetStackValue(2, PlayerUUID);
|
||||
|
||||
// Get the groups:
|
||||
@ -462,8 +471,8 @@ static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -471,7 +480,7 @@ static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString PlayerUUID;
|
||||
cUUID PlayerUUID;
|
||||
S.GetStackValue(2, PlayerUUID);
|
||||
|
||||
// Get the permissions:
|
||||
@ -498,8 +507,8 @@ static int tolua_cRankManager_GetPlayerPermissions(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -507,7 +516,7 @@ static int tolua_cRankManager_GetPlayerPermissions(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString PlayerUUID;
|
||||
cUUID PlayerUUID;
|
||||
S.GetStackValue(2, PlayerUUID);
|
||||
|
||||
// Get the permissions:
|
||||
@ -530,8 +539,8 @@ static int tolua_cRankManager_GetPlayerRestrictions(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -539,7 +548,7 @@ static int tolua_cRankManager_GetPlayerRestrictions(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString PlayerUUID;
|
||||
cUUID PlayerUUID;
|
||||
S.GetStackValue(2, PlayerUUID);
|
||||
|
||||
// Get the permissions:
|
||||
@ -562,8 +571,8 @@ static int tolua_cRankManager_GetPlayerRankName(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -571,7 +580,7 @@ static int tolua_cRankManager_GetPlayerRankName(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString PlayerUUID;
|
||||
cUUID PlayerUUID;
|
||||
S.GetStackValue(2, PlayerUUID);
|
||||
|
||||
// Get the rank name:
|
||||
@ -594,8 +603,8 @@ static int tolua_cRankManager_GetPlayerName(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -603,7 +612,7 @@ static int tolua_cRankManager_GetPlayerName(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString PlayerUUID;
|
||||
cUUID PlayerUUID;
|
||||
S.GetStackValue(2, PlayerUUID);
|
||||
|
||||
// Get the player name:
|
||||
@ -887,8 +896,8 @@ static int tolua_cRankManager_IsPlayerRankSet(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -896,7 +905,7 @@ static int tolua_cRankManager_IsPlayerRankSet(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString PlayerUUID;
|
||||
cUUID PlayerUUID;
|
||||
S.GetStackValue(2, PlayerUUID);
|
||||
|
||||
// Get the response:
|
||||
@ -1067,8 +1076,8 @@ static int tolua_cRankManager_RemovePlayerRank(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
@ -1076,7 +1085,7 @@ static int tolua_cRankManager_RemovePlayerRank(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString PlayerUUID;
|
||||
cUUID PlayerUUID;
|
||||
S.GetStackValue(2, PlayerUUID);
|
||||
|
||||
// Remove the player's rank:
|
||||
@ -1219,8 +1228,9 @@ static int tolua_cRankManager_SetPlayerRank(lua_State * L)
|
||||
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cRankManager") ||
|
||||
!S.CheckParamString(2, 4) ||
|
||||
!S.CheckParamStaticSelf("cRankManager") ||
|
||||
!S.CheckParamUUID(2) ||
|
||||
!S.CheckParamString(3, 4) ||
|
||||
!S.CheckParamEnd(5)
|
||||
)
|
||||
{
|
||||
@ -1228,7 +1238,8 @@ static int tolua_cRankManager_SetPlayerRank(lua_State * L)
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString PlayerUUID, PlayerName, RankName;
|
||||
AString PlayerName, RankName;
|
||||
cUUID PlayerUUID;
|
||||
S.GetStackValues(2, PlayerUUID, PlayerName, RankName);
|
||||
|
||||
// Set the rank:
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "tolua++/include/tolua++.h"
|
||||
#include "../World.h"
|
||||
#include "../Broadcaster.h"
|
||||
#include "../UUID.h"
|
||||
#include "ManualBindings.h"
|
||||
#include "LuaState.h"
|
||||
#include "PluginLua.h"
|
||||
@ -206,6 +207,53 @@ static int tolua_cWorld_DoExplosionAt(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cWorld_DoWithPlayerByUUID(lua_State * tolua_S)
|
||||
{
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamSelf("cWorld") ||
|
||||
!L.CheckParamUUID(2) ||
|
||||
!L.CheckParamFunction(3) ||
|
||||
!L.CheckParamEnd(4)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get parameters:
|
||||
cWorld * Self;
|
||||
cUUID PlayerUUID;
|
||||
cLuaState::cRef FnRef;
|
||||
L.GetStackValues(1, Self, PlayerUUID, FnRef);
|
||||
|
||||
if (PlayerUUID.IsNil())
|
||||
{
|
||||
return L.ApiParamError("Expected a non-nil UUID for parameter #1");
|
||||
}
|
||||
if (!FnRef.IsValid())
|
||||
{
|
||||
return L.ApiParamError("Expected a valid callback function for parameter #2");
|
||||
}
|
||||
|
||||
// Call the function:
|
||||
bool res = Self->DoWithPlayerByUUID(PlayerUUID, [&](cPlayer * a_Player)
|
||||
{
|
||||
bool ret = false;
|
||||
L.Call(FnRef, a_Player, cLuaState::Return, ret);
|
||||
return ret;
|
||||
}
|
||||
);
|
||||
|
||||
// Push the result as the return value:
|
||||
L.Push(res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cWorld_ForEachLoadedChunk(lua_State * tolua_S)
|
||||
{
|
||||
// Exported manually, because tolua doesn't support converting functions to functor types.
|
||||
@ -640,7 +688,7 @@ void cManualBindings::BindWorld(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "DoWithMobHeadAt", DoWithXYZ<cWorld, cMobHeadEntity, &cWorld::DoWithMobHeadAt>);
|
||||
tolua_function(tolua_S, "DoWithNoteBlockAt", DoWithXYZ<cWorld, cNoteEntity, &cWorld::DoWithNoteBlockAt>);
|
||||
tolua_function(tolua_S, "DoWithPlayer", DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>);
|
||||
tolua_function(tolua_S, "DoWithPlayerByUUID", DoWith< cWorld, cPlayer, &cWorld::DoWithPlayerByUUID>);
|
||||
tolua_function(tolua_S, "DoWithPlayerByUUID", tolua_cWorld_DoWithPlayerByUUID);
|
||||
tolua_function(tolua_S, "FindAndDoWithPlayer", DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>);
|
||||
tolua_function(tolua_S, "ForEachBlockEntityInChunk", ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>);
|
||||
tolua_function(tolua_S, "ForEachBrewingstandInChunk", ForEachInChunk<cWorld, cBrewingstandEntity, &cWorld::ForEachBrewingstandInChunk>);
|
||||
|
@ -54,7 +54,8 @@ void cMobHeadEntity::SetType(const eMobHeadType & a_Type)
|
||||
{
|
||||
if ((!m_OwnerName.empty()) && (a_Type != SKULL_TYPE_PLAYER))
|
||||
{
|
||||
m_OwnerName = m_OwnerUUID = m_OwnerTexture = m_OwnerTextureSignature = "";
|
||||
m_OwnerName = m_OwnerTexture = m_OwnerTextureSignature = "";
|
||||
m_OwnerUUID = cUUID{};
|
||||
}
|
||||
m_Type = a_Type;
|
||||
m_World->BroadcastBlockEntity(m_PosX, m_PosY, m_PosZ);
|
||||
@ -102,7 +103,7 @@ void cMobHeadEntity::SetOwner(const cPlayer & a_Owner)
|
||||
|
||||
|
||||
|
||||
void cMobHeadEntity::SetOwner(const AString & a_OwnerUUID, const AString & a_OwnerName, const AString & a_OwnerTexture, const AString & a_OwnerTextureSignature)
|
||||
void cMobHeadEntity::SetOwner(const cUUID & a_OwnerUUID, const AString & a_OwnerName, const AString & a_OwnerTexture, const AString & a_OwnerTextureSignature)
|
||||
{
|
||||
if (m_Type != SKULL_TYPE_PLAYER)
|
||||
{
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "BlockEntity.h"
|
||||
#include "Defines.h"
|
||||
#include "UUID.h"
|
||||
|
||||
|
||||
|
||||
@ -42,9 +43,6 @@ public:
|
||||
/** Set the player for mob heads with player type */
|
||||
void SetOwner(const cPlayer & a_Owner);
|
||||
|
||||
/** Sets the player components for the mob heads with player type. */
|
||||
void SetOwner(const AString & a_OwnerUUID, const AString & a_OwnerName, const AString & a_OwnerTexture, const AString & a_OwnerTextureSignature);
|
||||
|
||||
/** Returns the type of the mob head */
|
||||
eMobHeadType GetType(void) const { return m_Type; }
|
||||
|
||||
@ -54,9 +52,6 @@ public:
|
||||
/** Returns the player name of the mob head */
|
||||
AString GetOwnerName(void) const { return m_OwnerName; }
|
||||
|
||||
/** Returns the player UUID of the mob head */
|
||||
AString GetOwnerUUID(void) const { return m_OwnerUUID; }
|
||||
|
||||
/** Returns the texture of the mob head */
|
||||
AString GetOwnerTexture(void) const { return m_OwnerTexture; }
|
||||
|
||||
@ -65,6 +60,15 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Sets the player components for the mob heads with player type. */
|
||||
void SetOwner(
|
||||
const cUUID & a_OwnerUUID, const AString & a_OwnerName,
|
||||
const AString & a_OwnerTexture, const AString & a_OwnerTextureSignature
|
||||
); // Exported in ManualBindings.cpp
|
||||
|
||||
/** Returns the player UUID of the mob head */
|
||||
cUUID GetOwnerUUID(void) const { return m_OwnerUUID; } // Exported in ManualBindings.cpp
|
||||
|
||||
// cBlockEntity overrides:
|
||||
virtual void CopyFrom(const cBlockEntity & a_Src) override;
|
||||
virtual bool UsedBy(cPlayer * a_Player) override;
|
||||
@ -76,7 +80,7 @@ private:
|
||||
eMobHeadRotation m_Rotation;
|
||||
|
||||
AString m_OwnerName;
|
||||
AString m_OwnerUUID;
|
||||
cUUID m_OwnerUUID;
|
||||
AString m_OwnerTexture;
|
||||
AString m_OwnerTextureSignature;
|
||||
} ; // tolua_export
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
#include "Endianness.h"
|
||||
#include "UUID.h"
|
||||
#include "OSSupport/IsThread.h"
|
||||
|
||||
|
||||
@ -32,16 +33,6 @@ Unfortunately it is very slow, so it is disabled even for regular DEBUG builds.
|
||||
|
||||
|
||||
|
||||
static char ValueToHexDigit(UInt8 digit)
|
||||
{
|
||||
ASSERT(digit < 16);
|
||||
return "0123456789abcdef"[digit];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_SINGLE_THREAD_ACCESS
|
||||
|
||||
/** Simple RAII class that is used for checking that no two threads are using an object simultanously.
|
||||
@ -506,22 +497,17 @@ bool cByteBuffer::ReadPosition64(int & a_BlockX, int & a_BlockY, int & a_BlockZ)
|
||||
|
||||
|
||||
|
||||
bool cByteBuffer::ReadUUID(AString & a_Value)
|
||||
bool cByteBuffer::ReadUUID(cUUID & a_Value)
|
||||
{
|
||||
CHECK_THREAD
|
||||
|
||||
if (!ReadString(a_Value, 16))
|
||||
std::array<Byte, 16> UUIDBuf;
|
||||
if (!ReadBuf(UUIDBuf.data(), UUIDBuf.size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
a_Value.resize(32);
|
||||
for (unsigned int i = 15; i < 16; i--)
|
||||
{
|
||||
a_Value[i * 2 + 1] = ValueToHexDigit(a_Value[i] & 0xf);
|
||||
a_Value[i * 2] = ValueToHexDigit(static_cast<UInt8>(a_Value[i]) >> 4);
|
||||
}
|
||||
|
||||
a_Value.FromRaw(UUIDBuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cUUID;
|
||||
|
||||
|
||||
/** An object that can store incoming bytes and lets its clients read the bytes sequentially
|
||||
@ -68,7 +70,7 @@ public:
|
||||
bool ReadVarUTF8String (AString & a_Value); // string length as VarInt, then string as UTF-8
|
||||
bool ReadLEInt (int & a_Value);
|
||||
bool ReadPosition64 (int & a_BlockX, int & a_BlockY, int & a_BlockZ);
|
||||
bool ReadUUID (AString & a_Value); // UUID without dashes
|
||||
bool ReadUUID (cUUID & a_Value);
|
||||
|
||||
/** Reads VarInt, assigns it to anything that can be assigned from an UInt64 (unsigned short, char, Byte, double, ...) */
|
||||
template <typename T> bool ReadVarInt(T & a_Value)
|
||||
|
@ -69,6 +69,7 @@ SET (SRCS
|
||||
StringCompression.cpp
|
||||
StringUtils.cpp
|
||||
Tracer.cpp
|
||||
UUID.cpp
|
||||
VoronoiMap.cpp
|
||||
WebAdmin.cpp
|
||||
World.cpp
|
||||
@ -147,6 +148,7 @@ SET (HDRS
|
||||
StringCompression.h
|
||||
StringUtils.h
|
||||
Tracer.h
|
||||
UUID.h
|
||||
Vector3.h
|
||||
VoronoiMap.h
|
||||
WebAdmin.h
|
||||
|
@ -274,55 +274,28 @@ AString cClientHandle::FormatMessageType(bool ShouldAppendChatPrefixes, eMessage
|
||||
|
||||
|
||||
|
||||
AString cClientHandle::GenerateOfflineUUID(const AString & a_Username)
|
||||
cUUID cClientHandle::GenerateOfflineUUID(const AString & a_Username)
|
||||
{
|
||||
// Online UUIDs are always version 4 (random)
|
||||
// We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
|
||||
// This guarantees that they will never collide with an online UUID and can be distinguished.
|
||||
// Proper format for a version 3 UUID is:
|
||||
// xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B
|
||||
// Note that we generate a short UUID (without the dashes)
|
||||
|
||||
// First make the username lowercase:
|
||||
AString lcUsername = StrToLower(a_Username);
|
||||
|
||||
// Generate an md5 checksum, and use it as base for the ID:
|
||||
unsigned char MD5[16];
|
||||
md5(reinterpret_cast<const unsigned char *>(lcUsername.c_str()), lcUsername.length(), MD5);
|
||||
MD5[6] &= 0x0f; // Need to trim to 4 bits only...
|
||||
MD5[8] &= 0x0f; // ... otherwise %01x overflows into two chars
|
||||
return Printf("%02x%02x%02x%02x%02x%02x3%01x%02x8%01x%02x%02x%02x%02x%02x%02x%02x",
|
||||
MD5[0], MD5[1], MD5[2], MD5[3],
|
||||
MD5[4], MD5[5], MD5[6], MD5[7],
|
||||
MD5[8], MD5[9], MD5[10], MD5[11],
|
||||
MD5[12], MD5[13], MD5[14], MD5[15]
|
||||
);
|
||||
return cUUID::GenerateVersion3(lcUsername);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cClientHandle::IsUUIDOnline(const AString & a_UUID)
|
||||
bool cClientHandle::IsUUIDOnline(const cUUID & a_UUID)
|
||||
{
|
||||
// Online UUIDs are always version 4 (random)
|
||||
// We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
|
||||
// This guarantees that they will never collide with an online UUID and can be distinguished.
|
||||
// The version-specifying char is at pos #12 of raw UUID, pos #14 in dashed-UUID.
|
||||
switch (a_UUID.size())
|
||||
{
|
||||
case 32:
|
||||
{
|
||||
// This is the UUID format without dashes, the version char is at pos #12:
|
||||
return (a_UUID[12] == '4');
|
||||
}
|
||||
case 36:
|
||||
{
|
||||
// This is the UUID format with dashes, the version char is at pos #14:
|
||||
return (a_UUID[14] == '4');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return (a_UUID.Version() == 4);
|
||||
}
|
||||
|
||||
|
||||
@ -342,7 +315,7 @@ void cClientHandle::Kick(const AString & a_Reason)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties)
|
||||
void cClientHandle::Authenticate(const AString & a_Name, const cUUID & a_UUID, const Json::Value & a_Properties)
|
||||
{
|
||||
// Atomically increment player count (in server thread)
|
||||
cRoot::Get()->GetServer()->PlayerCreated();
|
||||
@ -366,7 +339,7 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID,
|
||||
m_Username = a_Name;
|
||||
|
||||
// Only assign UUID and properties if not already pre-assigned (BungeeCord sends those in the Handshake packet):
|
||||
if (m_UUID.empty())
|
||||
if (m_UUID.IsNil())
|
||||
{
|
||||
m_UUID = a_UUID;
|
||||
}
|
||||
@ -1661,7 +1634,7 @@ void cClientHandle::HandleSlotSelected(Int16 a_SlotNum)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleSpectate(const AString & a_PlayerUUID)
|
||||
void cClientHandle::HandleSpectate(const cUUID & a_PlayerUUID)
|
||||
{
|
||||
m_Player->GetWorld()->DoWithPlayerByUUID(a_PlayerUUID, [=](cPlayer * a_ToSpectate)
|
||||
{
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "json/json.h"
|
||||
#include "ChunkSender.h"
|
||||
#include "EffectID.h"
|
||||
#include "UUID.h"
|
||||
|
||||
|
||||
|
||||
@ -72,13 +73,13 @@ public: // tolua_export
|
||||
|
||||
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
|
||||
/** Returns the player's UUID, as used by the protocol */
|
||||
const cUUID & GetUUID(void) const { return m_UUID; } // Exported in ManualBindings.cpp
|
||||
|
||||
/** Sets the player's UUID, as used by the protocol. Short UUID form (no dashes) is expected.
|
||||
/** Sets the player's UUID, as used by the protocol.
|
||||
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; }
|
||||
void SetUUID(const cUUID & a_UUID) { ASSERT(!a_UUID.IsNil()); m_UUID = a_UUID; }
|
||||
|
||||
const Json::Value & GetProperties(void) const { return m_Properties; }
|
||||
|
||||
@ -95,15 +96,12 @@ public: // tolua_export
|
||||
|
||||
/** Generates an UUID based on the player name provided.
|
||||
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.
|
||||
Returns a 32-char UUID (no dashes). */
|
||||
static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export
|
||||
Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. */
|
||||
static cUUID GenerateOfflineUUID(const AString & a_Username); // Exported in ManualBindings.cpp
|
||||
|
||||
/** Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID.
|
||||
We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart.
|
||||
Accepts both 32-char and 36-char UUIDs (with and without dashes).
|
||||
If the string given is not a valid UUID, returns false. */
|
||||
static bool IsUUIDOnline(const AString & a_UUID); // tolua_export
|
||||
We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. */
|
||||
static bool IsUUIDOnline(const cUUID & a_UUID); // Exported in ManualBindings.cpp
|
||||
|
||||
/** Formats the type of message with the proper color and prefix for sending to the client. */
|
||||
static AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData);
|
||||
@ -113,7 +111,7 @@ public: // tolua_export
|
||||
void Kick(const AString & a_Reason); // tolua_export
|
||||
|
||||
/** Authenticates the specified user, called by cAuthenticator */
|
||||
void Authenticate(const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties);
|
||||
void Authenticate(const AString & a_Name, const cUUID & a_UUID, const Json::Value & a_Properties);
|
||||
|
||||
/** This function sends a new unloaded chunk to the player. Returns true if all chunks are loaded. */
|
||||
bool StreamNextChunk();
|
||||
@ -336,7 +334,7 @@ public: // tolua_export
|
||||
void HandleRespawn (void);
|
||||
void HandleRightClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, const cItem & a_HeldItem);
|
||||
void HandleSlotSelected (Int16 a_SlotNum);
|
||||
void HandleSpectate (const AString & a_PlayerUUID);
|
||||
void HandleSpectate (const cUUID & a_PlayerUUID);
|
||||
void HandleSteerVehicle (float Forward, float Sideways);
|
||||
void HandleTabCompletion (const AString & a_Text);
|
||||
void HandleUpdateSign (
|
||||
@ -498,8 +496,8 @@ private:
|
||||
/** ID used for identification during authenticating. Assigned sequentially for each new instance. */
|
||||
int m_UniqueID;
|
||||
|
||||
/** Contains the UUID used by Mojang to identify the player's account. Short UUID stored here (without dashes) */
|
||||
AString m_UUID;
|
||||
/** Contains the UUID used by Mojang to identify the player's account. */
|
||||
cUUID m_UUID;
|
||||
|
||||
/** Set to true when the chunk where the player is is sent to the client. Used for spawning the player */
|
||||
bool m_HasSentPlayerChunk;
|
||||
|
@ -84,7 +84,7 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) :
|
||||
m_bIsInBed(false),
|
||||
m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL),
|
||||
m_bIsTeleporting(false),
|
||||
m_UUID((a_Client != nullptr) ? a_Client->GetUUID() : ""),
|
||||
m_UUID((a_Client != nullptr) ? a_Client->GetUUID() : cUUID{}),
|
||||
m_CustomName(""),
|
||||
m_SkinParts(0),
|
||||
m_MainHand(mhRight)
|
||||
@ -2077,7 +2077,7 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
|
||||
}
|
||||
|
||||
// Load from the offline UUID file, if allowed:
|
||||
AString OfflineUUID = cClientHandle::GenerateOfflineUUID(GetName());
|
||||
cUUID OfflineUUID = cClientHandle::GenerateOfflineUUID(GetName());
|
||||
const char * OfflineUsage = " (unused)";
|
||||
if (cRoot::Get()->GetServer()->ShouldLoadOfflinePlayerData())
|
||||
{
|
||||
@ -2105,7 +2105,7 @@ bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
|
||||
|
||||
// None of the files loaded successfully
|
||||
LOG("Player data file not found for %s (%s, offline %s%s), will be reset to defaults.",
|
||||
GetName().c_str(), m_UUID.c_str(), OfflineUUID.c_str(), OfflineUsage
|
||||
GetName().c_str(), m_UUID.ToShortString().c_str(), OfflineUUID.ToShortString().c_str(), OfflineUsage
|
||||
);
|
||||
|
||||
if (a_World == nullptr)
|
||||
@ -2220,7 +2220,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World)
|
||||
bool cPlayer::SaveToDisk()
|
||||
{
|
||||
cFile::CreateFolder(FILE_IO_PREFIX + AString("players/")); // Create the "players" folder, if it doesn't exist yet (#1268)
|
||||
cFile::CreateFolder(FILE_IO_PREFIX + AString("players/") + m_UUID.substr(0, 2));
|
||||
cFile::CreateFolder(FILE_IO_PREFIX + AString("players/") + m_UUID.ToShortString().substr(0, 2));
|
||||
|
||||
// create the JSON data
|
||||
Json::Value JSON_PlayerPosition;
|
||||
@ -2879,10 +2879,9 @@ void cPlayer::RemoveClientHandle(void)
|
||||
|
||||
|
||||
|
||||
AString cPlayer::GetUUIDFileName(const AString & a_UUID)
|
||||
AString cPlayer::GetUUIDFileName(const cUUID & a_UUID)
|
||||
{
|
||||
AString UUID = cMojangAPI::MakeUUIDDashed(a_UUID);
|
||||
ASSERT(UUID.length() == 36);
|
||||
AString UUID = a_UUID.ToLongString();
|
||||
|
||||
AString res("players/");
|
||||
res.append(UUID, 0, 2);
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "../Statistics.h"
|
||||
|
||||
#include "../UUID.h"
|
||||
|
||||
|
||||
|
||||
|
||||
@ -488,14 +490,14 @@ public:
|
||||
/** Whether placing the given blocks would intersect any entitiy */
|
||||
bool DoesPlacingBlocksIntersectEntity(const sSetBlockVector & a_Blocks);
|
||||
|
||||
/** Returns the UUID that has been read from the client, or nil if not available. */
|
||||
const cUUID & GetUUID(void) const { return m_UUID; } // Exported in ManualBindings.cpp
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/** Returns wheter the player can fly or not. */
|
||||
virtual bool CanFly(void) const { return m_CanFly; }
|
||||
|
||||
/** Returns the UUID (short format) that has been read from the client, or empty string if not available. */
|
||||
const AString & GetUUID(void) const { return m_UUID; }
|
||||
|
||||
/** (Re)loads the rank and permissions from the cRankManager.
|
||||
Expects the m_UUID member to be valid.
|
||||
Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */
|
||||
@ -694,9 +696,9 @@ protected:
|
||||
*/
|
||||
bool m_bIsTeleporting;
|
||||
|
||||
/** The short UUID (no dashes) of the player, as read from the ClientHandle.
|
||||
If no ClientHandle is given, the UUID is initialized to empty. */
|
||||
AString m_UUID;
|
||||
/** The UUID of the player, as read from the ClientHandle.
|
||||
If no ClientHandle is given, the UUID is nil. */
|
||||
cUUID m_UUID;
|
||||
|
||||
AString m_CustomName;
|
||||
|
||||
@ -731,7 +733,7 @@ protected:
|
||||
|
||||
/** Returns the filename for the player data based on the UUID given.
|
||||
This can be used both for online and offline UUIDs. */
|
||||
AString GetUUIDFileName(const AString & a_UUID);
|
||||
AString GetUUIDFileName(const cUUID & a_UUID);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "PassiveMonster.h"
|
||||
#include "../UUID.h"
|
||||
|
||||
|
||||
|
||||
@ -40,14 +41,14 @@ public:
|
||||
bool IsTame (void) const override { return m_IsTame; }
|
||||
bool IsBegging (void) const { return m_IsBegging; }
|
||||
AString GetOwnerName (void) const { return m_OwnerName; }
|
||||
AString GetOwnerUUID (void) const { return m_OwnerUUID; }
|
||||
cUUID GetOwnerUUID (void) const { return m_OwnerUUID; }
|
||||
eCatType GetOcelotType (void) const { return m_CatType; }
|
||||
|
||||
// Set functions
|
||||
void SetIsSitting (bool a_IsSitting) { m_IsSitting = a_IsSitting; }
|
||||
void SetIsTame (bool a_IsTame) { m_IsTame = a_IsTame; }
|
||||
void SetIsBegging (bool a_IsBegging) { m_IsBegging = a_IsBegging; }
|
||||
void SetOwner (const AString & a_NewOwnerName, const AString & a_NewOwnerUUID)
|
||||
void SetOwner (const AString & a_NewOwnerName, const cUUID & a_NewOwnerUUID)
|
||||
{
|
||||
m_OwnerName = a_NewOwnerName;
|
||||
m_OwnerUUID = a_NewOwnerUUID;
|
||||
@ -66,7 +67,7 @@ protected:
|
||||
/** Only check for a nearby player holding the breeding items every 23 ticks. */
|
||||
int m_CheckPlayerTickCount;
|
||||
AString m_OwnerName;
|
||||
AString m_OwnerUUID;
|
||||
cUUID m_OwnerUUID;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -117,7 +117,7 @@ bool cWolf::Attack(std::chrono::milliseconds a_Dt)
|
||||
|
||||
|
||||
|
||||
void cWolf::ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool a_IsPlayerInvolved)
|
||||
void cWolf::ReceiveNearbyFightInfo(const cUUID & a_PlayerID, cPawn * a_Opponent, bool a_IsPlayerInvolved)
|
||||
{
|
||||
if (
|
||||
(a_Opponent == nullptr) || IsSitting() || (!IsTame()) ||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "PassiveAggressiveMonster.h"
|
||||
#include "../UUID.h"
|
||||
|
||||
|
||||
class cEntity;
|
||||
@ -31,7 +32,7 @@ public:
|
||||
bool IsBegging (void) const { return m_IsBegging; }
|
||||
bool IsAngry (void) const { return m_IsAngry; }
|
||||
AString GetOwnerName (void) const { return m_OwnerName; }
|
||||
AString GetOwnerUUID (void) const { return m_OwnerUUID; }
|
||||
cUUID GetOwnerUUID (void) const { return m_OwnerUUID; }
|
||||
int GetCollarColor(void) const { return m_CollarColor; }
|
||||
|
||||
// Set functions
|
||||
@ -40,7 +41,7 @@ public:
|
||||
void SetIsBegging (bool a_IsBegging) { m_IsBegging = a_IsBegging; }
|
||||
void SetIsAngry (bool a_IsAngry) { m_IsAngry = a_IsAngry; }
|
||||
void SetCollarColor(int a_CollarColor) { m_CollarColor = a_CollarColor; }
|
||||
void SetOwner (const AString & a_NewOwnerName, const AString & a_NewOwnerUUID)
|
||||
void SetOwner (const AString & a_NewOwnerName, const cUUID & a_NewOwnerUUID)
|
||||
{
|
||||
m_OwnerName = a_NewOwnerName;
|
||||
m_OwnerUUID = a_NewOwnerUUID;
|
||||
@ -48,12 +49,12 @@ public:
|
||||
|
||||
/** Notfies the wolf of a nearby fight.
|
||||
The wolf may then decide to attack a_Opponent.
|
||||
If a_IsPlayer is true, then the player whose ID is a_PlayerID is fighting a_Opponent
|
||||
If false, then a wolf owned by the player whose ID is a_PlayerID is fighting a_Opponent
|
||||
@param a_PlayerID The ID of the fighting player, or the ID of the owner whose wolf is fighting.
|
||||
If a_IsPlayerInvolved is true, then the player whose UUID is a_PlayerUUID is fighting a_Opponent
|
||||
If false, then a wolf owned by the player whose UUID is a_PlayerUUID is fighting a_Opponent
|
||||
@param a_PlayerUUID The UUID of the fighting player, or the UUID of the owner whose wolf is fighting.
|
||||
@param a_Opponent The opponent who is being faught.
|
||||
@param a_IsPlayerInvolved Whether the fighter a player or a wolf. */
|
||||
void ReceiveNearbyFightInfo(AString a_PlayerID, cPawn * a_Opponent, bool a_IsPlayerInvolved);
|
||||
void ReceiveNearbyFightInfo(const cUUID & a_PlayerUUID, cPawn * a_Opponent, bool a_IsPlayerInvolved);
|
||||
|
||||
virtual void InStateIdle(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
||||
|
||||
@ -64,7 +65,7 @@ protected:
|
||||
bool m_IsBegging;
|
||||
bool m_IsAngry;
|
||||
AString m_OwnerName;
|
||||
AString m_OwnerUUID;
|
||||
cUUID m_OwnerUUID;
|
||||
int m_CollarColor;
|
||||
int m_NotificationCooldown;
|
||||
} ;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "../Root.h"
|
||||
#include "../Server.h"
|
||||
#include "../ClientHandle.h"
|
||||
#include "../UUID.h"
|
||||
|
||||
#include "../IniFile.h"
|
||||
#include "json/json.h"
|
||||
@ -119,11 +120,11 @@ void cAuthenticator::Execute(void)
|
||||
Lock.Unlock();
|
||||
|
||||
AString NewUserName = UserName;
|
||||
AString UUID;
|
||||
cUUID UUID;
|
||||
Json::Value Properties;
|
||||
if (AuthWithYggdrasil(NewUserName, ServerID, UUID, Properties))
|
||||
{
|
||||
LOGINFO("User %s authenticated with UUID %s", NewUserName.c_str(), UUID.c_str());
|
||||
LOGINFO("User %s authenticated with UUID %s", NewUserName.c_str(), UUID.ToShortString().c_str());
|
||||
cRoot::Get()->AuthenticateUser(ClientID, NewUserName, UUID, Properties);
|
||||
}
|
||||
else
|
||||
@ -137,7 +138,7 @@ void cAuthenticator::Execute(void)
|
||||
|
||||
|
||||
|
||||
bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, AString & a_UUID, Json::Value & a_Properties)
|
||||
bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, cUUID & a_UUID, Json::Value & a_Properties)
|
||||
{
|
||||
LOGD("Trying to authenticate user %s", a_UserName.c_str());
|
||||
|
||||
@ -192,8 +193,12 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S
|
||||
return false;
|
||||
}
|
||||
a_UserName = root.get("name", "Unknown").asString();
|
||||
a_UUID = cMojangAPI::MakeUUIDShort(root.get("id", "").asString());
|
||||
a_Properties = root["properties"];
|
||||
if (!a_UUID.FromString(root.get("id", "").asString()))
|
||||
{
|
||||
LOGWARNING("cAuthenticator: Recieved invalid UUID format");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store the player's profile in the MojangAPI caches:
|
||||
cRoot::Get()->GetMojangAPI().AddPlayerProfile(a_UserName, a_UUID, a_Properties);
|
||||
|
@ -14,12 +14,10 @@
|
||||
|
||||
#include "../OSSupport/IsThread.h"
|
||||
|
||||
// fwd:
|
||||
class cUUID;
|
||||
class cSettingsRepositoryInterface;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Json
|
||||
{
|
||||
class Value;
|
||||
@ -90,7 +88,7 @@ private:
|
||||
|
||||
/** Returns true if the user authenticated okay, false on error
|
||||
Returns the case-corrected username, UUID, and properties (eg. skin). */
|
||||
bool AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, AString & a_UUID, Json::Value & a_Properties);
|
||||
bool AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, cUUID & a_UUID, Json::Value & a_Properties);
|
||||
};
|
||||
|
||||
|
||||
|
@ -154,7 +154,7 @@ static const AString & GetCACerts(void)
|
||||
|
||||
cMojangAPI::sProfile::sProfile(
|
||||
const AString & a_PlayerName,
|
||||
const AString & a_UUID,
|
||||
const cUUID & a_UUID,
|
||||
const Json::Value & a_Properties,
|
||||
Int64 a_DateTime
|
||||
) :
|
||||
@ -291,7 +291,7 @@ void cMojangAPI::Start(cSettingsRepositoryInterface & a_Settings, bool a_ShouldA
|
||||
|
||||
|
||||
|
||||
AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached)
|
||||
cUUID cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached)
|
||||
{
|
||||
// Convert the playername to lowercase:
|
||||
AString lcPlayerName = StrToLower(a_PlayerName);
|
||||
@ -299,8 +299,7 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U
|
||||
// Request the cache to query the name if not yet cached:
|
||||
if (!a_UseOnlyCached)
|
||||
{
|
||||
AStringVector PlayerNames;
|
||||
PlayerNames.push_back(lcPlayerName);
|
||||
AStringVector PlayerNames{ lcPlayerName };
|
||||
CacheNamesToUUIDs(PlayerNames);
|
||||
}
|
||||
|
||||
@ -310,7 +309,7 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U
|
||||
if (itr == m_NameToUUID.end())
|
||||
{
|
||||
// No UUID found
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
return itr->second.m_UUID;
|
||||
}
|
||||
@ -319,15 +318,12 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U
|
||||
|
||||
|
||||
|
||||
AString cMojangAPI::GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnlyCached)
|
||||
AString cMojangAPI::GetPlayerNameFromUUID(const cUUID & a_UUID, bool a_UseOnlyCached)
|
||||
{
|
||||
// Normalize the UUID to lowercase short format that is used as the map key:
|
||||
AString UUID = MakeUUIDShort(a_UUID);
|
||||
|
||||
// Retrieve from caches:
|
||||
{
|
||||
cCSLock Lock(m_CSUUIDToProfile);
|
||||
cProfileMap::const_iterator itr = m_UUIDToProfile.find(UUID);
|
||||
auto itr = m_UUIDToProfile.find(a_UUID);
|
||||
if (itr != m_UUIDToProfile.end())
|
||||
{
|
||||
return itr->second.m_PlayerName;
|
||||
@ -335,7 +331,7 @@ AString cMojangAPI::GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnly
|
||||
}
|
||||
{
|
||||
cCSLock Lock(m_CSUUIDToName);
|
||||
cProfileMap::const_iterator itr = m_UUIDToName.find(UUID);
|
||||
auto itr = m_UUIDToName.find(a_UUID);
|
||||
if (itr != m_UUIDToName.end())
|
||||
{
|
||||
return itr->second.m_PlayerName;
|
||||
@ -345,19 +341,19 @@ AString cMojangAPI::GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnly
|
||||
// Name not yet cached, request cache and retry:
|
||||
if (!a_UseOnlyCached)
|
||||
{
|
||||
CacheUUIDToProfile(UUID);
|
||||
CacheUUIDToProfile(a_UUID);
|
||||
return GetPlayerNameFromUUID(a_UUID, true);
|
||||
}
|
||||
|
||||
// No value found, none queried. Return an error:
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames, bool a_UseOnlyCached)
|
||||
std::vector<cUUID> cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames, bool a_UseOnlyCached)
|
||||
{
|
||||
// Convert all playernames to lowercase:
|
||||
AStringVector PlayerNames;
|
||||
@ -374,7 +370,7 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player
|
||||
|
||||
// Retrieve from cache:
|
||||
size_t idx = 0;
|
||||
AStringVector res;
|
||||
std::vector<cUUID> res;
|
||||
res.resize(PlayerNames.size());
|
||||
cCSLock Lock(m_CSNameToUUID);
|
||||
for (AStringVector::const_iterator itr = PlayerNames.begin(), end = PlayerNames.end(); itr != end; ++itr, ++idx)
|
||||
@ -392,17 +388,16 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player
|
||||
|
||||
|
||||
|
||||
void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID)
|
||||
void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const cUUID & a_UUID)
|
||||
{
|
||||
AString UUID = MakeUUIDShort(a_UUID);
|
||||
Int64 Now = time(nullptr);
|
||||
{
|
||||
cCSLock Lock(m_CSNameToUUID);
|
||||
m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, UUID, "", "", Now);
|
||||
m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, a_UUID, "", "", Now);
|
||||
}
|
||||
{
|
||||
cCSLock Lock(m_CSUUIDToName);
|
||||
m_UUIDToName[UUID] = sProfile(a_PlayerName, UUID, "", "", Now);
|
||||
m_UUIDToName[a_UUID] = sProfile(a_PlayerName, a_UUID, "", "", Now);
|
||||
}
|
||||
NotifyNameUUID(a_PlayerName, a_UUID);
|
||||
}
|
||||
@ -411,21 +406,20 @@ void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const
|
||||
|
||||
|
||||
|
||||
void cMojangAPI::AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties)
|
||||
void cMojangAPI::AddPlayerProfile(const AString & a_PlayerName, const cUUID & a_UUID, const Json::Value & a_Properties)
|
||||
{
|
||||
AString UUID = MakeUUIDShort(a_UUID);
|
||||
Int64 Now = time(nullptr);
|
||||
{
|
||||
cCSLock Lock(m_CSNameToUUID);
|
||||
m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, UUID, "", "", Now);
|
||||
m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, a_UUID, "", "", Now);
|
||||
}
|
||||
{
|
||||
cCSLock Lock(m_CSUUIDToName);
|
||||
m_UUIDToName[UUID] = sProfile(a_PlayerName, UUID, "", "", Now);
|
||||
m_UUIDToName[a_UUID] = sProfile(a_PlayerName, a_UUID, "", "", Now);
|
||||
}
|
||||
{
|
||||
cCSLock Lock(m_CSUUIDToProfile);
|
||||
m_UUIDToProfile[UUID] = sProfile(a_PlayerName, UUID, a_Properties, Now);
|
||||
m_UUIDToProfile[a_UUID] = sProfile(a_PlayerName, a_UUID, a_Properties, Now);
|
||||
}
|
||||
NotifyNameUUID(a_PlayerName, a_UUID);
|
||||
}
|
||||
@ -488,74 +482,6 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R
|
||||
|
||||
|
||||
|
||||
AString cMojangAPI::MakeUUIDShort(const AString & a_UUID)
|
||||
{
|
||||
// Note: we only check the string's length, not the actual content
|
||||
switch (a_UUID.size())
|
||||
{
|
||||
case 32:
|
||||
{
|
||||
// Already is a short UUID, only lowercase
|
||||
return StrToLower(a_UUID);
|
||||
}
|
||||
|
||||
case 36:
|
||||
{
|
||||
// Remove the dashes from the string by appending together the parts between them:
|
||||
AString res;
|
||||
res.reserve(32);
|
||||
res.append(a_UUID, 0, 8);
|
||||
res.append(a_UUID, 9, 4);
|
||||
res.append(a_UUID, 14, 4);
|
||||
res.append(a_UUID, 19, 4);
|
||||
res.append(a_UUID, 24, 12);
|
||||
return StrToLower(res);
|
||||
}
|
||||
}
|
||||
LOGWARNING("%s: Not an UUID: \"%s\".", __FUNCTION__, a_UUID.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cMojangAPI::MakeUUIDDashed(const AString & a_UUID)
|
||||
{
|
||||
// Note: we only check the string's length, not the actual content
|
||||
switch (a_UUID.size())
|
||||
{
|
||||
case 36:
|
||||
{
|
||||
// Already is a dashed UUID, only lowercase
|
||||
return StrToLower(a_UUID);
|
||||
}
|
||||
|
||||
case 32:
|
||||
{
|
||||
// Insert dashes at the proper positions:
|
||||
AString res;
|
||||
res.reserve(36);
|
||||
res.append(a_UUID, 0, 8);
|
||||
res.push_back('-');
|
||||
res.append(a_UUID, 8, 4);
|
||||
res.push_back('-');
|
||||
res.append(a_UUID, 12, 4);
|
||||
res.push_back('-');
|
||||
res.append(a_UUID, 16, 4);
|
||||
res.push_back('-');
|
||||
res.append(a_UUID, 20, 12);
|
||||
return StrToLower(res);
|
||||
}
|
||||
}
|
||||
LOGWARNING("%s: Not an UUID: \"%s\".", __FUNCTION__, a_UUID.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cMojangAPI::LoadCachesFromDisk(void)
|
||||
{
|
||||
try
|
||||
@ -571,9 +497,15 @@ void cMojangAPI::LoadCachesFromDisk(void)
|
||||
while (stmt.executeStep())
|
||||
{
|
||||
AString PlayerName = stmt.getColumn(0);
|
||||
AString UUID = stmt.getColumn(1);
|
||||
AString StringUUID = stmt.getColumn(1);
|
||||
Int64 DateTime = stmt.getColumn(2);
|
||||
UUID = MakeUUIDShort(UUID);
|
||||
|
||||
cUUID UUID;
|
||||
if (!UUID.FromString(StringUUID))
|
||||
{
|
||||
continue; // Invalid UUID
|
||||
}
|
||||
|
||||
m_NameToUUID[StrToLower(PlayerName)] = sProfile(PlayerName, UUID, "", "", DateTime);
|
||||
m_UUIDToName[UUID] = sProfile(PlayerName, UUID, "", "", DateTime);
|
||||
}
|
||||
@ -583,11 +515,17 @@ void cMojangAPI::LoadCachesFromDisk(void)
|
||||
while (stmt.executeStep())
|
||||
{
|
||||
AString PlayerName = stmt.getColumn(0);
|
||||
AString UUID = stmt.getColumn(1);
|
||||
AString StringUUID = stmt.getColumn(1);
|
||||
AString Textures = stmt.getColumn(2);
|
||||
AString TexturesSignature = stmt.getColumn(2);
|
||||
Int64 DateTime = stmt.getColumn(4);
|
||||
UUID = MakeUUIDShort(UUID);
|
||||
|
||||
cUUID UUID;
|
||||
if (!UUID.FromString(StringUUID))
|
||||
{
|
||||
continue; // Invalid UUID
|
||||
}
|
||||
|
||||
m_UUIDToProfile[UUID] = sProfile(PlayerName, UUID, Textures, TexturesSignature, DateTime);
|
||||
}
|
||||
}
|
||||
@ -620,16 +558,17 @@ void cMojangAPI::SaveCachesToDisk(void)
|
||||
{
|
||||
SQLite::Statement stmt(db, "INSERT INTO PlayerNameToUUID(PlayerName, UUID, DateTime) VALUES (?, ?, ?)");
|
||||
cCSLock Lock(m_CSNameToUUID);
|
||||
for (cProfileMap::const_iterator itr = m_NameToUUID.begin(), end = m_NameToUUID.end(); itr != end; ++itr)
|
||||
for (auto & NameToUUID : m_NameToUUID)
|
||||
{
|
||||
if (itr->second.m_DateTime < LimitDateTime)
|
||||
auto & Profile = NameToUUID.second;
|
||||
if (Profile.m_DateTime < LimitDateTime)
|
||||
{
|
||||
// This item is too old, do not save
|
||||
continue;
|
||||
}
|
||||
stmt.bind(1, itr->second.m_PlayerName);
|
||||
stmt.bind(2, itr->second.m_UUID);
|
||||
stmt.bind(3, itr->second.m_DateTime);
|
||||
stmt.bind(1, Profile.m_PlayerName);
|
||||
stmt.bind(2, Profile.m_UUID.ToShortString());
|
||||
stmt.bind(3, Profile.m_DateTime);
|
||||
stmt.exec();
|
||||
stmt.reset();
|
||||
}
|
||||
@ -639,18 +578,19 @@ void cMojangAPI::SaveCachesToDisk(void)
|
||||
{
|
||||
SQLite::Statement stmt(db, "INSERT INTO UUIDToProfile(UUID, PlayerName, Textures, TexturesSignature, DateTime) VALUES (?, ?, ?, ?, ?)");
|
||||
cCSLock Lock(m_CSUUIDToProfile);
|
||||
for (cProfileMap::const_iterator itr = m_UUIDToProfile.begin(), end = m_UUIDToProfile.end(); itr != end; ++itr)
|
||||
for (auto & UUIDToProfile : m_UUIDToProfile)
|
||||
{
|
||||
if (itr->second.m_DateTime < LimitDateTime)
|
||||
auto & Profile = UUIDToProfile.second;
|
||||
if (Profile.m_DateTime < LimitDateTime)
|
||||
{
|
||||
// This item is too old, do not save
|
||||
continue;
|
||||
}
|
||||
stmt.bind(1, itr->second.m_UUID);
|
||||
stmt.bind(2, itr->second.m_PlayerName);
|
||||
stmt.bind(3, itr->second.m_Textures);
|
||||
stmt.bind(4, itr->second.m_TexturesSignature);
|
||||
stmt.bind(5, itr->second.m_DateTime);
|
||||
stmt.bind(1, Profile.m_UUID.ToShortString());
|
||||
stmt.bind(2, Profile.m_PlayerName);
|
||||
stmt.bind(3, Profile.m_Textures);
|
||||
stmt.bind(4, Profile.m_TexturesSignature);
|
||||
stmt.bind(5, Profile.m_DateTime);
|
||||
stmt.exec();
|
||||
stmt.reset();
|
||||
}
|
||||
@ -762,8 +702,8 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery)
|
||||
{
|
||||
Json::Value & Val = root[idx];
|
||||
AString JsonName = Val.get("name", "").asString();
|
||||
AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString());
|
||||
if (JsonUUID.empty())
|
||||
cUUID JsonUUID;
|
||||
if (!JsonUUID.FromString(Val.get("id", "").asString()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -779,8 +719,8 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery)
|
||||
{
|
||||
Json::Value & Val = root[idx];
|
||||
AString JsonName = Val.get("name", "").asString();
|
||||
AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString());
|
||||
if (JsonUUID.empty())
|
||||
cUUID JsonUUID;
|
||||
if (!JsonUUID.FromString(Val.get("id", "").asString()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -794,10 +734,8 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery)
|
||||
|
||||
|
||||
|
||||
void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID)
|
||||
void cMojangAPI::CacheUUIDToProfile(const cUUID & a_UUID)
|
||||
{
|
||||
ASSERT(a_UUID.size() == 32);
|
||||
|
||||
// Check if already present:
|
||||
{
|
||||
cCSLock Lock(m_CSUUIDToProfile);
|
||||
@ -814,11 +752,11 @@ void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID)
|
||||
|
||||
|
||||
|
||||
void cMojangAPI::QueryUUIDToProfile(const AString & a_UUID)
|
||||
void cMojangAPI::QueryUUIDToProfile(const cUUID & a_UUID)
|
||||
{
|
||||
// Create the request address:
|
||||
AString Address = m_UUIDToProfileAddress;
|
||||
ReplaceString(Address, "%UUID%", a_UUID);
|
||||
ReplaceString(Address, "%UUID%", a_UUID.ToShortString());
|
||||
|
||||
// Create the HTTP request:
|
||||
AString Request;
|
||||
@ -909,7 +847,7 @@ void cMojangAPI::QueryUUIDToProfile(const AString & a_UUID)
|
||||
|
||||
|
||||
|
||||
void cMojangAPI::NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID)
|
||||
void cMojangAPI::NotifyNameUUID(const AString & a_PlayerName, const cUUID & a_UUID)
|
||||
{
|
||||
// Notify the rank manager:
|
||||
cCSLock Lock(m_CSRankMgr);
|
||||
@ -931,11 +869,11 @@ void cMojangAPI::Update(void)
|
||||
AStringVector PlayerNames;
|
||||
{
|
||||
cCSLock Lock(m_CSNameToUUID);
|
||||
for (cProfileMap::const_iterator itr = m_NameToUUID.begin(), end = m_NameToUUID.end(); itr != end; ++itr)
|
||||
for (const auto & NameToUUID : m_NameToUUID)
|
||||
{
|
||||
if (itr->second.m_DateTime < LimitDateTime)
|
||||
if (NameToUUID.second.m_DateTime < LimitDateTime)
|
||||
{
|
||||
PlayerNames.push_back(itr->first);
|
||||
PlayerNames.push_back(NameToUUID.first);
|
||||
}
|
||||
} // for itr - m_NameToUUID[]
|
||||
}
|
||||
@ -946,23 +884,23 @@ void cMojangAPI::Update(void)
|
||||
}
|
||||
|
||||
// Re-query all profiles that are stale:
|
||||
AStringVector ProfileUUIDs;
|
||||
std::vector<cUUID> ProfileUUIDs;
|
||||
{
|
||||
cCSLock Lock(m_CSUUIDToProfile);
|
||||
for (cProfileMap::const_iterator itr = m_UUIDToProfile.begin(), end = m_UUIDToProfile.end(); itr != end; ++itr)
|
||||
for (auto & UUIDToProfile : m_UUIDToProfile)
|
||||
{
|
||||
if (itr->second.m_DateTime < LimitDateTime)
|
||||
if (UUIDToProfile.second.m_DateTime < LimitDateTime)
|
||||
{
|
||||
ProfileUUIDs.push_back(itr->first);
|
||||
ProfileUUIDs.push_back(UUIDToProfile.first);
|
||||
}
|
||||
} // for itr - m_UUIDToProfile[]
|
||||
}
|
||||
if (!ProfileUUIDs.empty())
|
||||
{
|
||||
LOG("cMojangAPI: Updating uuid-to-profile cache for %u uuids", static_cast<unsigned>(ProfileUUIDs.size()));
|
||||
for (AStringVector::const_iterator itr = ProfileUUIDs.begin(), end = ProfileUUIDs.end(); itr != end; ++itr)
|
||||
for (const auto & UUID : ProfileUUIDs)
|
||||
{
|
||||
QueryUUIDToProfile(*itr);
|
||||
QueryUUIDToProfile(UUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "../UUID.h"
|
||||
|
||||
|
||||
|
||||
|
||||
@ -45,49 +47,38 @@ public:
|
||||
Returns true if all was successful, false on failure. */
|
||||
static bool SecureRequest(const AString & a_ServerName, const AString & a_Request, AString & a_Response);
|
||||
|
||||
/** Normalizes the given UUID to its short form (32 bytes, no dashes, lowercase).
|
||||
Logs a warning and returns empty string if not a UUID.
|
||||
Note: only checks the string's length, not the actual content. */
|
||||
static AString MakeUUIDShort(const AString & a_UUID);
|
||||
|
||||
/** Normalizes the given UUID to its dashed form (36 bytes, 4 dashes, lowercase).
|
||||
Logs a warning and returns empty string if not a UUID.
|
||||
Note: only checks the string's length, not the actual content. */
|
||||
static AString MakeUUIDDashed(const AString & a_UUID);
|
||||
|
||||
/** Converts a player name into a UUID.
|
||||
The UUID will be empty on error.
|
||||
The UUID will be nil on error.
|
||||
If a_UseOnlyCached is true, the function only consults the cached values.
|
||||
If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking
|
||||
operation, do not use this in world-tick thread!
|
||||
If you have multiple names to resolve, use the GetUUIDsFromPlayerNames() function, it uses a single request for multiple names. */
|
||||
AString GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached = false);
|
||||
cUUID GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached = false);
|
||||
|
||||
/** Converts a UUID into a playername.
|
||||
The returned playername will be empty on error.
|
||||
Both short and dashed UUID formats are accepted.
|
||||
Uses both m_UUIDToName and m_UUIDToProfile to search for the value. Uses m_UUIDToProfile for cache.
|
||||
If a_UseOnlyCached is true, the function only consults the cached values.
|
||||
If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking
|
||||
operation, do not use this in world-tick thread! */
|
||||
AString GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnlyCached = false);
|
||||
AString GetPlayerNameFromUUID(const cUUID & a_UUID, bool a_UseOnlyCached = false);
|
||||
|
||||
/** Converts the player names into UUIDs.
|
||||
a_PlayerName[idx] will be converted to UUID and returned as idx-th value
|
||||
The UUID will be empty on error.
|
||||
The UUID will be nil on error.
|
||||
If a_UseOnlyCached is true, only the cached values are returned.
|
||||
If a_UseOnlyCached is false, the names not found in the cache are looked up online, which is a blocking
|
||||
operation, do not use this in world-tick thread! */
|
||||
AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName, bool a_UseOnlyCached = false);
|
||||
std::vector<cUUID> GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName, bool a_UseOnlyCached = false);
|
||||
|
||||
/** Called by the Authenticator to add a PlayerName -> UUID mapping that it has received from
|
||||
authenticating a user. This adds the cache item and "refreshes" it if existing, adjusting its datetime
|
||||
stamp to now. */
|
||||
void AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID);
|
||||
void AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const cUUID & a_UUID);
|
||||
|
||||
/** Called by the Authenticator to add a profile that it has received from authenticating a user. Adds
|
||||
the profile to the respective mapping caches and updtes their datetime stamp to now. */
|
||||
void AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties);
|
||||
void AddPlayerProfile(const AString & a_PlayerName, const cUUID & a_UUID, const Json::Value & a_Properties);
|
||||
|
||||
/** Sets the m_RankMgr that is used for name-uuid notifications. Accepts nullptr to remove the binding. */
|
||||
void SetRankManager(cRankManager * a_RankManager) { m_RankMgr = a_RankManager; }
|
||||
@ -101,7 +92,7 @@ protected:
|
||||
struct sProfile
|
||||
{
|
||||
AString m_PlayerName; // Case-correct playername
|
||||
AString m_UUID; // Short lowercased UUID
|
||||
cUUID m_UUID; // Player UUID
|
||||
AString m_Textures; // The Textures field of the profile properties
|
||||
AString m_TexturesSignature; // The signature of the Textures field of the profile properties
|
||||
Int64 m_DateTime; // UNIXtime of the profile lookup
|
||||
@ -119,7 +110,7 @@ protected:
|
||||
/** Constructor for the storage creation. */
|
||||
sProfile(
|
||||
const AString & a_PlayerName,
|
||||
const AString & a_UUID,
|
||||
const cUUID & a_UUID,
|
||||
const AString & a_Textures,
|
||||
const AString & a_TexturesSignature,
|
||||
Int64 a_DateTime
|
||||
@ -135,12 +126,13 @@ protected:
|
||||
/** Constructor that parses the values from the Json profile. */
|
||||
sProfile(
|
||||
const AString & a_PlayerName,
|
||||
const AString & a_UUID,
|
||||
const cUUID & a_UUID,
|
||||
const Json::Value & a_Properties,
|
||||
Int64 a_DateTime
|
||||
);
|
||||
};
|
||||
typedef std::map<AString, sProfile> cProfileMap;
|
||||
typedef std::map<cUUID, sProfile> cUUIDProfileMap;
|
||||
|
||||
|
||||
/** The server to connect to when converting player names to UUIDs. For example "api.mojang.com". */
|
||||
@ -164,14 +156,14 @@ protected:
|
||||
cCriticalSection m_CSNameToUUID;
|
||||
|
||||
/** Cache for the Name-to-UUID lookups. The map key is lowercased short UUID. Protected by m_CSUUIDToName. */
|
||||
cProfileMap m_UUIDToName;
|
||||
cUUIDProfileMap m_UUIDToName;
|
||||
|
||||
/** Protects m_UUIDToName against simultaneous multi-threaded access. */
|
||||
cCriticalSection m_CSUUIDToName;
|
||||
|
||||
/** Cache for the UUID-to-profile lookups. The map key is lowercased short UUID.
|
||||
Protected by m_CSUUIDToProfile. */
|
||||
cProfileMap m_UUIDToProfile;
|
||||
cUUIDProfileMap m_UUIDToProfile;
|
||||
|
||||
/** Protects m_UUIDToProfile against simultaneous multi-threaded access. */
|
||||
cCriticalSection m_CSUUIDToProfile;
|
||||
@ -204,18 +196,16 @@ protected:
|
||||
void QueryNamesToUUIDs(AStringVector & a_PlayerNames);
|
||||
|
||||
/** Makes sure the specified UUID is in the m_UUIDToProfile cache. If missing, downloads it from Mojang API servers.
|
||||
UUIDs that are not valid will not be added into the cache.
|
||||
ASSUMEs that a_UUID is a lowercased short UUID. */
|
||||
void CacheUUIDToProfile(const AString & a_UUID);
|
||||
UUIDs that are not valid will not be added into the cache. */
|
||||
void CacheUUIDToProfile(const cUUID & a_UUID);
|
||||
|
||||
/** Queries the specified UUID's profile and stores it in the m_UUIDToProfile cache. If already present, updates the cache entry.
|
||||
UUIDs that are not valid will not be added into the cache.
|
||||
ASSUMEs that a_UUID is a lowercased short UUID. */
|
||||
void QueryUUIDToProfile(const AString & a_UUID);
|
||||
UUIDs that are not valid will not be added into the cache. */
|
||||
void QueryUUIDToProfile(const cUUID & a_UUID);
|
||||
|
||||
/** Called for each name-uuid pairing that is discovered.
|
||||
If assigned, notifies the m_RankManager of the event. */
|
||||
void NotifyNameUUID(const AString & a_PlayerName, const AString & a_PlayerUUID);
|
||||
void NotifyNameUUID(const AString & a_PlayerName, const cUUID & a_PlayerUUID);
|
||||
|
||||
/** Updates the stale values in the DB from the Mojang servers. Called from the cUpdateThread, blocks on the HTTPS API calls. */
|
||||
void Update(void);
|
||||
|
@ -5,46 +5,7 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Packetizer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Converts the hex digit character to its value. */
|
||||
static UInt8 HexDigitValue(char a_Character)
|
||||
{
|
||||
switch (a_Character)
|
||||
{
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'a': return 10;
|
||||
case 'b': return 11;
|
||||
case 'c': return 12;
|
||||
case 'd': return 13;
|
||||
case 'e': return 14;
|
||||
case 'f': return 15;
|
||||
case 'A': return 10;
|
||||
case 'B': return 11;
|
||||
case 'C': return 12;
|
||||
case 'D': return 13;
|
||||
case 'E': return 14;
|
||||
case 'F': return 15;
|
||||
default:
|
||||
{
|
||||
LOGWARNING("Bad hex digit: %c", a_Character);
|
||||
ASSERT(!"Bad hex digit");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "UUID.h"
|
||||
|
||||
|
||||
|
||||
@ -80,18 +41,10 @@ void cPacketizer::WriteFPInt(double a_Value)
|
||||
|
||||
|
||||
|
||||
void cPacketizer::WriteUUID(const AString & a_UUID)
|
||||
void cPacketizer::WriteUUID(const cUUID & a_UUID)
|
||||
{
|
||||
if (a_UUID.length() != 32)
|
||||
for (auto val : a_UUID.ToRaw())
|
||||
{
|
||||
LOGWARNING("%s: Attempt to send a bad uuid (length isn't 32): %s", __FUNCTION__, a_UUID.c_str());
|
||||
ASSERT(!"Wrong uuid length!");
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 32; i += 2)
|
||||
{
|
||||
auto val = static_cast<UInt8>(HexDigitValue(a_UUID[i]) << 4 | HexDigitValue(a_UUID[i + 1]));
|
||||
VERIFY(m_Out.WriteBEUInt8(val));
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
||||
class cByteBuffer;
|
||||
|
||||
|
||||
// fwd:
|
||||
class cUUID;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -134,7 +138,7 @@ public:
|
||||
void WriteFPInt(double a_Value);
|
||||
|
||||
/** Writes the specified UUID as a 128-bit BigEndian integer. */
|
||||
void WriteUUID(const AString & a_UUID);
|
||||
void WriteUUID(const cUUID & a_UUID);
|
||||
|
||||
UInt32 GetPacketType(void) const { return m_PacketType; }
|
||||
|
||||
|
@ -619,7 +619,7 @@ void cProtocol_1_10_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity
|
||||
|
||||
// The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity
|
||||
Writer.BeginCompound("Owner");
|
||||
Writer.AddString("Id", MobHeadEntity.GetOwnerUUID());
|
||||
Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString());
|
||||
Writer.AddString("Name", MobHeadEntity.GetOwnerName());
|
||||
Writer.BeginCompound("Properties");
|
||||
Writer.BeginList("textures", TAG_Compound);
|
||||
|
@ -466,7 +466,7 @@ void cProtocol_1_11_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity
|
||||
|
||||
// The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity
|
||||
Writer.BeginCompound("Owner");
|
||||
Writer.AddString("Id", MobHeadEntity.GetOwnerUUID());
|
||||
Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString());
|
||||
Writer.AddString("Name", MobHeadEntity.GetOwnerName());
|
||||
Writer.BeginCompound("Properties");
|
||||
Writer.BeginList("textures", TAG_Compound);
|
||||
|
@ -22,6 +22,7 @@ Implements the 1.8 protocol classes:
|
||||
#include "../StringCompression.h"
|
||||
#include "../CompositeChat.h"
|
||||
#include "../Statistics.h"
|
||||
#include "../UUID.h"
|
||||
|
||||
#include "../WorldStorage/FastNBT.h"
|
||||
#include "../WorldStorage/EnchantmentSerializer.h"
|
||||
@ -118,7 +119,11 @@ cProtocol_1_8_0::cProtocol_1_8_0(cClientHandle * a_Client, const AString & a_Ser
|
||||
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]));
|
||||
|
||||
cUUID UUID;
|
||||
UUID.FromString(Params[2]);
|
||||
m_Client->SetUUID(UUID);
|
||||
|
||||
m_Client->SetProperties(Params[3]);
|
||||
}
|
||||
|
||||
@ -705,7 +710,7 @@ void cProtocol_1_8_0::SendLoginSuccess(void)
|
||||
|
||||
{
|
||||
cPacketizer Pkt(*this, 0x02); // Login success packet
|
||||
Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID()));
|
||||
Pkt.WriteString(m_Client->GetUUID().ToLongString());
|
||||
Pkt.WriteString(m_Client->GetUsername());
|
||||
}
|
||||
}
|
||||
@ -1071,7 +1076,7 @@ void cProtocol_1_8_0::SendPlayerSpawn(const cPlayer & a_Player)
|
||||
// Called to spawn another player for the client
|
||||
cPacketizer Pkt(*this, 0x0c); // Spawn Player packet
|
||||
Pkt.WriteVarInt32(a_Player.GetUniqueID());
|
||||
Pkt.WriteUUID(cMojangAPI::MakeUUIDShort(a_Player.GetUUID()));
|
||||
Pkt.WriteUUID(a_Player.GetUUID());
|
||||
Pkt.WriteFPInt(a_Player.GetPosX());
|
||||
Pkt.WriteFPInt(a_Player.GetPosY() + 0.001); // The "+ 0.001" is there because otherwise the player falls through the block they were standing on.
|
||||
Pkt.WriteFPInt(a_Player.GetPosZ());
|
||||
@ -2551,7 +2556,7 @@ void cProtocol_1_8_0::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer)
|
||||
|
||||
void cProtocol_1_8_0::HandlePacketSpectate(cByteBuffer &a_ByteBuffer)
|
||||
{
|
||||
AString playerUUID;
|
||||
cUUID playerUUID;
|
||||
if (!a_ByteBuffer.ReadUUID(playerUUID))
|
||||
{
|
||||
return;
|
||||
@ -3183,7 +3188,7 @@ void cProtocol_1_8_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity &
|
||||
|
||||
// The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity
|
||||
Writer.BeginCompound("Owner");
|
||||
Writer.AddString("Id", MobHeadEntity.GetOwnerUUID());
|
||||
Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString());
|
||||
Writer.AddString("Name", MobHeadEntity.GetOwnerName());
|
||||
Writer.BeginCompound("Properties");
|
||||
Writer.BeginList("textures", TAG_Compound);
|
||||
|
@ -133,7 +133,11 @@ cProtocol_1_9_0::cProtocol_1_9_0(cClientHandle * a_Client, const AString & a_Ser
|
||||
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]));
|
||||
|
||||
cUUID UUID;
|
||||
UUID.FromString(Params[2]);
|
||||
m_Client->SetUUID(UUID);
|
||||
|
||||
m_Client->SetProperties(Params[3]);
|
||||
}
|
||||
|
||||
@ -720,7 +724,7 @@ void cProtocol_1_9_0::SendLoginSuccess(void)
|
||||
|
||||
{
|
||||
cPacketizer Pkt(*this, 0x02); // Login success packet
|
||||
Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID()));
|
||||
Pkt.WriteString(m_Client->GetUUID().ToLongString());
|
||||
Pkt.WriteString(m_Client->GetUsername());
|
||||
}
|
||||
}
|
||||
@ -1094,7 +1098,7 @@ void cProtocol_1_9_0::SendPlayerSpawn(const cPlayer & a_Player)
|
||||
// Called to spawn another player for the client
|
||||
cPacketizer Pkt(*this, 0x05); // Spawn Player packet
|
||||
Pkt.WriteVarInt32(a_Player.GetUniqueID());
|
||||
Pkt.WriteUUID(cMojangAPI::MakeUUIDShort(a_Player.GetUUID()));
|
||||
Pkt.WriteUUID(a_Player.GetUUID());
|
||||
Pkt.WriteBEDouble(a_Player.GetPosX());
|
||||
Pkt.WriteBEDouble(a_Player.GetPosY() + 0.001); // The "+ 0.001" is there because otherwise the player falls through the block they were standing on.
|
||||
Pkt.WriteBEDouble(a_Player.GetPosZ());
|
||||
@ -2624,7 +2628,7 @@ void cProtocol_1_9_0::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer)
|
||||
|
||||
void cProtocol_1_9_0::HandlePacketSpectate(cByteBuffer & a_ByteBuffer)
|
||||
{
|
||||
AString playerUUID;
|
||||
cUUID playerUUID;
|
||||
if (!a_ByteBuffer.ReadUUID(playerUUID))
|
||||
{
|
||||
return;
|
||||
@ -3513,7 +3517,7 @@ void cProtocol_1_9_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity &
|
||||
|
||||
// The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity
|
||||
Writer.BeginCompound("Owner");
|
||||
Writer.AddString("Id", MobHeadEntity.GetOwnerUUID());
|
||||
Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString());
|
||||
Writer.AddString("Name", MobHeadEntity.GetOwnerName());
|
||||
Writer.BeginCompound("Properties");
|
||||
Writer.BeginList("textures", TAG_Compound);
|
||||
|
@ -92,10 +92,10 @@ protected:
|
||||
AStringVector m_Groups;
|
||||
|
||||
/** Assigned by ResolveUserUUIDs(), contains the online (Mojang) UUID of the player. */
|
||||
AString m_UUID;
|
||||
cUUID m_UUID;
|
||||
|
||||
/** Assigned by ResolveUserUUIDs(), contains the offline (generated) UUID of the player. */
|
||||
AString m_OfflineUUID;
|
||||
cUUID m_OfflineUUID;
|
||||
|
||||
|
||||
sUser(void) {}
|
||||
@ -282,15 +282,15 @@ protected:
|
||||
m_MojangAPI.GetUUIDsFromPlayerNames(PlayerNames);
|
||||
|
||||
// Assign the UUIDs back to players, remove those not resolved:
|
||||
for (sUserMap::iterator itr = m_Users.begin(); itr != m_Users.end(); ++itr)
|
||||
for (auto & User : m_Users)
|
||||
{
|
||||
AString UUID = m_MojangAPI.GetUUIDFromPlayerName(itr->second.m_Name);
|
||||
if (UUID.empty())
|
||||
cUUID UUID = m_MojangAPI.GetUUIDFromPlayerName(User.second.m_Name);
|
||||
if (UUID.IsNil())
|
||||
{
|
||||
LOGWARNING("RankMigrator: Cannot resolve player %s to online UUID, player will be left unranked in online mode", itr->second.m_Name.c_str());
|
||||
LOGWARNING("RankMigrator: Cannot resolve player %s to online UUID, player will be left unranked in online mode", User.second.m_Name.c_str());
|
||||
}
|
||||
itr->second.m_UUID = UUID;
|
||||
itr->second.m_OfflineUUID = cClientHandle::GenerateOfflineUUID(itr->second.m_Name);
|
||||
User.second.m_UUID = UUID;
|
||||
User.second.m_OfflineUUID = cClientHandle::GenerateOfflineUUID(User.second.m_Name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,7 +469,7 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI)
|
||||
|
||||
|
||||
|
||||
AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID)
|
||||
AString cRankManager::GetPlayerRankName(const cUUID & a_PlayerUUID)
|
||||
{
|
||||
ASSERT(m_IsInitialized);
|
||||
cCSLock Lock(m_CS);
|
||||
@ -477,7 +477,7 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID)
|
||||
try
|
||||
{
|
||||
SQLite::Statement stmt(m_DB, "SELECT Rank.Name FROM Rank LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID WHERE PlayerRank.PlayerUUID = ?");
|
||||
stmt.bind(1, a_PlayerUUID);
|
||||
stmt.bind(1, a_PlayerUUID.ToShortString());
|
||||
// executeStep returns false on no data
|
||||
if (!stmt.executeStep())
|
||||
{
|
||||
@ -497,7 +497,7 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID)
|
||||
|
||||
|
||||
|
||||
AString cRankManager::GetPlayerName(const AString & a_PlayerUUID)
|
||||
AString cRankManager::GetPlayerName(const cUUID & a_PlayerUUID)
|
||||
{
|
||||
ASSERT(m_IsInitialized);
|
||||
cCSLock Lock(m_CS);
|
||||
@ -506,7 +506,7 @@ AString cRankManager::GetPlayerName(const AString & a_PlayerUUID)
|
||||
{
|
||||
// Prepare the DB statement:
|
||||
SQLite::Statement stmt(m_DB, "SELECT PlayerName FROM PlayerRank WHERE PlayerUUID = ?");
|
||||
stmt.bind(1, a_PlayerUUID);
|
||||
stmt.bind(1, a_PlayerUUID.ToShortString());
|
||||
|
||||
if (stmt.executeStep())
|
||||
{
|
||||
@ -524,7 +524,7 @@ AString cRankManager::GetPlayerName(const AString & a_PlayerUUID)
|
||||
|
||||
|
||||
|
||||
AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID)
|
||||
AStringVector cRankManager::GetPlayerGroups(const cUUID & a_PlayerUUID)
|
||||
{
|
||||
ASSERT(m_IsInitialized);
|
||||
cCSLock Lock(m_CS);
|
||||
@ -539,7 +539,7 @@ AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID)
|
||||
"LEFT JOIN PlayerRank ON PlayerRank.RankID = RankPermGroup.RankID "
|
||||
"WHERE PlayerRank.PlayerUUID = ?"
|
||||
);
|
||||
stmt.bind(1, a_PlayerUUID);
|
||||
stmt.bind(1, a_PlayerUUID.ToShortString());
|
||||
|
||||
// Execute and get results:
|
||||
while (stmt.executeStep())
|
||||
@ -558,7 +558,7 @@ AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID)
|
||||
|
||||
|
||||
|
||||
AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID)
|
||||
AStringVector cRankManager::GetPlayerPermissions(const cUUID & a_PlayerUUID)
|
||||
{
|
||||
AString Rank = GetPlayerRankName(a_PlayerUUID);
|
||||
if (Rank.empty())
|
||||
@ -572,7 +572,7 @@ AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID)
|
||||
|
||||
|
||||
|
||||
AStringVector cRankManager::GetPlayerRestrictions(const AString & a_PlayerUUID)
|
||||
AStringVector cRankManager::GetPlayerRestrictions(const cUUID & a_PlayerUUID)
|
||||
{
|
||||
AString Rank = GetPlayerRankName(a_PlayerUUID);
|
||||
if (Rank.empty())
|
||||
@ -739,18 +739,24 @@ AStringVector cRankManager::GetRankRestrictions(const AString & a_RankName)
|
||||
|
||||
|
||||
|
||||
AStringVector cRankManager::GetAllPlayerUUIDs(void)
|
||||
std::vector<cUUID> cRankManager::GetAllPlayerUUIDs(void)
|
||||
{
|
||||
ASSERT(m_IsInitialized);
|
||||
cCSLock Lock(m_CS);
|
||||
|
||||
AStringVector res;
|
||||
cUUID tempUUID;
|
||||
std::vector<cUUID> res;
|
||||
try
|
||||
{
|
||||
SQLite::Statement stmt(m_DB, "SELECT PlayerUUID FROM PlayerRank ORDER BY PlayerName COLLATE NOCASE");
|
||||
while (stmt.executeStep())
|
||||
{
|
||||
res.push_back(stmt.getColumn(0).getText());
|
||||
if (!tempUUID.FromString(stmt.getColumn(0).getText()))
|
||||
{
|
||||
// Invalid UUID, ignore
|
||||
continue;
|
||||
}
|
||||
res.push_back(tempUUID);
|
||||
}
|
||||
}
|
||||
catch (const SQLite::Exception & ex)
|
||||
@ -881,7 +887,7 @@ AStringVector cRankManager::GetAllPermissionsRestrictions(void)
|
||||
|
||||
|
||||
bool cRankManager::GetPlayerMsgVisuals(
|
||||
const AString & a_PlayerUUID,
|
||||
const cUUID & a_PlayerUUID,
|
||||
AString & a_MsgPrefix,
|
||||
AString & a_MsgSuffix,
|
||||
AString & a_MsgNameColorCode
|
||||
@ -1746,11 +1752,13 @@ bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewN
|
||||
|
||||
|
||||
|
||||
void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a_PlayerName, const AString & a_RankName)
|
||||
void cRankManager::SetPlayerRank(const cUUID & a_PlayerUUID, const AString & a_PlayerName, const AString & a_RankName)
|
||||
{
|
||||
ASSERT(m_IsInitialized);
|
||||
cCSLock Lock(m_CS);
|
||||
|
||||
AString StrUUID = a_PlayerUUID.ToShortString();
|
||||
|
||||
try
|
||||
{
|
||||
// Get the rank ID:
|
||||
@ -1771,7 +1779,7 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a
|
||||
SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET RankID = ?, PlayerName = ? WHERE PlayerUUID = ?");
|
||||
stmt.bind(1, RankID);
|
||||
stmt.bind(2, a_PlayerName);
|
||||
stmt.bind(3, a_PlayerUUID);
|
||||
stmt.bind(3, StrUUID);
|
||||
if (stmt.exec() > 0)
|
||||
{
|
||||
// Successfully updated the player's rank
|
||||
@ -1782,7 +1790,7 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a
|
||||
// The player is not yet in the DB, add them:
|
||||
SQLite::Statement stmt(m_DB, "INSERT INTO PlayerRank (RankID, PlayerUUID, PlayerName) VALUES (?, ?, ?)");
|
||||
stmt.bind(1, RankID);
|
||||
stmt.bind(2, a_PlayerUUID);
|
||||
stmt.bind(2, StrUUID);
|
||||
stmt.bind(3, a_PlayerName);
|
||||
if (stmt.exec() > 0)
|
||||
{
|
||||
@ -1791,13 +1799,13 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a
|
||||
}
|
||||
|
||||
LOGWARNING("%s: Failed to set player UUID %s to rank %s.",
|
||||
__FUNCTION__, a_PlayerUUID.c_str(), a_RankName.c_str()
|
||||
__FUNCTION__, StrUUID.c_str(), a_RankName.c_str()
|
||||
);
|
||||
}
|
||||
catch (const SQLite::Exception & ex)
|
||||
{
|
||||
LOGWARNING("%s: Failed to set player UUID %s to rank %s: %s",
|
||||
__FUNCTION__, a_PlayerUUID.c_str(), a_RankName.c_str(), ex.what()
|
||||
__FUNCTION__, StrUUID.c_str(), a_RankName.c_str(), ex.what()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1806,21 +1814,23 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a
|
||||
|
||||
|
||||
|
||||
void cRankManager::RemovePlayerRank(const AString & a_PlayerUUID)
|
||||
void cRankManager::RemovePlayerRank(const cUUID & a_PlayerUUID)
|
||||
{
|
||||
ASSERT(m_IsInitialized);
|
||||
cCSLock Lock(m_CS);
|
||||
|
||||
AString StrUUID = a_PlayerUUID.ToShortString();
|
||||
|
||||
try
|
||||
{
|
||||
SQLite::Statement stmt(m_DB, "DELETE FROM PlayerRank WHERE PlayerUUID = ?");
|
||||
stmt.bind(1, a_PlayerUUID);
|
||||
stmt.bind(1, StrUUID);
|
||||
stmt.exec();
|
||||
}
|
||||
catch (const SQLite::Exception & ex)
|
||||
{
|
||||
LOGWARNING("%s: Failed to remove rank from player UUID %s: %s",
|
||||
__FUNCTION__, a_PlayerUUID.c_str(), ex.what()
|
||||
__FUNCTION__, StrUUID.c_str(), ex.what()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1948,15 +1958,17 @@ bool cRankManager::GroupExists(const AString & a_GroupName)
|
||||
|
||||
|
||||
|
||||
bool cRankManager::IsPlayerRankSet(const AString & a_PlayerUUID)
|
||||
bool cRankManager::IsPlayerRankSet(const cUUID & a_PlayerUUID)
|
||||
{
|
||||
ASSERT(m_IsInitialized);
|
||||
cCSLock Lock(m_CS);
|
||||
|
||||
AString StrUUID = a_PlayerUUID.ToShortString();
|
||||
|
||||
try
|
||||
{
|
||||
SQLite::Statement stmt(m_DB, "SELECT * FROM PlayerRank WHERE PlayerUUID = ?");
|
||||
stmt.bind(1, a_PlayerUUID);
|
||||
stmt.bind(1, StrUUID);
|
||||
if (stmt.executeStep())
|
||||
{
|
||||
// The player UUID was found, they have a rank
|
||||
@ -1965,7 +1977,7 @@ bool cRankManager::IsPlayerRankSet(const AString & a_PlayerUUID)
|
||||
}
|
||||
catch (const SQLite::Exception & ex)
|
||||
{
|
||||
LOGWARNING("%s: Failed to query DB for player UUID %s: %s", __FUNCTION__, a_PlayerUUID.c_str(), ex.what());
|
||||
LOGWARNING("%s: Failed to query DB for player UUID %s: %s", __FUNCTION__, StrUUID.c_str(), ex.what());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -2068,7 +2080,7 @@ bool cRankManager::IsRestrictionInGroup(const AString & a_Restriction, const ASt
|
||||
|
||||
|
||||
|
||||
void cRankManager::NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID)
|
||||
void cRankManager::NotifyNameUUID(const AString & a_PlayerName, const cUUID & a_UUID)
|
||||
{
|
||||
ASSERT(m_IsInitialized);
|
||||
cCSLock Lock(m_CS);
|
||||
@ -2077,7 +2089,7 @@ void cRankManager::NotifyNameUUID(const AString & a_PlayerName, const AString &
|
||||
{
|
||||
SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET PlayerName = ? WHERE PlayerUUID = ?");
|
||||
stmt.bind(1, a_PlayerName);
|
||||
stmt.bind(2, a_UUID);
|
||||
stmt.bind(2, a_UUID.ToShortString());
|
||||
stmt.exec();
|
||||
}
|
||||
catch (const SQLite::Exception & ex)
|
||||
@ -2161,16 +2173,18 @@ void cRankManager::ClearPlayerRanks(void)
|
||||
|
||||
|
||||
|
||||
bool cRankManager::UpdatePlayerName(const AString & a_PlayerUUID, const AString & a_NewPlayerName)
|
||||
bool cRankManager::UpdatePlayerName(const cUUID & a_PlayerUUID, const AString & a_NewPlayerName)
|
||||
{
|
||||
ASSERT(m_IsInitialized);
|
||||
cCSLock Lock(m_CS);
|
||||
|
||||
AString StrUUID = a_PlayerUUID.ToShortString();
|
||||
|
||||
try
|
||||
{
|
||||
SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET PlayerName = ? WHERE PlayerUUID = ?");
|
||||
stmt.bind(1, a_NewPlayerName);
|
||||
stmt.bind(2, a_PlayerUUID);
|
||||
stmt.bind(2, StrUUID);
|
||||
if (stmt.exec() > 0)
|
||||
{
|
||||
// The player name was changed, returns true
|
||||
@ -2179,7 +2193,7 @@ bool cRankManager::UpdatePlayerName(const AString & a_PlayerUUID, const AString
|
||||
}
|
||||
catch (const SQLite::Exception & ex)
|
||||
{
|
||||
LOGWARNING("%s: Failed to update player name from UUID %s: %s", __FUNCTION__, a_PlayerUUID.c_str(), ex.what());
|
||||
LOGWARNING("%s: Failed to update player name from UUID %s: %s", __FUNCTION__, StrUUID.c_str(), ex.what());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class cUUID;
|
||||
class cMojangAPI;
|
||||
|
||||
|
||||
@ -58,22 +58,22 @@ public:
|
||||
|
||||
/** Returns the name of the rank that the specified player has assigned to them.
|
||||
If the player has no rank assigned, returns an empty string (NOT the default rank). */
|
||||
AString GetPlayerRankName(const AString & a_PlayerUUID);
|
||||
AString GetPlayerRankName(const cUUID & a_PlayerUUID);
|
||||
|
||||
/** Returns the last name that the specified player has.
|
||||
An empty string is returned if the player isn't in the database. */
|
||||
AString GetPlayerName(const AString & a_PlayerUUID);
|
||||
AString GetPlayerName(const cUUID & a_PlayerUUID);
|
||||
|
||||
/** Returns the names of Groups that the specified player has assigned to them. */
|
||||
AStringVector GetPlayerGroups(const AString & a_PlayerUUID);
|
||||
AStringVector GetPlayerGroups(const cUUID & a_PlayerUUID);
|
||||
|
||||
/** Returns the permissions that the specified player has assigned to them.
|
||||
If the player has no rank assigned to them, returns the default rank's permissions. */
|
||||
AStringVector GetPlayerPermissions(const AString & a_PlayerUUID);
|
||||
AStringVector GetPlayerPermissions(const cUUID & a_PlayerUUID);
|
||||
|
||||
/** Returns the restrictions that the specified player has assigned to them.
|
||||
If the player has no rank assigned to them, returns the default rank's restrictions. */
|
||||
AStringVector GetPlayerRestrictions(const AString & a_PlayerUUID);
|
||||
AStringVector GetPlayerRestrictions(const cUUID & a_PlayerUUID);
|
||||
|
||||
/** Returns the names of groups that the specified rank has assigned to it.
|
||||
Returns an empty vector if the rank doesn't exist. */
|
||||
@ -95,8 +95,8 @@ public:
|
||||
Returns an empty vector if the rank doesn't exist. Any non-existent groups are ignored. */
|
||||
AStringVector GetRankRestrictions(const AString & a_RankName);
|
||||
|
||||
/** Returns the short uuids of all defined players. The returned players are ordered by their name (NOT their UUIDs). */
|
||||
AStringVector GetAllPlayerUUIDs(void);
|
||||
/** Returns the uuids of all defined players. The returned players are ordered by their name (NOT their UUIDs). */
|
||||
std::vector<cUUID> GetAllPlayerUUIDs(void);
|
||||
|
||||
/** Returns the names of all defined ranks. */
|
||||
AStringVector GetAllRanks(void);
|
||||
@ -116,7 +116,7 @@ public:
|
||||
/** Returns the message visuals (prefix, postfix, color) for the specified player.
|
||||
Returns true if the visuals were read from the DB, false if not (player not found etc). */
|
||||
bool GetPlayerMsgVisuals(
|
||||
const AString & a_PlayerUUID,
|
||||
const cUUID & a_PlayerUUID,
|
||||
AString & a_MsgPrefix,
|
||||
AString & a_MsgSuffix,
|
||||
AString & a_MsgNameColorCode
|
||||
@ -199,13 +199,13 @@ public:
|
||||
Note that this doesn't change the cPlayer if the player is already connected, you need to update all the
|
||||
cPlayer instances manually.
|
||||
The PlayerName is provided for reference, so that GetRankPlayerNames() can work. */
|
||||
void SetPlayerRank(const AString & a_PlayerUUID, const AString & a_PlayerName, const AString & a_RankName);
|
||||
void SetPlayerRank(const cUUID & a_PlayerUUID, const AString & a_PlayerName, const AString & a_RankName);
|
||||
|
||||
/** Removes the player's rank assignment. The player is left without a rank.
|
||||
Note that this doesn't change the cPlayer instances for the already connected players, you need to update
|
||||
all the instances manually.
|
||||
No action if the player has no rank assigned to them already. */
|
||||
void RemovePlayerRank(const AString & a_PlayerUUID);
|
||||
void RemovePlayerRank(const cUUID & a_PlayerUUID);
|
||||
|
||||
/** Sets the message visuals of an existing rank. No action if the rank name is not found. */
|
||||
void SetRankVisuals(
|
||||
@ -231,7 +231,7 @@ public:
|
||||
bool GroupExists(const AString & a_GroupName);
|
||||
|
||||
/** Returns true iff the specified player has a rank assigned to them in the DB. */
|
||||
bool IsPlayerRankSet(const AString & a_PlayerUUID);
|
||||
bool IsPlayerRankSet(const cUUID & a_PlayerUUID);
|
||||
|
||||
/** Returns true iff the specified rank contains the specified group. */
|
||||
bool IsGroupInRank(const AString & a_GroupName, const AString & a_RankName);
|
||||
@ -243,7 +243,7 @@ public:
|
||||
bool IsRestrictionInGroup(const AString & a_Restriction, const AString & a_GroupName);
|
||||
|
||||
/** Called by cMojangAPI whenever the playername-uuid pairing is discovered. Updates the DB. */
|
||||
void NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID);
|
||||
void NotifyNameUUID(const AString & a_PlayerName, const cUUID & a_UUID);
|
||||
|
||||
/** Sets the specified rank as the default rank.
|
||||
Returns true on success, false on failure (rank not found). */
|
||||
@ -257,7 +257,7 @@ public:
|
||||
void ClearPlayerRanks(void);
|
||||
|
||||
/** Updates the playername that is saved with this uuid. Returns false if a error occurred */
|
||||
bool UpdatePlayerName(const AString & a_PlayerUUID, const AString & a_NewPlayerName);
|
||||
bool UpdatePlayerName(const cUUID & a_PlayerUUID, const AString & a_NewPlayerName);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -676,7 +676,7 @@ void cRoot::KickUser(int a_ClientID, const AString & a_Reason)
|
||||
|
||||
|
||||
|
||||
void cRoot::AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties)
|
||||
void cRoot::AuthenticateUser(int a_ClientID, const AString & a_Name, const cUUID & a_UUID, const Json::Value & a_Properties)
|
||||
{
|
||||
m_Server->AuthenticateUser(a_ClientID, a_Name, a_UUID, a_Properties);
|
||||
}
|
||||
@ -820,7 +820,7 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac
|
||||
|
||||
|
||||
|
||||
bool cRoot::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback)
|
||||
bool cRoot::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback & a_Callback)
|
||||
{
|
||||
for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr)
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ class cCommandOutputCallback;
|
||||
class cCompositeChat;
|
||||
class cSettingsRepositoryInterface;
|
||||
class cDeadlockDetect;
|
||||
class cUUID;
|
||||
|
||||
typedef cItemCallback<cPlayer> cPlayerListCallback;
|
||||
typedef cItemCallback<cWorld> cWorldListCallback;
|
||||
@ -123,7 +124,7 @@ public:
|
||||
void KickUser(int a_ClientID, const AString & a_Reason);
|
||||
|
||||
/** Called by cAuthenticator to auth the specified user */
|
||||
void AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties);
|
||||
void AuthenticateUser(int a_ClientID, const AString & a_Name, const cUUID & a_UUID, const Json::Value & a_Properties);
|
||||
|
||||
/** Executes commands queued in the command queue */
|
||||
void TickCommands(void);
|
||||
@ -141,7 +142,7 @@ public:
|
||||
bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
|
||||
/** Finds the player over his uuid and calls the callback */
|
||||
bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
bool DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
|
||||
/** Finds the player using it's complete username and calls the callback */
|
||||
bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback);
|
||||
|
@ -622,7 +622,7 @@ void cServer::KickUser(int a_ClientID, const AString & a_Reason)
|
||||
|
||||
|
||||
|
||||
void cServer::AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties)
|
||||
void cServer::AuthenticateUser(int a_ClientID, const AString & a_Name, const cUUID & a_UUID, const Json::Value & a_Properties)
|
||||
{
|
||||
cCSLock Lock(m_CSClients);
|
||||
|
||||
|
@ -39,6 +39,7 @@ typedef std::list<cClientHandlePtr> cClientHandlePtrs;
|
||||
typedef std::list<cClientHandle *> cClientHandles;
|
||||
class cCommandOutputCallback;
|
||||
class cSettingsRepositoryInterface;
|
||||
class cUUID;
|
||||
|
||||
|
||||
namespace Json
|
||||
@ -101,7 +102,7 @@ public:
|
||||
void KickUser(int a_ClientID, const AString & a_Reason);
|
||||
|
||||
/** Authenticates the specified user, called by cAuthenticator */
|
||||
void AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties);
|
||||
void AuthenticateUser(int a_ClientID, const AString & a_Name, const cUUID & a_UUID, const Json::Value & a_Properties);
|
||||
|
||||
const AString & GetServerID(void) const { return m_ServerID; } // tolua_export
|
||||
|
||||
|
283
src/UUID.cpp
Normal file
283
src/UUID.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
// UUID.h
|
||||
|
||||
// Defines the cUUID class representing a Universally Unique Identifier
|
||||
|
||||
#include "Globals.h"
|
||||
#include "UUID.h"
|
||||
|
||||
#include "polarssl/md5.h"
|
||||
|
||||
|
||||
/** UUID normalised in textual form. */
|
||||
struct sShortUUID
|
||||
{
|
||||
char Data[32]{};
|
||||
bool IsValid = false;
|
||||
};
|
||||
|
||||
/** Returns the given UUID in shortened form with IsValid indicating success.
|
||||
Doesn't check digits are hexadecimal but does check dashes if long form. */
|
||||
static sShortUUID ShortenUUID(const AString & a_StringUUID)
|
||||
{
|
||||
sShortUUID UUID;
|
||||
switch (a_StringUUID.size())
|
||||
{
|
||||
case 32:
|
||||
{
|
||||
// Already a short UUID
|
||||
std::memcpy(UUID.Data, a_StringUUID.data(), 32);
|
||||
UUID.IsValid = true;
|
||||
break;
|
||||
}
|
||||
case 36:
|
||||
{
|
||||
// Long UUID, confirm dashed
|
||||
if (
|
||||
(a_StringUUID[ 8] != '-') ||
|
||||
(a_StringUUID[13] != '-') ||
|
||||
(a_StringUUID[18] != '-') ||
|
||||
(a_StringUUID[23] != '-')
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Copy everying but the dashes from the string
|
||||
std::memcpy(UUID.Data, a_StringUUID.data(), 8);
|
||||
std::memcpy(UUID.Data + 8, a_StringUUID.data() + 9, 4);
|
||||
std::memcpy(UUID.Data + 12, a_StringUUID.data() + 14, 4);
|
||||
std::memcpy(UUID.Data + 16, a_StringUUID.data() + 19, 4);
|
||||
std::memcpy(UUID.Data + 20, a_StringUUID.data() + 24, 12);
|
||||
UUID.IsValid = true;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return UUID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Returns the integer value of the hex digit or 0xff if invalid. */
|
||||
static Byte FromHexDigit(char a_Hex)
|
||||
{
|
||||
if (('0' <= a_Hex) && (a_Hex <= '9'))
|
||||
{
|
||||
return static_cast<Byte>(a_Hex - '0');
|
||||
}
|
||||
if (('a' <= a_Hex) && (a_Hex <= 'f'))
|
||||
{
|
||||
return static_cast<Byte>(a_Hex - 'a');
|
||||
}
|
||||
if (('A' <= a_Hex) && (a_Hex <= 'F'))
|
||||
{
|
||||
return static_cast<Byte>(a_Hex - 'A');
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** From a number in the range [0, 16), returns the corresponding hex digit in lowercase. */
|
||||
static char ToHexDigit(UInt8 a_Nibble)
|
||||
{
|
||||
ASSERT((a_Nibble & 0xf0) == 0);
|
||||
return static_cast<char>(
|
||||
(a_Nibble < 10) ?
|
||||
('0' + a_Nibble) :
|
||||
('a' + (a_Nibble - 10))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cUUID:
|
||||
|
||||
bool cUUID::FromString(const AString & a_StringUUID)
|
||||
{
|
||||
sShortUUID Norm = ShortenUUID(a_StringUUID);
|
||||
if (!Norm.IsValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::array<Byte, 16> ParsedUUID{{0}};
|
||||
for (size_t i = 0; i != m_UUID.size(); ++i)
|
||||
{
|
||||
Byte HighNibble = FromHexDigit(Norm.Data[2 * i ]);
|
||||
Byte LowNibble = FromHexDigit(Norm.Data[2 * i + 1]);
|
||||
if ((HighNibble > 0x0f) || (LowNibble > 0x0f))
|
||||
{
|
||||
// Invalid hex digit
|
||||
return false;
|
||||
}
|
||||
|
||||
ParsedUUID[i] = static_cast<Byte>((HighNibble << 4) | LowNibble);
|
||||
}
|
||||
|
||||
// Parsed successfully
|
||||
m_UUID = ParsedUUID;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cUUID::ToShortString() const
|
||||
{
|
||||
AString ShortString(32, '\0');
|
||||
for (size_t i = 0; i != m_UUID.size(); ++i)
|
||||
{
|
||||
Byte HighNibble = (m_UUID[i] >> 4) & 0x0f;
|
||||
Byte LowNibble = m_UUID[i] & 0x0f;
|
||||
|
||||
ShortString[2 * i ] = ToHexDigit(HighNibble);
|
||||
ShortString[2 * i + 1] = ToHexDigit(LowNibble);
|
||||
}
|
||||
return ShortString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cUUID::ToLongString() const
|
||||
{
|
||||
AString LongString = ToShortString();
|
||||
LongString.reserve(36);
|
||||
|
||||
// Convert to long form by inserting the dashes
|
||||
auto First = LongString.begin();
|
||||
LongString.insert(First + 8, '-');
|
||||
LongString.insert(First + 13, '-');
|
||||
LongString.insert(First + 18, '-');
|
||||
LongString.insert(First + 23, '-');
|
||||
|
||||
return LongString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UInt8 cUUID::Version() const
|
||||
{
|
||||
return static_cast<UInt8>((m_UUID[6] >> 4) & 0x0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UInt8 cUUID::Variant() const
|
||||
{
|
||||
const Byte VariantBits = static_cast<Byte>((m_UUID[9] >> 5) & 0x07);
|
||||
|
||||
/* Variant bits format:
|
||||
bits | variant | Description
|
||||
-----|---------|----------------------
|
||||
0xx | 0 | Obsolete
|
||||
10x | 1 | Standard UUID
|
||||
110 | 2 | Microsoft Legacy GUID
|
||||
111 | 3 | Reserved
|
||||
*/
|
||||
|
||||
if ((VariantBits & 0x04) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if ((VariantBits & 0x02) == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if ((VariantBits & 0x01) == 0)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::array<Byte, 16> cUUID::ToRaw() const
|
||||
{
|
||||
std::array<Byte, 16> Raw(m_UUID);
|
||||
if (Variant() == 2)
|
||||
{
|
||||
// Convert to microsoft mixed-endian format
|
||||
// First 3 components are host-endian, last 2 are network
|
||||
auto First = reinterpret_cast<UInt32 *>(Raw.data());
|
||||
*First = ntohl(*First);
|
||||
|
||||
auto Second = reinterpret_cast<UInt16 *>(&Raw[4]);
|
||||
*Second = ntohs(*Second);
|
||||
|
||||
auto Third = Second + 1;
|
||||
*Third = ntohs(*Third);
|
||||
}
|
||||
|
||||
return Raw;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cUUID::FromRaw(const std::array<Byte, 16> & a_Raw)
|
||||
{
|
||||
m_UUID = a_Raw;
|
||||
if (Variant() != 2)
|
||||
{
|
||||
// Standard big-endian formats
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert from microsoft mixed-endian format
|
||||
// First 3 components are host-endian, last 2 are network
|
||||
auto First = reinterpret_cast<UInt32 *>(m_UUID.data());
|
||||
*First = htonl(*First);
|
||||
|
||||
auto Second = reinterpret_cast<UInt16 *>(&m_UUID[4]);
|
||||
*Second = htons(*Second);
|
||||
|
||||
auto Third = Second + 1;
|
||||
*Third = htons(*Third);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cUUID cUUID::GenerateVersion3(const AString & a_Name)
|
||||
{
|
||||
cUUID UUID;
|
||||
// Generate an md5 checksum, and use it as base for the ID:
|
||||
const Byte * ByteString = reinterpret_cast<const Byte *>(a_Name.data());
|
||||
md5(ByteString, a_Name.length(), UUID.m_UUID.data());
|
||||
|
||||
// Insert version number
|
||||
UUID.m_UUID[6] = (UUID.m_UUID[6] & 0x0f) | 0x30;
|
||||
|
||||
/* Insert variant number
|
||||
Note that by using 1000 instead of 10xx we are losing 2 bits
|
||||
but this is needed for compatibility with the old string uuid generator */
|
||||
UUID.m_UUID[8] = (UUID.m_UUID[8] & 0x0f) | 0x80;
|
||||
|
||||
return UUID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
100
src/UUID.h
Normal file
100
src/UUID.h
Normal file
@ -0,0 +1,100 @@
|
||||
// UUID.h
|
||||
|
||||
// Declares the cUUID class representing a Universally Unique Identifier
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
// tolua_begin
|
||||
|
||||
class cUUID
|
||||
{
|
||||
public:
|
||||
/** Default constructed "nil" UUID */
|
||||
cUUID():
|
||||
m_UUID()
|
||||
{
|
||||
}
|
||||
|
||||
/** Lexicographically compare bytes with another UUID.
|
||||
Returns:
|
||||
0 when equal to a_Other,
|
||||
< 0 when less than a_Other,
|
||||
> 0 when greater than a_Other */
|
||||
int Compare(const cUUID & a_Other) const
|
||||
{
|
||||
return std::memcmp(m_UUID.data(), a_Other.m_UUID.data(), m_UUID.size());
|
||||
}
|
||||
|
||||
/** Returns true if this contains the "nil" UUID with all bits set to 0 */
|
||||
bool IsNil() const
|
||||
{
|
||||
return (m_UUID == std::array<Byte, 16>{{0}});
|
||||
}
|
||||
|
||||
/** Tries to interpret the string as a short or long form UUID and assign from it.
|
||||
On error, returns false and does not set the value. */
|
||||
bool FromString(const AString & a_StringUUID);
|
||||
|
||||
/** Converts the UUID to a short form string (i.e without dashes). */
|
||||
AString ToShortString() const;
|
||||
|
||||
/** Converts the UUID to a long form string (i.e. with dashes). */
|
||||
AString ToLongString() const;
|
||||
|
||||
/** Returns the version number of the UUID. */
|
||||
UInt8 Version() const;
|
||||
|
||||
/** Returns the variant number of the UUID. */
|
||||
UInt8 Variant() const;
|
||||
|
||||
/** Generates a version 3, variant 1 UUID based on the md5 hash of a_Name. */
|
||||
static cUUID GenerateVersion3(const AString & a_Name);
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Converts UUID to raw memory representation, respecting UUID variant. */
|
||||
std::array<Byte, 16> ToRaw() const;
|
||||
|
||||
/** Assigns from raw memory representation, respecting UUID variant. */
|
||||
void FromRaw(const std::array<Byte, 16> & a_Raw);
|
||||
|
||||
private:
|
||||
/** Binary UUID stored big-endian. */
|
||||
std::array<Byte, 16> m_UUID;
|
||||
}; // tolua_export
|
||||
|
||||
|
||||
// Comparison operators:
|
||||
|
||||
inline bool operator == (const cUUID & a_Lhs, const cUUID & a_Rhs)
|
||||
{
|
||||
return (a_Lhs.Compare(a_Rhs) == 0);
|
||||
}
|
||||
|
||||
inline bool operator != (const cUUID & a_Lhs, const cUUID & a_Rhs)
|
||||
{
|
||||
return (a_Lhs.Compare(a_Rhs) != 0);
|
||||
}
|
||||
|
||||
inline bool operator < (const cUUID & a_Lhs, const cUUID & a_Rhs)
|
||||
{
|
||||
return (a_Lhs.Compare(a_Rhs) < 0);
|
||||
}
|
||||
|
||||
inline bool operator <= (const cUUID & a_Lhs, const cUUID & a_Rhs)
|
||||
{
|
||||
return (a_Lhs.Compare(a_Rhs) <= 0);
|
||||
}
|
||||
|
||||
inline bool operator > (const cUUID & a_Lhs, const cUUID & a_Rhs)
|
||||
{
|
||||
return (a_Lhs.Compare(a_Rhs) > 0);
|
||||
}
|
||||
|
||||
inline bool operator >= (const cUUID & a_Lhs, const cUUID & a_Rhs)
|
||||
{
|
||||
return (a_Lhs.Compare(a_Rhs) >= 0);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "SetChunkData.h"
|
||||
#include "DeadlockDetect.h"
|
||||
#include "LineBlockTracer.h"
|
||||
#include "UUID.h"
|
||||
|
||||
// Serializers
|
||||
#include "WorldStorage/ScoreboardSerializer.h"
|
||||
@ -3241,7 +3242,7 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa
|
||||
|
||||
|
||||
|
||||
bool cWorld::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback)
|
||||
bool cWorld::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback & a_Callback)
|
||||
{
|
||||
return DoWithPlayerByUUID(a_PlayerUUID, std::bind(&cPlayerListCallback::Item, &a_Callback, std::placeholders::_1));
|
||||
}
|
||||
@ -3250,7 +3251,7 @@ bool cWorld::DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallbac
|
||||
|
||||
|
||||
|
||||
bool cWorld::DoWithPlayerByUUID(const AString & a_PlayerUUID, cLambdaPlayerCallback a_Callback)
|
||||
bool cWorld::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cLambdaPlayerCallback a_Callback)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
|
@ -50,6 +50,7 @@ class cCompositeChat;
|
||||
class cSetChunkData;
|
||||
class cBroadcaster;
|
||||
class cDeadlockDetect;
|
||||
class cUUID;
|
||||
|
||||
typedef std::list< cPlayer * > cPlayerList;
|
||||
typedef std::list< std::pair< std::unique_ptr<cPlayer>, cWorld * > > cAwaitingPlayerList;
|
||||
@ -287,8 +288,8 @@ public:
|
||||
cPlayer * FindClosestPlayer(Vector3d a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true);
|
||||
|
||||
/** Finds the player over his uuid and calls the callback */
|
||||
bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cLambdaPlayerCallback a_Callback); // Lambda version
|
||||
bool DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
bool DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cLambdaPlayerCallback a_Callback); // Lambda version
|
||||
|
||||
void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "EnchantmentSerializer.h"
|
||||
#include "../ItemGrid.h"
|
||||
#include "../StringCompression.h"
|
||||
#include "../UUID.h"
|
||||
#include "FastNBT.h"
|
||||
|
||||
#include "../BlockEntities/BeaconEntity.h"
|
||||
@ -382,7 +383,7 @@ void cNBTChunkSerializer::AddMobHeadEntity(cMobHeadEntity * a_MobHead)
|
||||
|
||||
// The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity
|
||||
m_Writer.BeginCompound("Owner");
|
||||
m_Writer.AddString("Id", a_MobHead->GetOwnerUUID());
|
||||
m_Writer.AddString("Id", a_MobHead->GetOwnerUUID().ToShortString());
|
||||
m_Writer.AddString("Name", a_MobHead->GetOwnerName());
|
||||
m_Writer.BeginCompound("Properties");
|
||||
m_Writer.BeginList("textures", TAG_Compound);
|
||||
@ -679,9 +680,9 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
|
||||
{
|
||||
m_Writer.AddString("Owner", Wolf->GetOwnerName());
|
||||
}
|
||||
if (!Wolf->GetOwnerUUID().empty())
|
||||
if (!Wolf->GetOwnerUUID().IsNil())
|
||||
{
|
||||
m_Writer.AddString("OwnerUUID", Wolf->GetOwnerUUID());
|
||||
m_Writer.AddString("OwnerUUID", Wolf->GetOwnerUUID().ToShortString());
|
||||
}
|
||||
m_Writer.AddByte("Sitting", Wolf->IsSitting() ? 1 : 0);
|
||||
m_Writer.AddByte("Angry", Wolf->IsAngry() ? 1 : 0);
|
||||
@ -709,9 +710,9 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
|
||||
{
|
||||
m_Writer.AddString("Owner", Ocelot->GetOwnerName());
|
||||
}
|
||||
if (!Ocelot->GetOwnerUUID().empty())
|
||||
if (!Ocelot->GetOwnerUUID().IsNil())
|
||||
{
|
||||
m_Writer.AddString("OwnerUUID", Ocelot->GetOwnerUUID());
|
||||
m_Writer.AddString("OwnerUUID", Ocelot->GetOwnerUUID().ToShortString());
|
||||
}
|
||||
m_Writer.AddByte("Sitting", Ocelot->IsSitting() ? 1 : 0);
|
||||
m_Writer.AddInt ("CatType", Ocelot->GetOcelotType());
|
||||
|
@ -1398,12 +1398,13 @@ cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||
int ownerLine = a_NBT.FindChildByName(a_TagIdx, "Owner");
|
||||
if (ownerLine >= 0)
|
||||
{
|
||||
AString OwnerName, OwnerUUID, OwnerTexture, OwnerTextureSignature;
|
||||
AString OwnerName, OwnerTexture, OwnerTextureSignature;
|
||||
cUUID OwnerUUID;
|
||||
|
||||
currentLine = a_NBT.FindChildByName(ownerLine, "Id");
|
||||
if (currentLine >= 0)
|
||||
{
|
||||
OwnerUUID = a_NBT.GetString(currentLine);
|
||||
OwnerUUID.FromString(a_NBT.GetString(currentLine));
|
||||
}
|
||||
|
||||
currentLine = a_NBT.FindChildByName(ownerLine, "Name");
|
||||
@ -2526,7 +2527,7 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
}
|
||||
|
||||
auto OwnerInfo = LoadEntityOwner(a_NBT, a_TagIdx);
|
||||
if (!OwnerInfo.first.empty() && !OwnerInfo.second.empty())
|
||||
if (!OwnerInfo.first.empty() && !OwnerInfo.second.IsNil())
|
||||
{
|
||||
Monster->SetOwner(OwnerInfo.first, OwnerInfo.second);
|
||||
Monster->SetIsTame(true);
|
||||
@ -2927,7 +2928,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N
|
||||
}
|
||||
|
||||
auto OwnerInfo = LoadEntityOwner(a_NBT, a_TagIdx);
|
||||
if (!OwnerInfo.first.empty() && !OwnerInfo.second.empty())
|
||||
if (!OwnerInfo.first.empty() && !OwnerInfo.second.IsNil())
|
||||
{
|
||||
Monster->SetOwner(OwnerInfo.first, OwnerInfo.second);
|
||||
Monster->SetIsTame(true);
|
||||
@ -3064,43 +3065,39 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
|
||||
|
||||
|
||||
std::pair<AString, AString> cWSSAnvil::LoadEntityOwner(const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
std::pair<AString, cUUID> cWSSAnvil::LoadEntityOwner(const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
// Load the owner information. OwnerUUID or Owner may be specified, possibly both:
|
||||
AString OwnerUUID, OwnerName;
|
||||
AString OwnerName;
|
||||
cUUID OwnerUUID;
|
||||
int OwnerUUIDIdx = a_NBT.FindChildByName(a_TagIdx, "OwnerUUID");
|
||||
if (OwnerUUIDIdx > 0)
|
||||
{
|
||||
OwnerUUID = a_NBT.GetString(OwnerUUIDIdx);
|
||||
OwnerUUID.FromString(a_NBT.GetString(OwnerUUIDIdx));
|
||||
}
|
||||
int OwnerIdx = a_NBT.FindChildByName(a_TagIdx, "Owner");
|
||||
if (OwnerIdx > 0)
|
||||
{
|
||||
OwnerName = a_NBT.GetString(OwnerIdx);
|
||||
}
|
||||
if (OwnerName.empty() && OwnerUUID.empty())
|
||||
if (OwnerName.empty() && OwnerUUID.IsNil())
|
||||
{
|
||||
// There is no owner, bail out:
|
||||
return std::pair<AString, AString>();
|
||||
return {};
|
||||
}
|
||||
|
||||
// Convert name to UUID, if needed:
|
||||
if (OwnerUUID.empty())
|
||||
if (OwnerUUID.IsNil())
|
||||
{
|
||||
// This entity has only playername stored (pre-1.7.6), look up the UUID
|
||||
// The lookup is blocking, but we're running in a separate thread, so it's ok
|
||||
OwnerUUID = cRoot::Get()->GetMojangAPI().GetUUIDFromPlayerName(OwnerName);
|
||||
if (OwnerUUID.empty())
|
||||
if (OwnerUUID.IsNil())
|
||||
{
|
||||
// Not a known player, un-tame the entity by bailing out
|
||||
return std::pair<AString, AString>();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normalize the UUID:
|
||||
OwnerUUID = cMojangAPI::MakeUUIDShort(OwnerUUID);
|
||||
}
|
||||
|
||||
// Convert UUID to name, if needed:
|
||||
if (OwnerName.empty())
|
||||
@ -3110,11 +3107,11 @@ std::pair<AString, AString> cWSSAnvil::LoadEntityOwner(const cParsedNBT & a_NBT,
|
||||
if (OwnerName.empty())
|
||||
{
|
||||
// Not a known player, un-tame the entity by bailing out
|
||||
return std::pair<AString, AString>();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair(OwnerName, OwnerUUID);
|
||||
return { OwnerName, OwnerUUID };
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@ class cItemGrid;
|
||||
class cMonster;
|
||||
class cProjectileEntity;
|
||||
class cHangingEntity;
|
||||
class cUUID;
|
||||
|
||||
|
||||
|
||||
@ -230,8 +231,8 @@ protected:
|
||||
void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
/** Loads the owner name and UUID from the entity at the specified NBT tag.
|
||||
Returns a pair of {name, uuid}. If the entity is not owned, both are empty strings. */
|
||||
std::pair<AString, AString> LoadEntityOwner(const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
Returns a pair of {name, uuid}. If the entity is not owned, name is an empty string and uuid is nil. */
|
||||
std::pair<AString, cUUID> LoadEntityOwner(const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
/** Loads entity common data from the NBT compound; returns true if successful */
|
||||
bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
@ -19,6 +19,7 @@ set (SHARED_HDRS
|
||||
|
||||
set (SRCS
|
||||
ByteBufferTest.cpp
|
||||
Stubs.cpp
|
||||
)
|
||||
|
||||
source_group("Shared" FILES ${SHARED_SRCS} ${SHARED_HDRS})
|
||||
|
16
tests/ByteBuffer/Stubs.cpp
Normal file
16
tests/ByteBuffer/Stubs.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
// Stubs.cpp
|
||||
|
||||
// Implements stubs of various Cuberite methods that are needed for linking but not for runtime
|
||||
// This is required so that we don't bring in the entire Cuberite via dependencies
|
||||
|
||||
#include "Globals.h"
|
||||
#include "UUID.h"
|
||||
|
||||
|
||||
|
||||
|
||||
void cUUID::FromRaw(const std::array<Byte, 16> &){}
|
||||
|
||||
|
||||
|
@ -2,3 +2,8 @@
|
||||
// LuaState_Declaration.inc
|
||||
|
||||
// Dummy include file needed for LuaState to compile successfully
|
||||
|
||||
|
||||
bool GetStackValue(int, cUUID *&);
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@ class cPluginLua;
|
||||
class cBoundingBox;
|
||||
template <typename T> class cItemCallback;
|
||||
class cEntity;
|
||||
class cUUID;
|
||||
|
||||
|
||||
|
||||
|
@ -6,9 +6,11 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BlockInfo.h"
|
||||
#include "UUID.h"
|
||||
#include "Bindings.h"
|
||||
#include "Bindings/DeprecatedBindings.h"
|
||||
#include "Bindings/LuaJson.h"
|
||||
#include "Bindings/LuaState.h"
|
||||
#include "Bindings/ManualBindings.h"
|
||||
#include "BlockEntities/BlockEntity.h"
|
||||
#include "Blocks/BlockHandler.h"
|
||||
@ -332,3 +334,21 @@ cBlockEntity * cBlockEntity::Clone(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int, cUUID *&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cUUID::FromString(const AString&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2,3 +2,8 @@
|
||||
// LuaState_Declaration.inc
|
||||
|
||||
// Dummy include file needed for LuaState to compile successfully
|
||||
|
||||
|
||||
bool GetStackValue(int, cUUID *&);
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@ class cPluginLua;
|
||||
class cBoundingBox;
|
||||
template <typename T> class cItemCallback;
|
||||
class cEntity;
|
||||
class cUUID;
|
||||
|
||||
|
||||
|
||||
|
@ -7,13 +7,14 @@
|
||||
#include "Globals.h"
|
||||
#include "BlockInfo.h"
|
||||
#include "Bindings.h"
|
||||
#include "DeadlockDetect.h"
|
||||
#include "UUID.h"
|
||||
#include "Bindings/DeprecatedBindings.h"
|
||||
#include "Bindings/LuaJson.h"
|
||||
#include "Bindings/ManualBindings.h"
|
||||
#include "BlockEntities/BlockEntity.h"
|
||||
#include "Blocks/BlockHandler.h"
|
||||
#include "Generating/ChunkDesc.h"
|
||||
#include "DeadlockDetect.h"
|
||||
|
||||
|
||||
|
||||
@ -333,3 +334,21 @@ cBlockEntity * cBlockEntity::Clone(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int, cUUID *&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cUUID::FromString(const AString &)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user