Disabling buy item supported, few crash fixes
Fix #326 - buy from merchant can have the 'buy' button disabled function buy_display_flags(Item, Spawn) return 128 end charactersProperties -> character_properties CREATE TABLE `character_properties` ( `charid` int(10) unsigned NOT NULL DEFAULT 0, `propname` varchar(64) NOT NULL DEFAULT '', `propvalue` varchar(64) NOT NULL DEFAULT '' ) ENGINE=InnoDB DEFAULT CHARSET=latin1; drop table charactersProperties; drop table charactersproperties; - some misc crash fixes, sql escape issue, etc.
This commit is contained in:
parent
852f035b45
commit
5656ad22ce
6 changed files with 40 additions and 15 deletions
EQ2/source/WorldServer
|
@ -3095,13 +3095,13 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
|
|||
}
|
||||
case COMMAND_USE: {
|
||||
Spawn* target = cmdTarget;
|
||||
if (target->IsWidget())
|
||||
if (target && target->IsWidget())
|
||||
((Widget*)target)->HandleUse(client, "use");
|
||||
break;
|
||||
}
|
||||
case COMMAND_OPEN: {
|
||||
Spawn* target = cmdTarget;
|
||||
if (target->IsWidget())
|
||||
if (target && target->IsWidget())
|
||||
((Widget*)target)->HandleUse(client, "Open", WIDGET_TYPE_DOOR);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -603,6 +603,7 @@ extern MasterItemList master_item_list;
|
|||
#define DISPLAY_FLAG_NO_GUILD_STATUS 8
|
||||
#define DISPLAY_FLAG_NO_BUYBACK 16
|
||||
#define DISPLAY_FLAG_NOT_FOR_SALE 64
|
||||
#define DISPLAY_FLAG_NO_BUY 128 // disables buying on merchant 'buy' list
|
||||
|
||||
#pragma pack(1)
|
||||
struct ItemStatsValues{
|
||||
|
|
|
@ -396,7 +396,7 @@ int EQ2Emu_lua_SendStateCommand(lua_State* state) {
|
|||
}
|
||||
else
|
||||
{
|
||||
spawn->GetZone()->SendStateCommand(spawn, new_state);
|
||||
spawn->GetZone()->QueueStateCommandToClients(spawn->GetID(), new_state);
|
||||
lua_interface->SetBooleanValue(state, true);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1864,11 +1864,11 @@ bool WorldDatabase::UpdateCharacterTimeStamp(int32 account_id, int32 character_i
|
|||
bool WorldDatabase::insertCharacterProperty(Client* client, char* propName, char* propValue) {
|
||||
Query query;
|
||||
|
||||
string update_status = string("update charactersProperties set propvalue='%s' where charid=%i and propname='%s'");
|
||||
string update_status = string("update character_properties set propvalue='%s' where charid=%i and propname='%s'");
|
||||
query.RunQuery2(Q_UPDATE, update_status.c_str(), propValue, client->GetCharacterID(), propName);
|
||||
if (!query.GetAffectedRows())
|
||||
{
|
||||
query.RunQuery2(Q_UPDATE, "insert into charactersProperties (charid, propname, propvalue) values(%i, '%s', '%s')", client->GetCharacterID(), propName, propValue);
|
||||
query.RunQuery2(Q_UPDATE, "insert into character_properties (charid, propname, propvalue) values(%i, '%s', '%s')", client->GetCharacterID(), propName, propValue);
|
||||
if (query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF) {
|
||||
LogWrite(WORLD__ERROR, 0, "World", "Error in insertCharacterProperty query '%s': %s", query.GetQuery(), query.GetError());
|
||||
return false;
|
||||
|
@ -1881,7 +1881,7 @@ bool WorldDatabase::loadCharacterProperties(Client* client) {
|
|||
Query query;
|
||||
MYSQL_ROW row;
|
||||
int32 id = 0;
|
||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT propname, propvalue FROM charactersProperties where charid = %i", client->GetCharacterID());
|
||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT propname, propvalue FROM character_properties where charid = %i", client->GetCharacterID());
|
||||
// no character found
|
||||
if (result == NULL) {
|
||||
LogWrite(PLAYER__ERROR, 0, "Player", "Error loading character properties for '%s'", client->GetPlayer()->GetName());
|
||||
|
@ -2766,12 +2766,14 @@ void WorldDatabase::SaveZoneInfo(int32 zone_id, const char* field, const char* v
|
|||
int32 WorldDatabase::GetZoneID(const char* name) {
|
||||
int32 zone_id = 0;
|
||||
Query query;
|
||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id` FROM zones WHERE `name`='%s'", name);
|
||||
char* escaped = getEscapeString(name);
|
||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `id` FROM zones WHERE `name`=\"%s\"", escaped);
|
||||
if (result && mysql_num_rows(result) > 0) {
|
||||
MYSQL_ROW row;
|
||||
row = mysql_fetch_row(result);
|
||||
zone_id = atoi(row[0]);
|
||||
}
|
||||
safe_delete_array(escaped);
|
||||
return zone_id;
|
||||
}
|
||||
|
||||
|
@ -4941,6 +4943,10 @@ int32 WorldDatabase::LoadQuests(){
|
|||
total++;
|
||||
master_quest_list.AddQuest(id, quest);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogWrite(QUEST__ERROR, 5, "Quests", "\tFAILED LOADING QUEST: '%s' (%u), check that script file exists/permissions correct: %s", name, id, (script && strlen(script)) ? script : "Not Set, Missing!");
|
||||
}
|
||||
}
|
||||
}
|
||||
LogWrite(QUEST__DEBUG, 0, "Quest", "\tLoaded %i Quest(s)", total);
|
||||
|
|
|
@ -6570,7 +6570,11 @@ void Client::BuyBack(int32 item_id, int16 quantity) {
|
|||
else
|
||||
item->details.count = closest->quantity;
|
||||
}
|
||||
if (!player->item_list.HasFreeSlot() && !player->item_list.CanStack(item))
|
||||
bool itemAdded = false;
|
||||
sint64 dispFlags = 0;
|
||||
if (item && item->GetItemScript() && lua_interface && lua_interface->RunItemScript(item->GetItemScript(), "buyback_display_flags", item, player, &dispFlags) && (dispFlags & DISPLAY_FLAG_NO_BUY))
|
||||
SimpleMessage(CHANNEL_NARRATIVE, "You do not meet all the requirements to buy this item.");
|
||||
else if (!player->item_list.HasFreeSlot() && !player->item_list.CanStack(item))
|
||||
SimpleMessage(CHANNEL_COLOR_RED, "You do not have any slots available for this item.");
|
||||
else if (player->RemoveCoins(closest->quantity * closest->price)) {
|
||||
bool removed = false;
|
||||
|
@ -6590,6 +6594,7 @@ void Client::BuyBack(int32 item_id, int16 quantity) {
|
|||
closest->save_needed = true;
|
||||
}
|
||||
AddItem(item);
|
||||
itemAdded = true;
|
||||
//EQ2Packet* outapp = player->SendInventoryUpdate(GetVersion());
|
||||
//if(outapp)
|
||||
//QueuePacket(outapp);
|
||||
|
@ -6604,6 +6609,9 @@ void Client::BuyBack(int32 item_id, int16 quantity) {
|
|||
}
|
||||
else
|
||||
SimpleMessage(CHANNEL_COLOR_RED, "You cannot afford this item.");
|
||||
|
||||
if(!itemAdded)
|
||||
safe_delete(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6645,6 +6653,12 @@ void Client::BuyItem(int32 item_id, int16 quantity) {
|
|||
if (quantity > total_available)
|
||||
quantity = total_available;
|
||||
}
|
||||
sint64 dispFlags = 0;
|
||||
if (master_item->GetItemScript() && lua_interface && lua_interface->RunItemScript(master_item->GetItemScript(), "buy_display_flags", master_item, player, &dispFlags) && (dispFlags & DISPLAY_FLAG_NO_BUY))
|
||||
{
|
||||
SimpleMessage(CHANNEL_NARRATIVE, "You do not meet all the requirements to buy this item.");
|
||||
return;
|
||||
}
|
||||
if(quantity < 1)
|
||||
{
|
||||
SimpleMessage(CHANNEL_COLOR_RED, "Merchant does not have item for purchase (quantity < 1).");
|
||||
|
@ -7019,6 +7033,10 @@ void Client::SendBuyMerchantList(bool sell) {
|
|||
packet->setArrayDataByName("quantity", ItemInfo.quantity, i);
|
||||
packet->setArrayDataByName("unknown5", 255, i);
|
||||
packet->setArrayDataByName("stack_size2", item->stack_count, i);
|
||||
|
||||
sint64 dispFlags = 0;
|
||||
if (item->GetItemScript() && lua_interface && lua_interface->RunItemScript(item->GetItemScript(), "buy_display_flags", item, player, &dispFlags))
|
||||
packet->setArrayDataByName("display_flags", (int8)dispFlags, i);
|
||||
|
||||
std::string overrideValueStr;
|
||||
// classic client isn't properly tracking this field, DoF we don't have it identified yet, but no field to cause any issues (can add later if identified)
|
||||
|
@ -7275,6 +7293,11 @@ void Client::SendBuyBackList(bool sell) {
|
|||
if (item_difficulty < 0)
|
||||
item_difficulty *= -1;
|
||||
packet->setArrayDataByName("item_difficulty", item_difficulty, i);
|
||||
|
||||
sint64 dispFlags = 0;
|
||||
if (master_item->GetItemScript() && lua_interface && lua_interface->RunItemScript(master_item->GetItemScript(), "buyback_display_flags", master_item, player, &dispFlags))
|
||||
packet->setArrayDataByName("display_flags", (int8)dispFlags, i);
|
||||
|
||||
if (buyback->quantity == 1)
|
||||
packet->setArrayDataByName("quantity", 0xFFFF, i);
|
||||
else
|
||||
|
|
|
@ -1882,9 +1882,6 @@ void ZoneServer::SendSpawnChanges(){
|
|||
Spawn* spawn = 0;
|
||||
|
||||
MSpawnList.readlock(__FUNCTION__, __LINE__);
|
||||
|
||||
int32 max_updates = 100;
|
||||
|
||||
MutexList<int32>::iterator spawn_iter = changed_spawns.begin();
|
||||
int count = 0;
|
||||
while(spawn_iter.Next()){
|
||||
|
@ -1895,9 +1892,6 @@ void ZoneServer::SendSpawnChanges(){
|
|||
}
|
||||
if (!spawn)
|
||||
changed_spawns.Remove(spawn_iter->value);
|
||||
|
||||
if(count >= max_updates)
|
||||
break;
|
||||
}
|
||||
//changed_spawns.clear() is not thread safe, advise we rely on what was removed and continue on, get any others in next batch
|
||||
|
||||
|
@ -1906,7 +1900,8 @@ void ZoneServer::SendSpawnChanges(){
|
|||
MClientList.readlock(__FUNCTION__, __LINE__);
|
||||
for (client_itr = clients.begin(); client_itr != clients.end(); client_itr++) {
|
||||
client = *client_itr;
|
||||
client->SendSpawnChanges(spawns_to_send);
|
||||
if(client)
|
||||
client->SendSpawnChanges(spawns_to_send);
|
||||
}
|
||||
MClientList.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue