1
0
Fork 0

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
This commit is contained in:
madmaxoft@gmail.com 2012-08-18 09:56:28 +00:00
parent 2cae4b24d8
commit 2691e8daed
50 changed files with 2299 additions and 2704 deletions

View File

@ -1,9 +1,8 @@
function OnBlockDig( Block, Player )
function OnBlockDig(Player, BlockX, BlockY, BlockZ, BlockFace, Status, OldBlockType, OldBlockMeta)
-- dont check if the direction is in the air
if Block.m_Direction ~= -1 then
if (BlockFace ~= -1) then
if( Player:HasPermission("core.build") == false ) then
if (Player:HasPermission("core.build") == false) then
return true
end
end

View File

@ -1,60 +1,63 @@
function OnBlockPlace( Block, Player )
function OnBlockPlace(Player, BlockX, BlockY, BlockZ, BlockFace, HeldItem)
-- dont check if the direction is in the air
if Block.m_Direction ~= -1 then
if( Player:HasPermission("core.build") == false ) then
return true
end
local X = Block.m_PosX
local Y = Block.m_PosY
local Z = Block.m_PosZ
X, Y, Z = AddDirection( X, Y, Z, Block.m_Direction )
if( Y >= 256 or Y < 0 ) then
return true
end
local CheckCollision = function( Player )
-- drop the decimals, we only care about the full block X,Y,Z
local PlayerX = math.floor(Player:GetPosX(), 0)
local PlayerY = math.floor(Player:GetPosY(), 0)
local PlayerZ = math.floor(Player:GetPosZ(), 0)
local BlockX = Block.m_PosX
local BlockY = Block.m_PosY
local BlockZ = Block.m_PosZ
-- player height is 2 blocks, so we check the position and then offset it up one
-- so they can't place a block on there face
local collision = false
if Block.m_Direction == 0 then if PlayerY == BlockY-2 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end
if Block.m_Direction == 1 then if PlayerY == BlockY+1 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end
if Block.m_Direction == 2 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end
if Block.m_Direction == 2 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end
if Block.m_Direction == 3 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end
if Block.m_Direction == 3 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end
if Block.m_Direction == 4 then if PlayerY == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end
if Block.m_Direction == 4 then if PlayerY+1 == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end
if Block.m_Direction == 5 then if PlayerY == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end
if Block.m_Direction == 5 then if PlayerY+1 == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end
return collision
end
if( Player:GetWorld():ForEachPlayer( CheckCollision ) == false ) then
return true
else
return false
end
if (BlockFace == -1) then
return false
end
return false
if( Player:HasPermission("core.build") == false ) then
return true
end
-- TODO: If the placed block is not a block (torch etc.), allow it without checking for collisions
local X = BlockX
local Y = BlockY
local Z = BlockZ
X, Y, Z = AddDirection(X, Y, Z, BlockFace)
if (Y >= 256 or Y < 0) then
return true
end
local CheckCollision = function(Player)
-- drop the decimals, we only care about the full block X,Y,Z
local PlayerX = math.floor(Player:GetPosX(), 0)
local PlayerY = math.floor(Player:GetPosY(), 0)
local PlayerZ = math.floor(Player:GetPosZ(), 0)
-- player height is 2 blocks, so we check the position and then offset it up one
-- so they can't place a block in anyone's face
local collision = false
if ((BlockFace == BLOCK_FACE_TOP) and (PlayerY == BlockY - 2) and (PlayerX == BlockX) and (PlayerZ == BlockZ)) then
collision = true
end
if ((BlockFace == BLOCK_FACE_BOTTOM) and (PlayerY == BlockY + 1) and (PlayerX == BlockX) and (PlayerZ == BlockZ)) then
collision = true
end
if ((BlockFace == BLOCK_FACE_NORTH) and (PlayerX == BlockX) and (PlayerZ == BlockZ - 1)) then
if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end
end
if ((BlockFace == BLOCK_FACE_SOUTH) and (PlayerX == BlockX) and (PlayerZ == BlockZ + 1)) then
if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end
end
if ((BlockFace == BLOCK_FACE_WEST) and (PlayerX == BlockX - 1) and (PlayerZ == BlockZ)) then
if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end
end
if ((BlockFace == BLOCK_FACE_EAST) and (PlayerX == BlockX + 1) and (PlayerZ == BlockZ)) then
if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end
end
return collision
end
if (Player:GetWorld():ForEachPlayer(CheckCollision) == false) then
return true
end
return false
end

View File

@ -45,9 +45,6 @@ $cfile "cMCLogger.h"
$cfile "cTracer.h"
$cfile "cGroup.h"
$cfile "BlockArea.h"
$cfile "packets/cPacket_Login.h"
$cfile "packets/cPacket_BlockDig.h"
$cfile "packets/cPacket_BlockPlace.h"
$cfile "cLuaChunk.h"
$cfile "CraftingRecipes.h"
$cfile "LuaItems.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 08/11/12 21:48:17.
** Generated automatically by tolua++-1.0.92 on 08/18/12 11:57:21.
*/
/* Exported function */

View File

@ -292,6 +292,20 @@ bool cByteBuffer::ReadUTF16String(AString & a_String, int a_NumChars)
bool cByteBuffer::SkipRead(int a_Count)
{
if (!CanReadBytes(a_Count))
{
return false;
}
AdvanceReadPos(a_Count);
return true;
}
void cByteBuffer::CommitRead(void)
{
m_DataStart = m_ReadPos;

View File

@ -65,8 +65,8 @@ public:
/// Reads 2 * a_NumChars bytes and interprets it as a UTF16 string, converting it into UTF8 string a_String
bool ReadUTF16String(AString & a_String, int a_NumChars);
/// Skips reading by a_Count bytes
void SkipRead(int a_Count);
/// Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer
bool SkipRead(int a_Count);
/// Removes the bytes that have been read from the ringbuffer
void CommitRead(void);

View File

@ -11,7 +11,6 @@ extern unsigned char g_BlockSpreadLightFalloff[];
extern bool g_BlockTransparent[];
// one hit break blocks
extern bool g_BlockOneHitDig[];
//tolua_end
//--DO NOT DELETE THIS COMMENT-- //tolua_export
@ -19,16 +18,27 @@ extern bool g_BlockOneHitDig[];
// Block face constants, used in PlayerDigging and PlayerBlockPlacement packets
enum
{
BLOCK_FACE_BOTTOM = 0, // Interacting with the bottom face of the block
BLOCK_FACE_TOP = 1, // Interacting with the top face of the block
BLOCK_FACE_NORTH = 2, // Interacting with the northern face of the block
BLOCK_FACE_SOUTH = 3, // Interacting with the southern face of the block
BLOCK_FACE_EAST = 5, // Interacting with the eastern face of the block
BLOCK_FACE_WEST = 4, // Interacting with the western face of the block
BLOCK_FACE_EAST = 5, // Interacting with the eastern face of the block
} ;
// PlayerDigging status constants:
enum
{
DIG_STATUS_STARTED = 0,
DIG_STATUS_FINISHED = 2,
DIG_STATUS_DROP_HELD = 4,
DIG_STATUS_SHOOT_EAT = 5,
} ;
//tolua_end

View File

@ -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<cPacket_Handshake *>(a_Packet)); break;
case E_LOGIN: HandleLogin (reinterpret_cast<cPacket_Login *> (a_Packet)); break;
case E_HANDSHAKE:
{
cPacket_Handshake * Handshake = reinterpret_cast<cPacket_Handshake *>(a_Packet);
HandleHandshake(Handshake->m_Username);
break;
}
case E_LOGIN:
{
cPacket_Login * Login = reinterpret_cast<cPacket_Login *>(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<cPacket_PlayerMoveLook *>(a_Packet)); break;
case E_PLAYERMOVELOOK:
{
cPacket_PlayerMoveLook * MoveLook = reinterpret_cast<cPacket_PlayerMoveLook *>(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<cPacket_CreativeInventoryAction *>(a_Packet)); break;
case E_PLAYERPOS: HandlePlayerPos (reinterpret_cast<cPacket_PlayerPosition *> (a_Packet)); break;
case E_BLOCK_DIG: HandleBlockDig (reinterpret_cast<cPacket_BlockDig *> (a_Packet)); break;
case E_BLOCK_PLACE: HandleBlockPlace (reinterpret_cast<cPacket_BlockPlace *> (a_Packet)); break;
case E_CREATIVE_INVENTORY_ACTION:
{
cPacket_CreativeInventoryAction * cia = reinterpret_cast<cPacket_CreativeInventoryAction *>(a_Packet);
HandleCreativeInventory(cia->m_SlotNum, cia->m_ClickedItem);
break;
}
case E_PLAYERPOS:
{
cPacket_PlayerPosition * pp = reinterpret_cast<cPacket_PlayerPosition *>(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<cPacket_BlockDig *>(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<cPacket_BlockPlace *>(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<cPacket_PickupSpawn *> (a_Packet)); break;
case E_CHAT: HandleChat (reinterpret_cast<cPacket_Chat *> (a_Packet)); break;
case E_PLAYERLOOK: HandlePlayerLook (reinterpret_cast<cPacket_PlayerLook *> (a_Packet)); break;
@ -600,7 +641,12 @@ void cClientHandle::HandlePacket(cPacket * a_Packet)
case E_ANIMATION: HandleAnimation (reinterpret_cast<cPacket_ArmAnim *> (a_Packet)); break;
case E_ITEM_SWITCH: HandleItemSwitch (reinterpret_cast<cPacket_ItemSwitch *> (a_Packet)); break;
case E_WINDOW_CLOSE: HandleWindowClose (reinterpret_cast<cPacket_WindowClose *> (a_Packet)); break;
case E_WINDOW_CLICK: HandleWindowClick (reinterpret_cast<cPacket_WindowClick *> (a_Packet)); break;
case E_WINDOW_CLICK:
{
cPacket_WindowClick * wc = reinterpret_cast<cPacket_WindowClick *>(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<cPacket_UpdateSign *> (a_Packet)); break;
case E_USE_ENTITY: HandleUseEntity (reinterpret_cast<cPacket_UseEntity *> (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())
return;
if(NewBlock->CanBePlacedAt(World, X, Y, Z, Dir))
// Cannot be placed on the side of an other block
if ((a_BlockFace != BLOCK_FACE_TOP) && !NewBlock->CanBePlacedOnSide())
{
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
return;
}
if (NewBlock->CanBePlacedAt(World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
{
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;
}

View File

@ -103,6 +103,8 @@ public:
void Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority = E_PRIORITY_NORMAL);
void SendDisconnect(const AString & a_Reason);
void SendHandshake (const AString & a_ServerName);
void SendInventorySlot(int a_WindowID, short a_SlotNum, const cItem & a_Item);
const AString & GetUsername(void) const; //tolua_export
@ -182,18 +184,18 @@ private:
// Packets handled in csConnected:
void HandlePing (void);
void HandleHandshake (cPacket_Handshake * a_Packet);
void HandleLogin (cPacket_Login * a_Packet);
void HandleUnexpectedPacket(cPacket * a_Packet); // the default case -> kick
void HandleHandshake (const AString & a_Username);
void HandleLogin (int a_ProtocolVersion, const AString & a_Username);
void HandleUnexpectedPacket(int a_PacketType); // the default case -> kick
// Packets handled while in csConfirmingPos:
void HandleMoveLookConfirm(cPacket_PlayerMoveLook * a_Packet); // While !m_bPositionConfirmed
void HandleMoveLookConfirm(double a_PosX, double a_PosY, double a_PosZ); // While !m_bPositionConfirmed
// Packets handled while in csPlaying:
void HandleCreativeInventory(cPacket_CreativeInventoryAction * a_Packet);
void HandlePlayerPos (cPacket_PlayerPosition * a_Packet);
void HandleBlockDig (cPacket_BlockDig * a_Packet);
void HandleBlockPlace (cPacket_BlockPlace * a_Packet);
void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem);
void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround);
void HandleBlockDig (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
void HandleBlockPlace (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem);
void HandlePickupSpawn (cPacket_PickupSpawn * a_Packet);
void HandleChat (cPacket_Chat * a_Packet);
void HandlePlayerLook (cPacket_PlayerLook * a_Packet);
@ -201,7 +203,7 @@ private:
void HandleAnimation (cPacket_ArmAnim * a_Packet);
void HandleItemSwitch (cPacket_ItemSwitch * a_Packet);
void HandleWindowClose (cPacket_WindowClose * a_Packet);
void HandleWindowClick (cPacket_WindowClick * a_Packet);
void HandleWindowClick (int a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem);
void HandleUpdateSign (cPacket_UpdateSign * a_Packet);
void HandleUseEntity (cPacket_UseEntity * a_Packet);
void HandleRespawn (void);

View File

@ -10,9 +10,7 @@
#include "cPickup.h"
#include "cRoot.h"
#include "cWorld.h"
#include "packets/cPacket_WindowClick.h"
#include "packets/cPacket_InventorySlot.h"
#include "items/Item.h"
@ -44,33 +42,38 @@ cCraftingWindow::cCraftingWindow( cWindowOwner* a_Owner, bool a_bInventoryVisibl
void cCraftingWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player )
void cCraftingWindow::Clicked(
cPlayer & a_Player,
int a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed,
const cItem & a_HeldItem
)
{
bool bDontCook = false;
cItem * DraggingItem = GetDraggingItem(&a_Player);
if (
a_ClickPacket->m_IsShiftPressed &&
a_IsShiftPressed &&
((DraggingItem == NULL) || DraggingItem->IsEmpty())
)
{
ShiftClicked(a_ClickPacket, a_Player);
ShiftClicked(a_Player, a_SlotNum);
return;
}
// Override for craft result slot
if (a_ClickPacket->m_SlotNum == 0)
if (a_SlotNum == 0)
{
LOG("In craft slot: %i x %i !!", GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount );
cItem* DraggingItem = GetDraggingItem( &a_Player );
if( DraggingItem->m_ItemID <= 0 )
LOGD("Clicked in craft result slot, item there: %d:%d (%d times) !!", GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemHealth, GetSlot(0)->m_ItemCount);
cItem * DraggingItem = GetDraggingItem(&a_Player);
if (DraggingItem->IsEmpty())
{
*DraggingItem = *GetSlot(0);
GetSlot(0)->Empty();
}
else if( DraggingItem->Equals( *GetSlot(0) ) )
else if (DraggingItem->IsEqual(*GetSlot(0)))
{
if( DraggingItem->m_ItemCount + GetSlot(0)->m_ItemCount <= 64 )
cItemHandler * Handler = ItemHandler(GetSlot(0)->m_ItemID);
if (DraggingItem->m_ItemCount + GetSlot(0)->m_ItemCount <= Handler->GetMaxStackSize())
{
DraggingItem->m_ItemCount += GetSlot(0)->m_ItemCount;
GetSlot(0)->Empty();
@ -84,21 +87,20 @@ void cCraftingWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_P
{
bDontCook = true;
}
LOG("Dragging Dish %i", DraggingItem->m_ItemCount );
}
else
{
cWindow::Clicked( a_ClickPacket, a_Player );
cWindow::Clicked(a_Player, GetWindowID(), a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_HeldItem);
}
if ((a_ClickPacket->m_SlotNum >= 0) && (a_ClickPacket->m_SlotNum < 10))
if ((a_SlotNum >= 0) && (a_SlotNum < 10))
{
cCraftingGrid Grid(GetSlots() + 1, 3, 3);
cCraftingRecipe Recipe(Grid);
cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe);
if ((a_ClickPacket->m_SlotNum == 0) && !bDontCook)
if ((a_SlotNum == 0) && !bDontCook)
{
// Consume the items from the crafting grid:
Recipe.ConsumeIngredients(Grid);
@ -110,19 +112,13 @@ void cCraftingWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_P
cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe);
}
*GetSlot(0) = Recipe.GetResult();
LOGD("%s cooked: %i x %i !!", a_Player.GetName().c_str(), GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemCount );
LOGD("%s cooked: %d:%d (%d times) !!", a_Player.GetName().c_str(), GetSlot(0)->m_ItemID, GetSlot(0)->m_ItemHealth, GetSlot(0)->m_ItemCount);
}
SendWholeWindow( a_Player.GetClientHandle() );
a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() );
// Separate packet for result =/ Don't know why
cPacket_InventorySlot Packet;
Packet.m_WindowID = (char)GetWindowID();
Packet.m_SlotNum = 0;
Packet.m_ItemID = (short)GetSlot(0)->m_ItemID;
Packet.m_ItemCount = GetSlot(0)->m_ItemCount;
Packet.m_ItemUses = (char)GetSlot(0)->m_ItemHealth;
a_Player.GetClientHandle()->Send( Packet );
a_Player.GetClientHandle()->SendInventorySlot(GetWindowID(), 0, *GetSlot(0));
}
@ -153,16 +149,15 @@ void cCraftingWindow::Close(cPlayer & a_Player)
void cCraftingWindow::ShiftClicked(cPacket_WindowClick * a_ClickPacket, cPlayer & a_Player)
void cCraftingWindow::ShiftClicked(cPlayer & a_Player, short a_SlotNum)
{
short Slot = a_ClickPacket->m_SlotNum;
if (Slot == SLOT_CRAFTING_RESULT)
if (a_SlotNum == SLOT_CRAFTING_RESULT)
{
ShiftClickedCraftingResult(Slot, a_Player);
ShiftClickedCraftingResult(a_Player, a_SlotNum);
}
else if ((Slot >= SLOT_CRAFTING_MIN) && (Slot <= SLOT_CRAFTING_MAX))
else if ((a_SlotNum >= SLOT_CRAFTING_MIN) && (a_SlotNum <= SLOT_CRAFTING_MAX))
{
ShiftClickedCraftingGrid(Slot, a_Player);
ShiftClickedCraftingGrid(a_Player, a_SlotNum);
}
else
{
@ -175,7 +170,7 @@ void cCraftingWindow::ShiftClicked(cPacket_WindowClick * a_ClickPacket, cPlayer
void cCraftingWindow::ShiftClickedCraftingResult(short a_Slot, cPlayer & a_Player)
void cCraftingWindow::ShiftClickedCraftingResult(cPlayer & a_Player, short a_Slot)
{
// Craft until either the recipe changes (due to ingredients) or there's not enough storage for the result
cInventory & Inventory = a_Player.GetInventory();
@ -210,7 +205,7 @@ void cCraftingWindow::ShiftClickedCraftingResult(short a_Slot, cPlayer & a_Playe
GetSlots()[SLOT_CRAFTING_RESULT] = Recipe.GetResult();
// If the recipe changed, abort:
if (!Recipe.GetResult().Equals(ResultCopy))
if (!Recipe.GetResult().IsEqual(ResultCopy))
{
break;
}
@ -221,7 +216,7 @@ void cCraftingWindow::ShiftClickedCraftingResult(short a_Slot, cPlayer & a_Playe
void cCraftingWindow::ShiftClickedCraftingGrid(short a_Slot, cPlayer & a_Player)
void cCraftingWindow::ShiftClickedCraftingGrid(cPlayer & a_Player, short a_Slot)
{
cInventory & Inventory = a_Player.GetInventory();
cItem * Item = GetSlot(a_Slot);

View File

@ -25,12 +25,17 @@ public:
cCraftingWindow(cWindowOwner * a_Owner, bool a_bInventoryVisible);
virtual void Clicked(cPacket_WindowClick * a_ClickPacket, cPlayer & a_Player);
virtual void Close(cPlayer & a_Player);
virtual void Clicked(
cPlayer & a_Player,
int a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed,
const cItem & a_HeldItem
) override;
void ShiftClicked(cPacket_WindowClick * a_ClickPacket, cPlayer & a_Player);
void ShiftClickedCraftingResult(short a_Slot, cPlayer & a_Player);
void ShiftClickedCraftingGrid (short a_Slot, cPlayer & a_Player);
virtual void Close(cPlayer & a_Player) override;
void ShiftClicked(cPlayer & a_Player, short a_SlotNum);
void ShiftClickedCraftingResult(cPlayer & a_Player, short a_SlotNum);
void ShiftClickedCraftingGrid (cPlayer & a_Player, short a_SlotNum);
};

View File

@ -14,37 +14,50 @@
#include "packets/cPacket_WholeInventory.h"
#include "packets/cPacket_InventorySlot.h"
cCreativeInventory::~cCreativeInventory()
{
}
cCreativeInventory::cCreativeInventory(cPlayer* a_Owner)
cCreativeInventory::cCreativeInventory(cPlayer * a_Owner)
: cInventory(a_Owner)
{
}
void cCreativeInventory::Clicked( cPacket* a_ClickPacket )
cCreativeInventory::~cCreativeInventory()
{
cPacket_CreativeInventoryAction* Packet = reinterpret_cast<cPacket_CreativeInventoryAction *>(a_ClickPacket);
short Slot = Packet->m_Slot;
if (Slot == -1)
}
void cCreativeInventory::Clicked(
short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed,
const cItem & a_HeldItem
)
{
if (a_SlotNum == -1)
{
// object thrown out
m_Owner->TossItem(false, Packet->m_Quantity, Packet->m_ItemID, Packet->m_Damage);
m_Owner->TossItem(false, a_HeldItem.m_ItemCount, a_HeldItem.m_ItemType, a_HeldItem.m_ItemDamage);
return;
}
if ((Slot < c_HotOffset) || (Slot >= c_NumSlots))
if ((a_SlotNum < c_HotOffset) || (a_SlotNum >= c_NumSlots))
{
LOG("%s: Invalid slot (%d) in CreativeInventoryAction packet. Ignoring...", m_Owner->GetName().c_str(), Slot);
LOG("%s: Invalid slot (%d) in cCreativeInventory::Clicked(). Ignoring...", m_Owner->GetName().c_str(), a_SlotNum);
return;
}
cItem * SlotItem = &(this->m_Slots[Slot]);
SlotItem->m_ItemID = (ENUM_ITEM_ID) Packet->m_ItemID;
SlotItem->m_ItemHealth = Packet->m_Damage;
SlotItem->m_ItemCount = Packet->m_Quantity;
m_Slots[a_SlotNum] = a_HeldItem;
}

View File

@ -1,13 +1,22 @@
#pragma once
#include "cInventory.h"
class cCreativeInventory //tolua_export
class cCreativeInventory
: public cInventory
{ //tolua_export
{
public:
cCreativeInventory(cPlayer* a_Owner);
cCreativeInventory(cPlayer * a_Owner);
~cCreativeInventory();
virtual void Clicked( cPacket* a_ClickPacket );
}; //tolua_export
virtual void Clicked(short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem) override;
} ;

View File

@ -120,7 +120,7 @@ bool cFurnaceEntity::Tick( float a_Dt )
if ((m_CookingItem != NULL) && ((m_TimeBurned < m_BurnTime) || (m_TimeCooked + a_Dt >= m_CookTime)))
{
if (m_CookingItem->Equals(m_Items[2]) || m_Items[2].IsEmpty())
if (m_CookingItem->IsEqual(m_Items[2]) || m_Items[2].IsEmpty())
{
m_TimeCooked += a_Dt;
if ( m_TimeCooked >= m_CookTime )
@ -201,9 +201,9 @@ bool cFurnaceEntity::StartCooking(void)
if( (m_TimeBurned < m_BurnTime) || BurnTime > 0.f ) // burnable material
{
const cFurnaceRecipe::Recipe* R = FR->GetRecipeFrom( m_Items[0] );
if( R ) // cook able ingredient
if (R != NULL) // cook able ingredient
{
if( m_Items[2].Equals( *R->Out ) || m_Items[2].IsEmpty() )
if (m_Items[2].IsEqual(*R->Out) || m_Items[2].IsEmpty())
{
// good to go
@ -241,7 +241,7 @@ bool cFurnaceEntity::ContinueCooking(void)
const cFurnaceRecipe::Recipe * R = FR->GetRecipeFrom( m_Items[0] );
if (R != NULL) // cook able ingredient
{
if (m_Items[2].Equals(*R->Out) || m_Items[2].IsEmpty())
if (m_Items[2].IsEqual(*R->Out) || m_Items[2].IsEmpty())
{
// good to go
if (m_CookingItem == NULL) // Only cook new item if not already cooking

View File

@ -22,21 +22,27 @@ cFurnaceWindow::cFurnaceWindow( cFurnaceEntity* a_Owner )
void cFurnaceWindow::Clicked(cPacket_WindowClick * a_ClickPacket, cPlayer & a_Player)
void cFurnaceWindow::Clicked(
cPlayer & a_Player,
int a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed,
const cItem & a_HeldItem
)
{
cItem Fuel = *GetSlot( 0 );
cWindow::Clicked( a_ClickPacket, a_Player );
cWindow::Clicked(a_Player, a_WindowID, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_HeldItem);
if (m_Furnace != NULL)
{
if ((a_ClickPacket->m_SlotNum >= 0) && (a_ClickPacket->m_SlotNum <= 2)) // them important slots
if ((a_SlotNum >= 0) && (a_SlotNum <= 2)) // them important slots
{
if( Fuel.m_ItemID != GetSlot( 0 )->m_ItemID )
m_Furnace->ResetCookTimer();
if( m_Furnace->StartCooking() )
if (Fuel.m_ItemID != GetSlot( 0 )->m_ItemID)
{
SendWholeWindow( a_Player.GetClientHandle() );
m_Furnace->ResetCookTimer();
}
if (m_Furnace->StartCooking())
{
SendWholeWindow(a_Player.GetClientHandle());
}
}
}

View File

@ -1,16 +1,37 @@
#pragma once
#include "cWindow.h"
class cFurnaceEntity;
class cWindowOwner;
class cFurnaceWindow : public cWindow
class cFurnaceWindow :
public cWindow
{
public:
cFurnaceWindow( cFurnaceEntity* a_Owner );
virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player );
virtual void Close( cPlayer & a_Player );
virtual void Clicked(
cPlayer & a_Player,
int a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed,
const cItem & a_HeldItem
) override;
virtual void Close( cPlayer & a_Player ) override;
private:
cFurnaceEntity* m_Furnace;
};
cFurnaceEntity * m_Furnace;
};

View File

@ -293,7 +293,7 @@ void cInventory::SendWholeInventoryToAll(void)
void cInventory::SendSlot( int a_SlotNum )
{
cItem* Item = GetSlot( a_SlotNum );
cItem * Item = GetSlot(a_SlotNum);
if (Item != NULL)
{
if (Item->IsEmpty())

View File

@ -51,7 +51,7 @@ public:
void SetEquippedSlot( int a_SlotNum ); //tolua_export
short GetEquippedSlot() { return m_EquippedSlot; } //tolua_export
virtual void Clicked( cPacket* a_ClickPacket ) = 0;
virtual void Clicked(short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem) = 0;
void SendSlot( int a_SlotNum ); //tolua_export

View File

@ -28,24 +28,31 @@ void cItem::FromJson( const Json::Value & a_Value )
}
}
bool cItem::IsEnchantable(ENUM_ITEM_ID item)
bool cItem::IsEnchantable(short item)
{
if(item >= 256 && item <= 259)
if ((item >= 256) && (item <= 259))
return true;
if(item >= 267 && item <= 279)
if ((item >= 267) && (item <= 279))
return true;
if(item >= 283 && item <= 286)
if ((item >= 283) && (item <= 286))
return true;
if(item >= 290 && item <= 294)
if ((item >= 290) && (item <= 294))
return true;
if(item >= 298 && item <= 317)
if ((item >= 298) && (item <= 317))
return true;
if(item >= 290 && item <= 294)
if ((item >= 290) && (item <= 294))
return true;
if(item == 346 || item == 359 || item == 261)
if ((item == 346) || (item == 359) || (item == 261))
return true;
return false;
}

View File

@ -39,9 +39,23 @@ public:
{
return (m_ItemID <= 0 || m_ItemCount <= 0);
}
bool Equals( cItem & a_Item ) const
// tolua_end
OBSOLETE
// tolua_begin
bool Equals(const cItem & a_Item) const // obsolete, use IsEqual() instead
{
return ( (m_ItemID == a_Item.m_ItemID) && (m_ItemHealth == a_Item.m_ItemHealth) );
return IsEqual(a_Item);
}
bool IsEqual(const cItem & a_Item) const
{
return (IsSameType(a_Item) && (m_ItemHealth == a_Item.m_ItemHealth));
}
bool IsSameType(const cItem & a_Item) const
{
return (m_ItemID == a_Item.m_ItemID) || (IsEmpty() && a_Item.IsEmpty());
}
// TODO Sorry for writing the functions in the header. But somehow it doesn´t worked when I put them into the cpp File :s
@ -100,12 +114,25 @@ public:
void FromJson( const Json::Value & a_Value );
// tolua_begin
static bool IsEnchantable(ENUM_ITEM_ID item);
ENUM_ITEM_ID m_ItemID;
char m_ItemCount;
short m_ItemHealth;
static bool IsEnchantable(short a_ItemType);
// tolua_end
union
{
// tolua_begin
ENUM_ITEM_ID m_ItemID; // OBSOLETE, use m_ItemType instead
short m_ItemType;
// tolua_end
} ;
char m_ItemCount; // tolua_export
union
{
// tolua_begin
short m_ItemHealth; // OBSOLETE, use m_ItemDamage instead
short m_ItemDamage;
// tolua_end
} ;
// tolua_begin
};
// tolua_end

View File

@ -39,6 +39,7 @@ public:
double GetEyeHeight(); //tolua_export
Vector3d GetEyePosition(); //tolua_export
inline bool GetFlying() { return m_bTouchGround; } //tolua_export
inline bool IsOnGround(void) const {return m_bTouchGround; } // tolua_export
inline const double & GetStance() { return m_Stance; } //tolua_export
inline cInventory & GetInventory() { if(GetGameMode() == eGameMode_Survival) return *m_Inventory; else return *m_CreativeInventory; } //tolua_export

View File

@ -37,10 +37,16 @@ void cPlugin::Tick(float a_Dt)
bool cPlugin::OnBlockPlace(cPacket_BlockPlace * a_PacketData, cPlayer * a_Player)
bool cPlugin::OnBlockDig(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta)
{
UNUSED(a_PacketData);
UNUSED(a_Player);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_Status);
UNUSED(a_OldBlock);
UNUSED(a_OldMeta);
return false;
}
@ -48,11 +54,14 @@ bool cPlugin::OnBlockPlace(cPacket_BlockPlace * a_PacketData, cPlayer * a_Player
bool cPlugin::OnBlockDig(cPacket_BlockDig * a_PacketData, cPlayer * a_Player, cItem * a_PickupItem)
bool cPlugin::OnBlockPlace(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem)
{
UNUSED(a_PacketData);
UNUSED(a_Player);
UNUSED(a_PickupItem);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_BlockFace);
UNUSED(a_HeldItem);
return false;
}
@ -60,21 +69,13 @@ bool cPlugin::OnBlockDig(cPacket_BlockDig * a_PacketData, cPlayer * a_Player, cI
bool cPlugin::OnCollectItem(cPickup * a_Pickup, cPlayer * a_Player)
bool cPlugin::OnBlockToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups)
{
UNUSED(a_Pickup);
UNUSED(a_Player);
return false;
}
bool cPlugin::OnDisconnect(const AString & a_Reason, cPlayer * a_Player)
{
UNUSED(a_Reason);
UNUSED(a_BlockType);
UNUSED(a_BlockMeta);
UNUSED(a_Player);
UNUSED(a_EquippedItem);
UNUSED(a_Pickups);
return false;
}
@ -93,65 +94,6 @@ bool cPlugin::OnChat(const char * a_Chat, cPlayer * a_Player)
bool cPlugin::OnLogin(cPacket_Login * a_PacketData)
{
UNUSED(a_PacketData);
return false;
}
void cPlugin::OnPlayerSpawn(cPlayer * a_Player)
{
UNUSED(a_Player);
}
bool cPlugin::OnPlayerJoin(cPlayer * a_Player)
{
UNUSED(a_Player);
return false;
}
void cPlugin::OnPlayerMove(cPlayer * a_Player)
{
UNUSED(a_Player);
}
void cPlugin::OnTakeDamage(cPawn * a_Pawn, TakeDamageInfo * a_TakeDamageInfo)
{
UNUSED(a_Pawn);
UNUSED(a_TakeDamageInfo);
}
bool cPlugin::OnKilled(cPawn * a_Killed, cEntity * a_Killer)
{
UNUSED(a_Killed);
UNUSED(a_Killer);
return false;
}
void cPlugin::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
{
UNUSED(a_World);
@ -176,11 +118,10 @@ bool cPlugin::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cL
bool cPlugin::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
bool cPlugin::OnCollectItem(cPickup * a_Pickup, cPlayer * a_Player)
{
UNUSED(a_Pickup);
UNUSED(a_Player);
UNUSED(a_Grid);
UNUSED(a_Recipe);
return false;
}
@ -200,6 +141,68 @@ bool cPlugin::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid *
bool cPlugin::OnDisconnect(const AString & a_Reason, cPlayer * a_Player)
{
UNUSED(a_Reason);
UNUSED(a_Player);
return false;
}
bool cPlugin::OnKilled(cPawn * a_Killed, cEntity * a_Killer)
{
UNUSED(a_Killed);
UNUSED(a_Killer);
return false;
}
bool cPlugin::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username)
{
UNUSED(a_Client);
UNUSED(a_ProtocolVersion);
UNUSED(a_Username);
return false;
}
bool cPlugin::OnPlayerJoin(cPlayer * a_Player)
{
UNUSED(a_Player);
return false;
}
void cPlugin::OnPlayerMove(cPlayer * a_Player)
{
UNUSED(a_Player);
}
void cPlugin::OnPlayerSpawn(cPlayer * a_Player)
{
UNUSED(a_Player);
}
bool cPlugin::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
UNUSED(a_Player);
@ -212,13 +215,11 @@ bool cPlugin::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_G
bool cPlugin::OnBlockToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups)
bool cPlugin::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
UNUSED(a_BlockType);
UNUSED(a_BlockMeta);
UNUSED(a_Player);
UNUSED(a_EquippedItem);
UNUSED(a_Pickups);
UNUSED(a_Grid);
UNUSED(a_Recipe);
return false;
}
@ -226,9 +227,26 @@ bool cPlugin::OnBlockToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, con
bool cPlugin::OnWeatherChanged(cWorld * a_World)
void cPlugin::OnTakeDamage(cPawn * a_Pawn, TakeDamageInfo * a_TakeDamageInfo)
{
UNUSED(a_Pawn);
UNUSED(a_TakeDamageInfo);
}
bool cPlugin::OnUpdatedSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
{
UNUSED(a_World);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_Line1);
UNUSED(a_Line2);
UNUSED(a_Line3);
UNUSED(a_Line4);
return false;
}
@ -253,16 +271,9 @@ bool cPlugin::OnUpdatingSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a
bool cPlugin::OnUpdatedSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
bool cPlugin::OnWeatherChanged(cWorld * a_World)
{
UNUSED(a_World);
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_Line1);
UNUSED(a_Line2);
UNUSED(a_Line3);
UNUSED(a_Line4);
return false;
}

View File

@ -46,28 +46,28 @@ public:
/**
* On all these functions, return true if you want to override default behavior
* You can also return false, so default behavior is used, but with changed PacketData
* You can also return false, so default behavior is used.
**/
virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player );
virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player );
virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player );
virtual bool OnBlockDig (cPacket_BlockDig * a_PacketData, cPlayer * a_Player, cItem * a_PickupItem);
virtual bool OnChat (const char * a_Chat, cPlayer* a_Player );
virtual bool OnLogin (cPacket_Login* a_PacketData );
virtual void OnPlayerSpawn (cPlayer* a_Player );
virtual bool OnPlayerJoin (cPlayer* a_Player );
virtual void OnPlayerMove (cPlayer* a_Player );
virtual void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo );
virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer );
virtual bool OnBlockDig (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
virtual bool OnBlockPlace (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem);
virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
virtual bool OnChat (const char * a_Chat, cPlayer * a_Player );
virtual void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ);
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk);
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player );
virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player );
virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer );
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
virtual bool OnPlayerJoin (cPlayer* a_Player );
virtual void OnPlayerMove (cPlayer* a_Player );
virtual void OnPlayerSpawn (cPlayer* a_Player );
virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups);
virtual bool OnWeatherChanged (cWorld * a_World);
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4);
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual void OnTakeDamage (cPawn * a_Pawn, TakeDamageInfo * a_TakeDamageInfo );
virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4);
virtual bool OnWeatherChanged (cWorld * a_World);
// Accessors
const char* GetName() const { return m_Name.c_str(); }

View File

@ -262,40 +262,7 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...)
}
break;
}
case HOOK_BLOCK_DIG:
{
if( a_NumArgs != 2 ) break;
va_list argptr;
va_start( argptr, a_NumArgs);
cPacket_BlockDig* Packet = va_arg(argptr, cPacket_BlockDig* );
cPlayer* Player = va_arg(argptr, cPlayer* );
cItem* Item = va_arg( argptr, cItem* );
va_end (argptr);
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
{
if( (*itr)->OnBlockDig( Packet, Player, Item ) )
return true;
}
break;
}
case HOOK_BLOCK_PLACE:
{
if( a_NumArgs != 2 ) break;
va_list argptr;
va_start( argptr, a_NumArgs);
cPacket_BlockPlace* Packet = va_arg(argptr, cPacket_BlockPlace* );
cPlayer* Player = va_arg(argptr, cPlayer* );
va_end (argptr);
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
{
if( (*itr)->OnBlockPlace( Packet, Player ) )
return true;
}
break;
}
case HOOK_DISCONNECT:
{
if( a_NumArgs != 2 ) break;
@ -312,21 +279,6 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...)
break;
}
case HOOK_LOGIN:
{
if( a_NumArgs != 1 ) break;
va_list argptr;
va_start( argptr, a_NumArgs);
cPacket_Login* Packet = va_arg(argptr, cPacket_Login* );
va_end (argptr);
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
{
if( (*itr)->OnLogin( Packet ) )
return true;
}
break;
}
case HOOK_PLAYER_JOIN:
{
if( a_NumArgs != 1 ) break;
@ -437,6 +389,69 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...)
bool cPluginManager::CallHookLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_LOGIN);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnLogin(a_Client, a_ProtocolVersion, a_Username))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookBlockDig(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_DIG);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnBlockDig(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status, a_OldBlock, a_OldMeta))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookBlockPlace(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_PLACE);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnBlockPlace(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_HeldItem))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_LuaChunk)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_GENERATING);

View File

@ -97,6 +97,9 @@ public: //tolua_export
// If the hook returns true, no further hook is called and the functions return false
bool CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... );
bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
bool CallHookBlockDig (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE OldBlock, NIBBLETYPE OldMeta);
bool CallHookBlockPlace (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem);
bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_Chunk);
bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);

View File

@ -204,41 +204,56 @@ bool cPlugin_NewLua::OnDisconnect(const AString & a_Reason, cPlayer* a_Player )
bool cPlugin_NewLua::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player )
bool cPlugin_NewLua::OnBlockPlace(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem)
{
cCSLock Lock( m_CriticalSection );
if( !PushFunction("OnBlockPlace") )
cCSLock Lock(m_CriticalSection);
if (!PushFunction("OnBlockPlace"))
{
return false;
}
tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockPlace");
tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
tolua_pushnumber (m_LuaState, a_BlockX);
tolua_pushnumber (m_LuaState, a_BlockY);
tolua_pushnumber (m_LuaState, a_BlockZ);
tolua_pushnumber (m_LuaState, a_BlockFace);
tolua_pushusertype(m_LuaState, (void *)&a_HeldItem, "cItem");
if( !CallFunction(2, 1, "OnBlockPlace") )
if (!CallFunction(6, 1, "OnBlockPlace"))
{
return false;
}
bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
return bRetVal;
return (tolua_toboolean( m_LuaState, -1, 0) > 0);
}
bool cPlugin_NewLua::OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem )
bool cPlugin_NewLua::OnBlockDig(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta)
{
cCSLock Lock( m_CriticalSection );
if( !PushFunction("OnBlockDig") )
cCSLock Lock(m_CriticalSection);
if (!PushFunction("OnBlockDig"))
{
return false;
}
tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_BlockDig");
tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
tolua_pushusertype(m_LuaState, a_PickupItem, "cItem");
tolua_pushnumber (m_LuaState, a_BlockX);
tolua_pushnumber (m_LuaState, a_BlockY);
tolua_pushnumber (m_LuaState, a_BlockZ);
tolua_pushnumber (m_LuaState, a_BlockFace);
tolua_pushnumber (m_LuaState, a_Status);
tolua_pushnumber (m_LuaState, a_OldBlock);
tolua_pushnumber (m_LuaState, a_OldMeta);
if( !CallFunction(3, 1, "OnBlockDig") )
if (!CallFunction(8, 1, "OnBlockDig"))
{
return false;
}
bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);
return bRetVal;
return (tolua_toboolean( m_LuaState, -1, 0) > 0);
}
@ -265,15 +280,17 @@ bool cPlugin_NewLua::OnChat( const char* a_Chat, cPlayer* a_Player )
bool cPlugin_NewLua::OnLogin( cPacket_Login* a_PacketData )
bool cPlugin_NewLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username)
{
cCSLock Lock( m_CriticalSection );
if( !PushFunction("OnLogin") )
return false;
tolua_pushusertype(m_LuaState, a_PacketData, "cPacket_Login");
tolua_pushusertype (m_LuaState, a_Client, "cClientHandle");
tolua_pushnumber (m_LuaState, a_ProtocolVersion);
tolua_pushcppstring(m_LuaState, a_Username);
if( !CallFunction(1, 1, "OnLogin") )
if (!CallFunction(3, 1, "OnLogin"))
return false;
bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0);

View File

@ -27,10 +27,10 @@ public: //tolua_export
virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override;
virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override;
virtual bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) override;
virtual bool OnBlockDig (cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) override;
virtual bool OnBlockPlace (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem) override;
virtual bool OnBlockDig (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta) override;
virtual bool OnChat (const char* a_Chat, cPlayer* a_Player ) override;
virtual bool OnLogin (cPacket_Login* a_PacketData ) override;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override;
virtual void OnPlayerSpawn (cPlayer* a_Player ) override;
virtual bool OnPlayerJoin (cPlayer* a_Player ) override;
virtual void OnPlayerMove (cPlayer* a_Player ) override;

View File

@ -125,37 +125,37 @@ bool cPlugin_Squirrel::OnDisconnect(const AString & a_Reason, cPlayer* a_Player
bool cPlugin_Squirrel::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player )
bool cPlugin_Squirrel::OnBlockPlace(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem)
{
cCSLock Lock( m_CriticalSection );
cCSLock Lock(m_CriticalSection);
if(!m_Plugin->HasFunction("OnBlockPlace")) return false;
if (!m_Plugin->HasFunction("OnBlockPlace")) return false;
return m_Plugin->GetFunction("OnBlockPlace").Evaluate<bool>(a_PacketData, a_Player);
return m_Plugin->GetFunction("OnBlockPlace").Evaluate<bool>(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_HeldItem);
}
bool cPlugin_Squirrel::OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem )
bool cPlugin_Squirrel::OnBlockDig(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta)
{
cCSLock Lock( m_CriticalSection );
cCSLock Lock(m_CriticalSection);
if(!m_Plugin->HasFunction("OnBlockDig")) return false;
if (!m_Plugin->HasFunction("OnBlockDig")) return false;
return m_Plugin->GetFunction("OnBlockDig").Evaluate<bool>(a_PacketData, a_Player, a_PickupItem);
return m_Plugin->GetFunction("OnBlockDig").Evaluate<bool>(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status, a_OldBlock, a_OldMeta);
}
bool cPlugin_Squirrel::OnChat( const char* a_Chat, cPlayer* a_Player )
bool cPlugin_Squirrel::OnChat(const char * a_Chat, cPlayer * a_Player)
{
cCSLock Lock( m_CriticalSection );
if(!m_Plugin->HasFunction("OnChat")) return false;
if (!m_Plugin->HasFunction("OnChat")) return false;
return m_Plugin->GetFunction("OnChat").Evaluate<bool>(a_Chat, a_Player);
@ -165,13 +165,16 @@ bool cPlugin_Squirrel::OnChat( const char* a_Chat, cPlayer* a_Player )
bool cPlugin_Squirrel::OnLogin( cPacket_Login* a_PacketData )
bool cPlugin_Squirrel::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username)
{
cCSLock Lock( m_CriticalSection );
if(!m_Plugin->HasFunction("OnLogin")) return false;
if (!m_Plugin->HasFunction("OnLogin"))
{
return false;
}
return m_Plugin->GetFunction("OnLogin").Evaluate<bool>(a_PacketData);
return m_Plugin->GetFunction("OnLogin").Evaluate<bool>(a_Client, a_ProtocolVersion, a_Username);
}

View File

@ -16,10 +16,10 @@ public:
bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override;
bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override;
bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) override;
bool OnBlockDig (cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) override;
bool OnChat (const char* a_Chat, cPlayer* a_Player ) override;
bool OnLogin (cPacket_Login* a_PacketData ) override;
bool OnBlockPlace (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, const cItem & a_HeldItem) override;
bool OnBlockDig (cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta) override;
bool OnChat (const char * a_Chat, cPlayer * a_Player ) override;
bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override;
void OnPlayerSpawn (cPlayer* a_Player ) override;
bool OnPlayerJoin (cPlayer* a_Player ) override;
void OnPlayerMove (cPlayer* a_Player ) override;

View File

@ -8,7 +8,7 @@
#include "cItem.h"
#include "CraftingRecipes.h"
#include "cRoot.h"
#include "packets/cPacket_WindowClick.h"
#include "items/Item.h"
@ -31,39 +31,42 @@ cSurvivalInventory::~cSurvivalInventory()
void cSurvivalInventory::Clicked( cPacket* a_ClickPacket )
void cSurvivalInventory::Clicked(
short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed,
const cItem & a_HeldItem
)
{
cPacket_WindowClick * Packet = reinterpret_cast<cPacket_WindowClick *>(a_ClickPacket);
cWindow * Window = GetWindow();
if (
Packet->m_IsShiftPressed && // Shift pressed
(GetWindow() != NULL) && // Window is valid
(GetWindow()->GetDraggingItem()->IsEmpty()) // Not dragging anything
a_IsShiftPressed && // Shift pressed
(Window != NULL) && // Window is valid
(Window->GetDraggingItem()->IsEmpty()) // Not dragging anything
)
{
ShiftClicked(Packet);
ShiftClicked(a_SlotNum);
return;
}
bool bDontCook = false;
if (GetWindow())
if (Window != NULL)
{
// Override for craft result slot
if (Packet->m_SlotNum == (short)c_CraftOffset)
if (a_SlotNum == (short)c_CraftOffset)
{
LOGD("In craft slot: %i x %i !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount );
cItem * DraggingItem = GetWindow()->GetDraggingItem();
LOGD("Clicked in craft result slot, item there: %d:%d (%d times) !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemHealth, m_Slots[c_CraftOffset].m_ItemCount);
cItem * DraggingItem = Window->GetDraggingItem();
if (DraggingItem->IsEmpty())
{
*DraggingItem = m_Slots[c_CraftOffset];
m_Slots[c_CraftOffset].Empty();
}
else if (DraggingItem->Equals(m_Slots[c_CraftOffset]))
else if (DraggingItem->IsEqual(m_Slots[c_CraftOffset]))
{
if (DraggingItem->m_ItemCount + m_Slots[c_CraftOffset].m_ItemCount <= 64)
cItemHandler * Handler = ItemHandler(m_Slots[c_CraftOffset].m_ItemID);
if (DraggingItem->m_ItemCount + m_Slots[c_CraftOffset].m_ItemCount <= Handler->GetMaxStackSize())
{
DraggingItem->m_ItemCount += m_Slots[c_CraftOffset].m_ItemCount;
m_Slots[0].Empty();
m_Slots[c_CraftOffset].Empty();
}
else
{
@ -74,11 +77,10 @@ void cSurvivalInventory::Clicked( cPacket* a_ClickPacket )
{
bDontCook = true;
}
LOGD("Dragging Dish %i", DraggingItem->m_ItemCount );
}
else
{
GetWindow()->Clicked( Packet, *m_Owner );
Window->Clicked(*m_Owner, 0, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_HeldItem);
}
}
else
@ -87,14 +89,14 @@ void cSurvivalInventory::Clicked( cPacket* a_ClickPacket )
LOG("No Inventory window! WTF");
}
if ((Packet->m_SlotNum >= (short)c_CraftOffset) && (Packet->m_SlotNum < (short)(c_CraftOffset + c_CraftSlots + 1)))
if ((a_SlotNum >= (short)c_CraftOffset) && (a_SlotNum < (short)(c_CraftOffset + c_CraftSlots + 1)))
{
cCraftingGrid Grid(m_Slots + c_CraftOffset + 1, 2, 2);
cCraftingRecipe Recipe(Grid);
cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe);
if ((Packet->m_SlotNum == 0) && !bDontCook)
if ((a_SlotNum == 0) && !bDontCook)
{
// Consume the items from the crafting grid:
Recipe.ConsumeIngredients(Grid);
@ -106,8 +108,8 @@ void cSurvivalInventory::Clicked( cPacket* a_ClickPacket )
cRoot::Get()->GetCraftingRecipes()->GetRecipe(m_Owner, Grid, Recipe);
}
m_Slots[c_CraftOffset] = Recipe.GetResult();
LOGD("%s cooked: %i x %i !!", m_Owner->GetName().c_str(), m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount );
SendWholeInventory( m_Owner->GetClientHandle() );
LOGD("%s cooked: %d:%d (%d times) !!", m_Owner->GetName().c_str(), m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemHealth, m_Slots[c_CraftOffset].m_ItemCount );
SendWholeInventory(m_Owner->GetClientHandle());
}
SendSlot(0);
}
@ -116,32 +118,31 @@ void cSurvivalInventory::Clicked( cPacket* a_ClickPacket )
void cSurvivalInventory::ShiftClicked(cPacket_WindowClick * a_ClickPacket)
void cSurvivalInventory::ShiftClicked(short a_SlotNum)
{
ASSERT((GetWindow() == NULL) || (GetWindow()->GetDraggingItem()->IsEmpty())); // Cannot handle shift-click if dragging something
short Slot = a_ClickPacket->m_SlotNum;
if (Slot == SLOT_CRAFTING_RESULT)
if (a_SlotNum == SLOT_CRAFTING_RESULT)
{
ShiftClickedCraftingResult(Slot);
ShiftClickedCraftingResult(a_SlotNum);
}
else if ((Slot >= SLOT_CRAFTING_MIN) && (Slot <= SLOT_CRAFTING_MAX))
else if ((a_SlotNum >= SLOT_CRAFTING_MIN) && (a_SlotNum <= SLOT_CRAFTING_MAX))
{
ShiftClickedCraftingGrid(Slot);
ShiftClickedCraftingGrid(a_SlotNum);
}
else if ((Slot >= SLOT_ARMOR_MIN) && (Slot <= SLOT_ARMOR_MAX))
else if ((a_SlotNum >= SLOT_ARMOR_MIN) && (a_SlotNum <= SLOT_ARMOR_MAX))
{
ShiftClickedArmor(Slot);
ShiftClickedArmor(a_SlotNum);
}
else if ((Slot >= SLOT_HOTBAR_MIN) && (Slot <= SLOT_HOTBAR_MAX))
else if ((a_SlotNum >= SLOT_HOTBAR_MIN) && (a_SlotNum <= SLOT_HOTBAR_MAX))
{
ShiftClickedHotbar(Slot);
ShiftClickedHotbar(a_SlotNum);
}
else
{
ShiftClickedInventory(Slot);
ShiftClickedInventory(a_SlotNum);
}
// Because the client tries to guess our actions, not always right, send the whole inventory:
// Because the client tries to guess our actions and is not always right, send the whole inventory:
SendWholeInventoryToAll();
}
@ -182,7 +183,7 @@ void cSurvivalInventory::ShiftClickedCraftingResult(short a_Slot)
m_Slots[SLOT_CRAFTING_RESULT] = Recipe.GetResult();
// If the recipe changed, abort:
if (!Recipe.GetResult().Equals(ResultCopy))
if (!Recipe.GetResult().IsEqual(ResultCopy))
{
break;
}

View File

@ -28,8 +28,8 @@ class cSurvivalInventory //tolua_export
SLOT_HOTBAR_MAX = 44,
} ;
void ShiftClickedCraftingResult(short a_Slot);
void ShiftClickedCraftingGrid (short a_Slot);
void ShiftClickedCraftingResult(short a_SlotNum);
void ShiftClickedCraftingGrid (short a_SlotNum);
void ShiftClickedArmor (short a_Slot);
void ShiftClickedHotbar (short a_Slot);
void ShiftClickedInventory (short a_Slot);
@ -38,9 +38,9 @@ public:
cSurvivalInventory(cPlayer* a_Owner);
~cSurvivalInventory();
virtual void Clicked(cPacket * a_ClickPacket) override;
virtual void Clicked(short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem) override;
void ShiftClicked(cPacket_WindowClick * a_ClickPacket);
void ShiftClicked(short a_SlotNum);
}; //tolua_export

View File

@ -8,8 +8,8 @@
#include "cPickup.h"
#include "cInventory.h"
#include "cWindowOwner.h"
#include "items/Item.h"
#include "packets/cPacket_WindowClick.h"
#include "packets/cPacket_WholeInventory.h"
#include "packets/cPacket_WindowOpen.h"
#include "packets/cPacket_WindowClose.h"
@ -84,11 +84,15 @@ cItem* cWindow::GetDraggingItem( cPlayer * a_Player /* = 0 */ )
void cWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player )
void cWindow::Clicked(
cPlayer & a_Player,
int a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed,
const cItem & a_HeldItem
)
{
if (a_ClickPacket->m_WindowID != m_WindowID)
if (a_WindowID != m_WindowID)
{
LOG("WRONG WINDOW ID! (exp %d, got %d)", m_WindowID, a_ClickPacket->m_WindowID);
LOG("WRONG WINDOW ID! (exp %d, got %d) received from \"%s\"", m_WindowID, a_WindowID, a_Player.GetName().c_str());
return;
}
@ -101,111 +105,118 @@ void cWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player )
}
}
bool bAsync = false;
if (a_ClickPacket->m_SlotNum == -999) // Outside window click
if (a_SlotNum == -999) // Outside window click
{
if (a_ClickPacket->m_RightMouse)
if (a_IsRightClick)
{
a_Player.TossItem( true );
a_Player.TossItem(true);
}
else
{
a_Player.TossItem( true, m_DraggingItem->m_ItemCount );
a_Player.TossItem(true, m_DraggingItem->m_ItemCount);
}
}
else if (GetSlot(a_ClickPacket->m_SlotNum) != NULL)
else if (GetSlot(a_SlotNum) != NULL)
{
cItem * Item = GetSlot(a_ClickPacket->m_SlotNum);
if (
(a_ClickPacket->m_ItemID != Item->m_ItemID) ||
(a_ClickPacket->m_ItemCount != Item->m_ItemCount) ||
(a_ClickPacket->m_ItemUses != Item->m_ItemHealth)
)
cItem * Item = GetSlot(a_SlotNum);
if (!Item->IsEqual(a_HeldItem))
{
if (!((a_ClickPacket->m_ItemID == -1 || a_ClickPacket->m_ItemID == 0) && (Item->m_ItemID == -1 || Item->m_ItemID == 0 )) )
{
LOGD("My ID: %i Their ID: %i", Item->m_ItemID, a_ClickPacket->m_ItemID );
LOGD("My Count: %i Their Count: %i", Item->m_ItemCount, a_ClickPacket->m_ItemCount );
LOGD("My Uses: %i Their Uses: %i", Item->m_ItemHealth, a_ClickPacket->m_ItemUses );
bAsync = true;
}
LOGD("*** Window lost sync ***");
LOGD("My Type: %i Their Type: %i", Item->m_ItemID, a_HeldItem.m_ItemID);
LOGD("My Count: %i Their Count: %i", Item->m_ItemCount, a_HeldItem.m_ItemCount);
LOGD("My Dmg: %i Their Dmg: %i", Item->m_ItemHealth, a_HeldItem.m_ItemHealth);
bAsync = true;
}
}
if (m_DraggingItem && (a_ClickPacket->m_SlotNum > -1) && (a_ClickPacket->m_SlotNum < m_NumSlots))
if (m_DraggingItem && (a_SlotNum > -1) && (a_SlotNum < m_NumSlots))
{
if (a_ClickPacket->m_RightMouse == 0)
if (!a_IsRightClick)
{
if (!m_DraggingItem->Equals(m_Slots[a_ClickPacket->m_SlotNum]))
// Left-clicked
if (!m_DraggingItem->IsEqual(m_Slots[a_SlotNum]))
{
// Switch contents
cItem tmp(*m_DraggingItem);
*m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum];
m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents
*m_DraggingItem = m_Slots[a_SlotNum];
m_Slots[a_SlotNum] = tmp;
}
else
{
int FreeSlots = 64 - m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount;
int Filling = (FreeSlots > m_DraggingItem->m_ItemCount) ? m_DraggingItem->m_ItemCount : FreeSlots;
m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount += (char)Filling;
m_DraggingItem->m_ItemCount -= (char)Filling;
if( m_DraggingItem->m_ItemCount <= 0 )
m_DraggingItem->Empty();
}
}
else // Right clicked
{
if( m_DraggingItem->m_ItemID <= 0 ) // Empty?
{
m_DraggingItem->m_ItemCount = (char)(((float)m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount)/2.f + 0.5f);
m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount -= m_DraggingItem->m_ItemCount;
m_DraggingItem->m_ItemID = m_Slots[a_ClickPacket->m_SlotNum].m_ItemID;
m_DraggingItem->m_ItemHealth = m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth;
if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount <= 0 )
// Same type, add items:
cItemHandler * Handler = ItemHandler(m_DraggingItem->m_ItemID);
int FreeSlots = Handler->GetMaxStackSize() - m_Slots[a_SlotNum].m_ItemCount;
if (FreeSlots < 0)
{
m_Slots[a_ClickPacket->m_SlotNum].Empty();
ASSERT(!"Bad item stack size - where did we get more items in a slot than allowed?");
FreeSlots = 0;
}
int Filling = (FreeSlots > m_DraggingItem->m_ItemCount) ? m_DraggingItem->m_ItemCount : FreeSlots;
m_Slots[a_SlotNum].m_ItemCount += (char)Filling;
m_DraggingItem->m_ItemCount -= (char)Filling;
if (m_DraggingItem->m_ItemCount <= 0)
{
m_DraggingItem->Empty();
}
}
else if( m_Slots[a_ClickPacket->m_SlotNum].m_ItemID <= 0 || m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum] ) )
{ // Drop one item in slot
if( m_DraggingItem->m_ItemCount > 0 && m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount < 64 )
}
else
{
// Right clicked
if (m_DraggingItem->m_ItemID <= 0) // Empty-handed?
{
m_DraggingItem->m_ItemCount = (char)(((float)m_Slots[a_SlotNum].m_ItemCount) / 2.f + 0.5f);
m_Slots[a_SlotNum].m_ItemCount -= m_DraggingItem->m_ItemCount;
m_DraggingItem->m_ItemID = m_Slots[a_SlotNum].m_ItemID;
m_DraggingItem->m_ItemHealth = m_Slots[a_SlotNum].m_ItemHealth;
if (m_Slots[a_SlotNum].m_ItemCount <= 0)
{
m_Slots[a_ClickPacket->m_SlotNum].m_ItemID = m_DraggingItem->m_ItemID;
m_Slots[a_ClickPacket->m_SlotNum].m_ItemCount++;
m_Slots[a_ClickPacket->m_SlotNum].m_ItemHealth = m_DraggingItem->m_ItemHealth;
m_Slots[a_SlotNum].Empty();
}
}
else if ((m_Slots[a_SlotNum].m_ItemID <= 0) || m_DraggingItem->IsEqual(m_Slots[a_SlotNum]))
{
// Drop one item in slot
cItemHandler * Handler = ItemHandler(m_Slots[a_SlotNum].m_ItemID);
if ((m_DraggingItem->m_ItemCount > 0) && (m_Slots[a_SlotNum].m_ItemCount < Handler->GetMaxStackSize()))
{
m_Slots[a_SlotNum].m_ItemID = m_DraggingItem->m_ItemID;
m_Slots[a_SlotNum].m_ItemCount++;
m_Slots[a_SlotNum].m_ItemHealth = m_DraggingItem->m_ItemHealth;
m_DraggingItem->m_ItemCount--;
}
if( m_DraggingItem->m_ItemCount <= 0 )
if (m_DraggingItem->m_ItemCount <= 0)
{
m_DraggingItem->Empty();
}
}
else if( !m_DraggingItem->Equals( m_Slots[a_ClickPacket->m_SlotNum]) ) // Swap contents
else if (!m_DraggingItem->IsEqual(m_Slots[a_SlotNum]))
{
// Swap contents
cItem tmp( *m_DraggingItem );
*m_DraggingItem = m_Slots[a_ClickPacket->m_SlotNum];
m_Slots[a_ClickPacket->m_SlotNum] = tmp; // Switch contents
*m_DraggingItem = m_Slots[a_SlotNum];
m_Slots[a_SlotNum] = tmp;
}
}
if( bAsync )
if (bAsync)
{
LOG("Window is not synchonous with client. Sending whole window. ID: %i", m_WindowID);
for( std::list< cPlayer* >::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr )
// TODO: Handle this thread-safely (m_OpenedBy may change by another cSocketThread
for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr)
{
SendWholeWindow( (*itr)->GetClientHandle() );
SendWholeWindow((*itr)->GetClientHandle());
}
if( m_bInventoryVisible || m_OpenedBy.size() == 0 )
if (m_bInventoryVisible || m_OpenedBy.empty())
{
a_Player.GetInventory().SendWholeInventory( a_Player.GetClientHandle() );
}
}
}
else if( m_bInventoryVisible ) // Click in player inventory
else if (m_bInventoryVisible) // Click in player inventory
{
a_ClickPacket->m_WindowID = 0;
a_ClickPacket->m_SlotNum -= (short)(m_NumSlots - 9);
cWindow* Window = a_Player.GetInventory().GetWindow();
if( Window )
cWindow * Window = a_Player.GetInventory().GetWindow();
if (Window)
{
Window->Clicked( a_ClickPacket, a_Player );
Window->Clicked(a_Player, a_WindowID, a_SlotNum - 9, a_IsRightClick, a_IsShiftPressed, a_HeldItem);
}
}
if (m_DraggingItem != NULL)

View File

@ -10,12 +10,11 @@
#pragma once
class cPacket_WindowClick;
class cPlayer;
class cItem;
class cWindowOwner;
class cClientHandle;
class cPacket;
class cPacket; // TODO: remove this
typedef std::list<cPlayer *> cPlayerList;
@ -63,7 +62,11 @@ public:
bool IsInventoryVisible() { return m_bInventoryVisible; }
void SetInventoryVisible( bool a_bVisible ) { m_bInventoryVisible = a_bVisible; }
virtual void Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player );
virtual void Clicked(
cPlayer & a_Player, int a_WindowID,
short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed,
const cItem & a_HeldItem
);
virtual void Open( cPlayer & a_Player );
virtual void Close( cPlayer & a_Player );
@ -71,7 +74,7 @@ public:
cWindowOwner* GetOwner() { return m_Owner; }
void SetOwner( cWindowOwner* a_Owner ) { m_Owner = a_Owner; }
void SendWholeWindow( cClientHandle* a_Client );
void SendWholeWindow(cClientHandle * a_Client);
void BroadcastWholeWindow(void);
void Broadcast(const cPacket & a_Packet);

View File

@ -19,7 +19,7 @@ class cItemHandler
public:
cItemHandler(int a_ItemID);
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir); //eg for fishing or hoes
virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir);
virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * a_HeldItem, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace);
virtual void OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z);
virtual void OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item);

View File

@ -1,31 +1,37 @@
#pragma once
#include "cPacket.h"
class cPacket_BlockDig : public cPacket //tolua_export
{ //tolua_export
class cPacket_BlockDig :
public cPacket
{
public:
cPacket_BlockDig() //tolua_export
cPacket_BlockDig()
: m_Status( 0 )
, m_PosX( 0 )
, m_PosY( 0 )
, m_PosZ( 0 )
, m_Direction( 0 )
{ m_PacketID = E_BLOCK_DIG; } //tolua_export
virtual cPacket* Clone() const { return new cPacket_BlockDig(*this); } //tolua_export
{
m_PacketID = E_BLOCK_DIG;
}
virtual cPacket* Clone() const { return new cPacket_BlockDig(*this); }
virtual int Parse(cByteBuffer & a_Buffer) override;
virtual void Serialize(AString & a_Data) const override;
char m_Status; // tolua_export
int m_PosX; // tolua_export
char m_PosY; // tolua_export
int m_PosZ; // tolua_export
char m_Direction; // tolua_export
static const unsigned int c_Size = 12;
}; //tolua_export
char m_Status;
int m_PosX;
char m_PosY;
int m_PosZ;
char m_Direction;
};

View File

@ -16,18 +16,13 @@ int cPacket_BlockPlace::Parse(cByteBuffer & a_Buffer)
HANDLE_PACKET_READ(ReadBEInt, m_PosZ, TotalBytes);
HANDLE_PACKET_READ(ReadChar, m_Direction, TotalBytes);
cPacket_ItemData Item;
cPacket_ItemData Item(m_HeldItem);
int res = Item.Parse(a_Buffer);
if (res < 0)
{
return res;
}
TotalBytes += res;
m_ItemType = Item.m_ItemID;
m_Count = Item.m_ItemCount;
m_Uses = Item.m_ItemUses;
return TotalBytes;
}

View File

@ -2,38 +2,36 @@
#pragma once
#include "cPacket.h"
#include "../cItem.h"
class cPacket_BlockPlace : public cPacket //tolua_export
{ //tolua_export
class cPacket_BlockPlace :
public cPacket
{
public:
cPacket_BlockPlace()
: m_PosX( 0 )
, m_PosY( 0 )
, m_PosZ( 0 )
, m_Direction( 0 )
, m_ItemType( 0 )
, m_Count( 0 )
, m_Uses( 0 )
{ m_PacketID = E_BLOCK_PLACE; }
{
m_PacketID = E_BLOCK_PLACE;
}
virtual cPacket* Clone() const { return new cPacket_BlockPlace(*this); }
virtual int Parse(cByteBuffer & a_Buffer) override;
int m_PosX; //tolua_export
unsigned char m_PosY; //tolua_export
int m_PosZ; //tolua_export
char m_Direction; //tolua_export
int m_PosX;
unsigned char m_PosY;
int m_PosZ;
char m_Direction;
short m_ItemType; //tolua_export
char m_Count; //tolua_export
short m_Uses; //tolua_export
static const unsigned int c_Size = 1 + 4 + 1 + 4 + 1 + 2;// ( + 2 )
}; //tolua_export
cItem m_HeldItem;
} ;

View File

@ -10,11 +10,9 @@
cPacket_CreativeInventoryAction::cPacket_CreativeInventoryAction( const cPacket_CreativeInventoryAction & a_Copy )
{
m_PacketID = E_CREATIVE_INVENTORY_ACTION;
m_Slot = a_Copy.m_Slot;
m_ItemID = a_Copy.m_ItemID;
m_Quantity = a_Copy.m_Quantity;
m_Damage = a_Copy.m_Damage;
m_PacketID = E_CREATIVE_INVENTORY_ACTION;
m_SlotNum = a_Copy.m_SlotNum;
m_ClickedItem = a_Copy.m_ClickedItem;
}
@ -24,20 +22,15 @@ cPacket_CreativeInventoryAction::cPacket_CreativeInventoryAction( const cPacket_
int cPacket_CreativeInventoryAction::Parse(cByteBuffer & a_Buffer)
{
int TotalBytes = 0;
HANDLE_PACKET_READ(ReadBEShort, m_Slot, TotalBytes);
HANDLE_PACKET_READ(ReadBEShort, m_SlotNum, TotalBytes);
cPacket_ItemData Item;
cPacket_ItemData Item(m_ClickedItem);
int res = Item.Parse(a_Buffer);
if (res < 0)
{
return res;
}
TotalBytes += res;
m_ItemID = Item.m_ItemID;
m_Quantity = Item.m_ItemCount;
m_Damage = Item.m_ItemUses;
return TotalBytes;
}
@ -47,19 +40,10 @@ int cPacket_CreativeInventoryAction::Parse(cByteBuffer & a_Buffer)
void cPacket_CreativeInventoryAction::Serialize(AString & a_Data) const
{
short ItemID = m_ItemID;
ASSERT(ItemID >= -1); // Check validity of packets in debug runtime
if (ItemID <= 0)
{
ItemID = -1;
// Fix, to make sure no invalid values are sent.
// WARNING: HERE ITS -1, BUT IN NAMED ENTITY SPAWN PACKET ITS 0 !!
}
AppendByte (a_Data, m_PacketID);
AppendShort(a_Data, m_SlotNum);
AppendByte (a_Data, m_PacketID);
AppendShort (a_Data, m_Slot);
cPacket_ItemData::AppendItem(a_Data, ItemID, m_Quantity, m_Damage);
cPacket_ItemData::AppendItem(a_Data, m_ClickedItem);
}

View File

@ -2,35 +2,31 @@
#pragma once
#include "cPacket.h"
#include "../cItem.h"
//Sure it´s not Creative Inventory?
class cPacket_CreativeInventoryAction : public cPacket
class cPacket_CreativeInventoryAction :
public cPacket
{
public:
cPacket_CreativeInventoryAction()
: m_Slot( 0 )
, m_ItemID( 0 )
, m_Quantity( 0 )
, m_Damage( 0 )
{ m_PacketID = E_CREATIVE_INVENTORY_ACTION; m_Quantity = 1; }
cPacket_CreativeInventoryAction() :
m_SlotNum(0)
{
m_PacketID = E_CREATIVE_INVENTORY_ACTION;
}
cPacket_CreativeInventoryAction( const cPacket_CreativeInventoryAction & a_Copy );
virtual cPacket* Clone() const { return new cPacket_CreativeInventoryAction(*this); }
virtual int Parse(cByteBuffer & a_Buffer) override;
virtual void Serialize(AString & a_Data) const override;
short m_Slot; // 0 = hold 1-4 = armor
short m_ItemID;
char m_Quantity; //Byte not short ;)
short m_Damage;
static const unsigned int c_Size = 1 + 2;
};
short m_SlotNum;
cItem m_ClickedItem;
} ;

View File

@ -17,7 +17,6 @@ public:
virtual void Serialize(AString & a_Data) const override;
std::string m_Username;
static const unsigned int c_Size = 3; // Minimal size
};

View File

@ -10,25 +10,26 @@
int cPacket_ItemData::Parse(cByteBuffer & a_Buffer)
{
int TotalBytes = 0;
HANDLE_PACKET_READ(ReadBEShort, m_ItemID, TotalBytes);
HANDLE_PACKET_READ(ReadBEShort, m_Dst.m_ItemType, TotalBytes);
if (m_ItemID <= -1)
if (m_Dst.m_ItemType <= -1)
{
m_ItemCount = 0;
m_ItemUses = 0;
m_Dst.Empty();
return TotalBytes;
}
HANDLE_PACKET_READ(ReadChar, m_ItemCount, TotalBytes);
HANDLE_PACKET_READ(ReadBEShort, m_ItemUses, TotalBytes);
HANDLE_PACKET_READ(ReadChar, m_Dst.m_ItemCount, TotalBytes);
HANDLE_PACKET_READ(ReadBEShort, m_Dst.m_ItemDamage, TotalBytes);
if (cItem::IsEnchantable((ENUM_ITEM_ID) m_ItemID))
if (cItem::IsEnchantable(m_Dst.m_ItemType))
{
HANDLE_PACKET_READ(ReadBEShort, m_EnchantNums, TotalBytes);
short EnchantNumBytes;
HANDLE_PACKET_READ(ReadBEShort, EnchantNumBytes, TotalBytes);
if ( m_EnchantNums > -1 )
if (EnchantNumBytes > 0)
{
// TODO: Enchantment not implemented yet!
a_Buffer.SkipRead(EnchantNumBytes);
}
}
return TotalBytes;
@ -51,24 +52,32 @@ int cPacket_ItemData::GetSize(short a_ItemID)
void cPacket_ItemData::AppendItem(AString & a_Data, const cItem * a_Item)
void cPacket_ItemData::AppendItem(AString & a_Data, const cItem & a_Item)
{
return AppendItem(a_Data, a_Item->m_ItemID, a_Item->m_ItemCount, a_Item->m_ItemHealth);
return AppendItem(a_Data, a_Item.m_ItemType, a_Item.m_ItemCount, a_Item.m_ItemDamage);
}
void cPacket_ItemData::AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage)
void cPacket_ItemData::AppendItem(AString & a_Data, short a_ItemType, char a_Quantity, short a_Damage)
{
AppendShort(a_Data, (short) a_ItemID);
if (a_ItemID > -1)
short ItemType = a_ItemType;
ASSERT(ItemType >= -1); // Check validity of packets in debug runtime
if (ItemType <= 0)
{
// Fix, to make sure no invalid values are sent.
ItemType = -1;
}
AppendShort(a_Data, ItemType);
if (a_ItemType > -1)
{
AppendByte (a_Data, a_Quantity);
AppendShort(a_Data, a_Damage);
if (cItem::IsEnchantable((ENUM_ITEM_ID) a_ItemID))
if (cItem::IsEnchantable(a_ItemType))
{
// TODO: Implement enchantments
AppendShort(a_Data, (short) -1);

View File

@ -1,35 +1,34 @@
#pragma once
#include "cPacket.h"
#include "../cItem.h"
class cPacket_ItemData : public cPacket
{
cItem & m_Dst;
public:
cPacket_ItemData()
: m_ItemID( 0 )
, m_ItemCount( 0 )
, m_ItemUses( 0 )
, m_EnchantNums(-1)
cPacket_ItemData(cItem & a_Dst) :
m_Dst(a_Dst)
{
}
virtual cPacket* Clone() const { return new cPacket_ItemData(*this); }
virtual cPacket * Clone() const { return new cPacket_ItemData(*this); }
virtual int Parse(cByteBuffer & a_Buffer) override;
static void AppendItem(AString & a_Data, short a_ItemID, char a_Quantity, short a_Damage);
static void AppendItem(AString & a_Data, const cItem * a_Item);
static void AppendItem(AString & a_Data, short a_ItemType, char a_Quantity, short a_Damage);
static void AppendItem(AString & a_Data, const cItem & a_Item);
int GetSize(short a_ItemID);
} ;
// Below = item
short m_ItemID; // if this is -1 the next stuff dont exist
char m_ItemCount;
short m_ItemUses;
short m_EnchantNums;
static unsigned int c_Size; // Minimal size ( +1+1 = max)
};

View File

@ -7,8 +7,8 @@
const std::string cPacket_Login::LEVEL_TYPE_DEFAULT = "DEFAULT";
const std::string cPacket_Login::LEVEL_TYPE_SUPERFLAT = "SUPERFLAT";
const char * cPacket_Login::LEVEL_TYPE_DEFAULT = "DEFAULT";
const char * cPacket_Login::LEVEL_TYPE_SUPERFLAT = "SUPERFLAT";
@ -16,7 +16,6 @@ const std::string cPacket_Login::LEVEL_TYPE_SUPERFLAT = "SUPERFLAT";
int cPacket_Login::Parse(cByteBuffer & a_Buffer)
{
//printf("Parse: NEW Login\n");
int TotalBytes = 0;
m_Username.clear();
HANDLE_PACKET_READ(ReadBEInt, m_ProtocolVersion, TotalBytes);

View File

@ -7,8 +7,8 @@
class cPacket_Login : public cPacket //tolua_export
{ //tolua_export
class cPacket_Login : public cPacket
{
public:
cPacket_Login()
: m_ProtocolVersion( 0 )
@ -24,18 +24,18 @@ public:
virtual int Parse(cByteBuffer & a_Buffer) override;
virtual void Serialize(AString & a_Data) const override;
int m_ProtocolVersion; //tolua_export
AString m_Username; //tolua_export
AString m_LevelType; //tolua_export
int m_ServerMode; //tolua_export
int m_Dimension;
char m_Difficulty; //tolua_export
unsigned char m_WorldHeight; //tolua_export
unsigned char m_MaxPlayers; //tolua_export
int m_ProtocolVersion;
AString m_Username;
AString m_LevelType;
int m_ServerMode;
int m_Dimension;
char m_Difficulty;
unsigned char m_WorldHeight;
unsigned char m_MaxPlayers;
static const AString LEVEL_TYPE_DEFAULT;
static const AString LEVEL_TYPE_SUPERFLAT;
}; //tolua_export
static const char * LEVEL_TYPE_DEFAULT;
static const char * LEVEL_TYPE_SUPERFLAT;
};

View File

@ -195,15 +195,15 @@ void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cPacket_PlayerPosition:
cPacket_PlayerPosition::cPacket_PlayerPosition( cPlayer* a_Player )
cPacket_PlayerPosition::cPacket_PlayerPosition(cPlayer * a_Player)
{
m_PacketID = E_PLAYERPOS;
m_PosX = a_Player->GetPosX();
m_PosY = a_Player->GetPosY() + 1.65;
m_PosZ = a_Player->GetPosZ();
m_Stance = a_Player->GetStance();
m_bFlying = a_Player->GetFlying();
m_PosX = a_Player->GetPosX();
m_PosY = a_Player->GetPosY() + 1.65;
m_PosZ = a_Player->GetPosZ();
m_Stance = a_Player->GetStance();
m_IsOnGround = a_Player->IsOnGround();
}
@ -213,11 +213,11 @@ cPacket_PlayerPosition::cPacket_PlayerPosition( cPlayer* a_Player )
int cPacket_PlayerPosition::Parse(cByteBuffer & a_Buffer)
{
int TotalBytes = 0;
HANDLE_PACKET_READ(ReadBEDouble, m_PosX, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_PosY, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_Stance, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_PosZ, TotalBytes);
HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_PosX, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_PosY, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_Stance, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_PosZ, TotalBytes);
HANDLE_PACKET_READ(ReadBool, m_IsOnGround, TotalBytes);
return TotalBytes;
}
@ -232,7 +232,7 @@ void cPacket_PlayerPosition::Serialize(AString & a_Data) const
AppendDouble (a_Data, m_PosY);
AppendDouble (a_Data, m_Stance);
AppendDouble (a_Data, m_PosZ);
AppendBool (a_Data, m_bFlying);
AppendBool (a_Data, m_IsOnGround);
}

View File

@ -129,9 +129,9 @@ public:
cPacket_PlayerPosition()
: m_PosX( 0.0 )
, m_PosY( 0.0 )
, m_Stance( 0.0 )
, m_PosZ( 0.0 )
, m_bFlying( false )
, m_Stance( 0.0 )
, m_IsOnGround(true)
{ m_PacketID = E_PLAYERPOS; }
virtual cPacket* Clone() const { return new cPacket_PlayerPosition(*this); }
@ -140,9 +140,9 @@ public:
double m_PosX;
double m_PosY;
double m_Stance;
double m_PosZ;
bool m_bFlying; // Yeah.. wtf
double m_Stance;
bool m_IsOnGround;
} ;

View File

@ -17,19 +17,21 @@ cPacket_WholeInventory::cPacket_WholeInventory( const cPacket_WholeInventory & a
m_WindowID = a_Clone.m_WindowID;
m_Count = a_Clone.m_Count;
m_Items = new cItem[m_Count];
memcpy( m_Items, a_Clone.m_Items, sizeof(cItem)*m_Count );
// TODO: copy items one by one, they may have some values that needn't be shallow-copiable
memcpy(m_Items, a_Clone.m_Items, sizeof(cItem) * m_Count);
}
cPacket_WholeInventory::cPacket_WholeInventory( cInventory* a_Inventory )
cPacket_WholeInventory::cPacket_WholeInventory(cInventory * a_Inventory)
{
m_PacketID = E_INVENTORY_WHOLE;
m_WindowID = 0;
m_Count = a_Inventory->c_NumSlots;
m_Items = new cItem[m_Count];
// TODO: copy items one by one, they may have some values that needn't be shallow-copiable
memcpy( m_Items, a_Inventory->GetSlots(), sizeof(cItem)*m_Count );
}
@ -37,13 +39,14 @@ cPacket_WholeInventory::cPacket_WholeInventory( cInventory* a_Inventory )
cPacket_WholeInventory::cPacket_WholeInventory( cWindow* a_Window )
cPacket_WholeInventory::cPacket_WholeInventory(cWindow * a_Window)
{
m_PacketID = E_INVENTORY_WHOLE;
m_WindowID = (char)a_Window->GetWindowID();
m_Count = (short)a_Window->GetNumSlots();
m_Items = new cItem[m_Count];
memcpy( m_Items, a_Window->GetSlots(), sizeof(cItem)*m_Count );
// TODO: copy items one by one, they may have some values that needn't be shallow-copiable
memcpy( m_Items, a_Window->GetSlots(), sizeof(cItem) * m_Count);
}
@ -67,7 +70,7 @@ void cPacket_WholeInventory::Serialize(AString & a_Data) const
for (int j = 0; j < m_Count; j++)
{
cPacket_ItemData::AppendItem(a_Data, &(m_Items[j]));
cPacket_ItemData::AppendItem(a_Data, m_Items[j]);
}
}

View File

@ -14,11 +14,11 @@ int cPacket_WindowClick::Parse(cByteBuffer & a_Buffer)
int TotalBytes = 0;
HANDLE_PACKET_READ(ReadChar, m_WindowID, TotalBytes);
HANDLE_PACKET_READ(ReadBEShort, m_SlotNum, TotalBytes);
HANDLE_PACKET_READ(ReadChar, m_RightMouse, TotalBytes);
HANDLE_PACKET_READ(ReadBEShort, m_NumClicks, TotalBytes);
HANDLE_PACKET_READ(ReadBool, m_IsRightClick, TotalBytes);
HANDLE_PACKET_READ(ReadBEShort, m_TransactionID, TotalBytes);
HANDLE_PACKET_READ(ReadBool, m_IsShiftPressed, TotalBytes);
cPacket_ItemData Item;
cPacket_ItemData Item(m_HeldItem);
int res = Item.Parse(a_Buffer);
if (res < 0)
{
@ -26,12 +26,6 @@ int cPacket_WindowClick::Parse(cByteBuffer & a_Buffer)
}
TotalBytes += res;
m_ItemID = Item.m_ItemID;
m_ItemCount = Item.m_ItemCount;
m_ItemUses = Item.m_ItemUses;
m_EnchantNums = Item.m_EnchantNums;
return TotalBytes;
}

View File

@ -2,6 +2,7 @@
#pragma once
#include "cPacket.h"
#include "../cItem.h"
@ -13,36 +14,24 @@ public:
cPacket_WindowClick()
: m_WindowID( 0 )
, m_SlotNum( 0 )
, m_RightMouse( 0 )
, m_NumClicks( 0 )
, m_IsRightClick(false)
, m_TransactionID( 0 )
, m_IsShiftPressed( false )
, m_ItemID( 0 )
, m_ItemCount( 0 )
, m_ItemUses( 0 )
, m_EnchantNums(-1)
{ m_PacketID = E_WINDOW_CLICK; }
{
m_PacketID = E_WINDOW_CLICK;
}
virtual cPacket* Clone() const { return new cPacket_WindowClick(*this); }
virtual int Parse(cByteBuffer & a_Buffer) override;
char m_WindowID;
short m_SlotNum; // Slot
// 0 = craft result
// 1-4 = crafting table
// 5-8 = armor
// 9-35 = inventory
// 36-44 = Hot bar
char m_RightMouse; // 0 = Left 1 = Right mb
short m_NumClicks; // Num clicks
short m_SlotNum;
bool m_IsRightClick;
short m_TransactionID;
bool m_IsShiftPressed; // Shift pressed when clicked?
// Below = item
short m_ItemID; // if this is -1 the next stuff dont exist
char m_ItemCount;
short m_ItemUses;
short m_EnchantNums;
cItem m_HeldItem;
};