Files
itsRevela-LCE_Revelations/Minecraft.Server.FourKit/NativeBridge.cs
itsRevela 42a582fb9f feat: add FourKit plugin host with dual server build
Adds the FourKit .NET 10 plugin host as a second dedicated server
build flavour alongside the existing vanilla server. Both flavours
build from the same source tree, with FourKit gated by the
MINECRAFT_SERVER_FOURKIT_BUILD preprocessor define.

Build layout:

  Minecraft.Server         vanilla, no plugin support, no .NET dep
  Minecraft.Server.FourKit FourKit-enabled, ships with bundled
                           .NET 10 self-contained runtime in runtime/
                           and an empty plugins/ folder

Both produce a Minecraft.Server.exe in their own per-target output
dir. The variant identity lives in the directory name, not the
binary name, so either flavour can be shipped as a drop-in.

Native bridge (Minecraft.Server/FourKit*.{cpp,h}):

* FourKitRuntime: hosts CoreCLR via hostfxr's command-line init API
  (the runtime-config API does not support self-contained components)
* FourKitBridge: ~50 Fire* event entry points, with inline no-op
  stubs for the standalone build so gameplay code can call them
  unconditionally
* FourKitNatives: ~80 native callbacks the managed side invokes
  for player/world/inventory mutations
* FourKitMappers: type and enum mapping helpers

Managed plugin host (Minecraft.Server.FourKit/):

* Bukkit-style API: Player, World, Block, Inventory, Command,
  Listener, EventHandler attribute, ~54 event classes
* PluginLoader with per-plugin AssemblyLoadContext
* FourKitHost as the [UnmanagedCallersOnly] entry point table
* Runtime resolves plugins relative to the host process so they
  always live next to Minecraft.Server.exe regardless of where the
  managed assembly itself is loaded from

Engine hooks (Minecraft.Client/, Minecraft.World/):

* Player lifecycle (PreLogin, Login, Join, Quit, Kick, Move,
  Teleport, Portal, Death) wired into PendingConnection and
  PlayerConnection without disturbing the cipher handshake or
  identity-token security flow
* Inventory open/click/drop hooks across every container menu type
* Block place/break/grow/burn/spread/from-to hooks across the
  full tile family
* Bed enter/leave, sign change, entity damage/death, ender pearl
  teleport hooks

Regression fixes preserved while applying donor diffs:

* ServerPlayer::die() retains the LCE-Revelations hardcore branch
  (setGameMode(ADVENTURE) + banPlayerForHardcoreDeath) in both the
  FourKit and non-FourKit code paths
* ServerLevel::entityAdded() retains the sub-entity ID reassignment
  loop required by the client's handleAddMob offset, fixing Ender
  Dragon and Wither boss multi-part hit detection
* LivingEntity::travel() retains the raw Player* cast and the
  cached frictionTile, both Revelations perf wins that the donor
  silently reverted
* ServerLogger.cpp keeps the file-logging code donor stripped
* PlayerList.cpp end portal transition fix and UIScene_EndPoem
  bounds-check are intact

Build system:

* Top-level CMakeLists.txt adds the Minecraft.Server.FourKit
  subdirectory and pulls in the new shared cmake/ServerTarget.cmake
  helper
* Minecraft.Server/cmake/sources/Common.cmake is now location
  independent (uses CMAKE_CURRENT_LIST_DIR) so the source list
  can be consumed from either server target's CMakeLists.txt
* The seven FourKit*.cpp/h files live in their own
  _MINECRAFT_SERVER_COMMON_SERVER_FOURKIT variable so the
  standalone target omits them
* configure-time .NET 10 SDK check fails fast with a clear
  download link if the SDK is missing
* global.json pins the SDK to 10.0.100 with latestFeature
  rollforward

Sample plugin (samples/HelloPlugin/) demonstrates the loader and
the PlayerJoinEvent listener pattern.

CI:

* nightly.yml builds both server flavours, ships
  LCE-Revelations-Server-Win64.zip and
  LCE-Revelations-Server-Win64-FourKit.zip, attests both, and
  updates release notes for the dual-flavour layout
* pull-request.yml pulls in actions/setup-dotnet so the FourKit
  publish step works in PR validation
* All zip artifacts and the client zip are renamed from
  LCREWindows64 to LCE-Revelations-{Client,Server}-Win64

Documentation:

* COMPILE.md gets a VS 2022 quick start, .NET 10 prereq section,
  server flavours explanation, and a troubleshooting section
* docs/FOURKIT_PORT_RECON.md captures the file-by-file recon that
  drove the port
* docs/FOURKIT_PARITY.md is the canonical reference for which
  events FourKit fires

Docker:

* docker-compose.dedicated-server.yml MC_RUNTIME_DIR default points
  at the vanilla CMake output. The FourKit Docker image is
  intentionally NOT shipped yet because hosting .NET 10 self
  contained inside Wine has not been smoke-tested
2026-04-08 03:02:48 -05:00

338 lines
20 KiB
C#

using System.Runtime.InteropServices;
namespace Minecraft.Server.FourKit;
// EAT SHIT AND DIE
internal static class NativeBridge
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeDamageDelegate(int entityId, float amount);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetHealthDelegate(int entityId, float health);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeTeleportDelegate(int entityId, double x, double y, double z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetGameModeDelegate(int entityId, int gameMode);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeBroadcastMessageDelegate(IntPtr utf8, int byteLen);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetFallDistanceDelegate(int entityId, float distance);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeGetPlayerSnapshotDelegate(int entityId, IntPtr outBuf);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSendMessageDelegate(int entityId, IntPtr utf8, int byteLen);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetWalkSpeedDelegate(int entityId, float speed);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeTeleportEntityDelegate(int entityId, int dimId, double x, double y, double z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeGetTileIdDelegate(int dimId, int x, int y, int z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeGetTileDataDelegate(int dimId, int x, int y, int z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetTileDelegate(int dimId, int x, int y, int z, int tileId, int data);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetTileDataDelegate(int dimId, int x, int y, int z, int data);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeBreakBlockDelegate(int dimId, int x, int y, int z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeGetHighestBlockYDelegate(int dimId, int x, int z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeGetWorldInfoDelegate(int dimId, IntPtr outBuf);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetWorldTimeDelegate(int dimId, long time);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetWeatherDelegate(int dimId, int storm, int thundering, int thunderDuration);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeCreateExplosionDelegate(int dimId, double x, double y, double z, float power, int setFire, int breakBlocks);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeStrikeLightningDelegate(int dimId, double x, double y, double z, int effectOnly);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeSetSpawnLocationDelegate(int dimId, int x, int y, int z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeDropItemDelegate(int dimId, double x, double y, double z, int itemId, int count, int auxValue, int naturally);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeKickPlayerDelegate(int entityId, int reason);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeBanPlayerDelegate(int entityId, IntPtr reasonUtf8, int reasonByteLen);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeBanPlayerIpDelegate(int entityId, IntPtr reasonUtf8, int reasonByteLen);
[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);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetPlayerInventorySlotDelegate(int entityId, int slot, int itemId, int count, int aux);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeGetContainerContentsDelegate(int entityId, IntPtr outBuffer, int maxSlots);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetContainerSlotDelegate(int entityId, int slot, int itemId, int count, int aux);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeGetContainerViewerEntityIdsDelegate(int entityId, IntPtr outIds, int maxCount, IntPtr outCount);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeCloseContainerDelegate(int entityId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeOpenVirtualContainerDelegate(int entityId, int nativeType, IntPtr titleUtf8, int titleByteLen, int slotCount, IntPtr itemsBuf);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeGetItemMetaDelegate(int entityId, int slot, IntPtr outBuf, int bufSize);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetItemMetaDelegate(int entityId, int slot, IntPtr inBuf, int bufSize);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetHeldItemSlotDelegate(int entityId, int slot);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetSneakingDelegate(int entityId, int sneak);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetVelocityDelegate(int entityId, double x, double y, double z);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetAllowFlightDelegate(int entityId, int allowFlight);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativePlaySoundDelegate(int entityId, int soundId, double x, double y, double z, float volume, float pitch);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetSleepingIgnoredDelegate(int entityId, int ignored);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetLevelDelegate(int entityId, int level);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetExpDelegate(int entityId, float exp);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeGiveExpDelegate(int entityId, int amount);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeGiveExpLevelsDelegate(int entityId, int amount);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetFoodLevelDelegate(int entityId, int foodLevel);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetSaturationDelegate(int entityId, float saturation);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSetExhaustionDelegate(int entityId, float exhaustion);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeSpawnParticleDelegate(int entityId, int particleId, float x, float y, float z, float offsetX, float offsetY, float offsetZ, float speed, int count);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeSetPassengerDelegate(int entityId, int passengerEntityId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeLeaveVehicleDelegate(int entityId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeEjectDelegate(int entityId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeGetVehicleIdDelegate(int entityId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int NativeGetPassengerIdDelegate(int entityId);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void NativeGetEntityInfoDelegate(int entityId, IntPtr outBuf);
internal static NativeDamageDelegate? DamagePlayer;
internal static NativeSetHealthDelegate? SetPlayerHealth;
internal static NativeTeleportDelegate? TeleportPlayer;
internal static NativeSetGameModeDelegate? SetPlayerGameMode;
internal static NativeBroadcastMessageDelegate? BroadcastMessage;
internal static NativeSetFallDistanceDelegate? SetFallDistance;
internal static NativeGetPlayerSnapshotDelegate? GetPlayerSnapshot;
internal static NativeSendMessageDelegate? SendMessage;
internal static NativeSetWalkSpeedDelegate? SetWalkSpeed;
internal static NativeTeleportEntityDelegate? TeleportEntity;
internal static NativeGetTileIdDelegate? GetTileId;
internal static NativeGetTileDataDelegate? GetTileData;
internal static NativeSetTileDelegate? SetTile;
internal static NativeSetTileDataDelegate? SetTileData;
internal static NativeBreakBlockDelegate? BreakBlock;
internal static NativeGetHighestBlockYDelegate? GetHighestBlockY;
internal static NativeGetWorldInfoDelegate? GetWorldInfo;
internal static NativeSetWorldTimeDelegate? SetWorldTime;
internal static NativeSetWeatherDelegate? SetWeather;
internal static NativeCreateExplosionDelegate? CreateExplosion;
internal static NativeStrikeLightningDelegate? StrikeLightning;
internal static NativeSetSpawnLocationDelegate? SetSpawnLocation;
internal static NativeDropItemDelegate? DropItem;
internal static NativeKickPlayerDelegate? KickPlayer;
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;
internal static NativeSetContainerSlotDelegate? SetContainerSlot;
internal static NativeGetContainerViewerEntityIdsDelegate? GetContainerViewerEntityIds;
internal static NativeCloseContainerDelegate? CloseContainer;
internal static NativeOpenVirtualContainerDelegate? OpenVirtualContainer;
internal static NativeGetItemMetaDelegate? GetItemMeta;
internal static NativeSetItemMetaDelegate? SetItemMeta;
internal static NativeSetHeldItemSlotDelegate? SetHeldItemSlot;
internal static NativeSetSneakingDelegate? SetSneaking;
internal static NativeSetVelocityDelegate? SetVelocity;
internal static NativeSetAllowFlightDelegate? SetAllowFlight;
internal static NativePlaySoundDelegate? PlaySound;
internal static NativeSetSleepingIgnoredDelegate? SetSleepingIgnored;
internal static NativeSetLevelDelegate? SetLevel;
internal static NativeSetExpDelegate? SetExp;
internal static NativeGiveExpDelegate? GiveExp;
internal static NativeGiveExpLevelsDelegate? GiveExpLevels;
internal static NativeSetFoodLevelDelegate? SetFoodLevel;
internal static NativeSetSaturationDelegate? SetSaturation;
internal static NativeSetExhaustionDelegate? SetExhaustion;
internal static NativeSpawnParticleDelegate? SpawnParticle;
internal static NativeSetPassengerDelegate? SetPassenger;
internal static NativeLeaveVehicleDelegate? LeaveVehicle;
internal static NativeEjectDelegate? Eject;
internal static NativeGetVehicleIdDelegate? GetVehicleId;
internal static NativeGetPassengerIdDelegate? GetPassengerId;
internal static NativeGetEntityInfoDelegate? GetEntityInfo;
internal static void SetCallbacks(IntPtr damage, IntPtr setHealth, IntPtr teleport, IntPtr setGameMode, IntPtr broadcastMessage, IntPtr setFallDistance, IntPtr getPlayerSnapshot, IntPtr sendMessage, IntPtr setWalkSpeed, IntPtr teleportEntity)
{
DamagePlayer = Marshal.GetDelegateForFunctionPointer<NativeDamageDelegate>(damage);
SetPlayerHealth = Marshal.GetDelegateForFunctionPointer<NativeSetHealthDelegate>(setHealth);
TeleportPlayer = Marshal.GetDelegateForFunctionPointer<NativeTeleportDelegate>(teleport);
SetPlayerGameMode = Marshal.GetDelegateForFunctionPointer<NativeSetGameModeDelegate>(setGameMode);
BroadcastMessage = Marshal.GetDelegateForFunctionPointer<NativeBroadcastMessageDelegate>(broadcastMessage);
SetFallDistance = Marshal.GetDelegateForFunctionPointer<NativeSetFallDistanceDelegate>(setFallDistance);
GetPlayerSnapshot = Marshal.GetDelegateForFunctionPointer<NativeGetPlayerSnapshotDelegate>(getPlayerSnapshot);
SendMessage = Marshal.GetDelegateForFunctionPointer<NativeSendMessageDelegate>(sendMessage);
SetWalkSpeed = Marshal.GetDelegateForFunctionPointer<NativeSetWalkSpeedDelegate>(setWalkSpeed);
TeleportEntity = Marshal.GetDelegateForFunctionPointer<NativeTeleportEntityDelegate>(teleportEntity);
}
internal static void SetWorldCallbacks(IntPtr getTileId, IntPtr getTileData, IntPtr setTile, IntPtr setTileData, IntPtr breakBlock, IntPtr getHighestBlockY, IntPtr getWorldInfo, IntPtr setWorldTime, IntPtr setWeather, IntPtr createExplosion, IntPtr strikeLightning, IntPtr setSpawnLocation, IntPtr dropItem)
{
GetTileId = Marshal.GetDelegateForFunctionPointer<NativeGetTileIdDelegate>(getTileId);
GetTileData = Marshal.GetDelegateForFunctionPointer<NativeGetTileDataDelegate>(getTileData);
SetTile = Marshal.GetDelegateForFunctionPointer<NativeSetTileDelegate>(setTile);
SetTileData = Marshal.GetDelegateForFunctionPointer<NativeSetTileDataDelegate>(setTileData);
BreakBlock = Marshal.GetDelegateForFunctionPointer<NativeBreakBlockDelegate>(breakBlock);
GetHighestBlockY = Marshal.GetDelegateForFunctionPointer<NativeGetHighestBlockYDelegate>(getHighestBlockY);
GetWorldInfo = Marshal.GetDelegateForFunctionPointer<NativeGetWorldInfoDelegate>(getWorldInfo);
SetWorldTime = Marshal.GetDelegateForFunctionPointer<NativeSetWorldTimeDelegate>(setWorldTime);
SetWeather = Marshal.GetDelegateForFunctionPointer<NativeSetWeatherDelegate>(setWeather);
CreateExplosion = Marshal.GetDelegateForFunctionPointer<NativeCreateExplosionDelegate>(createExplosion);
StrikeLightning = Marshal.GetDelegateForFunctionPointer<NativeStrikeLightningDelegate>(strikeLightning);
SetSpawnLocation = Marshal.GetDelegateForFunctionPointer<NativeSetSpawnLocationDelegate>(setSpawnLocation);
DropItem = Marshal.GetDelegateForFunctionPointer<NativeDropItemDelegate>(dropItem);
}
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)
{
GetPlayerInventory = Marshal.GetDelegateForFunctionPointer<NativeGetPlayerInventoryDelegate>(getPlayerInventory);
SetPlayerInventorySlot = Marshal.GetDelegateForFunctionPointer<NativeSetPlayerInventorySlotDelegate>(setPlayerInventorySlot);
GetContainerContents = Marshal.GetDelegateForFunctionPointer<NativeGetContainerContentsDelegate>(getContainerContents);
SetContainerSlot = Marshal.GetDelegateForFunctionPointer<NativeSetContainerSlotDelegate>(setContainerSlot);
GetContainerViewerEntityIds = Marshal.GetDelegateForFunctionPointer<NativeGetContainerViewerEntityIdsDelegate>(getContainerViewerEntityIds);
CloseContainer = Marshal.GetDelegateForFunctionPointer<NativeCloseContainerDelegate>(closeContainer);
OpenVirtualContainer = Marshal.GetDelegateForFunctionPointer<NativeOpenVirtualContainerDelegate>(openVirtualContainer);
GetItemMeta = Marshal.GetDelegateForFunctionPointer<NativeGetItemMetaDelegate>(getItemMeta);
SetItemMeta = Marshal.GetDelegateForFunctionPointer<NativeSetItemMetaDelegate>(setItemMeta);
SetHeldItemSlot = Marshal.GetDelegateForFunctionPointer<NativeSetHeldItemSlotDelegate>(setHeldItemSlot);
}
internal static void SetEntityCallbacks(IntPtr setSneaking, IntPtr setVelocity, IntPtr setAllowFlight, IntPtr playSound, IntPtr setSleepingIgnored)
{
SetSneaking = Marshal.GetDelegateForFunctionPointer<NativeSetSneakingDelegate>(setSneaking);
SetVelocity = Marshal.GetDelegateForFunctionPointer<NativeSetVelocityDelegate>(setVelocity);
SetAllowFlight = Marshal.GetDelegateForFunctionPointer<NativeSetAllowFlightDelegate>(setAllowFlight);
PlaySound = Marshal.GetDelegateForFunctionPointer<NativePlaySoundDelegate>(playSound);
SetSleepingIgnored = Marshal.GetDelegateForFunctionPointer<NativeSetSleepingIgnoredDelegate>(setSleepingIgnored);
}
internal static void SetExperienceCallbacks(IntPtr setLevel, IntPtr setExp, IntPtr giveExp, IntPtr giveExpLevels, IntPtr setFoodLevel, IntPtr setSaturation, IntPtr setExhaustion)
{
SetLevel = Marshal.GetDelegateForFunctionPointer<NativeSetLevelDelegate>(setLevel);
SetExp = Marshal.GetDelegateForFunctionPointer<NativeSetExpDelegate>(setExp);
GiveExp = Marshal.GetDelegateForFunctionPointer<NativeGiveExpDelegate>(giveExp);
GiveExpLevels = Marshal.GetDelegateForFunctionPointer<NativeGiveExpLevelsDelegate>(giveExpLevels);
SetFoodLevel = Marshal.GetDelegateForFunctionPointer<NativeSetFoodLevelDelegate>(setFoodLevel);
SetSaturation = Marshal.GetDelegateForFunctionPointer<NativeSetSaturationDelegate>(setSaturation);
SetExhaustion = Marshal.GetDelegateForFunctionPointer<NativeSetExhaustionDelegate>(setExhaustion);
}
internal static void SetParticleCallbacks(IntPtr spawnParticle)
{
SpawnParticle = Marshal.GetDelegateForFunctionPointer<NativeSpawnParticleDelegate>(spawnParticle);
}
internal static void SetVehicleCallbacks(IntPtr setPassenger, IntPtr leaveVehicle, IntPtr eject, IntPtr getVehicleId, IntPtr getPassengerId, IntPtr getEntityInfo)
{
SetPassenger = Marshal.GetDelegateForFunctionPointer<NativeSetPassengerDelegate>(setPassenger);
LeaveVehicle = Marshal.GetDelegateForFunctionPointer<NativeLeaveVehicleDelegate>(leaveVehicle);
Eject = Marshal.GetDelegateForFunctionPointer<NativeEjectDelegate>(eject);
GetVehicleId = Marshal.GetDelegateForFunctionPointer<NativeGetVehicleIdDelegate>(getVehicleId);
GetPassengerId = Marshal.GetDelegateForFunctionPointer<NativeGetPassengerIdDelegate>(getPassengerId);
GetEntityInfo = Marshal.GetDelegateForFunctionPointer<NativeGetEntityInfoDelegate>(getEntityInfo);
}
}