Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
21 kB · 569 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570#include "stdafx.h"#include "System.h"#include "BasicTypeContainers.h"#include "InputOutputStream.h"#include "net.minecraft.network.packet.h"#include "PacketListener.h"#include "Packet.h"#include "com.mojang.nbt.h"
#ifndef _CONTENT_PACKAGE#include "..\Minecraft.Client\Minecraft.h"#include "..\Minecraft.Client\Gui.h"#endif
void Packet::staticCtor(){ //nextPrint = 0;
// 4J - Note that item IDs are now defined in virtual method for each packet type
// 4J Stu - The values for canSendToAnyClient may not necessarily be the correct choices map(0, true, true, true, false, typeid(KeepAlivePacket), KeepAlivePacket::create); map(1, true, true, true, false, typeid(LoginPacket), LoginPacket::create); map(2, true, true, true, false, typeid(PreLoginPacket), PreLoginPacket::create); map(3, true, true, true, false, typeid(ChatPacket), ChatPacket::create); map(4, true, false, false, true, typeid(SetTimePacket), SetTimePacket::create); map(5, true, false, false, true, typeid(SetEquippedItemPacket), SetEquippedItemPacket::create); map(6, true, false, true, true, typeid(SetSpawnPositionPacket), SetSpawnPositionPacket::create); map(7, false, true, false, false, typeid(InteractPacket), InteractPacket::create); map(8, true, false, true, true, typeid(SetHealthPacket), SetHealthPacket::create); map(9, true, true, true, false, typeid(RespawnPacket), RespawnPacket::create);
map(10, true, true, true, false, typeid(MovePlayerPacket), MovePlayerPacket::create); map(11, true, true, true, true, typeid(MovePlayerPacket::Pos), MovePlayerPacket::Pos::create); map(12, true, true, true, true, typeid(MovePlayerPacket::Rot), MovePlayerPacket::Rot::create); map(13, true, true, true, true, typeid(MovePlayerPacket::PosRot), MovePlayerPacket::PosRot::create);
map(14, false, true, false, false, typeid(PlayerActionPacket), PlayerActionPacket::create); map(15, false, true, false, false, typeid(UseItemPacket), UseItemPacket::create); map(16, true, true, true, false, typeid(SetCarriedItemPacket), SetCarriedItemPacket::create); // 4J-PB - we need to send to any client for the sleep in bed //map(17, true, false, false, false, EntityActionAtPositionPacket)); map(17, true, false, true, false, typeid(EntityActionAtPositionPacket), EntityActionAtPositionPacket::create); // 4J-PB - we need to send to any client for the wake up from sleeping //map(18, true, true, false, false, AnimatePacket)); map(18, true, true, true, false, typeid(AnimatePacket), AnimatePacket::create); map(19, false, true, false, false, typeid(PlayerCommandPacket), PlayerCommandPacket::create);
map(20, true, false, false, true, typeid(AddPlayerPacket), AddPlayerPacket::create); map(22, true, false, true, true, typeid(TakeItemEntityPacket), TakeItemEntityPacket::create); map(23, true, false, false, true, typeid(AddEntityPacket), AddEntityPacket::create); map(24, true, false, false, true, typeid(AddMobPacket), AddMobPacket::create); map(25, true, false, false, false, typeid(AddPaintingPacket), AddPaintingPacket::create); map(26, true, false, false, false, typeid(AddExperienceOrbPacket), AddExperienceOrbPacket::create); // TODO New for 1.8.2 - Needs sendToAny? map(27, false, true, false, false, typeid(PlayerInputPacket), PlayerInputPacket::create); // 4J-PB - needs to go to any player, due to the knockback effect when a played is hit map(28, true, false, true, true, typeid(SetEntityMotionPacket), SetEntityMotionPacket::create); map(29, true, false, false, true, typeid(RemoveEntitiesPacket), RemoveEntitiesPacket::create);
map(30, true, false, false, false, typeid(MoveEntityPacket), MoveEntityPacket::create); map(31, true, false, false, true, typeid(MoveEntityPacket::Pos), MoveEntityPacket::Pos::create); map(32, true, false, false, true, typeid(MoveEntityPacket::Rot), MoveEntityPacket::Rot::create); map(33, true, false, false, true, typeid(MoveEntityPacket::PosRot), MoveEntityPacket::PosRot::create); map(34, true, false, false, true, typeid(TeleportEntityPacket), TeleportEntityPacket::create); map(35, true, false, false, false, typeid(RotateHeadPacket), RotateHeadPacket::create);
// 4J - needs to go to any player, to create sound effect when a player is hit map(38, true, false, true, true, typeid(EntityEventPacket), EntityEventPacket::create); map(39, true, false, true, false, typeid(SetEntityLinkPacket), SetEntityLinkPacket::create); map(40, true, false, true, true, typeid(SetEntityDataPacket), SetEntityDataPacket::create); map(41, true, false, true, false, typeid(UpdateMobEffectPacket), UpdateMobEffectPacket::create); map(42, true, false, true, false, typeid(RemoveMobEffectPacket), RemoveMobEffectPacket::create); map(43, true, false, true, false, typeid(SetExperiencePacket), SetExperiencePacket::create); map(44, true, false, true, false, typeid(UpdateAttributesPacket), UpdateAttributesPacket::create);
map(50, true, false, true, true, typeid(ChunkVisibilityPacket), ChunkVisibilityPacket::create); map(51, true, false, true, true, typeid(BlockRegionUpdatePacket), BlockRegionUpdatePacket::create); // Changed to LevelChunkPacket in Java but we aren't using that map(52, true, false, true, true, typeid(ChunkTilesUpdatePacket), ChunkTilesUpdatePacket::create); map(53, true, false, true, true, typeid(TileUpdatePacket), TileUpdatePacket::create); map(54, true, false, true, true, typeid(TileEventPacket), TileEventPacket::create); map(55, true, false, false, false, typeid(TileDestructionPacket), TileDestructionPacket::create);
map(60, true, false, true, false, typeid(ExplodePacket), ExplodePacket::create); map(61, true, false, true, false, typeid(LevelEventPacket), LevelEventPacket::create); // 4J-PB - don't see the need for this, we can use 61 map(62, true, false, true, false, typeid(LevelSoundPacket), LevelSoundPacket::create); map(63, true, false, true, false, typeid(LevelParticlesPacket), LevelParticlesPacket::create);
map(70, true, false, false, false, typeid(GameEventPacket), GameEventPacket::create); map(71, true, false, false, false, typeid(AddGlobalEntityPacket), AddGlobalEntityPacket::create);
map(100, true, false, true, false, typeid(ContainerOpenPacket), ContainerOpenPacket::create); map(101, true, true, true, false, typeid(ContainerClosePacket), ContainerClosePacket::create); map(102, false, true, false, false, typeid(ContainerClickPacket), ContainerClickPacket::create);#ifndef _CONTENT_PACKAGE // 4J Stu - We have some debug code that uses this packet to send data back to the server from the client // We may wish to add this into the real game at some point map(103, true, true, true, false, typeid(ContainerSetSlotPacket), ContainerSetSlotPacket::create);#else map(103, true, false, true, false, typeid(ContainerSetSlotPacket), ContainerSetSlotPacket::create);#endif map(104, true, false, true, false, typeid(ContainerSetContentPacket), ContainerSetContentPacket::create); map(105, true, false, true, false, typeid(ContainerSetDataPacket), ContainerSetDataPacket::create); map(106, true, true, true, false, typeid(ContainerAckPacket), ContainerAckPacket::create); map(107, true, true, true, false, typeid(SetCreativeModeSlotPacket), SetCreativeModeSlotPacket::create); map(108, false, true, false, false, typeid(ContainerButtonClickPacket), ContainerButtonClickPacket::create);
map(130, true, true, true, false, typeid(SignUpdatePacket), SignUpdatePacket::create); map(131, true, false, true, false, typeid(ComplexItemDataPacket), ComplexItemDataPacket::create); map(132, true, false, false, false, typeid(TileEntityDataPacket), TileEntityDataPacket::create); map(133, true, false, true, false, typeid(TileEditorOpenPacket), TileEditorOpenPacket::create);
// 4J Added map(150, false, true, false, false, typeid(CraftItemPacket), CraftItemPacket::create); map(151, false, true, true, false, typeid(TradeItemPacket), TradeItemPacket::create); map(152, false, true, false, false, typeid(DebugOptionsPacket), DebugOptionsPacket::create); map(153, true, true, false, false, typeid(ServerSettingsChangedPacket), ServerSettingsChangedPacket::create); map(154, true, true, true, false, typeid(TexturePacket), TexturePacket::create); map(155, true, false, true, true, typeid(ChunkVisibilityAreaPacket), ChunkVisibilityAreaPacket::create); map(156, true, false, false, true, typeid(UpdateProgressPacket), UpdateProgressPacket::create); map(157, true, true, true, false, typeid(TextureChangePacket), TextureChangePacket::create); map(158, true, false, true, false, typeid(UpdateGameRuleProgressPacket), UpdateGameRuleProgressPacket::create); map(159, false, true, false, false, typeid(KickPlayerPacket), KickPlayerPacket::create); map(160, true, true, true, false, typeid(TextureAndGeometryPacket), TextureAndGeometryPacket::create); map(161, true, true, true, false, typeid(TextureAndGeometryChangePacket), TextureAndGeometryChangePacket::create);
map(162, true, false, false, false, typeid(MoveEntityPacketSmall), MoveEntityPacketSmall::create); map(163, true, false, false, true, typeid(MoveEntityPacketSmall::Pos), MoveEntityPacketSmall::Pos::create); map(164, true, false, false, true, typeid( MoveEntityPacketSmall::Rot), MoveEntityPacketSmall::Rot::create); map(165, true, false, false, true, typeid(MoveEntityPacketSmall::PosRot), MoveEntityPacketSmall::PosRot::create); map(166, true, true, false, false, typeid(XZPacket), XZPacket::create); map(167, false, true, false, false, typeid(GameCommandPacket), GameCommandPacket::create);
map(200, true, false, true, false, typeid(AwardStatPacket), AwardStatPacket::create); map(201, true, true, false, false, typeid(PlayerInfoPacket), PlayerInfoPacket::create); // TODO New for 1.8.2 - Repurposed by 4J map(202, true, true, true, false, typeid(PlayerAbilitiesPacket), PlayerAbilitiesPacket::create); // 4J Stu - These added 1.3.2, but don't think we need them //map(203, true, true, true, false, ChatAutoCompletePacket.class); //map(204, false, true, true, false, ClientInformationPacket.class); map(205, false, true, true, false, typeid(ClientCommandPacket), ClientCommandPacket::create);
map(206, true, false, true, false, typeid(SetObjectivePacket), SetObjectivePacket::create); map(207, true, false, true, false, typeid(SetScorePacket), SetScorePacket::create); map(208, true, false, true, false, typeid(SetDisplayObjectivePacket), SetDisplayObjectivePacket::create); map(209, true, false, true, false, typeid(SetPlayerTeamPacket), SetPlayerTeamPacket::create);
map(250, true, true, true, false, typeid(CustomPayloadPacket), CustomPayloadPacket::create); // 4J Stu - These added 1.3.2, but don't think we need them //map(252, true, true, SharedKeyPacket.class); //map(253, true, false, ServerAuthDataPacket.class); map(254, false, true, false, false, typeid(GetInfoPacket), GetInfoPacket::create); // TODO New for 1.8.2 - Needs sendToAny? map(255, true, true, true, false, typeid(DisconnectPacket), DisconnectPacket::create);}
IllegalArgumentException::IllegalArgumentException(const wstring& information){ this->information = information;}
IOException::IOException(const wstring& information){ this->information = information;}
Packet::Packet() : createTime( System::currentTimeMillis() ){ shouldDelay = false;}
unordered_map<int, packetCreateFn> Packet::idToCreateMap;
unordered_set<int> Packet::clientReceivedPackets;unordered_set<int> Packet::serverReceivedPackets;unordered_set<int> Packet::sendToAnyClientPackets;
// 4J Addedunordered_map<int, Packet::PacketStatistics *> Packet::outgoingStatistics = unordered_map<int, Packet::PacketStatistics *>();vector<Packet::PacketStatistics *> Packet::renderableStats = vector<Packet::PacketStatistics *>();int Packet::renderPos = 0;
// sendToAnyClient - true - send to anyone, false - Sends to one person per dimension per machinevoid Packet::map(int id, bool receiveOnClient, bool receiveOnServer, bool sendToAnyClient, bool renderStats, const type_info& clazz, packetCreateFn createFn){#if 0 if (idToClassMap.count(id) > 0) throw new IllegalArgumentException(wstring(L"Duplicate packet id:") + _toString<int>(id)); if (classToIdMap.count(clazz) > 0) throw new IllegalArgumentException(L"Duplicate packet class:"); // TODO + clazz);#endif
idToCreateMap.insert( unordered_map<int, packetCreateFn>::value_type(id, createFn) );
#ifndef _CONTENT_PACKAGE#if PACKET_ENABLE_STAT_TRACKING Packet::PacketStatistics *packetStatistics = new PacketStatistics(id); outgoingStatistics[id] = packetStatistics;
if(renderStats) { renderableStats.push_back( packetStatistics ); }#endif#endif
if (receiveOnClient) { clientReceivedPackets.insert(id); } if (receiveOnServer) { serverReceivedPackets.insert(id); } if(sendToAnyClient) { sendToAnyClientPackets.insert(id); }}
// 4J Added to record data for outgoing packetsvoid Packet::recordOutgoingPacket(shared_ptr<Packet> packet, int playerIndex){#ifndef _CONTENT_PACKAGE#if PACKET_ENABLE_STAT_TRACKING#if 0 int idx = packet->getId();#else int idx = playerIndex; if( packet->getId() != 51 ) { idx = 100; }#endif AUTO_VAR(it, outgoingStatistics.find(idx));
if( it == outgoingStatistics.end() ) { Packet::PacketStatistics *packetStatistics = new PacketStatistics(idx); outgoingStatistics[idx] = packetStatistics; packetStatistics->addPacket(packet->getEstimatedSize()); } else { it->second->addPacket(packet->getEstimatedSize()); }#endif#endif}
void Packet::updatePacketStatsPIX(){#ifndef _CONTENT_PACKAGE#if PACKET_ENABLE_STAT_TRACKING for( AUTO_VAR(it, outgoingStatistics.begin()); it != outgoingStatistics.end(); it++ ) { Packet::PacketStatistics *stat = it->second; __int64 count = stat->getRunningCount(); wchar_t pixName[256]; swprintf_s(pixName,L"Packet count %d",stat->id);// PIXReportCounter(pixName,(float)count); __int64 total = stat->getRunningTotal(); swprintf_s(pixName,L"Packet bytes %d",stat->id); PIXReportCounter(pixName,(float)total); stat->IncrementPos(); }#endif#endif}
shared_ptr<Packet> Packet::getPacket(int id) { // 4J: Removed try/catch return idToCreateMap[id]();}
void Packet::writeBytes(DataOutputStream *dataoutputstream, byteArray bytes){ dataoutputstream->writeShort(bytes.length); dataoutputstream->write(bytes);}
byteArray Packet::readBytes(DataInputStream *datainputstream){ int size = datainputstream->readShort(); if (size < 0) { app.DebugPrintf("Key was smaller than nothing! Weird key!");#ifndef _CONTENT_PACKAGE __debugbreak();#endif return byteArray(); //throw new IOException("Key was smaller than nothing! Weird key!"); }
byteArray bytes(size); datainputstream->readFully(bytes);
return bytes;}
bool Packet::canSendToAnyClient(shared_ptr<Packet> packet){ int packetId = packet->getId();
return sendToAnyClientPackets.count(packetId) != 0;}
// 4J - now a pure virtual method/*int Packet::getId(){return id;}*/
unordered_map<int, Packet::PacketStatistics *> Packet::statistics = unordered_map<int, Packet::PacketStatistics *>();
//int Packet::nextPrint = 0;
shared_ptr<Packet> Packet::readPacket(DataInputStream *dis, bool isServer) // throws IOException TODO 4J JEV, should this declare a throws?{ int id = 0; shared_ptr<Packet> packet = nullptr;
// 4J - removed try/catch // try // { id = dis->read(); if (id == -1) return nullptr;
if ((isServer && serverReceivedPackets.find(id) == serverReceivedPackets.end()) || (!isServer && clientReceivedPackets.find(id) == clientReceivedPackets.end())) { //app.DebugPrintf("Bad packet id %d\n", id); __debugbreak(); assert(false); // throw new IOException(wstring(L"Bad packet id ") + _toString<int>(id)); }
packet = getPacket(id); if (packet == NULL) assert(false);//throw new IOException(wstring(L"Bad packet id ") + _toString<int>(id)); //app.DebugPrintf("%s reading packet %d\n", isServer ? "Server" : "Client", packet->getId()); packet->read(dis); // } // catch (EOFException e) // { // // reached end of stream // OutputDebugString("Reached end of stream"); // return NULL; // }
// 4J - Don't bother tracking stats in a content package // 4J Stu - This changes a bit in 1.0.1, but we don't really use it so stick with what we have#ifndef _CONTENT_PACKAGE#if PACKET_ENABLE_STAT_TRACKING AUTO_VAR(it, statistics.find(id));
if( it == statistics.end() ) { Packet::PacketStatistics *packetStatistics = new PacketStatistics(id); statistics[id] = packetStatistics; packetStatistics->addPacket(packet->getEstimatedSize()); } else { it->second->addPacket(packet->getEstimatedSize()); }#endif#endif
return packet;}
void Packet::writePacket(shared_ptr<Packet> packet, DataOutputStream *dos) // throws IOException TODO 4J JEV, should this declare a throws?{ //app.DebugPrintf("Writing packet %d\n", packet->getId()); dos->write(packet->getId()); packet->write(dos);}
void Packet::writeUtf(const wstring& value, DataOutputStream *dos) // throws IOException TODO 4J JEV, should this declare a throws?{#if 0 if (value.length() > Short::MAX_VALUE) { throw new IOException(L"String too big"); }#endif
dos->writeShort((short)value.length()); dos->writeChars(value);}
wstring Packet::readUtf(DataInputStream *dis, int maxLength) // throws IOException TODO 4J JEV, should this declare a throws?{
short stringLength = dis->readShort(); if (stringLength > maxLength) { wstringstream stream; stream << L"Received string length longer than maximum allowed (" << stringLength << " > " << maxLength << ")"; assert(false); // throw new IOException( stream.str() ); } if (stringLength < 0) { assert(false); // throw new IOException(L"Received string length is less than zero! Weird string!"); }
wstring builder = L""; for (int i = 0; i < stringLength; i++) { wchar_t rc = dis->readChar(); builder.push_back( rc ); }
return builder;}
Packet::PacketStatistics::PacketStatistics(int id) : id( id ), count( 0 ), totalSize( 0 ), samplesPos( 0 ){ memset(countSamples, 0, sizeof(countSamples)); memset(sizeSamples, 0, sizeof(sizeSamples));}
void Packet::PacketStatistics::addPacket(int bytes){ countSamples[samplesPos]++; sizeSamples[samplesPos] += bytes; timeSamples[samplesPos] = System::currentTimeMillis(); totalSize += bytes; count++;}
int Packet::PacketStatistics::getCount() { return count;}
double Packet::PacketStatistics::getAverageSize(){ if (count == 0) { return 0; } return (double) totalSize / count;}
int Packet::PacketStatistics::getTotalSize() { return totalSize;}
__int64 Packet::PacketStatistics::getRunningTotal(){ __int64 total = 0; __int64 currentTime = System::currentTimeMillis(); for( int i = 0; i < TOTAL_TICKS; i++ ) { if( currentTime - timeSamples[i] <= 1000 ) { total += sizeSamples[i]; } } return total;}
__int64 Packet::PacketStatistics::getRunningCount(){ __int64 total = 0; __int64 currentTime = System::currentTimeMillis(); for( int i = 0; i < TOTAL_TICKS; i++ ) { if( currentTime - timeSamples[i] <= 1000 ) { total += countSamples[i]; } } return total;}
void Packet::PacketStatistics::IncrementPos(){ samplesPos = ( samplesPos + 1 ) % TOTAL_TICKS; countSamples[samplesPos] = 0; sizeSamples[samplesPos] = 0; timeSamples[samplesPos] = 0;}
bool Packet::canBeInvalidated(){ return false;}
bool Packet::isInvalidatedBy(shared_ptr<Packet> packet){ return false;}
bool Packet::isAync(){ return false;}
// 4J Stu - Brought these functions forward for enchanting/game rulesshared_ptr<ItemInstance> Packet::readItem(DataInputStream *dis){ shared_ptr<ItemInstance> item = nullptr; int id = dis->readShort(); if (id >= 0) { int count = dis->readByte(); int damage = dis->readShort();
item = shared_ptr<ItemInstance>( new ItemInstance(id, count, damage) ); // 4J Stu - Always read/write the tag //if (Item.items[id].canBeDepleted() || Item.items[id].shouldOverrideMultiplayerNBT()) { item->tag = readNbt(dis); } }
return item;}
void Packet::writeItem(shared_ptr<ItemInstance> item, DataOutputStream *dos){ if (item == NULL) { dos->writeShort(-1); } else { dos->writeShort(item->id); dos->writeByte(item->count); dos->writeShort(item->getAuxValue()); // 4J Stu - Always read/write the tag //if (item.getItem().canBeDepleted() || item.getItem().shouldOverrideMultiplayerNBT()) { writeNbt(item->tag, dos); } }}
CompoundTag *Packet::readNbt(DataInputStream *dis){ int size = dis->readShort(); if (size < 0) return NULL; byteArray buff(size); dis->readFully(buff); CompoundTag *result = (CompoundTag *) NbtIo::decompress(buff); delete [] buff.data; return result;}
void Packet::writeNbt(CompoundTag *tag, DataOutputStream *dos){ if (tag == NULL) { dos->writeShort(-1); } else { byteArray buff = NbtIo::compress(tag); dos->writeShort((short) buff.length); dos->write(buff); delete [] buff.data; }}