mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-04-25 00:17:42 +00:00
Add PlayerPreLoginEvent (#8)
* PlayerPreLoginEvent, comments for more events * basic plugin events * plugin failed to load event * add docs --------- Co-authored-by: sylvessa <225480449+sylvessa@users.noreply.github.com>
This commit is contained in:
parent
33e0ecac56
commit
da2aaf1247
|
|
@ -18,7 +18,10 @@
|
|||
#include "..\Minecraft.Server\ServerLogManager.h"
|
||||
#include "..\Minecraft.Server\Access\Access.h"
|
||||
#include "..\Minecraft.World\Socket.h"
|
||||
#include <FourKitBridge.h>
|
||||
#include <Windows64/Network/WinsockNetLayer.h>
|
||||
#endif
|
||||
|
||||
// #ifdef __PS3__
|
||||
// #include "PS3\Network\NetworkPlayerSony.h"
|
||||
// #endif
|
||||
|
|
@ -111,6 +114,58 @@ void PendingConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
std::string connectionIp = "";
|
||||
int connectionPort = 0;
|
||||
|
||||
if (!connection || !connection->getSocket()) {
|
||||
goto handlePreLoginEND;
|
||||
}
|
||||
|
||||
unsigned char smallId = connection->getSocket()->getSmallId();
|
||||
if (smallId == 0) {
|
||||
goto handlePreLoginEND;
|
||||
}
|
||||
|
||||
if (!ServerRuntime::ServerLogManager::TryGetConnectionRemoteIp(smallId, &connectionIp))
|
||||
{
|
||||
SOCKET sock = WinsockNetLayer::GetSocketForSmallId(smallId);
|
||||
if (sock != INVALID_SOCKET)
|
||||
{
|
||||
sockaddr_in addr;
|
||||
int addrLen = sizeof(addr);
|
||||
if (getpeername(sock, (sockaddr*)&addr, &addrLen) == 0)
|
||||
{
|
||||
char ipBuf[64] = {};
|
||||
if (inet_ntop(AF_INET, &addr.sin_addr, ipBuf, sizeof(ipBuf)))
|
||||
{
|
||||
connectionIp = ipBuf;
|
||||
connectionPort = (int)ntohs(addr.sin_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connectionIp.empty()) {
|
||||
goto handlePreLoginEND;
|
||||
}
|
||||
} else {
|
||||
SOCKET sock = WinsockNetLayer::GetSocketForSmallId(smallId);
|
||||
if (sock != INVALID_SOCKET)
|
||||
{
|
||||
sockaddr_in addr;
|
||||
int addrLen = sizeof(addr);
|
||||
if (getpeername(sock, (sockaddr*)&addr, &addrLen) == 0)
|
||||
connectionPort = (int)ntohs(addr.sin_port);
|
||||
}
|
||||
}
|
||||
|
||||
if (FourKitBridge::FirePlayerPreLogin(packet->loginKey, connectionIp, connectionPort)) {
|
||||
disconnect(DisconnectPacket::eDisconnect_EndOfStream); //idk what to use here, eventually it should be set by the event
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
handlePreLoginEND:
|
||||
// printf("Server: handlePreLogin\n");
|
||||
name = packet->loginKey; // 4J Stu - Change from the login packet as we know better on client end during the pre-login packet
|
||||
sendPreLoginResponse();
|
||||
|
|
|
|||
|
|
@ -1437,10 +1437,12 @@ void PlayerConnection::handleClientCommand(shared_ptr<ClientCommandPacket> packe
|
|||
|
||||
void PlayerConnection::handleRespawn(shared_ptr<RespawnPacket> packet)
|
||||
{
|
||||
//todo: fire respawn event
|
||||
}
|
||||
|
||||
void PlayerConnection::handleContainerClose(shared_ptr<ContainerClosePacket> packet)
|
||||
{
|
||||
//todo: fire container close event
|
||||
player->doCloseContainer();
|
||||
}
|
||||
|
||||
|
|
@ -1819,6 +1821,7 @@ bool PlayerConnection::isServerPacketListener()
|
|||
|
||||
void PlayerConnection::handlePlayerAbilities(shared_ptr<PlayerAbilitiesPacket> playerAbilitiesPacket)
|
||||
{
|
||||
//todo: fire abilities change event
|
||||
player->abilities.flying = playerAbilitiesPacket->isFlying() && player->abilities.mayfly;
|
||||
}
|
||||
|
||||
|
|
@ -1937,6 +1940,7 @@ void PlayerConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> custo
|
|||
Slot *slot = beaconMenu->getSlot(0);
|
||||
if (slot->hasItem())
|
||||
{
|
||||
//todo: beacon powered event?
|
||||
slot->remove(1);
|
||||
shared_ptr<BeaconTileEntity> beacon = beaconMenu->getBeacon();
|
||||
beacon->setPrimaryPower(primary);
|
||||
|
|
@ -1950,6 +1954,7 @@ void PlayerConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> custo
|
|||
AnvilMenu *menu = dynamic_cast<AnvilMenu *>( player->containerMenu);
|
||||
if (menu)
|
||||
{
|
||||
//todo: anvel item rename event?
|
||||
if (customPayloadPacket->data.data == nullptr || customPayloadPacket->data.length < 1)
|
||||
{
|
||||
menu->setItemName(L"");
|
||||
|
|
@ -1977,6 +1982,7 @@ bool PlayerConnection::isDisconnected()
|
|||
|
||||
void PlayerConnection::handleDebugOptions(shared_ptr<DebugOptionsPacket> packet)
|
||||
{
|
||||
//todo: debug options event?
|
||||
#ifdef _DEBUG
|
||||
// Player player = dynamic_pointer_cast<Player>( player->shared_from_this() );
|
||||
player->SetDebugOptions(packet->m_uiVal);
|
||||
|
|
@ -2063,6 +2069,8 @@ void PlayerConnection::handleCraftItem(shared_ptr<CraftItemPacket> packet)
|
|||
}
|
||||
}
|
||||
|
||||
//todo: fire item crafted event?
|
||||
|
||||
// 4J Stu - Fix for #13119 - We should add the item after we remove the ingredients
|
||||
if(player->inventory->add(pTempItemInst)==false )
|
||||
{
|
||||
|
|
@ -2137,6 +2145,7 @@ void PlayerConnection::handleTradeItem(shared_ptr<TradeItemPacket> packet)
|
|||
int buyBMatches = player->inventory->countMatches(buyBItem);
|
||||
if( (buyAItem != nullptr && buyAMatches >= buyAItem->count) && (buyBItem == nullptr || buyBMatches >= buyBItem->count) )
|
||||
{
|
||||
//todo: fire trade event?
|
||||
menu->getMerchant()->notifyTrade(activeRecipe);
|
||||
|
||||
// Remove the items we are purchasing with
|
||||
|
|
|
|||
40
Minecraft.Server.FourKit/Event/Player/PlayerPreLoginEvent.cs
Normal file
40
Minecraft.Server.FourKit/Event/Player/PlayerPreLoginEvent.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
namespace Minecraft.Server.FourKit.Event.Player;
|
||||
|
||||
using Minecraft.Server.FourKit.Net;
|
||||
|
||||
/// <summary>
|
||||
/// Stores details for players attempting to log in.
|
||||
/// </summary>
|
||||
public class PlayerPreLoginEvent : Event, Cancellable
|
||||
{
|
||||
private string name;
|
||||
private InetSocketAddress ipAddress; //bukkit uses InetAddress but we expose port also
|
||||
private bool _cancelled;
|
||||
|
||||
|
||||
internal PlayerPreLoginEvent(string name, InetSocketAddress ipAddress) : base()
|
||||
{
|
||||
this.name = name;
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the player's name.
|
||||
/// </summary>
|
||||
/// <returns>The player's name.</returns>
|
||||
public string getName() => name;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the player IP address.
|
||||
/// </summary>
|
||||
/// <returns>The IP address.</returns>
|
||||
public InetSocketAddress getAddress() => ipAddress;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool isCancelled() => _cancelled;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void setCancelled(bool cancel) => _cancelled = cancel;
|
||||
}
|
||||
11
Minecraft.Server.FourKit/Event/Server/PluginDisableEvent.cs
Normal file
11
Minecraft.Server.FourKit/Event/Server/PluginDisableEvent.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
namespace Minecraft.Server.FourKit.Event.Server;
|
||||
|
||||
using Minecraft.Server.FourKit.Plugin;
|
||||
|
||||
public class PluginDisableEvent : PluginEvent
|
||||
{
|
||||
|
||||
internal PluginDisableEvent(ServerPlugin plugin) : base(plugin)
|
||||
{
|
||||
}
|
||||
}
|
||||
11
Minecraft.Server.FourKit/Event/Server/PluginEnableEvent.cs
Normal file
11
Minecraft.Server.FourKit/Event/Server/PluginEnableEvent.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
namespace Minecraft.Server.FourKit.Event.Server;
|
||||
|
||||
using Minecraft.Server.FourKit.Plugin;
|
||||
|
||||
public class PluginEnableEvent : PluginEvent
|
||||
{
|
||||
|
||||
internal PluginEnableEvent(ServerPlugin plugin) : base(plugin)
|
||||
{
|
||||
}
|
||||
}
|
||||
16
Minecraft.Server.FourKit/Event/Server/PluginEvent.cs
Normal file
16
Minecraft.Server.FourKit/Event/Server/PluginEvent.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
namespace Minecraft.Server.FourKit.Event.Server;
|
||||
|
||||
using Minecraft.Server.FourKit.Plugin;
|
||||
|
||||
public abstract class PluginEvent : ServerEvent
|
||||
{
|
||||
private readonly ServerPlugin _plugin;
|
||||
|
||||
internal protected PluginEvent(ServerPlugin plugin) : base()
|
||||
{
|
||||
_plugin = plugin;
|
||||
}
|
||||
|
||||
/// <summary>Returns the plugin involved in this event.</summary>
|
||||
public ServerPlugin getPlugin() => _plugin;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
namespace Minecraft.Server.FourKit.Event.Server;
|
||||
|
||||
using Minecraft.Server.FourKit.Plugin;
|
||||
|
||||
public class PluginLoadFailedEvent : ServerEvent
|
||||
{
|
||||
private readonly string _fileName;
|
||||
private readonly string _message;
|
||||
internal PluginLoadFailedEvent(string fileName, string message) : base()
|
||||
{
|
||||
_fileName = fileName;
|
||||
_message = message;
|
||||
}
|
||||
|
||||
public string getFileName() => _fileName;
|
||||
|
||||
public string getMessage() => _message;
|
||||
}
|
||||
11
Minecraft.Server.FourKit/Event/Server/ServerEvent.cs
Normal file
11
Minecraft.Server.FourKit/Event/Server/ServerEvent.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
namespace Minecraft.Server.FourKit.Event.Server;
|
||||
|
||||
using Minecraft.Server.FourKit.Plugin;
|
||||
|
||||
public abstract class ServerEvent : Event
|
||||
{
|
||||
|
||||
internal protected ServerEvent() : base()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -7,11 +7,36 @@ using Minecraft.Server.FourKit.Event.Entity;
|
|||
using Minecraft.Server.FourKit.Event.Player;
|
||||
using Minecraft.Server.FourKit.Event.Inventory;
|
||||
using Minecraft.Server.FourKit.Inventory;
|
||||
using Minecraft.Server.FourKit.Net;
|
||||
|
||||
namespace Minecraft.Server.FourKit;
|
||||
|
||||
public static partial class FourKitHost
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static int FirePlayerPreLogin(IntPtr namePtr, int nameByteLen, IntPtr ipPtr, int ipByteLen, int port)
|
||||
{
|
||||
try
|
||||
{
|
||||
string name = nameByteLen > 0
|
||||
? Marshal.PtrToStringUTF8(namePtr, nameByteLen) ?? string.Empty
|
||||
: string.Empty;
|
||||
|
||||
string ipStr = ipByteLen > 0
|
||||
? Marshal.PtrToStringUTF8(ipPtr, ipByteLen) ?? string.Empty
|
||||
: string.Empty;
|
||||
|
||||
var evt = new PlayerPreLoginEvent(name, new InetSocketAddress(new InetAddress(ipStr), port));
|
||||
FourKit.FireEvent(evt);
|
||||
return evt.isCancelled() ? 1 : 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerLog.Error("fourkit", $"FirePlayerJoin error: {ex}");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void FirePlayerJoin(int entityId, IntPtr namePtr, int nameByteLen, IntPtr uuidPtr, int uuidByteLen)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Minecraft.Server.FourKit.Event.Server;
|
||||
using Minecraft.Server.FourKit.Plugin;
|
||||
using System.Reflection;
|
||||
|
||||
|
|
@ -44,15 +45,30 @@ internal sealed class PluginLoader
|
|||
|
||||
if (mainDll != null)
|
||||
{
|
||||
try { LoadPluginAssembly(mainDll); }
|
||||
catch (Exception ex) { ServerLog.Error("fourkit", $"Failed to load {Path.GetFileName(mainDll)}: {ex.Message}"); }
|
||||
try
|
||||
{
|
||||
LoadPluginAssembly(mainDll);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerLog.Error("fourkit", $"Failed to load {Path.GetFileName(mainDll)}: {ex.Message}");
|
||||
FourKit.FireEvent(new PluginLoadFailedEvent(mainDll, ex.Message));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var dll in allDlls)
|
||||
{
|
||||
try { LoadPluginAssembly(dll); }
|
||||
catch (Exception ex) { ServerLog.Error("fourkit", $"Failed to load {Path.GetFileName(dll)}: {ex.Message}"); }
|
||||
try
|
||||
{
|
||||
LoadPluginAssembly(dll);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerLog.Error("fourkit", $"Failed to load {Path.GetFileName(dll)}: {ex.Message}");
|
||||
FourKit.FireEvent(new PluginLoadFailedEvent(dll, ex.Message));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,6 +124,8 @@ internal sealed class PluginLoader
|
|||
InvokePluginMethod(plugin, "onEnable", "OnEnable");
|
||||
string pName = GetPluginString(plugin, "name", "getName", "GetName", plugin.GetType().Name);
|
||||
ServerLog.Info("fourkit", $"Enabled: {pName}");
|
||||
|
||||
FourKit.FireEvent(new PluginEnableEvent(plugin));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -126,6 +144,8 @@ internal sealed class PluginLoader
|
|||
InvokePluginMethod(_plugins[i], "onDisable", "OnDisable");
|
||||
string pName = GetPluginString(_plugins[i], "name", "getName", "GetName", _plugins[i].GetType().Name);
|
||||
ServerLog.Info("fourkit", $"Disabled: {pName}");
|
||||
|
||||
FourKit.FireEvent(new PluginDisableEvent(_plugins[i]));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace FourKitBridge
|
|||
{
|
||||
|
||||
typedef void(__stdcall *fn_initialize)();
|
||||
typedef int(__stdcall *fn_fire_player_prelogin)(const char* nameUtf8, int nameByteLen, const char* ipUtf8, int ipByteLen, int port);
|
||||
typedef void(__stdcall *fn_fire_player_join)(int entityId, const char *nameUtf8, int nameByteLen, const char *uuidUtf8, int uuidByteLen);
|
||||
typedef void(__stdcall *fn_fire_player_quit)(int entityId);
|
||||
typedef int(__stdcall *fn_fire_player_kick)(int entityId, int disconnectReason,
|
||||
|
|
@ -100,6 +101,7 @@ struct OpenContainerInfo
|
|||
static std::unordered_map<int, OpenContainerInfo> s_openContainerInfo;
|
||||
|
||||
static fn_initialize s_managedInit = nullptr;
|
||||
static fn_fire_player_prelogin s_managedFirePreLogin = nullptr;
|
||||
static fn_fire_player_join s_managedFireJoin = nullptr;
|
||||
static fn_update_entity_id s_managedUpdateEntityId = nullptr;
|
||||
static fn_fire_player_quit s_managedFireQuit = nullptr;
|
||||
|
|
@ -165,6 +167,7 @@ void Initialize()
|
|||
|
||||
struct { const wchar_t *name; void **target; } entries[] = {
|
||||
{L"Initialize", (void **)&s_managedInit},
|
||||
{L"FirePlayerPreLogin", (void **)&s_managedFirePreLogin},
|
||||
{L"FirePlayerJoin", (void **)&s_managedFireJoin},
|
||||
{L"FirePlayerQuit", (void **)&s_managedFireQuit},
|
||||
{L"FirePlayerKick", (void **)&s_managedFireKick},
|
||||
|
|
@ -305,6 +308,23 @@ void Shutdown()
|
|||
LogInfo("fourkit", "FourKit shut down.");
|
||||
}
|
||||
|
||||
bool FirePlayerPreLogin(const std::wstring& name, const std::string& ip, int port) {
|
||||
if (!s_initialized || !s_managedFirePreLogin)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string nameUtf8 = ServerRuntime::StringUtils::WideToUtf8(name);
|
||||
int canceled = s_managedFirePreLogin(
|
||||
nameUtf8.empty() ? "" : nameUtf8.data(), (int)nameUtf8.size(),
|
||||
ip.empty() ? "" : ip.data(), (int)ip.size(),
|
||||
port);
|
||||
|
||||
LogDebugf("fourkit", "Fired PlayerPreLogin: %s", nameUtf8.data());
|
||||
|
||||
return canceled != 0;
|
||||
}
|
||||
|
||||
void FirePlayerJoin(int entityId, const std::wstring &name, const std::wstring &uuid)
|
||||
{
|
||||
if (!s_initialized || !s_managedFireJoin)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace FourKitBridge
|
|||
{
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
bool FirePlayerPreLogin(const std::wstring& name, const std::string& ip, int port);
|
||||
void FirePlayerJoin(int entityId, const std::wstring &name, const std::wstring &uuid);
|
||||
bool FirePlayerQuit(int entityId);
|
||||
bool FirePlayerKick(int entityId, int disconnectReason,
|
||||
|
|
|
|||
Loading…
Reference in a new issue