From 89a64882ef35fe956a6056e5069c8362c0366ccd Mon Sep 17 00:00:00 2001 From: neoapps-dev Date: Sun, 3 May 2026 16:16:07 +0300 Subject: [PATCH] fix(PlayerConnection): /tp fix fix(PlayerConnection): pointer fix(PlayerConnection): bytearray fix(PlayerConnection): bytearray fix(PlayerConnection): bytearray fix(TeleportCommand): crash on coords fix(TeleportCommand): crash on coords fix: sunflower randomly spawning --- Minecraft.Client/PlayerConnection.cpp | 16 +-- Minecraft.Client/TeleportCommand.cpp | 150 +++++++++++++------------- Minecraft.Client/TeleportCommand.h | 3 + Minecraft.World/Biome.cpp | 4 +- Minecraft.World/DataOutputStream.cpp | 6 ++ Minecraft.World/DataOutputStream.h | 3 + 6 files changed, 96 insertions(+), 86 deletions(-) diff --git a/Minecraft.Client/PlayerConnection.cpp b/Minecraft.Client/PlayerConnection.cpp index 1c2ae73d..166e03dc 100644 --- a/Minecraft.Client/PlayerConnection.cpp +++ b/Minecraft.Client/PlayerConnection.cpp @@ -61,6 +61,7 @@ extern bool g_Win64DedicatedServer; //neo: added #include "ItemNameMap.h" +#include "../Minecraft.World/ByteArrayOutputStream.h" namespace { @@ -1131,19 +1132,10 @@ if (cmd == L"tp" || cmd == L"teleport") ? static_cast(tpTarget->xRot) : static_cast(stoi(sXRot) & 0xFF); - TeleportEntityPacket packet( - tpTarget->entityId, - static_cast(x), - static_cast(y), - static_cast(z), - yRot, - xRot - ); - DataOutputStream ds(OutputStream::createMemoryStream()); - packet.write(&ds); - shared_ptr gamePacket = make_shared(eGameCommand_Teleport, ds.getData()); + shared_ptr gamePacket = TeleportCommand::preparePacket( + tpTarget->getXuid(), x, y, z, yRot, xRot); server->getCommandDispatcher()->performCommand(tpTarget, eGameCommand_Teleport, gamePacket->data); - } + } } else if (cmd == L"time") { if (!player->hasPermission(eGameCommand_Time)) diff --git a/Minecraft.Client/TeleportCommand.cpp b/Minecraft.Client/TeleportCommand.cpp index ebe42efc..13edbe4f 100644 --- a/Minecraft.Client/TeleportCommand.cpp +++ b/Minecraft.Client/TeleportCommand.cpp @@ -19,89 +19,95 @@ EGameCommand TeleportCommand::getId() void TeleportCommand::execute(shared_ptr source, byteArray commandData) { - ByteArrayInputStream bais(commandData); - DataInputStream dis(&bais); + ByteArrayInputStream bais(commandData); + DataInputStream dis(&bais); + byte flag = dis.readByte(); + PlayerUID subjectID = dis.readPlayerUID(); + PlayerList *players = MinecraftServer::getInstance()->getPlayerList(); + shared_ptr subject = players->getPlayer(subjectID); + if (subject == nullptr || !subject->isAlive()) + return; - PlayerUID subjectID = dis.readPlayerUID(); - PlayerUID destinationID = dis.readPlayerUID(); - - bais.reset(); + if (flag == 1) + { + float x = dis.readFloat(); + float y = dis.readFloat(); + float z = dis.readFloat(); + byte yRot = dis.readByte(); + byte xRot = dis.readByte(); - PlayerList *players = MinecraftServer::getInstance()->getPlayerList(); - - shared_ptr subject = players->getPlayer(subjectID); - shared_ptr destination = players->getPlayer(destinationID); - - if(subject != nullptr && destination != nullptr && subject->level->dimension->id == destination->level->dimension->id && subject->isAlive() ) - { - subject->ride(nullptr); + subject->ride(nullptr); #if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) - { - double outX, outY, outZ; - bool cancelled = FourKitBridge::FirePlayerTeleport(subject->entityId, - subject->x, subject->y, subject->z, subject->dimension, - destination->x, destination->y, destination->z, destination->dimension, - 1 /* COMMAND */, - &outX, &outY, &outZ); - if (cancelled) - return; - subject->connection->teleport(outX, outY, outZ, destination->yRot, destination->xRot); - } + { + double outX, outY, outZ; + bool cancelled = FourKitBridge::FirePlayerTeleport(subject->entityId, + subject->x, subject->y, subject->z, subject->dimension, + x, y, z, subject->dimension, + 1, &outX, &outY, &outZ); + if (cancelled) + return; + subject->connection->teleport(outX, outY, outZ, yRot, xRot); + } #else - subject->connection->teleport(destination->x, destination->y, destination->z, destination->yRot, destination->xRot); + subject->connection->teleport(x, y, z, yRot, xRot); #endif - //logAdminAction(source, "commands.tp.success", subject->getAName(), destination->getAName()); - logAdminAction(source, ChatPacket::e_ChatCommandTeleportSuccess, subject->getName(), eTYPE_SERVERPLAYER, destination->getName()); + logAdminAction(source, ChatPacket::e_ChatCommandTeleportSuccess, subject->getName(), eTYPE_SERVERPLAYER, subject->getName()); + } + else + { + PlayerUID destinationID = dis.readPlayerUID(); + shared_ptr destination = players->getPlayer(destinationID); + if (destination == nullptr) + return; - if(subject == source) - { - destination->sendMessage(subject->getName(), ChatPacket::e_ChatCommandTeleportToMe); - } - else - { - subject->sendMessage(destination->getName(), ChatPacket::e_ChatCommandTeleportMe); - } - } + if (subject->level->dimension->id != destination->level->dimension->id) + return; - //if (args.length >= 1) { - // MinecraftServer server = MinecraftServer.getInstance(); - // ServerPlayer victim; - - // if (args.length == 2 || args.length == 4) { - // victim = server.getPlayers().getPlayer(args[0]); - // if (victim == null) throw new PlayerNotFoundException(); - // } else { - // victim = (ServerPlayer) convertSourceToPlayer(source); - // } - - // if (args.length == 3 || args.length == 4) { - // if (victim.level != null) { - // int pos = args.length - 3; - // int maxPos = Level.MAX_LEVEL_SIZE; - // int x = convertArgToInt(source, args[pos++], -maxPos, maxPos); - // int y = convertArgToInt(source, args[pos++], Level.minBuildHeight, Level.maxBuildHeight); - // int z = convertArgToInt(source, args[pos++], -maxPos, maxPos); - - // victim.teleportTo(x + 0.5f, y, z + 0.5f); - // logAdminAction(source, "commands.tp.coordinates", victim.getAName(), x, y, z); - // } - // } else if (args.length == 1 || args.length == 2) { - // ServerPlayer destination = server.getPlayers().getPlayer(args[args.length - 1]); - // if (destination == null) throw new PlayerNotFoundException(); - - // victim.connection.teleport(destination.x, destination.y, destination.z, destination.yRot, destination.xRot); - // logAdminAction(source, "commands.tp.success", victim.getAName(), destination.getAName()); - // } - //} + subject->ride(nullptr); +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) + { + double outX, outY, outZ; + bool cancelled = FourKitBridge::FirePlayerTeleport(subject->entityId, + subject->x, subject->y, subject->z, subject->dimension, + destination->x, destination->y, destination->z, destination->dimension, + 1, &outX, &outY, &outZ); + if (cancelled) + return; + subject->connection->teleport(outX, outY, outZ, destination->yRot, destination->xRot); + } +#else + subject->connection->teleport(destination->x, destination->y, destination->z, destination->yRot, destination->xRot); +#endif + logAdminAction(source, ChatPacket::e_ChatCommandTeleportSuccess, subject->getName(), eTYPE_SERVERPLAYER, destination->getName()); + if (subject == source) + destination->sendMessage(subject->getName(), ChatPacket::e_ChatCommandTeleportToMe); + else + subject->sendMessage(destination->getName(), ChatPacket::e_ChatCommandTeleportMe); + } } shared_ptr TeleportCommand::preparePacket(PlayerUID subject, PlayerUID destination) { - ByteArrayOutputStream baos; - DataOutputStream dos(&baos); + ByteArrayOutputStream baos; + DataOutputStream dos(&baos); + dos.writeByte(0); + dos.writePlayerUID(subject); + dos.writePlayerUID(destination); + return std::make_shared(eGameCommand_Teleport, baos.toByteArray()); +} - dos.writePlayerUID(subject); - dos.writePlayerUID(destination); - return std::make_shared(eGameCommand_Teleport, baos.toByteArray()); +//neo: added +shared_ptr TeleportCommand::preparePacket(PlayerUID subject, float x, float y, float z, byte yRot, byte xRot) +{ + ByteArrayOutputStream baos; + DataOutputStream dos(&baos); + dos.writeByte(1); + dos.writePlayerUID(subject); + dos.writeFloat(x); + dos.writeFloat(y); + dos.writeFloat(z); + dos.writeByte(yRot); + dos.writeByte(xRot); + return std::make_shared(eGameCommand_Teleport, baos.toByteArray()); } \ No newline at end of file diff --git a/Minecraft.Client/TeleportCommand.h b/Minecraft.Client/TeleportCommand.h index 0b37e6d1..a0fb7f1c 100644 --- a/Minecraft.Client/TeleportCommand.h +++ b/Minecraft.Client/TeleportCommand.h @@ -9,4 +9,7 @@ public: virtual void execute(shared_ptr source, byteArray commandData); static shared_ptr preparePacket(PlayerUID subject, PlayerUID destination); + + //neo: added + static shared_ptr preparePacket(PlayerUID subject, float x, float y, float z, byte yRot, byte xRot); }; \ No newline at end of file diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index ef58797a..f35769db 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -551,10 +551,10 @@ int Biome::getRandomDoublePlantType(Random *random) { int type = random->nextInt(10); - if (type < 7) return 0; + if (type < 7) return 2; if (type == 7) return 3; if (type == 8) return 4; - return 2; + return 5; } Biome* Biome::getBiome(uint32_t id) { diff --git a/Minecraft.World/DataOutputStream.cpp b/Minecraft.World/DataOutputStream.cpp index 1a3931cf..d8d4eb02 100644 --- a/Minecraft.World/DataOutputStream.cpp +++ b/Minecraft.World/DataOutputStream.cpp @@ -273,4 +273,10 @@ void DataOutputStream::writePlayerUID(PlayerUID player) #else writeLong(player); #endif // PS3 +} + +//neo: added +OutputStream* DataOutputStream::getChildOutputStream() +{ + return stream; } \ No newline at end of file diff --git a/Minecraft.World/DataOutputStream.h b/Minecraft.World/DataOutputStream.h index 7ecfcd44..545157ff 100644 --- a/Minecraft.World/DataOutputStream.h +++ b/Minecraft.World/DataOutputStream.h @@ -35,4 +35,7 @@ public: virtual void writeUTF(const wstring& a); virtual void writePlayerUID(PlayerUID player); virtual void flush(); + + //neo: added for future use cases, dont ask. + virtual OutputStream* getChildOutputStream(); }; \ No newline at end of file