add missing block.getData() (oops) and use string localization

This commit is contained in:
sylvessa 2026-03-22 02:37:45 -05:00
parent 0d1e0177e5
commit 54d4ad1ce0
6 changed files with 162 additions and 52 deletions

View file

@ -37,63 +37,147 @@
#include "..\Minecraft.Server\FourKitBridge.h"
#include "..\Minecraft.World\ChatPacket.h"
// todo: rework this to use string localization funcs instead of hardcoded
static std::wstring FormatDeathMessage(const shared_ptr<ChatPacket>& packet)
{
if (!packet) return L"";
const std::wstring& player = packet->m_stringArgs.size() > 0 ? packet->m_stringArgs[0] : L"";
const std::wstring& killer = packet->m_stringArgs.size() > 1 ? packet->m_stringArgs[1] : L"";
const std::wstring& item = packet->m_stringArgs.size() > 2 ? packet->m_stringArgs[2] : L"";
std::wstring message;
bool replacePlayer = false;
bool replaceEntitySource = false;
bool replaceItem = false;
// coug chough
// de hättn echt an gscheidern string konverter für de todesmeldungen macha soin
// a globaler helfer waar wahrscheinlich ganz bärig gwen
// waaaah
switch (packet->m_messageType)
{
case ChatPacket::e_ChatCustom: return player;
case ChatPacket::e_ChatDeathInFire: return player + L" went up in flames";
case ChatPacket::e_ChatDeathOnFire: return player + L" burned to death";
case ChatPacket::e_ChatDeathLava: return player + L" tried to swim in lava";
case ChatPacket::e_ChatDeathInWall: return player + L" suffocated in a wall";
case ChatPacket::e_ChatDeathDrown: return player + L" drowned";
case ChatPacket::e_ChatDeathStarve: return player + L" starved to death";
case ChatPacket::e_ChatDeathCactus: return player + L" was pricked to death";
case ChatPacket::e_ChatDeathFall: return player + L" hit the ground too hard";
case ChatPacket::e_ChatDeathOutOfWorld: return player + L" fell out of the world";
case ChatPacket::e_ChatDeathGeneric: return player + L" died";
case ChatPacket::e_ChatDeathExplosion: return player + L" blew up";
case ChatPacket::e_ChatDeathMagic: return player + L" was killed by magic";
case ChatPacket::e_ChatDeathWither: return player + L" withered away";
case ChatPacket::e_ChatDeathDragonBreath: return player + L" was killed by Ender Dragon breath";
case ChatPacket::e_ChatDeathAnvil: return player + L" was squashed by a falling Anvil.";
case ChatPacket::e_ChatDeathFallingBlock: return player + L" was squashed by a falling block.";
case ChatPacket::e_ChatDeathFellAccidentLadder: return player + L" fell off a ladder";
case ChatPacket::e_ChatDeathFellAccidentVines: return player + L" fell off some vines";
case ChatPacket::e_ChatDeathFellAccidentWater: return player + L" fell out of the water";
case ChatPacket::e_ChatDeathFellAccidentGeneric:return player + L" fell from a high place";
case ChatPacket::e_ChatDeathFellKiller: return player + L" was doomed to fall";
case ChatPacket::e_ChatCustom:
return packet->m_stringArgs.size() > 0 ? packet->m_stringArgs[0] : L"";
case ChatPacket::e_ChatDeathInFire:
message = app.GetString(IDS_DEATH_INFIRE); replacePlayer = true; break;
case ChatPacket::e_ChatDeathOnFire:
message = app.GetString(IDS_DEATH_ONFIRE); replacePlayer = true; break;
case ChatPacket::e_ChatDeathLava:
message = app.GetString(IDS_DEATH_LAVA); replacePlayer = true; break;
case ChatPacket::e_ChatDeathInWall:
message = app.GetString(IDS_DEATH_INWALL); replacePlayer = true; break;
case ChatPacket::e_ChatDeathDrown:
message = app.GetString(IDS_DEATH_DROWN); replacePlayer = true; break;
case ChatPacket::e_ChatDeathStarve:
message = app.GetString(IDS_DEATH_STARVE); replacePlayer = true; break;
case ChatPacket::e_ChatDeathCactus:
message = app.GetString(IDS_DEATH_CACTUS); replacePlayer = true; break;
case ChatPacket::e_ChatDeathFall:
message = app.GetString(IDS_DEATH_FALL); replacePlayer = true; break;
case ChatPacket::e_ChatDeathOutOfWorld:
message = app.GetString(IDS_DEATH_OUTOFWORLD); replacePlayer = true; break;
case ChatPacket::e_ChatDeathGeneric:
message = app.GetString(IDS_DEATH_GENERIC); replacePlayer = true; break;
case ChatPacket::e_ChatDeathExplosion:
message = app.GetString(IDS_DEATH_EXPLOSION); replacePlayer = true; break;
case ChatPacket::e_ChatDeathMagic:
message = app.GetString(IDS_DEATH_MAGIC); replacePlayer = true; break;
case ChatPacket::e_ChatDeathWither:
message = app.GetString(IDS_DEATH_WITHER); replacePlayer = true; break;
case ChatPacket::e_ChatDeathDragonBreath:
message = app.GetString(IDS_DEATH_DRAGON_BREATH); replacePlayer = true; break;
case ChatPacket::e_ChatDeathAnvil:
message = app.GetString(IDS_DEATH_FALLING_ANVIL); replacePlayer = true; break;
case ChatPacket::e_ChatDeathFallingBlock:
message = app.GetString(IDS_DEATH_FALLING_TILE); replacePlayer = true; break;
case ChatPacket::e_ChatDeathFellAccidentLadder:
message = app.GetString(IDS_DEATH_FELL_ACCIDENT_LADDER); replacePlayer = true; break;
case ChatPacket::e_ChatDeathFellAccidentVines:
message = app.GetString(IDS_DEATH_FELL_ACCIDENT_VINES); replacePlayer = true; break;
case ChatPacket::e_ChatDeathFellAccidentWater:
message = app.GetString(IDS_DEATH_FELL_ACCIDENT_WATER); replacePlayer = true; break;
case ChatPacket::e_ChatDeathFellAccidentGeneric:
message = app.GetString(IDS_DEATH_FELL_ACCIDENT_GENERIC); replacePlayer = true; break;
case ChatPacket::e_ChatDeathFellKiller:
message = app.GetString(IDS_DEATH_FALL); replacePlayer = true; break;
case ChatPacket::e_ChatDeathMob:
case ChatPacket::e_ChatDeathPlayer: return killer.empty() ? player + L" was slain" : player + L" was slain by " + killer;
case ChatPacket::e_ChatDeathArrow: return killer.empty() ? player + L" was shot" : player + L" was shot by " + killer;
case ChatPacket::e_ChatDeathFireball: return killer.empty() ? player + L" was fireballed" : player + L" was fireballed by " + killer;
case ChatPacket::e_ChatDeathThrown: return killer.empty() ? player + L" was pummeled" : player + L" was pummeled by " + killer;
case ChatPacket::e_ChatDeathIndirectMagic: return killer.empty() ? player + L" was killed by magic" : player + L" was killed by " + killer + L" using magic";
case ChatPacket::e_ChatDeathThorns: return killer.empty() ? player + L" died" : player + L" was killed trying to hurt " + killer;
case ChatPacket::e_ChatDeathExplosionPlayer: return killer.empty() ? player + L" blew up" : player + L" was blown up by " + killer;
case ChatPacket::e_ChatDeathInFirePlayer: return killer.empty() ? player + L" went up in flames" : player + L" walked into fire whilst fighting " + killer;
case ChatPacket::e_ChatDeathOnFirePlayer: return killer.empty() ? player + L" burned to death" : player + L" was burnt to a crisp whilst fighting " + killer;
case ChatPacket::e_ChatDeathLavaPlayer: return killer.empty() ? player + L" tried to swim in lava" : player + L" tried to swim in lava to escape " + killer;
case ChatPacket::e_ChatDeathDrownPlayer: return killer.empty() ? player + L" drowned" : player + L" drowned whilst trying to escape " + killer;
case ChatPacket::e_ChatDeathCactusPlayer: return killer.empty() ? player + L" was pricked to death" : player + L" walked into a cactus whilst trying to escape " + killer;
case ChatPacket::e_ChatDeathFellAssist: return killer.empty() ? player + L" was doomed to fall" : player + L" was doomed to fall by " + killer;
case ChatPacket::e_ChatDeathFellFinish: return killer.empty() ? player + L" fell too far" : player + L" fell too far and was finished by " + killer;
case ChatPacket::e_ChatDeathPlayerItem: return (killer.empty() ? player + L" was slain" : player + L" was slain by " + killer) + (item.empty() ? L"" : L" using " + item);
case ChatPacket::e_ChatDeathArrowItem: return (killer.empty() ? player + L" was shot" : player + L" was shot by " + killer) + (item.empty() ? L"" : L" with " + item);
case ChatPacket::e_ChatDeathFireballItem: return (killer.empty() ? player + L" was fireballed" : player + L" was fireballed by " + killer) + (item.empty() ? L"" : L" with " + item);
case ChatPacket::e_ChatDeathThrownItem: return (killer.empty() ? player + L" was pummeled" : player + L" was pummeled by " + killer) + (item.empty() ? L"" : L" using " + item);
case ChatPacket::e_ChatDeathIndirectMagicItem: return (killer.empty() ? player + L" was killed by magic" : player + L" was killed by " + killer) + (item.empty() ? L"" : L" using " + item);
case ChatPacket::e_ChatDeathFellAssistItem: return (killer.empty() ? player + L" was doomed to fall" : player + L" was doomed to fall by " + killer) + (item.empty() ? L"" : L" using " + item);
case ChatPacket::e_ChatDeathFellFinishItem: return (killer.empty() ? player + L" fell too far" : player + L" fell too far and was finished by " + killer) + (item.empty() ? L"" : L" using " + item);
default: return player + L" died";
message = app.GetString(IDS_DEATH_MOB); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathPlayer:
message = app.GetString(IDS_DEATH_PLAYER); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathArrow:
message = app.GetString(IDS_DEATH_ARROW); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathFireball:
message = app.GetString(IDS_DEATH_FIREBALL); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathThrown:
message = app.GetString(IDS_DEATH_THROWN); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathIndirectMagic:
message = app.GetString(IDS_DEATH_INDIRECT_MAGIC); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathThorns:
message = app.GetString(IDS_DEATH_THORNS); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathExplosionPlayer:
message = app.GetString(IDS_DEATH_EXPLOSION_PLAYER); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathInFirePlayer:
message = app.GetString(IDS_DEATH_INFIRE_PLAYER); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathOnFirePlayer:
message = app.GetString(IDS_DEATH_ONFIRE_PLAYER); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathLavaPlayer:
message = app.GetString(IDS_DEATH_LAVA_PLAYER); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathDrownPlayer:
message = app.GetString(IDS_DEATH_DROWN_PLAYER); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathCactusPlayer:
message = app.GetString(IDS_DEATH_CACTUS_PLAYER); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathFellAssist:
message = app.GetString(IDS_DEATH_FELL_ASSIST); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathFellFinish:
message = app.GetString(IDS_DEATH_FELL_FINISH); replacePlayer = true; replaceEntitySource = true; break;
case ChatPacket::e_ChatDeathPlayerItem:
message = app.GetString(IDS_DEATH_PLAYER_ITEM); replacePlayer = true; replaceEntitySource = true; replaceItem = true; break;
case ChatPacket::e_ChatDeathArrowItem:
message = app.GetString(IDS_DEATH_ARROW_ITEM); replacePlayer = true; replaceEntitySource = true; replaceItem = true; break;
case ChatPacket::e_ChatDeathFireballItem:
message = app.GetString(IDS_DEATH_FIREBALL_ITEM); replacePlayer = true; replaceEntitySource = true; replaceItem = true; break;
case ChatPacket::e_ChatDeathThrownItem:
message = app.GetString(IDS_DEATH_THROWN_ITEM); replacePlayer = true; replaceEntitySource = true; replaceItem = true; break;
case ChatPacket::e_ChatDeathIndirectMagicItem:
message = app.GetString(IDS_DEATH_INDIRECT_MAGIC_ITEM); replacePlayer = true; replaceEntitySource = true; replaceItem = true; break;
case ChatPacket::e_ChatDeathFellAssistItem:
message = app.GetString(IDS_DEATH_FELL_ASSIST_ITEM); replacePlayer = true; replaceEntitySource = true; replaceItem = true; break;
case ChatPacket::e_ChatDeathFellFinishItem:
message = app.GetString(IDS_DEATH_FELL_FINISH_ITEM); replacePlayer = true; replaceEntitySource = true; replaceItem = true; break;
default:
message = app.GetString(IDS_DEATH_GENERIC); replacePlayer = true; break;
}
if (replacePlayer)
{
std::wstring playerName = packet->m_stringArgs.size() > 0 ? packet->m_stringArgs[0] : L"";
message = replaceAll(message, L"{*PLAYER*}", playerName);
}
if (replaceEntitySource)
{
std::wstring sourceName;
if (!packet->m_intArgs.empty() && packet->m_intArgs[0] == eTYPE_SERVERPLAYER)
{
sourceName = packet->m_stringArgs.size() > 1 ? packet->m_stringArgs[1] : L"";
}
else
{
if (packet->m_stringArgs.size() > 1 && !packet->m_stringArgs[1].empty())
{
sourceName = packet->m_stringArgs[1];
}
else if (!packet->m_intArgs.empty())
{
sourceName = app.getEntityName((eINSTANCEOF)packet->m_intArgs[0]);
}
}
message = replaceAll(message, L"{*SOURCE*}", sourceName);
}
if (replaceItem)
{
std::wstring itemName = packet->m_stringArgs.size() > 2 ? packet->m_stringArgs[2] : L"";
message = replaceAll(message, L"{*ITEM*}", itemName);
}
return message;
}
#endif

View file

@ -93,6 +93,15 @@ public class Block
return true;
}
/// <summary>
/// Gets the metadata value for this block.
/// </summary>
/// <returns>Block specific metadata.</returns>
public byte getData()
{
return (byte)NativeBridge.GetTileData(_world.getDimensionId(), _x, _y, _z);
}
/// <summary>
/// Sets the metadata value for this block.
/// </summary>

View file

@ -553,11 +553,11 @@ public static class FourKitHost
}
[UnmanagedCallersOnly]
public static void SetWorldCallbacks(IntPtr getTileId, IntPtr setTile, IntPtr setTileData, IntPtr breakBlock, IntPtr getHighestBlockY, IntPtr getWorldInfo, IntPtr setWorldTime, IntPtr setWeather, IntPtr createExplosion, IntPtr strikeLightning, IntPtr setSpawnLocation, IntPtr dropItem)
public 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)
{
try
{
NativeBridge.SetWorldCallbacks(getTileId, setTile, setTileData, breakBlock, getHighestBlockY, getWorldInfo, setWorldTime, setWeather, createExplosion, strikeLightning, setSpawnLocation, dropItem);
NativeBridge.SetWorldCallbacks(getTileId, getTileData, setTile, setTileData, breakBlock, getHighestBlockY, getWorldInfo, setWorldTime, setWeather, createExplosion, strikeLightning, setSpawnLocation, dropItem);
//ServerLog.Info("fourkit", "World native callbacks registered.");
}
catch (Exception ex)

View file

@ -39,6 +39,9 @@ internal static class NativeBridge
[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);
@ -118,6 +121,7 @@ internal static class NativeBridge
internal static NativeTeleportEntityDelegate? TeleportEntity;
internal static NativeGetTileIdDelegate? GetTileId;
internal static NativeGetTileDataDelegate? GetTileData;
internal static NativeSetTileDelegate? SetTile;
internal static NativeSetTileDataDelegate? SetTileData;
internal static NativeBreakBlockDelegate? BreakBlock;
@ -155,9 +159,10 @@ internal static class NativeBridge
TeleportEntity = Marshal.GetDelegateForFunctionPointer<NativeTeleportEntityDelegate>(teleportEntity);
}
internal static void SetWorldCallbacks(IntPtr getTileId, IntPtr setTile, IntPtr setTileData, IntPtr breakBlock, IntPtr getHighestBlockY, IntPtr getWorldInfo, IntPtr setWorldTime, IntPtr setWeather, IntPtr createExplosion, IntPtr strikeLightning, IntPtr setSpawnLocation, IntPtr dropItem)
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);

View file

@ -112,7 +112,7 @@ typedef int(__stdcall *fn_fire_player_move)(int entityId,
double toX, double toY, double toZ,
double *outCoords);
typedef void(__stdcall *fn_set_native_callbacks)(void *damage, void *setHealth, void *teleport, void *setGameMode, void *broadcastMessage, void *setFallDistance, void *getPlayerSnapshot, void *sendMessage, void *setWalkSpeed, void *teleportEntity);
typedef void(__stdcall *fn_set_world_callbacks)(void *getTileId, void *setTile, void *setTileData, void *breakBlock, void *getHighestBlockY, void *getWorldInfo, void *setWorldTime, void *setWeather, void *createExplosion, void *strikeLightning, void *setSpawnLocation, void *dropItem);
typedef void(__stdcall *fn_set_world_callbacks)(void *getTileId, void *getTileData, void *setTile, void *setTileData, void *breakBlock, void *getHighestBlockY, void *getWorldInfo, void *setWorldTime, void *setWeather, void *createExplosion, void *strikeLightning, void *setSpawnLocation, void *dropItem);
typedef void(__stdcall *fn_update_entity_id)(int oldEntityId, int newEntityId);
typedef int(__stdcall *fn_fire_player_chat)(int entityId, const char *msgUtf8, int msgByteLen, char *outBuf, int outBufSize, int *outLen);
typedef int(__stdcall *fn_fire_block_place)(int entityId, int dimId,
@ -448,6 +448,16 @@ static void __cdecl NativeSetTile(int dimId, int x, int y, int z, int tileId, in
level->setTileAndData(x, y, z, tileId, data, Tile::UPDATE_ALL);
}
static int __cdecl NativeGetTileData(int dimId, int x, int y, int z)
{
ServerLevel *level = GetLevel(dimId);
if (!level)
{
return 0;
}
return level->getData(x, y, z);
}
static void __cdecl NativeSetTileData(int dimId, int x, int y, int z, int data)
{
ServerLevel *level = GetLevel(dimId);
@ -1318,6 +1328,7 @@ void Initialize()
s_managedSetWorldCallbacks(
(void *)&NativeGetTileId,
(void *)&NativeGetTileData,
(void *)&NativeSetTile,
(void *)&NativeSetTileData,
(void *)&NativeBreakBlock,

View file

@ -19,6 +19,7 @@ namespace FourKitBridge
void UpdatePlayerEntityId(int oldEntityId, int newEntityId);
int GetTileId(int dimId, int x, int y, int z);
int GetTileData(int dimId, int x, int y, int z);
void SetTile(int dimId, int x, int y, int z, int tileId, int data);
void SetTileData(int dimId, int x, int y, int z, int data);
int BreakBlock(int dimId, int x, int y, int z);