mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-10 21:43:51 +00:00
(RoF2) Bazaar is now partially functional. RoF2 clients can start/end trader mode and other clients can purchase from them. No other functionality yet.
This commit is contained in:
parent
7ac7914f33
commit
811e8809cc
@ -1,5 +1,8 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 02/14/2015 ==
|
||||
Trevius: (RoF2) Bazaar is now partially functional. RoF2 clients can start/end trader mode and other clients can purchase from them. No other functionality yet.
|
||||
|
||||
== 02/12/2015 ==
|
||||
Akkadius: Implement zone based gravity, required SQL DB change
|
||||
- To test `zone` table `gravity` values, change the value and use #zheader <zoneshortname> to test
|
||||
|
||||
@ -3146,6 +3146,7 @@ struct Trader_ShowItems_Struct{
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint32 TraderID;
|
||||
/*008*/ uint32 Unknown08[3];
|
||||
/*020*/
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct{
|
||||
@ -3194,6 +3195,7 @@ struct TraderClick_Struct{
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Unknown008;
|
||||
/*012*/ uint32 Approval;
|
||||
/*016*/
|
||||
};
|
||||
|
||||
struct FormattedMessage_Struct{
|
||||
|
||||
@ -180,7 +180,7 @@ IN(OP_GMLastName, GMLastName_Struct);
|
||||
IN(OP_GMToggle, GMToggle_Struct);
|
||||
IN(OP_LFGCommand, LFG_Struct);
|
||||
IN(OP_GMGoto, GMSummon_Struct);
|
||||
IN(OP_TraderShop, TraderClick_Struct);
|
||||
INv(OP_TraderShop, TraderClick_Struct);
|
||||
IN(OP_ShopRequest, Merchant_Click_Struct);
|
||||
IN(OP_Bazaar, BazaarSearch_Struct);
|
||||
//alt:IN(OP_Bazaar, BazaarWelcome_Struct); //alternate structure for OP_Bazaar
|
||||
@ -399,7 +399,7 @@ OUT(OP_Weather, Weather_Struct);
|
||||
OUT(OP_ZoneChange, ZoneChange_Struct);
|
||||
OUT(OP_ZoneInUnknown, ZoneInUnknown_Struct);
|
||||
|
||||
//this is the set of opcodes which are allready listed
|
||||
//this is the set of opcodes which are already listed
|
||||
//in the IN section above, but are also sent OUT
|
||||
#ifdef DISJOINT_DIRECTIONS
|
||||
OUTz(OP_ClientReady); //follows OP_SetServerFilter
|
||||
@ -449,7 +449,7 @@ OUT(OP_Trader, TraderBuy_Struct); //3 possible lengths
|
||||
//alt:OUT(OP_Trader, Trader_ShowItems_Struct);
|
||||
//alt:OUT(OP_Trader, Trader_Struct);
|
||||
OUT(OP_TraderBuy, TraderBuy_Struct);
|
||||
OUT(OP_TraderShop, TraderClick_Struct);
|
||||
OUTv(OP_TraderShop, TraderClick_Struct);
|
||||
OUT(OP_WearChange, WearChange_Struct);
|
||||
OUT(OP_ZoneEntry, ServerZoneEntry_Struct);
|
||||
#endif
|
||||
|
||||
@ -3578,7 +3578,9 @@ namespace RoF2
|
||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
||||
for (uint32 i = 0; i < 200; i++)
|
||||
{
|
||||
strncpy(eq->items[i].SerialNumber, "0000000000000000", sizeof(eq->items[i].SerialNumber));
|
||||
//strncpy(eq->items[i].SerialNumber, "0000000000000000", sizeof(eq->items[i].SerialNumber));
|
||||
//snprintf(eq->items[i].SerialNumber, sizeof(eq->items[i].SerialNumber), "%016d", emu->SerialNumber[i]);
|
||||
snprintf(eq->items[i].SerialNumber, sizeof(eq->items[i].SerialNumber), "%016d", 0);
|
||||
eq->items[i].Unknown18 = 0;
|
||||
if (i < 80) {
|
||||
eq->ItemCost[i] = emu->ItemCost[i];
|
||||
@ -3596,10 +3598,11 @@ namespace RoF2
|
||||
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
|
||||
eq->Code = emu->Code;
|
||||
strncpy(eq->SerialNumber, "0000000000000000", sizeof(eq->SerialNumber));
|
||||
//strncpy(eq->SerialNumber, "0000000000000000", sizeof(eq->SerialNumber));
|
||||
//snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", 0);
|
||||
eq->TraderID = emu->TraderID;
|
||||
eq->Stacksize = 0;
|
||||
eq->Price = 0;
|
||||
//eq->Stacksize = 0;
|
||||
//eq->Price = 0;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@ -3634,6 +3637,18 @@ namespace RoF2
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_TraderShop)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(TraderClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||
|
||||
//eq->Code = emu->Unknown004;
|
||||
OUT(TraderID);
|
||||
OUT(Approval);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_TributeInfo)
|
||||
{
|
||||
ENCODE_LENGTH_ATLEAST(TributeAbility_Struct);
|
||||
@ -4215,7 +4230,6 @@ namespace RoF2
|
||||
return;
|
||||
|
||||
SETUP_DIRECT_DECODE(NewBazaarInspect_Struct, structs::NewBazaarInspect_Struct);
|
||||
MEMSET_IN(structs::NewBazaarInspect_Struct);
|
||||
|
||||
IN(Beginning.Action);
|
||||
memcpy(emu->Name, eq->Name, sizeof(emu->Name));
|
||||
@ -4912,7 +4926,6 @@ namespace RoF2
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::ClickTrader_Struct);
|
||||
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
||||
MEMSET_IN(ClickTrader_Struct);
|
||||
|
||||
emu->Code = eq->Code;
|
||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
||||
@ -4928,7 +4941,6 @@ namespace RoF2
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::Trader_ShowItems_Struct);
|
||||
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
MEMSET_IN(Trader_ShowItems_Struct);
|
||||
|
||||
emu->Code = eq->Code;
|
||||
emu->TraderID = eq->TraderID;
|
||||
@ -4939,9 +4951,8 @@ namespace RoF2
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderStatus_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderStatus_Struct, structs::TraderStatus_Struct);
|
||||
MEMSET_IN(TraderStatus_Struct);
|
||||
|
||||
emu->Code = eq->Code;
|
||||
emu->Code = eq->Code; // 11 = Start Trader, 2 = End Trader, 22 = ? - Guessing
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@ -4951,7 +4962,6 @@ namespace RoF2
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
@ -4963,6 +4973,29 @@ namespace RoF2
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_TraderShop)
|
||||
{
|
||||
uint32 psize = __packet->size;
|
||||
if (psize == sizeof(structs::TraderClick_Struct))
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderClick_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||
//MEMSET_IN(TraderClick_Struct);
|
||||
|
||||
//emu->Unknown004 = eq->Code;
|
||||
IN(TraderID);
|
||||
IN(Approval);
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): Decoded packet size (%d) to size (%d)", sizeof(structs::TraderClick_Struct), sizeof(TraderClick_Struct));
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): Decode Size Mismatch (%d), expected (%d)", psize, sizeof(structs::TraderClick_Struct));
|
||||
}
|
||||
}
|
||||
|
||||
DECODE(OP_TradeSkillCombine)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::NewCombine_Struct);
|
||||
|
||||
@ -2,10 +2,13 @@
|
||||
// Begin RoF2 Encodes
|
||||
|
||||
E(OP_SendMembershipDetails)
|
||||
E(OP_TraderShop)
|
||||
|
||||
// incoming packets that require a DECODE translation:
|
||||
// Begin RoF2 Decodes
|
||||
|
||||
D(OP_TraderShop)
|
||||
|
||||
// End RoF2 Encodes/Decodes
|
||||
|
||||
// These require Encodes/Decodes for RoF, so they do for RoF2 as well
|
||||
|
||||
@ -3200,6 +3200,13 @@ struct BecomeTrader_Struct {
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct {
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint16 TraderID;
|
||||
/*008*/ uint32 Unknown08;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct_WIP {
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ char SerialNumber[17];
|
||||
/*021*/ uint8 Unknown21;
|
||||
@ -3262,9 +3269,10 @@ struct TraderDelItem_Struct{
|
||||
};
|
||||
|
||||
struct TraderClick_Struct{
|
||||
uint32 traderid;
|
||||
uint32 unknown4[2];
|
||||
uint32 approval;
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint32 TraderID;
|
||||
/*008*/ uint32 Approval;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
struct FormattedMessage_Struct{
|
||||
|
||||
@ -124,14 +124,14 @@
|
||||
//check length of packet before decoding. Call before setup.
|
||||
#define DECODE_LENGTH_EXACT(struct_) \
|
||||
if(__packet->size != sizeof(struct_)) { \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
return; \
|
||||
}
|
||||
#define DECODE_LENGTH_ATLEAST(struct_) \
|
||||
if(__packet->size < sizeof(struct_)) { \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected at least %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
return; \
|
||||
}
|
||||
|
||||
|
||||
@ -13278,7 +13278,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
|
||||
|
||||
/*
|
||||
if (GetClientVersion() >= EQClientRoF)
|
||||
max_items = 200;
|
||||
max_items = 200;
|
||||
*/
|
||||
|
||||
//Show Items
|
||||
@ -13290,20 +13290,25 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
|
||||
{
|
||||
case BazaarTrader_EndTraderMode: {
|
||||
Trader_EndTrader();
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: End Trader Session");
|
||||
break;
|
||||
}
|
||||
case BazaarTrader_EndTransaction: {
|
||||
|
||||
Client* c = entity_list.GetClientByID(sis->TraderID);
|
||||
if (c)
|
||||
{
|
||||
c->WithCustomer(0);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: End Transaction");
|
||||
}
|
||||
else
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderBuy: Null Client Pointer");
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: Null Client Pointer");
|
||||
|
||||
break;
|
||||
}
|
||||
case BazaarTrader_ShowItems: {
|
||||
Trader_ShowItems();
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: Show Trader Items");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -13326,6 +13331,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
|
||||
{
|
||||
GetItems_Struct* gis = GetTraderItems();
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: Start Trader Mode");
|
||||
// Verify there are no NODROP or items with a zero price
|
||||
bool TradeItemsValid = true;
|
||||
|
||||
@ -13372,7 +13378,8 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
|
||||
safe_delete(gis);
|
||||
|
||||
this->Trader_StartTrader();
|
||||
|
||||
|
||||
// This refreshes the Trader window to display the End Trader button
|
||||
if (GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Trader, sizeof(TraderStatus_Struct));
|
||||
@ -13382,15 +13389,6 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
|
||||
safe_delete(outapp);
|
||||
}
|
||||
}
|
||||
else if (app->size == sizeof(TraderStatus_Struct))
|
||||
{
|
||||
TraderStatus_Struct* tss = (TraderStatus_Struct*)app->pBuffer;
|
||||
|
||||
if (tss->Code == BazaarTrader_ShowItems)
|
||||
{
|
||||
Trader_ShowItems();
|
||||
}
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: Unknown TraderStruct code of: %i\n",
|
||||
ints->Code);
|
||||
@ -13398,9 +13396,35 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
|
||||
Log.Out(Logs::General, Logs::Error, "Unknown TraderStruct code of: %i\n", ints->Code);
|
||||
}
|
||||
}
|
||||
else if (app->size == sizeof(TraderStatus_Struct))
|
||||
{
|
||||
TraderStatus_Struct* tss = (TraderStatus_Struct*)app->pBuffer;
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: Trader Status Code: %d", tss->Code);
|
||||
|
||||
switch (tss->Code)
|
||||
{
|
||||
case BazaarTrader_EndTraderMode: {
|
||||
Trader_EndTrader();
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: End Trader Session");
|
||||
break;
|
||||
}
|
||||
case BazaarTrader_ShowItems: {
|
||||
Trader_ShowItems();
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: Show Trader Items");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Unhandled action code in OP_Trader ShowItems_Struct");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (app->size == sizeof(TraderPriceUpdate_Struct))
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_Trader: Trader Price Update");
|
||||
HandleTraderPriceUpdate(app);
|
||||
}
|
||||
else {
|
||||
@ -13425,8 +13449,8 @@ void Client::Handle_OP_TraderBuy(const EQApplicationPacket *app)
|
||||
TraderBuy_Struct* tbs = (TraderBuy_Struct*)app->pBuffer;
|
||||
|
||||
if (Client* Trader = entity_list.GetClientByID(tbs->TraderID)){
|
||||
|
||||
BuyTraderItem(tbs, Trader, app);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderBuy: Buy Trader Item ");
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderBuy: Null Client Pointer");
|
||||
@ -13502,23 +13526,24 @@ void Client::Handle_OP_TraderShop(const EQApplicationPacket *app)
|
||||
// browse their goods.
|
||||
//
|
||||
|
||||
TraderClick_Struct* tcs = (TraderClick_Struct*)app->pBuffer;
|
||||
|
||||
if (app->size != sizeof(TraderClick_Struct)) {
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Returning due to struct size mismatch");
|
||||
|
||||
Log.Out(Logs::General, Logs::Error, "Wrong size: OP_TraderShop, size=%i, expected %i", app->size, sizeof(TraderClick_Struct));
|
||||
return;
|
||||
}
|
||||
|
||||
TraderClick_Struct* tcs = (TraderClick_Struct*)app->pBuffer;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderShop, sizeof(TraderClick_Struct));
|
||||
|
||||
TraderClick_Struct* outtcs = (TraderClick_Struct*)outapp->pBuffer;
|
||||
|
||||
Client* Customer = entity_list.GetClientByID(tcs->TraderID);
|
||||
Client* Trader = entity_list.GetClientByID(tcs->TraderID);
|
||||
|
||||
if (Customer)
|
||||
outtcs->Approval = Customer->WithCustomer(GetID());
|
||||
if (Trader)
|
||||
{
|
||||
outtcs->Approval = Trader->WithCustomer(GetID());
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Shop Request (%s) to (%s) with Approval: %d", GetCleanName(), Trader->GetCleanName(), outtcs->Approval);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: entity_list.GetClientByID(tcs->traderid)"
|
||||
" returned a nullptr pointer");
|
||||
@ -13533,11 +13558,15 @@ void Client::Handle_OP_TraderShop(const EQApplicationPacket *app)
|
||||
|
||||
|
||||
if (outtcs->Approval) {
|
||||
this->BulkSendTraderInventory(Customer->CharacterID());
|
||||
Customer->Trader_CustomerBrowsing(this);
|
||||
this->BulkSendTraderInventory(Trader->CharacterID());
|
||||
Trader->Trader_CustomerBrowsing(this);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Inventory Sent");
|
||||
}
|
||||
else
|
||||
{
|
||||
Message_StringID(clientMessageYellow, TRADER_BUSY);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Busy");
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
|
||||
@ -1138,7 +1138,6 @@ void Client::Trader_EndTrader() {
|
||||
|
||||
QueuePacket(outapp);
|
||||
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
WithCustomer(0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user