mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-15 20:51:29 +00:00
Merge git://github.com/EQEmu/Server into Development
This commit is contained in:
commit
9f3a0a3f95
@ -289,6 +289,7 @@ ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG})
|
|||||||
ADD_DEFINITIONS(-DLOG_LEVEL_QUEST=${EQEMU_LOG_LEVEL_QUEST})
|
ADD_DEFINITIONS(-DLOG_LEVEL_QUEST=${EQEMU_LOG_LEVEL_QUEST})
|
||||||
ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS})
|
ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS})
|
||||||
ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH})
|
ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH})
|
||||||
|
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
||||||
|
|
||||||
IF(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
|
IF(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
|
||||||
ADD_DEFINITIONS(-DRETRANSMIT_ACKED_PACKETS=true)
|
ADD_DEFINITIONS(-DRETRANSMIT_ACKED_PACKETS=true)
|
||||||
|
|||||||
@ -387,3 +387,26 @@ float EQHtoFloat(int d)
|
|||||||
{
|
{
|
||||||
return(360.0f - float((d * 360) >> 11));
|
return(360.0f - float((d * 360) >> 11));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns a swapped-bit value for use in client translator and inventory functions
|
||||||
|
uint32 SwapBits21and22(uint32 mask)
|
||||||
|
{
|
||||||
|
static const uint32 BIT21 = 1 << 21;
|
||||||
|
static const uint32 BIT22 = 1 << 22;
|
||||||
|
static const uint32 SWAPBITS = (BIT21 | BIT22);
|
||||||
|
|
||||||
|
if ((bool)(mask & BIT21) != (bool)(mask & BIT22))
|
||||||
|
mask ^= SWAPBITS;
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns an unset bit 22 value for use in client translators
|
||||||
|
uint32 Catch22(uint32 mask)
|
||||||
|
{
|
||||||
|
static const uint32 KEEPBITS = ~(1 << 22);
|
||||||
|
|
||||||
|
mask &= KEEPBITS;
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|||||||
@ -102,6 +102,8 @@ int FloatToEQ13(float d);
|
|||||||
int NewFloatToEQ13(float d);
|
int NewFloatToEQ13(float d);
|
||||||
int FloatToEQ19(float d);
|
int FloatToEQ19(float d);
|
||||||
int FloatToEQH(float d);
|
int FloatToEQH(float d);
|
||||||
|
uint32 SwapBits21and22(uint32 mask);
|
||||||
|
uint32 Catch22(uint32 mask);
|
||||||
|
|
||||||
// macro to catch fp errors (provided by noudness)
|
// macro to catch fp errors (provided by noudness)
|
||||||
#define FCMP(a,b) (fabs(a-b) < FLT_EPSILON)
|
#define FCMP(a,b) (fabs(a-b) < FLT_EPSILON)
|
||||||
|
|||||||
@ -131,22 +131,6 @@ static inline uint32 Client62ToServerCorpseSlot(uint32 Client62Corpse) {
|
|||||||
// reserved
|
// reserved
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
static inline uint32 RemovePowerSourceBit(uint32 slots) { // shouldn't need to add one..just grab the actual server reference, if so...
|
|
||||||
static const uint32 BIT21 = 1 << 21;
|
|
||||||
static const uint32 BIT22 = 1 << 22;
|
|
||||||
static const uint32 KEEPBITS = ~(BIT21 | BIT22);
|
|
||||||
|
|
||||||
bool wearammo = slots & BIT22;
|
|
||||||
|
|
||||||
slots &= KEEPBITS;
|
|
||||||
|
|
||||||
if (wearammo)
|
|
||||||
slots |= BIT21;
|
|
||||||
|
|
||||||
return slots;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
EAT_ENCODE(OP_ZoneServerReady)
|
EAT_ENCODE(OP_ZoneServerReady)
|
||||||
|
|||||||
@ -1,36 +1,35 @@
|
|||||||
|
// out-going packets that require an ENCODE translation:
|
||||||
//list of packets we need to encode on the way out:
|
E(OP_Action)
|
||||||
|
E(OP_BazaarSearch)
|
||||||
|
E(OP_BecomeTrader)
|
||||||
|
E(OP_CharInventory)
|
||||||
|
E(OP_DeleteSpawn)
|
||||||
|
E(OP_GuildMemberLevelUpdate)
|
||||||
|
E(OP_GuildMemberList)
|
||||||
|
E(OP_Illusion)
|
||||||
|
E(OP_ItemLinkResponse)
|
||||||
|
E(OP_ItemPacket)
|
||||||
|
E(OP_LeadershipExpUpdate)
|
||||||
|
E(OP_NewSpawn)
|
||||||
|
E(OP_OnLevelMessage)
|
||||||
|
E(OP_PetBuffWindow)
|
||||||
|
E(OP_PlayerProfile)
|
||||||
|
E(OP_ReadBook)
|
||||||
|
E(OP_RespondAA)
|
||||||
E(OP_SendAATable)
|
E(OP_SendAATable)
|
||||||
E(OP_SendCharInfo)
|
E(OP_SendCharInfo)
|
||||||
E(OP_LeadershipExpUpdate)
|
|
||||||
E(OP_PlayerProfile)
|
|
||||||
E(OP_NewSpawn)
|
|
||||||
E(OP_ZoneSpawns)
|
|
||||||
E(OP_ZoneEntry)
|
|
||||||
E(OP_ItemPacket)
|
|
||||||
E(OP_ItemLinkResponse)
|
|
||||||
E(OP_CharInventory)
|
|
||||||
E(OP_GuildMemberList)
|
|
||||||
E(OP_ZoneServerReady)
|
|
||||||
E(OP_GuildMemberLevelUpdate)
|
|
||||||
E(OP_ReadBook)
|
|
||||||
E(OP_Illusion)
|
|
||||||
E(OP_Track)
|
E(OP_Track)
|
||||||
E(OP_BazaarSearch)
|
|
||||||
E(OP_RespondAA)
|
|
||||||
E(OP_DeleteSpawn)
|
|
||||||
E(OP_WearChange)
|
E(OP_WearChange)
|
||||||
E(OP_Action)
|
E(OP_ZoneEntry)
|
||||||
E(OP_BecomeTrader)
|
E(OP_ZoneServerReady)
|
||||||
E(OP_PetBuffWindow)
|
E(OP_ZoneSpawns)
|
||||||
E(OP_OnLevelMessage)
|
// incoming packets that require a DECODE translation:
|
||||||
//list of packets we need to decode on the way in:
|
|
||||||
D(OP_SetServerFilter)
|
|
||||||
D(OP_CharacterCreate)
|
D(OP_CharacterCreate)
|
||||||
D(OP_ItemLinkClick)
|
|
||||||
D(OP_WhoAllRequest)
|
|
||||||
D(OP_ReadBook)
|
|
||||||
D(OP_FaceChange)
|
D(OP_FaceChange)
|
||||||
|
D(OP_ItemLinkClick)
|
||||||
|
D(OP_ReadBook)
|
||||||
|
D(OP_SetServerFilter)
|
||||||
D(OP_WearChange)
|
D(OP_WearChange)
|
||||||
|
D(OP_WhoAllRequest)
|
||||||
#undef E
|
#undef E
|
||||||
#undef D
|
#undef D
|
||||||
|
|||||||
@ -1,162 +1,160 @@
|
|||||||
|
// out-going packets that require an ENCODE translation:
|
||||||
//list of packets we need to encode on the way out:
|
|
||||||
|
|
||||||
E(OP_SendCharInfo)
|
|
||||||
E(OP_ZoneServerInfo)
|
|
||||||
E(OP_SendAATable)
|
|
||||||
E(OP_PlayerProfile)
|
|
||||||
E(OP_ZoneEntry)
|
|
||||||
E(OP_CharInventory)
|
|
||||||
E(OP_NewZone)
|
|
||||||
E(OP_SpawnDoor)
|
|
||||||
E(OP_GroundSpawn)
|
|
||||||
E(OP_SendZonepoints)
|
|
||||||
E(OP_NewSpawn)
|
|
||||||
E(OP_ZoneSpawns)
|
|
||||||
E(OP_ItemLinkResponse)
|
|
||||||
E(OP_ItemPacket)
|
|
||||||
E(OP_GuildMemberList)
|
|
||||||
E(OP_Illusion)
|
|
||||||
E(OP_ManaChange)
|
|
||||||
E(OP_ClientUpdate)
|
|
||||||
E(OP_LeadershipExpUpdate)
|
|
||||||
E(OP_ExpansionInfo)
|
|
||||||
E(OP_LogServer)
|
|
||||||
E(OP_Damage)
|
|
||||||
E(OP_Buff)
|
|
||||||
E(OP_Action)
|
E(OP_Action)
|
||||||
E(OP_Consider)
|
|
||||||
E(OP_CancelTrade)
|
|
||||||
E(OP_ShopPlayerSell)
|
|
||||||
E(OP_DeleteItem)
|
|
||||||
E(OP_ItemVerifyReply)
|
|
||||||
E(OP_DeleteCharge)
|
|
||||||
E(OP_MoveItem)
|
|
||||||
//E(OP_OpenNewTasksWindow)
|
|
||||||
E(OP_BazaarSearch)
|
|
||||||
E(OP_Trader)
|
|
||||||
E(OP_TraderBuy)
|
|
||||||
E(OP_LootItem)
|
|
||||||
E(OP_TributeItem)
|
|
||||||
E(OP_SomeItemPacketMaybe)
|
|
||||||
E(OP_ReadBook)
|
|
||||||
E(OP_Stun)
|
|
||||||
E(OP_ZonePlayerToBind)
|
|
||||||
E(OP_AdventureMerchantSell)
|
E(OP_AdventureMerchantSell)
|
||||||
E(OP_RaidUpdate)
|
E(OP_AltCurrency)
|
||||||
E(OP_RaidJoin)
|
E(OP_AltCurrencySell)
|
||||||
E(OP_VetRewardsAvaliable)
|
E(OP_Animation)
|
||||||
E(OP_InspectRequest)
|
|
||||||
E(OP_GroupInvite)
|
|
||||||
E(OP_GroupFollow)
|
|
||||||
E(OP_GroupFollow2)
|
|
||||||
E(OP_GroupUpdate)
|
|
||||||
E(OP_GroupCancelInvite)
|
|
||||||
E(OP_WhoAllResponse)
|
|
||||||
E(OP_Track)
|
|
||||||
E(OP_ShopPlayerBuy)
|
|
||||||
E(OP_PetBuffWindow)
|
|
||||||
E(OP_OnLevelMessage)
|
|
||||||
E(OP_Barter)
|
|
||||||
E(OP_ApplyPoison)
|
E(OP_ApplyPoison)
|
||||||
|
E(OP_Barter)
|
||||||
|
E(OP_BazaarSearch)
|
||||||
|
E(OP_BeginCast)
|
||||||
|
E(OP_BlockedBuffs)
|
||||||
|
E(OP_Buff)
|
||||||
|
E(OP_BuffCreate)
|
||||||
|
E(OP_CancelTrade)
|
||||||
|
E(OP_CastSpell)
|
||||||
E(OP_ChannelMessage)
|
E(OP_ChannelMessage)
|
||||||
E(OP_GuildsList)
|
E(OP_CharInventory)
|
||||||
|
E(OP_ClickObjectAction)
|
||||||
|
E(OP_ClientUpdate)
|
||||||
|
E(OP_Consider)
|
||||||
|
E(OP_Damage)
|
||||||
|
E(OP_DeleteCharge)
|
||||||
|
E(OP_DeleteItem)
|
||||||
|
E(OP_DeleteSpawn)
|
||||||
|
E(OP_DisciplineUpdate)
|
||||||
|
E(OP_DzCompass)
|
||||||
E(OP_DzExpeditionEndsWarning)
|
E(OP_DzExpeditionEndsWarning)
|
||||||
E(OP_DzExpeditionInfo)
|
E(OP_DzExpeditionInfo)
|
||||||
E(OP_DzCompass)
|
|
||||||
E(OP_DzMemberList)
|
|
||||||
E(OP_DzExpeditionList)
|
E(OP_DzExpeditionList)
|
||||||
E(OP_DzLeaderStatus)
|
|
||||||
E(OP_DzJoinExpeditionConfirm)
|
E(OP_DzJoinExpeditionConfirm)
|
||||||
E(OP_TargetBuffs)
|
E(OP_DzLeaderStatus)
|
||||||
E(OP_BuffCreate)
|
E(OP_DzMemberList)
|
||||||
E(OP_SpawnAppearance)
|
E(OP_ExpansionInfo)
|
||||||
E(OP_RespondAA)
|
|
||||||
E(OP_DisciplineUpdate)
|
|
||||||
E(OP_AltCurrencySell)
|
|
||||||
E(OP_AltCurrency)
|
|
||||||
E(OP_RequestClientZoneChange)
|
|
||||||
E(OP_ZoneChange)
|
|
||||||
E(OP_WearChange)
|
|
||||||
E(OP_ShopRequest)
|
|
||||||
E(OP_CastSpell)
|
|
||||||
E(OP_InterruptCast)
|
|
||||||
E(OP_SendMembership)
|
|
||||||
E(OP_Animation)
|
|
||||||
E(OP_HPUpdate)
|
|
||||||
E(OP_BlockedBuffs)
|
|
||||||
E(OP_RemoveBlockedBuffs)
|
|
||||||
E(OP_DeleteSpawn)
|
|
||||||
E(OP_ClickObjectAction)
|
|
||||||
E(OP_RecipeAutoCombine)
|
|
||||||
E(OP_GMTrainSkillConfirm)
|
|
||||||
E(OP_SkillUpdate)
|
|
||||||
E(OP_TributeInfo)
|
|
||||||
E(OP_TaskHistoryReply)
|
|
||||||
E(OP_TaskDescription)
|
|
||||||
E(OP_SetGuildRank)
|
|
||||||
E(OP_MercenaryDataUpdate)
|
|
||||||
E(OP_MercenaryDataResponse)
|
|
||||||
E(OP_GuildMemberUpdate)
|
|
||||||
E(OP_GMLastName)
|
E(OP_GMLastName)
|
||||||
E(OP_BeginCast)
|
E(OP_GMTrainSkillConfirm)
|
||||||
|
E(OP_GroundSpawn)
|
||||||
|
E(OP_GroupCancelInvite)
|
||||||
|
E(OP_GroupFollow)
|
||||||
|
E(OP_GroupFollow2)
|
||||||
|
E(OP_GroupInvite)
|
||||||
|
E(OP_GroupUpdate)
|
||||||
|
E(OP_GuildMemberList)
|
||||||
|
E(OP_GuildMemberUpdate)
|
||||||
|
E(OP_GuildsList)
|
||||||
|
E(OP_HPUpdate)
|
||||||
|
E(OP_Illusion)
|
||||||
|
E(OP_InspectRequest)
|
||||||
|
E(OP_InterruptCast)
|
||||||
|
E(OP_ItemLinkResponse)
|
||||||
|
E(OP_ItemPacket)
|
||||||
|
E(OP_ItemVerifyReply)
|
||||||
|
E(OP_LeadershipExpUpdate)
|
||||||
|
E(OP_LogServer)
|
||||||
|
E(OP_LootItem)
|
||||||
|
E(OP_ManaChange)
|
||||||
|
E(OP_MercenaryDataResponse)
|
||||||
|
E(OP_MercenaryDataUpdate)
|
||||||
|
E(OP_MoveItem)
|
||||||
|
E(OP_NewSpawn)
|
||||||
|
E(OP_NewZone)
|
||||||
|
E(OP_OnLevelMessage)
|
||||||
|
//E(OP_OpenNewTasksWindow)
|
||||||
|
E(OP_PetBuffWindow)
|
||||||
|
E(OP_PlayerProfile)
|
||||||
|
E(OP_RaidJoin)
|
||||||
|
E(OP_RaidUpdate)
|
||||||
|
E(OP_ReadBook)
|
||||||
|
E(OP_RecipeAutoCombine)
|
||||||
|
E(OP_RemoveBlockedBuffs)
|
||||||
|
E(OP_RequestClientZoneChange)
|
||||||
|
E(OP_RespondAA)
|
||||||
E(OP_RezzRequest)
|
E(OP_RezzRequest)
|
||||||
//list of packets we need to decode on the way in:
|
E(OP_SendAATable)
|
||||||
D(OP_SetServerFilter)
|
E(OP_SendCharInfo)
|
||||||
D(OP_CharacterCreate)
|
E(OP_SendMembership)
|
||||||
D(OP_ItemLinkClick)
|
E(OP_SendZonepoints)
|
||||||
D(OP_ConsiderCorpse)
|
E(OP_SetGuildRank)
|
||||||
D(OP_Consider)
|
E(OP_ShopPlayerBuy)
|
||||||
D(OP_ClientUpdate)
|
E(OP_ShopPlayerSell)
|
||||||
D(OP_MoveItem)
|
E(OP_ShopRequest)
|
||||||
D(OP_WhoAllRequest)
|
E(OP_SkillUpdate)
|
||||||
|
E(OP_SomeItemPacketMaybe)
|
||||||
|
E(OP_SpawnAppearance)
|
||||||
|
E(OP_SpawnDoor)
|
||||||
|
E(OP_Stun)
|
||||||
|
E(OP_TargetBuffs)
|
||||||
|
E(OP_TaskDescription)
|
||||||
|
E(OP_TaskHistoryReply)
|
||||||
|
E(OP_Track)
|
||||||
|
E(OP_Trader)
|
||||||
|
E(OP_TraderBuy)
|
||||||
|
E(OP_TributeInfo)
|
||||||
|
E(OP_TributeItem)
|
||||||
|
E(OP_VetRewardsAvaliable)
|
||||||
|
E(OP_WearChange)
|
||||||
|
E(OP_WhoAllResponse)
|
||||||
|
E(OP_ZoneChange)
|
||||||
|
E(OP_ZoneEntry)
|
||||||
|
E(OP_ZonePlayerToBind)
|
||||||
|
E(OP_ZoneServerInfo)
|
||||||
|
E(OP_ZoneSpawns)
|
||||||
|
// incoming packets that require a DECODE translation:
|
||||||
|
D(OP_AdventureMerchantSell)
|
||||||
|
D(OP_AltCurrencySell)
|
||||||
|
D(OP_AltCurrencySellSelection)
|
||||||
|
D(OP_ApplyPoison)
|
||||||
|
D(OP_AugmentInfo)
|
||||||
|
D(OP_AugmentItem)
|
||||||
|
D(OP_BazaarSearch)
|
||||||
|
D(OP_BlockedBuffs)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_BuffRemoveRequest)
|
||||||
D(OP_Consume)
|
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_Save)
|
D(OP_ChannelMessage)
|
||||||
D(OP_ItemVerifyRequest)
|
D(OP_CharacterCreate)
|
||||||
D(OP_GroupInvite)
|
D(OP_ClientUpdate)
|
||||||
D(OP_GroupInvite2)
|
D(OP_Consider)
|
||||||
|
D(OP_ConsiderCorpse)
|
||||||
|
D(OP_Consume)
|
||||||
|
D(OP_Damage)
|
||||||
|
D(OP_DeleteItem)
|
||||||
|
D(OP_EnvDamage)
|
||||||
|
D(OP_FaceChange)
|
||||||
|
D(OP_FindPersonRequest)
|
||||||
|
D(OP_GMLastName)
|
||||||
|
D(OP_GroupCancelInvite)
|
||||||
|
D(OP_GroupDisband)
|
||||||
D(OP_GroupFollow)
|
D(OP_GroupFollow)
|
||||||
D(OP_GroupFollow2)
|
D(OP_GroupFollow2)
|
||||||
D(OP_GroupDisband)
|
D(OP_GroupInvite)
|
||||||
D(OP_GroupCancelInvite)
|
D(OP_GroupInvite2)
|
||||||
D(OP_FindPersonRequest)
|
|
||||||
D(OP_TraderBuy)
|
|
||||||
D(OP_LootItem)
|
|
||||||
D(OP_TributeItem)
|
|
||||||
D(OP_ReadBook)
|
|
||||||
D(OP_AugmentInfo)
|
|
||||||
D(OP_FaceChange)
|
|
||||||
D(OP_AdventureMerchantSell)
|
|
||||||
D(OP_TradeSkillCombine)
|
|
||||||
D(OP_RaidInvite)
|
|
||||||
D(OP_InspectRequest)
|
|
||||||
D(OP_ShopPlayerBuy)
|
|
||||||
D(OP_BazaarSearch)
|
|
||||||
D(OP_LoadSpellSet)
|
|
||||||
D(OP_ApplyPoison)
|
|
||||||
D(OP_Damage)
|
|
||||||
D(OP_EnvDamage)
|
|
||||||
D(OP_ChannelMessage)
|
|
||||||
D(OP_DeleteItem)
|
|
||||||
D(OP_AugmentItem)
|
|
||||||
D(OP_PetCommands)
|
|
||||||
D(OP_BuffRemoveRequest)
|
|
||||||
D(OP_AltCurrencySellSelection)
|
|
||||||
D(OP_AltCurrencySell)
|
|
||||||
D(OP_ZoneChange)
|
|
||||||
D(OP_ZoneEntry)
|
|
||||||
D(OP_ShopRequest)
|
|
||||||
D(OP_BlockedBuffs)
|
|
||||||
D(OP_RemoveBlockedBuffs)
|
|
||||||
D(OP_RecipeAutoCombine)
|
|
||||||
D(OP_GuildDemote)
|
D(OP_GuildDemote)
|
||||||
D(OP_GuildRemove)
|
D(OP_GuildRemove)
|
||||||
D(OP_GuildStatus)
|
D(OP_GuildStatus)
|
||||||
D(OP_Trader)
|
D(OP_InspectRequest)
|
||||||
D(OP_GMLastName)
|
D(OP_ItemLinkClick)
|
||||||
|
D(OP_ItemVerifyRequest)
|
||||||
|
D(OP_LoadSpellSet)
|
||||||
|
D(OP_LootItem)
|
||||||
|
D(OP_MoveItem)
|
||||||
|
D(OP_PetCommands)
|
||||||
|
D(OP_RaidInvite)
|
||||||
|
D(OP_ReadBook)
|
||||||
|
D(OP_RecipeAutoCombine)
|
||||||
|
D(OP_RemoveBlockedBuffs)
|
||||||
D(OP_RezzAnswer)
|
D(OP_RezzAnswer)
|
||||||
|
D(OP_Save)
|
||||||
|
D(OP_SetServerFilter)
|
||||||
|
D(OP_ShopPlayerBuy)
|
||||||
|
D(OP_ShopPlayerSell)
|
||||||
|
D(OP_ShopRequest)
|
||||||
|
D(OP_Trader)
|
||||||
|
D(OP_TraderBuy)
|
||||||
|
D(OP_TradeSkillCombine)
|
||||||
|
D(OP_TributeItem)
|
||||||
|
D(OP_WhoAllRequest)
|
||||||
|
D(OP_ZoneChange)
|
||||||
|
D(OP_ZoneEntry)
|
||||||
#undef E
|
#undef E
|
||||||
#undef D
|
#undef D
|
||||||
|
|||||||
@ -1,117 +1,115 @@
|
|||||||
|
// out-going packets that require an ENCODE translation:
|
||||||
//list of packets we need to encode on the way out:
|
|
||||||
|
|
||||||
E(OP_SendCharInfo)
|
|
||||||
E(OP_ZoneServerInfo)
|
|
||||||
E(OP_SendAATable)
|
|
||||||
E(OP_PlayerProfile)
|
|
||||||
E(OP_ZoneEntry)
|
|
||||||
E(OP_CharInventory)
|
|
||||||
E(OP_NewZone)
|
|
||||||
E(OP_SpawnDoor)
|
|
||||||
E(OP_GroundSpawn)
|
|
||||||
E(OP_SendZonepoints)
|
|
||||||
E(OP_NewSpawn)
|
|
||||||
E(OP_ZoneSpawns)
|
|
||||||
E(OP_ItemLinkResponse)
|
|
||||||
E(OP_ItemPacket)
|
|
||||||
E(OP_GuildMemberList)
|
|
||||||
E(OP_Illusion)
|
|
||||||
E(OP_ManaChange)
|
|
||||||
E(OP_ClientUpdate)
|
|
||||||
E(OP_LeadershipExpUpdate)
|
|
||||||
E(OP_ExpansionInfo)
|
|
||||||
E(OP_LogServer)
|
|
||||||
E(OP_Damage)
|
|
||||||
E(OP_Buff)
|
|
||||||
E(OP_Action)
|
E(OP_Action)
|
||||||
E(OP_Consider)
|
|
||||||
E(OP_CancelTrade)
|
|
||||||
E(OP_ShopPlayerSell)
|
|
||||||
E(OP_DeleteItem)
|
|
||||||
E(OP_ItemVerifyReply)
|
|
||||||
E(OP_DeleteCharge)
|
|
||||||
E(OP_MoveItem)
|
|
||||||
E(OP_OpenNewTasksWindow)
|
|
||||||
E(OP_BazaarSearch)
|
|
||||||
E(OP_Trader)
|
|
||||||
E(OP_TraderBuy)
|
|
||||||
E(OP_LootItem)
|
|
||||||
E(OP_TributeItem)
|
|
||||||
E(OP_SomeItemPacketMaybe)
|
|
||||||
E(OP_ReadBook)
|
|
||||||
E(OP_Stun)
|
|
||||||
E(OP_ZonePlayerToBind)
|
|
||||||
E(OP_AdventureMerchantSell)
|
E(OP_AdventureMerchantSell)
|
||||||
E(OP_RaidUpdate)
|
E(OP_AltCurrencySell)
|
||||||
E(OP_RaidJoin)
|
|
||||||
E(OP_VetRewardsAvaliable)
|
|
||||||
E(OP_InspectRequest)
|
|
||||||
E(OP_GroupInvite)
|
|
||||||
E(OP_GroupFollow)
|
|
||||||
E(OP_GroupFollow2)
|
|
||||||
E(OP_GroupUpdate)
|
|
||||||
E(OP_GroupCancelInvite)
|
|
||||||
E(OP_WhoAllResponse)
|
|
||||||
E(OP_Track)
|
|
||||||
E(OP_ShopPlayerBuy)
|
|
||||||
E(OP_PetBuffWindow)
|
|
||||||
E(OP_OnLevelMessage)
|
|
||||||
E(OP_Barter)
|
|
||||||
E(OP_ApplyPoison)
|
E(OP_ApplyPoison)
|
||||||
|
E(OP_Barter)
|
||||||
|
E(OP_BazaarSearch)
|
||||||
|
E(OP_Buff)
|
||||||
|
E(OP_CancelTrade)
|
||||||
|
E(OP_CharInventory)
|
||||||
|
E(OP_ClientUpdate)
|
||||||
|
E(OP_Consider)
|
||||||
|
E(OP_Damage)
|
||||||
|
E(OP_DeleteCharge)
|
||||||
|
E(OP_DeleteItem)
|
||||||
|
E(OP_DzCompass)
|
||||||
E(OP_DzExpeditionEndsWarning)
|
E(OP_DzExpeditionEndsWarning)
|
||||||
E(OP_DzExpeditionInfo)
|
E(OP_DzExpeditionInfo)
|
||||||
E(OP_DzCompass)
|
|
||||||
E(OP_DzMemberList)
|
|
||||||
E(OP_DzExpeditionList)
|
E(OP_DzExpeditionList)
|
||||||
E(OP_DzLeaderStatus)
|
|
||||||
E(OP_DzJoinExpeditionConfirm)
|
E(OP_DzJoinExpeditionConfirm)
|
||||||
E(OP_TargetBuffs)
|
E(OP_DzLeaderStatus)
|
||||||
E(OP_AltCurrencySell)
|
E(OP_DzMemberList)
|
||||||
E(OP_WearChange)
|
E(OP_ExpansionInfo)
|
||||||
|
E(OP_GroundSpawn)
|
||||||
|
E(OP_GroupCancelInvite)
|
||||||
|
E(OP_GroupFollow)
|
||||||
|
E(OP_GroupFollow2)
|
||||||
|
E(OP_GroupInvite)
|
||||||
|
E(OP_GroupUpdate)
|
||||||
|
E(OP_GuildMemberList)
|
||||||
|
E(OP_Illusion)
|
||||||
|
E(OP_InspectRequest)
|
||||||
|
E(OP_ItemLinkResponse)
|
||||||
|
E(OP_ItemPacket)
|
||||||
|
E(OP_ItemVerifyReply)
|
||||||
|
E(OP_LeadershipExpUpdate)
|
||||||
|
E(OP_LogServer)
|
||||||
|
E(OP_LootItem)
|
||||||
|
E(OP_ManaChange)
|
||||||
E(OP_MercenaryDataResponse)
|
E(OP_MercenaryDataResponse)
|
||||||
E(OP_MercenaryDataUpdate)
|
E(OP_MercenaryDataUpdate)
|
||||||
//list of packets we need to decode on the way in:
|
E(OP_MoveItem)
|
||||||
D(OP_SetServerFilter)
|
E(OP_NewSpawn)
|
||||||
D(OP_CharacterCreate)
|
E(OP_NewZone)
|
||||||
D(OP_ItemLinkClick)
|
E(OP_OnLevelMessage)
|
||||||
D(OP_ConsiderCorpse)
|
E(OP_OpenNewTasksWindow)
|
||||||
D(OP_Consider)
|
E(OP_PetBuffWindow)
|
||||||
D(OP_ClientUpdate)
|
E(OP_PlayerProfile)
|
||||||
D(OP_MoveItem)
|
E(OP_RaidJoin)
|
||||||
D(OP_WhoAllRequest)
|
E(OP_RaidUpdate)
|
||||||
|
E(OP_ReadBook)
|
||||||
|
E(OP_SendAATable)
|
||||||
|
E(OP_SendCharInfo)
|
||||||
|
E(OP_SendZonepoints)
|
||||||
|
E(OP_ShopPlayerBuy)
|
||||||
|
E(OP_ShopPlayerSell)
|
||||||
|
E(OP_SomeItemPacketMaybe)
|
||||||
|
E(OP_SpawnDoor)
|
||||||
|
E(OP_Stun)
|
||||||
|
E(OP_TargetBuffs)
|
||||||
|
E(OP_Track)
|
||||||
|
E(OP_Trader)
|
||||||
|
E(OP_TraderBuy)
|
||||||
|
E(OP_TributeItem)
|
||||||
|
E(OP_VetRewardsAvaliable)
|
||||||
|
E(OP_WearChange)
|
||||||
|
E(OP_WhoAllResponse)
|
||||||
|
E(OP_ZoneEntry)
|
||||||
|
E(OP_ZonePlayerToBind)
|
||||||
|
E(OP_ZoneServerInfo)
|
||||||
|
E(OP_ZoneSpawns)
|
||||||
|
// incoming packets that require a DECODE translation:
|
||||||
|
D(OP_AdventureMerchantSell)
|
||||||
|
D(OP_AltCurrencySell)
|
||||||
|
D(OP_AltCurrencySellSelection)
|
||||||
|
D(OP_ApplyPoison)
|
||||||
|
D(OP_AugmentInfo)
|
||||||
|
D(OP_AugmentItem)
|
||||||
|
D(OP_BazaarSearch)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_Bug)
|
||||||
D(OP_Consume)
|
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_Save)
|
D(OP_CharacterCreate)
|
||||||
D(OP_ItemVerifyRequest)
|
D(OP_ClientUpdate)
|
||||||
D(OP_GroupInvite)
|
D(OP_Consider)
|
||||||
D(OP_GroupInvite2)
|
D(OP_ConsiderCorpse)
|
||||||
|
D(OP_Consume)
|
||||||
|
D(OP_DeleteItem)
|
||||||
|
D(OP_FaceChange)
|
||||||
|
D(OP_FindPersonRequest)
|
||||||
|
D(OP_GroupCancelInvite)
|
||||||
|
D(OP_GroupDisband)
|
||||||
D(OP_GroupFollow)
|
D(OP_GroupFollow)
|
||||||
D(OP_GroupFollow2)
|
D(OP_GroupFollow2)
|
||||||
D(OP_GroupDisband)
|
D(OP_GroupInvite)
|
||||||
D(OP_GroupCancelInvite)
|
D(OP_GroupInvite2)
|
||||||
D(OP_FindPersonRequest)
|
|
||||||
D(OP_TraderBuy)
|
|
||||||
D(OP_LootItem)
|
|
||||||
D(OP_TributeItem)
|
|
||||||
D(OP_ReadBook)
|
|
||||||
D(OP_AugmentInfo)
|
|
||||||
D(OP_FaceChange)
|
|
||||||
D(OP_AdventureMerchantSell)
|
|
||||||
D(OP_TradeSkillCombine)
|
|
||||||
D(OP_RaidInvite)
|
|
||||||
D(OP_InspectRequest)
|
D(OP_InspectRequest)
|
||||||
D(OP_WearChange)
|
D(OP_ItemLinkClick)
|
||||||
D(OP_ShopPlayerBuy)
|
D(OP_ItemVerifyRequest)
|
||||||
D(OP_BazaarSearch)
|
|
||||||
D(OP_LoadSpellSet)
|
D(OP_LoadSpellSet)
|
||||||
D(OP_ApplyPoison)
|
D(OP_LootItem)
|
||||||
D(OP_DeleteItem)
|
D(OP_MoveItem)
|
||||||
D(OP_AugmentItem)
|
D(OP_RaidInvite)
|
||||||
D(OP_Bug)
|
D(OP_ReadBook)
|
||||||
D(OP_AltCurrencySellSelection)
|
D(OP_Save)
|
||||||
D(OP_AltCurrencySell)
|
D(OP_SetServerFilter)
|
||||||
|
D(OP_ShopPlayerBuy)
|
||||||
|
D(OP_ShopPlayerSell)
|
||||||
|
D(OP_TraderBuy)
|
||||||
|
D(OP_TradeSkillCombine)
|
||||||
|
D(OP_TributeItem)
|
||||||
|
D(OP_WearChange)
|
||||||
|
D(OP_WhoAllRequest)
|
||||||
#undef E
|
#undef E
|
||||||
#undef D
|
#undef D
|
||||||
|
|||||||
@ -1,100 +1,98 @@
|
|||||||
|
// out-going packets that require an ENCODE translation:
|
||||||
//list of packets we need to encode on the way out:
|
|
||||||
|
|
||||||
E(OP_SendCharInfo)
|
|
||||||
E(OP_ZoneServerInfo)
|
|
||||||
E(OP_SendAATable)
|
|
||||||
E(OP_PlayerProfile)
|
|
||||||
E(OP_ZoneEntry)
|
|
||||||
E(OP_CharInventory)
|
|
||||||
E(OP_NewZone)
|
|
||||||
E(OP_SpawnDoor)
|
|
||||||
E(OP_GroundSpawn)
|
|
||||||
E(OP_SendZonepoints)
|
|
||||||
E(OP_NewSpawn)
|
|
||||||
E(OP_ZoneSpawns)
|
|
||||||
E(OP_ItemLinkResponse)
|
|
||||||
E(OP_ItemPacket)
|
|
||||||
E(OP_GuildMemberList)
|
|
||||||
E(OP_Illusion)
|
|
||||||
E(OP_ManaChange)
|
|
||||||
E(OP_ClientUpdate)
|
|
||||||
E(OP_LeadershipExpUpdate)
|
|
||||||
E(OP_ExpansionInfo)
|
|
||||||
E(OP_LogServer)
|
|
||||||
E(OP_Damage)
|
|
||||||
E(OP_Buff)
|
|
||||||
E(OP_Action)
|
E(OP_Action)
|
||||||
E(OP_Consider)
|
|
||||||
E(OP_CancelTrade)
|
|
||||||
E(OP_ShopPlayerSell)
|
|
||||||
E(OP_DeleteItem)
|
|
||||||
E(OP_ItemVerifyReply)
|
|
||||||
E(OP_DeleteCharge)
|
|
||||||
E(OP_MoveItem)
|
|
||||||
E(OP_OpenNewTasksWindow)
|
|
||||||
E(OP_BazaarSearch)
|
|
||||||
E(OP_Trader)
|
|
||||||
E(OP_TraderBuy)
|
|
||||||
E(OP_LootItem)
|
|
||||||
E(OP_TributeItem)
|
|
||||||
E(OP_SomeItemPacketMaybe)
|
|
||||||
E(OP_ReadBook)
|
|
||||||
E(OP_Stun)
|
|
||||||
E(OP_ZonePlayerToBind)
|
|
||||||
E(OP_AdventureMerchantSell)
|
E(OP_AdventureMerchantSell)
|
||||||
E(OP_RaidUpdate)
|
E(OP_AltCurrencySell)
|
||||||
E(OP_RaidJoin)
|
|
||||||
E(OP_VetRewardsAvaliable)
|
|
||||||
E(OP_InspectRequest)
|
|
||||||
E(OP_Track)
|
|
||||||
E(OP_DeleteSpawn)
|
|
||||||
E(OP_ApplyPoison)
|
E(OP_ApplyPoison)
|
||||||
|
E(OP_BazaarSearch)
|
||||||
|
E(OP_BecomeTrader)
|
||||||
|
E(OP_Buff)
|
||||||
|
E(OP_CancelTrade)
|
||||||
|
E(OP_CharInventory)
|
||||||
|
E(OP_ClientUpdate)
|
||||||
|
E(OP_Consider)
|
||||||
|
E(OP_Damage)
|
||||||
|
E(OP_DeleteCharge)
|
||||||
|
E(OP_DeleteItem)
|
||||||
|
E(OP_DeleteSpawn)
|
||||||
|
E(OP_DzCompass)
|
||||||
E(OP_DzExpeditionEndsWarning)
|
E(OP_DzExpeditionEndsWarning)
|
||||||
E(OP_DzExpeditionInfo)
|
E(OP_DzExpeditionInfo)
|
||||||
E(OP_DzCompass)
|
|
||||||
E(OP_DzMemberList)
|
|
||||||
E(OP_DzExpeditionList)
|
E(OP_DzExpeditionList)
|
||||||
E(OP_DzLeaderStatus)
|
|
||||||
E(OP_DzJoinExpeditionConfirm)
|
E(OP_DzJoinExpeditionConfirm)
|
||||||
E(OP_BecomeTrader)
|
E(OP_DzLeaderStatus)
|
||||||
E(OP_PetBuffWindow)
|
E(OP_DzMemberList)
|
||||||
|
E(OP_ExpansionInfo)
|
||||||
|
E(OP_GroundSpawn)
|
||||||
|
E(OP_GuildMemberList)
|
||||||
|
E(OP_Illusion)
|
||||||
|
E(OP_InspectRequest)
|
||||||
|
E(OP_ItemLinkResponse)
|
||||||
|
E(OP_ItemPacket)
|
||||||
|
E(OP_ItemVerifyReply)
|
||||||
|
E(OP_LeadershipExpUpdate)
|
||||||
|
E(OP_LogServer)
|
||||||
|
E(OP_LootItem)
|
||||||
|
E(OP_ManaChange)
|
||||||
|
E(OP_MoveItem)
|
||||||
|
E(OP_NewSpawn)
|
||||||
|
E(OP_NewZone)
|
||||||
E(OP_OnLevelMessage)
|
E(OP_OnLevelMessage)
|
||||||
E(OP_AltCurrencySell)
|
E(OP_OpenNewTasksWindow)
|
||||||
|
E(OP_PetBuffWindow)
|
||||||
|
E(OP_PlayerProfile)
|
||||||
|
E(OP_RaidJoin)
|
||||||
|
E(OP_RaidUpdate)
|
||||||
|
E(OP_ReadBook)
|
||||||
|
E(OP_SendAATable)
|
||||||
|
E(OP_SendCharInfo)
|
||||||
|
E(OP_SendZonepoints)
|
||||||
|
E(OP_ShopPlayerSell)
|
||||||
|
E(OP_SomeItemPacketMaybe)
|
||||||
|
E(OP_SpawnDoor)
|
||||||
|
E(OP_Stun)
|
||||||
|
E(OP_Track)
|
||||||
|
E(OP_Trader)
|
||||||
|
E(OP_TraderBuy)
|
||||||
|
E(OP_TributeItem)
|
||||||
|
E(OP_VetRewardsAvaliable)
|
||||||
E(OP_WearChange)
|
E(OP_WearChange)
|
||||||
//list of packets we need to decode on the way in:
|
E(OP_ZoneEntry)
|
||||||
D(OP_SetServerFilter)
|
E(OP_ZonePlayerToBind)
|
||||||
D(OP_CharacterCreate)
|
E(OP_ZoneServerInfo)
|
||||||
D(OP_ItemLinkClick)
|
E(OP_ZoneSpawns)
|
||||||
D(OP_ConsiderCorpse)
|
// incoming packets that require a DECODE translation:
|
||||||
D(OP_Consider)
|
D(OP_AdventureMerchantSell)
|
||||||
D(OP_ClientUpdate)
|
D(OP_AltCurrencySell)
|
||||||
D(OP_MoveItem)
|
D(OP_AltCurrencySellSelection)
|
||||||
D(OP_WhoAllRequest)
|
D(OP_ApplyPoison)
|
||||||
|
D(OP_AugmentInfo)
|
||||||
|
D(OP_AugmentItem)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_ShopPlayerSell)
|
|
||||||
D(OP_Consume)
|
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_Save)
|
D(OP_CharacterCreate)
|
||||||
D(OP_ItemVerifyRequest)
|
D(OP_ClientUpdate)
|
||||||
|
D(OP_Consider)
|
||||||
|
D(OP_ConsiderCorpse)
|
||||||
|
D(OP_Consume)
|
||||||
|
D(OP_DeleteItem)
|
||||||
|
D(OP_FaceChange)
|
||||||
|
D(OP_FindPersonRequest)
|
||||||
D(OP_GroupFollow)
|
D(OP_GroupFollow)
|
||||||
D(OP_GroupFollow2)
|
D(OP_GroupFollow2)
|
||||||
D(OP_FindPersonRequest)
|
|
||||||
D(OP_TraderBuy)
|
|
||||||
D(OP_LootItem)
|
|
||||||
D(OP_TributeItem)
|
|
||||||
D(OP_ReadBook)
|
|
||||||
D(OP_AugmentInfo)
|
|
||||||
D(OP_FaceChange)
|
|
||||||
D(OP_AdventureMerchantSell)
|
|
||||||
D(OP_TradeSkillCombine)
|
|
||||||
D(OP_RaidInvite)
|
|
||||||
D(OP_InspectRequest)
|
D(OP_InspectRequest)
|
||||||
|
D(OP_ItemLinkClick)
|
||||||
|
D(OP_ItemVerifyRequest)
|
||||||
|
D(OP_LootItem)
|
||||||
|
D(OP_MoveItem)
|
||||||
|
D(OP_RaidInvite)
|
||||||
|
D(OP_ReadBook)
|
||||||
|
D(OP_Save)
|
||||||
|
D(OP_SetServerFilter)
|
||||||
|
D(OP_ShopPlayerSell)
|
||||||
|
D(OP_TraderBuy)
|
||||||
|
D(OP_TradeSkillCombine)
|
||||||
|
D(OP_TributeItem)
|
||||||
D(OP_WearChange)
|
D(OP_WearChange)
|
||||||
D(OP_ApplyPoison)
|
D(OP_WhoAllRequest)
|
||||||
D(OP_DeleteItem)
|
|
||||||
D(OP_AugmentItem)
|
|
||||||
D(OP_AltCurrencySellSelection)
|
|
||||||
D(OP_AltCurrencySell)
|
|
||||||
#undef E
|
#undef E
|
||||||
#undef D
|
#undef D
|
||||||
|
|||||||
@ -133,22 +133,6 @@ static inline uint32 TitaniumToServerCorpseSlot(uint32 TitaniumCorpse) {
|
|||||||
// reserved
|
// reserved
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
static inline uint32 RemovePowerSourceBit(uint32 slots) { // shouldn't need to add one..just grab the actual server reference, if so...
|
|
||||||
static const uint32 BIT21 = 1 << 21;
|
|
||||||
static const uint32 BIT22 = 1 << 22;
|
|
||||||
static const uint32 KEEPBITS = ~(BIT21 | BIT22);
|
|
||||||
|
|
||||||
bool wearammo = slots & BIT22;
|
|
||||||
|
|
||||||
slots &= KEEPBITS;
|
|
||||||
|
|
||||||
if (wearammo)
|
|
||||||
slots |= BIT21;
|
|
||||||
|
|
||||||
return slots;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
EAT_ENCODE(OP_ZoneServerReady)
|
EAT_ENCODE(OP_ZoneServerReady)
|
||||||
|
|||||||
@ -1,53 +1,52 @@
|
|||||||
|
// out-going packets that require an ENCODE translation:
|
||||||
//list of packets we need to encode on the way out:
|
E(OP_Action)
|
||||||
E(OP_SendCharInfo)
|
|
||||||
E(OP_SendAATable)
|
|
||||||
E(OP_LeadershipExpUpdate)
|
|
||||||
E(OP_PlayerProfile)
|
|
||||||
E(OP_NewSpawn)
|
|
||||||
E(OP_ZoneSpawns)
|
|
||||||
E(OP_ZoneEntry)
|
|
||||||
E(OP_CharInventory)
|
|
||||||
E(OP_ItemLinkResponse)
|
|
||||||
E(OP_ItemPacket)
|
|
||||||
E(OP_BazaarSearch)
|
E(OP_BazaarSearch)
|
||||||
E(OP_GuildMemberList)
|
E(OP_BecomeTrader)
|
||||||
E(OP_ZoneServerReady)
|
E(OP_CharInventory)
|
||||||
E(OP_GuildMemberLevelUpdate)
|
|
||||||
E(OP_Trader)
|
|
||||||
E(OP_TraderBuy)
|
|
||||||
E(OP_ReadBook)
|
|
||||||
E(OP_Illusion)
|
|
||||||
E(OP_VetRewardsAvaliable)
|
|
||||||
E(OP_InspectRequest)
|
|
||||||
E(OP_InspectAnswer)
|
|
||||||
E(OP_Track)
|
|
||||||
E(OP_RespondAA)
|
|
||||||
E(OP_DeleteSpawn)
|
E(OP_DeleteSpawn)
|
||||||
E(OP_WearChange)
|
E(OP_DzCompass)
|
||||||
E(OP_DzExpeditionEndsWarning)
|
E(OP_DzExpeditionEndsWarning)
|
||||||
E(OP_DzExpeditionInfo)
|
E(OP_DzExpeditionInfo)
|
||||||
E(OP_DzCompass)
|
|
||||||
E(OP_DzMemberList)
|
|
||||||
E(OP_DzExpeditionList)
|
E(OP_DzExpeditionList)
|
||||||
E(OP_DzLeaderStatus)
|
|
||||||
E(OP_DzJoinExpeditionConfirm)
|
E(OP_DzJoinExpeditionConfirm)
|
||||||
E(OP_Action)
|
E(OP_DzLeaderStatus)
|
||||||
E(OP_BecomeTrader)
|
E(OP_DzMemberList)
|
||||||
E(OP_PetBuffWindow)
|
E(OP_GuildMemberLevelUpdate)
|
||||||
E(OP_OnLevelMessage)
|
E(OP_GuildMemberList)
|
||||||
|
E(OP_Illusion)
|
||||||
|
E(OP_InspectAnswer)
|
||||||
|
E(OP_InspectRequest)
|
||||||
|
E(OP_ItemLinkResponse)
|
||||||
|
E(OP_ItemPacket)
|
||||||
|
E(OP_LeadershipExpUpdate)
|
||||||
E(OP_LFGuild)
|
E(OP_LFGuild)
|
||||||
//list of packets we need to decode on the way in:
|
E(OP_OnLevelMessage)
|
||||||
D(OP_SetServerFilter)
|
E(OP_PetBuffWindow)
|
||||||
|
E(OP_PlayerProfile)
|
||||||
|
E(OP_NewSpawn)
|
||||||
|
E(OP_ReadBook)
|
||||||
|
E(OP_RespondAA)
|
||||||
|
E(OP_SendCharInfo)
|
||||||
|
E(OP_SendAATable)
|
||||||
|
E(OP_Track)
|
||||||
|
E(OP_Trader)
|
||||||
|
E(OP_TraderBuy)
|
||||||
|
E(OP_VetRewardsAvaliable)
|
||||||
|
E(OP_WearChange)
|
||||||
|
E(OP_ZoneEntry)
|
||||||
|
E(OP_ZoneServerReady)
|
||||||
|
E(OP_ZoneSpawns)
|
||||||
|
// incoming packets that require a DECODE translation:
|
||||||
D(OP_CharacterCreate)
|
D(OP_CharacterCreate)
|
||||||
D(OP_ItemLinkClick)
|
|
||||||
D(OP_TraderBuy)
|
|
||||||
D(OP_WhoAllRequest)
|
|
||||||
D(OP_ReadBook)
|
|
||||||
D(OP_FaceChange)
|
D(OP_FaceChange)
|
||||||
D(OP_InspectRequest)
|
|
||||||
D(OP_InspectAnswer)
|
D(OP_InspectAnswer)
|
||||||
D(OP_WearChange)
|
D(OP_InspectRequest)
|
||||||
|
D(OP_ItemLinkClick)
|
||||||
D(OP_LFGuild)
|
D(OP_LFGuild)
|
||||||
|
D(OP_ReadBook)
|
||||||
|
D(OP_SetServerFilter)
|
||||||
|
D(OP_TraderBuy)
|
||||||
|
D(OP_WearChange)
|
||||||
|
D(OP_WhoAllRequest)
|
||||||
#undef E
|
#undef E
|
||||||
#undef D
|
#undef D
|
||||||
|
|||||||
@ -1,128 +1,126 @@
|
|||||||
|
// out-going packets that require an ENCODE translation:
|
||||||
//list of packets we need to encode on the way out:
|
|
||||||
|
|
||||||
E(OP_SendCharInfo)
|
|
||||||
E(OP_ZoneServerInfo)
|
|
||||||
E(OP_SendAATable)
|
|
||||||
E(OP_PlayerProfile)
|
|
||||||
E(OP_ZoneEntry)
|
|
||||||
E(OP_CharInventory)
|
|
||||||
E(OP_NewZone)
|
|
||||||
E(OP_SpawnDoor)
|
|
||||||
E(OP_GroundSpawn)
|
|
||||||
E(OP_SendZonepoints)
|
|
||||||
E(OP_NewSpawn)
|
|
||||||
E(OP_ZoneSpawns)
|
|
||||||
E(OP_ItemLinkResponse)
|
|
||||||
E(OP_ItemPacket)
|
|
||||||
E(OP_GuildMemberList)
|
|
||||||
E(OP_Illusion)
|
|
||||||
E(OP_ManaChange)
|
|
||||||
E(OP_ClientUpdate)
|
|
||||||
E(OP_LeadershipExpUpdate)
|
|
||||||
E(OP_ExpansionInfo)
|
|
||||||
E(OP_LogServer)
|
|
||||||
E(OP_Damage)
|
|
||||||
E(OP_Buff)
|
|
||||||
E(OP_Action)
|
E(OP_Action)
|
||||||
E(OP_Consider)
|
|
||||||
E(OP_CancelTrade)
|
|
||||||
E(OP_ShopPlayerSell)
|
|
||||||
E(OP_DeleteItem)
|
|
||||||
E(OP_ItemVerifyReply)
|
|
||||||
E(OP_DeleteCharge)
|
|
||||||
E(OP_MoveItem)
|
|
||||||
E(OP_OpenNewTasksWindow)
|
|
||||||
E(OP_BazaarSearch)
|
|
||||||
E(OP_Trader)
|
|
||||||
E(OP_TraderBuy)
|
|
||||||
E(OP_LootItem)
|
|
||||||
E(OP_TributeItem)
|
|
||||||
E(OP_SomeItemPacketMaybe)
|
|
||||||
E(OP_ReadBook)
|
|
||||||
E(OP_Stun)
|
|
||||||
E(OP_ZonePlayerToBind)
|
|
||||||
E(OP_AdventureMerchantSell)
|
E(OP_AdventureMerchantSell)
|
||||||
E(OP_RaidUpdate)
|
E(OP_AltCurrency)
|
||||||
E(OP_RaidJoin)
|
E(OP_AltCurrencySell)
|
||||||
E(OP_VetRewardsAvaliable)
|
|
||||||
E(OP_InspectRequest)
|
|
||||||
E(OP_GroupInvite)
|
|
||||||
E(OP_GroupFollow)
|
|
||||||
E(OP_GroupFollow2)
|
|
||||||
E(OP_GroupUpdate)
|
|
||||||
E(OP_GroupCancelInvite)
|
|
||||||
E(OP_WhoAllResponse)
|
|
||||||
E(OP_Track)
|
|
||||||
E(OP_ShopPlayerBuy)
|
|
||||||
E(OP_PetBuffWindow)
|
|
||||||
E(OP_OnLevelMessage)
|
|
||||||
E(OP_Barter)
|
|
||||||
E(OP_ApplyPoison)
|
E(OP_ApplyPoison)
|
||||||
|
E(OP_Barter)
|
||||||
|
E(OP_BazaarSearch)
|
||||||
|
E(OP_Buff)
|
||||||
|
E(OP_BuffCreate)
|
||||||
|
E(OP_CancelTrade)
|
||||||
E(OP_ChannelMessage)
|
E(OP_ChannelMessage)
|
||||||
E(OP_GuildsList)
|
E(OP_CharInventory)
|
||||||
|
E(OP_ClientUpdate)
|
||||||
|
E(OP_Consider)
|
||||||
|
E(OP_Damage)
|
||||||
|
E(OP_DeleteCharge)
|
||||||
|
E(OP_DeleteItem)
|
||||||
|
E(OP_DisciplineUpdate)
|
||||||
|
E(OP_DzCompass)
|
||||||
E(OP_DzExpeditionEndsWarning)
|
E(OP_DzExpeditionEndsWarning)
|
||||||
E(OP_DzExpeditionInfo)
|
E(OP_DzExpeditionInfo)
|
||||||
E(OP_DzCompass)
|
|
||||||
E(OP_DzMemberList)
|
|
||||||
E(OP_DzExpeditionList)
|
E(OP_DzExpeditionList)
|
||||||
E(OP_DzLeaderStatus)
|
|
||||||
E(OP_DzJoinExpeditionConfirm)
|
E(OP_DzJoinExpeditionConfirm)
|
||||||
E(OP_TargetBuffs)
|
E(OP_DzLeaderStatus)
|
||||||
E(OP_BuffCreate)
|
E(OP_DzMemberList)
|
||||||
E(OP_SpawnAppearance)
|
E(OP_ExpansionInfo)
|
||||||
E(OP_RespondAA)
|
E(OP_GroundSpawn)
|
||||||
E(OP_DisciplineUpdate)
|
E(OP_GroupCancelInvite)
|
||||||
E(OP_AltCurrencySell)
|
E(OP_GroupFollow)
|
||||||
E(OP_AltCurrency)
|
E(OP_GroupFollow2)
|
||||||
E(OP_WearChange)
|
E(OP_GroupInvite)
|
||||||
|
E(OP_GroupUpdate)
|
||||||
|
E(OP_GuildMemberList)
|
||||||
|
E(OP_GuildsList)
|
||||||
|
E(OP_Illusion)
|
||||||
|
E(OP_InspectRequest)
|
||||||
|
E(OP_ItemLinkResponse)
|
||||||
|
E(OP_ItemPacket)
|
||||||
|
E(OP_ItemVerifyReply)
|
||||||
|
E(OP_LeadershipExpUpdate)
|
||||||
|
E(OP_LogServer)
|
||||||
|
E(OP_LootItem)
|
||||||
|
E(OP_ManaChange)
|
||||||
E(OP_MercenaryDataResponse)
|
E(OP_MercenaryDataResponse)
|
||||||
E(OP_MercenaryDataUpdate)
|
E(OP_MercenaryDataUpdate)
|
||||||
//list of packets we need to decode on the way in:
|
E(OP_MoveItem)
|
||||||
D(OP_SetServerFilter)
|
E(OP_NewSpawn)
|
||||||
D(OP_CharacterCreate)
|
E(OP_NewZone)
|
||||||
D(OP_ItemLinkClick)
|
E(OP_OnLevelMessage)
|
||||||
D(OP_ConsiderCorpse)
|
E(OP_OpenNewTasksWindow)
|
||||||
D(OP_Consider)
|
E(OP_PetBuffWindow)
|
||||||
D(OP_ClientUpdate)
|
E(OP_PlayerProfile)
|
||||||
D(OP_MoveItem)
|
E(OP_RaidJoin)
|
||||||
D(OP_WhoAllRequest)
|
E(OP_RaidUpdate)
|
||||||
|
E(OP_ReadBook)
|
||||||
|
E(OP_RespondAA)
|
||||||
|
E(OP_SendAATable)
|
||||||
|
E(OP_SendCharInfo)
|
||||||
|
E(OP_SendZonepoints)
|
||||||
|
E(OP_ShopPlayerBuy)
|
||||||
|
E(OP_ShopPlayerSell)
|
||||||
|
E(OP_SomeItemPacketMaybe)
|
||||||
|
E(OP_SpawnAppearance)
|
||||||
|
E(OP_SpawnDoor)
|
||||||
|
E(OP_Stun)
|
||||||
|
E(OP_TargetBuffs)
|
||||||
|
E(OP_Track)
|
||||||
|
E(OP_Trader)
|
||||||
|
E(OP_TraderBuy)
|
||||||
|
E(OP_TributeItem)
|
||||||
|
E(OP_VetRewardsAvaliable)
|
||||||
|
E(OP_WearChange)
|
||||||
|
E(OP_WhoAllResponse)
|
||||||
|
E(OP_ZoneEntry)
|
||||||
|
E(OP_ZonePlayerToBind)
|
||||||
|
E(OP_ZoneServerInfo)
|
||||||
|
E(OP_ZoneSpawns)
|
||||||
|
// incoming packets that require a DECODE translation:
|
||||||
|
D(OP_AdventureMerchantSell)
|
||||||
|
D(OP_AltCurrencySell)
|
||||||
|
D(OP_AltCurrencySellSelection)
|
||||||
|
D(OP_ApplyPoison)
|
||||||
|
D(OP_AugmentInfo)
|
||||||
|
D(OP_AugmentItem)
|
||||||
|
D(OP_BazaarSearch)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_ShopPlayerSell)
|
D(OP_BuffRemoveRequest)
|
||||||
D(OP_Consume)
|
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_Save)
|
D(OP_ChannelMessage)
|
||||||
D(OP_ItemVerifyRequest)
|
D(OP_CharacterCreate)
|
||||||
D(OP_GroupInvite)
|
D(OP_ClientUpdate)
|
||||||
D(OP_GroupInvite2)
|
D(OP_Consider)
|
||||||
|
D(OP_ConsiderCorpse)
|
||||||
|
D(OP_Consume)
|
||||||
|
D(OP_Damage)
|
||||||
|
D(OP_DeleteItem)
|
||||||
|
D(OP_EnvDamage)
|
||||||
|
D(OP_FaceChange)
|
||||||
|
D(OP_FindPersonRequest)
|
||||||
|
D(OP_GroupCancelInvite)
|
||||||
|
D(OP_GroupDisband)
|
||||||
D(OP_GroupFollow)
|
D(OP_GroupFollow)
|
||||||
D(OP_GroupFollow2)
|
D(OP_GroupFollow2)
|
||||||
D(OP_GroupDisband)
|
D(OP_GroupInvite)
|
||||||
D(OP_GroupCancelInvite)
|
D(OP_GroupInvite2)
|
||||||
D(OP_FindPersonRequest)
|
|
||||||
D(OP_TraderBuy)
|
|
||||||
D(OP_LootItem)
|
|
||||||
D(OP_TributeItem)
|
|
||||||
D(OP_ReadBook)
|
|
||||||
D(OP_AugmentInfo)
|
|
||||||
D(OP_FaceChange)
|
|
||||||
D(OP_AdventureMerchantSell)
|
|
||||||
D(OP_TradeSkillCombine)
|
|
||||||
D(OP_RaidInvite)
|
|
||||||
D(OP_InspectRequest)
|
D(OP_InspectRequest)
|
||||||
D(OP_WearChange)
|
D(OP_ItemLinkClick)
|
||||||
D(OP_ShopPlayerBuy)
|
D(OP_ItemVerifyRequest)
|
||||||
D(OP_BazaarSearch)
|
|
||||||
D(OP_LoadSpellSet)
|
D(OP_LoadSpellSet)
|
||||||
D(OP_ApplyPoison)
|
D(OP_LootItem)
|
||||||
D(OP_Damage)
|
D(OP_MoveItem)
|
||||||
D(OP_EnvDamage)
|
|
||||||
D(OP_ChannelMessage)
|
|
||||||
D(OP_DeleteItem)
|
|
||||||
D(OP_AugmentItem)
|
|
||||||
D(OP_PetCommands)
|
D(OP_PetCommands)
|
||||||
D(OP_BuffRemoveRequest)
|
D(OP_RaidInvite)
|
||||||
D(OP_AltCurrencySellSelection)
|
D(OP_ReadBook)
|
||||||
D(OP_AltCurrencySell)
|
D(OP_Save)
|
||||||
|
D(OP_SetServerFilter)
|
||||||
|
D(OP_ShopPlayerBuy)
|
||||||
|
D(OP_ShopPlayerSell)
|
||||||
|
D(OP_TraderBuy)
|
||||||
|
D(OP_TradeSkillCombine)
|
||||||
|
D(OP_TributeItem)
|
||||||
|
D(OP_WearChange)
|
||||||
|
D(OP_WhoAllRequest)
|
||||||
#undef E
|
#undef E
|
||||||
#undef D
|
#undef D
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "skills.h"
|
#include "skills.h"
|
||||||
|
|
||||||
bool EQEmu::IsTradeskill(uint32 skill)
|
bool EQEmu::IsTradeskill(SkillUseTypes skill)
|
||||||
{
|
{
|
||||||
switch (skill) {
|
switch (skill) {
|
||||||
case SkillFishing:
|
case SkillFishing:
|
||||||
@ -38,3 +38,19 @@ bool EQEmu::IsTradeskill(uint32 skill)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EQEmu::IsSpecializedSkill(SkillUseTypes skill)
|
||||||
|
{
|
||||||
|
// this could be a simple if, but if this is more portable if any IDs change (probably won't)
|
||||||
|
// or any other specialized are added (also unlikely)
|
||||||
|
switch (skill) {
|
||||||
|
case SkillSpecializeAbjure:
|
||||||
|
case SkillSpecializeAlteration:
|
||||||
|
case SkillSpecializeConjuration:
|
||||||
|
case SkillSpecializeDivination:
|
||||||
|
case SkillSpecializeEvocation:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -262,7 +262,8 @@ typedef enum {
|
|||||||
|
|
||||||
// for skill related helper functions
|
// for skill related helper functions
|
||||||
namespace EQEmu {
|
namespace EQEmu {
|
||||||
bool IsTradeskill(uint32 skill);
|
bool IsTradeskill(SkillUseTypes skill);
|
||||||
|
bool IsSpecializedSkill(SkillUseTypes skill);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -15,6 +15,7 @@ SET(tests_headers
|
|||||||
ipc_mutex_test.h
|
ipc_mutex_test.h
|
||||||
memory_mapped_file_test.h
|
memory_mapped_file_test.h
|
||||||
string_util_test.h
|
string_util_test.h
|
||||||
|
skills_util_test.h
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "hextoi_32_64_test.h"
|
#include "hextoi_32_64_test.h"
|
||||||
#include "string_util_test.h"
|
#include "string_util_test.h"
|
||||||
#include "data_verification_test.h"
|
#include "data_verification_test.h"
|
||||||
|
#include "skills_util_test.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
try {
|
try {
|
||||||
@ -42,6 +43,7 @@ int main() {
|
|||||||
tests.add(new hextoi_32_64_Test());
|
tests.add(new hextoi_32_64_Test());
|
||||||
tests.add(new StringUtilTest());
|
tests.add(new StringUtilTest());
|
||||||
tests.add(new DataVerificationTest());
|
tests.add(new DataVerificationTest());
|
||||||
|
tests.add(new SkillsUtilsTest());
|
||||||
tests.run(*output, true);
|
tests.run(*output, true);
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
48
tests/skills_util_test.h
Normal file
48
tests/skills_util_test.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* EQEMu: Everquest Server Emulator
|
||||||
|
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
are required to give you total support for your newly bought product;
|
||||||
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __EQEMU_TESTS_SKILLS_UTILS_H
|
||||||
|
#define __EQEMU_TESTS_SKILLS_UTILS_H
|
||||||
|
|
||||||
|
#include "cppunit/cpptest.h"
|
||||||
|
#include "../common/skills.h"
|
||||||
|
|
||||||
|
class SkillsUtilsTest: public Test::Suite {
|
||||||
|
typedef void(SkillsUtilsTest::*TestFunction)(void);
|
||||||
|
public:
|
||||||
|
SkillsUtilsTest() {
|
||||||
|
TEST_ADD(SkillsUtilsTest::IsTradeskill);
|
||||||
|
TEST_ADD(SkillsUtilsTest::IsSpecializedSkill);
|
||||||
|
}
|
||||||
|
|
||||||
|
~SkillsUtilsTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void IsTradeskill() {
|
||||||
|
TEST_ASSERT(EQEmu::IsTradeskill(SkillPottery));
|
||||||
|
TEST_ASSERT(!EQEmu::IsTradeskill(SkillParry));
|
||||||
|
}
|
||||||
|
|
||||||
|
void IsSpecializedSkill() {
|
||||||
|
TEST_ASSERT(EQEmu::IsSpecializedSkill(SkillSpecializeConjuration));
|
||||||
|
TEST_ASSERT(!EQEmu::IsSpecializedSkill(SkillConjuration))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1794,10 +1794,10 @@ void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
|
|||||||
{
|
{
|
||||||
for (uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
|
for (uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
|
||||||
if (pp->skills[i] == 0) {
|
if (pp->skills[i] == 0) {
|
||||||
if (i >= SkillSpecializeAbjure && i <= SkillSpecializeEvocation)
|
// Skip specialized, tradeskills (fishing excluded), Alcohol Tolerance, and Bind Wound
|
||||||
continue;
|
if (EQEmu::IsSpecializedSkill((SkillUseTypes)i) ||
|
||||||
|
(EQEmu::IsTradeskill((SkillUseTypes)i) && i != SkillFishing) ||
|
||||||
if (EQEmu::IsTradeskill(i) || i == SkillBegging)
|
i == SkillAlcoholTolerance || i == SkillBindWound)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1);
|
pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1);
|
||||||
|
|||||||
@ -490,22 +490,36 @@ void EntityList::MobProcess()
|
|||||||
#endif
|
#endif
|
||||||
auto it = mob_list.begin();
|
auto it = mob_list.begin();
|
||||||
while (it != mob_list.end()) {
|
while (it != mob_list.end()) {
|
||||||
if (!it->second) {
|
uint16 id = it->first;
|
||||||
|
Mob *mob = it->second;
|
||||||
|
|
||||||
|
size_t sz = mob_list.size();
|
||||||
|
bool p_val = mob->Process();
|
||||||
|
size_t a_sz = mob_list.size();
|
||||||
|
|
||||||
|
if(a_sz > sz) {
|
||||||
|
//increased size can potentially screw with iterators so reset it to current value
|
||||||
|
//if buckets are re-orderered we may skip a process here and there but since
|
||||||
|
//process happens so often it shouldn't matter much
|
||||||
|
it = mob_list.find(id);
|
||||||
|
++it;
|
||||||
|
} else {
|
||||||
++it;
|
++it;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (!it->second->Process()) {
|
|
||||||
Mob *mob = it->second;
|
if(!p_val) {
|
||||||
uint16 tempid = it->first;
|
if(mob->IsNPC()) {
|
||||||
if (mob->IsNPC()) {
|
entity_list.RemoveNPC(id);
|
||||||
entity_list.RemoveNPC(mob->CastToNPC()->GetID());
|
}
|
||||||
} else if (mob->IsMerc()) {
|
else if(mob->IsMerc()) {
|
||||||
entity_list.RemoveMerc(mob->CastToMerc()->GetID());
|
entity_list.RemoveMerc(id);
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
} else if (mob->IsBot()) {
|
}
|
||||||
entity_list.RemoveBot(mob->CastToBot()->GetID());
|
else if(mob->IsBot()) {
|
||||||
|
entity_list.RemoveBot(id);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
in.s_addr = mob->CastToClient()->GetIP();
|
in.s_addr = mob->CastToClient()->GetIP();
|
||||||
@ -513,25 +527,19 @@ void EntityList::MobProcess()
|
|||||||
#endif
|
#endif
|
||||||
zone->StartShutdownTimer();
|
zone->StartShutdownTimer();
|
||||||
Group *g = GetGroupByMob(mob);
|
Group *g = GetGroupByMob(mob);
|
||||||
if (g) {
|
if(g) {
|
||||||
LogFile->write(EQEMuLog::Error, "About to delete a client still in a group.");
|
LogFile->write(EQEMuLog::Error, "About to delete a client still in a group.");
|
||||||
g->DelMember(mob);
|
g->DelMember(mob);
|
||||||
}
|
}
|
||||||
Raid *r = entity_list.GetRaidByClient(mob->CastToClient());
|
Raid *r = entity_list.GetRaidByClient(mob->CastToClient());
|
||||||
if (r) {
|
if(r) {
|
||||||
LogFile->write(EQEMuLog::Error, "About to delete a client still in a raid.");
|
LogFile->write(EQEMuLog::Error, "About to delete a client still in a raid.");
|
||||||
r->MemberZoned(mob->CastToClient());
|
r->MemberZoned(mob->CastToClient());
|
||||||
}
|
}
|
||||||
entity_list.RemoveClient(mob->GetID());
|
entity_list.RemoveClient(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity_list.RemoveMob(tempid)) {
|
entity_list.RemoveMob(id);
|
||||||
it = mob_list.begin();
|
|
||||||
} else {
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
141
zone/groups.cpp
141
zone/groups.cpp
@ -969,31 +969,28 @@ void Group::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Group::LearnMembers() {
|
bool Group::LearnMembers() {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("SELECT name FROM group_id WHERE groupid = %lu", (unsigned long)GetID());
|
||||||
char* query = 0;
|
auto results = database.QueryDatabase(query);
|
||||||
MYSQL_RES *result;
|
if (!results.Success())
|
||||||
MYSQL_ROW row;
|
return false;
|
||||||
if (database.RunQuery(query,MakeAnyLenString(&query, "SELECT name FROM group_id WHERE groupid=%lu", (unsigned long)GetID()),
|
|
||||||
errbuf,&result)){
|
|
||||||
safe_delete_array(query);
|
|
||||||
if(mysql_num_rows(result) < 1) { //could prolly be 2
|
|
||||||
mysql_free_result(result);
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error getting group members for group %lu: %s", (unsigned long)GetID(), errbuf);
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
int i = 0;
|
|
||||||
while((row = mysql_fetch_row(result))) {
|
|
||||||
if(!row[0])
|
|
||||||
continue;
|
|
||||||
members[i] = nullptr;
|
|
||||||
strn0cpy(membername[i], row[0], 64);
|
|
||||||
|
|
||||||
i++;
|
if (results.RowCount() == 0) {
|
||||||
}
|
LogFile->write(EQEMuLog::Error, "Error getting group members for group %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
|
||||||
mysql_free_result(result);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memberIndex = 0;
|
||||||
|
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
if(!row[0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
members[memberIndex] = nullptr;
|
||||||
|
strn0cpy(membername[memberIndex], row[0], 64);
|
||||||
|
|
||||||
|
memberIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::VerifyGroup() {
|
void Group::VerifyGroup() {
|
||||||
@ -1341,15 +1338,12 @@ void Group::DelegateMainTank(const char *NewMainTankName, uint8 toggle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(updateDB) {
|
if(updateDB) {
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char *Query = nullptr;
|
std::string query = StringFormat("UPDATE group_leaders SET maintank = '%s' WHERE gid = %i LIMIT 1",
|
||||||
|
MainTankName.c_str(), GetID());
|
||||||
if (!database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE group_leaders SET maintank='%s' WHERE gid=%i LIMIT 1",
|
auto results = database.QueryDatabase(query);
|
||||||
MainTankName.c_str(), GetID()), errbuff))
|
if (!results.Success())
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to set group main tank: %s\n", errbuff);
|
LogFile->write(EQEMuLog::Error, "Unable to set group main tank: %s\n", results.ErrorMessage().c_str());
|
||||||
|
|
||||||
safe_delete_array(Query);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1390,15 +1384,13 @@ void Group::DelegateMainAssist(const char *NewMainAssistName, uint8 toggle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(updateDB) {
|
if(updateDB) {
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char *Query = nullptr;
|
std::string query = StringFormat("UPDATE group_leaders SET assist = '%s' WHERE gid = %i LIMIT 1",
|
||||||
|
MainAssistName.c_str(), GetID());
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
LogFile->write(EQEMuLog::Error, "Unable to set group main assist: %s\n", results.ErrorMessage().c_str());
|
||||||
|
|
||||||
if (!database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE group_leaders SET assist='%s' WHERE gid=%i LIMIT 1",
|
|
||||||
MainAssistName.c_str(), GetID()), errbuff))
|
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to set group main assist: %s\n", errbuff);
|
|
||||||
|
|
||||||
safe_delete_array(Query);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1439,15 +1431,13 @@ void Group::DelegatePuller(const char *NewPullerName, uint8 toggle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(updateDB) {
|
if(updateDB) {
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char *Query = nullptr;
|
std::string query = StringFormat("UPDATE group_leaders SET puller = '%s' WHERE gid = %i LIMIT 1",
|
||||||
|
PullerName.c_str(), GetID());
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
LogFile->write(EQEMuLog::Error, "Unable to set group main puller: %s\n", results.ErrorMessage().c_str());
|
||||||
|
|
||||||
if (!database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE group_leaders SET puller='%s' WHERE gid=%i LIMIT 1",
|
|
||||||
PullerName.c_str(), GetID()), errbuff))
|
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to set group main puller: %s\n", errbuff);
|
|
||||||
|
|
||||||
safe_delete_array(Query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1593,15 +1583,11 @@ void Group::UnDelegateMainTank(const char *OldMainTankName, uint8 toggle)
|
|||||||
// informing them of the change and update the group_leaders table.
|
// informing them of the change and update the group_leaders table.
|
||||||
//
|
//
|
||||||
if(OldMainTankName == MainTankName) {
|
if(OldMainTankName == MainTankName) {
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char *Query = 0;
|
std::string query = StringFormat("UPDATE group_leaders SET maintank = '' WHERE gid = %i LIMIT 1", GetID());
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
if (!database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE group_leaders SET maintank='' WHERE gid=%i LIMIT 1",
|
if (!results.Success())
|
||||||
GetID()), errbuff))
|
LogFile->write(EQEMuLog::Error, "Unable to clear group main tank: %s\n", results.ErrorMessage().c_str());
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to clear group main tank: %s\n", errbuff);
|
|
||||||
|
|
||||||
safe_delete_array(Query);
|
|
||||||
|
|
||||||
if(!toggle) {
|
if(!toggle) {
|
||||||
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||||
@ -1647,15 +1633,10 @@ void Group::UnDelegateMainAssist(const char *OldMainAssistName, uint8 toggle)
|
|||||||
|
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("UPDATE group_leaders SET assist = '' WHERE gid = %i LIMIT 1", GetID());
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
char *Query = 0;
|
if (!results.Success())
|
||||||
|
LogFile->write(EQEMuLog::Error, "Unable to clear group main assist: %s\n", results.ErrorMessage().c_str());
|
||||||
if (!database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE group_leaders SET assist='' WHERE gid=%i LIMIT 1",
|
|
||||||
GetID()), errbuff))
|
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to clear group main assist: %s\n", errbuff);
|
|
||||||
|
|
||||||
safe_delete_array(Query);
|
|
||||||
|
|
||||||
if(!toggle)
|
if(!toggle)
|
||||||
{
|
{
|
||||||
@ -1679,15 +1660,11 @@ void Group::UnDelegatePuller(const char *OldPullerName, uint8 toggle)
|
|||||||
// informing them of the change and update the group_leaders table.
|
// informing them of the change and update the group_leaders table.
|
||||||
//
|
//
|
||||||
if(OldPullerName == PullerName) {
|
if(OldPullerName == PullerName) {
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char *Query = 0;
|
std::string query = StringFormat("UPDATE group_leaders SET puller = '' WHERE gid = %i LIMIT 1", GetID());
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
if (!database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE group_leaders SET puller='' WHERE gid=%i LIMIT 1",
|
if (!results.Success())
|
||||||
GetID()), errbuff))
|
LogFile->write(EQEMuLog::Error, "Unable to clear group main puller: %s\n", results.ErrorMessage().c_str());
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to clear group main puller: %s\n", errbuff);
|
|
||||||
|
|
||||||
safe_delete_array(Query);
|
|
||||||
|
|
||||||
if(!toggle) {
|
if(!toggle) {
|
||||||
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||||
@ -1822,16 +1799,11 @@ void Group::DelegateMarkNPC(const char *NewNPCMarkerName)
|
|||||||
if(members[i] && members[i]->IsClient())
|
if(members[i] && members[i]->IsClient())
|
||||||
NotifyMarkNPC(members[i]->CastToClient());
|
NotifyMarkNPC(members[i]->CastToClient());
|
||||||
|
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("UPDATE group_leaders SET marknpc = '%s' WHERE gid = %i LIMIT 1",
|
||||||
|
NewNPCMarkerName, GetID());
|
||||||
char *Query = 0;
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
if (!database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE group_leaders SET marknpc='%s' WHERE gid=%i LIMIT 1",
|
LogFile->write(EQEMuLog::Error, "Unable to set group mark npc: %s\n", results.ErrorMessage().c_str());
|
||||||
NewNPCMarkerName, GetID()), errbuff))
|
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to set group mark npc: %s\n", errbuff);
|
|
||||||
|
|
||||||
safe_delete_array(Query);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::NotifyMarkNPC(Client *c)
|
void Group::NotifyMarkNPC(Client *c)
|
||||||
@ -1908,15 +1880,12 @@ void Group::UnDelegateMarkNPC(const char *OldNPCMarkerName)
|
|||||||
|
|
||||||
NPCMarkerName.clear();
|
NPCMarkerName.clear();
|
||||||
|
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char *Query = 0;
|
std::string query = StringFormat("UPDATE group_leaders SET marknpc = '' WHERE gid = %i LIMIT 1", GetID());
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
LogFile->write(EQEMuLog::Error, "Unable to clear group marknpc: %s\n", results.ErrorMessage().c_str());
|
||||||
|
|
||||||
if (!database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE group_leaders SET marknpc='' WHERE gid=%i LIMIT 1",
|
|
||||||
GetID()), errbuff))
|
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to clear group marknpc: %s\n", errbuff);
|
|
||||||
|
|
||||||
safe_delete_array(Query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::SaveGroupLeaderAA()
|
void Group::SaveGroupLeaderAA()
|
||||||
|
|||||||
@ -1337,81 +1337,69 @@ void QuestManager::setglobal(const char *varname, const char *newvalue, int opti
|
|||||||
|
|
||||||
/* Inserts global variable into quest_globals table */
|
/* Inserts global variable into quest_globals table */
|
||||||
int QuestManager::InsertQuestGlobal(int charid, int npcid, int zoneid, const char *varname, const char *varvalue, int duration) {
|
int QuestManager::InsertQuestGlobal(int charid, int npcid, int zoneid, const char *varname, const char *varvalue, int duration) {
|
||||||
char *query = 0;
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
// Make duration string either "unix_timestamp(now()) + xxx" or "NULL"
|
// Make duration string either "unix_timestamp(now()) + xxx" or "NULL"
|
||||||
std::stringstream duration_ss;
|
std::string durationText = (duration == INT_MAX)? "NULL": StringFormat("unix_timestamp(now()) + %i", duration);
|
||||||
if (duration == INT_MAX) {
|
|
||||||
duration_ss << "NULL";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
duration_ss << "unix_timestamp(now()) + " << duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NOTE: this should be escaping the contents of arglist
|
NOTE: this should be escaping the contents of arglist
|
||||||
npcwise a malicious script can arbitrarily alter the DB
|
npcwise a malicious script can arbitrarily alter the DB
|
||||||
*/
|
*/
|
||||||
uint32 last_id = 0;
|
|
||||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
|
||||||
"REPLACE INTO quest_globals (charid, npcid, zoneid, name, value, expdate)"
|
|
||||||
"VALUES (%i, %i, %i, '%s', '%s', %s)",
|
|
||||||
charid, npcid, zoneid, varname, varvalue, duration_ss.str().c_str()
|
|
||||||
), errbuf, nullptr, nullptr, &last_id))
|
|
||||||
{
|
|
||||||
std::cerr << "setglobal error inserting " << varname << " : " << errbuf << std::endl;
|
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if(zone) {
|
std::string query = StringFormat("REPLACE INTO quest_globals "
|
||||||
/* Delete existing qglobal data and update zone processes */
|
"(charid, npcid, zoneid, name, value, expdate)"
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
"VALUES (%i, %i, %i, '%s', '%s', %s)",
|
||||||
ServerQGlobalDelete_Struct *qgd = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
charid, npcid, zoneid, varname, varvalue, durationText.c_str());
|
||||||
qgd->npc_id = npcid;
|
auto results = database.QueryDatabase(query);
|
||||||
qgd->char_id = charid;
|
if (!results.Success())
|
||||||
qgd->zone_id = zoneid;
|
std::cerr << "setglobal error inserting " << varname << " : " << results.ErrorMessage() << std::endl;
|
||||||
qgd->from_zone_id = zone->GetZoneID();
|
|
||||||
qgd->from_instance_id = zone->GetInstanceID();
|
|
||||||
strcpy(qgd->name, varname);
|
|
||||||
|
|
||||||
entity_list.DeleteQGlobal(std::string((char*)qgd->name), qgd->npc_id, qgd->char_id, qgd->zone_id);
|
if(!zone)
|
||||||
zone->DeleteQGlobal(std::string((char*)qgd->name), qgd->npc_id, qgd->char_id, qgd->zone_id);
|
return 0;
|
||||||
|
|
||||||
worldserver.SendPacket(pack);
|
/* Delete existing qglobal data and update zone processes */
|
||||||
safe_delete(pack);
|
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
||||||
|
ServerQGlobalDelete_Struct *qgd = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
||||||
|
qgd->npc_id = npcid;
|
||||||
|
qgd->char_id = charid;
|
||||||
|
qgd->zone_id = zoneid;
|
||||||
|
qgd->from_zone_id = zone->GetZoneID();
|
||||||
|
qgd->from_instance_id = zone->GetInstanceID();
|
||||||
|
strcpy(qgd->name, varname);
|
||||||
|
|
||||||
/* Create new qglobal data and update zone processes */
|
entity_list.DeleteQGlobal(std::string((char*)qgd->name), qgd->npc_id, qgd->char_id, qgd->zone_id);
|
||||||
pack = new ServerPacket(ServerOP_QGlobalUpdate, sizeof(ServerQGlobalUpdate_Struct));
|
zone->DeleteQGlobal(std::string((char*)qgd->name), qgd->npc_id, qgd->char_id, qgd->zone_id);
|
||||||
ServerQGlobalUpdate_Struct *qgu = (ServerQGlobalUpdate_Struct*)pack->pBuffer;
|
|
||||||
qgu->npc_id = npcid;
|
|
||||||
qgu->char_id = charid;
|
|
||||||
qgu->zone_id = zoneid;
|
|
||||||
if(duration == INT_MAX) {
|
|
||||||
qgu->expdate = 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qgu->expdate = Timer::GetTimeSeconds() + duration;
|
|
||||||
}
|
|
||||||
strcpy((char*)qgu->name, varname);
|
|
||||||
strn0cpy((char*)qgu->value, varvalue, 128);
|
|
||||||
qgu->id = last_id;
|
|
||||||
qgu->from_zone_id = zone->GetZoneID();
|
|
||||||
qgu->from_instance_id = zone->GetInstanceID();
|
|
||||||
|
|
||||||
QGlobal temp;
|
worldserver.SendPacket(pack);
|
||||||
temp.npc_id = npcid;
|
safe_delete(pack);
|
||||||
temp.char_id = charid;
|
|
||||||
temp.zone_id = zoneid;
|
|
||||||
temp.expdate = qgu->expdate;
|
|
||||||
temp.name.assign(qgu->name);
|
|
||||||
temp.value.assign(qgu->value);
|
|
||||||
entity_list.UpdateQGlobal(qgu->id, temp);
|
|
||||||
zone->UpdateQGlobal(qgu->id, temp);
|
|
||||||
|
|
||||||
worldserver.SendPacket(pack);
|
/* Create new qglobal data and update zone processes */
|
||||||
safe_delete(pack);
|
pack = new ServerPacket(ServerOP_QGlobalUpdate, sizeof(ServerQGlobalUpdate_Struct));
|
||||||
}
|
ServerQGlobalUpdate_Struct *qgu = (ServerQGlobalUpdate_Struct*)pack->pBuffer;
|
||||||
|
qgu->npc_id = npcid;
|
||||||
|
qgu->char_id = charid;
|
||||||
|
qgu->zone_id = zoneid;
|
||||||
|
|
||||||
|
qgu->expdate = (duration == INT_MAX)? 0xFFFFFFFF: Timer::GetTimeSeconds() + duration;
|
||||||
|
|
||||||
|
strcpy((char*)qgu->name, varname);
|
||||||
|
strn0cpy((char*)qgu->value, varvalue, 128);
|
||||||
|
qgu->id = results.LastInsertedID();
|
||||||
|
qgu->from_zone_id = zone->GetZoneID();
|
||||||
|
qgu->from_instance_id = zone->GetInstanceID();
|
||||||
|
|
||||||
|
QGlobal temp;
|
||||||
|
temp.npc_id = npcid;
|
||||||
|
temp.char_id = charid;
|
||||||
|
temp.zone_id = zoneid;
|
||||||
|
temp.expdate = qgu->expdate;
|
||||||
|
temp.name.assign(qgu->name);
|
||||||
|
temp.value.assign(qgu->value);
|
||||||
|
entity_list.UpdateQGlobal(qgu->id, temp);
|
||||||
|
zone->UpdateQGlobal(qgu->id, temp);
|
||||||
|
|
||||||
|
worldserver.SendPacket(pack);
|
||||||
|
safe_delete(pack);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1422,22 +1410,14 @@ void QuestManager::targlobal(const char *varname, const char *value, const char
|
|||||||
|
|
||||||
void QuestManager::delglobal(const char *varname) {
|
void QuestManager::delglobal(const char *varname) {
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
int qgZoneid=zone->GetZoneID();
|
int qgZoneid=zone->GetZoneID();
|
||||||
int qgCharid=0;
|
int qgCharid=0;
|
||||||
int qgNpcid=owner->GetNPCTypeID();
|
int qgNpcid=owner->GetNPCTypeID();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (initiator && initiator->IsClient()) // some events like waypoint and spawn don't have a player involved
|
if (initiator && initiator->IsClient()) // some events like waypoint and spawn don't have a player involved
|
||||||
{
|
|
||||||
qgCharid=initiator->CharacterID();
|
qgCharid=initiator->CharacterID();
|
||||||
}
|
else
|
||||||
|
|
||||||
else {
|
|
||||||
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
||||||
}
|
|
||||||
|
|
||||||
/* QS: PlayerLogQGlobalUpdate */
|
/* QS: PlayerLogQGlobalUpdate */
|
||||||
if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){
|
if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){
|
||||||
@ -1445,31 +1425,32 @@ void QuestManager::delglobal(const char *varname) {
|
|||||||
QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc);
|
QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!database.RunQuery(query,
|
std::string query = StringFormat("DELETE FROM quest_globals "
|
||||||
MakeAnyLenString(&query,
|
"WHERE name = '%s' "
|
||||||
"DELETE FROM quest_globals WHERE name='%s'"
|
"&& (npcid=0 || npcid=%i) "
|
||||||
" && (npcid=0 || npcid=%i) && (charid=0 || charid=%i) && (zoneid=%i || zoneid=0)",
|
"&& (charid=0 || charid=%i) "
|
||||||
varname,qgNpcid,qgCharid,qgZoneid),errbuf))
|
"&& (zoneid=%i || zoneid=0)",
|
||||||
{
|
varname, qgNpcid, qgCharid, qgZoneid);
|
||||||
std::cerr << "delglobal error deleting " << varname << " : " << errbuf << std::endl;
|
auto results = database.QueryDatabase(query);
|
||||||
}
|
if (!results.Success())
|
||||||
safe_delete_array(query);
|
std::cerr << "delglobal error deleting " << varname << " : " << results.ErrorMessage() << std::endl;
|
||||||
|
|
||||||
if(zone) {
|
if(!zone)
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
return;
|
||||||
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
|
||||||
|
|
||||||
qgu->npc_id = qgNpcid;
|
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
||||||
qgu->char_id = qgCharid;
|
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
||||||
qgu->zone_id = qgZoneid;
|
|
||||||
strcpy(qgu->name, varname);
|
|
||||||
|
|
||||||
entity_list.DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id);
|
qgu->npc_id = qgNpcid;
|
||||||
zone->DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id);
|
qgu->char_id = qgCharid;
|
||||||
|
qgu->zone_id = qgZoneid;
|
||||||
|
strcpy(qgu->name, varname);
|
||||||
|
|
||||||
worldserver.SendPacket(pack);
|
entity_list.DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id);
|
||||||
safe_delete(pack);
|
zone->DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id);
|
||||||
}
|
|
||||||
|
worldserver.SendPacket(pack);
|
||||||
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts duration string to duration value (in seconds)
|
// Converts duration string to duration value (in seconds)
|
||||||
@ -1690,11 +1671,6 @@ void QuestManager::showgrid(int grid) {
|
|||||||
if(initiator == nullptr)
|
if(initiator == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
FindPerson_Point pt;
|
FindPerson_Point pt;
|
||||||
std::vector<FindPerson_Point> pts;
|
std::vector<FindPerson_Point> pts;
|
||||||
|
|
||||||
@ -1704,22 +1680,25 @@ void QuestManager::showgrid(int grid) {
|
|||||||
pts.push_back(pt);
|
pts.push_back(pt);
|
||||||
|
|
||||||
// Retrieve all waypoints for this grid
|
// Retrieve all waypoints for this grid
|
||||||
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `x`,`y`,`z` FROM grid_entries WHERE `gridid`=%i AND `zoneid`=%i ORDER BY `number`",grid,zone->GetZoneID()),errbuf,&result)) {
|
std::string query = StringFormat("SELECT `x`,`y`,`z` FROM grid_entries "
|
||||||
while((row = mysql_fetch_row(result))) {
|
"WHERE `gridid` = %i AND `zoneid` = %i "
|
||||||
pt.x = atof(row[0]);
|
"ORDER BY `number`", grid, zone->GetZoneID());
|
||||||
pt.y = atof(row[1]);
|
auto results = database.QueryDatabase(query);
|
||||||
pt.z = atof(row[2]);
|
if (!results.Success()) {
|
||||||
pts.push_back(pt);
|
LogFile->write(EQEMuLog::Quest, "Error loading grid %d for showgrid(): %s", grid, results.ErrorMessage().c_str());
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
initiator->SendPathPacket(pts);
|
|
||||||
}
|
|
||||||
else // DB query error!
|
|
||||||
{
|
|
||||||
LogFile->write(EQEMuLog::Quest, "Error loading grid %d for showgrid(): %s", grid, errbuf);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
safe_delete_array(query);
|
|
||||||
|
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
pt.x = atof(row[0]);
|
||||||
|
pt.y = atof(row[1]);
|
||||||
|
pt.z = atof(row[2]);
|
||||||
|
|
||||||
|
pts.push_back(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
initiator->SendPathPacket(pts);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//change the value of a spawn condition
|
//change the value of a spawn condition
|
||||||
@ -2295,19 +2274,19 @@ bool QuestManager::istaskappropriate(int task) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QuestManager::clearspawntimers() {
|
void QuestManager::clearspawntimers() {
|
||||||
if(zone) {
|
if(!zone)
|
||||||
//TODO: Dec 19, 2008, replace with code updated for current spawn timers.
|
return;
|
||||||
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
|
||||||
iterator.Reset();
|
//TODO: Dec 19, 2008, replace with code updated for current spawn timers.
|
||||||
while (iterator.MoreElements())
|
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
||||||
{
|
iterator.Reset();
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
while (iterator.MoreElements()) {
|
||||||
char *query = 0;
|
std::string query = StringFormat("DELETE FROM respawn_times "
|
||||||
database.RunQuery(query, MakeAnyLenString(&query, "DELETE FROM respawn_times WHERE id=%lu AND "
|
"WHERE id = %lu AND instance_id = %lu",
|
||||||
"instance_id=%lu",(unsigned long)iterator.GetData()->GetID(), (unsigned long)zone->GetInstanceID()), errbuf);
|
(unsigned long)iterator.GetData()->GetID(),
|
||||||
safe_delete_array(query);
|
(unsigned long)zone->GetInstanceID());
|
||||||
iterator.Advance();
|
auto results = database.QueryDatabase(query);
|
||||||
}
|
iterator.Advance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2684,11 +2663,6 @@ void QuestManager::FlagInstanceByRaidLeader(uint32 zone, int16 version)
|
|||||||
const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkName) {
|
const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkName) {
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
|
|
||||||
const char *ERR_MYSQLERROR = "Error in saylink phrase queries";
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
int sayid = 0;
|
int sayid = 0;
|
||||||
|
|
||||||
int sz = strlen(Phrase);
|
int sz = strlen(Phrase);
|
||||||
@ -2696,42 +2670,26 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
|
|||||||
database.DoEscapeString(escaped_string, Phrase, sz);
|
database.DoEscapeString(escaped_string, Phrase, sz);
|
||||||
|
|
||||||
// Query for an existing phrase and id in the saylink table
|
// Query for an existing phrase and id in the saylink table
|
||||||
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `id` FROM `saylink` WHERE `phrase` = '%s'", escaped_string),errbuf,&result))
|
std::string query = StringFormat("SELECT `id` FROM `saylink` WHERE `phrase` = '%s'", escaped_string);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if(results.Success())
|
||||||
{
|
{
|
||||||
if (mysql_num_rows(result) >= 1)
|
if (results.RowCount() >= 1)
|
||||||
{
|
for (auto row = results.begin();row != results.end(); ++row)
|
||||||
while((row = mysql_fetch_row(result)))
|
|
||||||
{
|
|
||||||
sayid = atoi(row[0]);
|
sayid = atoi(row[0]);
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else // Add a new saylink entry to the database and query it again for the new sayid number
|
else // Add a new saylink entry to the database and query it again for the new sayid number
|
||||||
{
|
{
|
||||||
safe_delete_array(query);
|
query = StringFormat("INSERT INTO `saylink` (`phrase`) VALUES ('%s')", escaped_string);
|
||||||
|
results = database.QueryDatabase(query);
|
||||||
|
|
||||||
database.RunQuery(query,MakeAnyLenString(&query,"INSERT INTO `saylink` (`phrase`) VALUES ('%s')", escaped_string),errbuf);
|
if(!results.Success())
|
||||||
safe_delete_array(query);
|
LogFile->write(EQEMuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str());
|
||||||
|
else if (results.RowCount() >= 1)
|
||||||
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `id` FROM saylink WHERE `phrase` = '%s'", escaped_string),errbuf,&result))
|
for(auto row = results.begin(); row != results.end(); ++row)
|
||||||
{
|
|
||||||
if (mysql_num_rows(result) >= 1)
|
|
||||||
{
|
|
||||||
while((row = mysql_fetch_row(result)))
|
|
||||||
{
|
|
||||||
sayid = atoi(row[0]);
|
sayid = atoi(row[0]);
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, errbuf);
|
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
safe_delete_array(query);
|
|
||||||
safe_delete_array(escaped_string);
|
safe_delete_array(escaped_string);
|
||||||
|
|
||||||
if(silent)
|
if(silent)
|
||||||
@ -2739,27 +2697,21 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
|
|||||||
else
|
else
|
||||||
sayid = sayid + 500000;
|
sayid = sayid + 500000;
|
||||||
|
|
||||||
//Create the say link as an item link hash
|
//Create the say link as an item link hash
|
||||||
char linktext[250];
|
char linktext[250];
|
||||||
|
|
||||||
if(initiator)
|
if(initiator)
|
||||||
{
|
{
|
||||||
if (initiator->GetClientVersion() >= EQClientRoF)
|
if (initiator->GetClientVersion() >= EQClientRoF)
|
||||||
{
|
|
||||||
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"0000000000000000000000000000000000000000000000000",LinkName,0x12);
|
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"0000000000000000000000000000000000000000000000000",LinkName,0x12);
|
||||||
}
|
|
||||||
else if (initiator->GetClientVersion() >= EQClientSoF)
|
else if (initiator->GetClientVersion() >= EQClientSoF)
|
||||||
{
|
|
||||||
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"00000000000000000000000000000000000000000000",LinkName,0x12);
|
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"00000000000000000000000000000000000000000000",LinkName,0x12);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"000000000000000000000000000000000000000",LinkName,0x12);
|
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"000000000000000000000000000000000000000",LinkName,0x12);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else { // If no initiator, create an RoF saylink, since older clients handle RoF ones better than RoF handles older ones.
|
else // If no initiator, create an RoF saylink, since older clients handle RoF ones better than RoF handles older ones.
|
||||||
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"0000000000000000000000000000000000000000000000000",LinkName,0x12);
|
sprintf(linktext,"%c%06X%s%s%c",0x12,sayid,"0000000000000000000000000000000000000000000000000",LinkName,0x12);
|
||||||
}
|
|
||||||
strcpy(Phrase,linktext);
|
strcpy(Phrase,linktext);
|
||||||
return Phrase;
|
return Phrase;
|
||||||
|
|
||||||
|
|||||||
704
zone/trading.cpp
704
zone/trading.cpp
@ -1468,18 +1468,16 @@ void Client::TradeRequestFailed(const EQApplicationPacket* app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void BazaarAuditTrail(const char *Seller, const char *Buyer, const char *ItemName, int Quantity, int TotalCost, int TranType) {
|
static void BazaarAuditTrail(const char *seller, const char *buyer, const char *itemName, int quantity, int totalCost, int tranType) {
|
||||||
|
|
||||||
const char *AuditQuery="INSERT INTO `trader_audit` (`time`, `seller`, `buyer`, `itemname`, `quantity`, `totalcost`, `trantype`) "
|
std::string query = StringFormat("INSERT INTO `trader_audit` "
|
||||||
"VALUES (NOW(), '%s', '%s', '%s', %i, %i, %i)";
|
"(`time`, `seller`, `buyer`, `itemname`, `quantity`, `totalcost`, `trantype`) "
|
||||||
|
"VALUES (NOW(), '%s', '%s', '%s', %i, %i, %i)",
|
||||||
|
seller, buyer, itemName, quantity, totalCost, tranType);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if(!results.Success())
|
||||||
|
_log(TRADING__CLIENT, "Audit write error: %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
|
|
||||||
if(!database.RunQuery(query, MakeAnyLenString(&query, AuditQuery, Seller, Buyer, ItemName, Quantity, TotalCost, TranType), errbuf))
|
|
||||||
_log(TRADING__CLIENT, "Audit write error: %s : %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1619,363 +1617,324 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicat
|
|||||||
|
|
||||||
void Client::SendBazaarWelcome(){
|
void Client::SendBazaarWelcome(){
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
const std::string query = "SELECT COUNT(DISTINCT char_id), count(char_id) FROM trader";
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (results.Success() && results.RowCount() == 1){
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
char* query = 0;
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarWelcome_Struct));
|
||||||
|
|
||||||
MYSQL_RES *result;
|
memset(outapp->pBuffer,0,outapp->size);
|
||||||
|
|
||||||
MYSQL_ROW row;
|
BazaarWelcome_Struct* bws = (BazaarWelcome_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
if (database.RunQuery(query,MakeAnyLenString(&query, "select count(distinct char_id),count(char_id) from trader"),errbuf,&result)){
|
bws->Beginning.Action = BazaarWelcome;
|
||||||
if(mysql_num_rows(result)==1){
|
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
bws->Traders = atoi(row[0]);
|
||||||
|
bws->Items = atoi(row[1]);
|
||||||
|
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarWelcome_Struct));
|
QueuePacket(outapp);
|
||||||
|
|
||||||
memset(outapp->pBuffer,0,outapp->size);
|
safe_delete(outapp);
|
||||||
|
}
|
||||||
|
|
||||||
BazaarWelcome_Struct* bws = (BazaarWelcome_Struct*)outapp->pBuffer;
|
const std::string buyerCountQuery = "SELECT COUNT(DISTINCT charid) FROM buyer";
|
||||||
|
results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success() || results.RowCount() != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
bws->Beginning.Action = BazaarWelcome;
|
auto row = results.begin();
|
||||||
|
Message(10, "There are %i Buyers waiting to purchase your loot. Type /barter to search for them, "
|
||||||
bws->Items = atoi(row[1]);
|
"or use /buyer to set up your own Buy Lines.", atoi(row[0]));
|
||||||
|
|
||||||
bws->Traders = atoi(row[0]);
|
|
||||||
|
|
||||||
QueuePacket(outapp);
|
|
||||||
|
|
||||||
safe_delete(outapp);
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if (database.RunQuery(query,MakeAnyLenString(&query, "select count(distinct charid) from buyer"),errbuf,&result)){
|
|
||||||
if(mysql_num_rows(result)==1) {
|
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
|
|
||||||
Message(10, "There are %i Buyers waiting to purchase your loot. Type /barter to search for them,"
|
|
||||||
" or use /buyer to set up your own Buy Lines.", atoi(row[0]));
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendBazaarResults(uint32 TraderID, uint32 Class_, uint32 Race, uint32 ItemStat, uint32 Slot, uint32 Type,
|
void Client::SendBazaarResults(uint32 TraderID, uint32 Class_, uint32 Race, uint32 ItemStat, uint32 Slot, uint32 Type,
|
||||||
char Name[64], uint32 MinPrice, uint32 MaxPrice) {
|
char Name[64], uint32 MinPrice, uint32 MaxPrice) {
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string searchValues = " COUNT(item_id), trader.*, items.name ";
|
||||||
char* Query = 0;
|
std::string searchCriteria = " WHERE trader.item_id = items.id ";
|
||||||
std::string Search, Values;
|
|
||||||
MYSQL_RES *Result;
|
|
||||||
MYSQL_ROW Row;
|
|
||||||
char Tmp[100] = {0};
|
|
||||||
|
|
||||||
Values.append("count(item_id),trader.*,items.name");
|
if(TraderID > 0) {
|
||||||
|
Client* trader = entity_list.GetClientByID(TraderID);
|
||||||
|
|
||||||
Search.append("where trader.item_id=items.id");
|
if(trader)
|
||||||
|
searchCriteria.append(StringFormat(" AND trader.char_id = %i", trader->CharacterID()));
|
||||||
|
}
|
||||||
|
|
||||||
if(TraderID > 0){
|
if(MinPrice != 0)
|
||||||
Client* Trader = entity_list.GetClientByID(TraderID);
|
searchCriteria.append(StringFormat(" AND trader.item_cost >= %i", MinPrice));
|
||||||
|
|
||||||
if(Trader){
|
if(MaxPrice != 0)
|
||||||
sprintf(Tmp," and trader.char_id=%i",Trader->CharacterID());
|
searchCriteria.append(StringFormat(" AND trader.item_cost <= %i", MaxPrice));
|
||||||
Search.append(Tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(strlen(Name) > 0) {
|
||||||
|
char *safeName = RemoveApostrophes(Name);
|
||||||
|
searchCriteria.append(StringFormat(" AND items.name LIKE '%%%s%%'", safeName));
|
||||||
|
safe_delete_array(safeName);
|
||||||
}
|
}
|
||||||
std::string SearchrResults;
|
|
||||||
|
|
||||||
if(MinPrice != 0){
|
if(Class_ != 0xFFFFFFFF)
|
||||||
sprintf(Tmp, " and trader.item_cost>=%i", MinPrice);
|
searchCriteria.append(StringFormat(" AND MID(REVERSE(BIN(items.classes)), %i, 1) = 1", Class_));
|
||||||
Search.append(Tmp);
|
|
||||||
}
|
|
||||||
if(MaxPrice != 0){
|
|
||||||
sprintf(Tmp, " and trader.item_cost<=%i", MaxPrice);
|
|
||||||
Search.append(Tmp);
|
|
||||||
}
|
|
||||||
if(strlen(Name) > 0){
|
|
||||||
char *SafeName = RemoveApostrophes(Name);
|
|
||||||
sprintf(Tmp, " and items.name like '%%%s%%'", SafeName);
|
|
||||||
safe_delete_array(SafeName);
|
|
||||||
Search.append(Tmp);
|
|
||||||
}
|
|
||||||
if(Class_ != 0xFFFFFFFF){
|
|
||||||
sprintf(Tmp, " and mid(reverse(bin(items.classes)),%i,1)=1", Class_);
|
|
||||||
Search.append(Tmp);
|
|
||||||
}
|
|
||||||
if(Race!=0xFFFFFFFF){
|
|
||||||
sprintf(Tmp, " and mid(reverse(bin(items.races)),%i,1)=1", Race);
|
|
||||||
Search.append(Tmp);
|
|
||||||
}
|
|
||||||
if(Slot!=0xFFFFFFFF){
|
|
||||||
sprintf(Tmp, " and mid(reverse(bin(items.slots)),%i,1)=1", Slot + 1);
|
|
||||||
Search.append(Tmp);
|
|
||||||
}
|
|
||||||
if(Type!=0xFFFFFFFF){
|
|
||||||
|
|
||||||
switch(Type){
|
if(Race != 0xFFFFFFFF)
|
||||||
|
searchCriteria.append(StringFormat(" AND MID(REVERSE(BIN(items.races)), %i, 1) = 1", Race));
|
||||||
|
|
||||||
case 0:
|
if(Slot != 0xFFFFFFFF)
|
||||||
// 1H Slashing
|
searchCriteria.append(StringFormat(" AND MID(REVERSE(BIN(items.slots)), %i, 1) = 1", Slot + 1));
|
||||||
Search.append(" and items.itemtype=0 and damage>0");
|
|
||||||
break;
|
switch(Type){
|
||||||
case 31:
|
case 0xFFFFFFFF:
|
||||||
Search.append(" and items.itemclass=2");
|
break;
|
||||||
break;
|
case 0:
|
||||||
case 46:
|
// 1H Slashing
|
||||||
Search.append(" and items.spellid>0 and items.spellid<65000");
|
searchCriteria.append(" AND items.itemtype = 0 AND damage > 0");
|
||||||
break;
|
break;
|
||||||
case 47:
|
case 31:
|
||||||
Search.append(" and items.spellid=998");
|
searchCriteria.append(" AND items.itemclass = 2");
|
||||||
break;
|
break;
|
||||||
case 48:
|
case 46:
|
||||||
Search.append(" and items.spellid>=1298 and items.spellid<=1307");
|
searchCriteria.append(" AND items.spellid > 0 AND items.spellid < 65000");
|
||||||
break;
|
break;
|
||||||
case 49:
|
case 47:
|
||||||
Search.append(" and items.focuseffect>0");
|
searchCriteria.append(" AND items.spellid = 998");
|
||||||
break;
|
break;
|
||||||
default:
|
case 48:
|
||||||
sprintf(Tmp, " and items.itemtype=%i", Type);
|
searchCriteria.append(" AND items.spellid >= 1298 AND items.spellid <= 1307");
|
||||||
Search.append(Tmp);
|
break;
|
||||||
}
|
case 49:
|
||||||
}
|
searchCriteria.append(" AND items.focuseffect > 0");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
searchCriteria.append(StringFormat(" AND items.itemtype = %i", Type));
|
||||||
|
}
|
||||||
|
|
||||||
switch(ItemStat) {
|
switch(ItemStat) {
|
||||||
|
|
||||||
case STAT_AC:
|
case STAT_AC:
|
||||||
Search.append(" and items.ac>0");
|
searchCriteria.append(" AND items.ac > 0");
|
||||||
Values.append(",items.ac");
|
searchValues.append(", items.ac");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_AGI:
|
case STAT_AGI:
|
||||||
Search.append(" and items.aagi>0");
|
searchCriteria.append(" AND items.aagi > 0");
|
||||||
Values.append(",items.aagi");
|
searchValues.append(", items.aagi");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_CHA:
|
case STAT_CHA:
|
||||||
Search.append(" and items.acha>0");
|
searchCriteria.append(" AND items.acha > 0");
|
||||||
Values.append(",items.acha");
|
searchValues.append(", items.acha");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_DEX:
|
case STAT_DEX:
|
||||||
Search.append(" and items.adex>0");
|
searchCriteria.append(" AND items.adex > 0");
|
||||||
Values.append(",items.adex");
|
searchValues.append(", items.adex");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_INT:
|
case STAT_INT:
|
||||||
Search.append(" and items.aint>0");
|
searchCriteria.append(" AND items.aint > 0");
|
||||||
Values.append(",items.aint");
|
searchValues.append(", items.aint");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_STA:
|
case STAT_STA:
|
||||||
Search.append(" and items.asta>0");
|
searchCriteria.append(" AND items.asta > 0");
|
||||||
Values.append(",items.asta");
|
searchValues.append(", items.asta");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_STR:
|
case STAT_STR:
|
||||||
Search.append(" and items.astr>0");
|
searchCriteria.append(" AND items.astr > 0");
|
||||||
Values.append(",items.astr");
|
searchValues.append(", items.astr");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_WIS:
|
case STAT_WIS:
|
||||||
Search.append(" and items.awis>0");
|
searchCriteria.append(" AND items.awis > 0");
|
||||||
Values.append(",items.awis");
|
searchValues.append(", items.awis");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_COLD:
|
case STAT_COLD:
|
||||||
Search.append(" and items.cr>0");
|
searchCriteria.append(" AND items.cr > 0");
|
||||||
Values.append(",items.cr");
|
searchValues.append(", items.cr");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_DISEASE:
|
case STAT_DISEASE:
|
||||||
Search.append(" and items.dr>0");
|
searchCriteria.append(" AND items.dr > 0");
|
||||||
Values.append(",items.dr");
|
searchValues.append(", items.dr");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_FIRE:
|
case STAT_FIRE:
|
||||||
Search.append(" and items.fr>0");
|
searchCriteria.append(" AND items.fr > 0");
|
||||||
Values.append(",items.fr");
|
searchValues.append(", items.fr");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_MAGIC:
|
case STAT_MAGIC:
|
||||||
Values.append(",items.mr");
|
searchCriteria.append(" AND items.mr > 0");
|
||||||
Search.append(" and items.mr>0");
|
searchValues.append(", items.mr");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_POISON:
|
case STAT_POISON:
|
||||||
Search.append(" and items.pr>0");
|
searchCriteria.append(" AND items.pr > 0");
|
||||||
Values.append(",items.pr");
|
searchValues.append(", items.pr");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_HP:
|
case STAT_HP:
|
||||||
Search.append(" and items.hp>0");
|
searchCriteria.append(" AND items.hp > 0");
|
||||||
Values.append(",items.hp");
|
searchValues.append(", items.hp");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_MANA:
|
case STAT_MANA:
|
||||||
Search.append(" and items.mana>0");
|
searchCriteria.append(" AND items.mana > 0");
|
||||||
Values.append(",items.mana");
|
searchValues.append(", items.mana");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_ENDURANCE:
|
case STAT_ENDURANCE:
|
||||||
Search.append(" and items.endur>0");
|
searchCriteria.append(" AND items.endur > 0");
|
||||||
Values.append(",items.endur");
|
searchValues.append(", items.endur");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_ATTACK:
|
case STAT_ATTACK:
|
||||||
Search.append(" and items.attack>0");
|
searchCriteria.append(" AND items.attack > 0");
|
||||||
Values.append(",items.attack");
|
searchValues.append(", items.attack");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_HP_REGEN:
|
case STAT_HP_REGEN:
|
||||||
Search.append(" and items.regen>0");
|
searchCriteria.append(" AND items.regen > 0");
|
||||||
Values.append(",items.regen");
|
searchValues.append(", items.regen");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_MANA_REGEN:
|
case STAT_MANA_REGEN:
|
||||||
Search.append(" and items.manaregen>0");
|
searchCriteria.append(" AND items.manaregen > 0");
|
||||||
Values.append(",items.manaregen");
|
searchValues.append(", items.manaregen");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_HASTE:
|
case STAT_HASTE:
|
||||||
Search.append(" and items.haste>0");
|
searchCriteria.append(" AND items.haste > 0");
|
||||||
Values.append(",items.haste");
|
searchValues.append(", items.haste");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_DAMAGE_SHIELD:
|
case STAT_DAMAGE_SHIELD:
|
||||||
Search.append(" and items.damageshield>00");
|
searchCriteria.append(" AND items.damageshield > 0");
|
||||||
Values.append(",items.damageshield");
|
searchValues.append(", items.damageshield");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Values.append(",0");
|
searchValues.append(", 0");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Values.append(",sum(charges), items.stackable ");
|
std::string query = StringFormat("SELECT %s, SUM(charges), items.stackable "
|
||||||
|
"FROM trader, items %s GROUP BY items.id, charges, char_id LIMIT %i",
|
||||||
|
searchValues.c_str(), searchCriteria.c_str(), RuleI(Bazaar, MaxSearchResults));
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
_log(TRADING__CLIENT, "Failed to retrieve Bazaar Search!! %s %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (database.RunQuery(Query,MakeAnyLenString(&Query, "select %s from trader,items %s group by items.id,charges,char_id limit %i",
|
_log(TRADING__CLIENT, "SRCH: %s", query.c_str());
|
||||||
Values.c_str(),Search.c_str(), RuleI(Bazaar, MaxSearchResults)),errbuf,&Result)){
|
|
||||||
|
|
||||||
_log(TRADING__CLIENT, "SRCH: %s", Query);
|
int Size = 0;
|
||||||
safe_delete_array(Query);
|
uint32 ID = 0;
|
||||||
|
|
||||||
int Size = 0;
|
if (results.RowCount() == static_cast<unsigned long>(RuleI(Bazaar, MaxSearchResults)))
|
||||||
uint32 ID = 0;
|
|
||||||
|
|
||||||
if(mysql_num_rows(Result) == static_cast<unsigned long>(RuleI(Bazaar, MaxSearchResults)))
|
|
||||||
Message(15, "Your search reached the limit of %i results. Please narrow your search down by selecting more options.",
|
Message(15, "Your search reached the limit of %i results. Please narrow your search down by selecting more options.",
|
||||||
RuleI(Bazaar, MaxSearchResults));
|
RuleI(Bazaar, MaxSearchResults));
|
||||||
|
|
||||||
if(mysql_num_rows(Result) == 0){
|
if(results.RowCount() == 0) {
|
||||||
EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarReturnDone_Struct));
|
|
||||||
BazaarReturnDone_Struct* brds = (BazaarReturnDone_Struct*)outapp2->pBuffer;
|
|
||||||
brds->TraderID = ID;
|
|
||||||
brds->Type = BazaarSearchDone;
|
|
||||||
brds->Unknown008 = 0xFFFFFFFF;
|
|
||||||
brds->Unknown012 = 0xFFFFFFFF;
|
|
||||||
brds->Unknown016 = 0xFFFFFFFF;
|
|
||||||
this->QueuePacket(outapp2);
|
|
||||||
_pkt(TRADING__PACKETS,outapp2);
|
|
||||||
safe_delete(outapp2);
|
|
||||||
mysql_free_result(Result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Size = mysql_num_rows(Result) * sizeof(BazaarSearchResults_Struct);
|
|
||||||
uchar *buffer = new uchar[Size];
|
|
||||||
uchar *bufptr = buffer;
|
|
||||||
memset(buffer, 0, Size);
|
|
||||||
|
|
||||||
int Action = BazaarSearchResults;
|
|
||||||
uint32 Cost = 0;
|
|
||||||
int32 SerialNumber = 0;
|
|
||||||
char Name[64] = {0};
|
|
||||||
int Count = 0;
|
|
||||||
uint32 StatValue=0;
|
|
||||||
|
|
||||||
while ((Row = mysql_fetch_row(Result))) {
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Action);
|
|
||||||
Count = atoi(Row[0]);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Count);
|
|
||||||
SerialNumber = atoi(Row[3]);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(int32, bufptr, SerialNumber);
|
|
||||||
Client* Trader2=entity_list.GetClientByCharID(atoi(Row[1]));
|
|
||||||
if(Trader2){
|
|
||||||
ID = Trader2->GetID();
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, ID);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
_log(TRADING__CLIENT, "Unable to find trader: %i\n",atoi(Row[1]));
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, 0);
|
|
||||||
}
|
|
||||||
Cost = atoi(Row[5]);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Cost);
|
|
||||||
StatValue = atoi(Row[8]);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, StatValue);
|
|
||||||
bool Stackable = atoi(Row[10]);
|
|
||||||
if(Stackable) {
|
|
||||||
int Charges = atoi(Row[9]);
|
|
||||||
sprintf(Name, "%s(%i)", Row[7], Charges);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sprintf(Name,"%s(%i)",Row[7], Count);
|
|
||||||
|
|
||||||
memcpy(bufptr,&Name, strlen(Name));
|
|
||||||
|
|
||||||
bufptr += 64;
|
|
||||||
|
|
||||||
// Extra fields for SoD+
|
|
||||||
//
|
|
||||||
if(Trader2)
|
|
||||||
sprintf(Name, "%s", Trader2->GetName());
|
|
||||||
else
|
|
||||||
sprintf(Name, "Unknown");
|
|
||||||
|
|
||||||
memcpy(bufptr,&Name, strlen(Name));
|
|
||||||
|
|
||||||
bufptr += 64;
|
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, atoi(Row[1])); // ItemID
|
|
||||||
}
|
|
||||||
mysql_free_result(Result);
|
|
||||||
|
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_BazaarSearch, Size);
|
|
||||||
|
|
||||||
memcpy(outapp->pBuffer, buffer, Size);
|
|
||||||
|
|
||||||
this->QueuePacket(outapp);
|
|
||||||
|
|
||||||
_pkt(TRADING__PACKETS,outapp);
|
|
||||||
|
|
||||||
safe_delete(outapp);
|
|
||||||
safe_delete_array(buffer);
|
|
||||||
|
|
||||||
EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarReturnDone_Struct));
|
EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarReturnDone_Struct));
|
||||||
BazaarReturnDone_Struct* brds = (BazaarReturnDone_Struct*)outapp2->pBuffer;
|
BazaarReturnDone_Struct* brds = (BazaarReturnDone_Struct*)outapp2->pBuffer;
|
||||||
|
|
||||||
brds->TraderID = ID;
|
brds->TraderID = ID;
|
||||||
brds->Type = BazaarSearchDone;
|
brds->Type = BazaarSearchDone;
|
||||||
|
|
||||||
brds->Unknown008 = 0xFFFFFFFF;
|
brds->Unknown008 = 0xFFFFFFFF;
|
||||||
brds->Unknown012 = 0xFFFFFFFF;
|
brds->Unknown012 = 0xFFFFFFFF;
|
||||||
brds->Unknown016 = 0xFFFFFFFF;
|
brds->Unknown016 = 0xFFFFFFFF;
|
||||||
|
|
||||||
this->QueuePacket(outapp2);
|
this->QueuePacket(outapp2);
|
||||||
|
|
||||||
_pkt(TRADING__PACKETS,outapp2);
|
_pkt(TRADING__PACKETS,outapp2);
|
||||||
safe_delete(outapp2);
|
safe_delete(outapp2);
|
||||||
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
_log(TRADING__CLIENT, "Failed to retrieve Bazaar Search!! %s %s\n", Query, errbuf);
|
|
||||||
safe_delete_array(Query);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Size = results.RowCount() * sizeof(BazaarSearchResults_Struct);
|
||||||
|
uchar *buffer = new uchar[Size];
|
||||||
|
uchar *bufptr = buffer;
|
||||||
|
memset(buffer, 0, Size);
|
||||||
|
|
||||||
|
int Action = BazaarSearchResults;
|
||||||
|
uint32 Cost = 0;
|
||||||
|
int32 SerialNumber = 0;
|
||||||
|
char Name[64] = {0};
|
||||||
|
int Count = 0;
|
||||||
|
uint32 StatValue=0;
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Action);
|
||||||
|
Count = atoi(row[0]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Count);
|
||||||
|
SerialNumber = atoi(row[3]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(int32, bufptr, SerialNumber);
|
||||||
|
Client* Trader2=entity_list.GetClientByCharID(atoi(row[1]));
|
||||||
|
if(Trader2){
|
||||||
|
ID = Trader2->GetID();
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, ID);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
_log(TRADING__CLIENT, "Unable to find trader: %i\n",atoi(row[1]));
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, 0);
|
||||||
|
}
|
||||||
|
Cost = atoi(row[5]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Cost);
|
||||||
|
StatValue = atoi(row[8]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, StatValue);
|
||||||
|
bool Stackable = atoi(row[10]);
|
||||||
|
if(Stackable) {
|
||||||
|
int Charges = atoi(row[9]);
|
||||||
|
sprintf(Name, "%s(%i)", row[7], Charges);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sprintf(Name,"%s(%i)",row[7], Count);
|
||||||
|
|
||||||
|
memcpy(bufptr,&Name, strlen(Name));
|
||||||
|
|
||||||
|
bufptr += 64;
|
||||||
|
|
||||||
|
// Extra fields for SoD+
|
||||||
|
//
|
||||||
|
if(Trader2)
|
||||||
|
sprintf(Name, "%s", Trader2->GetName());
|
||||||
|
else
|
||||||
|
sprintf(Name, "Unknown");
|
||||||
|
|
||||||
|
memcpy(bufptr,&Name, strlen(Name));
|
||||||
|
|
||||||
|
bufptr += 64;
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, atoi(row[1])); // ItemID
|
||||||
|
}
|
||||||
|
|
||||||
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_BazaarSearch, Size);
|
||||||
|
|
||||||
|
memcpy(outapp->pBuffer, buffer, Size);
|
||||||
|
|
||||||
|
this->QueuePacket(outapp);
|
||||||
|
|
||||||
|
_pkt(TRADING__PACKETS,outapp);
|
||||||
|
|
||||||
|
safe_delete(outapp);
|
||||||
|
safe_delete_array(buffer);
|
||||||
|
|
||||||
|
EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarReturnDone_Struct));
|
||||||
|
BazaarReturnDone_Struct* brds = (BazaarReturnDone_Struct*)outapp2->pBuffer;
|
||||||
|
|
||||||
|
brds->TraderID = ID;
|
||||||
|
brds->Type = BazaarSearchDone;
|
||||||
|
|
||||||
|
brds->Unknown008 = 0xFFFFFFFF;
|
||||||
|
brds->Unknown012 = 0xFFFFFFFF;
|
||||||
|
brds->Unknown016 = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
this->QueuePacket(outapp2);
|
||||||
|
|
||||||
|
_pkt(TRADING__PACKETS,outapp2);
|
||||||
|
safe_delete(outapp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateTraderCustomerItemsAdded(uint32 CustomerID, TraderCharges_Struct* gis, uint32 ItemID) {
|
static void UpdateTraderCustomerItemsAdded(uint32 CustomerID, TraderCharges_Struct* gis, uint32 ItemID) {
|
||||||
@ -2297,103 +2256,92 @@ void Client::HandleTraderPriceUpdate(const EQApplicationPacket *app) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendBuyerResults(char* SearchString, uint32 SearchID) {
|
void Client::SendBuyerResults(char* searchString, uint32 searchID) {
|
||||||
|
|
||||||
// This method is called when a potential seller in the /barter window searches for matching buyers
|
// This method is called when a potential seller in the /barter window searches for matching buyers
|
||||||
//
|
//
|
||||||
_log(TRADING__BARTER, "Client::SendBuyerResults %s\n", SearchString);
|
_log(TRADING__BARTER, "Client::SendBuyerResults %s\n", searchString);
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char* escSearchString = new char[strlen(searchString) * 2 + 1];
|
||||||
char* Query = 0;
|
database.DoEscapeString(escSearchString, searchString, strlen(searchString));
|
||||||
char ItemName[64];
|
|
||||||
std::string Search, Values;
|
|
||||||
MYSQL_RES *Result;
|
|
||||||
MYSQL_ROW Row;
|
|
||||||
|
|
||||||
char*EscSearchString = new char[strlen(SearchString) * 2 + 1];
|
std::string query = StringFormat("SELECT * FROM buyer WHERE itemname LIKE '%%%s%%' ORDER BY charid LIMIT %i",
|
||||||
database.DoEscapeString(EscSearchString, SearchString, strlen(SearchString));
|
escSearchString, RuleI(Bazaar, MaxBarterSearchResults));
|
||||||
|
safe_delete_array(escSearchString);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
_log(TRADING__CLIENT, "Failed to retrieve Barter Search!! %s %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (database.RunQuery(Query,MakeAnyLenString(&Query, "select * from buyer where itemname like '%%%s%%' order by charid limit %i",
|
int numberOfRows = results.RowCount();
|
||||||
EscSearchString, RuleI(Bazaar, MaxBarterSearchResults)), errbuf, &Result)) {
|
|
||||||
|
|
||||||
int NumberOfRows = mysql_num_rows(Result);
|
if(numberOfRows == RuleI(Bazaar, MaxBarterSearchResults))
|
||||||
|
Message(15, "Your search found too many results; some are not displayed.");
|
||||||
|
else if(strlen(searchString) == 0)
|
||||||
|
Message(10, "There are %i Buy Lines.", numberOfRows);
|
||||||
|
else
|
||||||
|
Message(10, "There are %i Buy Lines that match the search string '%s'.", numberOfRows, searchString);
|
||||||
|
|
||||||
if(NumberOfRows == RuleI(Bazaar, MaxBarterSearchResults))
|
if(numberOfRows == 0)
|
||||||
Message(15, "Your search found too many results; some are not displayed.");
|
return;
|
||||||
else {
|
|
||||||
if(strlen(SearchString) == 0)
|
uint32 lastCharID = 0;
|
||||||
Message(10, "There are %i Buy Lines.", NumberOfRows);
|
Client *buyer = nullptr;
|
||||||
else
|
|
||||||
Message(10, "There are %i Buy Lines that match the search string '%s'.",
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
NumberOfRows, SearchString);
|
char itemName[64];
|
||||||
|
|
||||||
|
uint32 charID = atoi(row[0]);
|
||||||
|
uint32 buySlot = atoi(row[1]);
|
||||||
|
uint32 itemID = atoi(row[2]);
|
||||||
|
strcpy(itemName, row[3]);
|
||||||
|
uint32 quantity = atoi(row[4]);
|
||||||
|
uint32 price = atoi(row[5]);
|
||||||
|
|
||||||
|
// Each item in the search results is sent as a single fixed length packet, although the position of
|
||||||
|
// the fields varies due to the use of variable length strings. The reason the packet is so big, is
|
||||||
|
// to allow item compensation, e.g. a buyer could offer to buy a Blade Of Carnage for 10000pp plus
|
||||||
|
// other items in exchange. Item compensation is not currently supported in EQEmu.
|
||||||
|
//
|
||||||
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Barter, 940);
|
||||||
|
|
||||||
|
char *buf = (char *)outapp->pBuffer;
|
||||||
|
|
||||||
|
const Item_Struct* item = database.GetItem(itemID);
|
||||||
|
|
||||||
|
if(!item)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Save having to scan the client list when dealing with multiple buylines for the same Character.
|
||||||
|
if(charID != lastCharID) {
|
||||||
|
buyer = entity_list.GetClientByCharID(charID);
|
||||||
|
lastCharID = charID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NumberOfRows == 0) {
|
if(!buyer)
|
||||||
mysql_free_result(Result);
|
continue;
|
||||||
safe_delete_array(Query);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 LastCharID = 0;
|
VARSTRUCT_ENCODE_TYPE(uint32, buf, Barter_BuyerSearchResults); // Command
|
||||||
Client *Buyer = nullptr;
|
VARSTRUCT_ENCODE_TYPE(uint32, buf, searchID); // Match up results with the request
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, buf, buySlot); // Slot in this Buyer's list
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, buf, 0x01); // Unknown - probably a flag field
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, buf, itemID); // ItemID
|
||||||
|
VARSTRUCT_ENCODE_STRING(buf, itemName); // Itemname
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, buf, item->Icon); // Icon
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, buf, quantity); // Quantity
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, buf, 0x01); // Unknown - probably a flag field
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, buf, price); // Price
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, buf, buyer->GetID()); // Entity ID
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, buf, 0); // Flag for + Items , probably ItemCount
|
||||||
|
VARSTRUCT_ENCODE_STRING(buf, buyer->GetName()); // Seller Name
|
||||||
|
|
||||||
while ((Row = mysql_fetch_row(Result))) {
|
_pkt(TRADING__BARTER, outapp);
|
||||||
|
|
||||||
uint32 CharID = atoi(Row[0]);
|
QueuePacket(outapp);
|
||||||
uint32 BuySlot = atoi(Row[1]);
|
safe_delete(outapp);
|
||||||
uint32 ItemID = atoi(Row[2]);
|
}
|
||||||
strcpy(ItemName, Row[3]);
|
|
||||||
uint32 Quantity = atoi(Row[4]);
|
|
||||||
uint32 Price = atoi(Row[5]);
|
|
||||||
|
|
||||||
// Each item in the search results is sent as a single fixed length packet, although the position of
|
|
||||||
// the fields varies due to the use of variable length strings. The reason the packet is so big, is
|
|
||||||
// to allow item compensation, e.g. a buyer could offer to buy a Blade Of Carnage for 10000pp plus
|
|
||||||
// other items in exchange. Item compensation is not currently supported in EQEmu.
|
|
||||||
//
|
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Barter, 940);
|
|
||||||
|
|
||||||
char *Buf = (char *)outapp->pBuffer;
|
|
||||||
|
|
||||||
const Item_Struct* item = database.GetItem(ItemID);
|
|
||||||
|
|
||||||
if(!item) continue;
|
|
||||||
|
|
||||||
// Save having to scan the client list when dealing with multiple buylines for the same Character.
|
|
||||||
if(CharID != LastCharID) {
|
|
||||||
Buyer = entity_list.GetClientByCharID(CharID);
|
|
||||||
LastCharID = CharID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!Buyer) continue;
|
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerSearchResults); // Command
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, SearchID); // Match up results with the request
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot); // Slot in this Buyer's list
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01); // Unknown - probably a flag field
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, ItemID); // ItemID
|
|
||||||
VARSTRUCT_ENCODE_STRING(Buf, ItemName); // Itemname
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon); // Icon
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity); // Quantity
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01); // Unknown - probably a flag field
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price); // Price
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Buyer->GetID()); // Entity ID
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Flag for + Items , probably ItemCount
|
|
||||||
VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName()); // Seller Name
|
|
||||||
|
|
||||||
_pkt(TRADING__BARTER, outapp);
|
|
||||||
|
|
||||||
QueuePacket(outapp);
|
|
||||||
safe_delete(outapp);
|
|
||||||
}
|
|
||||||
|
|
||||||
mysql_free_result(Result);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
_log(TRADING__CLIENT, "Failed to retrieve Barter Search!! %s %s\n", Query, errbuf);
|
|
||||||
}
|
|
||||||
safe_delete_array(Query);
|
|
||||||
safe_delete_array(EscSearchString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::ShowBuyLines(const EQApplicationPacket *app) {
|
void Client::ShowBuyLines(const EQApplicationPacket *app) {
|
||||||
@ -2436,60 +2384,44 @@ void Client::ShowBuyLines(const EQApplicationPacket *app) {
|
|||||||
|
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("SELECT * FROM buyer WHERE charid = %i", Buyer->CharacterID());
|
||||||
char* Query = 0;
|
auto results = database.QueryDatabase(query);
|
||||||
char ItemName[64];
|
if (!results.Success() || results.RowCount() == 0)
|
||||||
std::string Search, Values;
|
return;
|
||||||
MYSQL_RES *Result;
|
|
||||||
MYSQL_ROW Row;
|
|
||||||
|
|
||||||
if (database.RunQuery(Query,MakeAnyLenString(&Query, "select * from buyer where charid = %i",
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
Buyer->CharacterID()),errbuf,&Result)){
|
char ItemName[64];
|
||||||
|
uint32 BuySlot = atoi(row[1]);
|
||||||
|
uint32 ItemID = atoi(row[2]);
|
||||||
|
strcpy(ItemName, row[3]);
|
||||||
|
uint32 Quantity = atoi(row[4]);
|
||||||
|
uint32 Price = atoi(row[5]);
|
||||||
|
|
||||||
if(mysql_num_rows(Result) == 0) {
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Barter, 936);
|
||||||
|
|
||||||
safe_delete_array(Query);
|
char *Buf = (char *)outapp->pBuffer;
|
||||||
|
|
||||||
mysql_free_result(Result);
|
const Item_Struct* item = database.GetItem(ItemID);
|
||||||
|
|
||||||
return;
|
if(!item)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
while ((Row = mysql_fetch_row(Result))) {
|
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerInspectWindow);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // Flag
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buf, ItemID);
|
||||||
|
VARSTRUCT_ENCODE_STRING(Buf, ItemName);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // Flag
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Buyer->GetID());
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0);
|
||||||
|
VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName());
|
||||||
|
|
||||||
uint32 BuySlot = atoi(Row[1]);
|
_pkt(TRADING__BARTER, outapp);
|
||||||
uint32 ItemID = atoi(Row[2]);
|
QueuePacket(outapp);
|
||||||
strcpy(ItemName, Row[3]);
|
}
|
||||||
uint32 Quantity = atoi(Row[4]);
|
|
||||||
uint32 Price = atoi(Row[5]);
|
|
||||||
|
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Barter, 936);
|
|
||||||
|
|
||||||
char *Buf = (char *)outapp->pBuffer;
|
|
||||||
|
|
||||||
const Item_Struct* item = database.GetItem(ItemID);
|
|
||||||
|
|
||||||
if(!item) continue;
|
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerInspectWindow);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // Flag
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, ItemID);
|
|
||||||
VARSTRUCT_ENCODE_STRING(Buf, ItemName);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // Flag
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Buyer->GetID());
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0);
|
|
||||||
VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName());
|
|
||||||
|
|
||||||
_pkt(TRADING__BARTER, outapp);
|
|
||||||
QueuePacket(outapp);
|
|
||||||
}
|
|
||||||
mysql_free_result(Result);
|
|
||||||
}
|
|
||||||
safe_delete_array(Query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SellToBuyer(const EQApplicationPacket *app) {
|
void Client::SellToBuyer(const EQApplicationPacket *app) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user