From 2691e8daed826e944ca38f4787c77273edbf9404 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sat, 18 Aug 2012 09:56:28 +0000 Subject: Packet refactoring, phase two, partial. Rewritten a few packet handling functions not to use cPacket-descendant objects. This breaks plugin API! Plugins need to modify their hook functions to match those used in the Core plugin git-svn-id: http://mc-server.googlecode.com/svn/trunk@750 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cClientHandle.cpp | 311 +++++++++++++++++++++++++++++------------------ 1 file changed, 196 insertions(+), 115 deletions(-) (limited to 'source/cClientHandle.cpp') diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index c045a4ed7..07cf1c62f 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -66,6 +66,7 @@ #include "packets/cPacket_NamedEntitySpawn.h" #include "packets/cPacket_MapChunk.h" #include "packets/cPacket_PreChunk.h" +#include "packets/cPacket_InventorySlot.h" // DEBUG: #include "packets/cPacket_BlockChange.h" @@ -492,6 +493,11 @@ void cClientHandle::RemoveFromAllChunks() void cClientHandle::HandlePacket(cPacket * a_Packet) { + // TODO: _X: This function will get out-sourced into a separate cProtocol class + // and the switch statements will be split into virtual functions of that class + // Therefore I keep this function huge and untidy for the time being + // ( http://forum.mc-server.org/showthread.php?tid=524 ) + m_TimeLastPacket = cWorld::GetTime(); // LOG("Recv packet 0x%02x from client \"%s\" (\"%s\")", a_Packet->m_PacketID, m_Socket.GetIPString().c_str(), m_Username.c_str()); @@ -513,8 +519,18 @@ void cClientHandle::HandlePacket(cPacket * a_Packet) break; } case E_PING: HandlePing (); break; - case E_HANDSHAKE: HandleHandshake(reinterpret_cast(a_Packet)); break; - case E_LOGIN: HandleLogin (reinterpret_cast (a_Packet)); break; + case E_HANDSHAKE: + { + cPacket_Handshake * Handshake = reinterpret_cast(a_Packet); + HandleHandshake(Handshake->m_Username); + break; + } + case E_LOGIN: + { + cPacket_Login * Login = reinterpret_cast(a_Packet); + HandleLogin(Login->m_ProtocolVersion, Login->m_Username); + break; + } // Ignored packets: case E_PLAYERLOOK: @@ -522,7 +538,7 @@ void cClientHandle::HandlePacket(cPacket * a_Packet) case E_PLAYERMOVELOOK: case E_PLAYERPOS: case E_KEEP_ALIVE: break; - default: HandleUnexpectedPacket(a_Packet); break; + default: HandleUnexpectedPacket(a_Packet->m_PacketID); break; } // switch (PacketType) break; } // case csConnected @@ -540,7 +556,7 @@ void cClientHandle::HandlePacket(cPacket * a_Packet) case E_PLAYERMOVELOOK: case E_PLAYERPOS: break; - default: HandleUnexpectedPacket(a_Packet); break; + default: HandleUnexpectedPacket(a_Packet->m_PacketID); break; } break; } @@ -558,7 +574,7 @@ void cClientHandle::HandlePacket(cPacket * a_Packet) case E_PLAYERMOVELOOK: case E_PLAYERPOS: break; - default: HandleUnexpectedPacket(a_Packet); break; + default: HandleUnexpectedPacket(a_Packet->m_PacketID); break; } break; } @@ -574,11 +590,16 @@ void cClientHandle::HandlePacket(cPacket * a_Packet) case E_PLAYERLOOK: case E_PLAYERPOS: break; - case E_PLAYERMOVELOOK: HandleMoveLookConfirm(reinterpret_cast(a_Packet)); break; + case E_PLAYERMOVELOOK: + { + cPacket_PlayerMoveLook * MoveLook = reinterpret_cast(a_Packet); + HandleMoveLookConfirm(MoveLook->m_PosX, MoveLook->m_PosY, MoveLook->m_PosZ); + break; + } default: { - HandleUnexpectedPacket(a_Packet); + HandleUnexpectedPacket(a_Packet->m_PacketID); break; } } // switch (PacketType) @@ -589,10 +610,30 @@ void cClientHandle::HandlePacket(cPacket * a_Packet) { switch (a_Packet->m_PacketID) { - case E_CREATIVE_INVENTORY_ACTION: HandleCreativeInventory(reinterpret_cast(a_Packet)); break; - case E_PLAYERPOS: HandlePlayerPos (reinterpret_cast (a_Packet)); break; - case E_BLOCK_DIG: HandleBlockDig (reinterpret_cast (a_Packet)); break; - case E_BLOCK_PLACE: HandleBlockPlace (reinterpret_cast (a_Packet)); break; + case E_CREATIVE_INVENTORY_ACTION: + { + cPacket_CreativeInventoryAction * cia = reinterpret_cast(a_Packet); + HandleCreativeInventory(cia->m_SlotNum, cia->m_ClickedItem); + break; + } + case E_PLAYERPOS: + { + cPacket_PlayerPosition * pp = reinterpret_cast(a_Packet); + HandlePlayerPos(pp->m_PosX, pp->m_PosY, pp->m_PosZ, pp->m_Stance, pp->m_IsOnGround); + break; + } + case E_BLOCK_DIG: + { + cPacket_BlockDig * bd = reinterpret_cast(a_Packet); + HandleBlockDig(bd->m_PosX, bd->m_PosY, bd->m_PosZ, bd->m_Direction, bd->m_Status); + break; + } + case E_BLOCK_PLACE: + { + cPacket_BlockPlace * bp = reinterpret_cast(a_Packet); + HandleBlockPlace(bp->m_PosX, bp->m_PosY, bp->m_PosZ, bp->m_Direction, bp->m_HeldItem); + break; + } case E_PICKUP_SPAWN: HandlePickupSpawn (reinterpret_cast (a_Packet)); break; case E_CHAT: HandleChat (reinterpret_cast (a_Packet)); break; case E_PLAYERLOOK: HandlePlayerLook (reinterpret_cast (a_Packet)); break; @@ -600,7 +641,12 @@ void cClientHandle::HandlePacket(cPacket * a_Packet) case E_ANIMATION: HandleAnimation (reinterpret_cast (a_Packet)); break; case E_ITEM_SWITCH: HandleItemSwitch (reinterpret_cast (a_Packet)); break; case E_WINDOW_CLOSE: HandleWindowClose (reinterpret_cast (a_Packet)); break; - case E_WINDOW_CLICK: HandleWindowClick (reinterpret_cast (a_Packet)); break; + case E_WINDOW_CLICK: + { + cPacket_WindowClick * wc = reinterpret_cast(a_Packet); + HandleWindowClick(wc->m_WindowID, wc->m_SlotNum, wc->m_IsRightClick, wc->m_IsShiftPressed, wc->m_HeldItem); + break; + } case E_UPDATE_SIGN: HandleUpdateSign (reinterpret_cast (a_Packet)); break; case E_USE_ENTITY: HandleUseEntity (reinterpret_cast (a_Packet)); break; case E_RESPAWN: HandleRespawn(); break; @@ -634,17 +680,17 @@ void cClientHandle::HandlePing(void) -void cClientHandle::HandleHandshake(cPacket_Handshake * a_Packet) +void cClientHandle::HandleHandshake(const AString & a_Username) { - AStringVector UserData = StringSplit( a_Packet->m_Username, ";" ); // "FakeTruth;localhost:25565" - if( UserData.size() == 0 ) + AStringVector UserData = StringSplit(a_Username, ";"); // "FakeTruth;localhost:25565" + if (UserData.empty()) { - Kick("Could not receive username"); + Kick("Did not receive username"); return; } m_Username = UserData[0]; - LOG("HANDSHAKE %s", m_Username.c_str()); + LOGD("HANDSHAKE %s", m_Username.c_str()); if (cRoot::Get()->GetDefaultWorld()->GetNumPlayers() >= cRoot::Get()->GetDefaultWorld()->GetMaxPlayers()) { @@ -654,9 +700,7 @@ void cClientHandle::HandleHandshake(cPacket_Handshake * a_Packet) cPacket_Chat Connecting(m_Username + " is connecting."); cRoot::Get()->GetServer()->Broadcast(Connecting, this); - cPacket_Handshake Handshake; - Handshake.m_Username = cRoot::Get()->GetServer()->GetServerID(); - Send(Handshake); + SendHandshake(cRoot::Get()->GetServer()->GetServerID()); LOG("User \"%s\" was sent a handshake", m_Username.c_str()); } @@ -664,23 +708,23 @@ void cClientHandle::HandleHandshake(cPacket_Handshake * a_Packet) -void cClientHandle::HandleLogin(cPacket_Login * a_Packet) +void cClientHandle::HandleLogin(int a_ProtocolVersion, const AString & a_Username) { - LOG("LOGIN %s", m_Username.c_str()); - if (a_Packet->m_ProtocolVersion < m_ProtocolVersion) + LOGD("LOGIN %s", a_Username.c_str()); + if (a_ProtocolVersion < m_ProtocolVersion) { Kick("Your client is outdated!"); return; } - else if (a_Packet->m_ProtocolVersion > m_ProtocolVersion) + else if (a_ProtocolVersion > m_ProtocolVersion) { Kick("Your client version is higher than the server!"); return; } - if (m_Username.compare(a_Packet->m_Username) != 0) + if (m_Username.compare(a_Username) != 0) { - LOGWARNING("Login Username (\"%s\") does not match Handshake username (\"%s\") for client \"%s\")", - a_Packet->m_Username.c_str(), + LOGWARNING("Login Username (\"%s\") does not match Handshake username (\"%s\") for client @ \"%s\")", + a_Username.c_str(), m_Username.c_str(), m_Socket.GetIPString().c_str() ); @@ -688,7 +732,7 @@ void cClientHandle::HandleLogin(cPacket_Login * a_Packet) return; } - if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_LOGIN, 1, a_Packet)) + if (cRoot::Get()->GetPluginManager()->CallHookLogin(this, a_ProtocolVersion, a_Username)) { Destroy(); return; @@ -703,12 +747,12 @@ void cClientHandle::HandleLogin(cPacket_Login * a_Packet) -void cClientHandle::HandleUnexpectedPacket(cPacket * a_Packet) +void cClientHandle::HandleUnexpectedPacket(int a_PacketType) { LOGWARNING( "Invalid packet in state %d: 0x%02x from client \"%s\", username \"%s\"", m_State, - a_Packet->m_PacketID, + a_PacketType, m_Socket.GetIPString().c_str(), m_Username.c_str() ); @@ -719,9 +763,9 @@ void cClientHandle::HandleUnexpectedPacket(cPacket * a_Packet) -void cClientHandle::HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet) +void cClientHandle::HandleMoveLookConfirm(double a_PosX, double a_PosY, double a_PosZ) { - Vector3d ReceivedPosition = Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + Vector3d ReceivedPosition = Vector3d(a_PosX, a_PosY, a_PosZ); // Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength(); @@ -746,12 +790,12 @@ void cClientHandle::HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet) -void cClientHandle::HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet) +void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem) { // This is for creative Inventory changes if (m_Player->GetGameMode() == 1) { - m_Player->GetInventory().Clicked(a_Packet); + m_Player->GetInventory().Clicked(a_SlotNum, false, false, a_HeldItem); } else { @@ -763,84 +807,86 @@ void cClientHandle::HandleCreativeInventory(cPacket_CreativeInventoryAction * a_ -void cClientHandle::HandlePlayerPos(cPacket_PlayerPosition * a_Packet) +void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround) { // LOG("recv player pos: %0.2f %0.2f %0.2f", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ); - m_Player->MoveTo(Vector3d(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)); - m_Player->SetStance(a_Packet->m_Stance); - m_Player->SetTouchGround(a_Packet->m_bFlying); + m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ)); + m_Player->SetStance(a_Stance); + m_Player->SetTouchGround(a_IsOnGround); } -void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet) +void cClientHandle::HandleBlockDig(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) { if (!CheckBlockInteractionsRate()) { return; } - LOGD("OnBlockDig: {%i, %i, %i} Dir: %i Stat: %i", - a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, - a_Packet->m_Direction, a_Packet->m_Status + LOGD("OnBlockDig: {%i, %i, %i}; Face: %i; Stat: %i", + a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status ); // Do we want plugins to disable tossing items? Probably no, so toss item before asking plugins for permission - if (a_Packet->m_Status == 0x04) // Drop held item + if (a_Status == DIG_STATUS_DROP_HELD) // Drop held item { m_Player->TossItem(false); return; } - if (a_Packet->m_Status == 0x05) + if (a_Status == DIG_STATUS_SHOOT_EAT) { - LOGINFO("BlockDig: Status 5 not implemented"); + LOGINFO("BlockDig: Status SHOOT/EAT not implemented"); + return; } - cWorld* World = m_Player->GetWorld(); - BLOCKTYPE OldBlock = World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - NIBBLETYPE OldMeta = World->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + cWorld * World = m_Player->GetWorld(); + BLOCKTYPE OldBlock; + NIBBLETYPE OldMeta; + World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, OldBlock, OldMeta); - if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_BLOCK_DIG, 4, a_Packet, m_Player, OldBlock, OldMeta)) + if (cRoot::Get()->GetPluginManager()->CallHookBlockDig(m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status, OldBlock, OldMeta)) { // The plugin doesn't agree with the digging, replace the block on the client and quit: - World->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); + World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); return; } bool bBroken = ( - (a_Packet->m_Status == 0x02) || + (a_Status == DIG_STATUS_FINISHED) || (g_BlockOneHitDig[(int)OldBlock]) || - ((a_Packet->m_Status == 0x00) && (m_Player->GetGameMode() == 1)) + ((a_Status == DIG_STATUS_STARTED) && (m_Player->GetGameMode() == 1)) ); - cItem &Equipped = m_Player->GetInventory().GetEquippedItem(); - - cItemHandler *ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID); + cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); + cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID); - if(bBroken) + if (bBroken) { - ItemHandler->OnBlockDestroyed(World, m_Player, &Equipped, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + ItemHandler->OnBlockDestroyed(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ); - BlockHandler(OldBlock)->OnDestroyedByPlayer(World, m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - World->DigBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - }else{ - cBlockHandler *Handler = cBlockHandler::GetBlockHandler(OldBlock); - Handler->OnClick(World, m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + BlockHandler(OldBlock)->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ); + World->DigBlock(a_BlockX, a_BlockY, a_BlockZ); + } + else + { + cBlockHandler * Handler = cBlockHandler::GetBlockHandler(OldBlock); + Handler->OnClick(World, m_Player, a_BlockX, a_BlockY, a_BlockZ); - ItemHandler->OnDiggingBlock(World, m_Player, &Equipped, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction); + ItemHandler->OnDiggingBlock(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - //Check for clickthrough-blocks: - int pX = a_Packet->m_PosX; - unsigned char pY = a_Packet->m_PosY; - int pZ = a_Packet->m_PosZ; - AddDirection(pX, pY, pZ, a_Packet->m_Direction); + // Check for clickthrough-blocks: + int pX = a_BlockX; + unsigned char pY = a_BlockY; + int pZ = a_BlockZ; + AddDirection(pX, pY, pZ, a_BlockFace); Handler = cBlockHandler::GetBlockHandler(World->GetBlock(pX, pY, pZ)); - if(Handler->IsClickedThrough()) + if (Handler->IsClickedThrough()) { Handler->OnClick(World, m_Player, pX, pY, pZ); } @@ -851,9 +897,8 @@ void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet) -void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet) +void cClientHandle::HandleBlockPlace(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem) { - if (!CheckBlockInteractionsRate()) { return; @@ -861,94 +906,105 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet) cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); - if ((Equipped.m_ItemID != a_Packet->m_ItemType)) // Not valid + if ((Equipped.m_ItemID != a_HeldItem.m_ItemType)) // Not valid { LOGWARN("Player %s tried to place a block that was not equipped (exp %d, got %d)", - m_Username.c_str(), Equipped.m_ItemID, a_Packet->m_ItemType + m_Username.c_str(), Equipped.m_ItemType, a_HeldItem.m_ItemType ); - // TODO: We should probably send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block + + // Let's send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block + if (a_BlockFace > -1) + { + AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + } return; } - if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_BLOCK_PLACE, 2, a_Packet, m_Player)) + if (cRoot::Get()->GetPluginManager()->CallHookBlockPlace(m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_HeldItem)) { - if (a_Packet->m_Direction > -1) + if (a_BlockFace > -1) { - AddDirection(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction); - m_Player->GetWorld()->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); + AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); } return; } cWorld * World = m_Player->GetWorld(); - cBlockHandler *Handler = cBlockHandler::GetBlockHandler(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)); + cBlockHandler *Handler = cBlockHandler::GetBlockHandler(World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)); if (Handler->IsUseable()) { - Handler->OnClick(World, m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + Handler->OnClick(World, m_Player, a_BlockX, a_BlockY, a_BlockZ); } else { - cItemHandler *ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID); + cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID); - if(ItemHandler->OnItemUse(World, m_Player, &Equipped, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction)) + if (ItemHandler->OnItemUse(World, m_Player, &Equipped, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) { - //Nothing here :P - }else if(ItemHandler->IsPlaceable()) + // Nothing here :P + } + else if (ItemHandler->IsPlaceable()) { - if (a_Packet->m_Direction < 0) + if (a_BlockFace < 0) { // clicked in air return; } - int X = a_Packet->m_PosX; - int Y = a_Packet->m_PosY; - int Z = a_Packet->m_PosZ; - char Dir = a_Packet->m_Direction; - BLOCKTYPE ClickedBlock = World->GetBlock(X, Y, Z); + BLOCKTYPE ClickedBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); cBlockHandler *Handler = cBlockHandler::GetBlockHandler(ClickedBlock); if(Handler->IgnoreBuildCollision()) { - Handler->OnDestroyedByPlayer(World, m_Player, X, Y, Z); - World->FastSetBlock(X, Y, Z, E_BLOCK_AIR, 0); - }else{ - AddDirection(X, Y, Z, a_Packet->m_Direction); - //Check for Blocks not allowing placement on top - if(Dir == 1 && !Handler->AllowBlockOnTop()) + Handler->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ); + World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + } + else + { + AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + // Check for Blocks not allowing placement on top + if ((a_BlockFace == BLOCK_FACE_TOP) && !Handler->AllowBlockOnTop()) { - //Resend the old block - //Some times the client still places the block O.o + // Resend the old block + // Some times the client still places the block O.o - World->SendBlockTo(X, Y, Z, m_Player); + World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); return; } - int PlaceBlock = m_Player->GetWorld()->GetBlock(X, Y, Z); + int PlaceBlock = m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ); if (!BlockHandler(PlaceBlock)->IgnoreBuildCollision()) { - //tried to place a block *into* another? - return; // happens when you place a block aiming at side of block like torch or stem + // Tried to place a block *into* another? + return; // Happens when you place a block aiming at side of block like torch or stem } } - cBlockHandler *NewBlock = BlockHandler(ItemHandler->GetBlockType()); + cBlockHandler * NewBlock = BlockHandler(ItemHandler->GetBlockType()); - //cannot be placed on the side of an other block - if(Dir != 1 && !NewBlock->CanBePlacedOnSide()) + // Cannot be placed on the side of an other block + if ((a_BlockFace != BLOCK_FACE_TOP) && !NewBlock->CanBePlacedOnSide()) + { return; + } - if(NewBlock->CanBePlacedAt(World, X, Y, Z, Dir)) + if (NewBlock->CanBePlacedAt(World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) { - ItemHandler->PlaceBlock(World, m_Player, &m_Player->GetInventory().GetEquippedItem(), X, Y, Z, a_Packet->m_Direction); - }else{ - World->SendBlockTo(X, Y, Z, m_Player); //Send the old block back to the player + ItemHandler->PlaceBlock(World, m_Player, &m_Player->GetInventory().GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + } + else + { + World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); // Send the old block back to the player return; } - } else if(ItemHandler->IsFood()) { + } + else if (ItemHandler->IsFood()) + { cItem Item; Item.m_ItemID = Equipped.m_ItemID; Item.m_ItemCount = 1; @@ -1058,11 +1114,11 @@ void cClientHandle::HandleWindowClose(cPacket_WindowClose * a_Packet) -void cClientHandle::HandleWindowClick(cPacket_WindowClick * a_Packet) +void cClientHandle::HandleWindowClick(int a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem) { - if (a_Packet->m_WindowID == 0) + if (a_WindowID == 0) { - m_Player->GetInventory().Clicked(a_Packet); + m_Player->GetInventory().Clicked(a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_HeldItem); return; } @@ -1073,7 +1129,7 @@ void cClientHandle::HandleWindowClick(cPacket_WindowClick * a_Packet) return; } - Window->Clicked(a_Packet, *m_Player); + Window->Clicked(*m_Player, a_WindowID, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_HeldItem); } @@ -1361,7 +1417,32 @@ void cClientHandle::Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority /* = void cClientHandle::SendDisconnect(const AString & a_Reason) { cPacket_Disconnect DC(a_Reason); - m_Socket.Send(&DC); + m_Socket.Send(&DC); // Send it immediately to the socket, bypassing any packet buffers +} + + + + + +void cClientHandle::SendHandshake(const AString & a_ServerName) +{ + cPacket_Handshake Handshake; + Handshake.m_Username = a_ServerName; + Send(Handshake); +} + + + + + +void cClientHandle::SendInventorySlot(int a_WindowID, short a_SlotNum, const cItem & a_Item) +{ + cPacket_InventorySlot Packet; + Packet.m_WindowID = (char)a_WindowID; + Packet.m_SlotNum = a_SlotNum; + Packet.m_ItemID = (short)(a_Item.m_ItemID); + Packet.m_ItemCount = a_Item.m_ItemCount; + Packet.m_ItemUses = a_Item.m_ItemHealth; } -- cgit v1.2.3