mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-05-29 20:32:56 +00:00
add PlayerBedEnterEvent and PlayerBedLeaveEvent + 2 new HumanEntity funcs
This commit is contained in:
parent
6847af62e1
commit
9cbc9aca28
|
|
@ -1046,6 +1046,10 @@ void ServerPlayer::take(shared_ptr<Entity> e, int orgCount)
|
|||
|
||||
Player::BedSleepingResult ServerPlayer::startSleepInBed(int x, int y, int z, bool bTestUse)
|
||||
{
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
if (!bTestUse && FourKitBridge::FireBedEnter(entityId, dimension, x, y, z))
|
||||
return OTHER_PROBLEM;
|
||||
#endif
|
||||
BedSleepingResult result = Player::startSleepInBed(x, y, z, bTestUse);
|
||||
if (result == OK)
|
||||
{
|
||||
|
|
@ -1059,12 +1063,22 @@ Player::BedSleepingResult ServerPlayer::startSleepInBed(int x, int y, int z, boo
|
|||
|
||||
void ServerPlayer::stopSleepInBed(bool forcefulWakeUp, bool updateLevelList, bool saveRespawnPoint)
|
||||
{
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
int bedX = bedPosition ? bedPosition->x : 0;
|
||||
int bedY = bedPosition ? bedPosition->y : 0;
|
||||
int bedZ = bedPosition ? bedPosition->z : 0;
|
||||
bool wasSleeping = isSleeping();
|
||||
#endif
|
||||
if (isSleeping())
|
||||
{
|
||||
getLevel()->getTracker()->broadcastAndSend(shared_from_this(), std::make_shared<AnimatePacket>(shared_from_this(), AnimatePacket::WAKE_UP));
|
||||
}
|
||||
Player::stopSleepInBed(forcefulWakeUp, updateLevelList, saveRespawnPoint);
|
||||
if (connection != nullptr) connection->teleport(x, y, z, yRot, xRot);
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
if (wasSleeping)
|
||||
FourKitBridge::FireBedLeave(entityId, dimension, bedX, bedY, bedZ);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ServerPlayer::ride(shared_ptr<Entity> e)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ public abstract class HumanEntity : LivingEntity, InventoryHolder
|
|||
internal PlayerInventory _playerInventory = new();
|
||||
internal Inventory _enderChestInventory = new("Ender Chest", InventoryType.ENDER_CHEST, 27);
|
||||
private ItemStack? _cursorItem;
|
||||
private bool _sleeping;
|
||||
private int _sleepTicks;
|
||||
|
||||
/// <summary>
|
||||
/// Gets this human's current <see cref="GameMode"/>.
|
||||
|
|
@ -154,4 +156,20 @@ public abstract class HumanEntity : LivingEntity, InventoryHolder
|
|||
internal void SetGameModeInternal(GameMode mode) => _gameMode = mode;
|
||||
|
||||
internal void SetNameInternal(string name) => _name = name;
|
||||
|
||||
internal void SetSleepingInternal(bool sleeping) => _sleeping = sleeping;
|
||||
|
||||
internal void SetSleepTicksInternal(int ticks) => _sleepTicks = ticks;
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this player is slumbering.
|
||||
/// </summary>
|
||||
/// <returns>slumber state</returns>
|
||||
public bool isSleeping() => _sleeping;
|
||||
|
||||
/// <summary>
|
||||
/// Get the sleep ticks of the player. This value may be capped.
|
||||
/// </summary>
|
||||
/// <returns>slumber ticks</returns>
|
||||
public int getSleepTicks() => _sleepTicks;
|
||||
}
|
||||
|
|
|
|||
33
Minecraft.Server.FourKit/Event/Player/PlayerBedEnterEvent.cs
Normal file
33
Minecraft.Server.FourKit/Event/Player/PlayerBedEnterEvent.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
namespace Minecraft.Server.FourKit.Event.Player;
|
||||
|
||||
using Minecraft.Server.FourKit.Entity;
|
||||
using Minecraft.Server.FourKit.Block;
|
||||
|
||||
/// <summary>
|
||||
/// This event is fired when the player is almost about to enter the bed.
|
||||
/// </summary>
|
||||
public class PlayerBedEnterEvent : PlayerEvent, Cancellable
|
||||
{
|
||||
private readonly Block _bed;
|
||||
private bool _cancelled;
|
||||
|
||||
internal PlayerBedEnterEvent(Player player, Block bed) : base(player)
|
||||
{
|
||||
_bed = bed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the bed block involved in this event.
|
||||
/// </summary>
|
||||
/// <returns>the bed block involved in this event</returns>
|
||||
public Block getBed() => _bed;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool isCancelled() => _cancelled;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void setCancelled(bool cancel)
|
||||
{
|
||||
_cancelled = cancel;
|
||||
}
|
||||
}
|
||||
23
Minecraft.Server.FourKit/Event/Player/PlayerBedLeaveEvent.cs
Normal file
23
Minecraft.Server.FourKit/Event/Player/PlayerBedLeaveEvent.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
namespace Minecraft.Server.FourKit.Event.Player;
|
||||
|
||||
using Minecraft.Server.FourKit.Entity;
|
||||
using Minecraft.Server.FourKit.Block;
|
||||
|
||||
/// <summary>
|
||||
/// This event is fired when the player is leaving a bed.
|
||||
/// </summary>
|
||||
public class PlayerBedLeaveEvent : PlayerEvent
|
||||
{
|
||||
private readonly Block _bed;
|
||||
|
||||
internal PlayerBedLeaveEvent(Player player, Block bed) : base(player)
|
||||
{
|
||||
_bed = bed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the bed block involved in this event.
|
||||
/// </summary>
|
||||
/// <returns>the bed block involved in this event</returns>
|
||||
public Block getBed() => _bed;
|
||||
}
|
||||
|
|
@ -948,12 +948,12 @@ public static class FourKitHost
|
|||
};
|
||||
}
|
||||
|
||||
// double[11] = { x, y, z, health, maxHealth, fallDistance, gameMode, walkSpeed, yaw, pitch, dimension }
|
||||
// double[13] = { x, y, z, health, maxHealth, fallDistance, gameMode, walkSpeed, yaw, pitch, dimension, isSleeping, sleepTimer }
|
||||
private static void SyncPlayerFromNative(Player player)
|
||||
{
|
||||
if (NativeBridge.GetPlayerSnapshot == null)
|
||||
return;
|
||||
double[] buf = new double[11];
|
||||
double[] buf = new double[13];
|
||||
var gh = GCHandle.Alloc(buf, GCHandleType.Pinned);
|
||||
try
|
||||
{
|
||||
|
|
@ -972,6 +972,8 @@ public static class FourKitHost
|
|||
player.SetFallDistanceInternal((float)buf[5]);
|
||||
player.SetGameModeInternal((GameMode)(int)buf[6]);
|
||||
player.SetWalkSpeedInternal((float)buf[7]);
|
||||
player.SetSleepingInternal(buf[11] != 0.0);
|
||||
player.SetSleepTicksInternal((int)buf[12]);
|
||||
}
|
||||
|
||||
private static void BroadcastNativeMessage(string message)
|
||||
|
|
@ -1180,6 +1182,51 @@ public static class FourKitHost
|
|||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static int FireBedEnter(int entityId, int dimId, int bedX, int bedY, int bedZ)
|
||||
{
|
||||
try
|
||||
{
|
||||
var player = FourKit.GetPlayerByEntityId(entityId);
|
||||
if (player == null) return 0;
|
||||
|
||||
SyncPlayerFromNative(player);
|
||||
|
||||
var world = FourKit.getWorld(dimId);
|
||||
var bed = new Block.Block(world, bedX, bedY, bedZ);
|
||||
var evt = new Event.Player.PlayerBedEnterEvent(player, bed);
|
||||
FourKit.FireEvent(evt);
|
||||
|
||||
return evt.isCancelled() ? 1 : 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerLog.Error("fourkit", $"FireBedEnter error: {ex}");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void FireBedLeave(int entityId, int dimId, int bedX, int bedY, int bedZ)
|
||||
{
|
||||
try
|
||||
{
|
||||
var player = FourKit.GetPlayerByEntityId(entityId);
|
||||
if (player == null) return;
|
||||
|
||||
SyncPlayerFromNative(player);
|
||||
|
||||
var world = FourKit.getWorld(dimId);
|
||||
var bed = new Block.Block(world, bedX, bedY, bedZ);
|
||||
var evt = new Event.Player.PlayerBedLeaveEvent(player, bed);
|
||||
FourKit.FireEvent(evt);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerLog.Error("fourkit", $"FireBedLeave error: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private static ClickType MapNativeClickType(int nativeClickType, int button)
|
||||
{
|
||||
return nativeClickType switch
|
||||
|
|
|
|||
|
|
@ -170,8 +170,10 @@ typedef int(__stdcall *fn_fire_player_portal)(int entityId,
|
|||
double toX, double toY, double toZ, int toDimId,
|
||||
int cause, double *outCoords);
|
||||
typedef int(__stdcall *fn_fire_inventory_click)(int entityId,
|
||||
int slot, int button, int clickType, int nativeContainerType, int containerSize,
|
||||
const char *titleUtf8, int titleByteLen);
|
||||
int slot, int button, int clickType, int nativeContainerType, int containerSize,
|
||||
const char *titleUtf8, int titleByteLen);
|
||||
typedef int(__stdcall *fn_fire_bed_enter)(int entityId, int dimId, int bedX, int bedY, int bedZ);
|
||||
typedef void(__stdcall *fn_fire_bed_leave)(int entityId, int dimId, int bedX, int bedY, int bedZ);
|
||||
|
||||
struct OpenContainerInfo
|
||||
{
|
||||
|
|
@ -210,6 +212,8 @@ static fn_get_plugin_command_help s_managedGetPluginCommandHelp = nullptr;
|
|||
static fn_fire_player_teleport s_managedFirePlayerTeleport = nullptr;
|
||||
static fn_fire_player_portal s_managedFirePlayerPortal = nullptr;
|
||||
static fn_fire_inventory_click s_managedFireInventoryClick = nullptr;
|
||||
static fn_fire_bed_enter s_managedFireBedEnter = nullptr;
|
||||
static fn_fire_bed_leave s_managedFireBedLeave = nullptr;
|
||||
|
||||
static bool s_initialized = false;
|
||||
|
||||
|
|
@ -321,13 +325,13 @@ static void __cdecl NativeSetFallDistance(int entityId, float distance)
|
|||
}
|
||||
}
|
||||
|
||||
// double[11] = { x, y, z, health, maxHealth, fallDistance, gameMode, walkSpeed, yaw, pitch, dimension }
|
||||
// double[13] = { x, y, z, health, maxHealth, fallDistance, gameMode, walkSpeed, yaw, pitch, dimension, isSleeping, sleepTimer }
|
||||
static void __cdecl NativeGetPlayerSnapshot(int entityId, double *outData)
|
||||
{
|
||||
auto player = FindPlayer(entityId);
|
||||
if (!player)
|
||||
{
|
||||
memset(outData, 0, 11 * sizeof(double));
|
||||
memset(outData, 0, 13 * sizeof(double));
|
||||
outData[3] = 20.0;
|
||||
outData[4] = 20.0;
|
||||
outData[7] = 0.1;
|
||||
|
|
@ -345,6 +349,8 @@ static void __cdecl NativeGetPlayerSnapshot(int entityId, double *outData)
|
|||
outData[8] = (double)player->yRot;
|
||||
outData[9] = (double)player->xRot;
|
||||
outData[10] = (double)player->dimension;
|
||||
outData[11] = player->isSleeping() ? 1.0 : 0.0;
|
||||
outData[12] = (double)player->getSleepTimer();
|
||||
}
|
||||
|
||||
static void __cdecl NativeBroadcastMessage(const char *utf8, int len)
|
||||
|
|
@ -1303,6 +1309,8 @@ void Initialize()
|
|||
ok = ok && GetManagedEntryPoint(loadAssembly, assemblyPath.c_str(), typeName, L"FirePlayerTeleport", (void **)&s_managedFirePlayerTeleport);
|
||||
ok = ok && GetManagedEntryPoint(loadAssembly, assemblyPath.c_str(), typeName, L"FirePlayerPortal", (void **)&s_managedFirePlayerPortal);
|
||||
ok = ok && GetManagedEntryPoint(loadAssembly, assemblyPath.c_str(), typeName, L"FireInventoryClick", (void **)&s_managedFireInventoryClick);
|
||||
ok = ok && GetManagedEntryPoint(loadAssembly, assemblyPath.c_str(), typeName, L"FireBedEnter", (void **)&s_managedFireBedEnter);
|
||||
ok = ok && GetManagedEntryPoint(loadAssembly, assemblyPath.c_str(), typeName, L"FireBedLeave", (void **)&s_managedFireBedLeave);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
|
|
@ -2110,4 +2118,18 @@ int FireInventoryClick(int entityId, int slot, int button, int clickType)
|
|||
return s_managedFireInventoryClick(entityId, slot, button, clickType, nativeContainerType, containerSize,
|
||||
titleUtf8.empty() ? nullptr : titleUtf8.data(), (int)titleUtf8.size());
|
||||
}
|
||||
|
||||
bool FireBedEnter(int entityId, int dimId, int bedX, int bedY, int bedZ)
|
||||
{
|
||||
if (!s_initialized || !s_managedFireBedEnter)
|
||||
return false;
|
||||
return s_managedFireBedEnter(entityId, dimId, bedX, bedY, bedZ) != 0;
|
||||
}
|
||||
|
||||
void FireBedLeave(int entityId, int dimId, int bedX, int bedY, int bedZ)
|
||||
{
|
||||
if (!s_initialized || !s_managedFireBedLeave)
|
||||
return;
|
||||
s_managedFireBedLeave(entityId, dimId, bedX, bedY, bedZ);
|
||||
}
|
||||
} // namespace FourKitBridge
|
||||
|
|
|
|||
|
|
@ -78,4 +78,6 @@ namespace FourKitBridge
|
|||
int cause,
|
||||
double *outToX, double *outToY, double *outToZ);
|
||||
int FireInventoryClick(int entityId, int slot, int button, int clickType);
|
||||
bool FireBedEnter(int entityId, int dimId, int bedX, int bedY, int bedZ);
|
||||
void FireBedLeave(int entityId, int dimId, int bedX, int bedY, int bedZ);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue