Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Forge protocol handshake support #3869

Merged
merged 180 commits into from Aug 27, 2017
Merged
Show file tree
Hide file tree
Changes from 167 commits
Commits
Show all changes
180 commits
Select commit Hold shift + click to select a range
a53734e
Send modinfo/modList in 1.12 ping response
satoshinm Jul 9, 2017
376c525
Refactor to new ForgeHandshake class
satoshinm Jul 9, 2017
5f4f050
Add modinfo to ping response of all protocol versions
satoshinm Jul 9, 2017
24adfe9
Move cForgeHandshake to instance variable of Protocol
satoshinm Jul 9, 2017
2c0dd69
Detect Forge client connection (\0FML\0 in server name)
satoshinm Jul 9, 2017
c6eff1d
Send plugin channel registration to Forge client after login success
satoshinm Jul 9, 2017
e73c227
Refactor sending plugin channels into cForgeHandshake::onLoginSuccess
satoshinm Jul 9, 2017
3950cda
Send FML|HS ServerHello to Forge clients
satoshinm Jul 9, 2017
60fedd7
Listen for FML|HS in ForgeDataReceived, client hello
satoshinm Jul 9, 2017
9dc47b2
Move cForgeHandshake instance to cClientHandle to fix duplication cau…
satoshinm Jul 9, 2017
506bebd
Fix recognizing FML protocol version 2 in ClientHello field
satoshinm Jul 9, 2017
e299ad3
Add m_Client member to m_ForgeHandshake, move from parameters
satoshinm Jul 9, 2017
62b57cc
Send client modlist back in server modlist packet
satoshinm Jul 9, 2017
91e908d
Send encoded server ModList
satoshinm Jul 9, 2017
86d8c27
Receive HandshakeAck packets with phase byte
satoshinm Jul 10, 2017
3b0dbab
Simplify ForgeHandshake switch on discriminator
satoshinm Jul 10, 2017
f9b337b
Call BeginForgeHandshake() in cClientHandle::Authenticate() instead
satoshinm Jul 10, 2017
31887fd
Try using a cCriticalSection, but not locked by current thread
satoshinm Jul 10, 2017
40551e1
Remove broken m_CSLock in cForgeHandshake
satoshinm Jul 10, 2017
ad5cb68
Move second half of Authenticate into PostAuthenticate
satoshinm Jul 10, 2017
8969bd6
cForgeHandshake calls PostAuthenticate after completing
satoshinm Jul 10, 2017
61d1919
Add missing SendServerHello() in BeginForgeHandshake()
satoshinm Jul 10, 2017
bff3bc7
Add missing ForgeHandshake.h
satoshinm Jul 10, 2017
1fe784e
Fixed signedness error in discriminator, -1 not 255
satoshinm Jul 10, 2017
6906315
Rename PostAuthenticate to FinishAuthenticate since it actually sets …
satoshinm Jul 10, 2017
367f2c1
Implement the pending/completion acknowledgments, send stub registry
satoshinm Jul 10, 2017
6b73390
Use a valid registry id name, potions
satoshinm Jul 10, 2017
3c5fca7
Remove semi-unused Stage enum
satoshinm Jul 10, 2017
442d8f1
Fix signedness compile errors in counts in RegistryData
satoshinm Jul 10, 2017
8b1eac5
Add missing break in case Discriminator_HandshakeAck
satoshinm Jul 12, 2017
d0a5426
Parse number of mods from client ModList
satoshinm Jul 12, 2017
7fac624
Parse mod name/version from client ModList
satoshinm Jul 12, 2017
934c8a3
Show client mod list on connecting, AStringMap
satoshinm Jul 12, 2017
b174347
Merge branch 'master' into forge
satoshinm Jul 14, 2017
07f82d1
Add HOOK_PLAYER_FORGE_MODS Lua API hook, call with mods, allow plugin…
satoshinm Jul 14, 2017
2813628
Add new cForgeMods class representing a list of Forge mods+versions
satoshinm Jul 15, 2017
ead2601
Try to document GetForgeMods()
satoshinm Jul 15, 2017
66c52f0
Move // tolua_end comment to end of file
satoshinm Jul 15, 2017
a12fa5d
Remove unbridgeable AStringMap mods list from HOOK_PLAYER_FORGE_MODS …
satoshinm Jul 15, 2017
d669b75
Rename hook to HOOK_LOGIN_FORGE
satoshinm Jul 15, 2017
df6e37f
Add cForgeMods to Lua plugins bindings
satoshinm Jul 15, 2017
bf5f211
Pass protocol version string to AugmentServerListPing()
satoshinm Jul 15, 2017
f2d6ec1
Revert "Pass protocol version string to AugmentServerListPing()"
satoshinm Jul 15, 2017
b916c77
Log protocol version received in augmentServerListPing() - available …
satoshinm Jul 15, 2017
5b86899
Fix capitalization of AugmentServerListPing()
satoshinm Jul 15, 2017
734de89
Add RegisterForgeMod() Lua API to cServer
satoshinm Jul 15, 2017
2b33a30
Change RegisterForgeMod() to register for all versions, add RegisterF…
satoshinm Jul 15, 2017
02dc012
Server ping list doesn't include modinfo unless Forge mods were regis…
satoshinm Jul 15, 2017
c8f5b14
Remove some unnecessary whitespace changes
satoshinm Jul 15, 2017
6705990
Revert submodule Core checkout change
satoshinm Jul 15, 2017
280113e
Add cClientHandle IsModded()
satoshinm Jul 22, 2017
8910218
Revert unnecessary whitespace changes
satoshinm Jul 23, 2017
c2c575e
Remove outdated comment
satoshinm Jul 23, 2017
78a094e
Add documentation for new Lua API
satoshinm Jul 23, 2017
d7f8fe9
Add cServer mod registration Lua API documentation
satoshinm Jul 23, 2017
117a555
Add mod unregistration APIs
satoshinm Jul 23, 2017
8af34c0
Remove another outdated comment (unmodded checked above)
satoshinm Jul 23, 2017
81d4d71
Rename to HasMods clarifying no mods on server, versus modded but pos…
satoshinm Jul 23, 2017
caafd12
Send plugin-registered server-side Forge mods in FML|HS ModList packet
satoshinm Jul 23, 2017
3158c15
Fix cForgeMods Remove() iterator erasing from versions vector
satoshinm Jul 23, 2017
2950468
Fix trailing whitespace style violations
satoshinm Jul 23, 2017
e865cf7
Fixed signedness errors not caught with Xcode cmake target
satoshinm Jul 23, 2017
82caf1b
Fix style violations in ForgeHandshake and ForgeMods
satoshinm Jul 23, 2017
e70b0f3
Fix remaining style violations caught by src/CheckBasicStyle.lua
satoshinm Jul 23, 2017
46593e3
Fix capitalization on m_IsForgeClient member variable
satoshinm Jul 23, 2017
6c2d177
Fix new variable names to CamelCase convention
satoshinm Jul 23, 2017
44bc3b8
Merge branch 'master' into forge
satoshinm Jul 23, 2017
789a545
Remove cForgeMods::GetModVersionAt(), use GetModVersion() instead
satoshinm Jul 25, 2017
12117fb
Fix top-level 5 empty line whitespace in cForgeHandshake
satoshinm Jul 25, 2017
02915d6
Change to map data structure for m_ForgeModsByVersion instead of indi…
satoshinm Jul 25, 2017
82e2fdd
Rename IsModded -> IsForgeClient
satoshinm Jul 25, 2017
b58aae7
Alpha-sort the PluginManager hook list for HOOK_LOGIN_FORGE
satoshinm Jul 25, 2017
3749574
Initialize m_ForgeMods pointer with nullptr instead of 0 integer
satoshinm Jul 25, 2017
0cb1ed5
Alpha-sort src/Protocol/CMakeLists new Forge files
satoshinm Jul 25, 2017
0a2c0e6
cForgeHandshake constructor initialization list on separate lines
satoshinm Jul 25, 2017
6ca813a
Clean up ModList parsing, pass only payload and add length check
satoshinm Jul 25, 2017
6da327f
Add whitespace before ForgeHandshake class definition
satoshinm Jul 25, 2017
859acae
Move enums into ForgeHandshake implementation file, not part of inter…
satoshinm Jul 25, 2017
a3fa137
Comment and whitespace on cProtocol::ForgeDataReceived
satoshinm Jul 25, 2017
6e9fc39
Merge branch 'master' into forge
satoshinm Jul 25, 2017
688ba2d
Add documentation for HOOK_LOGIN_FORGE
satoshinm Jul 25, 2017
2ce1ddc
Change cClientHandle cForgeMods to std::unique_ptr
satoshinm Jul 26, 2017
a3ee324
Change fixed handshake channels list from vector to std::array
satoshinm Jul 26, 2017
f3a8b58
Change to use uniform initialization insert() on string maps
satoshinm Jul 26, 2017
9e5cbe2
Change cForgeMods AString params to const AString
satoshinm Jul 26, 2017
fa7e152
Check Buf.ReadVar return values in ForgeHandshake parsing
satoshinm Jul 26, 2017
66975f8
Fix double copy in cForgeMods constructor, pass by reference
satoshinm Jul 27, 2017
222ac0e
Merge branch 'master' into forge
satoshinm Jul 27, 2017
276918d
Forge mod registration checks success, prevent duplicate regresion
satoshinm Jul 28, 2017
981486f
Manually bind RegisterForgeMod to throw Lua exception on failure
satoshinm Jul 28, 2017
d7e5e58
Remove all-protocol Forge mod registration, rename per-proto to Regis…
satoshinm Jul 28, 2017
3868658
Simplify using GetStackValues() in manual binding for tolua_cServer_R…
satoshinm Jul 28, 2017
343467b
Revert accidental whitespace change in tolua_cScoreboard_GetTeamNames
satoshinm Jul 28, 2017
094a4e7
Remove unnecessary nullptr check before m_ForgeMods.reset()
satoshinm Jul 28, 2017
2da145c
Remove cProtocol::ForgeDataReceived(), unnecessary indirection
satoshinm Jul 28, 2017
8823e39
Privitize m_ForgeMods and m_ForgeHandshake
satoshinm Jul 28, 2017
7be5d61
Move member variables after typedef
satoshinm Jul 28, 2017
19026b9
enum Discriminator: signed char, Discriminator_ -> Discriminator::
satoshinm Jul 28, 2017
4401a75
a_ prefix on cForgeHandshake constructor
satoshinm Jul 28, 2017
ed6acb7
size_t format specifier: %zu -> SIZE_T_FMT
satoshinm Jul 28, 2017
935bebc
Tone down logging in ParseModList, debug log only errors
satoshinm Jul 28, 2017
5109370
Remove empty lines in ForgeHandshake, more logical block grouping
satoshinm Jul 28, 2017
bc3adb6
Refactor cForgeHandshake::DataReceived into Handle* functions
satoshinm Jul 28, 2017
f7b6d3a
Merge branch 'master' into forge
satoshinm Jul 28, 2017
9dfb124
Fix initialization error in file Plugins/APIDump/APIDesc.lua: 2 (Plug…
satoshinm Jul 29, 2017
ab62461
Revert enum Discriminator: signed char, Discriminator_ -> Discriminat…
satoshinm Jul 29, 2017
4c59531
Try changing Discriminator to an 'enum class'
satoshinm Jul 29, 2017
e10e3ff
Change client/server phase to enum classes
satoshinm Jul 29, 2017
db5956d
Revert "Change client/server phase to enum classes" (gcc fail)
satoshinm Jul 29, 2017
342056d
Revert "Try changing Discriminator to an 'enum class'" (gcc fail)
satoshinm Jul 29, 2017
cd07cd1
Initialize m_ForgeModsByVersion on-demand when each version is requested
satoshinm Jul 29, 2017
bfb4b7a
Add doxy comment for GetRegisteredForgeMods()
satoshinm Jul 29, 2017
7a7992b
Remove cForgeMods in registration, use AStringMap
satoshinm Jul 29, 2017
2d63362
Remove cForgeMods in ClientHandle, use AStringMap
satoshinm Jul 29, 2017
f547136
Remove cForgeMods class in favor of AStringMap
satoshinm Jul 29, 2017
abd295f
APIDesc: GetForgeMods() returns table (Lua), =C++ AStringMap?
satoshinm Jul 29, 2017
c01c9ff
(Incomplete) Try to bridge GetForgeMods AStringMap -> Lua table
satoshinm Jul 29, 2017
4aea032
Copy saved values by value for BeginForgeHandshake(), not ptr
satoshinm Jul 30, 2017
d360dd3
Fix m_Properties copy (curiously only clang on Travis caught this...)
satoshinm Jul 30, 2017
ee58733
Restore cForgeMods until I can properly bridge AStringMap to Lua table
satoshinm Jul 30, 2017
ee630a2
Revert "Restore cForgeMods until I can properly bridge AStringMap to …
satoshinm Jul 30, 2017
cc8ca32
Fix tolua_cClientHandle_GetForgeMods() return value 1
satoshinm Jul 30, 2017
8e8db6c
LOGD when Forge client connected
satoshinm Jul 30, 2017
8fffcb3
Fix tolua_cServer_RegisterForgeMod, it doesn't return a value
satoshinm Jul 30, 2017
0bd28f3
static const registration channels array
satoshinm Jul 30, 2017
6040fe5
Merge branch 'master' into forge
satoshinm Jul 30, 2017
60a5a47
Fix comment, PostAuthenticate was renamed FinishAuthenticate
satoshinm Jul 30, 2017
33bdcea
LOGD commonplace ForgeHandshake messages
satoshinm Jul 30, 2017
bd5f1c9
Pass mods AStringMap param to Forge login hook
satoshinm Jul 30, 2017
67b2570
Use namespaces for discriminator and phase constants
satoshinm Jul 30, 2017
3f0926b
Merge branch 'master' into forge
satoshinm Jul 30, 2017
87435ce
Change cClientHandle m_ForgeMods to value, remove pointer
satoshinm Jul 31, 2017
a51b606
Update plugin Core from master branch
satoshinm Aug 1, 2017
4d25690
Use CheckParamSelf() in manual bindings, remove now-unnecessary null …
satoshinm Aug 1, 2017
9884d27
Use GetStackValue() instead of reinterpret_cast<cClientHandle *>(tolu…
satoshinm Aug 1, 2017
ea7f421
Alpha-sort manual bindings cClientHandle and add blank line to separa…
satoshinm Aug 1, 2017
1bf7c3d
Spaces around i = in ModList parse debugging message
satoshinm Aug 1, 2017
c45d6a7
Fix ClientHello error message, unexpected length not only short
satoshinm Aug 1, 2017
d7ccda1
Space after & in auto &
satoshinm Aug 1, 2017
d5390be
Fix finishing login in ClientPhase::COMPLETE ack, and catch unknown p…
satoshinm Aug 1, 2017
1c5a48a
Single-line cases in Discriminator switch
satoshinm Aug 1, 2017
716fa0a
Merge branch 'master' into forge
satoshinm Aug 2, 2017
1a7f587
Change to use 'auto' everywhere possible
satoshinm Aug 2, 2017
ef94a24
Change SetError() to variadic macro SET_HANDSHAKE_ERROR()
satoshinm Aug 3, 2017
df5be52
Merge branch 'master' into forge
satoshinm Aug 3, 2017
254b339
Change to SetError(Printf()) removing variadic macro
satoshinm Aug 4, 2017
de1cf38
Fix checking errored state and add SetError() documentation
satoshinm Aug 5, 2017
abf00ed
Merge branch 'master' into forge
satoshinm Aug 7, 2017
5cbdbd2
Fix cByteBuffer definition error from latest merge
satoshinm Aug 7, 2017
44bf20e
Style: remove indent for if condition in tolua_cClientHandle_GetForge…
satoshinm Aug 8, 2017
68b9a11
Remove unnecessary Mods variable in tolua_cClientHandle_GetForgeMods
satoshinm Aug 8, 2017
e7f1ccd
Change .size() == 0 to .empty()
satoshinm Aug 8, 2017
620b68b
Spaces around '=' in ParseModList error message
satoshinm Aug 8, 2017
8035bff
Loop induction variable UInt32 to match NumMods not size_t
satoshinm Aug 8, 2017
ab7910b
Scale max ModList buffer size to 256 bytes per mod
satoshinm Aug 8, 2017
c61d209
Consts in HandleModList
satoshinm Aug 8, 2017
1dd19be
Comment field names instead of variables
satoshinm Aug 8, 2017
b0cd907
Space around '=' with phase
satoshinm Aug 8, 2017
d89917f
Remove logging binary data in cForgeHandshake::DataReceived
satoshinm Aug 8, 2017
ab61bcb
Remove unnecessary forward declaration of Json in ForgeHandshake
satoshinm Aug 8, 2017
c5908ed
Move data members above functions in cForgeHandshake
satoshinm Aug 8, 2017
d34632a
Move ClientHandle include to Protocol_1_10 where it is used
satoshinm Aug 8, 2017
f6307c5
Whitespace around tolua comments Server.h
satoshinm Aug 8, 2017
c2645db
Merge branch 'master' into forge
satoshinm Aug 8, 2017
aa596db
const GetRegisteredForgeMods() and add private non-const accessor
satoshinm Aug 9, 2017
68d0782
Revert "const GetRegisteredForgeMods() and add private non-const acce…
satoshinm Aug 9, 2017
9de99fe
const GetRegisteredForgeMods() and add private non-const accessor
satoshinm Aug 9, 2017
16ca36b
Merge branch 'master' into forge
satoshinm Aug 25, 2017
0737594
Augment server ping for 1.12.1 protocol for Forge
satoshinm Aug 25, 2017
bc28d90
Merge branch 'master' into forge
satoshinm Aug 26, 2017
a466173
Fix duplicate CompositeChat.h inclusion in ManualBindings
satoshinm Aug 26, 2017
63a0f40
Fix ManualBindings merge
satoshinm Aug 26, 2017
c169ec9
Fix UUID type, now cUUID not AString
satoshinm Aug 26, 2017
b4056d5
Encode Forge ServerHello using cByteBuffer
satoshinm Aug 26, 2017
6cd0545
Change mod list string to use AppendPrintf
satoshinm Aug 26, 2017
6642288
Fix five lines spacing after CallHookLoginForge()
satoshinm Aug 26, 2017
9a9f612
Add const to AString references in (Un)registerForgeMod
satoshinm Aug 26, 2017
b8e5b3f
Enhance documentation string for m_ForgeModsByVersion
satoshinm Aug 26, 2017
b6570d8
Enhance documentation string for GetRegisteredForgeMods, detail map
satoshinm Aug 26, 2017
13ef3a6
Merge branch 'master' into forge
satoshinm Aug 26, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 54 additions & 0 deletions Server/Plugins/APIDump/APIDesc.lua
Expand Up @@ -1348,6 +1348,16 @@ end
},
Notes = "Returns the brand that the client has sent in their MC|Brand plugin message.",
},
GetForgeMods =
{
Returns =
{
{
Type = "table",
},
},
Notes = "Returns the Forge mods installed on the client.",
},
GetIPString =
{
Returns =
Expand Down Expand Up @@ -1466,6 +1476,16 @@ end
},
Notes = "Returns true if the client has registered to receive messages on the specified plugin channel.",
},
IsForgeClient =
{
Returns =
{
{
Type = "boolean",
},
},
Notes = "Returns true if the client is modded with Forge.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be Forge-specific, or (future-proofing) would this mean any client-side mod? Perhaps consider renaming to indicate Forge-specific.

Copy link
Contributor Author

@satoshinm satoshinm Jul 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forge-specific, or technically, if the "Forge Mod Loader" is installed on the client which is a part of Forge. Won't pick up LiteLoader or other loaders, or other non-loader mods. Renamed IsModded to "IsForgeClient", a clearer description.

},
IsUUIDOnline =
{
IsStatic = true,
Expand Down Expand Up @@ -11795,6 +11815,25 @@ end
},
Notes = "Returns true if the specified player is queued to be transferred to a World.",
},
RegisterForgeMod =
{
Params =
{
{
Name = "ModName",
Type = "string",
},
{
Name = "ModVersion",
Type = "string",
},
{
Name = "ProtocolVersionNumber",
Type = "number",
},
},
Notes = "Add a Forge mod name/version to the server ping list.",
},
SetMaxPlayers =
{
Params =
Expand All @@ -11816,6 +11855,21 @@ end
},
Notes = "Returns true iff the server is set to authenticate players (\"online mode\").",
},
UnregisterForgeMod =
{
Params =
{
{
Name = "ModName",
Type = "string",
},
{
Name = "ProtocolVersionNumber",
Type = "number",
},
},
Notes = "Remove a Forge mod name/version from the server ping list.",
},
},
},
cStringCompression =
Expand Down
4 changes: 4 additions & 0 deletions Server/Plugins/APIDump/Classes/Plugins.lua
Expand Up @@ -796,6 +796,10 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
{
Notes = "Called when a Login packet is sent to the client, before the client is queued for authentication.",
},
HOOK_LOGIN_FORGE =
{
Notes = "Called when a Forge client has sent its ModList to the server, during the login handshake.",
},
HOOK_PLAYER_ANIMATION =
{
Notes = "Called when a client send the Animation packet.",
Expand Down
60 changes: 60 additions & 0 deletions src/Bindings/ManualBindings.cpp
Expand Up @@ -31,6 +31,7 @@
#include "../Generating/ChunkDesc.h"
#include "../LineBlockTracer.h"
#include "../CompositeChat.h"
#include "../Server.h"
#include "../StringCompression.h"
#include "../CommandOutput.h"
#include "../BuildInfo.h"
Expand Down Expand Up @@ -2342,6 +2343,28 @@ static int tolua_cClientHandle_SendPluginMessage(lua_State * L)



static int tolua_cClientHandle_GetForgeMods(lua_State * L)
{
cLuaState S(L);
if (
!S.CheckParamSelf("cClientHandle") ||
!S.CheckParamEnd(2)
)
{
return 0;
}
cClientHandle * Client;
S.GetStackValue(1, Client);

S.Push(Client->GetForgeMods());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the unneeded Mods variable above.

return 1;
}






static int tolua_cMojangAPI_AddPlayerNameToUUIDMapping(lua_State * L)
{
cLuaState S(L);
Expand Down Expand Up @@ -3133,6 +3156,37 @@ static int tolua_cRoot_GetFurnaceRecipe(lua_State * tolua_S)



static int tolua_cServer_RegisterForgeMod(lua_State * a_LuaState)
{
cLuaState L(a_LuaState);
if (
!L.CheckParamSelf("cServer") ||
!L.CheckParamString(2, 3) ||
!L.CheckParamNumber(4) ||
!L.CheckParamEnd(5)
)
{
return 0;
}

cServer * Server;
AString Name, Version;
UInt32 Protocol;
L.GetStackValues(1, Server, Name, Version, Protocol);

if (!Server->RegisterForgeMod(Name, Version, Protocol))
{
tolua_error(L, "duplicate Forge mod name registration", nullptr);
return 0;
}

return 0;
}





static int tolua_cScoreboard_GetTeamNames(lua_State * L)
{
cLuaState S(L);
Expand Down Expand Up @@ -3741,6 +3795,8 @@ void cManualBindings::Bind(lua_State * 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, "GetForgeMods", tolua_cClientHandle_GetForgeMods);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alpha-sort the (two) functions. Perhaps add an empty line to separate the functions from the constants.

tolua_function(tolua_S, "SendPluginMessage", tolua_cClientHandle_SendPluginMessage);
tolua_endmodule(tolua_S);

Expand Down Expand Up @@ -3884,6 +3940,10 @@ void cManualBindings::Bind(lua_State * tolua_S)
tolua_function(tolua_S, "GetTeamNames", tolua_cScoreboard_GetTeamNames);
tolua_endmodule(tolua_S);

tolua_beginmodule(tolua_S, "cServer");
tolua_function(tolua_S, "RegisterForgeMod", tolua_cServer_RegisterForgeMod);
tolua_endmodule(tolua_S);

tolua_beginmodule(tolua_S, "cStringCompression");
tolua_function(tolua_S, "CompressStringZLIB", tolua_CompressStringZLIB);
tolua_function(tolua_S, "UncompressStringZLIB", tolua_UncompressStringZLIB);
Expand Down
1 change: 1 addition & 0 deletions src/Bindings/Plugin.h
Expand Up @@ -69,6 +69,7 @@ class cPlugin
virtual bool OnKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage) = 0;
virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) = 0;
virtual bool OnLogin (cClientHandle & a_Client, UInt32 a_ProtocolVersion, const AString & a_Username) = 0;
virtual bool OnLoginForge (cClientHandle & a_Client, const AStringMap & a_Mods) = 0;
virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) = 0;
virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
Expand Down
10 changes: 10 additions & 0 deletions src/Bindings/PluginLua.cpp
Expand Up @@ -550,6 +550,15 @@ bool cPluginLua::OnLogin(cClientHandle & a_Client, UInt32 a_ProtocolVersion, con



bool cPluginLua::OnLoginForge(cClientHandle & a_Client, const AStringMap & a_Mods)
{
return CallSimpleHooks(cPluginManager::HOOK_LOGIN_FORGE, &a_Client, a_Mods);
}





bool cPluginLua::OnPlayerAnimation(cPlayer & a_Player, int a_Animation)
{
return CallSimpleHooks(cPluginManager::HOOK_PLAYER_ANIMATION, &a_Player, a_Animation);
Expand Down Expand Up @@ -1050,6 +1059,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType)
case cPluginManager::HOOK_HANDSHAKE: return "OnHandshake";
case cPluginManager::HOOK_KILLING: return "OnKilling";
case cPluginManager::HOOK_LOGIN: return "OnLogin";
case cPluginManager::HOOK_LOGIN_FORGE: return "OnLoginForge";
case cPluginManager::HOOK_PLAYER_BREAKING_BLOCK: return "OnPlayerBreakingBlock";
case cPluginManager::HOOK_PLAYER_BROKEN_BLOCK: return "OnPlayerBrokenBlock";
case cPluginManager::HOOK_PLAYER_EATING: return "OnPlayerEating";
Expand Down
1 change: 1 addition & 0 deletions src/Bindings/PluginLua.h
Expand Up @@ -90,6 +90,7 @@ class cPluginLua :
virtual bool OnKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage) override;
virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) override;
virtual bool OnLogin (cClientHandle & a_Client, UInt32 a_ProtocolVersion, const AString & a_Username) override;
virtual bool OnLoginForge (cClientHandle & a_Client, const AStringMap & a_Mods) override;
virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) override;
virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
Expand Down
19 changes: 19 additions & 0 deletions src/Bindings/PluginManager.cpp
Expand Up @@ -789,6 +789,25 @@ bool cPluginManager::CallHookLogin(cClientHandle & a_Client, UInt32 a_ProtocolVe



bool cPluginManager::CallHookLoginForge(cClientHandle & a_Client, AStringMap & a_Mods)
{
FIND_HOOK(HOOK_LOGIN_FORGE)
VERIFY_HOOK;

for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnLoginForge(a_Client, a_Mods))
{
return true;
}
}
return false;
}






bool cPluginManager::CallHookPlayerAnimation(cPlayer & a_Player, int a_Animation)
{
Expand Down
2 changes: 2 additions & 0 deletions src/Bindings/PluginManager.h
Expand Up @@ -101,6 +101,7 @@ class cPluginManager
HOOK_KILLED,
HOOK_KILLING,
HOOK_LOGIN,
HOOK_LOGIN_FORGE,
HOOK_PLAYER_BREAKING_BLOCK,
HOOK_PLAYER_BROKEN_BLOCK,
HOOK_PLAYER_DESTROYED,
Expand Down Expand Up @@ -246,6 +247,7 @@ class cPluginManager
bool CallHookKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage);
bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI);
bool CallHookLogin (cClientHandle & a_Client, UInt32 a_ProtocolVersion, const AString & a_Username);
bool CallHookLoginForge (cClientHandle & a_Client, AStringMap & a_Mods);
bool CallHookPlayerAnimation (cPlayer & a_Player, int a_Animation);
bool CallHookPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
Expand Down
25 changes: 24 additions & 1 deletion src/ClientHandle.cpp
Expand Up @@ -64,6 +64,7 @@ float cClientHandle::FASTBREAK_PERCENTAGE;

cClientHandle::cClientHandle(const AString & a_IPString, int a_ViewDistance) :
m_LastSentDimension(dimNotSet),
m_ForgeHandshake(this),
m_CurrentViewDistance(a_ViewDistance),
m_RequestedViewDistance(a_ViewDistance),
m_IPString(a_IPString),
Expand Down Expand Up @@ -327,7 +328,6 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID,
// Atomically increment player count (in server thread)
cRoot::Get()->GetServer()->PlayerCreated();

cWorld * World;
{
cCSLock lock(m_CSState);
/*
Expand Down Expand Up @@ -358,6 +358,25 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID,
// Send login success (if the protocol supports it):
m_Protocol->SendLoginSuccess();

if (m_ForgeHandshake.m_IsForgeClient)
{
m_ForgeHandshake.BeginForgeHandshake(a_Name, a_UUID, a_Properties);
}
else
{
FinishAuthenticate(a_Name, a_UUID, a_Properties);
}
}
}





void cClientHandle::FinishAuthenticate(const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties)
{
cWorld * World;
{
// Spawn player (only serversided, so data is loaded)
m_Player = new cPlayer(m_Self, GetUsername());
/*
Expand Down Expand Up @@ -860,6 +879,10 @@ void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString
{
UnregisterPluginChannels(BreakApartPluginChannels(a_Message));
}
else if (a_Channel == "FML|HS")
{
m_ForgeHandshake.DataReceived(this, a_Message.c_str(), a_Message.size());
}
else if (!HasPluginChannel(a_Channel))
{
// Ignore if client sent something but didn't register the channel first
Expand Down
29 changes: 29 additions & 0 deletions src/ClientHandle.h
Expand Up @@ -17,6 +17,7 @@
#include "json/json.h"
#include "ChunkSender.h"
#include "EffectID.h"
#include "Protocol/ForgeHandshake.h"



Expand Down Expand Up @@ -255,8 +256,26 @@ class cClientHandle // tolua_export
/** Returns the client brand received in the MC|Brand plugin message or set by a plugin. */
const AString & GetClientBrand(void) const { return m_ClientBrand; }

/** Returns the Forge mods installed on the client. */
const AStringMap & GetForgeMods(void) const { return m_ForgeMods; }

/** Returns true if the client is modded with Forge. */
bool IsForgeClient(void) const { return m_ForgeHandshake.m_IsForgeClient; }

// tolua_end

/** Add the Forge mod list to the server ping response. */
void ForgeAugmentServerListPing(Json::Value & a_Response)
{
m_ForgeHandshake.AugmentServerListPing(a_Response);
}

/** Mark a client connection as using Forge. Set by the protocol. */
void SetIsForgeClient()
{
m_ForgeHandshake.m_IsForgeClient = true;
}

/** Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) */
bool WantsSendChunk(int a_ChunkX, int a_ChunkZ);

Expand Down Expand Up @@ -375,10 +394,17 @@ class cClientHandle // tolua_export

friend class cServer; // Needs access to SetSelf()

friend class cForgeHandshake; // Needs access to FinishAuthenticate()

/** The type used for storing the names of registered plugin channels. */
typedef std::set<AString> cChannels;

/** Forge handshake state machine. */
cForgeHandshake m_ForgeHandshake;

/** Forge mods and versions installed on this client. */
AStringMap m_ForgeMods;

/** The actual view distance used, the minimum of client's requested view distance and world's max view distance. */
int m_CurrentViewDistance;

Expand Down Expand Up @@ -523,6 +549,9 @@ class cClientHandle // tolua_export

float m_BreakProgress;

/** Finish logging the user in after authenticating. */
void FinishAuthenticate(const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties);

/** Returns true if the rate block interactions is within a reasonable limit (bot protection) */
bool CheckBlockInteractionsRate(void);

Expand Down