mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-05-11 08:20:29 +00:00
Feature/plugin api experimental (#12)
* added a null check to fix crash, expose internal latency value (its buggy) * fix latency calculations * sending packets from c# * world save event, move shutdown def, move called location of shutdown, expose FourKit.FireEvent * add docs --------- Co-authored-by: sylvessa <225480449+sylvessa@users.noreply.github.com>
This commit is contained in:
parent
682989c8f1
commit
21b5accc69
2
Doxyfile
2
Doxyfile
|
|
@ -572,7 +572,7 @@ EXTRACT_PACKAGE = NO
|
|||
# included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_STATIC = YES
|
||||
|
||||
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
|
||||
# locally in source files will be included in the documentation. If set to NO,
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ void PlayerConnection::handleMovePlayer(shared_ptr<MovePlayerPacket> packet)
|
|||
// Anti-cheat: reject movement packets that exceed server-authoritative bounds.
|
||||
double velocitySq = player->xd * player->xd + player->yd * player->yd + player->zd * player->zd;
|
||||
double maxAllowedSq = kMoveBaseAllowanceSq + (velocitySq * kMoveVelocityAllowanceScale);
|
||||
if (player->isAllowedToFly() || player->gameMode->isCreative())
|
||||
if (player->isAllowedToFly() || (player->gameMode != nullptr && player->gameMode->isCreative()))
|
||||
{
|
||||
// Creative / flight-allowed players can move farther legitimately per tick.
|
||||
maxAllowedSq *= 1.5;
|
||||
|
|
@ -1717,8 +1717,13 @@ void PlayerConnection::handleKeepAlive(shared_ptr<KeepAlivePacket> packet)
|
|||
{
|
||||
if (packet->id == lastKeepAliveId)
|
||||
{
|
||||
int time = static_cast<int>(System::nanoTime() / 1000000 - lastKeepAliveTime);
|
||||
player->latency = (player->latency * 3 + time) / 4;
|
||||
int64_t now = (System::nanoTime() / 1000000);
|
||||
if (lastKeepAliveTime == 0) lastKeepAliveTime = now;
|
||||
int64_t delta = static_cast<int64_t>(now - lastKeepAliveTime);
|
||||
|
||||
player->latency = (player->latency * 3 + delta) / 4;
|
||||
|
||||
lastKeepAliveTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public class Player : HumanEntity, OfflinePlayer, CommandSender
|
|||
SetNameInternal(name);
|
||||
IsOnline = true;
|
||||
_playerInventory._holder = this;
|
||||
_connection = new PlayerConnection(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
@ -55,6 +56,13 @@ public class Player : HumanEntity, OfflinePlayer, CommandSender
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <b>Experimental.</b> Gets the player's <see cref="PlayerConnection"/>, which can be used
|
||||
/// to send raw packet data directly to the client.
|
||||
/// </summary>
|
||||
/// <returns>The player's connection.</returns>
|
||||
public PlayerConnection getConnection() => _connection;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Player? getPlayer() => IsOnline ? this : null;
|
||||
|
||||
|
|
@ -86,10 +94,32 @@ public class Player : HumanEntity, OfflinePlayer, CommandSender
|
|||
public new Guid getUniqueId() => _playerUniqueId;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <b>Experimental.</b> Gets the raw online XUID (Xbox User ID) for this player.
|
||||
/// The online XUID is used for guests.
|
||||
/// </summary>
|
||||
/// <returns>The raw online XUID value.</returns>
|
||||
public ulong getRawOnlineXUID() => _playerRawOnlineXUID;
|
||||
|
||||
/// <summary>
|
||||
/// <b>Experimental.</b> Gets the raw offline XUID (Xbox User ID) for this player.
|
||||
/// The offline XUID is the main XUID used by the client.
|
||||
/// </summary>
|
||||
/// <returns>The raw offline XUID value.</returns>
|
||||
public ulong getRawOfflineXUID() => _playerRawOfflineXUID;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the player's estimated ping in milliseconds.
|
||||
/// This value represents a weighted average of the response time to application layer ping packets sent. This value does not represent the network round trip time and as such may have less granularity and be impacted by other sources. For these reasons it should not be used for anti-cheat purposes. Its recommended use is only as a qualitative indicator of connection quality.
|
||||
/// </summary>
|
||||
/// <returns>The player's estimated ping in milliseconds.</returns>
|
||||
public int getPing()
|
||||
{
|
||||
if (NativeBridge.GetPlayerLatency == null)
|
||||
return -1;
|
||||
|
||||
return NativeBridge.GetPlayerLatency(getEntityId());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the player's current saturation level.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ public class WorldEvent : Event
|
|||
{
|
||||
internal World? _world;
|
||||
|
||||
public WorldEvent(World? world) : base()
|
||||
internal WorldEvent(World? world) : base()
|
||||
{
|
||||
_world = world;
|
||||
}
|
||||
|
|
|
|||
11
Minecraft.Server.FourKit/Event/World/WorldSaveEvent.cs
Normal file
11
Minecraft.Server.FourKit/Event/World/WorldSaveEvent.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
namespace Minecraft.Server.FourKit.Event.World;
|
||||
|
||||
using Minecraft.Server.FourKit;
|
||||
|
||||
public class WorldSaveEvent : Event
|
||||
{
|
||||
|
||||
internal WorldSaveEvent() : base()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,35 @@
|
|||
using System;
|
||||
using Minecraft.Server.FourKit.Entity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Minecraft.Server.FourKit.Experimental;
|
||||
|
||||
public class PlayerConnection
|
||||
{
|
||||
private Player _player;
|
||||
|
||||
internal PlayerConnection(Player player)
|
||||
{
|
||||
this._player = player;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends raw packet data directly to the client over the player's connection.
|
||||
/// The byte array must contain the complete packet including the packet ID as the first byte. The server automatically prepends the 4-byte big-endian size header before transmitting.
|
||||
/// </summary>
|
||||
/// <param name="data">The raw packet bytes to send, where <c>data[0]</c> is the packet ID.</param>
|
||||
public void send(byte[] data)
|
||||
{
|
||||
var gh = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||
try
|
||||
{
|
||||
NativeBridge.SendRaw?.Invoke(_player.getEntityId(), gh.AddrOfPinnedObject(), data.Length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
gh.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ using Minecraft.Server.FourKit.Event;
|
|||
using Minecraft.Server.FourKit.Inventory;
|
||||
using Minecraft.Server.FourKit.Plugin;
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the FourKit plugin API.
|
||||
/// </summary>
|
||||
public static class FourKit
|
||||
{
|
||||
private static readonly EventDispatcher _dispatcher = new();
|
||||
|
|
|
|||
|
|
@ -32,11 +32,11 @@ public static partial class FourKitHost
|
|||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void SetPlayerCallbacks(IntPtr kickPlayer, IntPtr banPlayer, IntPtr banPlayerIp, IntPtr getPlayerAddress)
|
||||
public static void SetPlayerCallbacks(IntPtr kickPlayer, IntPtr banPlayer, IntPtr banPlayerIp, IntPtr getPlayerAddress, IntPtr getPlayerLatency)
|
||||
{
|
||||
try
|
||||
{
|
||||
NativeBridge.SetPlayerCallbacks(kickPlayer, banPlayer, banPlayerIp, getPlayerAddress);
|
||||
NativeBridge.SetPlayerCallbacks(kickPlayer, banPlayer, banPlayerIp, getPlayerAddress, getPlayerLatency);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -44,6 +44,19 @@ public static partial class FourKitHost
|
|||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void SetPlayerConnectionCallbacks(IntPtr sendRaw)
|
||||
{
|
||||
try
|
||||
{
|
||||
NativeBridge.SetPlayerConnectionCallbacks(sendRaw);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerLog.Error("fourkit", $"SetPlayerConnectionCallbacks error: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void SetInventoryCallbacks(IntPtr getPlayerInventory, IntPtr setPlayerInventorySlot, IntPtr getContainerContents, IntPtr setContainerSlot, IntPtr getContainerViewerEntityIds, IntPtr closeContainer, IntPtr openVirtualContainer, IntPtr getItemMeta, IntPtr setItemMeta, IntPtr setHeldItemSlot)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,6 +15,19 @@ namespace Minecraft.Server.FourKit;
|
|||
|
||||
public static partial class FourKitHost
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static void FireWorldSave()
|
||||
{
|
||||
try
|
||||
{
|
||||
FourKit.FireEvent(new WorldSaveEvent());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerLog.Error("fourkit", $"FireWorldSave error: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static int FirePlayerPreLogin(IntPtr namePtr, int nameByteLen, IntPtr ipPtr, int ipByteLen, int port)
|
||||
{
|
||||
|
|
@ -34,7 +47,7 @@ public static partial class FourKitHost
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerLog.Error("fourkit", $"FirePlayerJoin error: {ex}");
|
||||
ServerLog.Error("fourkit", $"FirePlayerPreLogin error: {ex}");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,12 @@ internal static class NativeBridge
|
|||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate int NativeGetPlayerAddressDelegate(int entityId, IntPtr outIpBuf, int outIpBufSize, IntPtr outPort);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate int NativeGetPlayerLatencyDelegate(int entityId);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate int NativeSendRawDelegate(int entityId, IntPtr dataBuf, int dataBufSize);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void NativeGetPlayerInventoryDelegate(int entityId, IntPtr outBuffer);
|
||||
|
||||
|
|
@ -203,6 +209,8 @@ internal static class NativeBridge
|
|||
internal static NativeBanPlayerDelegate? BanPlayer;
|
||||
internal static NativeBanPlayerIpDelegate? BanPlayerIp;
|
||||
internal static NativeGetPlayerAddressDelegate? GetPlayerAddress;
|
||||
internal static NativeGetPlayerLatencyDelegate? GetPlayerLatency;
|
||||
internal static NativeSendRawDelegate? SendRaw;
|
||||
internal static NativeGetPlayerInventoryDelegate? GetPlayerInventory;
|
||||
internal static NativeSetPlayerInventorySlotDelegate? SetPlayerInventorySlot;
|
||||
internal static NativeGetContainerContentsDelegate? GetContainerContents;
|
||||
|
|
@ -264,12 +272,18 @@ internal static class NativeBridge
|
|||
DropItem = Marshal.GetDelegateForFunctionPointer<NativeDropItemDelegate>(dropItem);
|
||||
}
|
||||
|
||||
internal static void SetPlayerCallbacks(IntPtr kickPlayer, IntPtr banPlayer, IntPtr banPlayerIp, IntPtr getPlayerAddress)
|
||||
internal static void SetPlayerCallbacks(IntPtr kickPlayer, IntPtr banPlayer, IntPtr banPlayerIp, IntPtr getPlayerAddress, IntPtr getPlayerLatency)
|
||||
{
|
||||
KickPlayer = Marshal.GetDelegateForFunctionPointer<NativeKickPlayerDelegate>(kickPlayer);
|
||||
BanPlayer = Marshal.GetDelegateForFunctionPointer<NativeBanPlayerDelegate>(banPlayer);
|
||||
BanPlayerIp = Marshal.GetDelegateForFunctionPointer<NativeBanPlayerIpDelegate>(banPlayerIp);
|
||||
GetPlayerAddress = Marshal.GetDelegateForFunctionPointer<NativeGetPlayerAddressDelegate>(getPlayerAddress);
|
||||
GetPlayerLatency = Marshal.GetDelegateForFunctionPointer<NativeGetPlayerLatencyDelegate>(getPlayerLatency);
|
||||
}
|
||||
|
||||
internal static void SetPlayerConnectionCallbacks(IntPtr sendRaw)
|
||||
{
|
||||
SendRaw = Marshal.GetDelegateForFunctionPointer<NativeSendRawDelegate>(sendRaw);
|
||||
}
|
||||
|
||||
internal static void SetInventoryCallbacks(IntPtr getPlayerInventory, IntPtr setPlayerInventorySlot, IntPtr getContainerContents, IntPtr setContainerSlot, IntPtr getContainerViewerEntityIds, IntPtr closeContainer, IntPtr openVirtualContainer, IntPtr getItemMeta, IntPtr setItemMeta, IntPtr setHeldItemSlot)
|
||||
|
|
|
|||
1189
Minecraft.Server.FourKit/docs/sending-packets.md
Normal file
1189
Minecraft.Server.FourKit/docs/sending-packets.md
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -17,14 +17,15 @@ 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_shutdown)();
|
||||
typedef void(__stdcall *fn_fire_world_save)();
|
||||
typedef int(__stdcall *fn_fire_player_prelogin)(const char* nameUtf8, int nameByteLen, const char* ipUtf8, int ipByteLen, int port);
|
||||
typedef int(__stdcall *fn_fire_player_login)(const char* nameUtf8, int nameByteLen, const char* ipUtf8, int ipByteLen, int port, int type, unsigned long long* offlineXUID, unsigned long long* onlineXUID);
|
||||
typedef void(__stdcall *fn_fire_player_join)(int entityId, const char *nameUtf8, int nameByteLen, const char *uuidUtf8, int uuidByteLen, unsigned long long offlineXUID, unsigned long long onlineXUID);
|
||||
typedef void(__stdcall *fn_fire_player_quit)(int entityId);
|
||||
typedef int(__stdcall *fn_fire_player_kick)(int entityId, int disconnectReason,
|
||||
const char *reasonUtf8, int reasonByteLen,
|
||||
char *outBuf, int outBufSize, int *outLen);
|
||||
typedef void(__stdcall *fn_shutdown)();
|
||||
typedef int(__stdcall *fn_fire_player_move)(int entityId,
|
||||
double fromX, double fromY, double fromZ,
|
||||
double toX, double toY, double toZ,
|
||||
|
|
@ -56,7 +57,8 @@ typedef int(__stdcall *fn_fire_player_death)(int entityId,
|
|||
const char *deathMsgUtf8, int deathMsgByteLen, int exp,
|
||||
char *outMsgBuf, int outMsgBufSize, int *outMsgLen, int *outKeepInventory,
|
||||
int *outNewExp, int *outNewLevel, int *outKeepLevel);
|
||||
typedef void(__stdcall *fn_set_player_callbacks)(void *kickPlayer, void *banPlayer, void *banPlayerIp, void *getPlayerAddress);
|
||||
typedef void(__stdcall *fn_set_player_callbacks)(void *kickPlayer, void *banPlayer, void *banPlayerIp, void *getPlayerAddress, void *getPlayerLatency);
|
||||
typedef void(__stdcall *fn_set_player_connection_callbacks)(void *sendRaw);
|
||||
typedef long long(__stdcall *fn_fire_player_drop_item)(int entityId,
|
||||
int itemId, int itemCount, int itemAux,
|
||||
int *outItemId, int *outItemCount, int *outItemAux);
|
||||
|
|
@ -103,13 +105,14 @@ struct OpenContainerInfo
|
|||
static std::unordered_map<int, OpenContainerInfo> s_openContainerInfo;
|
||||
|
||||
static fn_initialize s_managedInit = nullptr;
|
||||
static fn_shutdown s_managedShutdown = nullptr;
|
||||
static fn_fire_world_save s_managedFireWorldSave = nullptr;
|
||||
static fn_fire_player_prelogin s_managedFirePreLogin = nullptr;
|
||||
static fn_fire_player_login s_managedFireLogin = 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;
|
||||
static fn_fire_player_kick s_managedFireKick = nullptr;
|
||||
static fn_shutdown s_managedShutdown = nullptr;
|
||||
static fn_fire_player_move s_managedFireMove = nullptr;
|
||||
static fn_set_native_callbacks s_managedSetCallbacks = nullptr;
|
||||
static fn_set_world_callbacks s_managedSetWorldCallbacks = nullptr;
|
||||
|
|
@ -122,6 +125,7 @@ static fn_fire_sign_change s_managedFireSignChange = nullptr;
|
|||
static fn_fire_entity_death s_managedFireEntityDeath = nullptr;
|
||||
static fn_fire_player_death s_managedFirePlayerDeath = nullptr;
|
||||
static fn_set_player_callbacks s_managedSetPlayerCallbacks = nullptr;
|
||||
static fn_set_player_connection_callbacks s_managedSetPlayerConnectionCallbacks = nullptr;
|
||||
static fn_fire_player_drop_item s_managedFirePlayerDropItem = nullptr;
|
||||
static fn_set_inventory_callbacks s_managedSetInventoryCallbacks = nullptr;
|
||||
static fn_fire_player_interact s_managedFirePlayerInteract = nullptr;
|
||||
|
|
@ -171,13 +175,14 @@ void Initialize()
|
|||
|
||||
struct { const wchar_t *name; void **target; } entries[] = {
|
||||
{L"Initialize", (void **)&s_managedInit},
|
||||
{L"FirePlayerPreLogin", (void**)&s_managedFirePreLogin},
|
||||
{L"Shutdown", (void **)&s_managedShutdown},
|
||||
{L"FireWorldSave", (void **)&s_managedFireWorldSave},
|
||||
{L"FirePlayerPreLogin", (void **)&s_managedFirePreLogin},
|
||||
{L"FirePlayerLogin", (void **)&s_managedFireLogin},
|
||||
{L"FirePlayerJoin", (void **)&s_managedFireJoin},
|
||||
{L"FirePlayerQuit", (void **)&s_managedFireQuit},
|
||||
{L"FirePlayerKick", (void **)&s_managedFireKick},
|
||||
{L"FirePlayerMove", (void **)&s_managedFireMove},
|
||||
{L"Shutdown", (void **)&s_managedShutdown},
|
||||
{L"SetNativeCallbacks", (void **)&s_managedSetCallbacks},
|
||||
{L"SetWorldCallbacks", (void **)&s_managedSetWorldCallbacks},
|
||||
{L"UpdatePlayerEntityId", (void **)&s_managedUpdateEntityId},
|
||||
|
|
@ -189,7 +194,8 @@ void Initialize()
|
|||
{L"FireSignChange", (void **)&s_managedFireSignChange},
|
||||
{L"FireEntityDeath", (void **)&s_managedFireEntityDeath},
|
||||
{L"FirePlayerDeath", (void **)&s_managedFirePlayerDeath},
|
||||
{L"SetPlayerCallbacks", (void **)&s_managedSetPlayerCallbacks},
|
||||
{L"SetPlayerCallbacks", (void**)&s_managedSetPlayerCallbacks},
|
||||
{L"SetPlayerConnectionCallbacks", (void **)&s_managedSetPlayerConnectionCallbacks},
|
||||
{L"FirePlayerDropItem", (void **)&s_managedFirePlayerDropItem},
|
||||
{L"SetInventoryCallbacks", (void **)&s_managedSetInventoryCallbacks},
|
||||
{L"FirePlayerInteract", (void **)&s_managedFirePlayerInteract},
|
||||
|
|
@ -257,7 +263,11 @@ void Initialize()
|
|||
(void *)&NativeKickPlayer,
|
||||
(void *)&NativeBanPlayer,
|
||||
(void *)&NativeBanPlayerIp,
|
||||
(void *)&NativeGetPlayerAddress);
|
||||
(void *)&NativeGetPlayerAddress,
|
||||
(void *)&NativeGetPlayerLatency);
|
||||
|
||||
s_managedSetPlayerConnectionCallbacks(
|
||||
(void*)&NativeSendRaw);
|
||||
|
||||
s_managedSetInventoryCallbacks(
|
||||
(void *)&NativeGetPlayerInventory,
|
||||
|
|
@ -314,6 +324,18 @@ void Shutdown()
|
|||
LogInfo("fourkit", "FourKit shut down.");
|
||||
}
|
||||
|
||||
void FireWorldSave()
|
||||
{
|
||||
if (!s_initialized || !s_managedFireWorldSave)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_managedFireWorldSave();
|
||||
|
||||
LogDebugf("fourkit", "Fired WorldSave");
|
||||
}
|
||||
|
||||
bool FirePlayerPreLogin(const std::wstring& name, const std::string& ip, int port)
|
||||
{
|
||||
if (!s_initialized || !s_managedFirePreLogin)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace FourKitBridge
|
|||
{
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
void FireWorldSave();
|
||||
bool FirePlayerPreLogin(const std::wstring& name, const std::string& ip, int port);
|
||||
bool FirePlayerLogin(const std::wstring& name, const std::string& ip, int port, int type, unsigned long long* onlineXUID, unsigned long long* offlineXUID);
|
||||
void FirePlayerJoin(int entityId, const std::wstring& name, const std::wstring& uuid, unsigned long long onlineXUID, unsigned long long offlineXUID);
|
||||
|
|
|
|||
|
|
@ -612,6 +612,25 @@ int __cdecl NativeGetPlayerAddress(int entityId, char *outIpBuf, int outIpBufSiz
|
|||
return 1;
|
||||
}
|
||||
|
||||
int __cdecl NativeGetPlayerLatency(int entityId)
|
||||
{
|
||||
auto player = FindPlayer(entityId);
|
||||
if (!player) return -1;
|
||||
|
||||
return player->latency;
|
||||
}
|
||||
|
||||
int __cdecl NativeSendRaw(int entityId, unsigned char *bufferData, int bufferSize)
|
||||
{
|
||||
auto player = FindPlayer(entityId);
|
||||
if (!player) return -1;
|
||||
|
||||
if (!player->connection || !player->connection->connection)
|
||||
return -1;
|
||||
|
||||
player->connection->connection->send(bufferData, bufferSize);
|
||||
}
|
||||
|
||||
void WriteInventoryItemData(std::shared_ptr<ItemInstance> item, int index, int* outBuffer) {
|
||||
if (item) {
|
||||
//ItemFlags Key:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,11 @@ namespace FourKitBridge
|
|||
void __cdecl NativeKickPlayer(int entityId, int reason);
|
||||
int __cdecl NativeBanPlayer(int entityId, const char *reasonUtf8, int reasonByteLen);
|
||||
int __cdecl NativeBanPlayerIp(int entityId, const char *reasonUtf8, int reasonByteLen);
|
||||
int __cdecl NativeGetPlayerAddress(int entityId, char *outIpBuf, int outIpBufSize, int *outPort);
|
||||
int __cdecl NativeGetPlayerAddress(int entityId, char* outIpBuf, int outIpBufSize, int* outPort);
|
||||
int __cdecl NativeGetPlayerLatency(int entityId);
|
||||
|
||||
//plr connection
|
||||
int __cdecl NativeSendRaw(int entityId, unsigned char* dataBuf, int dataBufSize);
|
||||
|
||||
// inv
|
||||
void __cdecl NativeGetPlayerInventory(int entityId, int *outData);
|
||||
|
|
|
|||
|
|
@ -678,6 +678,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
LogWorldIO("requesting autosave");
|
||||
app.SetXuiServerAction(kServerActionPad, eXuiServerAction_AutoSaveGame);
|
||||
FourKitBridge::FireWorldSave();
|
||||
autosaveRequested = true;
|
||||
}
|
||||
nextAutosaveTick = now + autosaveIntervalMs;
|
||||
|
|
@ -688,6 +689,8 @@ int main(int argc, char **argv)
|
|||
serverCli.Stop();
|
||||
app.m_bShutdown = true;
|
||||
|
||||
FourKitBridge::Shutdown(); //close out the translation layer early for plugin shutdown
|
||||
|
||||
LogInfof("shutdown", "Dedicated server stopped");
|
||||
MinecraftServer *server = MinecraftServer::getInstance();
|
||||
if (server != NULL)
|
||||
|
|
@ -721,7 +724,6 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
LogInfof("shutdown", "Cleaning up and exiting.");
|
||||
FourKitBridge::Shutdown();
|
||||
WinsockNetLayer::Shutdown();
|
||||
LogDebugf("shutdown", "Network layer shutdown complete.");
|
||||
g_NetworkManager.Terminate();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "Connection.h"
|
||||
#include "stdafx.h"
|
||||
#include "InputOutputStream.h"
|
||||
#include "Socket.h"
|
||||
|
|
@ -32,6 +33,7 @@ void Connection::_init()
|
|||
disconnectReason = DisconnectPacket::eDisconnect_None;
|
||||
noInputTicks = 0;
|
||||
estimatedRemaining = 0;
|
||||
estimatedRemainingRaw = 0;
|
||||
fakeLag = 0;
|
||||
slowWriteDelay = 50;
|
||||
|
||||
|
|
@ -145,6 +147,23 @@ void Connection::setListener(PacketListener *packetListener)
|
|||
this->packetListener = packetListener;
|
||||
}
|
||||
|
||||
void Connection::send(unsigned char* buffer, int size)
|
||||
{
|
||||
if (quitting) return;
|
||||
|
||||
MemSect(15);
|
||||
// 4J Jev, synchronized (&writeLock)
|
||||
EnterCriticalSection(&writeLock);
|
||||
|
||||
estimatedRemainingRaw += size;
|
||||
|
||||
outgoingRaw.push(std::make_pair(buffer, size));
|
||||
|
||||
// 4J Jev, end synchronized.
|
||||
LeaveCriticalSection(&writeLock);
|
||||
MemSect(0);
|
||||
}
|
||||
|
||||
void Connection::send(shared_ptr<Packet> packet)
|
||||
{
|
||||
if (quitting) return;
|
||||
|
|
@ -232,6 +251,32 @@ bool Connection::writeTick()
|
|||
didSomething = true;
|
||||
}
|
||||
|
||||
if (!outgoingRaw.empty())
|
||||
{
|
||||
std::pair<unsigned char*, int> rawPacket;
|
||||
EnterCriticalSection(&writeLock);
|
||||
|
||||
rawPacket = outgoingRaw.front();
|
||||
outgoingRaw.pop();
|
||||
estimatedRemainingRaw -= rawPacket.second;
|
||||
|
||||
LeaveCriticalSection(&writeLock);
|
||||
|
||||
for (int i = 0; i < rawPacket.second; i++) {
|
||||
byteArrayDos->writeByte(rawPacket.first[i]);
|
||||
}
|
||||
|
||||
// 4J Stu - Changed this so that rather than writing to the network stream through a buffered stream we want to:
|
||||
// a) Only push whole "game" packets to QNet, rather than amalgamated chunks of data that may include many packets, and partial packets
|
||||
// b) To be able to change the priority and queue of a packet if required
|
||||
//sos->writeWithFlags( baos->buf, 0, baos->size(), 0 );
|
||||
//baos->reset();
|
||||
|
||||
int value = rawPacket.first[0];
|
||||
writeSizes[value] += rawPacket.second;
|
||||
didSomething = true;
|
||||
}
|
||||
|
||||
if ((slowWriteDelay-- <= 0) && !outgoing_slow.empty() && (fakeLag == 0 || System::currentTimeMillis() - outgoing_slow.front()->createTime >= fakeLag))
|
||||
{
|
||||
shared_ptr<Packet> packet;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ private:
|
|||
|
||||
queue<shared_ptr<Packet> > incoming; // 4J - was using synchronizedList...
|
||||
CRITICAL_SECTION incoming_cs; // ... now has this critical section
|
||||
queue<std::pair<unsigned char*, int>> outgoingRaw; // 4J - was using synchronizedList - but don't think it is required as usage is wrapped in writeLock critical section
|
||||
queue<shared_ptr<Packet> > outgoing; // 4J - was using synchronizedList - but don't think it is required as usage is wrapped in writeLock critical section
|
||||
queue<shared_ptr<Packet> > outgoing_slow; // 4J - was using synchronizedList - but don't think it is required as usage is wrapped in writeLock critical section
|
||||
|
||||
|
|
@ -76,6 +77,7 @@ private:
|
|||
|
||||
int noInputTicks;
|
||||
int estimatedRemaining;
|
||||
int estimatedRemainingRaw;
|
||||
|
||||
int tickCount; // 4J Added
|
||||
|
||||
|
|
@ -99,6 +101,7 @@ public:
|
|||
|
||||
void setListener(PacketListener *packetListener);
|
||||
void send(shared_ptr<Packet> packet);
|
||||
void send(unsigned char *buffer, int size);
|
||||
|
||||
public:
|
||||
void queueSend(shared_ptr<Packet> packet);
|
||||
|
|
|
|||
Loading…
Reference in a new issue