From 5fec840f0696282b169968b41fbc55d484cf05ee Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 13:58:36 -0700 Subject: [PATCH 01/89] AssignWaypoints converted to QueryDatabase --- zone/waypoints.cpp | 135 +++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 77 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index eb22f13a8..d0da194e8 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -869,97 +869,78 @@ void NPC::AssignWaypoints(int32 grid) { return; } - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - bool GridErr = false, WPErr = false; Waypoints.clear(); + roamer = false; // Retrieve the wander and pause types for this grid - if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `type`,`type2` FROM `grid` WHERE `id`=%i AND `zoneid`=%i",grid,zone->GetZoneID()),errbuf, &result)) - { - if((row = mysql_fetch_row(result))) - { - if(row[0] != 0) - wandertype = atoi(row[0]); - else - wandertype = 0; - if(row[1] != 0) - pausetype = atoi(row[1]); - else - pausetype = 0; - } - else // No grid record found in this zone for the given ID - GridErr = true; - mysql_free_result(result); + std::string query = StringFormat("SELECT `type`, `type2` FROM `grid` WHERE `id` = %i AND `zoneid` = %i", grid, zone->GetZoneID()); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str()); + return; } - else // DB query error! - { - GridErr = true; - LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign grid %u to mob %s: %s", grid, name, errbuf); - } - safe_delete_array(query); - if(!GridErr) - { - this->CastToNPC()->SetGrid(grid); // Assign grid number + if (results.RowCount() == 0) + return; - // Retrieve all waypoints for this grid - if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `x`,`y`,`z`,`pause`,`heading` FROM grid_entries WHERE `gridid`=%i AND `zoneid`=%i ORDER BY `number`",grid,zone->GetZoneID()),errbuf,&result)) - { - roamer = true; - max_wp = -1; // Initialize it; will increment it for each waypoint successfully added to the list + auto row = results.begin(); - while((row = mysql_fetch_row(result))) - { - if(row[0] != 0 && row[1] != 0 && row[2] != 0 && row[3] != 0) - { - wplist newwp; - newwp.index = ++max_wp; - newwp.x = atof(row[0]); - newwp.y = atof(row[1]); - newwp.z = atof(row[2]); + wandertype = atoi(row[0]); + pausetype = atoi(row[1]); - if(zone->HasMap() && RuleB(Map, FixPathingZWhenLoading) ) - { - if(!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() || - (zone->HasWaterMap() && !zone->watermap->InWater(newwp.x, newwp.y, newwp.z))) - { - Map::Vertex dest(newwp.x, newwp.y, newwp.z); - float newz = zone->zonemap->FindBestZ(dest, nullptr); + this->CastToNPC()->SetGrid(grid); // Assign grid number - if( (newz > -2000) && ABS(newz-dest.z) < RuleR(Map, FixPathingZMaxDeltaLoading)) - newwp.z = newz + 1; - } - } + // Retrieve all waypoints for this grid + query = StringFormat("SELECT `x`,`y`,`z`,`pause`,`heading` " + "FROM grid_entries WHERE `gridid` = %i AND `zoneid` = %i " + "ORDER BY `number`", grid, zone->GetZoneID()); + results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign waypoints from grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str()); + return; + } + + roamer = true; + max_wp = 0; // Initialize it; will increment it for each waypoint successfully added to the list + + for (auto row = results.begin(); row != results.end(); ++row, ++max_wp) + { + wplist newwp; + newwp.index = max_wp; + newwp.x = atof(row[0]); + newwp.y = atof(row[1]); + newwp.z = atof(row[2]); + + if(zone->HasMap() && RuleB(Map, FixPathingZWhenLoading) ) + { + if(!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() || + (zone->HasWaterMap() && !zone->watermap->InWater(newwp.x, newwp.y, newwp.z))) + { + Map::Vertex dest(newwp.x, newwp.y, newwp.z); + + float newz = zone->zonemap->FindBestZ(dest, nullptr); + + if( (newz > -2000) && ABS(newz-dest.z) < RuleR(Map, FixPathingZMaxDeltaLoading)) + newwp.z = newz + 1; + } + } + + newwp.pause = atoi(row[3]); + newwp.heading = atof(row[4]); + Waypoints.push_back(newwp); + } - newwp.pause = atoi(row[3]); - newwp.heading = atof(row[4]); - Waypoints.push_back(newwp); - } - } - mysql_free_result(result); - } - else // DB query error! - { - WPErr = true; - LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign waypoints from grid %u to mob %s: %s", grid, name, errbuf); - } - safe_delete_array(query); - } // end if (!GridErr) if(Waypoints.size() < 2) { roamer = false; - } else if(!GridErr && !WPErr) { - UpdateWaypoint(0); - SetWaypointPause(); - if (wandertype == 1 || wandertype == 2 || wandertype == 5) - CalculateNewWaypoint(); - } else { - roamer = false; } + + UpdateWaypoint(0); + SetWaypointPause(); + + if (wandertype == 1 || wandertype == 2 || wandertype == 5) + CalculateNewWaypoint(); + } void Mob::SendTo(float new_x, float new_y, float new_z) { From b6547293839be356c004051e1fe7e6fb95470722 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 14:03:00 -0700 Subject: [PATCH 02/89] GetGridType2 converted to QueryDatabase --- zone/waypoints.cpp | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index d0da194e8..44f8d061f 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1030,24 +1030,21 @@ int ZoneDatabase::GetHighestGrid(uint32 zoneid) { } uint8 ZoneDatabase::GetGridType2(uint32 grid, uint16 zoneid) { - char *query = 0; - char errbuff[MYSQL_ERRMSG_SIZE]; - MYSQL_RES *result; - MYSQL_ROW row; - int type2 = 0; - if (RunQuery(query, MakeAnyLenString(&query,"SELECT type2 from grid where id = %i and zoneid = %i",grid,zoneid),errbuff,&result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - type2 = atoi( row[0] ); - } - mysql_free_result(result); - } else { - LogFile->write(EQEMuLog::Error, "Error in GetGridType2 query '%s': %s", query, errbuff); - safe_delete_array(query); - } - return(type2); + int type2 = 0; + std::string query = StringFormat("SELECT type2 FROM grid WHERE id = %i AND zoneid = %i", grid, zoneid); + auto results = QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in GetGridType2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + return 0; + } + + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + + return atoi(row[0]); } bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp) { From 5f2db0d1cbef149585eb01d95c4e3df95d0aef90 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 14:08:43 -0700 Subject: [PATCH 03/89] GetWaypoints converted to QueryDatabase --- zone/waypoints.cpp | 48 ++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 44f8d061f..c3a1331fb 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1048,31 +1048,29 @@ uint8 ZoneDatabase::GetGridType2(uint32 grid, uint16 zoneid) { } bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp) { - char *query = 0; - char errbuff[MYSQL_ERRMSG_SIZE]; - MYSQL_RES *result; - MYSQL_ROW row; - if (RunQuery(query, MakeAnyLenString(&query,"SELECT x, y, z, pause, heading from grid_entries where gridid = %i and number = %i and zoneid = %i",grid,num,zoneid),errbuff,&result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - if ( wp ) { - wp->x = atof( row[0] ); - wp->y = atof( row[1] ); - wp->z = atof( row[2] ); - wp->pause = atoi( row[3] ); - wp->heading = atof( row[4] ); - } - mysql_free_result(result); - return true; - } - mysql_free_result(result); - } - else { - LogFile->write(EQEMuLog::Error, "Error in GetWaypoints query '%s': %s", query, errbuff); - safe_delete_array(query); - } - return false; + + std::string query = StringFormat("SELECT x, y, z, pause, heading FROM grid_entries " + "WHERE gridid = %i AND number = %i AND zoneid = %i", grid, num, zoneid); + auto results = QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in GetWaypoints query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + return false; + } + + if (results.RowCount() != 1) + return false; + + auto row = results.begin(); + + if (wp) { + wp->x = atof( row[0] ); + wp->y = atof( row[1] ); + wp->z = atof( row[2] ); + wp->pause = atoi( row[3] ); + wp->heading = atof( row[4] ); + } + + return true; } void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid) From cab0beb77f21b502b0e441c3b38e6d1eaff5a210 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 14:32:04 -0700 Subject: [PATCH 04/89] AssignGrid converted to QueryDatabase --- zone/waypoints.cpp | 155 ++++++++++++++++++--------------------------- 1 file changed, 62 insertions(+), 93 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index c3a1331fb..46304b31e 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1049,6 +1049,9 @@ uint8 ZoneDatabase::GetGridType2(uint32 grid, uint16 zoneid) { bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp) { + if (wp == nullptr) + return false; + std::string query = StringFormat("SELECT x, y, z, pause, heading FROM grid_entries " "WHERE gridid = %i AND number = %i AND zoneid = %i", grid, num, zoneid); auto results = QueryDatabase(query); @@ -1062,122 +1065,88 @@ bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* auto row = results.begin(); - if (wp) { - wp->x = atof( row[0] ); - wp->y = atof( row[1] ); - wp->z = atof( row[2] ); - wp->pause = atoi( row[3] ); - wp->heading = atof( row[4] ); - } + wp->x = atof(row[0]); + wp->y = atof(row[1]); + wp->z = atof(row[2]); + wp->pause = atoi(row[3]); + wp->heading = atof(row[4]); return true; } void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid) { - char *query = 0; - char errbuf[MYSQL_ERRMSG_SIZE]; - MYSQL_RES *result; - MYSQL_ROW row; int matches = 0, fuzzy = 0, spawn2id = 0; - uint32 affected_rows; float dbx = 0, dby = 0; // looks like most of the stuff in spawn2 is straight integers // so let's try that first - if(!RunQuery( - query, - MakeAnyLenString( - &query, - "SELECT id,x,y FROM spawn2 WHERE zone='%s' AND x=%i AND y=%i", - zone->GetShortName(), (int)x, (int)y - ), - errbuf, - &result - )) { - LogFile->write(EQEMuLog::Error, "Error querying spawn2 '%s': '%s'", query, errbuf); - return; + std::string query = StringFormat("SELECT id, x, y FROM spawn2 WHERE zone = '%s' AND x = %i AND y = %i", + zone->GetShortName(), (int)x, (int)y); + auto results = QueryDatabase(query); + if(!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error querying spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + return; } - safe_delete_array(query); // how much it's allowed to be off by #define _GASSIGN_TOLERANCE 1.0 - if(!(matches = mysql_num_rows(result))) // try a fuzzy match if that didn't find it + if(results.RowCount() == 0) // try a fuzzy match if that didn't find it { - mysql_free_result(result); - if(!RunQuery( - query, - MakeAnyLenString( - &query, - "SELECT id,x,y FROM spawn2 WHERE zone='%s' AND " - "ABS( ABS(x) - ABS(%f) ) < %f AND " - "ABS( ABS(y) - ABS(%f) ) < %f", - zone->GetShortName(), x, _GASSIGN_TOLERANCE, y, _GASSIGN_TOLERANCE - ), - errbuf, - &result - )) { - LogFile->write(EQEMuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query, errbuf); + query = StringFormat("SELECT id,x,y FROM spawn2 WHERE zone='%s' AND " + "ABS( ABS(x) - ABS(%f) ) < %f AND " + "ABS( ABS(y) - ABS(%f) ) < %f", + zone->GetShortName(), x, _GASSIGN_TOLERANCE, y, _GASSIGN_TOLERANCE); + results = QueryDatabase(query); + if(!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return; } - safe_delete_array(query); + fuzzy = 1; - if(!(matches = mysql_num_rows(result))) - mysql_free_result(result); + matches = results.RowCount(); } - if(matches) + + if (matches == 0) { + client->Message(0, "ERROR: Unable to assign grid - can't find it in spawn2"); + return; + } + + if(matches == 1) { - if(matches > 1) - { - client->Message(0, "ERROR: Unable to assign grid - multiple spawn2 rows match"); - mysql_free_result(result); - } - else - { - row = mysql_fetch_row(result); - spawn2id = atoi(row[0]); - dbx = atof(row[1]); - dby = atof(row[2]); - if(!RunQuery( - query, - MakeAnyLenString( - &query, - "UPDATE spawn2 SET pathgrid = %d WHERE id = %d", grid, spawn2id - ), - errbuf, - &result, - &affected_rows - )) { - LogFile->write(EQEMuLog::Error, "Error updating spawn2 '%s': '%s'", query, errbuf); - return; - } - if(affected_rows == 1) - { - if(client) client->LogSQL(query); - if(fuzzy) - { - float difference; - difference = sqrtf(pow(fabs(x-dbx),2) + pow(fabs(y-dby),2)); - client->Message(0, - "Grid assign: spawn2 id = %d updated - fuzzy match: deviation %f", - spawn2id, difference - ); - } - else - { - client->Message(0, "Grid assign: spawn2 id = %d updated - exact match", spawn2id); - } - } - else - { - client->Message(0, "ERROR: found spawn2 id %d but the update query failed", spawn2id); - } - } + client->Message(0, "ERROR: Unable to assign grid - multiple spawn2 rows match"); + return; } - else + + auto row = results.begin(); + + spawn2id = atoi(row[0]); + dbx = atof(row[1]); + dby = atof(row[2]); + + query = StringFormat("UPDATE spawn2 SET pathgrid = %d WHERE id = %d", grid, spawn2id); + results = QueryDatabase(query); + if (!results.Success()) { - client->Message(0, "ERROR: Unable to assign grid - can't find it in spawn2"); - } + LogFile->write(EQEMuLog::Error, "Error updating spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + return; + } + + if (results.RowsAffected() != 1) { + client->Message(0, "ERROR: found spawn2 id %d but the update query failed", spawn2id); + return; + } + + if(client) + client->LogSQL(query.c_str()); + + if(!fuzzy) { + client->Message(0, "Grid assign: spawn2 id = %d updated - exact match", spawn2id); + return; + } + + float difference = sqrtf(pow(fabs(x - dbx) , 2) + pow(fabs(y - dby), 2)); + client->Message(0, "Grid assign: spawn2 id = %d updated - fuzzy match: deviation %f", spawn2id, difference); } /****************** From 334e29a6d66ce6815fbe19b336f335cb547a09ab Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 14:40:47 -0700 Subject: [PATCH 05/89] ModifyGrid converted to QueryDatabase --- zone/waypoints.cpp | 56 ++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 46304b31e..571cb5e13 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1156,41 +1156,43 @@ void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid) * type,type2: The type and type2 values for the grid being created (ignored if grid is being deleted) * zoneid: The ID number of the zone the grid is being created/deleted in */ +void ZoneDatabase::ModifyGrid(Client *client, bool remove, uint32 id, uint8 type, uint8 type2, uint16 zoneid) { -void ZoneDatabase::ModifyGrid(Client *c, bool remove, uint32 id, uint8 type, uint8 type2, uint16 zoneid) { - char *query = 0; - char errbuf[MYSQL_ERRMSG_SIZE]; if (!remove) { - if(!RunQuery(query, MakeAnyLenString(&query,"INSERT INTO grid(id,zoneid,type,type2) VALUES(%i,%i,%i,%i)",id,zoneid,type,type2), errbuf)) { - LogFile->write(EQEMuLog::Error, "Error creating grid entry '%s': '%s'", query, errbuf); - } else { - if(c) c->LogSQL(query); - } - safe_delete_array(query); + std::string query = StringFormat("INSERT INTO grid(id, zoneid, type, type2) " + "VALUES (%i, %i, %i, %i)", id, zoneid, type, type2); + auto results = QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error creating grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + return; + } + + if(client) + client->LogSQL(query.c_str()); + + return; } - else - { - if(!RunQuery(query, MakeAnyLenString(&query,"DELETE FROM grid where id=%i",id), errbuf)) { - LogFile->write(EQEMuLog::Error, "Error deleting grid '%s': '%s'", query, errbuf); - } else { - if(c) c->LogSQL(query); - } - safe_delete_array(query); - query = 0; - if(!RunQuery(query, MakeAnyLenString(&query,"DELETE FROM grid_entries WHERE zoneid=%i AND gridid=%i",zoneid,id), errbuf)) { - LogFile->write(EQEMuLog::Error, "Error deleting grid entries '%s': '%s'", query, errbuf); - } else { - if(c) c->LogSQL(query); - } - safe_delete_array(query); - } -} /*** END ZoneDatabase::ModifyGrid() ***/ + + std::string query = StringFormat("DELETE FROM grid where id=%i", id); + auto results = QueryDatabase(query); + if (!results.Success()) + LogFile->write(EQEMuLog::Error, "Error deleting grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + else if(client) + client->LogSQL(query.c_str()); + + query = StringFormat("DELETE FROM grid_entries WHERE zoneid = %i AND gridid = %i", zoneid, id); + results = QueryDatabase(query); + if(!results.Success()) + LogFile->write(EQEMuLog::Error, "Error deleting grid entries '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + else if(client) + client->LogSQL(query.c_str()); + +} /************************************** * AddWP - Adds a new waypoint to a specific grid for a specific zone. */ - void ZoneDatabase::AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading) { char *query = 0; From 06b0bd6da45c1d4f0a05d0c7fba19535585640b5 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 14:44:32 -0700 Subject: [PATCH 06/89] AddWP converted to QueryDatabase --- zone/waypoints.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 571cb5e13..a4a4ba40a 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1193,18 +1193,20 @@ void ZoneDatabase::ModifyGrid(Client *client, bool remove, uint32 id, uint8 type /************************************** * AddWP - Adds a new waypoint to a specific grid for a specific zone. */ -void ZoneDatabase::AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading) +void ZoneDatabase::AddWP(Client *client, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading) { - char *query = 0; - char errbuf[MYSQL_ERRMSG_SIZE]; - - if(!RunQuery(query,MakeAnyLenString(&query,"INSERT INTO grid_entries (gridid,zoneid,`number`,x,y,z,pause,heading) values (%i,%i,%i,%f,%f,%f,%i,%f)",gridid,zoneid,wpnum,xpos,ypos,zpos,pause,heading), errbuf)) { - LogFile->write(EQEMuLog::Error, "Error adding waypoint '%s': '%s'", query, errbuf); - } else { - if(c) c->LogSQL(query); + std::string query = StringFormat("INSERT INTO grid_entries (gridid, zoneid, `number`, x, y, z, pause, heading) " + "VALUES (%i, %i, %i, %f, %f, %f, %i, %f)", + gridid, zoneid, wpnum, xpos, ypos, zpos, pause, heading); + auto results = QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error adding waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + return; } - safe_delete_array(query); -} /*** END ZoneDatabase::AddWP() ***/ + + if(client) + client->LogSQL(query.c_str()); +} /********** From c466317082eaa945c4c4eb2e891a861b186b48c0 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 14:48:57 -0700 Subject: [PATCH 07/89] DeleteWaypoint converted to QueryDatabase --- zone/waypoints.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index a4a4ba40a..81d5c4ed4 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1219,19 +1219,20 @@ void ZoneDatabase::AddWP(Client *client, uint32 gridid, uint32 wpnum, float xpos * wp_num: The number of the waypoint being deleted * zoneid: The ID number of the zone that contains the waypoint being deleted */ - -void ZoneDatabase::DeleteWaypoint(Client *c, uint32 grid_num, uint32 wp_num, uint16 zoneid) +void ZoneDatabase::DeleteWaypoint(Client *client, uint32 grid_num, uint32 wp_num, uint16 zoneid) { - char *query=0; - char errbuf[MYSQL_ERRMSG_SIZE]; - - if(!RunQuery(query, MakeAnyLenString(&query,"DELETE FROM grid_entries where gridid=%i and zoneid=%i and `number`=%i",grid_num,zoneid,wp_num), errbuf)) { - LogFile->write(EQEMuLog::Error, "Error deleting waypoint '%s': '%s'", query, errbuf); - } else { - if(c) c->LogSQL(query); + std::string query = StringFormat("DELETE FROM grid_entries WHERE " + "gridid = %i AND zoneid = %i AND `number` = %i", + grid_num, zoneid, wp_num); + auto results = QueryDatabase(query); + if(!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error deleting waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + return; } - safe_delete_array(query); -} /*** END ZoneDatabase::DeleteWaypoint() ***/ + + if(client) + client->LogSQL(query.c_str()); +} /****************** From 8b69de46e9309ac019b459a01bdd8c8523aa2e69 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 15:06:53 -0700 Subject: [PATCH 08/89] AddWPForSpawn converted to QueryDatabase --- zone/waypoints.cpp | 121 ++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 68 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 81d5c4ed4..111d091e4 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1242,92 +1242,77 @@ void ZoneDatabase::DeleteWaypoint(Client *client, uint32 grid_num, uint32 wp_num * Returns 0 if the function didn't have to create a new grid. If the function had to create a new grid for the spawn, then the ID of * the created grid is returned. */ +uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading) { -uint32 ZoneDatabase::AddWPForSpawn(Client *c, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading) { - char *query = 0; - uint32 grid_num, // The grid number the spawn is assigned to (if spawn has no grid, will be the grid number we end up creating) - next_wp_num; // The waypoint number we should be assigning to the new waypoint - bool CreatedNewGrid; // Did we create a new grid in this function? - MYSQL_RES *result; - MYSQL_ROW row; - char errbuf[MYSQL_ERRMSG_SIZE]; + uint32 grid_num; // The grid number the spawn is assigned to (if spawn has no grid, will be the grid number we end up creating) + uint32 next_wp_num; // The waypoint number we should be assigning to the new waypoint + bool createdNewGrid; // Did we create a new grid in this function? // See what grid number our spawn is assigned - if(RunQuery(query, MakeAnyLenString(&query,"SELECT pathgrid FROM spawn2 WHERE id=%i",spawn2id),errbuf,&result)) - { - safe_delete_array(query); - if(mysql_num_rows(result) > 0) - { - row = mysql_fetch_row(result); - grid_num = atoi(row[0]); - } - else // This spawn ID was not found in the `spawn2` table - return 0; - - mysql_free_result(result); - } - else { // Query error - LogFile->write(EQEMuLog::Error, "Error setting pathgrid '%s': '%s'", query, errbuf); + std::string query = StringFormat("SELECT pathgrid FROM spawn2 WHERE id = %i", spawn2id); + auto results = QueryDatabase(query); + if (!results.Success()) { + // Query error + LogFile->write(EQEMuLog::Error, "Error setting pathgrid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return 0; } - if (grid_num == 0) // Our spawn doesn't have a grid assigned to it -- we need to create a new grid and assign it to the spawn - { - CreatedNewGrid = true; - if((grid_num = GetFreeGrid(zoneid)) == 0) // There are no grids for the current zone -- create Grid #1 - grid_num = 1; + if (results.RowCount() == 0) + return 0; - if(!RunQuery(query, MakeAnyLenString(&query,"insert into grid set id='%i',zoneid= %i, type='%i', type2='%i'",grid_num,zoneid,type1,type2), errbuf)) { - LogFile->write(EQEMuLog::Error, "Error adding grid '%s': '%s'", query, errbuf); - } else { - if(c) c->LogSQL(query); - } - safe_delete_array(query); + auto row = results.begin(); + grid_num = atoi(row[0]); - query = 0; - if(!RunQuery(query, MakeAnyLenString(&query,"update spawn2 set pathgrid='%i' where id='%i'",grid_num,spawn2id), errbuf)) { - LogFile->write(EQEMuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query, errbuf); - } else { - if(c) c->LogSQL(query); - } - safe_delete_array(query); + if (grid_num == 0) + { // Our spawn doesn't have a grid assigned to it -- we need to create a new grid and assign it to the spawn + createdNewGrid = true; + grid_num = GetFreeGrid(zoneid); + if(grid_num == 0) // There are no grids for the current zone -- create Grid #1 + grid_num = 1; + + query = StringFormat("INSERT INTO grid SET id = '%i', zoneid = %i, type ='%i', type2 = '%i'", + grid_num, zoneid, type1, type2); + results = QueryDatabase(query); + if(!results.Success()) + LogFile->write(EQEMuLog::Error, "Error adding grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + else if(client) + client->LogSQL(query.c_str()); + + query = StringFormat("UPDATE spawn2 SET pathgrid = '%i' WHERE id = '%i'", grid_num, spawn2id); + results = QueryDatabase(query); + if(!results.Success()) + LogFile->write(EQEMuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + else if(client) + client->LogSQL(query.c_str()); } else // NPC had a grid assigned to it - CreatedNewGrid = false; - + createdNewGrid = false; // Find out what the next waypoint is for this grid - query = 0; - if(RunQuery(query, MakeAnyLenString(&query,"SELECT max(`number`) FROM grid_entries WHERE zoneid='%i' AND gridid='%i'",zoneid,grid_num),errbuf,&result)) - { - safe_delete_array(query); - row = mysql_fetch_row(result); - if(row[0] != 0) - next_wp_num = atoi(row[0]) + 1; - else // No waypoints in this grid yet - next_wp_num = 1; + query = StringFormat("SELECT max(`number`) FROM grid_entries WHERE zoneid = '%i' AND gridid = '%i'", zoneid, grid_num); - mysql_free_result(result); - } - else { // Query error - LogFile->write(EQEMuLog::Error, "Error getting next waypoint id '%s': '%s'", query, errbuf); + if(!results.Success()) { // Query error + LogFile->write(EQEMuLog::Error, "Error getting next waypoint id '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return 0; } - query = 0; - if(!RunQuery(query, MakeAnyLenString(&query,"INSERT INTO grid_entries(gridid,zoneid,`number`,x,y,z,pause,heading) VALUES (%i,%i,%i,%f,%f,%f,%i,%f)",grid_num,zoneid,next_wp_num,xpos,ypos,zpos,pause,heading), errbuf)) { - LogFile->write(EQEMuLog::Error, "Error adding grid entry '%s': '%s'", query, errbuf); - } else { - if(c) c->LogSQL(query); - } - safe_delete_array(query); + row = results.begin(); + if(row[0] != 0) + next_wp_num = atoi(row[0]) + 1; + else // No waypoints in this grid yet + next_wp_num = 1; - if(CreatedNewGrid) - return grid_num; - - return 0; -} /*** END ZoneDatabase::AddWPForSpawn() ***/ + query = StringFormat("INSERT INTO grid_entries(gridid, zoneid, `number`, x, y, z, pause, heading) " + "VALUES (%i, %i, %i, %f, %f, %f, %i, %f)", + grid_num, zoneid, next_wp_num, xpos, ypos, zpos, pause, heading); + results = QueryDatabase(query); + if(!results.Success()) + LogFile->write(EQEMuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); + else if(client) + client->LogSQL(query.c_str()); + return createdNewGrid? grid_num: 0; +} uint32 ZoneDatabase::GetFreeGrid(uint16 zoneid) { char *query = 0; From 2f30488cd55af2cad3716b8d955a3d706d831331 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 15:11:12 -0700 Subject: [PATCH 09/89] GetFreeGrid converted to QueryDatabase --- zone/waypoints.cpp | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 111d091e4..a67943b5c 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1315,28 +1315,22 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, } uint32 ZoneDatabase::GetFreeGrid(uint16 zoneid) { - char *query = 0; - char errbuf[MYSQL_ERRMSG_SIZE]; - MYSQL_RES *result; - MYSQL_ROW row; - if (RunQuery(query, MakeAnyLenString(&query,"SELECT max(id) from grid where zoneid = %i",zoneid),errbuf,&result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - uint32 tmp=0; - if (row[0]) - tmp = atoi(row[0]); - mysql_free_result(result); - tmp++; - return tmp; - } - mysql_free_result(result); + + std::string query = StringFormat("SELECT max(id) FROM grid WHERE zoneid = %i", zoneid); + auto results = QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in GetFreeGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + return 0; } - else { - LogFile->write(EQEMuLog::Error, "Error in GetFreeGrid query '%s': %s", query, errbuf); - safe_delete_array(query); - } - return 0; + + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + uint32 freeGridID = 1; + freeGridID = atoi(row[0]) + 1; + + return freeGridID; } int ZoneDatabase::GetHighestWaypoint(uint32 zoneid, uint32 gridid) { From fe718a81f3ed6bbff96ed8082a0918bd789d0ee0 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 20 Aug 2014 15:14:36 -0700 Subject: [PATCH 10/89] GetHighestWaypoint converted to QueryDatabase --- zone/waypoints.cpp | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index a67943b5c..2119ea384 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1334,26 +1334,20 @@ uint32 ZoneDatabase::GetFreeGrid(uint16 zoneid) { } int ZoneDatabase::GetHighestWaypoint(uint32 zoneid, uint32 gridid) { - char *query = 0; - char errbuff[MYSQL_ERRMSG_SIZE]; - MYSQL_RES *result; - MYSQL_ROW row; - int res = 0; - if (RunQuery(query, MakeAnyLenString(&query, - "SELECT COALESCE(MAX(number), 0) FROM grid_entries WHERE zoneid = %i AND gridid = %i", - zoneid, gridid),errbuff,&result)) { - safe_delete_array(query); - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - res = atoi( row[0] ); - } - mysql_free_result(result); - } else { - LogFile->write(EQEMuLog::Error, "Error in GetHighestWaypoint query '%s': %s", query, errbuff); - safe_delete_array(query); + + std::string query = StringFormat("SELECT COALESCE(MAX(number), 0) FROM grid_entries " + "WHERE zoneid = %i AND gridid = %i", zoneid, gridid); + auto results = QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in GetHighestWaypoint query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + return 0; } - return(res); + if (results.RowCount() != 1) + return 0; + + auto row = results.begin(); + return atoi(row[0]); } void NPC::SaveGuardSpotCharm() From 9a5d2d2bc575b34f4a8464e4db2501d7a6a365d0 Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 22 Aug 2014 20:48:11 -0400 Subject: [PATCH 11/89] Trade Stacking: BETA --- changelog.txt | 10 + common/item.cpp | 93 ++++++++ common/item.h | 1 + zone/common.h | 2 +- zone/inventory.cpp | 21 +- zone/trading.cpp | 533 ++++++++++++++++++++++++++++++--------------- 6 files changed, 475 insertions(+), 185 deletions(-) diff --git a/changelog.txt b/changelog.txt index bf2ea97f0..9d593e3e2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,15 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 08/22/2014 == +Uleat: Rework of Trade::FinishedTrade() and Trade::ResetTrade() to parse items a little more intelligently. + +Trade window items are now sent to client inventory in this order: + - Bags + - Partial stack movements + - All remaining items + +If any of these procedures cause any problems, please post them immediately. + == 08/20/2014 == Uleat: Rework of Trade::AddEntity() - function used to move items into the trade window. Now accepts argument for 'stack_size' and updates client properly. Note: I tested trade with Titanium:{SoF,SoD,UF,RoF} in both directions and no client generated an OP_MoveItem event for attempting to place a stackable diff --git a/common/item.cpp b/common/item.cpp index 7d6618335..bbb6f14f8 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -654,6 +654,99 @@ int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, boo return INVALID_INDEX; } +// This is a mix of HasSpaceForItem and FindFreeSlot..due to existing coding behavior, it was better to add a new helper function... +int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { + // Do not arbitrarily use this function..it is designed for use with Client::ResetTrade() and Client::FinishTrade(). + // If you have a need, use it..but, understand it is not a compatible replacement for Inventory::FindFreeSlot(). + // + // I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias -U + + if (!inst || !inst->GetID()) + return INVALID_INDEX; + + // step 1: find room for bags (caller should really ask for slots for bags first to avoid sending them to cursor..and bag item loss) + if (inst->IsType(ItemClassContainer)) { + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) + if (!m_inv[free_slot]) + return free_slot; + + return MainCursor; // return cursor since bags do not stack and will not fit inside other bags..yet...) + } + + // step 2: find partial room for stackables + if (inst->IsStackable()) { + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) { + const ItemInst* main_inst = m_inv[free_slot]; + + if (!main_inst) + continue; + + if ((main_inst->GetID() == inst->GetID()) && (main_inst->GetCharges() < main_inst->GetItem()->StackSize)) + return free_slot; + + if (main_inst->IsType(ItemClassContainer)) { // if item-specific containers already have bad items, we won't fix it here... + for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) { + const ItemInst* sub_inst = main_inst->GetItem(free_bag_slot); + + if (!sub_inst) + continue; + + if ((sub_inst->GetID() == inst->GetID()) && (sub_inst->GetCharges() < sub_inst->GetItem()->StackSize)) + return Inventory::CalcSlotId(free_slot, free_bag_slot); + } + } + } + } + + // step 3a: find room for container-specific items (ItemClassArrow) + if (inst->GetItem()->ItemType == ItemTypeArrow) { + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) { + const ItemInst* main_inst = m_inv[free_slot]; + + if (!main_inst || (main_inst->GetItem()->BagType != BagTypeQuiver) || !main_inst->IsType(ItemClassContainer)) + continue; + + for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) + if (!main_inst->GetItem(free_bag_slot)) + return Inventory::CalcSlotId(free_slot, free_bag_slot); + } + } + + // step 3b: find room for container-specific items (ItemClassSmallThrowing) + if (inst->GetItem()->ItemType == ItemTypeSmallThrowing) { + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) { + const ItemInst* main_inst = m_inv[free_slot]; + + if (!main_inst || (main_inst->GetItem()->BagType != BagTypeBandolier) || !main_inst->IsType(ItemClassContainer)) + continue; + + for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) + if (!main_inst->GetItem(free_bag_slot)) + return Inventory::CalcSlotId(free_slot, free_bag_slot); + } + } + + // step 4: just find an empty slot + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) { + const ItemInst* main_inst = m_inv[free_slot]; + + if (!main_inst) + return free_slot; + + if (main_inst->IsType(ItemClassContainer)) { + if ((main_inst->GetItem()->BagSize < inst->GetItem()->Size) || (main_inst->GetItem()->BagType == BagTypeBandolier) || (main_inst->GetItem()->BagType == BagTypeQuiver)) + continue; + + for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) + if (!main_inst->GetItem(free_bag_slot)) + return Inventory::CalcSlotId(free_slot, free_bag_slot); + } + } + + //return INVALID_INDEX; // everything else pushes to the cursor + return MainCursor; +} + // Opposite of below: Get parent bag slot_id from a slot inside of bag int16 Inventory::CalcSlotId(int16 slot_id) { int16 parent_slot_id = INVALID_INDEX; diff --git a/common/item.h b/common/item.h index ef59ddd6f..f279bd2aa 100644 --- a/common/item.h +++ b/common/item.h @@ -172,6 +172,7 @@ public: // Locate an available inventory slot int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false); + int16 FindFreeSlotForTradeItem(const ItemInst* inst); // Calculate slot_id for an item within a bag static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id diff --git a/zone/common.h b/zone/common.h index 3cc1af1cf..eccffec62 100644 --- a/zone/common.h +++ b/zone/common.h @@ -526,7 +526,7 @@ public: Mob* With(); // Add item from cursor slot to trade bucket (automatically does bag data too) - void AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_size); + void AddEntity(uint16 trade_slot_id, uint32 stack_size); // Audit trade void LogTrade(); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 5c5f80122..197841c76 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -822,25 +822,24 @@ bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update) return database.SaveCursor(CharacterID(), s, e); } -bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update) -{ +bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update) { mlog(INVENTORY__SLOTS, "Putting item %s (%d) into slot %d", inst.GetItem()->Name, inst.GetItem()->ID, slot_id); + if (slot_id == MainCursor) - { - return PushItemOnCursor(inst,client_update); - } + return PushItemOnCursor(inst, client_update); else m_inv.PutItem(slot_id, inst); - if (client_update) { - SendItemPacket(slot_id, &inst, (slot_id == MainCursor) ? ItemPacketSummonItem : ItemPacketTrade); - } + if (client_update) + SendItemPacket(slot_id, &inst, ((slot_id == MainCursor) ? ItemPacketSummonItem : ItemPacketTrade)); if (slot_id == MainCursor) { - std::list::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); + std::list::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end(); return database.SaveCursor(this->CharacterID(), s, e); - } else + } + else { return database.SaveInventory(this->CharacterID(), &inst, slot_id); + } CalcBonuses(); } @@ -1539,7 +1538,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { // Also sends trade information to other client of trade session if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit - trade->AddEntity(src_slot_id, dst_slot_id, move_in->number_in_stack); + trade->AddEntity(dst_slot_id, move_in->number_in_stack); return true; } else { diff --git a/zone/trading.cpp b/zone/trading.cpp index 1efcbbb33..1ae9596b9 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -71,8 +71,8 @@ void Trade::Start(uint32 mob_id, bool initiate_with) } // Add item from a given slot to trade bucket (automatically does bag data too) -void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_size) { - // TODO: review for inventory saves +void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) { + // TODO: review for inventory saves / consider changing return type to bool so failure can be passed to desync handler if (!owner || !owner->IsClient()) { // This should never happen @@ -121,7 +121,7 @@ void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_si if (_stack_size > 0) inst->SetCharges(_stack_size); else - client->DeleteItemInInventory(from_slot_id); + client->DeleteItemInInventory(MainCursor); SendItemData(inst2, trade_slot_id); } @@ -136,7 +136,7 @@ void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_si _log(TRADING__HOLDER, "%s added item '%s' to trade slot %i", owner->GetName(), inst->GetItem()->Name, trade_slot_id); client->PutItemInInventory(trade_slot_id, *inst); - client->DeleteItemInInventory(from_slot_id); + client->DeleteItemInInventory(MainCursor); } } @@ -316,206 +316,393 @@ void Trade::DumpTrade() #endif void Client::ResetTrade() { - const Item_Struct* TempItem = 0; - ItemInst* ins; - int x; AddMoneyToPP(trade->cp, trade->sp, trade->gp, trade->pp, true); - for(x = EmuConstants::TRADE_BEGIN; x <= EmuConstants::TRADE_END; x++) - { - TempItem = 0; - ins = GetInv().GetItem(x); - if (ins) - TempItem = ins->GetItem(); - if (TempItem) - { - bool is_arrow = (TempItem->ItemType == ItemTypeArrow) ? true : false; - int freeslotid = GetInv().FindFreeSlot(ins->IsType(ItemClassContainer), true, TempItem->Size, is_arrow); - if (freeslotid == INVALID_INDEX) - { - DropInst(ins); + + // step 1: process bags + for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) { + const ItemInst* inst = m_inv[trade_slot]; + + if (inst && inst->IsType(ItemClassContainer)) { + int16 free_slot = m_inv.FindFreeSlotForTradeItem(inst); + + if (free_slot != INVALID_INDEX) { + PutItemInInventory(free_slot, *inst); + SendItemPacket(free_slot, inst, ItemPacketTrade); } - else - { - PutItemInInventory(freeslotid, *ins); - SendItemPacket(freeslotid, ins, ItemPacketTrade); + else { + DropInst(inst); } - DeleteItemInInventory(x); + + DeleteItemInInventory(trade_slot); + } + } + + // step 2a: process stackables + for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) { + ItemInst* inst = GetInv().GetItem(trade_slot); + + if (inst && inst->IsStackable()) { + while (true) { + // there's no built-in safety check against an infinite loop..but, it should break on one of the conditional checks + int16 free_slot = m_inv.FindFreeSlotForTradeItem(inst); + + if ((free_slot == MainCursor) || (free_slot == INVALID_INDEX)) + break; + + ItemInst* partial_inst = GetInv().GetItem(free_slot); + + if (!partial_inst) + break; + + if (partial_inst->GetID() != inst->GetID()) { + _log(TRADING__ERROR, "Client::ResetTrade() - an incompatible location reference was returned by Inventory::FindFreeSlotForTradeItem()"); + + break; + } + + if ((partial_inst->GetCharges() + inst->GetCharges()) > partial_inst->GetItem()->StackSize) { + int16 new_charges = (partial_inst->GetCharges() + inst->GetCharges()) - partial_inst->GetItem()->StackSize; + + partial_inst->SetCharges(partial_inst->GetItem()->StackSize); + inst->SetCharges(new_charges); + } + else { + partial_inst->SetCharges(partial_inst->GetCharges() + inst->GetCharges()); + inst->SetCharges(0); + } + + PutItemInInventory(free_slot, *partial_inst); + SendItemPacket(free_slot, partial_inst, ItemPacketTrade); + + if (inst->GetCharges() == 0) { + DeleteItemInInventory(trade_slot); + + break; + } + } + } + } + + // step 2b: adjust trade stack bias + // (if any partial stacks exist before the final stack, FindFreeSlotForTradeItem() will return that slot in step 3 and an overwrite will occur) + for (int16 trade_slot = EmuConstants::TRADE_END; trade_slot >= EmuConstants::TRADE_BEGIN; --trade_slot) { + ItemInst* inst = GetInv().GetItem(trade_slot); + + if (inst && inst->IsStackable()) { + for (int16 bias_slot = EmuConstants::TRADE_BEGIN; bias_slot <= EmuConstants::TRADE_END; ++bias_slot) { + if (bias_slot >= trade_slot) + break; + + ItemInst* bias_inst = GetInv().GetItem(bias_slot); + + if (!bias_inst || (bias_inst->GetID() != inst->GetID()) || (bias_inst->GetCharges() >= bias_inst->GetItem()->StackSize)) + continue; + + if ((bias_inst->GetCharges() + inst->GetCharges()) > bias_inst->GetItem()->StackSize) { + int16 new_charges = (bias_inst->GetCharges() + inst->GetCharges()) - bias_inst->GetItem()->StackSize; + + bias_inst->SetCharges(bias_inst->GetItem()->StackSize); + inst->SetCharges(new_charges); + } + else { + bias_inst->SetCharges(bias_inst->GetCharges() + inst->GetCharges()); + inst->SetCharges(0); + } + + if (inst->GetCharges() == 0) { + DeleteItemInInventory(trade_slot); + + break; + } + } + } + } + + // step 3: process everything else + for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) { + const ItemInst* inst = m_inv[trade_slot]; + + if (inst) { + int16 free_slot = m_inv.FindFreeSlotForTradeItem(inst); + + if (free_slot != INVALID_INDEX) { + PutItemInInventory(free_slot, *inst); + SendItemPacket(free_slot, inst, ItemPacketTrade); + } + else { + DropInst(inst); + } + + DeleteItemInInventory(trade_slot); } } } void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) { - if(tradingWith && tradingWith->IsClient()) { Client* other = tradingWith->CastToClient(); if(other) { mlog(TRADING__CLIENT, "Finishing trade with client %s", other->GetName()); - int16 slot_id; - const Item_Struct* item = nullptr; - QSPlayerLogTrade_Struct* qsaudit = nullptr; - bool QSPLT = false; - - // QS code - if(qspack && RuleB(QueryServ, PlayerLogTrades)) { - qsaudit = (QSPlayerLogTrade_Struct*) qspack->pBuffer; - QSPLT = true; - - if(finalizer) { qsaudit->char2_id = this->character_id; } - else { qsaudit->char1_id = this->character_id; } - } - - // Move each trade slot into free inventory slot - for(int16 i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_END; i++){ - const ItemInst* inst = m_inv[i]; - uint16 parent_offset = 0; - - if(inst == nullptr) { continue; } - - mlog(TRADING__CLIENT, "Giving %s (%d) in slot %d to %s", inst->GetItem()->Name, inst->GetItem()->ID, i, other->GetName()); - - /// Log Player Trades through QueryServ if Rule Enabled - if(QSPLT) { - uint16 item_count = qsaudit->char1_count + qsaudit->char2_count; - parent_offset = item_count; - - qsaudit->items[item_count].from_id = this->character_id; - qsaudit->items[item_count].from_slot = i; - qsaudit->items[item_count].to_id = other->CharacterID(); - qsaudit->items[item_count].to_slot = 0; - qsaudit->items[item_count].item_id = inst->GetID(); - qsaudit->items[item_count].charges = inst->GetCharges(); - qsaudit->items[item_count].aug_1 = inst->GetAugmentItemID(1); - qsaudit->items[item_count].aug_2 = inst->GetAugmentItemID(2); - qsaudit->items[item_count].aug_3 = inst->GetAugmentItemID(3); - qsaudit->items[item_count].aug_4 = inst->GetAugmentItemID(4); - qsaudit->items[item_count].aug_5 = inst->GetAugmentItemID(5); - - if(finalizer) { qsaudit->char2_count++; } - else { qsaudit->char1_count++; } - - if(inst->IsType(ItemClassContainer)) { - // Pseudo-Slot ID's are generated based on how the db saves bag items... - for(uint8 j = SUB_BEGIN; j < inst->GetItem()->BagSlots; j++) { - const ItemInst* baginst = inst->GetItem(j); - - if(baginst == nullptr) { continue; } - - int16 k=Inventory::CalcSlotId(i, j); - item_count = qsaudit->char1_count + qsaudit->char2_count; - - qsaudit->items[item_count].from_id = this->character_id; - qsaudit->items[item_count].from_slot = k; - qsaudit->items[item_count].to_id = other->CharacterID(); - qsaudit->items[item_count].to_slot = 0; - qsaudit->items[item_count].item_id = baginst->GetID(); - qsaudit->items[item_count].charges = baginst->GetCharges(); - qsaudit->items[item_count].aug_1 = baginst->GetAugmentItemID(1); - qsaudit->items[item_count].aug_2 = baginst->GetAugmentItemID(2); - qsaudit->items[item_count].aug_3 = baginst->GetAugmentItemID(3); - qsaudit->items[item_count].aug_4 = baginst->GetAugmentItemID(4); - qsaudit->items[item_count].aug_5 = baginst->GetAugmentItemID(5); - - if(finalizer) { qsaudit->char2_count++; } - else { qsaudit->char1_count++; } - } - } - } - - if (inst->GetItem()->NoDrop != 0 || Admin() >= RuleI(Character, MinStatusForNoDropExemptions) || RuleI(World, FVNoDropFlag) == 1 || other == this) { - bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false; - slot_id = other->GetInv().FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow); - - mlog(TRADING__CLIENT, "Trying to put %s (%d) into slot %d", inst->GetItem()->Name, inst->GetItem()->ID, slot_id); - - if(other->PutItemInInventory(slot_id, *inst, true)) { - mlog(TRADING__CLIENT, "Item %s (%d) successfully transfered, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID); - - if(QSPLT) { - qsaudit->items[parent_offset].to_slot = slot_id; - - if(inst->IsType(ItemClassContainer)) { - for(uint8 bagslot_idx = SUB_BEGIN; bagslot_idx < inst->GetItem()->BagSlots; bagslot_idx++) { - const ItemInst* bag_inst = inst->GetItem(bagslot_idx); - - if(bag_inst == nullptr) { continue; } - int16 to_bagslot_id = Inventory::CalcSlotId(slot_id, bagslot_idx); - - qsaudit->items[++parent_offset].to_slot = to_bagslot_id; - } - } - } - } - else { - PushItemOnCursor(*inst, true); - mlog(TRADING__ERROR, "Unable to give item %d (%d) to %s, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName()); - - if(QSPLT) { - qsaudit->items[parent_offset].to_id = this->character_id; - qsaudit->items[parent_offset].to_slot = MainCursor; - - if(inst->IsType(ItemClassContainer)) { - for(uint8 bagslot_idx = SUB_BEGIN; bagslot_idx < inst->GetItem()->BagSlots; bagslot_idx++) { - const ItemInst* bag_inst = inst->GetItem(bagslot_idx); - - if(bag_inst == nullptr) { continue; } - int16 to_bagslot_id = Inventory::CalcSlotId(MainCursor, bagslot_idx); - - qsaudit->items[++parent_offset].to_id = this->character_id; - qsaudit->items[parent_offset].to_slot = to_bagslot_id; - } - } - } - } - - DeleteItemInInventory(i); - } - else { - PushItemOnCursor(*inst, true); - DeleteItemInInventory(i); - - if(QSPLT) { - qsaudit->items[parent_offset].to_id = this->character_id; - qsaudit->items[parent_offset].to_slot = MainCursor; - - if(inst->IsType(ItemClassContainer)) { - for(uint8 bagslot_idx = SUB_BEGIN; bagslot_idx < inst->GetItem()->BagSlots; bagslot_idx++) { - const ItemInst* bag_inst = inst->GetItem(bagslot_idx); - - if(bag_inst == nullptr) { continue; } - int16 to_bagslot_id = Inventory::CalcSlotId(MainCursor, bagslot_idx); - - qsaudit->items[++parent_offset].to_id = this->character_id; - qsaudit->items[parent_offset].to_slot = to_bagslot_id; - } - } - } - } - } - - // Money - look into how NPC's receive cash this->AddMoneyToPP(other->trade->cp, other->trade->sp, other->trade->gp, other->trade->pp, true); - // This is currently setup to show character offers, not receipts - if(QSPLT) { - if(finalizer) { + // step 0: pre-processing + // QS code + if (qspack && RuleB(QueryServ, PlayerLogTrades)) { + QSPlayerLogTrade_Struct* qsaudit = (QSPlayerLogTrade_Struct*)qspack->pBuffer; + + if (finalizer) { + qsaudit->char2_id = this->character_id; + qsaudit->char2_money.platinum = this->trade->pp; qsaudit->char2_money.gold = this->trade->gp; qsaudit->char2_money.silver = this->trade->sp; qsaudit->char2_money.copper = this->trade->cp; } else { - qsaudit->char1_money.platinum = this->trade->pp; + qsaudit->char1_id = this->character_id; + + qsaudit->char1_money.platinum = this->trade->pp; qsaudit->char1_money.gold = this->trade->gp; qsaudit->char1_money.silver = this->trade->sp; qsaudit->char1_money.copper = this->trade->cp; } + + // qsaudit->items[x].to_slot is disabled until QueryServ:PlayerLogTrades code is updated + for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) { + const ItemInst* inst = m_inv[trade_slot]; + + if (!inst) + continue; + + uint16 item_offset = qsaudit->char1_count + qsaudit->char2_count; + + qsaudit->items[item_offset].from_id = this->character_id; + qsaudit->items[item_offset].from_slot = trade_slot; + qsaudit->items[item_offset].to_id = other->CharacterID(); + qsaudit->items[item_offset].to_slot = 0; // disabled + qsaudit->items[item_offset].item_id = inst->GetID(); + qsaudit->items[item_offset].charges = inst->GetCharges(); + qsaudit->items[item_offset].aug_1 = inst->GetAugmentItemID(1); + qsaudit->items[item_offset].aug_2 = inst->GetAugmentItemID(2); + qsaudit->items[item_offset].aug_3 = inst->GetAugmentItemID(3); + qsaudit->items[item_offset].aug_4 = inst->GetAugmentItemID(4); + qsaudit->items[item_offset].aug_5 = inst->GetAugmentItemID(5); + + if (finalizer) + ++qsaudit->char2_count; + else + ++qsaudit->char1_count; + + if (inst->IsType(ItemClassContainer)) { + // Pseudo-Slot ID's are generated based on how the db saves bag items... + for (uint8 sub_slot = SUB_BEGIN; sub_slot < inst->GetItem()->BagSlots; ++sub_slot) { + const ItemInst* sub_inst = inst->GetItem(sub_slot); + + if (!sub_inst) + continue; + + int16 from_slot = Inventory::CalcSlotId(trade_slot, sub_slot); + item_offset = qsaudit->char1_count + qsaudit->char2_count; + + qsaudit->items[item_offset].from_id = this->character_id; + qsaudit->items[item_offset].from_slot = from_slot; + qsaudit->items[item_offset].to_id = other->CharacterID(); + qsaudit->items[item_offset].to_slot = 0; // disabled + qsaudit->items[item_offset].item_id = sub_inst->GetID(); + qsaudit->items[item_offset].charges = sub_inst->GetCharges(); + qsaudit->items[item_offset].aug_1 = sub_inst->GetAugmentItemID(1); + qsaudit->items[item_offset].aug_2 = sub_inst->GetAugmentItemID(2); + qsaudit->items[item_offset].aug_3 = sub_inst->GetAugmentItemID(3); + qsaudit->items[item_offset].aug_4 = sub_inst->GetAugmentItemID(4); + qsaudit->items[item_offset].aug_5 = sub_inst->GetAugmentItemID(5); + + if (finalizer) + ++qsaudit->char2_count; + else + ++qsaudit->char1_count; + } + } + } + } + + // step 1: process bags + for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) { + const ItemInst* inst = m_inv[trade_slot]; + + if (inst && inst->IsType(ItemClassContainer)) { + mlog(TRADING__CLIENT, "Giving container %s (%d) in slot %d to %s", inst->GetItem()->Name, inst->GetItem()->ID, trade_slot, other->GetName()); + + // TODO: need to check bag items/augments for no drop..everything for attuned... + if (inst->GetItem()->NoDrop != 0 || Admin() >= RuleI(Character, MinStatusForNoDropExemptions) || RuleI(World, FVNoDropFlag) == 1 || other == this) { + int16 free_slot = other->GetInv().FindFreeSlotForTradeItem(inst); + + if (free_slot != INVALID_INDEX) { + if (other->PutItemInInventory(free_slot, *inst, true)) { + mlog(TRADING__CLIENT, "Container %s (%d) successfully transferred, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID); + } + else { + mlog(TRADING__ERROR, "Transfer of container %s (%d) to %s failed, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName()); + + PushItemOnCursor(*inst, true); + } + } + else { + mlog(TRADING__ERROR, "%s's inventory is full, returning container %s (%d) to giver.", other->GetName(), inst->GetItem()->Name, inst->GetItem()->ID); + + PushItemOnCursor(*inst, true); + } + } + else { + mlog(TRADING__ERROR, "Container %s (%d) is NoDrop, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID); + + PushItemOnCursor(*inst, true); + } + + DeleteItemInInventory(trade_slot); + } + } + + // step 2a: process stackables + for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) { + ItemInst* inst = GetInv().GetItem(trade_slot); + + if (inst && inst->IsStackable()) { + while (true) { + // there's no built-in safety check against an infinite loop..but, it should break on one of the conditional checks + int16 partial_slot = other->GetInv().FindFreeSlotForTradeItem(inst); + + if ((partial_slot == MainCursor) || (partial_slot == INVALID_INDEX)) + break; + + ItemInst* partial_inst = other->GetInv().GetItem(partial_slot); + + if (!partial_inst) + break; + + if (partial_inst->GetID() != inst->GetID()) { + _log(TRADING__ERROR, "Client::ResetTrade() - an incompatible location reference was returned by Inventory::FindFreeSlotForTradeItem()"); + + break; + } + + int16 old_charges = inst->GetCharges(); + int16 partial_charges = partial_inst->GetCharges(); + + if ((partial_inst->GetCharges() + inst->GetCharges()) > partial_inst->GetItem()->StackSize) { + int16 new_charges = (partial_inst->GetCharges() + inst->GetCharges()) - partial_inst->GetItem()->StackSize; + + partial_inst->SetCharges(partial_inst->GetItem()->StackSize); + inst->SetCharges(new_charges); + } + else { + partial_inst->SetCharges(partial_inst->GetCharges() + inst->GetCharges()); + inst->SetCharges(0); + } + + mlog(TRADING__CLIENT, "Transferring partial stack %s (%d) in slot %d to %s", inst->GetItem()->Name, inst->GetItem()->ID, trade_slot, other->GetName()); + + if (other->PutItemInInventory(partial_slot, *partial_inst, true)) { + mlog(TRADING__CLIENT, "Partial stack %s (%d) successfully transferred, deleting %i charges from trade slot.", + inst->GetItem()->Name, inst->GetItem()->ID, (old_charges - inst->GetCharges())); + } + else { + mlog(TRADING__ERROR, "Transfer of partial stack %s (%d) to %s failed, returning %i charges to trade slot.", + inst->GetItem()->Name, inst->GetItem()->ID, other->GetName(), (old_charges - inst->GetCharges())); + + inst->SetCharges(old_charges); + partial_inst->SetCharges(partial_charges); + + break; + } + + if (inst->GetCharges() == 0) { + DeleteItemInInventory(trade_slot); + + break; + } + } + } + } + + // step 2b: adjust trade stack bias + // (if any partial stacks exist before the final stack, FindFreeSlotForTradeItem() will return that slot in step 3 and an overwrite will occur) + for (int16 trade_slot = EmuConstants::TRADE_END; trade_slot >= EmuConstants::TRADE_BEGIN; --trade_slot) { + ItemInst* inst = GetInv().GetItem(trade_slot); + + if (inst && inst->IsStackable()) { + for (int16 bias_slot = EmuConstants::TRADE_BEGIN; bias_slot <= EmuConstants::TRADE_END; ++bias_slot) { + if (bias_slot >= trade_slot) + break; + + ItemInst* bias_inst = GetInv().GetItem(bias_slot); + + if (!bias_inst || (bias_inst->GetID() != inst->GetID()) || (bias_inst->GetCharges() >= bias_inst->GetItem()->StackSize)) + continue; + + if ((bias_inst->GetCharges() + inst->GetCharges()) > bias_inst->GetItem()->StackSize) { + int16 new_charges = (bias_inst->GetCharges() + inst->GetCharges()) - bias_inst->GetItem()->StackSize; + + bias_inst->SetCharges(bias_inst->GetItem()->StackSize); + inst->SetCharges(new_charges); + } + else { + bias_inst->SetCharges(bias_inst->GetCharges() + inst->GetCharges()); + inst->SetCharges(0); + } + + if (inst->GetCharges() == 0) { + DeleteItemInInventory(trade_slot); + + break; + } + } + } + } + + // step 3: process everything else + for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) { + const ItemInst* inst = m_inv[trade_slot]; + + if (inst) { + mlog(TRADING__CLIENT, "Giving item %s (%d) in slot %d to %s", inst->GetItem()->Name, inst->GetItem()->ID, trade_slot, other->GetName()); + + // TODO: need to check bag items/augments for no drop..everything for attuned... + if (inst->GetItem()->NoDrop != 0 || Admin() >= RuleI(Character, MinStatusForNoDropExemptions) || RuleI(World, FVNoDropFlag) == 1 || other == this) { + int16 free_slot = other->GetInv().FindFreeSlotForTradeItem(inst); + + if (free_slot != INVALID_INDEX) { + if (other->PutItemInInventory(free_slot, *inst, true)) { + mlog(TRADING__CLIENT, "Item %s (%d) successfully transferred, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID); + } + else { + mlog(TRADING__ERROR, "Transfer of Item %s (%d) to %s failed, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName()); + + PushItemOnCursor(*inst, true); + } + } + else { + mlog(TRADING__ERROR, "%s's inventory is full, returning item %s (%d) to giver.", other->GetName(), inst->GetItem()->Name, inst->GetItem()->ID); + + PushItemOnCursor(*inst, true); + } + } + else { + mlog(TRADING__ERROR, "Item %s (%d) is NoDrop, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID); + + PushItemOnCursor(*inst, true); + } + + DeleteItemInInventory(trade_slot); + } } //Do not reset the trade here, done by the caller. } } + + // trading with npc doesn't require Inventory::FindFreeSlotForTradeItem() rework else if(tradingWith && tradingWith->IsNPC()) { QSPlayerLogHandin_Struct* qsaudit = nullptr; bool QSPLH = false; From a568a6f1947d54ded73acfa6113321284d0fc8c4 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:10:30 -0700 Subject: [PATCH 12/89] GetAccountStatus converted to QueryDatabase --- ucs/database.cpp | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 4d055e2a4..c71601cdf 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -102,41 +102,34 @@ Database::~Database() { } -void Database::GetAccountStatus(Client *c) { - - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - if (!RunQuery(query,MakeAnyLenString(&query, "select `status`, `hideme`, `karma`, `revoked` from `account` where `id`='%i' limit 1", - c->GetAccountID()),errbuf,&result)){ - - _log(UCS__ERROR, "Unable to get account status for character %s, error %s", c->GetName().c_str(), errbuf); - - safe_delete_array(query); +void Database::GetAccountStatus(Client *client) { + std::string query = StringFormat("SELECT `status`, `hideme`, `karma`, `revoked` " + "FROM `account` WHERE `id` = '%i' LIMIT 1", + client->GetAccountID()); + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(UCS__ERROR, "Unable to get account status for character %s, error %s", client->GetName().c_str(), results.ErrorMessage().c_str()); return; } - _log(UCS__TRACE, "GetAccountStatus Query: %s", query); - safe_delete_array(query); - if(mysql_num_rows(result) != 1) + _log(UCS__TRACE, "GetAccountStatus Query: %s", query.c_str()); + + if(results.RowCount() != 1) { _log(UCS__ERROR, "Error in GetAccountStatus"); - mysql_free_result(result); return; } - row = mysql_fetch_row(result); + auto row = results.begin(); - c->SetAccountStatus(atoi(row[0])); - c->SetHideMe(atoi(row[1]) != 0); - c->SetKarma(atoi(row[2])); - c->SetRevoked((atoi(row[3])==1?true:false)); + client->SetAccountStatus(atoi(row[0])); + client->SetHideMe(atoi(row[1]) != 0); + client->SetKarma(atoi(row[2])); + client->SetRevoked((atoi(row[3])==1?true:false)); + + _log(UCS__TRACE, "Set account status to %i, hideme to %i and karma to %i for %s", client->GetAccountStatus(), client->GetHideMe(), client->GetKarma(), client->GetName().c_str()); - _log(UCS__TRACE, "Set account status to %i, hideme to %i and karma to %i for %s", c->GetAccountStatus(), c->GetHideMe(), c->GetKarma(), c->GetName().c_str()); - mysql_free_result(result); } int Database::FindAccount(const char *CharacterName, Client *c) { From 5c640b2d4007ba23bbec76dc0797f394ad5e17dd Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:16:05 -0700 Subject: [PATCH 13/89] FindAccount converted to QueryDatabase --- ucs/database.cpp | 61 ++++++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index c71601cdf..2ac80bda2 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -132,55 +132,44 @@ void Database::GetAccountStatus(Client *client) { } -int Database::FindAccount(const char *CharacterName, Client *c) { +int Database::FindAccount(const char *characterName, Client *client) { - _log(UCS__TRACE, "FindAccount for character %s", CharacterName); + _log(UCS__TRACE, "FindAccount for character %s", characterName); - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - c->ClearCharacters(); - - if (!RunQuery(query,MakeAnyLenString(&query, "select `id`, `account_id`, `level` from `character_` where `name`='%s' limit 1", - CharacterName),errbuf,&result)) - { - _log(UCS__ERROR, "FindAccount query failed: %s", query); - safe_delete_array(query); + client->ClearCharacters(); + std::string query = StringFormat("SELECT `id`, `account_id`, `level` " + "FROM `character_` WHERE `name` = '%s' LIMIT 1", + characterName); + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(UCS__ERROR, "FindAccount query failed: %s", query.c_str()); return -1; } - safe_delete_array(query); - if (mysql_num_rows(result) != 1) - { + if (results.RowCount() != 1) { _log(UCS__ERROR, "Bad result from query"); - mysql_free_result(result); return -1; } - row = mysql_fetch_row(result); - c->AddCharacter(atoi(row[0]), CharacterName, atoi(row[2])); - int AccountID = atoi(row[1]); + auto row = results.begin(); + client->AddCharacter(atoi(row[0]), characterName, atoi(row[2])); - mysql_free_result(result); - _log(UCS__TRACE, "Account ID for %s is %i", CharacterName, AccountID); + int accountID = atoi(row[1]); - if (!RunQuery(query,MakeAnyLenString(&query, "select `id`, `name`, `level` from `character_` where `account_id`=%i and `name` !='%s'", - AccountID, CharacterName),errbuf,&result)) - { - safe_delete_array(query); - return AccountID; - } - safe_delete_array(query); + _log(UCS__TRACE, "Account ID for %s is %i", characterName, accountID); - for(unsigned int i = 0; i < mysql_num_rows(result); i++) - { - row = mysql_fetch_row(result); - c->AddCharacter(atoi(row[0]), row[1], atoi(row[2])); - } - mysql_free_result(result); - return AccountID; + query = StringFormat("SELECT `id`, `name`, `level` FROM `character_` " + "WHERE `account_id` = %i AND `name` != '%s'", + accountID, characterName); + results = QueryDatabase(query); + if (!results.Success()) + return accountID; + + for (auto row = results.begin(); row != results.end(); ++row) + client->AddCharacter(atoi(row[0]), row[1], atoi(row[2])); + + return accountID; } bool Database::VerifyMailKey(std::string CharacterName, int IPAddress, std::string MailKey) { From 6b90f883cd7ed30fca2d3c37242c8671d773f449 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:18:47 -0700 Subject: [PATCH 14/89] VerifyMailKey converted to QueryDatabase --- ucs/database.cpp | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 2ac80bda2..6d2606fd7 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -172,45 +172,31 @@ int Database::FindAccount(const char *characterName, Client *client) { return accountID; } -bool Database::VerifyMailKey(std::string CharacterName, int IPAddress, std::string MailKey) { - - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - if (!RunQuery(query,MakeAnyLenString(&query, "select `mailkey` from `character_` where `name`='%s' limit 1", - CharacterName.c_str()),errbuf,&result)){ - - safe_delete_array(query); - - _log(UCS__ERROR, "Error retrieving mailkey from database: %s", errbuf); +bool Database::VerifyMailKey(std::string characterName, int IPAddress, std::string MailKey) { + std::string query = StringFormat("SELECT `mailkey` FROM `character_` WHERE `name`='%s' LIMIT 1", + characterName.c_str()); + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(UCS__ERROR, "Error retrieving mailkey from database: %s", results.ErrorMessage().c_str()); return false; } - safe_delete_array(query); - - row = mysql_fetch_row(result); + auto row = results.begin(); // The key is the client's IP address (expressed as 8 hex digits) and an 8 hex digit random string generated // by world. // - char CombinedKey[17]; + char combinedKey[17]; if(RuleB(Chat, EnableMailKeyIPVerification) == true) - sprintf(CombinedKey, "%08X%s", IPAddress, MailKey.c_str()); + sprintf(combinedKey, "%08X%s", IPAddress, MailKey.c_str()); else - sprintf(CombinedKey, "%s", MailKey.c_str()); + sprintf(combinedKey, "%s", MailKey.c_str()); - _log(UCS__TRACE, "DB key is [%s], Client key is [%s]", row[0], CombinedKey); - - bool Valid = !strcmp(row[0], CombinedKey); - - mysql_free_result(result); - - return Valid; + _log(UCS__TRACE, "DB key is [%s], Client key is [%s]", row[0], combinedKey); + return !strcmp(row[0], combinedKey); } int Database::FindCharacter(const char *CharacterName) { From de477553206230350d6ca6988c5cc0d7979def13 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:24:28 -0700 Subject: [PATCH 15/89] FindCharacter converted to QueryDatabase --- ucs/database.cpp | 48 +++++++++++++++--------------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 6d2606fd7..28eb93af5 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -199,46 +199,28 @@ bool Database::VerifyMailKey(std::string characterName, int IPAddress, std::stri return !strcmp(row[0], combinedKey); } -int Database::FindCharacter(const char *CharacterName) { +int Database::FindCharacter(const char *characterName) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - char *SafeCharName = RemoveApostrophes(CharacterName); - - if (!RunQuery(query,MakeAnyLenString(&query, "select `id` from `character_` where `name`='%s' limit 1", - SafeCharName),errbuf,&result)){ - - _log(UCS__ERROR, "FindCharacter failed. %s %s", query, errbuf); - - safe_delete_array(query); - safe_delete_array(SafeCharName); + char *safeCharName = RemoveApostrophes(characterName); + std::string query = StringFormat("SELECT `id` FROM `character_` WHERE `name`='%s' LIMIT 1", safeCharName); + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(UCS__ERROR, "FindCharacter failed. %s %s", query.c_str(), results.ErrorMessage().c_str()); + safe_delete(safeCharName); + return -1; + } + safe_delete(safeCharName); + if (results.RowCount() != 1) { + _log(UCS__ERROR, "Bad result from FindCharacter query for character %s", characterName); return -1; } - safe_delete_array(query); - safe_delete_array(SafeCharName); + auto row = results.begin(); - if (mysql_num_rows(result) != 1) { - - _log(UCS__ERROR, "Bad result from FindCharacter query for character %s", CharacterName); - - mysql_free_result(result); - - return -1; - } - - row = mysql_fetch_row(result); - - int CharacterID = atoi(row[0]); - - mysql_free_result(result); - - return CharacterID; + int characterID = atoi(row[0]); + return characterID; } bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) { From 19486bac0d2e253aa0b6a90699b7198d0237f51a Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:27:18 -0700 Subject: [PATCH 16/89] GetVariable converted to QueryDatabase --- ucs/database.cpp | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 28eb93af5..155ee986a 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -225,35 +225,20 @@ int Database::FindCharacter(const char *characterName) { bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - if (!RunQuery(query,MakeAnyLenString(&query, "select `value` from `variables` where `varname`='%s'", varname), errbuf, &result)) { - - _log(UCS__ERROR, "Unable to get message count from database. %s %s", query, errbuf); - - safe_delete_array(query); - + std::string query = StringFormat("SELECT `value` FROM `variables` WHERE `varname` = '%s'", varname); + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(UCS__ERROR, "Unable to get message count from database. %s %s", query.c_str(), results.ErrorMessage().c_str()); return false; } - safe_delete_array(query); - - if (mysql_num_rows(result) != 1) { - - mysql_free_result(result); - + if (results.RowCount() != 1) return false; - } - row = mysql_fetch_row(result); + auto row = results.begin(); snprintf(varvalue, varvalue_len, "%s", row[0]); - mysql_free_result(result); - return true; } From 76fdfa87c1d60a30f605b067b5f92ad8843915de Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:31:26 -0700 Subject: [PATCH 17/89] LoadChatChannels converted to QueryDatabase --- ucs/database.cpp | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 155ee986a..3785992de 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -246,32 +246,21 @@ bool Database::LoadChatChannels() { _log(UCS__INIT, "Loading chat channels from the database."); - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - if (!RunQuery(query,MakeAnyLenString(&query, "select `name`,`owner`,`password`, `minstatus` from `chatchannels`"),errbuf,&result)){ - - _log(UCS__ERROR, "Failed to load channels. %s %s", query, errbuf); - safe_delete_array(query); - + const std::string query = "SELECT `name`, `owner`, `password`, `minstatus` FROM `chatchannels`"; + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(UCS__ERROR, "Failed to load channels. %s %s", query.c_str(), results.ErrorMessage().c_str()); return false; } - safe_delete_array(query); + for (auto row = results.begin();row != results.end(); ++row) { + std::string channelName = row[0]; + std::string channelOwner = row[1]; + std::string channelPassword = row[2]; - while((row = mysql_fetch_row(result))) { - - std::string ChannelName = row[0]; - std::string ChannelOwner = row[1]; - std::string ChannelPassword = row[2]; - - ChannelList->CreateChannel(ChannelName, ChannelOwner, ChannelPassword, true, atoi(row[3])); + ChannelList->CreateChannel(channelName, channelOwner, channelPassword, true, atoi(row[3])); } - mysql_free_result(result); - return true; } From 7a507e8d1ec5e2cddb6a028081364bce4d650b63 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:34:27 -0700 Subject: [PATCH 18/89] SetChannelPassword converted to QueryDatabase --- ucs/database.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 3785992de..063ab5e35 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -264,21 +264,16 @@ bool Database::LoadChatChannels() { return true; } -void Database::SetChannelPassword(std::string ChannelName, std::string Password) { +void Database::SetChannelPassword(std::string channelName, std::string password) { - _log(UCS__TRACE, "Database::SetChannelPassword(%s, %s)", ChannelName.c_str(), Password.c_str()); + _log(UCS__TRACE, "Database::SetChannelPassword(%s, %s)", channelName.c_str(), password.c_str()); - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + std::string query = StringFormat("UPDATE `chatchannels` SET `password` = '%s' WHERE `name` = '%s'", + password.c_str(), channelName.c_str()); + auto results = QueryDatabase(query); + if(!results.Success()) + _log(UCS__ERROR, "Error updating password in database: %s, %s", query.c_str(), results.ErrorMessage().c_str()); - if(!RunQuery(query, MakeAnyLenString(&query, "UPDATE `chatchannels` set `password`='%s' where `name`='%s'", Password.c_str(), - ChannelName.c_str()), errbuf)) { - - _log(UCS__ERROR, "Error updating password in database: %s, %s", query, errbuf); - - } - - safe_delete_array(query); } void Database::SetChannelOwner(std::string ChannelName, std::string Owner) { From 6e7136ea186e41666df7a2104b5460ac2ef32aec Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:38:57 -0700 Subject: [PATCH 19/89] SetChannelOwner converted to QueryDatabase --- ucs/database.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 063ab5e35..22f1431ae 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -276,21 +276,16 @@ void Database::SetChannelPassword(std::string channelName, std::string password) } -void Database::SetChannelOwner(std::string ChannelName, std::string Owner) { +void Database::SetChannelOwner(std::string channelName, std::string owner) { - _log(UCS__TRACE, "Database::SetChannelOwner(%s, %s)", ChannelName.c_str(), Owner.c_str()); + _log(UCS__TRACE, "Database::SetChannelOwner(%s, %s)", channelName.c_str(), owner.c_str()); - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + std::string query = StringFormat("UPDATE `chatchannels` SET `owner` = '%s' WHERE `name` = '%s'", + owner.c_str(), channelName.c_str()); + auto results = QueryDatabase(query); + if(!results.Success()) + _log(UCS__ERROR, "Error updating Owner in database: %s, %s", query.c_str(), results.ErrorMessage().c_str()); - if(!RunQuery(query, MakeAnyLenString(&query, "UPDATE `chatchannels` set `owner`='%s' where `name`='%s'", Owner.c_str(), - ChannelName.c_str()), errbuf)) { - - _log(UCS__ERROR, "Error updating Owner in database: %s, %s", query, errbuf); - - } - - safe_delete_array(query); } void Database::SendHeaders(Client *c) { From 2bdc44dfb2fbe335a2e4d7aed904152ed4b59f03 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:47:59 -0700 Subject: [PATCH 20/89] SendHeaders converted to QueryDatabase --- ucs/database.cpp | 129 ++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 73 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 22f1431ae..b05810f0e 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -288,110 +288,93 @@ void Database::SetChannelOwner(std::string channelName, std::string owner) { } -void Database::SendHeaders(Client *c) { +void Database::SendHeaders(Client *client) { - int UnknownField2 = 25015275; - int UnknownField3 = 1; + int unknownField2 = 25015275; + int unknownField3 = 1; + int characterID = FindCharacter(client->MailBoxName().c_str()); - int CharacterID = FindCharacter(c->MailBoxName().c_str()); - _log(UCS__TRACE, "Sendheaders for %s, CharID is %i", c->MailBoxName().c_str(), CharacterID); - if(CharacterID <= 0) + _log(UCS__TRACE, "Sendheaders for %s, CharID is %i", client->MailBoxName().c_str(), characterID); + + if(characterID <= 0) return; + std::string query = StringFormat("SELECT `msgid`,`timestamp`, `from`, `subject`, `status` " + "FROM `mail` WHERE `charid`=%i", characterID); + auto results = QueryDatabase(query); + if (!results.Success()) + return; - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + char buffer[100]; - if (!RunQuery(query,MakeAnyLenString(&query, "select `msgid`,`timestamp`,`from`,`subject`, `status` from `mail` " - "where `charid`=%i", CharacterID),errbuf,&result)){ + int headerCountPacketLength = 0; - safe_delete_array(query); + sprintf(buffer, "%i", client->GetMailBoxNumber()); + headerCountPacketLength += (strlen(buffer) + 1); - return ; - } + sprintf(buffer, "%i", unknownField2); + headerCountPacketLength += (strlen(buffer) + 1); - safe_delete_array(query); + sprintf(buffer, "%i", unknownField3); + headerCountPacketLength += (strlen(buffer) + 1); - char Buf[100]; + sprintf(buffer, "%i", results.RowCount()); + headerCountPacketLength += (strlen(buffer) + 1); - uint32 NumRows = mysql_num_rows(result); + EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailHeaderCount, headerCountPacketLength); - int HeaderCountPacketLength = 0; + char *packetBuffer = (char *)outapp->pBuffer; - sprintf(Buf, "%i", c->GetMailBoxNumber()); - HeaderCountPacketLength += (strlen(Buf) + 1); - - sprintf(Buf, "%i", UnknownField2); - HeaderCountPacketLength += (strlen(Buf) + 1); - - sprintf(Buf, "%i", UnknownField3); - HeaderCountPacketLength += (strlen(Buf) + 1); - - sprintf(Buf, "%i", NumRows); - HeaderCountPacketLength += (strlen(Buf) + 1); - - EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailHeaderCount, HeaderCountPacketLength); - - char *PacketBuffer = (char *)outapp->pBuffer; - - VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber()); - VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField2); - VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField3); - VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, NumRows); + VARSTRUCT_ENCODE_INTSTRING(packetBuffer, client->GetMailBoxNumber()); + VARSTRUCT_ENCODE_INTSTRING(packetBuffer, unknownField2); + VARSTRUCT_ENCODE_INTSTRING(packetBuffer, unknownField3); + VARSTRUCT_ENCODE_INTSTRING(packetBuffer, results.RowCount()); _pkt(UCS__PACKETS, outapp); - c->QueuePacket(outapp); + client->QueuePacket(outapp); safe_delete(outapp); - int RowNum = 0; + int rowIndex = 0; + for(auto row = results.begin(); row != results.end(); ++row, ++rowIndex) { + int headerPacketLength = 0; - while((row = mysql_fetch_row(result))) { + sprintf(buffer, "%i", client->GetMailBoxNumber()); + headerPacketLength += strlen(buffer) + 1; + sprintf(buffer, "%i", unknownField2); + headerPacketLength += strlen(buffer) + 1; + sprintf(buffer, "%i", rowIndex); + headerPacketLength += strlen(buffer) + 1; + headerPacketLength += strlen(row[0]) + 1; + headerPacketLength += strlen(row[1]) + 1; + headerPacketLength += strlen(row[4]) + 1; + headerPacketLength += GetMailPrefix().length() + strlen(row[2]) + 1; + headerPacketLength += strlen(row[3]) + 1; - int HeaderPacketLength = 0; + outapp = new EQApplicationPacket(OP_MailHeader, headerPacketLength); - sprintf(Buf, "%i", c->GetMailBoxNumber()); - HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1; - sprintf(Buf, "%i", UnknownField2); - HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1; - sprintf(Buf, "%i", RowNum); - HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1; + packetBuffer = (char *)outapp->pBuffer; - HeaderPacketLength = HeaderPacketLength + strlen(row[0]) + 1; - HeaderPacketLength = HeaderPacketLength + strlen(row[1]) + 1; - HeaderPacketLength = HeaderPacketLength + strlen(row[4]) + 1; - HeaderPacketLength = HeaderPacketLength + GetMailPrefix().length() + strlen(row[2]) + 1; - HeaderPacketLength = HeaderPacketLength + strlen(row[3]) + 1; - - outapp = new EQApplicationPacket(OP_MailHeader, HeaderPacketLength); - - PacketBuffer = (char *)outapp->pBuffer; - - VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber()); - VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField2); - VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, RowNum); - VARSTRUCT_ENCODE_STRING(PacketBuffer, row[0]); - VARSTRUCT_ENCODE_STRING(PacketBuffer, row[1]); - VARSTRUCT_ENCODE_STRING(PacketBuffer, row[4]); - VARSTRUCT_ENCODE_STRING(PacketBuffer, GetMailPrefix().c_str()); PacketBuffer--; - VARSTRUCT_ENCODE_STRING(PacketBuffer, row[2]); - VARSTRUCT_ENCODE_STRING(PacketBuffer, row[3]); + VARSTRUCT_ENCODE_INTSTRING(packetBuffer, client->GetMailBoxNumber()); + VARSTRUCT_ENCODE_INTSTRING(packetBuffer, unknownField2); + VARSTRUCT_ENCODE_INTSTRING(packetBuffer, rowIndex); + VARSTRUCT_ENCODE_STRING(packetBuffer, row[0]); + VARSTRUCT_ENCODE_STRING(packetBuffer, row[1]); + VARSTRUCT_ENCODE_STRING(packetBuffer, row[4]); + VARSTRUCT_ENCODE_STRING(packetBuffer, GetMailPrefix().c_str()); + packetBuffer--; + VARSTRUCT_ENCODE_STRING(packetBuffer, row[2]); + VARSTRUCT_ENCODE_STRING(packetBuffer, row[3]); _pkt(UCS__PACKETS, outapp); - c->QueuePacket(outapp); + client->QueuePacket(outapp); safe_delete(outapp); - - RowNum++; } - mysql_free_result(result); - } void Database::SendBody(Client *c, int MessageNumber) { From aaf5f8c9307cd99199309ed7d51bf080a939b2c7 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 21:51:40 -0700 Subject: [PATCH 21/89] SendBody converted to QueryDatabase --- ucs/database.cpp | 69 ++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index b05810f0e..b704a271b 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -377,65 +377,52 @@ void Database::SendHeaders(Client *client) { } -void Database::SendBody(Client *c, int MessageNumber) { +void Database::SendBody(Client *client, int messageNumber) { - int CharacterID = FindCharacter(c->MailBoxName().c_str()); + int characterID = FindCharacter(client->MailBoxName().c_str()); - _log(UCS__TRACE, "SendBody: MsgID %i, to %s, CharID is %i", MessageNumber, c->MailBoxName().c_str(), CharacterID); + _log(UCS__TRACE, "SendBody: MsgID %i, to %s, CharID is %i", messageNumber, client->MailBoxName().c_str(), characterID); - if(CharacterID <= 0) + if(characterID <= 0) return; - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - if (!RunQuery(query,MakeAnyLenString(&query, "select `msgid`, `body`, `to` from `mail` " - "where `charid`=%i and `msgid`=%i", CharacterID, MessageNumber), errbuf, &result)){ - safe_delete_array(query); - - return ; - } - - safe_delete_array(query); - - if (mysql_num_rows(result) != 1) { - - mysql_free_result(result); - + std::string query = StringFormat("SELECT `msgid`, `body`, `to` FROM `mail` " + "WHERE `charid`=%i AND `msgid`=%i", characterID, messageNumber); + auto results = QueryDatabase(query); + if (!results.Success()) return; - } - row = mysql_fetch_row(result); - _log(UCS__TRACE, "Message: %i body (%i bytes)", MessageNumber, strlen(row[1])); + if (results.RowCount() != 1) + return; - int PacketLength = 12 + strlen(row[0]) + strlen(row[1]) + strlen(row[2]); + auto row = results.begin(); - EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailSendBody,PacketLength); + _log(UCS__TRACE, "Message: %i body (%i bytes)", messageNumber, strlen(row[1])); - char *PacketBuffer = (char *)outapp->pBuffer; + int packetLength = 12 + strlen(row[0]) + strlen(row[1]) + strlen(row[2]); - VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber()); - VARSTRUCT_ENCODE_STRING(PacketBuffer,row[0]); - VARSTRUCT_ENCODE_STRING(PacketBuffer,row[1]); - VARSTRUCT_ENCODE_STRING(PacketBuffer,"1"); - VARSTRUCT_ENCODE_TYPE(uint8, PacketBuffer, 0); - VARSTRUCT_ENCODE_TYPE(uint8, PacketBuffer, 0x0a); - VARSTRUCT_ENCODE_STRING(PacketBuffer, "TO:"); PacketBuffer--; - VARSTRUCT_ENCODE_STRING(PacketBuffer, row[2]); PacketBuffer--; // Overwrite the null terminator - VARSTRUCT_ENCODE_TYPE(uint8, PacketBuffer, 0x0a); + EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailSendBody,packetLength); - mysql_free_result(result); + char *packetBuffer = (char *)outapp->pBuffer; + + VARSTRUCT_ENCODE_INTSTRING(packetBuffer, client->GetMailBoxNumber()); + VARSTRUCT_ENCODE_STRING(packetBuffer,row[0]); + VARSTRUCT_ENCODE_STRING(packetBuffer,row[1]); + VARSTRUCT_ENCODE_STRING(packetBuffer,"1"); + VARSTRUCT_ENCODE_TYPE(uint8, packetBuffer, 0); + VARSTRUCT_ENCODE_TYPE(uint8, packetBuffer, 0x0a); + VARSTRUCT_ENCODE_STRING(packetBuffer, "TO:"); + packetBuffer--; + VARSTRUCT_ENCODE_STRING(packetBuffer, row[2]); + packetBuffer--; // Overwrite the null terminator + VARSTRUCT_ENCODE_TYPE(uint8, packetBuffer, 0x0a); _pkt(UCS__PACKETS, outapp); - c->QueuePacket(outapp); + client->QueuePacket(outapp); safe_delete(outapp); - - } bool Database::SendMail(std::string Recipient, std::string From, std::string Subject, std::string Body, std::string RecipientsString) { From 8529384b009a56214fc8a888374d811b62319f08 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 22:00:40 -0700 Subject: [PATCH 22/89] SendMail converted to QueryDatabase --- ucs/database.cpp | 78 +++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index b704a271b..6bdf2b1e8 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -425,72 +425,62 @@ void Database::SendBody(Client *client, int messageNumber) { safe_delete(outapp); } -bool Database::SendMail(std::string Recipient, std::string From, std::string Subject, std::string Body, std::string RecipientsString) { +bool Database::SendMail(std::string recipient, std::string from, std::string subject, std::string body, std::string recipientsString) { - int CharacterID; + int characterID; - std::string CharacterName; + std::string characterName; //printf("Database::SendMail(%s, %s, %s)\n", Recipient.c_str(), From.c_str(), Subject.c_str()); - std::string::size_type LastPeriod = Recipient.find_last_of("."); + auto lastPeriod = recipient.find_last_of("."); - if(LastPeriod == std::string::npos) - CharacterName = Recipient; + if(lastPeriod == std::string::npos) + characterName = recipient; else - CharacterName = Recipient.substr(LastPeriod+1); + characterName = recipient.substr(lastPeriod+1); - CharacterName[0] = toupper(CharacterName[0]); + characterName[0] = toupper(characterName[0]); - for(unsigned int i = 1; i < CharacterName.length(); i++) - CharacterName[i] = tolower(CharacterName[i]); + for(unsigned int i = 1; i < characterName.length(); i++) + characterName[i] = tolower(characterName[i]); - CharacterID = FindCharacter(CharacterName.c_str()); + characterID = FindCharacter(characterName.c_str()); - _log(UCS__TRACE, "SendMail: CharacterID for recipient %s is %i", CharacterName.c_str(), CharacterID); + _log(UCS__TRACE, "SendMail: CharacterID for recipient %s is %i", characterName.c_str(), characterID); - if(CharacterID <= 0) return false; + if(characterID <= 0) + return false; - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; + char *escSubject = new char[subject.length() * 2 + 1]; + char *escBody = new char[body.length() * 2 + 1]; - char *EscSubject = new char[Subject.length() * 2 + 1]; - char *EscBody = new char[Body.length() * 2 + 1]; + DoEscapeString(escSubject, subject.c_str(), subject.length()); + DoEscapeString(escBody, body.c_str(), body.length()); - DoEscapeString(EscSubject, Subject.c_str(), Subject.length()); - DoEscapeString(EscBody, Body.c_str(), Body.length()); - - const char *MailQuery="INSERT INTO `mail` (`charid`, `timestamp`, `from`, `subject`, `body`, `to`, `status`) " - "VALUES ('%i', %i, '%s', '%s', '%s', '%s', %i)"; - - uint32 LastMsgID; - - int Now = time(nullptr); // time returns a 64 bit int on Windows at least, which vsnprintf doesn't like. - - if(!RunQuery(query, MakeAnyLenString(&query, MailQuery, CharacterID, Now, From.c_str(), EscSubject, EscBody, - RecipientsString.c_str(), 1), errbuf, 0, 0, &LastMsgID)) { - - _log(UCS__ERROR, "SendMail: Query %s failed with error %s", query, errbuf); - - safe_delete_array(EscSubject); - safe_delete_array(EscBody); - safe_delete_array(query); + int now = time(nullptr); // time returns a 64 bit int on Windows at least, which vsnprintf doesn't like. + std::string query = StringFormat("INSERT INTO `mail` " + "(`charid`, `timestamp`, `from`, `subject`, `body`, `to`, `status`) " + "VALUES ('%i', %i, '%s', '%s', '%s', '%s', %i)", + characterID, now, from.c_str(), escSubject, escBody, + recipientsString.c_str(), 1); + safe_delete_array(escSubject); + safe_delete_array(escBody); + auto results = QueryDatabase(query); + if(!results.Success()) { + _log(UCS__ERROR, "SendMail: Query %s failed with error %s", query.c_str(), results.ErrorMessage().c_str()); return false; } - _log(UCS__TRACE, "MessageID %i generated, from %s, to %s", LastMsgID, From.c_str(), Recipient.c_str()); + _log(UCS__TRACE, "MessageID %i generated, from %s, to %s", results.LastInsertedID(), from.c_str(), recipient.c_str()); - safe_delete_array(EscSubject); - safe_delete_array(EscBody); - safe_delete_array(query); - Client *c = CL->IsCharacterOnline(CharacterName); + Client *client = CL->IsCharacterOnline(characterName); - if(c) { - std::string FQN = GetMailPrefix() + From; - - c->SendNotification(c->GetMailBoxNumber(CharacterName), Subject, FQN, LastMsgID); + if(client) { + std::string FQN = GetMailPrefix() + from; + client->SendNotification(client->GetMailBoxNumber(characterName), subject, FQN, results.LastInsertedID()); } MailMessagesSent++; From c9bd662b57cfb01d62b8070ac4cd5b6aac6373f6 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 22:07:04 -0700 Subject: [PATCH 23/89] SetMessageStatus converted to QueryDatabase --- ucs/database.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 6bdf2b1e8..4e47b27ed 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -428,11 +428,8 @@ void Database::SendBody(Client *client, int messageNumber) { bool Database::SendMail(std::string recipient, std::string from, std::string subject, std::string body, std::string recipientsString) { int characterID; - std::string characterName; - //printf("Database::SendMail(%s, %s, %s)\n", Recipient.c_str(), From.c_str(), Subject.c_str()); - auto lastPeriod = recipient.find_last_of("."); if(lastPeriod == std::string::npos) @@ -488,22 +485,21 @@ bool Database::SendMail(std::string recipient, std::string from, std::string sub return true; } -void Database::SetMessageStatus(int MessageNumber, int Status) { +void Database::SetMessageStatus(int messageNumber, int status) { - _log(UCS__TRACE, "SetMessageStatus %i %i", MessageNumber, Status); + _log(UCS__TRACE, "SetMessageStatus %i %i", messageNumber, status); - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + if(status == 0) { + std::string query = StringFormat("DELETE FROM `mail` WHERE `msgid` = %i", messageNumber); + auto results = QueryDatabase(query); + return; + } - if(Status == 0) - RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `msgid`=%i", MessageNumber), errbuf); - else if (!RunQuery(query, MakeAnyLenString(&query, "update `mail` set `status`=%i where `msgid`=%i", Status, MessageNumber), errbuf)) { + std::string query = StringFormat("UPDATE `mail` SET `status` = %i WHERE `msgid`=%i", status, messageNumber); + auto results = QueryDatabase(query); + if (!results.Success()) + _log(UCS__ERROR, "Error updating status %s, %s", query.c_str(), results.ErrorMessage().c_str()); - _log(UCS__ERROR, "Error updating status %s, %s", query, errbuf); - - } - - safe_delete_array(query); } void Database::ExpireMail() { From 20e978b6769f6096775fac3bdcff9e2a56356d4a Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 22:16:37 -0700 Subject: [PATCH 24/89] ExpiredMail converted to QueryDatabase --- ucs/database.cpp | 68 +++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 4e47b27ed..d66b41418 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -506,58 +506,48 @@ void Database::ExpireMail() { _log(UCS__INIT, "Expiring mail..."); - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - uint32 AffectedRows; - - if (!RunQuery(query,MakeAnyLenString(&query, "select COUNT(*) from `mail` "),errbuf,&result)){ - _log(UCS__ERROR, "Unable to get message count from database. %s %s", query, errbuf); - safe_delete_array(query); - return ; + std::string query = "SELECT COUNT(*) FROM `mail`"; + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(UCS__ERROR, "Unable to get message count from database. %s %s", query.c_str(), results.ErrorMessage().c_str()); + return; } - safe_delete_array(query); - row = mysql_fetch_row(result); + auto row = results.begin(); _log(UCS__INIT, "There are %s messages in the database.", row[0]); - mysql_free_result(result); - // Expire Trash if(RuleI(Mail, ExpireTrash) >= 0) { - if(RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `status`=4 and `timestamp` < %i", - time(nullptr) - RuleI(Mail, ExpireTrash)), errbuf, 0, &AffectedRows)) { - _log(UCS__INIT, "Expired %i trash messages.", AffectedRows); - } - else { - _log(UCS__ERROR, "Error expiring trash messages, %s %s", query, errbuf); - } - safe_delete_array(query); + query = StringFormat("DELETE FROM `mail` WHERE `status`=4 AND `timestamp` < %i", + time(nullptr) - RuleI(Mail, ExpireTrash)); + results = QueryDatabase(query); + if(!results.Success()) + _log(UCS__INIT, "Expired %i trash messages.", results.RowsAffected()); + else + _log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); } + // Expire Read if(RuleI(Mail, ExpireRead) >= 0) { - if(RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `status`=3 and `timestamp` < %i", - time(nullptr) - RuleI(Mail, ExpireRead)), errbuf, 0, &AffectedRows)) { - _log(UCS__INIT, "Expired %i read messages.", AffectedRows); - } - else { - _log(UCS__ERROR, "Error expiring read messages, %s %s", query, errbuf); - } - safe_delete_array(query); + query = StringFormat("DELETE FROM `mail` WHERE `status` = 3 AND `timestamp` < %i", + time(nullptr) - RuleI(Mail, ExpireRead)); + results = QueryDatabase(query); + if(!results.Success()) + _log(UCS__INIT, "Expired %i read messages.", results.RowsAffected()); + else + _log(UCS__ERROR, "Error expiring read messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); } + // Expire Unread if(RuleI(Mail, ExpireUnread) >= 0) { - if(RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `status`=1 and `timestamp` < %i", - time(nullptr) - RuleI(Mail, ExpireUnread)), errbuf, 0, &AffectedRows)) { - _log(UCS__INIT, "Expired %i unread messages.", AffectedRows); - } - else { - _log(UCS__ERROR, "Error expiring unread messages, %s %s", query, errbuf); - } - safe_delete_array(query); + query = StringFormat("DELETE FROM `mail` WHERE `status`=1 AND `timestamp` < %i", + time(nullptr) - RuleI(Mail, ExpireUnread)); + results = QueryDatabase(query); + if(!results.Success()) + _log(UCS__INIT, "Expired %i unread messages.", results.RowsAffected()); + else + _log(UCS__ERROR, "Error expiring unread messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); } } From 9d5f427f5738d1e17538a8e9cd28c98f5e01f8b9 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 22:20:16 -0700 Subject: [PATCH 25/89] AddFriendOrIgnore converted to QueryDatabase --- ucs/database.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index d66b41418..36e2b1251 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -551,22 +551,17 @@ void Database::ExpireMail() { } } -void Database::AddFriendOrIgnore(int CharID, int Type, std::string Name) { +void Database::AddFriendOrIgnore(int charID, int type, std::string name) { - const char *FriendsQuery="INSERT INTO `friends` (`charid`, `type`, `name`) VALUES ('%i', %i, '%s')"; - - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - - - if(!RunQuery(query, MakeAnyLenString(&query, FriendsQuery, CharID, Type, CapitaliseName(Name).c_str()), errbuf, 0, 0)) - _log(UCS__ERROR, "Error adding friend/ignore, query was %s : %s", query, errbuf); + std::string query = StringFormat("INSERT INTO `friends` (`charid`, `type`, `name`) " + "VALUES('%i', %i, '%s')", + charID, type, CapitaliseName(name).c_str()); + auto results = QueryDatabase(query); + if(!results.Success()) + _log(UCS__ERROR, "Error adding friend/ignore, query was %s : %s", query.c_str(), results.ErrorMessage().c_str()); else - _log(UCS__TRACE, "Wrote Friend/Ignore entry for charid %i, type %i, name %s to database.", - CharID, Type, Name.c_str()); + _log(UCS__TRACE, "Wrote Friend/Ignore entry for charid %i, type %i, name %s to database.", charID, type, name.c_str()); - - safe_delete_array(query); } void Database::RemoveFriendOrIgnore(int CharID, int Type, std::string Name) { From c1469a3a8e1a4f592aa70bd1ef9e380153d5289e Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 22:22:49 -0700 Subject: [PATCH 26/89] RemoveFriendOrIgnore converted to QueryDatabase --- ucs/database.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 36e2b1251..880972152 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -564,21 +564,17 @@ void Database::AddFriendOrIgnore(int charID, int type, std::string name) { } -void Database::RemoveFriendOrIgnore(int CharID, int Type, std::string Name) { +void Database::RemoveFriendOrIgnore(int charID, int type, std::string name) { - const char *FriendsQuery="DELETE FROM `friends` WHERE `charid`=%i AND `type`=%i and `name`='%s'"; - - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - - if(!RunQuery(query, MakeAnyLenString(&query, FriendsQuery, CharID, Type, CapitaliseName(Name).c_str()), errbuf, 0, 0)) - _log(UCS__ERROR, "Error removing friend/ignore, query was %s", query); + std::string query = StringFormat("DELETE FROM `friends` WHERE `charid` = %i " + "AND `type` = %i AND `name` = '%s'", + charID, type, CapitaliseName(name).c_str()); + auto results = QueryDatabase(query); + if(!results.Success()) + _log(UCS__ERROR, "Error removing friend/ignore, query was %s", query.c_str()); else - _log(UCS__TRACE, "Removed Friend/Ignore entry for charid %i, type %i, name %s from database.", - CharID, Type, Name.c_str()); + _log(UCS__TRACE, "Removed Friend/Ignore entry for charid %i, type %i, name %s from database.", charID, type, name.c_str()); - - safe_delete_array(query); } void Database::GetFriendsAndIgnore(int CharID, std::vector &Friends, std::vector &Ignorees) { From 232d61b98394cbe9a46babc22b14b2747cd64c85 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sat, 23 Aug 2014 22:33:05 -0700 Subject: [PATCH 27/89] GetFriendAndIgnore converted to QueryDatabase --- ucs/database.cpp | 43 ++++++++++++++----------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index 880972152..d3c44174c 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -577,44 +577,29 @@ void Database::RemoveFriendOrIgnore(int charID, int type, std::string name) { } -void Database::GetFriendsAndIgnore(int CharID, std::vector &Friends, std::vector &Ignorees) { +void Database::GetFriendsAndIgnore(int charID, std::vector &friends, std::vector &ignorees) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - const char *FriendsQuery="select `type`, `name` from `friends` WHERE `charid`=%i"; - - if (!RunQuery(query,MakeAnyLenString(&query, FriendsQuery, CharID),errbuf,&result)){ - - _log(UCS__ERROR, "GetFriendsAndIgnore query error %s, %s", query, errbuf); - - safe_delete_array(query); - - return ; + std::string query = StringFormat("select `type`, `name` FROM `friends` WHERE `charid`=%i", charID); + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(UCS__ERROR, "GetFriendsAndIgnore query error %s, %s", query.c_str(), results.ErrorMessage().c_str()); + return; } - safe_delete_array(query); - while((row = mysql_fetch_row(result))) { - - std::string Name = row[1]; + for (auto row = results.begin(); row != results.end(); ++row) { + std::string name = row[1]; if(atoi(row[0]) == 0) { - Ignorees.push_back(Name); - _log(UCS__TRACE, "Added Ignoree from DB %s", Name.c_str()); - } - else - { - Friends.push_back(Name); - _log(UCS__TRACE, "Added Friend from DB %s", Name.c_str()); + ignorees.push_back(name); + _log(UCS__TRACE, "Added Ignoree from DB %s", name.c_str()); + continue; } + + friends.push_back(name); + _log(UCS__TRACE, "Added Friend from DB %s", name.c_str()); } - mysql_free_result(result); - - return; } From 377c6a87a2bb629462431cf68c2ab84c1b8b7f71 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 11:53:28 -0700 Subject: [PATCH 28/89] GetDoorsCount converted to QueryDatabase --- zone/doors.cpp | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/zone/doors.cpp b/zone/doors.cpp index c353ce568..d3b9ec6ec 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -568,36 +568,31 @@ void Doors::DumpDoor(){ } int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - query = new char[256]; - sprintf(query, "SELECT MAX(id), count(*) FROM doors WHERE zone='%s' AND (version=%u OR version=-1)", zone_name, version); - if (RunQuery(query, strlen(query), errbuf, &result)) { - safe_delete_array(query); - row = mysql_fetch_row(result); - if (row != nullptr && row[1] != 0) { - int32 ret = atoi(row[1]); - if (oMaxID) { - if (row[0]) - *oMaxID = atoi(row[0]); - else - *oMaxID = 0; - } - mysql_free_result(result); - return ret; - } - mysql_free_result(result); - } - else { - std::cerr << "Error in GetDoorsCount query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::string query = StringFormat("SELECT MAX(id), count(*) FROM doors " + "WHERE zone = '%s' AND (version = %u OR version = -1)", + zone_name, version); + auto results = QueryDatabase(query); + if (!results.Success()) { + std::cerr << "Error in GetDoorsCount query '" << query << "' " << results.ErrorMessage() << std::endl; return -1; - } + } + + if (results.RowCount() != 1) + return -1; + + auto row = results.begin(); + + if (!oMaxID) + return atoi(row[1]); + + if (row[0]) + *oMaxID = atoi(row[0]); + else + *oMaxID = 0; + + return atoi(row[1]); - return -1; } int32 ZoneDatabase::GetDoorsCountPlusOne(const char *zone_name, int16 version) { From 8f4e2e99db454a124a6ccaf9b31a476fbce41d21 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 12:00:45 -0700 Subject: [PATCH 29/89] GetDoorsCountPlusOne converted to QueryDatabase --- zone/doors.cpp | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/zone/doors.cpp b/zone/doors.cpp index d3b9ec6ec..375b59be5 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -596,34 +596,24 @@ int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 v } int32 ZoneDatabase::GetDoorsCountPlusOne(const char *zone_name, int16 version) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 oMaxID = 0; - MYSQL_RES *result; - MYSQL_ROW row; - query = new char[256]; - sprintf(query, "SELECT MAX(id) FROM doors WHERE zone='%s' AND version=%u", zone_name, version); - if (RunQuery(query, strlen(query), errbuf, &result)) { - safe_delete_array(query); - row = mysql_fetch_row(result); - if (row != nullptr && row[1] != 0) { - if (row[0]) - oMaxID = atoi(row[0]) + 1; - else - oMaxID = 0; - mysql_free_result(result); - return oMaxID; - } - mysql_free_result(result); - } - else { - std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::string query = StringFormat("SELECT MAX(id) FROM doors " + "WHERE zone = '%s' AND version = %u", zone_name, version); + auto results = QueryDatabase(query); + if (!results.Success()) { + std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << results.ErrorMessage() << std::endl; return -1; - } + } - return -1; + if (results.RowCount() != 1) + return -1; + + auto row = results.begin(); + + if (!row[0]) + return 0; + + return atoi(row[0]) + 1; } int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version) { From 5d6d48988964f46063dfb786c345ae1ccbe4b944 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 12:08:39 -0700 Subject: [PATCH 30/89] GetDoorsDBCountPlusOne converted to QueryDatabase --- zone/doors.cpp | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/zone/doors.cpp b/zone/doors.cpp index 375b59be5..f01c4dbc0 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -617,34 +617,27 @@ int32 ZoneDatabase::GetDoorsCountPlusOne(const char *zone_name, int16 version) { } int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; + uint32 oMaxID = 0; - MYSQL_RES *result; - MYSQL_ROW row; - query = new char[256]; - sprintf(query, "SELECT MAX(doorid) FROM doors WHERE zone='%s' AND (version=%u OR version=-1)", zone_name, version); - if (RunQuery(query, strlen(query), errbuf, &result)) { - safe_delete_array(query); - row = mysql_fetch_row(result); - if (row != nullptr && row[1] != 0) { - if (row[0]) - oMaxID = atoi(row[0]) + 1; - else - oMaxID = 0; - mysql_free_result(result); - return oMaxID; - } - mysql_free_result(result); - } - else { - std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::string query = StringFormat("SELECT MAX(doorid) FROM doors " + "WHERE zone = '%s' AND (version = %u OR version = -1)", + zone_name, version); + auto results = QueryDatabase(query); + if (!results.Success()) { + std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << results.ErrorMessage() << std::endl; return -1; } - return -1; + if (results.RowCount() != 1) + return -1; + + auto row = results.begin(); + + if (!row[0]) + return 0; + + return atoi(row[0]) + 1; } bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version) { From 9707b53df26b68a3938c43bca7bd17d3ee5de51c Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 12:14:16 -0700 Subject: [PATCH 31/89] LoadDoors converted to QueryDatabase --- zone/doors.cpp | 104 +++++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/zone/doors.cpp b/zone/doors.cpp index f01c4dbc0..5ff7eae26 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -642,61 +642,63 @@ int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version) bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version) { LogFile->write(EQEMuLog::Status, "Loading Doors from database..."); - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + // Door tmpDoor; - MakeAnyLenString(&query, "SELECT id,doorid,zone,name,pos_x,pos_y,pos_z,heading," - "opentype,guild,lockpick,keyitem,nokeyring,triggerdoor,triggertype,dest_zone,dest_instance,dest_x," - "dest_y,dest_z,dest_heading,door_param,invert_state,incline,size,is_ldon_door,client_version_mask " - "FROM doors WHERE zone='%s' AND (version=%u OR version=-1) ORDER BY doorid asc", zone_name, version); - if (RunQuery(query, strlen(query), errbuf, &result)) { - safe_delete_array(query); - int32 r; - for(r = 0; (row = mysql_fetch_row(result)); r++) { - if(r >= iDoorCount) { - std::cerr << "Error, Door Count of " << iDoorCount << " exceeded." << std::endl; - break; - } - memset(&into[r], 0, sizeof(Door)); - into[r].db_id = atoi(row[0]); - into[r].door_id = atoi(row[1]); - strn0cpy(into[r].zone_name,row[2],32); - strn0cpy(into[r].door_name,row[3],32); - into[r].pos_x = (float)atof(row[4]); - into[r].pos_y = (float)atof(row[5]); - into[r].pos_z = (float)atof(row[6]); - into[r].heading = (float)atof(row[7]); - into[r].opentype = atoi(row[8]); - into[r].guild_id = atoi(row[9]); - into[r].lockpick = atoi(row[10]); - into[r].keyitem = atoi(row[11]); - into[r].nokeyring = atoi(row[12]); - into[r].trigger_door = atoi(row[13]); - into[r].trigger_type = atoi(row[14]); - strn0cpy(into[r].dest_zone, row[15], 32); - into[r].dest_instance_id = atoi(row[16]); - into[r].dest_x = (float) atof(row[17]); - into[r].dest_y = (float) atof(row[18]); - into[r].dest_z = (float) atof(row[19]); - into[r].dest_heading = (float) atof(row[20]); - into[r].door_param=atoi(row[21]); - into[r].invert_state=atoi(row[22]); - into[r].incline=atoi(row[23]); - into[r].size=atoi(row[24]); - into[r].is_ldon_door=atoi(row[25]); - into[r].client_version_mask = (uint32)strtoul(row[26], nullptr, 10); - } - mysql_free_result(result); - } - else - { - std::cerr << "Error in DBLoadDoors query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::string query = StringFormat("SELECT id, doorid, zone, name, pos_x, pos_y, pos_z, heading, " + "opentype, guild, lockpick, keyitem, nokeyring, triggerdoor, triggertype, " + "dest_zone, dest_instance, dest_x, dest_y, dest_z, dest_heading, " + "door_param, invert_state, incline, size, is_ldon_door, client_version_mask " + "FROM doors WHERE zone = '%s' AND (version = %u OR version = -1) " + "ORDER BY doorid asc", zone_name, version); + auto results = QueryDatabase(query); + if (!results.Success()){ + std::cerr << "Error in DBLoadDoors query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } + + int32 rowIndex = 0; + for(auto row = results.begin(); row != results.end(); ++row, ++rowIndex) { + if(rowIndex >= iDoorCount) { + std::cerr << "Error, Door Count of " << iDoorCount << " exceeded." << std::endl; + break; + } + + memset(&into[rowIndex], 0, sizeof(Door)); + + into[rowIndex].db_id = atoi(row[0]); + into[rowIndex].door_id = atoi(row[1]); + + strn0cpy(into[rowIndex].zone_name,row[2],32); + strn0cpy(into[rowIndex].door_name,row[3],32); + + into[rowIndex].pos_x = (float)atof(row[4]); + into[rowIndex].pos_y = (float)atof(row[5]); + into[rowIndex].pos_z = (float)atof(row[6]); + into[rowIndex].heading = (float)atof(row[7]); + into[rowIndex].opentype = atoi(row[8]); + into[rowIndex].guild_id = atoi(row[9]); + into[rowIndex].lockpick = atoi(row[10]); + into[rowIndex].keyitem = atoi(row[11]); + into[rowIndex].nokeyring = atoi(row[12]); + into[rowIndex].trigger_door = atoi(row[13]); + into[rowIndex].trigger_type = atoi(row[14]); + + strn0cpy(into[rowIndex].dest_zone, row[15], 32); + + into[rowIndex].dest_instance_id = atoi(row[16]); + into[rowIndex].dest_x = (float) atof(row[17]); + into[rowIndex].dest_y = (float) atof(row[18]); + into[rowIndex].dest_z = (float) atof(row[19]); + into[rowIndex].dest_heading = (float) atof(row[20]); + into[rowIndex].door_param=atoi(row[21]); + into[rowIndex].invert_state=atoi(row[22]); + into[rowIndex].incline=atoi(row[23]); + into[rowIndex].size=atoi(row[24]); + into[rowIndex].is_ldon_door=atoi(row[25]); + into[rowIndex].client_version_mask = (uint32)strtoul(row[26], nullptr, 10); + } + return true; } From 3d1521857ea7a1077a8c3b45265d874014f3a1d6 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 12:21:16 -0700 Subject: [PATCH 32/89] LoadStaticZonePoints converted to QueryDatabase --- zone/zone.cpp | 66 ++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/zone/zone.cpp b/zone/zone.cpp index a3026425c..a85b2d9ff 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1678,45 +1678,41 @@ ZonePoint* Zone::GetClosestZonePointWithoutZone(float x, float y, float z, Clien bool ZoneDatabase::LoadStaticZonePoints(LinkedList* zone_point_list, const char* zonename, uint32 version) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + zone_point_list->Clear(); zone->numzonepoints = 0; - MakeAnyLenString(&query, "SELECT x, y, z, target_x, target_y, " - "target_z, target_zone_id, heading, target_heading, number, " - "target_instance, client_version_mask FROM zone_points " - "WHERE zone='%s' AND (version=%i OR version=-1) order by number", zonename, version); - if (RunQuery(query, strlen(query), errbuf, &result)) - { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) - { - ZonePoint* zp = new ZonePoint; - zp->x = atof(row[0]); - zp->y = atof(row[1]); - zp->z = atof(row[2]); - zp->target_x = atof(row[3]); - zp->target_y = atof(row[4]); - zp->target_z = atof(row[5]); - zp->target_zone_id = atoi(row[6]); - zp->heading = atof(row[7]); - zp->target_heading = atof(row[8]); - zp->number = atoi(row[9]); - zp->target_zone_instance = atoi(row[10]); - zp->client_version_mask = (uint32)strtoul(row[11], nullptr, 0); - zone_point_list->Insert(zp); - zone->numzonepoints++; - } - mysql_free_result(result); - } - else - { - std::cerr << "Error1 in LoadStaticZonePoints query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); + std::string query = StringFormat("SELECT x, y, z, target_x, target_y, " + "target_z, target_zone_id, heading, target_heading, " + "number, target_instance, client_version_mask " + "FROM zone_points WHERE zone='%s' AND (version=%i OR version=-1) " + "ORDER BY number", zonename, version); + auto results = QueryDatabase(query); + if (!results.Success()) { + std::cerr << "Error1 in LoadStaticZonePoints query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } + + for (auto row = results.begin(); row != results.end(); ++row) { + ZonePoint* zp = new ZonePoint; + + zp->x = atof(row[0]); + zp->y = atof(row[1]); + zp->z = atof(row[2]); + zp->target_x = atof(row[3]); + zp->target_y = atof(row[4]); + zp->target_z = atof(row[5]); + zp->target_zone_id = atoi(row[6]); + zp->heading = atof(row[7]); + zp->target_heading = atof(row[8]); + zp->number = atoi(row[9]); + zp->target_zone_instance = atoi(row[10]); + zp->client_version_mask = (uint32)strtoul(row[11], nullptr, 0); + + zone_point_list->Insert(zp); + + zone->numzonepoints++; + } + return true; } From e7ef4b5484fe3df0fa0e78eff5ac415aa7ddf7ea Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 12:37:44 -0700 Subject: [PATCH 33/89] SpellGlobalCheck converted to QueryDatabase --- zone/spells.cpp | 160 ++++++++++++++++++++++-------------------------- 1 file changed, 74 insertions(+), 86 deletions(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index 4eddf5883..357fafbd4 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1252,7 +1252,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, } } - if(IsClient()) { + if(IsClient()) { CheckNumHitsRemaining(NUMHIT_MatchingSpells); TrySympatheticProc(target, spell_id); } @@ -1378,7 +1378,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce mlog(AA__MESSAGE, "Project Illusion overwrote target caster: %s spell id: %d was ON", GetName(), spell_id); targetType = ST_GroupClientAndPet; } - + if (spell_target && !spell_target->PassCastRestriction(true, spells[spell_id].CastRestriction)){ Message_StringID(13,SPELL_NEED_TAR); return false; @@ -1386,16 +1386,16 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce //Must be out of combat. (If Beneficial checks casters combat state, Deterimental checks targets) if (!spells[spell_id].InCombat && spells[spell_id].OutofCombat){ - if (IsDetrimentalSpell(spell_id)) { - if ( (spell_target->IsNPC() && spell_target->IsEngaged()) || + if (IsDetrimentalSpell(spell_id)) { + if ( (spell_target->IsNPC() && spell_target->IsEngaged()) || (spell_target->IsClient() && spell_target->CastToClient()->GetAggroCount())){ Message_StringID(13,SPELL_NO_EFFECT); //Unsure correct string return false; } } - else if (IsBeneficialSpell(spell_id)) { - if ( (IsNPC() && IsEngaged()) || + else if (IsBeneficialSpell(spell_id)) { + if ( (IsNPC() && IsEngaged()) || (IsClient() && CastToClient()->GetAggroCount())){ if (IsDiscipline(spell_id)) Message_StringID(13,NO_ABILITY_IN_COMBAT); @@ -1409,16 +1409,16 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce //Must be in combat. (If Beneficial checks casters combat state, Deterimental checks targets) else if (spells[spell_id].InCombat && !spells[spell_id].OutofCombat){ - if (IsDetrimentalSpell(spell_id)) { - if ( (spell_target->IsNPC() && !spell_target->IsEngaged()) || + if (IsDetrimentalSpell(spell_id)) { + if ( (spell_target->IsNPC() && !spell_target->IsEngaged()) || (spell_target->IsClient() && !spell_target->CastToClient()->GetAggroCount())){ Message_StringID(13,SPELL_NO_EFFECT); //Unsure correct string return false; } } - else if (IsBeneficialSpell(spell_id)) { - if ( (IsNPC() && !IsEngaged()) || + else if (IsBeneficialSpell(spell_id)) { + if ( (IsNPC() && !IsEngaged()) || (IsClient() && !CastToClient()->GetAggroCount())){ if (IsDiscipline(spell_id)) Message_StringID(13,NO_ABILITY_OUT_OF_COMBAT); @@ -1782,10 +1782,10 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce case ST_PetMaster: { - + Mob *owner = nullptr; - - if (IsPet()) + + if (IsPet()) owner = GetOwner(); else if ((IsNPC() && CastToNPC()->GetSwarmOwner())) owner = entity_list.GetMobID(CastToNPC()->GetSwarmOwner()); @@ -1975,7 +1975,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 if (!TrySpellProjectile(spell_target, spell_id)) return false; } - + else if(!SpellOnTarget(spell_id, spell_target, false, true, resist_adjust, false)) { if(IsBuffSpell(spell_id) && IsBeneficialSpell(spell_id)) { // Prevent mana usage/timers being set for beneficial buffs @@ -2723,7 +2723,7 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, if ((effect2 == SE_BStacker) && (!IsCastonFadeDurationSpell(spellid1) && buffs[buffslot].ticsremaining != 1 && IsEffectInSpell(spellid1, SE_CStacker))) return -1; } - + if (spellbonuses.DStacker[0]) { if ((effect2 == SE_DStacker) && (sp2.effectid[i] <= spellbonuses.DStacker[1])) return -1; @@ -2775,7 +2775,7 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, mlog(SPELLS__STACKING, "%s (%d) blocks effect %d on slot %d below %d, but we do not have that effect on that slot. Ignored.", sp1.name, spellid1, blocked_effect, blocked_slot, blocked_below_value); } - } + } } } else { mlog(SPELLS__STACKING, "%s (%d) and %s (%d) appear to be in the same line, skipping Stacking Overwrite/Blocking checks", @@ -3564,7 +3564,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r if(spell_effectiveness == 0 || !IsPartialCapableSpell(spell_id) ) { mlog(SPELLS__RESISTS, "Spell %d was completely resisted by %s", spell_id, spelltar->GetName()); - + if (spells[spell_id].resisttype == RESIST_PHYSICAL){ Message_StringID(MT_SpellFailure, PHYSICAL_RESIST_FAIL,spells[spell_id].name); spelltar->Message_StringID(MT_SpellFailure, YOU_RESIST, spells[spell_id].name); @@ -3707,7 +3707,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r TrySpellTrigger(spelltar, spell_id); TryApplyEffect(spelltar, spell_id); - + if (spelltar->IsAIControlled() && IsDetrimentalSpell(spell_id) && !IsHarmonySpell(spell_id)) { int32 aggro_amount = CheckAggroAmount(spell_id, isproc); mlog(SPELLS__CASTING, "Spell %d cast on %s generated %d hate", spell_id, spelltar->GetName(), aggro_amount); @@ -3733,7 +3733,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r safe_delete(action_packet); return false; } - + // cause the effects to the target if(!spelltar->SpellEffect(this, spell_id, spell_effectiveness)) { @@ -3746,11 +3746,11 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r return false; } - + if (IsDetrimentalSpell(spell_id)) { - + CheckNumHitsRemaining(NUMHIT_OutgoingSpells); - + if (spelltar) spelltar->CheckNumHitsRemaining(NUMHIT_IncomingSpells); } @@ -4408,7 +4408,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use if (CharismaCheck) { - /* + /* Charisma ONLY effects the initial resist check when charm is cast with 10 CHA = -1 Resist mod up to 255 CHA (min ~ 75 cha) Charisma less than ~ 75 gives a postive modifier to resist checks at approximate ratio of -10 CHA = +6 Resist. Mez spells do same initial resist check as a above. @@ -4470,7 +4470,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use if (CharmTick) { int min_charmbreakchance = ((100/RuleI(Spells, CharmBreakCheckChance))/66 * 100)*2; - + if (resist_chance < min_charmbreakchance) resist_chance = min_charmbreakchance; } @@ -4965,68 +4965,56 @@ int Client::FindSpellBookSlotBySpellID(uint16 spellid) { return -1; //default } -bool Client::SpellGlobalCheck(uint16 Spell_ID, uint16 Char_ID) { +bool Client::SpellGlobalCheck(uint16 spell_ID, uint16 char_ID) { - std::string Spell_Global_Name; - int Spell_Global_Value; - int Global_Value; + std::string spell_Global_Name; + int spell_Global_Value; + int global_Value; - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - - if (database.RunQuery(query,MakeAnyLenString(&query, "SELECT qglobal, value FROM spell_globals WHERE spellid=%i", Spell_ID), errbuf, &result)) { - safe_delete_array(query); - - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - Spell_Global_Name = row[0]; - Spell_Global_Value = atoi(row[1]); - - mysql_free_result(result); - - if (Spell_Global_Name.empty()) { // If the entry in the spell_globals table has nothing set for the qglobal name - return true; - } - else if (database.RunQuery(query,MakeAnyLenString(&query, "SELECT value FROM quest_globals WHERE charid=%i AND name='%s'", Char_ID, Spell_Global_Name.c_str()), errbuf, &result)) { - safe_delete_array(query); - - if (mysql_num_rows(result) == 1) { - row = mysql_fetch_row(result); - - Global_Value = atoi(row[0]); - mysql_free_result(result); - if (Global_Value == Spell_Global_Value) { // If the values match from both tables, allow the spell to be scribed - return true; - } - else if (Global_Value > Spell_Global_Value) { // Check if the qglobal value is greater than the require spellglobal value - return true; - } - else // If no matching result found in qglobals, don't scribe this spell - { - LogFile->write(EQEMuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", Char_ID, Spell_Global_Name.c_str(), Spell_Global_Value, Global_Value, Spell_ID); - return false; - } - } - else - LogFile->write(EQEMuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", Char_ID, Spell_Global_Name.c_str(), Spell_ID); - safe_delete_array(query); - } - else - LogFile->write(EQEMuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", Spell_ID, Spell_Global_Name.c_str(), Spell_Global_Value); - } - else { - return true; // Spell ID isn't listed in the spells_global table, so it is not restricted from scribing - } - mysql_free_result(result); - } - else { - LogFile->write(EQEMuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", Spell_ID, query, errbuf); - safe_delete_array(query); + std::string query = StringFormat("SELECT qglobal, value FROM spell_globals " + "WHERE spellid = %i", spell_ID); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", spell_ID, query.c_str(), results.ErrorMessage().c_str()); return false; // Query failed, so prevent spell from scribing just in case - } - return false; // Default is false + } + + if (results.RowCount() != 1) + return true; // Spell ID isn't listed in the spells_global table, so it is not restricted from scribing + + auto row = results.begin(); + spell_Global_Name = row[0]; + spell_Global_Value = atoi(row[1]); + + if (spell_Global_Name.empty()) + return true; // If the entry in the spell_globals table has nothing set for the qglobal name + + query = StringFormat("SELECT value FROM quest_globals " + "WHERE charid = %i AND name = '%s'", + char_ID, spell_Global_Name.c_str()); + results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", spell_ID, spell_Global_Name.c_str(), spell_Global_Value); + return false; + } + + if (results.RowCount() != 1) { + LogFile->write(EQEMuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_ID); + return false; + } + + row = results.begin(); + + global_Value = atoi(row[0]); + + if (global_Value == spell_Global_Value) + return true; // If the values match from both tables, allow the spell to be scribed + else if (global_Value > spell_Global_Value) + return true; // Check if the qglobal value is greater than the require spellglobal value + + // If no matching result found in qglobals, don't scribe this spell + LogFile->write(EQEMuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_Global_Value, global_Value, spell_ID); + return false; } // TODO get rid of this @@ -5081,7 +5069,7 @@ bool Mob::FindType(uint16 type, bool bOffensive, uint16 threshold) { } bool Mob::IsCombatProc(uint16 spell_id) { - + if (RuleB(Spells, FocusCombatProcs)) return false; @@ -5092,7 +5080,7 @@ bool Mob::IsCombatProc(uint16 spell_id) { { for (int i = 0; i < MAX_PROCS; i++){ - if (PermaProcs[i].spellID == spell_id || SpellProcs[i].spellID == spell_id + if (PermaProcs[i].spellID == spell_id || SpellProcs[i].spellID == spell_id || RangedProcs[i].spellID == spell_id){ return true; } @@ -5150,7 +5138,7 @@ bool Mob::AddDefensiveProc(uint16 spell_id, uint16 iChance, uint16 base_spell_id { if(spell_id == SPELL_UNKNOWN) return(false); - + int i; for (i = 0; i < MAX_PROCS; i++) { if (DefensiveProcs[i].spellID == SPELL_UNKNOWN) { From adf36bf912d10440cde2d928e71939dab03c0a4d Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 12:46:02 -0700 Subject: [PATCH 34/89] LoadSpawnGroups converted to QueryDatabase --- zone/spawngroup.cpp | 82 +++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/zone/spawngroup.cpp b/zone/spawngroup.cpp index fc0360aee..ef0a0882a 100644 --- a/zone/spawngroup.cpp +++ b/zone/spawngroup.cpp @@ -140,53 +140,49 @@ bool SpawnGroupList::RemoveSpawnGroup(uint32 in_id) { } bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - query = 0; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawn2,spawngroup WHERE spawn2.spawngroupID=spawngroup.ID and spawn2.version=%u and zone='%s'", version, zone_name), errbuf, &result)) - { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) { - SpawnGroup* newSpawnGroup = new SpawnGroup( atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11])); - spawn_group_list->AddSpawnGroup(newSpawnGroup); - } - mysql_free_result(result); - } - else - { - _log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%s' ", query); - safe_delete_array(query); + std::string query = StringFormat("SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, " + "spawngroup.dist, spawngroup.max_x, spawngroup.min_x, " + "spawngroup.max_y, spawngroup.min_y, spawngroup.delay, " + "spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay " + "FROM spawn2, spawngroup WHERE spawn2.spawngroupID = spawngroup.ID " + "AND spawn2.version = %u and zone = '%s'", version, zone_name); + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%s' ", query.c_str()); return false; - } + } - query = 0; - if (RunQuery(query, MakeAnyLenString(&query, - "SELECT DISTINCT spawnentry.spawngroupID, npcid, chance, " - "npc_types.spawn_limit AS sl " - "FROM spawnentry, spawn2, npc_types " - "WHERE spawnentry.npcID=npc_types.id AND spawnentry.spawngroupID=spawn2.spawngroupID " - "AND zone='%s'", zone_name), errbuf, &result)) { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) - { - SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]), row[3]?atoi(row[3]):0); - SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0])); - if (sg) - sg->AddSpawnEntry(newSpawnEntry); - else - _log(ZONE__SPAWNS, "Error in LoadSpawnGroups %s ", query); - } - mysql_free_result(result); - } - else - { - _log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%'", query); - safe_delete_array(query); + for (auto row = results.begin(); row != results.end(); ++row) { + SpawnGroup* newSpawnGroup = new SpawnGroup(atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), + atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), + atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11])); + spawn_group_list->AddSpawnGroup(newSpawnGroup); + } + + query = StringFormat("SELECT DISTINCT spawnentry.spawngroupID, npcid, chance, " + "npc_types.spawn_limit AS sl " + "FROM spawnentry, spawn2, npc_types " + "WHERE spawnentry.npcID=npc_types.id " + "AND spawnentry.spawngroupID = spawn2.spawngroupID " + "AND zone = '%s'", zone_name); + results = QueryDatabase(query); + if (!results.Success()) { + _log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%'", query.c_str()); return false; - } + } + + for (auto row = results.begin(); row != results.end(); ++row) { + SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]), row[3]?atoi(row[3]):0); + SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0])); + + if (!sg) { + _log(ZONE__SPAWNS, "Error in LoadSpawnGroups %s ", query.c_str()); + continue; + } + + sg->AddSpawnEntry(newSpawnEntry); + } return true; } From 932dd836d0f706d6de579919fc49bb34a4675cb2 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 12:54:06 -0700 Subject: [PATCH 35/89] LoadSpawnGroupsByID converted to QueryDatabase --- zone/spawngroup.cpp | 73 +++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/zone/spawngroup.cpp b/zone/spawngroup.cpp index ef0a0882a..81d6c5d51 100644 --- a/zone/spawngroup.cpp +++ b/zone/spawngroup.cpp @@ -188,49 +188,44 @@ bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnG } bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - query = 0; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT spawngroup.id, spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawngroup WHERE spawngroup.ID='%i'", spawngroupid), errbuf, &result)) - { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) { - SpawnGroup* newSpawnGroup = new SpawnGroup( atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11])); - spawn_group_list->AddSpawnGroup(newSpawnGroup); - } - mysql_free_result(result); - } - else - { - _log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query %s", query); - safe_delete_array(query); + + std::string query = StringFormat("SELECT DISTINCT(spawngroup.id), spawngroup.name, spawngroup.spawn_limit, " + "spawngroup.dist, spawngroup.max_x, spawngroup.min_x, " + "spawngroup.max_y, spawngroup.min_y, spawngroup.delay, " + "spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay " + "FROM spawngroup WHERE spawngroup.ID = '%i'", spawngroupid); + auto results = QueryDatabase(query); + if (!results.Success()) { + _log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query %s", query.c_str()); + return false; + } + + for (auto row = results.begin(); row != results.end(); ++row) { + SpawnGroup* newSpawnGroup = new SpawnGroup(atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11])); + spawn_group_list->AddSpawnGroup(newSpawnGroup); + } + + query = StringFormat("SELECT DISTINCT(spawnentry.spawngroupID), spawnentry.npcid, " + "spawnentry.chance, spawngroup.spawn_limit FROM spawnentry, spawngroup " + "WHERE spawnentry.spawngroupID = '%i' AND spawngroup.spawn_limit = '0' " + "ORDER BY chance", spawngroupid); + results = QueryDatabase(query); + if (!results.Success()) { + _log(ZONE__SPAWNS, "Error3 in PopulateZoneLists query '%s'", query.c_str()); return false; } - query = 0; - if (RunQuery(query, MakeAnyLenString(&query, - "SELECT DISTINCT spawnentry.spawngroupID, spawnentry.npcid, spawnentry.chance, spawngroup.spawn_limit FROM spawnentry,spawngroup WHERE spawnentry.spawngroupID='%i' AND spawngroup.spawn_limit='0' ORDER by chance", spawngroupid), errbuf, &result)) { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) - { - SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]), row[3]?atoi(row[3]):0); - SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0])); - if (sg) - sg->AddSpawnEntry(newSpawnEntry); - else - _log(ZONE__SPAWNS, "Error in SpawngroupID: %s ", row[0]); - } - mysql_free_result(result); - } - else - { - _log(ZONE__SPAWNS, "Error3 in PopulateZoneLists query '%s'", row[0]); - safe_delete_array(query); - return false; - } + for(auto row = results.begin(); row != results.end(); ++row) { + SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]), row[3]?atoi(row[3]):0); + SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0])); + if (!sg) { + _log(ZONE__SPAWNS, "Error in SpawngroupID: %s ", row[0]); + continue; + } + + sg->AddSpawnEntry(newSpawnEntry); + } return true; } From 42a51eb37341cdec85275526bff8eca5d8f31311 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 13:00:39 -0700 Subject: [PATCH 36/89] PopulateZoneSpawnList converted to QueryDatabase --- zone/spawn2.cpp | 58 +++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index dd541e0a2..53656489c 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -354,34 +354,30 @@ void Spawn2::DeathReset(bool realdeath) } bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version, uint32 repopdelay) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; const char *zone_name = database.GetZoneName(zoneid); - - MakeAnyLenString(&query, "SELECT id, spawngroupID, x, y, z, heading, respawntime, variance, pathgrid, _condition, cond_value, enabled, animation FROM spawn2 WHERE zone='%s' AND version=%u", zone_name, version); - if (RunQuery(query, strlen(query), errbuf, &result)) - { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) - { - Spawn2* newSpawn = 0; - - bool perl_enabled = atoi(row[11]) == 1 ? true : false; - uint32 spawnLeft = (GetSpawnTimeLeft(atoi(row[0]), zone->GetInstanceID()) * 1000); - newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atoi(row[6]), atoi(row[7]), spawnLeft, atoi(row[8]), atoi(row[9]), atoi(row[10]), perl_enabled, (EmuAppearance)atoi(row[12])); - spawn2_list.Insert( newSpawn ); - } - mysql_free_result(result); - } - else - { - LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query, errbuf); - safe_delete_array(query); + std::string query = StringFormat("SELECT id, spawngroupID, x, y, z, heading, " + "respawntime, variance, pathgrid, _condition, " + "cond_value, enabled, animation FROM spawn2 " + "WHERE zone = '%s' AND version = %u", + zone_name, version); + auto results = QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; - } + } + + for (auto row = results.begin(); row != results.end(); ++row) { + Spawn2* newSpawn = 0; + + bool perl_enabled = atoi(row[11]) == 1? true: false; + uint32 spawnLeft = (GetSpawnTimeLeft(atoi(row[0]), zone->GetInstanceID()) * 1000); + newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), + atof(row[5]), atoi(row[6]), atoi(row[7]), spawnLeft, atoi(row[8]), + atoi(row[9]), atoi(row[10]), perl_enabled, (EmuAppearance)atoi(row[12])); + + spawn2_list.Insert(newSpawn); + } return true; } @@ -863,10 +859,10 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in SpawnEvent &cevent = *cur; bool StrictCheck = false; - if(cevent.strict && - cevent.next.hour == tod.hour && - cevent.next.day == tod.day && - cevent.next.month == tod.month && + if(cevent.strict && + cevent.next.hour == tod.hour && + cevent.next.day == tod.day && + cevent.next.month == tod.month && cevent.next.year == tod.year) StrictCheck = true; @@ -894,7 +890,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in //execute the event if(!cevent.strict || StrictCheck) ExecEvent(cevent, false); - + //add the period of the event to the trigger time EQTime::AddMinutes(cevent.period, &cevent.next); ran = true; @@ -926,7 +922,7 @@ void SpawnConditionManager::FindNearestEvent() { if(cevent.enabled) { //see if this event is before our last nearest - if(EQTime::IsTimeBefore(&next_event, &cevent.next)) + if(EQTime::IsTimeBefore(&next_event, &cevent.next)) { memcpy(&next_event, &cevent.next, sizeof(next_event)); next_id = cevent.id; From 9980dfe80e8ac3682ed803bd04400e60c0ef66c7 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 13:03:45 -0700 Subject: [PATCH 37/89] LoadSpawn2 converted to QueryDatabase --- zone/spawn2.cpp | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 53656489c..e7e5e9e81 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -384,28 +384,33 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList &spa Spawn2* ZoneDatabase::LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2id, uint32 timeleft) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, spawngroupID, x, y, z, heading, respawntime, variance, pathgrid, _condition, cond_value, enabled, animation FROM spawn2 WHERE id=%i", spawn2id), errbuf, &result)) { - if (mysql_num_rows(result) == 1) - { - row = mysql_fetch_row(result); - bool perl_enabled = atoi(row[11]) == 1 ? true : false; - Spawn2* newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atoi(row[6]), atoi(row[7]), timeleft, atoi(row[8]), atoi(row[9]), atoi(row[10]), perl_enabled, (EmuAppearance)atoi(row[12])); - spawn2_list.Insert( newSpawn ); - mysql_free_result(result); - safe_delete_array(query); - return newSpawn; - } - mysql_free_result(result); - } + std::string query = StringFormat("SELECT id, spawngroupID, x, y, z, heading, " + "respawntime, variance, pathgrid, _condition, " + "cond_value, enabled, animation FROM spawn2 " + "WHERE id = %i", spawn2id); + auto results = QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + return nullptr; + } - LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query, errbuf); - safe_delete_array(query); - return 0; + if (results.RowCount() != 1) { + LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + return nullptr; + } + + auto row = results.begin(); + + bool perl_enabled = atoi(row[11]) == 1 ? true : false; + + Spawn2* newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), + atof(row[5]), atoi(row[6]), atoi(row[7]), timeleft, atoi(row[8]), + atoi(row[9]), atoi(row[10]), perl_enabled, (EmuAppearance)atoi(row[12])); + + spawn2_list.Insert(newSpawn); + + return newSpawn; } bool ZoneDatabase::CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value) From c70c7e13ec9510b09d33603b47ab14f5b6278b45 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 13:07:15 -0700 Subject: [PATCH 38/89] CreateSpawn2 converted to QueryDatabase --- zone/spawn2.cpp | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index e7e5e9e81..36ca4b3d6 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -413,38 +413,27 @@ Spawn2* ZoneDatabase::LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2 return newSpawn; } -bool ZoneDatabase::CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value) +bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - uint32 affected_rows = 0; - - // if(GetInverseXY()==1) { - // float temp=x; - // x=y; - // y=temp; - // } - if (RunQuery(query, MakeAnyLenString(&query, - "INSERT INTO spawn2 (spawngroupID,zone,x,y,z,heading,respawntime,variance,_condition,cond_value) Values (%i, '%s', %f, %f, %f, %f, %i, %i, %u, %i)", - spawngroup, zone, x, y, z, heading, respawn, variance, condition, cond_value - ), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - if (affected_rows == 1) { - if(c) c->LogSQL(query); - return true; - } - else { - return false; - } - } - else { - LogFile->write(EQEMuLog::Error, "Error in CreateSpawn2 query '%s': %s", query, errbuf); - safe_delete_array(query); + std::string query = StringFormat("INSERT INTO spawn2 (spawngroupID, zone, x, y, z, heading, " + "respawntime, variance, _condition, cond_value) " + "VALUES (%i, '%s', %f, %f, %f, %f, %i, %i, %u, %i)", + spawngroup, zone, x, y, z, heading, + respawn, variance, condition, cond_value); + auto results = QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in CreateSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; - } + } - return false; + if (results.RowsAffected() != 1) + return false; + + if(client) + client->LogSQL(query.c_str()); + + return true; } uint32 Zone::CountSpawn2() { From 3cf4d4af1ba052d8cab8693ed3ad62ad02f8f5ed Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 13:10:15 -0700 Subject: [PATCH 39/89] UpdateDBEvent converted to QueryDatabase --- zone/spawn2.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 36ca4b3d6..f4cbe64a7 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -661,23 +661,20 @@ void SpawnConditionManager::ExecEvent(SpawnEvent &event, bool send_update) { } void SpawnConditionManager::UpdateDBEvent(SpawnEvent &event) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - int len; - SpawnCondition cond; - len = MakeAnyLenString(&query, - "UPDATE spawn_events SET " - "next_minute=%d, next_hour=%d, next_day=%d, next_month=%d, " - "next_year=%d, enabled=%d, strict=%d " - "WHERE id=%d", - event.next.minute, event.next.hour, event.next.day, event.next.month, - event.next.year, event.enabled?1:0, event.strict?1:0,event.id - ); - if(!database.RunQuery(query, len, errbuf)) { - LogFile->write(EQEMuLog::Error, "Unable to update spawn event '%s': %s\n", query, errbuf); - } - safe_delete_array(query); + std::string query = StringFormat("UPDATE spawn_events SET " + "next_minute = %d, next_hour = %d, " + "next_day = %d, next_month = %d, " + "next_year = %d, enabled = %d, " + "strict = %d WHERE id = %d", + event.next.minute, event.next.hour, + event.next.day, event.next.month, + event.next.year, event.enabled? 1: 0, + event.strict? 1: 0, event.id); + auto results = database.QueryDatabase(query); + if(!results.Success()) + LogFile->write(EQEMuLog::Error, "Unable to update spawn event '%s': %s\n", query.c_str(), results.ErrorMessage().c_str()); + } void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 instance_id, uint16 cond_id, int16 value) { From 538921701c42252531987da8ecc12477068a9b79 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 13:13:11 -0700 Subject: [PATCH 40/89] UpdatedDBCondition converted to QueryDatabase --- zone/spawn2.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index f4cbe64a7..7440f07af 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -678,19 +678,15 @@ void SpawnConditionManager::UpdateDBEvent(SpawnEvent &event) { } void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 instance_id, uint16 cond_id, int16 value) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - int len; - SpawnCondition cond; - len = MakeAnyLenString(&query, - "REPLACE INTO spawn_condition_values (id, value, zone, instance_id) VALUES(%u, %u, '%s', %u)", - cond_id, value, zone_name, instance_id - ); - if(!database.RunQuery(query, len, errbuf)) { - LogFile->write(EQEMuLog::Error, "Unable to update spawn condition '%s': %s\n", query, errbuf); - } - safe_delete_array(query); + std::string query = StringFormat("REPLACE INTO spawn_condition_values " + "(id, value, zone, instance_id) " + "VALUES( %u, %u, '%s', %u)", + cond_id, value, zone_name, instance_id); + auto results = database.QueryDatabase(query); + if(!results.Success()) + LogFile->write(EQEMuLog::Error, "Unable to update spawn condition '%s': %s\n", query.c_str(), results.ErrorMessage().c_str()); + } bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std::string &zone_name) { From 7864a5285de41f05315ce06803fe22a47e35a2ec Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 13:18:51 -0700 Subject: [PATCH 41/89] LoadDBEvent converted to QueryDatabase --- zone/spawn2.cpp | 78 +++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 7440f07af..752052f2c 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -690,49 +690,45 @@ void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 inst } bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std::string &zone_name) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - int len; - bool ret = false; - - len = MakeAnyLenString(&query, - "SELECT id,cond_id,period,next_minute,next_hour,next_day,next_month,next_year,enabled,action,argument,strict,zone " - "FROM spawn_events WHERE id=%d", event_id); - if (database.RunQuery(query, len, errbuf, &result)) { - safe_delete_array(query); - if((row = mysql_fetch_row(result))) { - event.id = atoi(row[0]); - event.condition_id = atoi(row[1]); - event.period = atoi(row[2]); - - event.next.minute = atoi(row[3]); - event.next.hour = atoi(row[4]); - event.next.day = atoi(row[5]); - event.next.month = atoi(row[6]); - event.next.year = atoi(row[7]); - - event.enabled = atoi(row[8])==0?false:true; - event.action = (SpawnEvent::Action) atoi(row[9]); - event.argument = atoi(row[10]); - event.strict = atoi(row[11])==0?false:true; - zone_name = row[12]; - - std::string t; - EQTime::ToString(&event.next, t); - _log(SPAWNS__CONDITIONS, "(LoadDBEvent) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d. Will trigger at %s", - event.enabled?"enabled":"disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict, t.c_str()); - - ret = true; - } - mysql_free_result(result); - } else { - LogFile->write(EQEMuLog::Error, "Error in LoadDBEvent query '%s': %s", query, errbuf); - safe_delete_array(query); + std::string query = StringFormat("SELECT id, cond_id, period, " + "next_minute, next_hour, next_day, " + "next_month, next_year, enabled, " + "action, argument, strict, zone " + "FROM spawn_events WHERE id = %d", event_id); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in LoadDBEvent query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); + return false; } - return(ret); + + if (results.RowCount() == 0) + return false; + + auto row = results.begin(); + + event.id = atoi(row[0]); + event.condition_id = atoi(row[1]); + event.period = atoi(row[2]); + + event.next.minute = atoi(row[3]); + event.next.hour = atoi(row[4]); + event.next.day = atoi(row[5]); + event.next.month = atoi(row[6]); + event.next.year = atoi(row[7]); + + event.enabled = atoi(row[8]) != 0; + event.action = (SpawnEvent::Action) atoi(row[9]); + event.argument = atoi(row[10]); + event.strict = atoi(row[11]) != 0; + zone_name = row[12]; + + std::string timeAsString; + EQTime::ToString(&event.next, timeAsString); + + _log(SPAWNS__CONDITIONS, "(LoadDBEvent) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d. Will trigger at %s", event.enabled? "enabled": "disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict, timeAsString.c_str()); + + return true; } bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 instance_id) From 0240c6195252ebd55dbc16cc2dbb063becf6f78c Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 13:31:55 -0700 Subject: [PATCH 42/89] LoadSpawnConditions converted to QueryDatabase --- zone/spawn2.cpp | 210 +++++++++++++++++++++++------------------------- 1 file changed, 99 insertions(+), 111 deletions(-) diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 752052f2c..1e233a36f 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -733,94 +733,87 @@ bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std: bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 instance_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - int len; - //clear out old stuff.. spawn_conditions.clear(); - //load spawn conditions - SpawnCondition cond; - len = MakeAnyLenString(&query, "SELECT id, onchange, value FROM spawn_conditions WHERE zone='%s'", zone_name); - if (database.RunQuery(query, len, errbuf, &result)) { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) { - cond.condition_id = atoi(row[0]); - cond.value = atoi(row[2]); - cond.on_change = (SpawnCondition::OnChange) atoi(row[1]); - spawn_conditions[cond.condition_id] = cond; - _log(SPAWNS__CONDITIONS, "Loaded spawn condition %d with value %d and on_change %d", cond.condition_id, cond.value, cond.on_change); - } - mysql_free_result(result); - } else { - LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query, errbuf); - safe_delete_array(query); + + std::string query = StringFormat("SELECT id, onchange, value " + "FROM spawn_conditions " + "WHERE zone = '%s'", zone_name); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; - } + } + + for (auto row = results.begin(); row != results.end(); ++row) { + //load spawn conditions + SpawnCondition cond; + + cond.condition_id = atoi(row[0]); + cond.value = atoi(row[2]); + cond.on_change = (SpawnCondition::OnChange) atoi(row[1]); + spawn_conditions[cond.condition_id] = cond; + + _log(SPAWNS__CONDITIONS, "Loaded spawn condition %d with value %d and on_change %d", cond.condition_id, cond.value, cond.on_change); + } //load values - len = MakeAnyLenString(&query, "SELECT id, value FROM spawn_condition_values WHERE zone='%s' and instance_id=%u", zone_name, instance_id); - if (database.RunQuery(query, len, errbuf, &result)) { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) - { - std::map::iterator iter = spawn_conditions.find(atoi(row[0])); - if(iter != spawn_conditions.end()) - { - iter->second.value = atoi(row[1]); - } - } - mysql_free_result(result); - } - else - { - LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query, errbuf); - safe_delete_array(query); + query = StringFormat("SELECT id, value FROM spawn_condition_values " + "WHERE zone = '%s' AND instance_id = %u", + zone_name, instance_id); + results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); spawn_conditions.clear(); return false; - } + } + + for (auto row = results.begin(); row != results.end(); ++row) { + auto iter = spawn_conditions.find(atoi(row[0])); + + if(iter != spawn_conditions.end()) + iter->second.value = atoi(row[1]); + } //load spawn events - SpawnEvent event; - len = MakeAnyLenString(&query, - "SELECT id,cond_id,period,next_minute,next_hour,next_day,next_month,next_year,enabled,action,argument,strict " - "FROM spawn_events WHERE zone='%s'", zone_name); - if (database.RunQuery(query, len, errbuf, &result)) { - safe_delete_array(query); - while((row = mysql_fetch_row(result))) { - event.id = atoi(row[0]); - event.condition_id = atoi(row[1]); - event.period = atoi(row[2]); - if(event.period == 0) { - LogFile->write(EQEMuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id); - continue; - } - - event.next.minute = atoi(row[3]); - event.next.hour = atoi(row[4]); - event.next.day = atoi(row[5]); - event.next.month = atoi(row[6]); - event.next.year = atoi(row[7]); - - event.enabled = atoi(row[8])==0?false:true; - event.action = (SpawnEvent::Action) atoi(row[9]); - event.argument = atoi(row[10]); - event.strict = atoi(row[11])==0?false:true; - spawn_events.push_back(event); - - _log(SPAWNS__CONDITIONS, "(LoadSpawnConditions) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d", - event.enabled?"enabled":"disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict); - } - mysql_free_result(result); - } else { - LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query, errbuf); - safe_delete_array(query); + query = StringFormat("SELECT id, cond_id, period, next_minute, next_hour, " + "next_day, next_month, next_year, enabled, action, argument, strict " + "FROM spawn_events WHERE zone = '%s'", zone_name); + results = database.QueryDatabase(query); + if (!results.Success()) { + LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return false; - } + } + + for (auto row = results.begin(); row != results.end(); ++row) { + SpawnEvent event; + + event.id = atoi(row[0]); + event.condition_id = atoi(row[1]); + event.period = atoi(row[2]); + + if(event.period == 0) { + LogFile->write(EQEMuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id); + continue; + } + + event.next.minute = atoi(row[3]); + event.next.hour = atoi(row[4]); + event.next.day = atoi(row[5]); + event.next.month = atoi(row[6]); + event.next.year = atoi(row[7]); + + event.enabled = atoi(row[8])==0?false:true; + event.action = (SpawnEvent::Action) atoi(row[9]); + event.argument = atoi(row[10]); + event.strict = atoi(row[11])==0?false:true; + + spawn_events.push_back(event); + + _log(SPAWNS__CONDITIONS, "(LoadSpawnConditions) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d", event.enabled? "enabled": "disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict); + } //now we need to catch up on events that happened while we were away //and use them to alter just the condition variables. @@ -834,11 +827,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in TimeOfDay_Struct tod; zone->zone_time.getEQTimeOfDay(&tod); - std::vector::iterator cur,end; - cur = spawn_events.begin(); - end = spawn_events.end(); - bool ran; - for(; cur != end; ++cur) { + for(auto cur = spawn_events.begin(); cur != spawn_events.end(); ++cur) { SpawnEvent &cevent = *cur; bool StrictCheck = false; @@ -853,43 +842,42 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in if(!cevent.enabled || !StrictCheck) SetCondition(zone->GetShortName(), zone->GetInstanceID(),cevent.condition_id,0); - if(cevent.enabled) - { - //watch for special case of all 0s, which means to reset next to now - if(cevent.next.year == 0 && cevent.next.month == 0 && cevent.next.day == 0 && cevent.next.hour == 0 && cevent.next.minute == 0) { - _log(SPAWNS__CONDITIONS, "Initial next trigger time set for spawn event %d", cevent.id); - memcpy(&cevent.next, &tod, sizeof(cevent.next)); - //add one period - EQTime::AddMinutes(cevent.period, &cevent.next); - //save it in the db. - UpdateDBEvent(cevent); - continue; //were done with this event. - } + if(!cevent.enabled) + continue; - ran = false; - while(EQTime::IsTimeBefore(&tod, &cevent.next)) { - _log(SPAWNS__CONDITIONS, "Catch up triggering on event %d", cevent.id); - //this event has been triggered. - //execute the event - if(!cevent.strict || StrictCheck) - ExecEvent(cevent, false); + //watch for special case of all 0s, which means to reset next to now + if(cevent.next.year == 0 && cevent.next.month == 0 && cevent.next.day == 0 && cevent.next.hour == 0 && cevent.next.minute == 0) { + _log(SPAWNS__CONDITIONS, "Initial next trigger time set for spawn event %d", cevent.id); + memcpy(&cevent.next, &tod, sizeof(cevent.next)); + //add one period + EQTime::AddMinutes(cevent.period, &cevent.next); + //save it in the db. + UpdateDBEvent(cevent); + continue; //were done with this event. + } - //add the period of the event to the trigger time - EQTime::AddMinutes(cevent.period, &cevent.next); - ran = true; - } - //only write it out if the event actually ran - if(ran) { - //save the event in the DB - UpdateDBEvent(cevent); - } - } + bool ran = false; + while(EQTime::IsTimeBefore(&tod, &cevent.next)) { + _log(SPAWNS__CONDITIONS, "Catch up triggering on event %d", cevent.id); + //this event has been triggered. + //execute the event + if(!cevent.strict || StrictCheck) + ExecEvent(cevent, false); + + //add the period of the event to the trigger time + EQTime::AddMinutes(cevent.period, &cevent.next); + ran = true; + } + + //only write it out if the event actually ran + if(ran) + UpdateDBEvent(cevent); //save the event in the DB } //now our event timers are all up to date, find our closest event. FindNearestEvent(); - return(true); + return true; } void SpawnConditionManager::FindNearestEvent() { From b6875564d41c5c7bce10cab252a69b244bad663a Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 13:47:18 -0700 Subject: [PATCH 43/89] GetCondition converted to QueryDatabase --- zone/spawn2.cpp | 51 ++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 1e233a36f..25cbb8ccf 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -1129,37 +1129,28 @@ int16 SpawnConditionManager::GetCondition(const char *zone_short, uint32 instanc } SpawnCondition &cond = condi->second; - return(cond.value); - } else { - //this is a remote spawn condition, grab it from the DB - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - int len; - - int16 value; - - //load spawn conditions - SpawnCondition cond; - len = MakeAnyLenString(&query, "SELECT value FROM spawn_condition_values WHERE zone='%s' AND instance_id=%u AND id=%d", - zone_short, instance_id, condition_id); - if (database.RunQuery(query, len, errbuf, &result)) { - safe_delete_array(query); - if((row = mysql_fetch_row(result))) { - value = atoi(row[0]); - } else { - _log(SPAWNS__CONDITIONS, "Unable to load remote condition %d from zone %s in Get request.", condition_id, zone_short); - value = 0; //dunno a better thing to do... - } - mysql_free_result(result); - } else { - _log(SPAWNS__CONDITIONS, "Unable to query remote condition %d from zone %s in Get request.", condition_id, zone_short); - safe_delete_array(query); - value = 0; //dunno a better thing to do... - } - return(value); + return cond.value; } + + //this is a remote spawn condition, grab it from the DB + //load spawn conditions + std::string query = StringFormat("SELECT value FROM spawn_condition_values " + "WHERE zone = '%s' AND instance_id = %u AND id = %d", + zone_short, instance_id, condition_id); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + _log(SPAWNS__CONDITIONS, "Unable to query remote condition %d from zone %s in Get request.", condition_id, zone_short); + return 0; //dunno a better thing to do... + } + + if (results.RowCount() == 0) { + _log(SPAWNS__CONDITIONS, "Unable to load remote condition %d from zone %s in Get request.", condition_id, zone_short); + return 0; //dunno a better thing to do... + } + + auto row = results.begin(); + + return atoi(row[0]); } bool SpawnConditionManager::Check(uint16 condition, int16 min_value) { From c851cd3f120d070996d3d73b238965cf5803a01b Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 14:06:52 -0700 Subject: [PATCH 44/89] Handle_OP_ItemLinkClick converted to QueryDatabase --- zone/client_packet.cpp | 55 +++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f35ec0565..5ec2e9e9e 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -3137,6 +3137,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) DumpPacket(app); return; } + DumpPacket(app); ItemViewRequest_Struct* ivrs = (ItemViewRequest_Struct*)app->pBuffer; @@ -3156,30 +3157,24 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) silentsaylink = true; } - if (sayid && sayid > 0) + if (sayid > 0) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; + std::string query = StringFormat("SELECT `phrase` FROM saylink WHERE `id` = '%i'", sayid); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); + return; + } - if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `phrase` FROM saylink WHERE `id` = '%i'", sayid),errbuf,&result)) - { - if (mysql_num_rows(result) == 1) - { - row = mysql_fetch_row(result); - response = row[0]; - } - mysql_free_result(result); - } - else - { - Message(13, "Error: The saylink (%s) was not found in the database.",response.c_str()); - safe_delete_array(query); + if (results.RowCount() != 1) { + Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); return; } - safe_delete_array(query); + + auto row = results.begin(); + response = row[0]; + } if((response).size() > 0) @@ -4628,7 +4623,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) p_timers.Start(pTimerHarmTouch, HarmTouchReuseTime); } - + if (spell_to_cast > 0) // if we've matched LoH or HT, cast now CastSpell(spell_to_cast, castspell->target_id, castspell->slot); } @@ -5864,9 +5859,9 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) else this->DeleteItemInInventory(mp->itemslot,mp->quantity,false); - //This forces the price to show up correctly for charged items. + //This forces the price to show up correctly for charged items. if(inst->IsCharged()) - mp->quantity = 1; + mp->quantity = 1; EQApplicationPacket* outapp = new EQApplicationPacket(OP_ShopPlayerSell, sizeof(Merchant_Purchase_Struct)); Merchant_Purchase_Struct* mco=(Merchant_Purchase_Struct*)outapp->pBuffer; @@ -7635,7 +7630,7 @@ void Client::Handle_OP_Mend(const EQApplicationPacket *app) int mendhp = GetMaxHP() / 4; int currenthp = GetHP(); if (MakeRandomInt(0, 199) < (int)GetSkill(SkillMend)) { - + int criticalchance = spellbonuses.CriticalMend + itembonuses.CriticalMend + aabonuses.CriticalMend; if(MakeRandomInt(0,99) < criticalchance){ @@ -9532,7 +9527,7 @@ void Client::CompleteConnect() { /* This sub event is for if a player logs in for the first time since entering world. */ if (firstlogon == 1){ - parse->EventPlayer(EVENT_CONNECT, this, "", 0); + parse->EventPlayer(EVENT_CONNECT, this, "", 0); /* QS: PlayerLogConnectDisconnect */ if (RuleB(QueryServ, PlayerLogConnectDisconnect)){ std::string event_desc = StringFormat("Connect :: Logged into zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID()); @@ -12775,7 +12770,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) { QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc); } } - } + } /* Cursor to Item storage */ else { uint32 max_currency = GetAlternateCurrencyValue(reclaim->currency_id); @@ -12784,7 +12779,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) { if(reclaim->count > max_currency) { SummonItem(item_id, max_currency); SetAlternateCurrencyValue(reclaim->currency_id, 0); - } + } else { SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, false, MainCursor); AddAlternateCurrencyValue(reclaim->currency_id, -((int32)reclaim->count)); @@ -12793,7 +12788,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) { if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){ std::string event_desc = StringFormat("Reclaim :: Cursor to Item :: alt_currency_id:%i amount:-%i in zoneid:%i instid:%i", reclaim->currency_id, reclaim->count, this->GetZoneID(), this->GetInstanceID()); QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc); - } + } } } @@ -12885,8 +12880,8 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app) { /* QS: PlayerLogAlternateCurrencyTransactions :: Sold to Merchant*/ if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){ std::string event_desc = StringFormat("Sold to Merchant :: itemid:%u npcid:%u alt_currency_id:%u cost:%u in zoneid:%u instid:%i", item->ID, npc_id, alt_cur_id, cost, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc); - } + QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc); + } FastQueuePacket(&outapp); AddAlternateCurrencyValue(alt_cur_id, cost); @@ -12947,7 +12942,7 @@ void Client::Handle_OP_LFGuild(const EQApplicationPacket *app) switch(Command) { case 0: - { + { VERIFY_PACKET_LENGTH(OP_LFGuild, app, LFGuild_PlayerToggle_Struct); LFGuild_PlayerToggle_Struct *pts = (LFGuild_PlayerToggle_Struct *)app->pBuffer; From 4d0179d525633175548a71b9b0182fd16c6e8588 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 14:13:06 -0700 Subject: [PATCH 45/89] Handle_OP_SetStartCity converted to QueryDatabase --- zone/client_packet.cpp | 102 ++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 63 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 5ec2e9e9e..3ab2338c7 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -11405,92 +11405,68 @@ void Client::Handle_OP_SetStartCity(const EQApplicationPacket *app) Message(15,"Your home city has already been set.", m_pp.binds[4].zoneId, database.GetZoneName(m_pp.binds[4].zoneId)); return; } + if (app->size < 1) { LogFile->write(EQEMuLog::Error, "Wrong size: OP_SetStartCity, size=%i, expected %i", app->size, 1); DumpPacket(app); return; } - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result = nullptr; - MYSQL_ROW row = 0; float x(0),y(0),z(0); uint32 zoneid = 0; + uint32 startCity = (uint32)strtol((const char*)app->pBuffer, nullptr, 10); - uint32 StartCity = (uint32)strtol((const char*)app->pBuffer, nullptr, 10); - bool ValidCity = false; - database.RunQuery - ( - query, - MakeAnyLenString - ( - &query, - "SELECT zone_id, bind_id, x, y, z FROM start_zones " - "WHERE player_class=%i AND player_deity=%i AND player_race=%i", - m_pp.class_, - m_pp.deity, - m_pp.race - ), - errbuf, - &result - ); - safe_delete_array(query); - - if(!result) { + std::string query = StringFormat("SELECT zone_id, bind_id, x, y, z FROM start_zones " + "WHERE player_class=%i AND player_deity=%i AND player_race=%i", + m_pp.class_, m_pp.deity, m_pp.race); + auto results = database.QueryDatabase(query); + if(!results.Success()) { LogFile->write(EQEMuLog::Error, "No valid start zones found for /setstartcity"); return; } - while(row = mysql_fetch_row(result)) { + bool validCity = false; + for (auto row = results.begin(); row != results.end(); ++row) { if(atoi(row[1]) != 0) zoneid = atoi(row[1]); else zoneid = atoi(row[0]); - if(zoneid == StartCity) { - ValidCity = true; - x = atof(row[2]); - y = atof(row[3]); - z = atof(row[4]); - } + if(zoneid != startCity) + continue; + + validCity = true; + x = atof(row[2]); + y = atof(row[3]); + z = atof(row[4]); } - if(ValidCity) { + if(validCity) { Message(15,"Your home city has been set"); - SetStartZone(StartCity, x, y, z); - } - else { - database.RunQuery - ( - query, - MakeAnyLenString - ( - &query, - "SELECT zone_id, bind_id FROM start_zones " - "WHERE player_class=%i AND player_deity=%i AND player_race=%i", - m_pp.class_, - m_pp.deity, - m_pp.race - ), - errbuf, - &result - ); - safe_delete_array(query); - Message(15,"Use \"/startcity #\" to choose a home city from the following list:"); - char* name; - while(row = mysql_fetch_row(result)) { - if(atoi(row[1]) != 0) - zoneid = atoi(row[1]); - else - zoneid = atoi(row[0]); - database.GetZoneLongName(database.GetZoneName(zoneid),&name); - Message(15,"%d - %s", zoneid, name); - safe_delete_array(name); - } + SetStartZone(startCity, x, y, z); + return; } - mysql_free_result(result); + query = StringFormat("SELECT zone_id, bind_id FROM start_zones " + "WHERE player_class=%i AND player_deity=%i AND player_race=%i", + m_pp.class_, m_pp.deity, m_pp.race); + results = database.QueryDatabase(query); + if (!results.Success()) + return; + + Message(15,"Use \"/startcity #\" to choose a home city from the following list:"); + + for (auto row = results.begin(); row != results.end(); ++row) { + if(atoi(row[1]) != 0) + zoneid = atoi(row[1]); + else + zoneid = atoi(row[0]); + + char* name; + database.GetZoneLongName(database.GetZoneName(zoneid), &name); + Message(15,"%d - %s", zoneid, name); + } + } void Client::Handle_OP_Report(const EQApplicationPacket *app) From f948786f6a22b16abc76bc13ceb3874fc7d557ac Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 14:21:33 -0700 Subject: [PATCH 46/89] Handle_OP_GMSearchCorpse converted to QueryDatabase --- zone/client_packet.cpp | 101 ++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 62 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 3ab2338c7..7cc3ebe85 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -11573,7 +11573,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) // Could make this into a rule, although there is a hard limit since we are using a popup, of 4096 bytes that can // be displayed in the window, including all the HTML formatting tags. // - const int MaxResults = 10; + const int maxResults = 10; if(app->size < sizeof(GMSearchCorpse_Struct)) { @@ -11586,85 +11586,62 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) GMSearchCorpse_Struct *gmscs = (GMSearchCorpse_Struct *)app->pBuffer; gmscs->Name[63] = '\0'; - char errbuf[MYSQL_ERRMSG_SIZE]; - char* Query = 0; - MYSQL_RES *Result; - MYSQL_ROW Row; + char *escSearchString = new char[129]; + database.DoEscapeString(escSearchString, gmscs->Name, strlen(gmscs->Name)); - char *EscSearchString = new char[129]; + std::string query = StringFormat("SELECT charname, zoneid, x, y, z, timeofdeath, rezzed, IsBurried " + "FROM player_corpses WheRE charname LIKE '%%%s%%' ORDER BY charname LIMIT %i", + escSearchString, maxResults); + safe_delete_array(escSearchString); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + Message(0, "Query failed: %s.", results.ErrorMessage().c_str()); + return; + } - database.DoEscapeString(EscSearchString, gmscs->Name, strlen(gmscs->Name)); + if (results.RowCount() == 0) + return; - if (database.RunQuery(Query, MakeAnyLenString(&Query, "select charname, zoneid, x, y, z, timeofdeath, rezzed, IsBurried from " - "player_corpses where charname like '%%%s%%' order by charname limit %i", - EscSearchString, MaxResults), errbuf, &Result)) - { + if(results.RowCount() == maxResults) + Message(clientMessageError, "Your search found too many results; some are not displayed."); + else + Message(clientMessageYellow, "There are %i corpse(s) that match the search string '%s'.", results.RowCount(), gmscs->Name); - int NumberOfRows = mysql_num_rows(Result); + char charName[64], timeOfDeath[20]; - if(NumberOfRows == MaxResults) - Message(clientMessageError, "Your search found too many results; some are not displayed."); - else { - Message(clientMessageYellow, "There are %i corpse(s) that match the search string '%s'.", - NumberOfRows, gmscs->Name); - } - - if(NumberOfRows == 0) - { - mysql_free_result(Result); - safe_delete_array(Query); - return; - } - - char CharName[64], TimeOfDeath[20], Buffer[512]; - - std::string PopupText = "
NameZoneXYZDate" + std::string popupText = ""; + for (auto row = results.begin(); row != results.end(); ++row) { - while ((Row = mysql_fetch_row(Result))) - { + strn0cpy(charName, row[0], sizeof(charName)); - strn0cpy(CharName, Row[0], sizeof(CharName)); + uint32 ZoneID = atoi(row[1]); + float CorpseX = atof(row[2]); + float CorpseY = atof(row[3]); + float CorpseZ = atof(row[4]); - uint32 ZoneID = atoi(Row[1]); + strn0cpy(timeOfDeath, row[5], sizeof(timeOfDeath)); - float CorpseX = atof(Row[2]); - float CorpseY = atof(Row[3]); - float CorpseZ = atof(Row[4]); + bool corpseRezzed = atoi(row[6]); + bool corpseBuried = atoi(row[7]); - strn0cpy(TimeOfDeath, Row[5], sizeof(TimeOfDeath)); + popupText += StringFormat("", + charName, StaticGetZoneName(ZoneID), CorpseX, CorpseY, CorpseZ, timeOfDeath, + corpseRezzed ? "Yes" : "No", corpseBuried ? "Yes" : "No"); - bool CorpseRezzed = atoi(Row[6]); - bool CorpseBuried = atoi(Row[7]); + if(popupText.size() > 4000) { + Message(clientMessageError, "Unable to display all the results."); + break; + } - sprintf(Buffer, "", - CharName, StaticGetZoneName(ZoneID), CorpseX, CorpseY, CorpseZ, TimeOfDeath, - CorpseRezzed ? "Yes" : "No", CorpseBuried ? "Yes" : "No"); + } - PopupText += Buffer; + popupText += "
NameZoneXYZDate" "RezzedBuried
 " "
%s%s%8.0f%8.0f%8.0f%s%s%s
%s%s%8.0f%8.0f%8.0f%s%s%s
"; - if(PopupText.size() > 4000) - { - Message(clientMessageError, "Unable to display all the results."); - break; - } + SendPopupToClient("Corpses", popupText.c_str()); - } - - PopupText += "
"; - - mysql_free_result(Result); - - SendPopupToClient("Corpses", PopupText.c_str()); - } - else{ - Message(0, "Query failed: %s.", errbuf); - - } - safe_delete_array(Query); - safe_delete_array(EscSearchString); } void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) From 50e6d0d256a62ca06d52142bf50eb3f4f6dc9087 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Sun, 24 Aug 2014 16:02:21 -0700 Subject: [PATCH 47/89] Load converted to QueryDatabase --- zone/guild_mgr.cpp | 146 +++++++++++++++++---------------------------- 1 file changed, 54 insertions(+), 92 deletions(-) diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 087878ffc..876feb4bd 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -644,104 +644,66 @@ GuildBankManager::~GuildBankManager() } } -bool GuildBankManager::Load(uint32 GuildID) +bool GuildBankManager::Load(uint32 guildID) { - const char *LoadQuery = "SELECT `area`, `slot`, `itemid`, `qty`, `donator`, `permissions`, `whofor` from `guild_bank` " - "WHERE `guildid` = %i"; - - char errbuf[MYSQL_ERRMSG_SIZE]; - - char* query = 0; - - MYSQL_RES *result; - - MYSQL_ROW row; - - if(database.RunQuery(query, MakeAnyLenString(&query, LoadQuery, GuildID), errbuf, &result)) - { - GuildBank *Bank = new GuildBank; - - Bank->GuildID = GuildID; - - for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i) - Bank->Items.MainArea[i].ItemID = 0; - - for(int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i) - Bank->Items.DepositArea[i].ItemID = 0; - - char Donator[64], WhoFor[64]; - - while((row = mysql_fetch_row(result))) - { - int Area = atoi(row[0]); - - int Slot = atoi(row[1]); - - int ItemID = atoi(row[2]); - - int Qty = atoi(row[3]); - - if(row[4]) - strn0cpy(Donator, row[4], sizeof(Donator)); - else - Donator[0] = '\0'; - - int Permissions = atoi(row[5]); - - if(row[6]) - strn0cpy(WhoFor, row[6], sizeof(WhoFor)); - else - WhoFor[0] = '\0'; - - if(Area == GuildBankMainArea) - { - if((Slot >= 0) && (Slot < GUILD_BANK_MAIN_AREA_SIZE)) - { - Bank->Items.MainArea[Slot].ItemID = ItemID; - - Bank->Items.MainArea[Slot].Quantity = Qty; - - strn0cpy(Bank->Items.MainArea[Slot].Donator, Donator, sizeof(Donator)); - - Bank->Items.MainArea[Slot].Permissions = Permissions; - - strn0cpy(Bank->Items.MainArea[Slot].WhoFor, WhoFor, sizeof(WhoFor)); - } - } - else - { - if((Slot >= 0 ) && (Slot < GUILD_BANK_DEPOSIT_AREA_SIZE)) - { - Bank->Items.DepositArea[Slot].ItemID = ItemID; - - Bank->Items.DepositArea[Slot].Quantity = Qty; - - strn0cpy(Bank->Items.DepositArea[Slot].Donator, Donator, sizeof(Donator)); - - Bank->Items.DepositArea[Slot].Permissions = Permissions; - - strn0cpy(Bank->Items.DepositArea[Slot].WhoFor, WhoFor, sizeof(WhoFor)); - } - } - - } - mysql_free_result(result); - - safe_delete_array(query); - - Banks.push_back(Bank); - } - else - { - _log(GUILDS__BANK_ERROR, "Error Loading guild bank: %s, %s", query, errbuf); - - safe_delete_array(query); + std::string query = StringFormat("SELECT `area`, `slot`, `itemid`, `qty`, `donator`, `permissions`, `whofor` " + "FROM `guild_bank` WHERE `guildid` = %i", guildID); + auto results = database.QueryDatabase(query); + if(!results.Success()) { + _log(GUILDS__BANK_ERROR, "Error Loading guild bank: %s, %s", query.c_str(), results.ErrorMessage().c_str()); return false; } - return true; + GuildBank *bank = new GuildBank; + bank->GuildID = guildID; + + for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i) + bank->Items.MainArea[i].ItemID = 0; + + for(int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i) + bank->Items.DepositArea[i].ItemID = 0; + + char donator[64], whoFor[64]; + + for (auto row = results.begin(); row != results.end(); ++row) + { + int area = atoi(row[0]); + int slot = atoi(row[1]); + int itemID = atoi(row[2]); + int qty = atoi(row[3]); + + if(row[4]) + strn0cpy(donator, row[4], sizeof(donator)); + else + donator[0] = '\0'; + + int permissions = atoi(row[5]); + + if(row[6]) + strn0cpy(whoFor, row[6], sizeof(whoFor)); + else + whoFor[0] = '\0'; + + if(slot < 0 || + ((area != GuildBankMainArea || slot >= GUILD_BANK_MAIN_AREA_SIZE) || + (area == GuildBankMainArea || slot >= GUILD_BANK_DEPOSIT_AREA_SIZE))) + continue; + + bank->Items.MainArea[slot].ItemID = itemID; + bank->Items.MainArea[slot].Quantity = qty; + + strn0cpy(bank->Items.MainArea[slot].Donator, donator, sizeof(donator)); + + bank->Items.MainArea[slot].Permissions = permissions; + + strn0cpy(bank->Items.MainArea[slot].WhoFor, whoFor, sizeof(whoFor)); + } + + Banks.push_back(bank); + + return true; } bool GuildBankManager::IsLoaded(uint32 GuildID) From 00852063c2990fce2dcef0d01e203ec3b301ebb0 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Mon, 25 Aug 2014 12:15:06 -0700 Subject: [PATCH 48/89] Promote converted to QueryDatabase --- zone/guild_mgr.cpp | 81 ++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 49 deletions(-) diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 876feb4bd..316ec6409 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -935,90 +935,73 @@ bool GuildBankManager::AddItem(uint32 GuildID, uint8 Area, uint32 ItemID, int32 return true; } -int GuildBankManager::Promote(uint32 GuildID, int SlotID) +int GuildBankManager::Promote(uint32 guildID, int slotID) { - if((SlotID < 0) || (SlotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1))) + if((slotID < 0) || (slotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1))) return -1; - std::list::iterator Iterator = GetGuildBank(GuildID); + auto iter = GetGuildBank(guildID); - if(Iterator == Banks.end()) - { + if(iter == Banks.end()) return -1; - } - if((*Iterator)->Items.DepositArea[SlotID].ItemID == 0) - { + if((*iter)->Items.DepositArea[slotID].ItemID == 0) return -1; - } - int MainSlot = -1; + int mainSlot = -1; for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i) - if((*Iterator)->Items.MainArea[i].ItemID == 0) - { - MainSlot = i; - + if((*iter)->Items.MainArea[i].ItemID == 0) { + mainSlot = i; break; } - if(MainSlot == -1) + if(mainSlot == -1) return -1; + (*iter)->Items.MainArea[mainSlot].ItemID = (*iter)->Items.DepositArea[slotID].ItemID; + (*iter)->Items.MainArea[mainSlot].Quantity = (*iter)->Items.DepositArea[slotID].Quantity; + (*iter)->Items.MainArea[mainSlot].Permissions = (*iter)->Items.DepositArea[slotID].Permissions; - (*Iterator)->Items.MainArea[MainSlot].ItemID = (*Iterator)->Items.DepositArea[SlotID].ItemID; - - (*Iterator)->Items.MainArea[MainSlot].Quantity = (*Iterator)->Items.DepositArea[SlotID].Quantity; - - strn0cpy((*Iterator)->Items.MainArea[MainSlot].Donator, (*Iterator)->Items.DepositArea[SlotID].Donator, sizeof((*Iterator)->Items.MainArea[MainSlot].Donator)); - (*Iterator)->Items.MainArea[MainSlot].Permissions = (*Iterator)->Items.DepositArea[SlotID].Permissions; - - strn0cpy((*Iterator)->Items.MainArea[MainSlot].WhoFor, (*Iterator)->Items.DepositArea[SlotID].WhoFor, sizeof((*Iterator)->Items.MainArea[MainSlot].WhoFor)); - - const char *Query="UPDATE `guild_bank` SET `area` = 1, `slot` = %i WHERE `guildid` = %i AND `area` = 0 AND `slot` = %i LIMIT 1"; - - char errbuf[MYSQL_ERRMSG_SIZE]; - - char* query = 0; - - if(!database.RunQuery(query, MakeAnyLenString(&query, Query, MainSlot, GuildID, SlotID), errbuf)) - { - _log(GUILDS__BANK_ERROR, "error promoting item: %s : %s", query, errbuf); - - safe_delete_array(query); + strn0cpy((*iter)->Items.MainArea[mainSlot].Donator, (*iter)->Items.DepositArea[slotID].Donator, sizeof((*iter)->Items.MainArea[mainSlot].Donator)); + strn0cpy((*iter)->Items.MainArea[mainSlot].WhoFor, (*iter)->Items.DepositArea[slotID].WhoFor, sizeof((*iter)->Items.MainArea[mainSlot].WhoFor)); + std::string query = StringFormat("UPDATE `guild_bank` SET `area` = 1, `slot` = %i " + "WHERE `guildid` = %i AND `area` = 0 AND `slot` = %i " + "LIMIT 1", mainSlot, guildID, slotID); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + _log(GUILDS__BANK_ERROR, "error promoting item: %s : %s", query.c_str(), results.ErrorMessage().c_str()); return -1; } - safe_delete_array(query); + (*iter)->Items.DepositArea[slotID].ItemID = 0; - (*Iterator)->Items.DepositArea[SlotID].ItemID = 0; - - const Item_Struct *Item = database.GetItem((*Iterator)->Items.MainArea[MainSlot].ItemID); + const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[mainSlot].ItemID); GuildBankItemUpdate_Struct gbius; if(!Item->Stackable) - gbius.Init(GuildBankItemUpdate, 1, MainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon, 1, 0, 0, 0); + gbius.Init(GuildBankItemUpdate, 1, mainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon, 1, 0, 0, 0); else { - if((*Iterator)->Items.MainArea[MainSlot].Quantity == Item->StackSize) - gbius.Init(GuildBankItemUpdate, 1, MainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon, - (*Iterator)->Items.MainArea[MainSlot].Quantity, 0, 0, 0); + if((*iter)->Items.MainArea[mainSlot].Quantity == Item->StackSize) + gbius.Init(GuildBankItemUpdate, 1, mainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon, + (*iter)->Items.MainArea[mainSlot].Quantity, 0, 0, 0); else - gbius.Init(GuildBankItemUpdate, 1, MainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon, - (*Iterator)->Items.MainArea[MainSlot].Quantity, 0, 1, 0); + gbius.Init(GuildBankItemUpdate, 1, mainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon, + (*iter)->Items.MainArea[mainSlot].Quantity, 0, 1, 0); } strn0cpy(gbius.ItemName, Item->Name, sizeof(gbius.ItemName)); - entity_list.QueueClientsGuildBankItemUpdate(&gbius, GuildID); + entity_list.QueueClientsGuildBankItemUpdate(&gbius, guildID); - gbius.Init(GuildBankItemUpdate, 1, SlotID, GuildBankDepositArea, 0, 0, 0, 0, 0, 0, 0); + gbius.Init(GuildBankItemUpdate, 1, slotID, GuildBankDepositArea, 0, 0, 0, 0, 0, 0, 0); - entity_list.QueueClientsGuildBankItemUpdate(&gbius, GuildID); + entity_list.QueueClientsGuildBankItemUpdate(&gbius, guildID); - return MainSlot; + return mainSlot; } void GuildBankManager::SetPermissions(uint32 GuildID, uint16 SlotID, uint32 Permissions, const char *MemberName) From c3fdbfe90469f4f46aef164c279fa1387675191d Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Mon, 25 Aug 2014 12:33:09 -0700 Subject: [PATCH 49/89] SetPermissions converted to QueryDatabase --- zone/guild_mgr.cpp | 68 +++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 316ec6409..3f477df6f 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -1004,70 +1004,58 @@ int GuildBankManager::Promote(uint32 guildID, int slotID) return mainSlot; } -void GuildBankManager::SetPermissions(uint32 GuildID, uint16 SlotID, uint32 Permissions, const char *MemberName) +void GuildBankManager::SetPermissions(uint32 guildID, uint16 slotID, uint32 permissions, const char *memberName) { - if((SlotID > (GUILD_BANK_MAIN_AREA_SIZE - 1))) + if((slotID > (GUILD_BANK_MAIN_AREA_SIZE - 1))) return; - std::list::iterator Iterator = GetGuildBank(GuildID); + auto iter = GetGuildBank(guildID); - if(Iterator == Banks.end()) + if(iter == Banks.end()) + return; + + if((*iter)->Items.MainArea[slotID].ItemID == 0) + return; + + std::string query = StringFormat("UPDATE `guild_bank` SET `permissions` = %i, `whofor` = '%s' " + "WHERE `guildid` = %i AND `area` = 1 AND `slot` = %i LIMIT 1", + permissions, memberName, guildID, slotID); + auto results = database.QueryDatabase(query); + if(!results.Success()) { + _log(GUILDS__BANK_ERROR, "error changing permissions: %s : %s", query.c_str(), results.ErrorMessage().c_str()); return; } - if((*Iterator)->Items.MainArea[SlotID].ItemID == 0) - { - return; - } + (*iter)->Items.MainArea[slotID].Permissions = permissions; - const char *Query="UPDATE `guild_bank` SET `permissions` = %i, `whofor` = '%s' WHERE `guildid` = %i AND `area` = 1 AND `slot` = %i LIMIT 1"; - - char errbuf[MYSQL_ERRMSG_SIZE]; - - char* query = 0; - - if(!database.RunQuery(query, MakeAnyLenString(&query, Query, Permissions, MemberName, GuildID, SlotID), errbuf)) - { - _log(GUILDS__BANK_ERROR, "error changing permissions: %s : %s", query, errbuf); - - safe_delete_array(query); - - return; - } - - safe_delete_array(query); - - (*Iterator)->Items.MainArea[SlotID].Permissions = Permissions; - - if(Permissions == GuildBankSingleMember) - strn0cpy((*Iterator)->Items.MainArea[SlotID].WhoFor, MemberName, sizeof((*Iterator)->Items.MainArea[SlotID].WhoFor)); + if(permissions == GuildBankSingleMember) + strn0cpy((*iter)->Items.MainArea[slotID].WhoFor, memberName, sizeof((*iter)->Items.MainArea[slotID].WhoFor)); else - (*Iterator)->Items.MainArea[SlotID].WhoFor[0] = '\0'; + (*iter)->Items.MainArea[slotID].WhoFor[0] = '\0'; - - const Item_Struct *Item = database.GetItem((*Iterator)->Items.MainArea[SlotID].ItemID); + const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[slotID].ItemID); GuildBankItemUpdate_Struct gbius; if(!Item->Stackable) - gbius.Init(GuildBankItemUpdate, 1, SlotID, GuildBankMainArea, 1, Item->ID, Item->Icon, 1, (*Iterator)->Items.MainArea[SlotID].Permissions, 0, 0); + gbius.Init(GuildBankItemUpdate, 1, slotID, GuildBankMainArea, 1, Item->ID, Item->Icon, 1, (*iter)->Items.MainArea[slotID].Permissions, 0, 0); else { - if((*Iterator)->Items.MainArea[SlotID].Quantity == Item->StackSize) - gbius.Init(GuildBankItemUpdate, 1, SlotID, GuildBankMainArea, 1, Item->ID, Item->Icon, - (*Iterator)->Items.MainArea[SlotID].Quantity, (*Iterator)->Items.MainArea[SlotID].Permissions, 0, 0); + if((*iter)->Items.MainArea[slotID].Quantity == Item->StackSize) + gbius.Init(GuildBankItemUpdate, 1, slotID, GuildBankMainArea, 1, Item->ID, Item->Icon, + (*iter)->Items.MainArea[slotID].Quantity, (*iter)->Items.MainArea[slotID].Permissions, 0, 0); else - gbius.Init(GuildBankItemUpdate, 1, SlotID, GuildBankMainArea, 1, Item->ID, Item->Icon, - (*Iterator)->Items.MainArea[SlotID].Quantity, (*Iterator)->Items.MainArea[SlotID].Permissions, 1, 0); + gbius.Init(GuildBankItemUpdate, 1, slotID, GuildBankMainArea, 1, Item->ID, Item->Icon, + (*iter)->Items.MainArea[slotID].Quantity, (*iter)->Items.MainArea[slotID].Permissions, 1, 0); } strn0cpy(gbius.ItemName, Item->Name, sizeof(gbius.ItemName)); - strn0cpy(gbius.WhoFor, (*Iterator)->Items.MainArea[SlotID].WhoFor, sizeof(gbius.WhoFor)); + strn0cpy(gbius.WhoFor, (*iter)->Items.MainArea[slotID].WhoFor, sizeof(gbius.WhoFor)); - entity_list.QueueClientsGuildBankItemUpdate(&gbius, GuildID); + entity_list.QueueClientsGuildBankItemUpdate(&gbius, guildID); } ItemInst* GuildBankManager::GetItem(uint32 GuildID, uint16 Area, uint16 SlotID, uint32 Quantity) From 1e870864716ff9b7da32323cc94c7941cd944e60 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Mon, 25 Aug 2014 12:43:14 -0700 Subject: [PATCH 50/89] DeleteItem converted to QueryDatabase --- zone/guild_mgr.cpp | 85 +++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 51 deletions(-) diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 3f477df6f..e1fbf0db5 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -1141,90 +1141,73 @@ std::list::iterator GuildBankManager::GetGuildBank(uint32 GuildID) return Iterator; } -bool GuildBankManager::DeleteItem(uint32 GuildID, uint16 Area, uint16 SlotID, uint32 Quantity) +bool GuildBankManager::DeleteItem(uint32 guildID, uint16 area, uint16 slotID, uint32 quantity) { - std::list::iterator Iterator = GetGuildBank(GuildID); + auto iter = GetGuildBank(guildID); - if(Iterator == Banks.end()) + if(iter == Banks.end()) return false; - char errbuf[MYSQL_ERRMSG_SIZE]; - - char* query = 0; - GuildBankItem* BankArea = nullptr; - if(Area == GuildBankMainArea) + if(area == GuildBankMainArea) { - if(SlotID > (GUILD_BANK_MAIN_AREA_SIZE - 1)) + if(slotID > (GUILD_BANK_MAIN_AREA_SIZE - 1)) return false; - BankArea = &(*Iterator)->Items.MainArea[0]; - } - else - { - if(SlotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1)) + BankArea = &(*iter)->Items.MainArea[0]; + } else { + if(slotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1)) return false; - BankArea = &(*Iterator)->Items.DepositArea[0]; + BankArea = &(*iter)->Items.DepositArea[0]; } + bool deleted = true; - bool Deleted = true; - - const Item_Struct *Item = database.GetItem(BankArea[SlotID].ItemID); - - if(!Item->Stackable || (Quantity >= BankArea[SlotID].Quantity)) - { - const char *Query = "DELETE from `guild_bank` where `guildid` = %i AND `area` = %i AND `slot` = %i LIMIT 1"; - - if(!database.RunQuery(query, MakeAnyLenString(&query, Query, GuildID, Area, SlotID), errbuf)) - { - _log(GUILDS__BANK_ERROR, "Delete item failed. %s : %s", query, errbuf); - - safe_delete_array(query); + const Item_Struct *Item = database.GetItem(BankArea[slotID].ItemID); + if(!Item->Stackable || (quantity >= BankArea[slotID].Quantity)) { + std::string query = StringFormat("DELETE FROM `guild_bank` WHERE `guildid` = %i " + "AND `area` = %i AND `slot` = %i LIMIT 1", + guildID, area, slotID); + auto results = database.QueryDatabase(query); + if(!results.Success()) { + _log(GUILDS__BANK_ERROR, "Delete item failed. %s : %s", query.c_str(), results.ErrorMessage().c_str()); return false; } - safe_delete_array(query); - - BankArea[SlotID].ItemID = 0; - } - else - { - const char *Query = "UPDATE `guild_bank` SET `qty` = %i where `guildid` = %i AND `area` = %i AND `slot` = %i LIMIT 1"; - - if(!database.RunQuery(query, MakeAnyLenString(&query, Query, BankArea[SlotID].Quantity - Quantity, - GuildID, Area, SlotID), errbuf)) - { - _log(GUILDS__BANK_ERROR, "Update item failed. %s : %s", query, errbuf); - - safe_delete_array(query); + BankArea[slotID].ItemID = 0; + } else { + std::string query = StringFormat("UPDATE `guild_bank` SET `qty` = %i WHERE `guildid` = %i " + "AND `area` = %i AND `slot` = %i LIMIT 1", + BankArea[slotID].Quantity - quantity, guildID, area, slotID); + auto results = database.QueryDatabase(query); + if(!results.Success()) { + _log(GUILDS__BANK_ERROR, "Update item failed. %s : %s", query.c_str(), results.ErrorMessage().c_str()); return false; } - safe_delete_array(query); + BankArea[slotID].Quantity -= quantity; - BankArea[SlotID].Quantity -= Quantity; - - Deleted = false; + deleted = false; } + GuildBankItemUpdate_Struct gbius; - if(!Deleted) + if(!deleted) { - gbius.Init(GuildBankItemUpdate, 1, SlotID, Area, 1, Item->ID, Item->Icon, BankArea[SlotID].Quantity, BankArea[SlotID].Permissions, 1, 0); + gbius.Init(GuildBankItemUpdate, 1, slotID, area, 1, Item->ID, Item->Icon, BankArea[slotID].Quantity, BankArea[slotID].Permissions, 1, 0); strn0cpy(gbius.ItemName, Item->Name, sizeof(gbius.ItemName)); - strn0cpy(gbius.WhoFor, BankArea[SlotID].WhoFor, sizeof(gbius.WhoFor)); + strn0cpy(gbius.WhoFor, BankArea[slotID].WhoFor, sizeof(gbius.WhoFor)); } else - gbius.Init(GuildBankItemUpdate, 1, SlotID, Area, 0, 0, 0, 0, 0, 0, 0); + gbius.Init(GuildBankItemUpdate, 1, slotID, area, 0, 0, 0, 0, 0, 0, 0); - entity_list.QueueClientsGuildBankItemUpdate(&gbius, GuildID); + entity_list.QueueClientsGuildBankItemUpdate(&gbius, guildID); return true; From a6b923a22ef19fb610d33b99e9e2f681ecf54379 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Mon, 25 Aug 2014 15:10:46 -0700 Subject: [PATCH 51/89] UpdateItemQuantity converted to QueryDatabase --- zone/guild_mgr.cpp | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index e1fbf0db5..37cc7a3de 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -1338,26 +1338,20 @@ bool GuildBankManager::SplitStack(uint32 GuildID, uint16 SlotID, uint32 Quantity return true; } -void GuildBankManager::UpdateItemQuantity(uint32 GuildID, uint16 Area, uint16 SlotID, uint32 Quantity) +void GuildBankManager::UpdateItemQuantity(uint32 guildID, uint16 area, uint16 slotID, uint32 quantity) { // Helper method for MergeStacks. Assuming all passed parameters are valid. // - char errbuf[MYSQL_ERRMSG_SIZE]; - - char* query = 0; - - const char *Query = "UPDATE `guild_bank` SET `qty` = %i where `guildid` = %i AND `area` = %i AND `slot` = %i LIMIT 1"; - - if(!database.RunQuery(query, MakeAnyLenString(&query, Query, Quantity, GuildID, Area, SlotID), errbuf)) - { - _log(GUILDS__BANK_ERROR, "Update item quantity failed. %s : %s", query, errbuf); - - safe_delete_array(query); - + std::string query = StringFormat("UPDATE `guild_bank` SET `qty` = %i " + "WHERE `guildid` = %i AND `area` = %i " + "AND `slot` = %i LIMIT 1", + quantity, guildID, area, slotID); + auto results = database.QueryDatabase(query); + if(!results.Success()) { + _log(GUILDS__BANK_ERROR, "Update item quantity failed. %s : %s", query.c_str(), results.ErrorMessage().c_str()); return; } - safe_delete_array(query); } bool GuildBankManager::AllowedToWithdraw(uint32 GuildID, uint16 Area, uint16 SlotID, const char *Name) From d4a9fed45eeae224f64dfaa93bb3920af19a6cff Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 25 Aug 2014 22:29:00 -0400 Subject: [PATCH 52/89] Added QS code to Client::FinishTrade() --- zone/client.h | 2 +- zone/client_packet.cpp | 75 +++++++--- zone/trading.cpp | 320 +++++++++++++++++++++++++---------------- 3 files changed, 250 insertions(+), 147 deletions(-) diff --git a/zone/client.h b/zone/client.h index f2d16ea0f..d3aed5540 100644 --- a/zone/client.h +++ b/zone/client.h @@ -268,7 +268,7 @@ public: void TradeRequestFailed(const EQApplicationPacket* app); void BuyTraderItem(TraderBuy_Struct* tbs,Client* trader,const EQApplicationPacket* app); void TraderUpdate(uint16 slot_id,uint32 trader_id); - void FinishTrade(Mob* with, ServerPacket* qspack = nullptr, bool finalizer = false); + void FinishTrade(Mob* with, bool finalizer = false, void* event_entry = nullptr, std::list* event_details = nullptr); void SendZonePoints(); void SendBuyerResults(char *SearchQuery, uint32 SearchID); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f35ec0565..8d39f815a 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4862,6 +4862,7 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) { Mob* with = trade->With(); trade->state = TradeAccepted; + if (with && with->IsClient()) { //finish trade... // Have both accepted? @@ -4872,6 +4873,7 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) other->trade->state = TradeCompleting; trade->state = TradeCompleting; + // should we do this for NoDrop items as well? if (CheckTradeLoreConflict(other) || other->CheckTradeLoreConflict(this)) { Message_StringID(13, TRADE_CANCEL_LORE); other->Message_StringID(13, TRADE_CANCEL_LORE); @@ -4887,23 +4889,37 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) // start QS code if(RuleB(QueryServ, PlayerLogTrades)) { - uint16 trade_count = 0; + QSPlayerLogTrade_Struct event_entry; + std::list event_details; - // Item trade count for packet sizing - for(int16 slot_id = EmuConstants::TRADE_BEGIN; slot_id <= EmuConstants::TRADE_END; slot_id++) { - if(other->GetInv().GetItem(slot_id)) { trade_count += other->GetInv().GetItem(slot_id)->GetTotalItemCount(); } - if(m_inv[slot_id]) { trade_count += m_inv[slot_id]->GetTotalItemCount(); } - } - - ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogTrades, sizeof(QSPlayerLogTrade_Struct) + (sizeof(QSTradeItems_Struct) * trade_count)); + memset(&event_entry, 0, sizeof(QSPlayerLogTrade_Struct)); // Perform actual trade - this->FinishTrade(other, qspack, true); - other->FinishTrade(this, qspack, false); + this->FinishTrade(other, true, &event_entry, &event_details); + other->FinishTrade(this, false, &event_entry, &event_details); - qspack->Deflate(); - if(worldserver.Connected()) { worldserver.SendPacket(qspack); } - safe_delete(qspack); + ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogTrades, sizeof(QSPlayerLogTrade_Struct)+(sizeof(QSTradeItems_Struct)* event_details.size())); + + QSPlayerLogTrade_Struct* qs_buf = (QSPlayerLogTrade_Struct*)qs_pack->pBuffer; + + memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogTrade_Struct)); + + int offset = 0; + + for (std::list::iterator iter = event_details.begin(); iter != event_details.end(); ++iter, ++offset) { + QSTradeItems_Struct* detail = reinterpret_cast(*iter); + qs_buf->items[offset] = *detail; + safe_delete(detail); + } + + event_details.clear(); + + qs_pack->Deflate(); + + if(worldserver.Connected()) + worldserver.SendPacket(qs_pack); + + safe_delete(qs_pack); // end QS code } else { @@ -4928,25 +4944,42 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) if(with->IsNPC()) { // Audit trade to database for player trade stream if(RuleB(QueryServ, PlayerLogHandins)) { - uint16 handin_count = 0; + QSPlayerLogHandin_Struct event_entry; + std::list event_details; - for(int16 slot_id = EmuConstants::TRADE_BEGIN; slot_id <= EmuConstants::TRADE_NPC_END; slot_id++) { - if(m_inv[slot_id]) { handin_count += m_inv[slot_id]->GetTotalItemCount(); } + memset(&event_entry, 0, sizeof(QSPlayerLogHandin_Struct)); + + FinishTrade(with->CastToNPC(), false, &event_entry, &event_details); + + ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogHandins, sizeof(QSPlayerLogHandin_Struct)+(sizeof(QSHandinItems_Struct)* event_details.size())); + + QSPlayerLogHandin_Struct* qs_buf = (QSPlayerLogHandin_Struct*)qs_pack->pBuffer; + + memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogHandin_Struct)); + + int offset = 0; + + for (std::list::iterator iter = event_details.begin(); iter != event_details.end(); ++iter, ++offset) { + QSHandinItems_Struct* detail = reinterpret_cast(*iter); + qs_buf->items[offset] = *detail; + safe_delete(detail); } - ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogHandins, sizeof(QSPlayerLogHandin_Struct) + (sizeof(QSHandinItems_Struct) * handin_count)); + event_details.clear(); - FinishTrade(with->CastToNPC(), qspack); + qs_pack->Deflate(); - qspack->Deflate(); - if(worldserver.Connected()) { worldserver.SendPacket(qspack); } - safe_delete(qspack); + if(worldserver.Connected()) + worldserver.SendPacket(qs_pack); + + safe_delete(qs_pack); } else { FinishTrade(with->CastToNPC()); } } #ifdef BOTS + // TODO: Log Bot trades else if(with->IsBot()) with->CastToBot()->FinishTrade(this, Bot::BotTradeClientNormal); #endif diff --git a/zone/trading.cpp b/zone/trading.cpp index 1ae9596b9..88b277651 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -22,7 +22,10 @@ #include "../common/rulesys.h" #include "quest_parser_collection.h" #include "worldserver.h" +#include "queryserv.h" + extern WorldServer worldserver; +extern QueryServ* QServ; // The maximum amount of a single bazaar/barter transaction expressed in copper. // Equivalent to 2 Million plat @@ -438,92 +441,38 @@ void Client::ResetTrade() { } } -void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) { +void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, std::list* event_details) { if(tradingWith && tradingWith->IsClient()) { Client* other = tradingWith->CastToClient(); + QSPlayerLogTrade_Struct* qs_audit = nullptr; + bool qs_log = false; if(other) { mlog(TRADING__CLIENT, "Finishing trade with client %s", other->GetName()); this->AddMoneyToPP(other->trade->cp, other->trade->sp, other->trade->gp, other->trade->pp, true); - + // step 0: pre-processing // QS code - if (qspack && RuleB(QueryServ, PlayerLogTrades)) { - QSPlayerLogTrade_Struct* qsaudit = (QSPlayerLogTrade_Struct*)qspack->pBuffer; - + if (RuleB(QueryServ, PlayerLogTrades) && event_entry && event_details) { + qs_audit = (QSPlayerLogTrade_Struct*)event_entry; + qs_log = true; + if (finalizer) { - qsaudit->char2_id = this->character_id; + qs_audit->char2_id = this->character_id; - qsaudit->char2_money.platinum = this->trade->pp; - qsaudit->char2_money.gold = this->trade->gp; - qsaudit->char2_money.silver = this->trade->sp; - qsaudit->char2_money.copper = this->trade->cp; + qs_audit->char2_money.platinum = this->trade->pp; + qs_audit->char2_money.gold = this->trade->gp; + qs_audit->char2_money.silver = this->trade->sp; + qs_audit->char2_money.copper = this->trade->cp; } else { - qsaudit->char1_id = this->character_id; + qs_audit->char1_id = this->character_id; - qsaudit->char1_money.platinum = this->trade->pp; - qsaudit->char1_money.gold = this->trade->gp; - qsaudit->char1_money.silver = this->trade->sp; - qsaudit->char1_money.copper = this->trade->cp; - } - - // qsaudit->items[x].to_slot is disabled until QueryServ:PlayerLogTrades code is updated - for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) { - const ItemInst* inst = m_inv[trade_slot]; - - if (!inst) - continue; - - uint16 item_offset = qsaudit->char1_count + qsaudit->char2_count; - - qsaudit->items[item_offset].from_id = this->character_id; - qsaudit->items[item_offset].from_slot = trade_slot; - qsaudit->items[item_offset].to_id = other->CharacterID(); - qsaudit->items[item_offset].to_slot = 0; // disabled - qsaudit->items[item_offset].item_id = inst->GetID(); - qsaudit->items[item_offset].charges = inst->GetCharges(); - qsaudit->items[item_offset].aug_1 = inst->GetAugmentItemID(1); - qsaudit->items[item_offset].aug_2 = inst->GetAugmentItemID(2); - qsaudit->items[item_offset].aug_3 = inst->GetAugmentItemID(3); - qsaudit->items[item_offset].aug_4 = inst->GetAugmentItemID(4); - qsaudit->items[item_offset].aug_5 = inst->GetAugmentItemID(5); - - if (finalizer) - ++qsaudit->char2_count; - else - ++qsaudit->char1_count; - - if (inst->IsType(ItemClassContainer)) { - // Pseudo-Slot ID's are generated based on how the db saves bag items... - for (uint8 sub_slot = SUB_BEGIN; sub_slot < inst->GetItem()->BagSlots; ++sub_slot) { - const ItemInst* sub_inst = inst->GetItem(sub_slot); - - if (!sub_inst) - continue; - - int16 from_slot = Inventory::CalcSlotId(trade_slot, sub_slot); - item_offset = qsaudit->char1_count + qsaudit->char2_count; - - qsaudit->items[item_offset].from_id = this->character_id; - qsaudit->items[item_offset].from_slot = from_slot; - qsaudit->items[item_offset].to_id = other->CharacterID(); - qsaudit->items[item_offset].to_slot = 0; // disabled - qsaudit->items[item_offset].item_id = sub_inst->GetID(); - qsaudit->items[item_offset].charges = sub_inst->GetCharges(); - qsaudit->items[item_offset].aug_1 = sub_inst->GetAugmentItemID(1); - qsaudit->items[item_offset].aug_2 = sub_inst->GetAugmentItemID(2); - qsaudit->items[item_offset].aug_3 = sub_inst->GetAugmentItemID(3); - qsaudit->items[item_offset].aug_4 = sub_inst->GetAugmentItemID(4); - qsaudit->items[item_offset].aug_5 = sub_inst->GetAugmentItemID(5); - - if (finalizer) - ++qsaudit->char2_count; - else - ++qsaudit->char1_count; - } - } + qs_audit->char1_money.platinum = this->trade->pp; + qs_audit->char1_money.gold = this->trade->gp; + qs_audit->char1_money.silver = this->trade->sp; + qs_audit->char1_money.copper = this->trade->cp; } } @@ -541,22 +490,69 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) if (free_slot != INVALID_INDEX) { if (other->PutItemInInventory(free_slot, *inst, true)) { mlog(TRADING__CLIENT, "Container %s (%d) successfully transferred, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID); + if (qs_log) { + QSTradeItems_Struct* detail = new QSTradeItems_Struct; + + detail->from_id = this->character_id; + detail->from_slot = trade_slot; + detail->to_id = other->CharacterID(); + detail->to_slot = free_slot; + detail->item_id = inst->GetID(); + detail->charges = 1; + detail->aug_1 = inst->GetAugmentItemID(1); + detail->aug_2 = inst->GetAugmentItemID(2); + detail->aug_3 = inst->GetAugmentItemID(3); + detail->aug_4 = inst->GetAugmentItemID(4); + detail->aug_5 = inst->GetAugmentItemID(5); + + event_details->push_back(detail); + + if (finalizer) + qs_audit->char2_count += detail->charges; + else + qs_audit->char1_count += detail->charges; + + //for (uint8 sub_slot = SUB_BEGIN; ((sub_slot < inst->GetItem()->BagSlots) && (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE)); ++sub_slot) { + for (uint8 sub_slot = SUB_BEGIN; (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++sub_slot) { // this is to catch ALL items + const ItemInst* bag_inst = inst->GetItem(sub_slot); + + if (bag_inst) { + detail = new QSTradeItems_Struct; + + detail->from_id = this->character_id; + detail->from_slot = Inventory::CalcSlotId(trade_slot, sub_slot); + detail->to_id = other->CharacterID(); + detail->to_slot = Inventory::CalcSlotId(free_slot, sub_slot); + detail->item_id = bag_inst->GetID(); + detail->charges = (!bag_inst->IsStackable() ? 1 : bag_inst->GetCharges()); + detail->aug_1 = bag_inst->GetAugmentItemID(1); + detail->aug_2 = bag_inst->GetAugmentItemID(2); + detail->aug_3 = bag_inst->GetAugmentItemID(3); + detail->aug_4 = bag_inst->GetAugmentItemID(4); + detail->aug_5 = bag_inst->GetAugmentItemID(5); + + event_details->push_back(detail); + + if (finalizer) + qs_audit->char2_count += detail->charges; + else + qs_audit->char1_count += detail->charges; + } + } + } } else { mlog(TRADING__ERROR, "Transfer of container %s (%d) to %s failed, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName()); - PushItemOnCursor(*inst, true); } } else { mlog(TRADING__ERROR, "%s's inventory is full, returning container %s (%d) to giver.", other->GetName(), inst->GetItem()->Name, inst->GetItem()->ID); - PushItemOnCursor(*inst, true); } } else { mlog(TRADING__ERROR, "Container %s (%d) is NoDrop, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID); - PushItemOnCursor(*inst, true); } @@ -583,7 +579,6 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) if (partial_inst->GetID() != inst->GetID()) { _log(TRADING__ERROR, "Client::ResetTrade() - an incompatible location reference was returned by Inventory::FindFreeSlotForTradeItem()"); - break; } @@ -606,6 +601,28 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) if (other->PutItemInInventory(partial_slot, *partial_inst, true)) { mlog(TRADING__CLIENT, "Partial stack %s (%d) successfully transferred, deleting %i charges from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID, (old_charges - inst->GetCharges())); + if (qs_log) { + QSTradeItems_Struct* detail = new QSTradeItems_Struct; + + detail->from_id = this->character_id; + detail->from_slot = trade_slot; + detail->to_id = other->CharacterID(); + detail->to_slot = partial_slot; + detail->item_id = inst->GetID(); + detail->charges = (old_charges - inst->GetCharges()); + detail->aug_1 = 0; + detail->aug_2 = 0; + detail->aug_3 = 0; + detail->aug_4 = 0; + detail->aug_5 = 0; + + event_details->push_back(detail); + + if (finalizer) + qs_audit->char2_count += detail->charges; + else + qs_audit->char1_count += detail->charges; + } } else { mlog(TRADING__ERROR, "Transfer of partial stack %s (%d) to %s failed, returning %i charges to trade slot.", @@ -613,13 +630,11 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) inst->SetCharges(old_charges); partial_inst->SetCharges(partial_charges); - break; } if (inst->GetCharges() == 0) { DeleteItemInInventory(trade_slot); - break; } } @@ -654,7 +669,6 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) if (inst->GetCharges() == 0) { DeleteItemInInventory(trade_slot); - break; } } @@ -675,22 +689,70 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) if (free_slot != INVALID_INDEX) { if (other->PutItemInInventory(free_slot, *inst, true)) { mlog(TRADING__CLIENT, "Item %s (%d) successfully transferred, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID); + if (qs_log) { + QSTradeItems_Struct* detail = new QSTradeItems_Struct; + + detail->from_id = this->character_id; + detail->from_slot = trade_slot; + detail->to_id = other->CharacterID(); + detail->to_slot = free_slot; + detail->item_id = inst->GetID(); + detail->charges = (!inst->IsStackable() ? 1 : inst->GetCharges()); + detail->aug_1 = inst->GetAugmentItemID(1); + detail->aug_2 = inst->GetAugmentItemID(2); + detail->aug_3 = inst->GetAugmentItemID(3); + detail->aug_4 = inst->GetAugmentItemID(4); + detail->aug_5 = inst->GetAugmentItemID(5); + + event_details->push_back(detail); + + if (finalizer) + qs_audit->char2_count += detail->charges; + else + qs_audit->char1_count += detail->charges; + + // 'step 3' should never really see containers..but, just in case... + //for (uint8 sub_slot = SUB_BEGIN; ((sub_slot < inst->GetItem()->BagSlots) && (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE)); ++sub_slot) { + for (uint8 sub_slot = SUB_BEGIN; (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++sub_slot) { // this is to catch ALL items + const ItemInst* bag_inst = inst->GetItem(sub_slot); + + if (bag_inst) { + detail = new QSTradeItems_Struct; + + detail->from_id = this->character_id; + detail->from_slot = trade_slot; + detail->to_id = other->CharacterID(); + detail->to_slot = free_slot; + detail->item_id = bag_inst->GetID(); + detail->charges = (!bag_inst->IsStackable() ? 1 : bag_inst->GetCharges()); + detail->aug_1 = bag_inst->GetAugmentItemID(1); + detail->aug_2 = bag_inst->GetAugmentItemID(2); + detail->aug_3 = bag_inst->GetAugmentItemID(3); + detail->aug_4 = bag_inst->GetAugmentItemID(4); + detail->aug_5 = bag_inst->GetAugmentItemID(5); + + event_details->push_back(detail); + + if (finalizer) + qs_audit->char2_count += detail->charges; + else + qs_audit->char1_count += detail->charges; + } + } + } } else { mlog(TRADING__ERROR, "Transfer of Item %s (%d) to %s failed, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName()); - PushItemOnCursor(*inst, true); } } else { mlog(TRADING__ERROR, "%s's inventory is full, returning item %s (%d) to giver.", other->GetName(), inst->GetItem()->Name, inst->GetItem()->ID); - PushItemOnCursor(*inst, true); } } else { mlog(TRADING__ERROR, "Item %s (%d) is NoDrop, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID); - PushItemOnCursor(*inst, true); } @@ -701,65 +763,73 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) //Do not reset the trade here, done by the caller. } } - - // trading with npc doesn't require Inventory::FindFreeSlotForTradeItem() rework else if(tradingWith && tradingWith->IsNPC()) { - QSPlayerLogHandin_Struct* qsaudit = nullptr; - bool QSPLH = false; + QSPlayerLogHandin_Struct* qs_audit = nullptr; + bool qs_log = false; // QS code - if(qspack && RuleB(QueryServ, PlayerLogTrades)) { + if(RuleB(QueryServ, PlayerLogTrades) && event_entry && event_details) { // Currently provides only basic functionality. Calling method will also // need to be modified before item returns and rewards can be logged. -U - qsaudit = (QSPlayerLogHandin_Struct*) qspack->pBuffer; - QSPLH = true; + qs_audit = (QSPlayerLogHandin_Struct*)event_entry; + qs_log = true; - qsaudit->quest_id = 0; - qsaudit->char_id = character_id; - qsaudit->char_money.platinum = trade->pp; - qsaudit->char_money.gold = trade->gp; - qsaudit->char_money.silver = trade->sp; - qsaudit->char_money.copper = trade->cp; - qsaudit->char_count = 0; - qsaudit->npc_id = tradingWith->GetNPCTypeID(); - qsaudit->npc_money.platinum = 0; - qsaudit->npc_money.gold = 0; - qsaudit->npc_money.silver = 0; - qsaudit->npc_money.copper = 0; - qsaudit->npc_count = 0; + qs_audit->quest_id = 0; + qs_audit->char_id = character_id; + qs_audit->char_money.platinum = trade->pp; + qs_audit->char_money.gold = trade->gp; + qs_audit->char_money.silver = trade->sp; + qs_audit->char_money.copper = trade->cp; + qs_audit->char_count = 0; + qs_audit->npc_id = tradingWith->GetNPCTypeID(); + qs_audit->npc_money.platinum = 0; + qs_audit->npc_money.gold = 0; + qs_audit->npc_money.silver = 0; + qs_audit->npc_money.copper = 0; + qs_audit->npc_count = 0; } - if(QSPLH) { // This can be incoporated below when revisions are made -U - for(int16 slot_id = EmuConstants::TRADE_BEGIN; slot_id <= EmuConstants::TRADE_NPC_END; slot_id++) { - const ItemInst* trade_inst = m_inv[slot_id]; + if(qs_log) { // This can be incorporated below when revisions are made -U + for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_NPC_END; ++trade_slot) { + const ItemInst* trade_inst = m_inv[trade_slot]; if(trade_inst) { - strcpy(qsaudit->items[qsaudit->char_count].action_type, "HANDIN"); + QSHandinItems_Struct* detail = new QSHandinItems_Struct; - qsaudit->items[qsaudit->char_count].char_slot = slot_id; - qsaudit->items[qsaudit->char_count].item_id = trade_inst->GetID(); - qsaudit->items[qsaudit->char_count].charges = trade_inst->GetCharges(); - qsaudit->items[qsaudit->char_count].aug_1 = trade_inst->GetAugmentItemID(1); - qsaudit->items[qsaudit->char_count].aug_2 = trade_inst->GetAugmentItemID(2); - qsaudit->items[qsaudit->char_count].aug_3 = trade_inst->GetAugmentItemID(3); - qsaudit->items[qsaudit->char_count].aug_4 = trade_inst->GetAugmentItemID(4); - qsaudit->items[qsaudit->char_count++].aug_5 = trade_inst->GetAugmentItemID(5); + strcpy(detail->action_type, "HANDIN"); + + detail->char_slot = trade_slot; + detail->item_id = trade_inst->GetID(); + detail->charges = (!trade_inst->IsStackable() ? 1 : trade_inst->GetCharges()); + detail->aug_1 = trade_inst->GetAugmentItemID(1); + detail->aug_2 = trade_inst->GetAugmentItemID(2); + detail->aug_3 = trade_inst->GetAugmentItemID(3); + detail->aug_4 = trade_inst->GetAugmentItemID(4); + detail->aug_5 = trade_inst->GetAugmentItemID(5); + + event_details->push_back(detail); + qs_audit->char_count += detail->charges; if(trade_inst->IsType(ItemClassContainer)) { - for(uint8 bag_idx = SUB_BEGIN; bag_idx < trade_inst->GetItem()->BagSlots; bag_idx++) { - const ItemInst* trade_baginst = trade_inst->GetItem(bag_idx); + for (uint8 sub_slot = SUB_BEGIN; sub_slot < trade_inst->GetItem()->BagSlots; ++sub_slot) { + const ItemInst* trade_baginst = trade_inst->GetItem(sub_slot); if(trade_baginst) { - strcpy(qsaudit->items[qsaudit->char_count].action_type, "HANDIN"); + detail = new QSHandinItems_Struct; - qsaudit->items[qsaudit->char_count].char_slot = Inventory::CalcSlotId(slot_id, bag_idx); - qsaudit->items[qsaudit->char_count].item_id = trade_baginst->GetID(); - qsaudit->items[qsaudit->char_count].charges = trade_baginst->GetCharges(); - qsaudit->items[qsaudit->char_count].aug_1 = trade_baginst->GetAugmentItemID(1); - qsaudit->items[qsaudit->char_count].aug_2 = trade_baginst->GetAugmentItemID(2); - qsaudit->items[qsaudit->char_count].aug_3 = trade_baginst->GetAugmentItemID(3); - qsaudit->items[qsaudit->char_count].aug_4 = trade_baginst->GetAugmentItemID(4); - qsaudit->items[qsaudit->char_count++].aug_5 = trade_baginst->GetAugmentItemID(5); + strcpy(detail->action_type, "HANDIN"); + + detail->char_slot = Inventory::CalcSlotId(trade_slot, sub_slot); + detail->item_id = trade_baginst->GetID(); + detail->charges = (!trade_inst->IsStackable() ? 1 : trade_inst->GetCharges()); + detail->aug_1 = trade_baginst->GetAugmentItemID(1); + detail->aug_2 = trade_baginst->GetAugmentItemID(2); + detail->aug_3 = trade_baginst->GetAugmentItemID(3); + detail->aug_4 = trade_baginst->GetAugmentItemID(4); + detail->aug_5 = trade_baginst->GetAugmentItemID(5); + + event_details->push_back(detail); + qs_audit->char_count += detail->charges; } } } From 70d598356291198c83fcc67a446c814be6f5daf4 Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 25 Aug 2014 22:31:02 -0700 Subject: [PATCH 53/89] Added eqemu::any --- common/CMakeLists.txt | 1 + common/any.h | 190 ++++++++++++++++++ ...postgreSQL.cpp => database_postgresql.cpp} | 0 tests/string_util_test.h | 2 +- 4 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 common/any.h rename loginserver/{database_postgreSQL.cpp => database_postgresql.cpp} (100%) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f02212161..a6a25f612 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -93,6 +93,7 @@ SET(common_sources ) SET(common_headers + any.h base_packet.h base_data.h bodytypes.h diff --git a/common/any.h b/common/any.h new file mode 100644 index 000000000..fd80fbc5f --- /dev/null +++ b/common/any.h @@ -0,0 +1,190 @@ +/* + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +// EQEmu::Any is a modified version of Boost::Any and as such retains the Boost licensing. + +#ifndef EQEMU_COMMON_ANY_H +#define EQEMU_COMMON_ANY_H + +#include +#include + +namespace EQEmu +{ + class Any + { + public: + Any() + : content(nullptr) + { + } + + template + Any(const ValueType &value) + : content(new Holder(value)) + { + } + + Any(const Any &other) + : content(other.content ? other.content->clone() : 0) + { + } + + ~Any() + { + if(content) + delete content; + } + + Any& swap(Any &rhs) + { + std::swap(content, rhs.content); + return *this; + } + + template + Any& operator=(const ValueType &rhs) + { + Any(rhs).swap(*this); + return *this; + } + + Any& operator=(Any rhs) + { + rhs.swap(*this); + return *this; + } + + bool empty() const + { + return !content; + } + + const std::type_info& type() const + { + return content ? content->type() : typeid(void); + } + + class Placeholder + { + public: + virtual ~Placeholder() + { + } + + virtual const std::type_info& type() const = 0; + virtual Placeholder* clone() const = 0; + }; + + + template + class Holder : public Placeholder + { + public: + Holder(const ValueType &value) + : held(value) + { + } + + virtual const std::type_info& type() const + { + return typeid(ValueType); + } + + virtual Placeholder* clone() const + { + return new Holder(held); + } + + ValueType held; + + private: + Holder& operator=(const Holder&); + }; + + private: + template + friend ValueType* any_cast(Any*); + + template + friend ValueType* unsafe_any_cast(Any*); + + Placeholder* content; + }; + + class bad_any_cast : public std::bad_cast + { + public: + virtual const char * what() const throw() + { + return "DBI::bad_any_cast: failed conversion using DBI::any_cast"; + } + }; + + template + ValueType* any_cast(Any* operand) + { + return operand && + operand->type() == typeid(ValueType) ? &static_cast*>(operand->content)->held : nullptr; + } + + template + inline const ValueType* any_cast(const Any* operand) + { + return any_cast(const_cast(operand)); + } + + template + ValueType any_cast(Any& operand) + { + typedef typename std::remove_reference::type nonref; + nonref* result = any_cast(&operand); + if(!result) + throw bad_any_cast(); + return *result; + } + + template + inline ValueType any_cast(const Any& operand) + { + typedef typename std::remove_reference::type nonref; + return any_cast(const_cast(operand)); + } + + template + inline ValueType* unsafe_any_cast(Any* operand) + { + return &static_cast*>(operand->content)->held; + } + + template + inline const ValueType* unsafe_any_cast(const Any* operand) + { + return unsafe_any_cast(const_cast(operand)); + } +} + +#endif diff --git a/loginserver/database_postgreSQL.cpp b/loginserver/database_postgresql.cpp similarity index 100% rename from loginserver/database_postgreSQL.cpp rename to loginserver/database_postgresql.cpp diff --git a/tests/string_util_test.h b/tests/string_util_test.h index 374878065..32efb5320 100644 --- a/tests/string_util_test.h +++ b/tests/string_util_test.h @@ -42,7 +42,7 @@ public: float f = 3.1416; auto s = StringFormat(fmt, c, i, f); - TEST_ASSERT(s.length() == 17); + TEST_ASSERT_EQUALS(s.length(), 17); TEST_ASSERT(s.compare("Test: a 2014 3.14") == 0); } From 6597967acdfa2473e1a613f9e30efd808e0a4afe Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 25 Aug 2014 22:59:52 -0700 Subject: [PATCH 54/89] Changed void* to EQEmu::Any in quest interface. Been meaning to change from void* for a while to a structure that data hides instead. --- zone/client_packet.cpp | 8 +- zone/corpse.cpp | 2 +- zone/embparser.cpp | 18 ++-- zone/embparser.h | 16 ++-- zone/entity.cpp | 8 +- zone/forage.cpp | 4 +- zone/lua_parser.cpp | 32 +++---- zone/lua_parser.h | 32 +++---- zone/lua_parser_events.cpp | 158 +++++++++++++++---------------- zone/lua_parser_events.h | 118 +++++++++++------------ zone/object.cpp | 2 +- zone/quest_interface.h | 23 ++--- zone/quest_parser_collection.cpp | 26 ++--- zone/quest_parser_collection.h | 26 ++--- zone/spell_effects.cpp | 12 +-- zone/tradeskills.cpp | 4 +- zone/trading.cpp | 2 +- 17 files changed, 246 insertions(+), 245 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f35ec0565..4087d28b1 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -433,7 +433,7 @@ int Client::HandlePacket(const EQApplicationPacket *app) case CLIENT_CONNECTING: { if(ConnectingOpcodes.count(opcode) != 1) { //Hate const cast but everything in lua needs to be non-const even if i make it non-mutable - std::vector args; + std::vector args; args.push_back(const_cast(app)); parse->EventPlayer(EVENT_UNHANDLED_OPCODE, this, "", 1, &args); @@ -462,7 +462,7 @@ int Client::HandlePacket(const EQApplicationPacket *app) ClientPacketProc p; p = ConnectedOpcodes[opcode]; if(p == nullptr) { - std::vector args; + std::vector args; args.push_back(const_cast(app)); parse->EventPlayer(EVENT_UNHANDLED_OPCODE, this, "", 0, &args); @@ -5986,7 +5986,7 @@ void Client::Handle_OP_ClickObject(const EQApplicationPacket *app) object->HandleClick(this, click_object); - std::vector args; + std::vector args; args.push_back(object); char buf[10]; @@ -6222,7 +6222,7 @@ void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app) char buf[20]; snprintf(buf, 19, "%u", cd->doorid); buf[19] = '\0'; - std::vector args; + std::vector args; args.push_back(currentdoor); parse->EventPlayer(EVENT_CLICK_DOOR, this, buf, 0, &args); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index aa7841a64..da9ffab17 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -1164,7 +1164,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) strcpy(corpse_name, orgname); snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(corpse_name)); buf[87] = '\0'; - std::vector args; + std::vector args; args.push_back(inst); args.push_back(this); parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args); diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 8c4a82f55..f577bcb11 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -154,7 +154,7 @@ void PerlembParser::ReloadQuests() { } int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, - uint32 extradata, bool global, std::vector *extra_pointers) + uint32 extradata, bool global, std::vector *extra_pointers) { if(!perl) return 0; @@ -211,32 +211,32 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da } int PerlembParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, false, extra_pointers); } int PerlembParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, true, extra_pointers); } int PerlembParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, false, extra_pointers); } int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, true, extra_pointers); } int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, extra_pointers); } int PerlembParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, 0, itoa(spell_id), npc, nullptr, client, extra_data, false, extra_pointers); } @@ -1114,7 +1114,7 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob) { #undef HASITEM_ISNULLITEM void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data, - NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *extra_pointers) + NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *extra_pointers) { switch (event) { case EVENT_SAY: { @@ -1131,7 +1131,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID case EVENT_TRADE: { if(extra_pointers) { for(size_t i = 0; i < extra_pointers->size(); ++i) { - ItemInst *inst = reinterpret_cast(extra_pointers->at(i)); + ItemInst *inst = EQEmu::any_cast(extra_pointers->at(i)); std::string var_name = "item"; var_name += std::to_string(static_cast(i + 1)); diff --git a/zone/embparser.h b/zone/embparser.h index 3cb3a57f7..1357ae20b 100644 --- a/zone/embparser.h +++ b/zone/embparser.h @@ -45,17 +45,17 @@ public: ~PerlembParser(); virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual bool HasQuestSub(uint32 npcid, QuestEventID evt); virtual bool HasGlobalQuestSub(QuestEventID evt); @@ -86,7 +86,7 @@ private: void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value); int EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, - uint32 extradata, bool global, std::vector *extra_pointers); + uint32 extradata, bool global, std::vector *extra_pointers); int SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst *iteminst); void MapFunctions(); @@ -103,7 +103,7 @@ private: void ExportZoneVariables(std::string &package_name); void ExportItemVariables(std::string &package_name, Mob *mob); void ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data, - NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *extra_pointers); + NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *extra_pointers); std::map npc_quest_status_; PerlQuestStatus global_npc_quest_status_; diff --git a/zone/entity.cpp b/zone/entity.cpp index 2ca3f640d..16fbe7077 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1476,7 +1476,7 @@ void EntityList::QueueClientsStatus(Mob *sender, const EQApplicationPacket *app, void EntityList::DuelMessage(Mob *winner, Mob *loser, bool flee) { if (winner->GetLevelCon(winner->GetLevel(), loser->GetLevel()) > 2) { - std::vector args; + std::vector args; args.push_back(winner); args.push_back(loser); @@ -2847,7 +2847,7 @@ void EntityList::ClearFeignAggro(Mob *targ) } if (targ->IsClient()) { - std::vector args; + std::vector args; args.push_back(it->second); int i = parse->EventPlayer(EVENT_FEIGN_DEATH, targ->CastToClient(), "", 0, &args); if (i != 0) { @@ -3244,7 +3244,7 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z) if (evt.npc) { parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0); } else { - std::vector args; + std::vector args; args.push_back(&evt.area_id); args.push_back(&evt.area_type); parse->EventPlayer(evt.event_id, evt.client, "", 0, &args); @@ -3298,7 +3298,7 @@ void EntityList::ProcessMove(NPC *n, float x, float y, float z) for (auto iter = events.begin(); iter != events.end(); ++iter) { quest_proximity_event& evt = (*iter); - std::vector args; + std::vector args; args.push_back(&evt.area_id); args.push_back(&evt.area_type); parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0, &args); diff --git a/zone/forage.cpp b/zone/forage.cpp index aaa3451d5..e85cbda4a 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -357,7 +357,7 @@ void Client::GoFish() } } - std::vector args; + std::vector args; args.push_back(inst); parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst != nullptr ? inst->GetItem()->ID : 0, &args); } @@ -471,7 +471,7 @@ void Client::ForageItem(bool guarantee) { } } - std::vector args; + std::vector args; args.push_back(inst); parse->EventPlayer(EVENT_FORAGE_SUCCESS, this, "", inst ? inst->GetItem()->ID : 0, &args); diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 9f082993c..1de119afa 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -220,7 +220,7 @@ LuaParser::~LuaParser() { } int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -239,7 +239,7 @@ int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, } int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -257,7 +257,7 @@ int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string } int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func) { + std::vector *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -316,7 +316,7 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M } int LuaParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -334,7 +334,7 @@ int LuaParser::EventPlayer(QuestEventID evt, Client *client, std::string data, u } int LuaParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -352,7 +352,7 @@ int LuaParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string d } int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func) { + std::vector *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -409,7 +409,7 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client * } int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -429,7 +429,7 @@ int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob * } int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob, - std::string data, uint32 extra_data, std::vector *extra_pointers, luabind::adl::object *l_func) { + std::string data, uint32 extra_data, std::vector *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -492,7 +492,7 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl } int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -508,7 +508,7 @@ int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spe } int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func) { + std::vector *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -572,7 +572,7 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, return 0; } -int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, std::vector *extra_pointers) { +int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -588,7 +588,7 @@ int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint } int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -972,7 +972,7 @@ void LuaParser::MapFunctions(lua_State *L) { } int LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -1018,7 +1018,7 @@ int LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::stri } int LuaParser::DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -1047,7 +1047,7 @@ int LuaParser::DispatchEventPlayer(QuestEventID evt, Client *client, std::string } int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -1093,7 +1093,7 @@ int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *ite } int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; diff --git a/zone/lua_parser.h b/zone/lua_parser.h index 732f7d235..13cebe0fc 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -28,19 +28,19 @@ public: ~LuaParser(); virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt); virtual bool HasGlobalQuestSub(QuestEventID evt); @@ -65,25 +65,25 @@ public: virtual uint32 GetIdentifier() { return 0xb0712acc; } virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); private: int _EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); + std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); int _EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); + std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); int _EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, - uint32 extra_data, std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); + uint32 extra_data, std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); int _EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); + std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void LoadScript(std::string filename, std::string package_name); bool HasFunction(std::string function, std::string package_name); diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 56e5d236d..87155d97b 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -27,7 +27,7 @@ //NPC void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { npc->DoQuestPause(init); Lua_Client l_client(reinterpret_cast(init)); @@ -43,7 +43,7 @@ void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *in } void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Client l_client(reinterpret_cast(init)); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); @@ -56,7 +56,7 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob * if(extra_pointers) { for(size_t i = 0; i < extra_pointers->size(); ++i) { std::string prefix = "item" + std::to_string(static_cast(i + 1)); - Lua_ItemInst l_inst = reinterpret_cast(extra_pointers->at(i)); + Lua_ItemInst l_inst = EQEmu::any_cast(extra_pointers->at(i)); luabind::adl::object l_inst_o = luabind::adl::object(L, l_inst); l_inst_o.push(L); @@ -79,7 +79,7 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob * } void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(extra_data == 1) { lua_pushinteger(L, -1); lua_setfield(L, -2, "hp_event"); @@ -96,7 +96,7 @@ void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *ini } void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -104,7 +104,7 @@ void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *i } void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Client l_client(reinterpret_cast(init)); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); @@ -112,7 +112,7 @@ void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob } void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_NPC l_npc(reinterpret_cast(init)); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); l_npc_o.push(L); @@ -120,7 +120,7 @@ void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *i } void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Client l_client(reinterpret_cast(init)); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); @@ -131,7 +131,7 @@ void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob } void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -142,7 +142,7 @@ void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, } void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -153,7 +153,7 @@ void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *ini } void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -165,19 +165,19 @@ void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, s void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "signal"); } void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "timer"); } void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -205,7 +205,7 @@ void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, } void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int spell_id = std::stoi(data); if(IsValidSpell(spell_id)) { Lua_Spell l_spell(&spells[spell_id]); @@ -221,21 +221,21 @@ void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, s } void handle_npc_area(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "area_id"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(1))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(1))); lua_setfield(L, -2, "area_type"); } void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { } //Player void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "message"); @@ -244,7 +244,7 @@ void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std: } void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Seperator sep(data.c_str()); Mob *o = entity_list.GetMobID(std::stoi(sep.arg[0])); @@ -274,13 +274,13 @@ void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, st } void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "timer"); } void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { const Item_Struct *item = database.GetItem(extra_data); if(item) { Lua_Item l_item(item); @@ -296,51 +296,51 @@ void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* cl } void handle_player_fish_forage_success(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); } void handle_player_click_object(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Object l_object(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_Object l_object(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_object_o = luabind::adl::object(L, l_object); l_object_o.push(L); lua_setfield(L, -2, "object"); } void handle_player_click_door(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Door l_door(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_Door l_door(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_door_o = luabind::adl::object(L, l_door); l_door_o.push(L); lua_setfield(L, -2, "door"); } void handle_player_signal(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "signal"); } void handle_player_popup_response(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "popup_id"); } void handle_player_pick_up(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); } void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int spell_id = std::stoi(data); if(IsValidSpell(spell_id)) { Lua_Spell l_spell(&spells[spell_id]); @@ -356,48 +356,48 @@ void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std } void handle_player_task_fail(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "task_id"); } void handle_player_zone(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "zone_id"); } void handle_player_duel_win(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Client l_client(reinterpret_cast(extra_pointers->at(1))); + std::vector *extra_pointers) { + Lua_Client l_client(EQEmu::any_cast(extra_pointers->at(1))); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); lua_setfield(L, -2, "other"); } void handle_player_duel_loss(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Client l_client(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_Client l_client(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); lua_setfield(L, -2, "other"); } void handle_player_loot(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); - Lua_Corpse l_corpse(reinterpret_cast(extra_pointers->at(1))); + Lua_Corpse l_corpse(EQEmu::any_cast(extra_pointers->at(1))); luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse); l_corpse_o.push(L); lua_setfield(L, -2, "corpse"); } void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Seperator sep(data.c_str()); lua_pushinteger(L, std::stoi(sep.arg[0])); lua_setfield(L, -2, "task_id"); @@ -407,7 +407,7 @@ void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Clie } void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Seperator sep(data.c_str()); lua_pushinteger(L, std::stoi(sep.arg[0])); lua_setfield(L, -2, "count"); @@ -420,7 +420,7 @@ void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* clie } void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Seperator sep(data.c_str(), ' ', 10, 100, true); std::string command(sep.arg[0] + 1); lua_pushstring(L, command.c_str()); @@ -439,7 +439,7 @@ void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, } void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, extra_data); lua_setfield(L, -2, "recipe_id"); @@ -448,24 +448,24 @@ void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, } void handle_player_feign(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_NPC l_npc(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_NPC l_npc(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); l_npc_o.push(L); lua_setfield(L, -2, "other"); } void handle_player_area(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "area_id"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(1))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(1))); lua_setfield(L, -2, "area_type"); } void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "option"); @@ -474,8 +474,8 @@ void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, } void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Packet l_packet(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_Packet l_packet(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_packet_o = luabind::adl::object(L, l_packet); l_packet_o.push(L); lua_setfield(L, -2, "packet"); @@ -485,24 +485,24 @@ void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, s } void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { } //Item void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, extra_data); lua_setfield(L, -2, "slot_id"); } void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "timer"); } void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(mob); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); @@ -523,7 +523,7 @@ void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemI } void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(mob && mob->IsCorpse()) { Lua_Corpse l_corpse(mob->CastToCorpse()); luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse); @@ -538,14 +538,14 @@ void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemI } void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, extra_data); lua_setfield(L, -2, "slot_id"); } void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "aug"); @@ -555,8 +555,8 @@ void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, It } void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); @@ -566,8 +566,8 @@ void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* cli } void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); @@ -575,17 +575,17 @@ void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* cli lua_pushinteger(L, extra_data); lua_setfield(L, -2, "slot_id"); - lua_pushboolean(L, *reinterpret_cast(extra_pointers->at(1))); + lua_pushboolean(L, *EQEmu::any_cast(extra_pointers->at(1))); lua_setfield(L, -2, "destroyed"); } void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { } //Spell void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(npc) { Lua_Mob l_npc(npc); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); @@ -602,7 +602,7 @@ void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* lua_setfield(L, -2, "target"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "buff_slot"); lua_pushinteger(L, extra_data); @@ -610,7 +610,7 @@ void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* } void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(npc) { Lua_Mob l_npc(npc); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); @@ -627,13 +627,13 @@ void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* cli lua_setfield(L, -2, "target"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "tics_remaining"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(1))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(1))); lua_setfield(L, -2, "caster_level"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(2))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(2))); lua_setfield(L, -2, "buff_slot"); lua_pushinteger(L, extra_data); @@ -641,7 +641,7 @@ void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* cli } void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(npc) { Lua_Mob l_npc(npc); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); @@ -661,12 +661,12 @@ void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* cl lua_pushinteger(L, extra_data); lua_setfield(L, -2, "buff_slot"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "caster_id"); } void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(npc) { Lua_Mob l_npc(npc); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); @@ -685,7 +685,7 @@ void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Cl } void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { } #endif diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 8272e30c3..32a59e0da 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -2,128 +2,128 @@ #define _EQE_LUA_PARSER_EVENTS_H #ifdef LUA_EQEMU -typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector*); -typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector*); -typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector*); -typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector*); +typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector*); +typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector*); +typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector*); +typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector*); //NPC void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_area(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); //Player void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_fish_forage_success(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_click_object(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_click_door(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_signal(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_popup_response(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_pick_up(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_task_fail(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_zone(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_duel_win(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_duel_loss(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_loot(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_feign(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_area(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); //Item void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); //Spell void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); #endif #endif diff --git a/zone/object.cpp b/zone/object.cpp index a2c418b40..c560191f1 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -465,7 +465,7 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) char buf[10]; snprintf(buf, 9, "%u", m_inst->GetItem()->ID); buf[9] = '\0'; - std::vector args; + std::vector args; args.push_back(m_inst); parse->EventPlayer(EVENT_PLAYER_PICKUP, sender, buf, 0, &args); diff --git a/zone/quest_interface.h b/zone/quest_interface.h index 8e3e3a93e..68c79923f 100644 --- a/zone/quest_interface.h +++ b/zone/quest_interface.h @@ -20,6 +20,7 @@ #define _EQE_QUESTINTERFACE_H #include "../common/types.h" +#include "../common/any.h" #include "event_codes.h" class ItemInst; @@ -29,19 +30,19 @@ class NPC; class QuestInterface { public: virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual bool HasQuestSub(uint32 npcid, QuestEventID evt) { return false; } virtual bool HasGlobalQuestSub(QuestEventID evt) { return false; } @@ -60,13 +61,13 @@ public: virtual void LoadEncounterScript(std::string filename, std::string encounter_name) { } virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual void AddVar(std::string name, std::string val) { } virtual std::string GetVar(std::string name) { return std::string(); } diff --git a/zone/quest_parser_collection.cpp b/zone/quest_parser_collection.cpp index 8fc0f9c43..10703c299 100644 --- a/zone/quest_parser_collection.cpp +++ b/zone/quest_parser_collection.cpp @@ -234,7 +234,7 @@ bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) { } int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int rd = DispatchEventNPC(evt, npc, init, data, extra_data, extra_pointers); int rl = EventNPCLocal(evt, npc, init, data, extra_data, extra_pointers); int rg = EventNPCGlobal(evt, npc, init, data, extra_data, extra_pointers); @@ -252,7 +252,7 @@ int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std:: } int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { std::map::iterator iter = _npc_quest_status.find(npc->GetNPCTypeID()); if(iter != _npc_quest_status.end()) { //loaded or failed to load @@ -275,7 +275,7 @@ int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, } int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) { std::map::iterator qiter = _interfaces.find(_global_npc_quest_status); return qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data, extra_pointers); @@ -294,7 +294,7 @@ int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, } int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int rd = DispatchEventPlayer(evt, client, data, extra_data, extra_pointers); int rl = EventPlayerLocal(evt, client, data, extra_data, extra_pointers); int rg = EventPlayerGlobal(evt, client, data, extra_data, extra_pointers); @@ -312,7 +312,7 @@ int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::st } int QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(_player_quest_status == QuestUnloaded) { std::string filename; QuestInterface *qi = GetQIByPlayerQuest(filename); @@ -331,7 +331,7 @@ int QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, st } int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(_global_player_quest_status == QuestUnloaded) { std::string filename; QuestInterface *qi = GetQIByGlobalPlayerQuest(filename); @@ -350,7 +350,7 @@ int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, s } int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { std::string item_script; if(item->GetItem()->ScriptFileID != 0) { item_script = "script_"; @@ -396,7 +396,7 @@ int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst } int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { std::map::iterator iter = _spell_quest_status.find(spell_id); if(iter != _spell_quest_status.end()) { //loaded or failed to load @@ -431,7 +431,7 @@ int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client } int QuestParserCollection::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { auto iter = _encounter_quest_status.find(encounter_name); if(iter != _encounter_quest_status.end()) { //loaded or failed to load @@ -974,7 +974,7 @@ void QuestParserCollection::GetErrors(std::list &err) { } int QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int ret = 0; auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { @@ -988,7 +988,7 @@ int QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *ini } int QuestParserCollection::DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int ret = 0; auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { @@ -1002,7 +1002,7 @@ int QuestParserCollection::DispatchEventPlayer(QuestEventID evt, Client *client, } int QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, - uint32 extra_data, std::vector *extra_pointers) { + uint32 extra_data, std::vector *extra_pointers) { int ret = 0; auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { @@ -1016,7 +1016,7 @@ int QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, I } int QuestParserCollection::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int ret = 0; auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { diff --git a/zone/quest_parser_collection.h b/zone/quest_parser_collection.h index 902500231..006bcfe24 100644 --- a/zone/quest_parser_collection.h +++ b/zone/quest_parser_collection.h @@ -51,15 +51,15 @@ public: bool ItemHasQuestSub(ItemInst *itm, QuestEventID evt); int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); void GetErrors(std::list &err); @@ -69,10 +69,10 @@ private: bool PlayerHasQuestSubLocal(QuestEventID evt); bool PlayerHasQuestSubGlobal(QuestEventID evt); - int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); - int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); - int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); - int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); + int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); + int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); + int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); + int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); QuestInterface *GetQIByNPCQuest(uint32 npcid, std::string &filename); QuestInterface *GetQIByGlobalNPCQuest(std::string &filename); @@ -83,13 +83,13 @@ private: QuestInterface *GetQIByEncounterQuest(std::string encounter_name, std::string &filename); int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); std::map _interfaces; std::map _extensions; diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index bb1c3c449..b10c436f2 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -139,7 +139,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) if(IsNPC()) { - std::vector args; + std::vector args; args.push_back(&buffslot); int i = parse->EventSpell(EVENT_SPELL_EFFECT_NPC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0, &args); if(i != 0){ @@ -149,7 +149,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) } else if(IsClient()) { - std::vector args; + std::vector args; args.push_back(&buffslot); int i = parse->EventSpell(EVENT_SPELL_EFFECT_CLIENT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0, &args); if(i != 0){ @@ -3293,7 +3293,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste if(IsNPC()) { - std::vector args; + std::vector args; args.push_back(&ticsremaining); args.push_back(&caster_level); args.push_back(&slot); @@ -3304,7 +3304,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste } else { - std::vector args; + std::vector args; args.push_back(&ticsremaining); args.push_back(&caster_level); args.push_back(&slot); @@ -3654,12 +3654,12 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses) } if(IsClient()) { - std::vector args; + std::vector args; args.push_back(&buffs[slot].casterid); parse->EventSpell(EVENT_SPELL_FADE, nullptr, CastToClient(), buffs[slot].spellid, slot, &args); } else if(IsNPC()) { - std::vector args; + std::vector args; args.push_back(&buffs[slot].casterid); parse->EventSpell(EVENT_SPELL_FADE, CastToNPC(), nullptr, buffs[slot].spellid, slot, &args); diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index e8e787de0..91cb458a0 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -149,7 +149,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme ItemInst *aug = tobe_auged->GetAugment(slot); if(aug) { - std::vector args; + std::vector args; args.push_back(aug); parse->EventItem(EVENT_AUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args); @@ -171,7 +171,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme const uint32 id = auged_with->GetID(); ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_slot); if(aug) { - std::vector args; + std::vector args; args.push_back(aug); parse->EventItem(EVENT_UNAUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args); diff --git a/zone/trading.cpp b/zone/trading.cpp index 1efcbbb33..75469abdf 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -586,7 +586,7 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) quest_npc = true; } - std::vector item_list; + std::vector item_list; uint32 items[4] = { 0 }; for(int i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_NPC_END; ++i) { ItemInst *inst = m_inv.GetItem(i); From 18a4f831be630adca360763dfbc302f5d3d07767 Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 26 Aug 2014 06:37:40 -0400 Subject: [PATCH 55/89] Tweaked QS code for Client::FinishTrade() and QueryServ handlers. --- changelog.txt | 6 ++++++ common/servertalk.h | 2 ++ queryserv/database.cpp | 12 ++++++------ queryserv/database.h | 4 ++-- queryserv/worldserver.cpp | 6 ++---- zone/client_packet.cpp | 6 ++++-- zone/trading.cpp | 20 ++++++++++++++++++++ 7 files changed, 42 insertions(+), 14 deletions(-) diff --git a/changelog.txt b/changelog.txt index 9172332d9..98e1f0606 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 08/26/2014 == +Uleat: Implemented 'Smart' Player Trade transfers. Trades are processed by containers, stackables and then all remaining. QueryServ logs have been updated to match these transactions. +Note: QueryServ logs previously listed 'Items' on the main entry table. This indicated the number of slots affected and not the actual number of items. +This field now indicates the actual number of items transferred. For non-stackable, the value is '1' and stackable is the number of charges. A _detail_count +property has been added to both 'Trade' and 'Handin' structs to indicate the number of details recorded..though, not tracked..it could be added. + == 08/24/2014 == Uleat: Fix (attempted) for zone crashes related to zone shut-down. This change disables all Mob AI and disables/deletes all Mob timers once Zone::ShutDown() is called. More areas will be addressed as reports come in. Note: Perl and Lua quests tested to work..please post any aberrant behavior. (I finally set my spell-check to US English...) diff --git a/common/servertalk.h b/common/servertalk.h index 6d1a83a84..5337b6b1d 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -1118,6 +1118,7 @@ struct QSPlayerLogTrade_Struct { uint32 char2_id; MoneyUpdate_Struct char2_money; uint16 char2_count; + uint16 _detail_count; QSTradeItems_Struct items[0]; }; @@ -1141,6 +1142,7 @@ struct QSPlayerLogHandin_Struct { uint32 npc_id; MoneyUpdate_Struct npc_money; uint16 npc_count; + uint16 _detail_count; QSHandinItems_Struct items[0]; }; diff --git a/queryserv/database.cpp b/queryserv/database.cpp index 4b94f215b..cfc4a8892 100644 --- a/queryserv/database.cpp +++ b/queryserv/database.cpp @@ -119,7 +119,7 @@ void Database::AddSpeech(const char* from, const char* to, const char* message, safe_delete_array(S3); } -void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) { +void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount) { char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; @@ -134,8 +134,8 @@ void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) { _log(QUERYSERV__ERROR, "%s", query); } - if(Items > 0) { - for(int i = 0; i < Items; i++) { + if(DetailCount > 0) { + for(int i = 0; i < DetailCount; i++) { if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_trade_record_entries` SET `event_id`='%i', " "`from_id`='%i', `from_slot`='%i', `to_id`='%i', `to_slot`='%i', `item_id`='%i', " "`charges`='%i', `aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'", @@ -149,7 +149,7 @@ void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) { } } -void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) { +void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount) { char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; uint32 lastid = 0; @@ -163,8 +163,8 @@ void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) { _log(QUERYSERV__ERROR, "%s", query); } - if(Items > 0) { - for(int i = 0; i < Items; i++) { + if(DetailCount > 0) { + for(int i = 0; i < DetailCount; i++) { if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_handin_record_entries` SET `event_id`='%i', " "`action_type`='%s', `char_slot`='%i', `item_id`='%i', `charges`='%i', " "`aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'", diff --git a/queryserv/database.h b/queryserv/database.h index ac002a0b5..a25d91611 100644 --- a/queryserv/database.h +++ b/queryserv/database.h @@ -43,8 +43,8 @@ public: ~Database(); void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type); - void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items); - void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items); + void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount); + void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount); void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members); void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items); void LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items); diff --git a/queryserv/worldserver.cpp b/queryserv/worldserver.cpp index 154db3a07..fc87929ca 100644 --- a/queryserv/worldserver.cpp +++ b/queryserv/worldserver.cpp @@ -80,14 +80,12 @@ void WorldServer::Process() } case ServerOP_QSPlayerLogTrades: { QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)pack->pBuffer; - uint32 Items = QS->char1_count + QS->char2_count; - database.LogPlayerTrade(QS, Items); + database.LogPlayerTrade(QS, QS->_detail_count); break; } case ServerOP_QSPlayerLogHandins: { QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)pack->pBuffer; - uint32 Items = QS->char_count + QS->npc_count; - database.LogPlayerHandin(QS, Items); + database.LogPlayerHandin(QS, QS->_detail_count); break; } case ServerOP_QSPlayerLogNPCKills: { diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 8d39f815a..76c873711 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4898,8 +4898,9 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) this->FinishTrade(other, true, &event_entry, &event_details); other->FinishTrade(this, false, &event_entry, &event_details); - ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogTrades, sizeof(QSPlayerLogTrade_Struct)+(sizeof(QSTradeItems_Struct)* event_details.size())); + event_entry._detail_count = event_details.size(); + ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogTrades, sizeof(QSPlayerLogTrade_Struct)+(sizeof(QSTradeItems_Struct)* event_entry._detail_count)); QSPlayerLogTrade_Struct* qs_buf = (QSPlayerLogTrade_Struct*)qs_pack->pBuffer; memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogTrade_Struct)); @@ -4951,8 +4952,9 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) FinishTrade(with->CastToNPC(), false, &event_entry, &event_details); - ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogHandins, sizeof(QSPlayerLogHandin_Struct)+(sizeof(QSHandinItems_Struct)* event_details.size())); + event_entry._detail_count = event_details.size(); + ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogHandins, sizeof(QSPlayerLogHandin_Struct)+(sizeof(QSHandinItems_Struct)* event_entry._detail_count)); QSPlayerLogHandin_Struct* qs_buf = (QSPlayerLogHandin_Struct*)qs_pack->pBuffer; memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogHandin_Struct)); diff --git a/zone/trading.cpp b/zone/trading.cpp index 88b277651..23d8d77af 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -656,6 +656,8 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st if (!bias_inst || (bias_inst->GetID() != inst->GetID()) || (bias_inst->GetCharges() >= bias_inst->GetItem()->StackSize)) continue; + int16 old_charges = inst->GetCharges(); + if ((bias_inst->GetCharges() + inst->GetCharges()) > bias_inst->GetItem()->StackSize) { int16 new_charges = (bias_inst->GetCharges() + inst->GetCharges()) - bias_inst->GetItem()->StackSize; @@ -667,6 +669,24 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st inst->SetCharges(0); } + if (qs_log) { + QSTradeItems_Struct* detail = new QSTradeItems_Struct; + + detail->from_id = this->character_id; + detail->from_slot = trade_slot; + detail->to_id = this->character_id; + detail->to_slot = bias_slot; + detail->item_id = inst->GetID(); + detail->charges = (old_charges - inst->GetCharges()); + detail->aug_1 = 0; + detail->aug_2 = 0; + detail->aug_3 = 0; + detail->aug_4 = 0; + detail->aug_5 = 0; + + event_details->push_back(detail); + } + if (inst->GetCharges() == 0) { DeleteItemInInventory(trade_slot); break; From dedd1fc70df5162653fc3417e3e27a7ec1001ac4 Mon Sep 17 00:00:00 2001 From: akkadius Date: Wed, 27 Aug 2014 14:26:36 -0500 Subject: [PATCH 56/89] NPC::ModifyNPCStat function bloat cleanup --- zone/npc.cpp | 283 ++++++++------------------------------------------- 1 file changed, 40 insertions(+), 243 deletions(-) diff --git a/zone/npc.cpp b/zone/npc.cpp index f70c1e847..151852a2b 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -1787,252 +1787,49 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue) { std::string id = identifier; std::string val = newValue; - for(int i = 0; i < id.length(); ++i) - { + for(int i = 0; i < id.length(); ++i) { id[i] = std::tolower(id[i]); } - if(id == "ac") - { - AC = atoi(val.c_str()); - return; - } - - if(id == "str") - { - STR = atoi(val.c_str()); - return; - } - - if(id == "sta") - { - STA = atoi(val.c_str()); - return; - } - - if(id == "agi") - { - AGI = atoi(val.c_str()); - return; - } - - if(id == "dex") - { - DEX = atoi(val.c_str()); - return; - } - - if(id == "wis") - { - WIS = atoi(val.c_str()); - CalcMaxMana(); - return; - } - - if(id == "int" || id == "_int") - { - INT = atoi(val.c_str()); - CalcMaxMana(); - return; - } - - if(id == "cha") - { - CHA = atoi(val.c_str()); - return; - } - - if(id == "max_hp") - { - base_hp = atoi(val.c_str()); - CalcMaxHP(); - if(cur_hp > max_hp) - cur_hp = max_hp; - return; - } - - if(id == "max_mana") - { - npc_mana = atoi(val.c_str()); - CalcMaxMana(); - if(cur_mana > max_mana) - cur_mana = max_mana; - return; - } - - if(id == "mr") - { - MR = atoi(val.c_str()); - return; - } - - if(id == "fr") - { - FR = atoi(val.c_str()); - return; - } - - if(id == "cr") - { - CR = atoi(val.c_str()); - return; - } - - if(id == "pr") - { - PR = atoi(val.c_str()); - return; - } - - if(id == "dr") - { - DR = atoi(val.c_str()); - return; - } - - if(id == "PhR") - { - PhR = atoi(val.c_str()); - return; - } - - if(id == "runspeed") - { - runspeed = (float)atof(val.c_str()); - CalcBonuses(); - return; - } - - if(id == "special_attacks") - { - //Added reset flag. - NPCSpecialAttacks(val.c_str(), 0, 1); - return; - } - - if(id == "attack_speed") - { - attack_speed = (float)atof(val.c_str()); - CalcBonuses(); - return; - } - - if(id == "atk") - { - ATK = atoi(val.c_str()); - return; - } - - if(id == "accuracy") - { - accuracy_rating = atoi(val.c_str()); - return; - } - - if(id == "avoidance") - { - avoidance_rating = atoi(val.c_str()); - return; - } - - if(id == "trackable") - { - trackable = atoi(val.c_str()); - return; - } - - if(id == "min_hit") - { - min_dmg = atoi(val.c_str()); - return; - } - - if(id == "max_hit") - { - max_dmg = atoi(val.c_str()); - return; - } - - if(id == "attack_count") - { - attack_count = atoi(val.c_str()); - return; - } - - if(id == "see_invis") - { - see_invis = atoi(val.c_str()); - return; - } - - if(id == "see_invis_undead") - { - see_invis_undead = atoi(val.c_str()); - return; - } - - if(id == "see_hide") - { - see_hide = atoi(val.c_str()); - return; - } - - if(id == "see_improved_hide") - { - see_improved_hide = atoi(val.c_str()); - return; - } - - if(id == "hp_regen") - { - hp_regen = atoi(val.c_str()); - return; - } - - if(id == "mana_regen") - { - mana_regen = atoi(val.c_str()); - return; - } - - if(id == "level") - { - SetLevel(atoi(val.c_str())); - return; - } - - if(id == "aggro") - { - pAggroRange = atof(val.c_str()); - return; - } - - if(id == "assist") - { - pAssistRange = atof(val.c_str()); - return; - } - - if(id == "slow_mitigation") - { - slow_mitigation = atoi(val.c_str()); - return; - } - if(id == "loottable_id") - { - loottable_id = atof(val.c_str()); - return; - } - if(id == "healscale") - { - healscale = atof(val.c_str()); - return; - } - if(id == "spellscale") - { - spellscale = atof(val.c_str()); - return; - } + if(id == "ac") { AC = atoi(val.c_str()); return; } + else if(id == "str") { STR = atoi(val.c_str()); return; } + else if(id == "sta") { STA = atoi(val.c_str()); return; } + else if(id == "agi") { AGI = atoi(val.c_str()); return; } + else if(id == "dex") { DEX = atoi(val.c_str()); return; } + else if(id == "wis") { WIS = atoi(val.c_str()); CalcMaxMana(); return; } + else if(id == "int" || id == "_int") { INT = atoi(val.c_str()); CalcMaxMana(); return; } + else if(id == "cha") { CHA = atoi(val.c_str()); return; } + else if(id == "max_hp") { base_hp = atoi(val.c_str()); CalcMaxHP(); if (cur_hp > max_hp) { cur_hp = max_hp; } return; } + else if(id == "max_mana") { npc_mana = atoi(val.c_str()); CalcMaxMana(); if (cur_mana > max_mana){ cur_mana = max_mana; } return; } + else if(id == "mr") { MR = atoi(val.c_str()); return; } + else if(id == "fr") { FR = atoi(val.c_str()); return; } + else if(id == "cr") { CR = atoi(val.c_str()); return; } + else if(id == "pr") { PR = atoi(val.c_str()); return; } + else if(id == "dr") { DR = atoi(val.c_str()); return; } + else if(id == "PhR") { PhR = atoi(val.c_str()); return; } + else if(id == "runspeed") { runspeed = (float)atof(val.c_str()); CalcBonuses(); return; } + else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; } + else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; } + else if(id == "atk") { ATK = atoi(val.c_str()); return; } + else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; } + else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; } + else if(id == "trackable") { trackable = atoi(val.c_str()); return; } + else if(id == "min_hit") { min_dmg = atoi(val.c_str()); return; } + else if(id == "max_hit") { max_dmg = atoi(val.c_str()); return; } + else if(id == "attack_count") { attack_count = atoi(val.c_str()); return; } + else if(id == "see_invis") { see_invis = atoi(val.c_str()); return; } + else if(id == "see_invis_undead") { see_invis_undead = atoi(val.c_str()); return; } + else if(id == "see_hide") { see_hide = atoi(val.c_str()); return; } + else if(id == "see_improved_hide") { see_improved_hide = atoi(val.c_str()); return; } + else if(id == "hp_regen") { hp_regen = atoi(val.c_str()); return; } + else if(id == "mana_regen") { mana_regen = atoi(val.c_str()); return; } + else if(id == "level") { SetLevel(atoi(val.c_str())); return; } + else if(id == "aggro") { pAggroRange = atof(val.c_str()); return; } + else if(id == "assist") { pAssistRange = atof(val.c_str()); return; } + else if(id == "slow_mitigation") { slow_mitigation = atoi(val.c_str()); return; } + else if(id == "loottable_id") { loottable_id = atof(val.c_str()); return; } + else if(id == "healscale") { healscale = atof(val.c_str()); return; } + else if(id == "spellscale") { spellscale = atof(val.c_str()); return; } } void NPC::LevelScale() { From 9041891557d685b9da86e32bf9c71ff6f8bc51a4 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Wed, 27 Aug 2014 22:57:03 -0700 Subject: [PATCH 57/89] Fixed crash on expire mail success, messages where switched accidentally --- ucs/database.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ucs/database.cpp b/ucs/database.cpp index d3c44174c..8eb8746b3 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -523,9 +523,10 @@ void Database::ExpireMail() { time(nullptr) - RuleI(Mail, ExpireTrash)); results = QueryDatabase(query); if(!results.Success()) - _log(UCS__INIT, "Expired %i trash messages.", results.RowsAffected()); + _log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); else - _log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); + _log(UCS__INIT, "Expired %i trash messages.", results.RowsAffected()); + } // Expire Read From 9d6dc47cf4d71ea6c12c838dc81f75c458f0d79a Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Thu, 28 Aug 2014 02:15:37 -0400 Subject: [PATCH 58/89] Fix crash with MySQLRequestResult::ErrorMessage() --- common/mysql_request_result.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/mysql_request_result.h b/common/mysql_request_result.h index cd561be56..ab84eeb18 100644 --- a/common/mysql_request_result.h +++ b/common/mysql_request_result.h @@ -40,7 +40,7 @@ public: MySQLRequestResult& operator=(MySQLRequestResult&& other); bool Success() const { return m_Success;} - std::string ErrorMessage() const {return std::string(m_ErrorBuffer);} + std::string ErrorMessage() const {return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");} uint32 ErrorNumber() const {return m_ErrorNumber;} uint32 RowsAffected() const {return m_RowsAffected;} uint32 RowCount() const {return m_RowCount;} From 19271f90a448d3e45418e486f8804fd11f10c9b4 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 28 Aug 2014 03:17:47 -0700 Subject: [PATCH 59/89] Crash fixes --- client_files/export/main.cpp | 8 ++++++-- common/database.cpp | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/client_files/export/main.cpp b/client_files/export/main.cpp index c4faa4718..e9b127aad 100644 --- a/client_files/export/main.cpp +++ b/client_files/export/main.cpp @@ -81,7 +81,9 @@ void ExportSpells(SharedDatabase *db) { line.push_back('^'); } - line += row[i]; + if(row[i] != nullptr) { + line += row[i]; + } } fprintf(f, "%s\n", line.c_str()); @@ -180,7 +182,9 @@ void ExportBaseData(SharedDatabase *db) { if(rowIndex != 0) line.push_back('^'); - line += row[rowIndex]; + if(row[rowIndex] != nullptr) { + line += row[rowIndex]; + } } fprintf(f, "%s\n", line.c_str()); diff --git a/common/database.cpp b/common/database.cpp index 8d27d5b46..0787f396a 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -161,6 +161,9 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat return 0; } + if(results.RowCount() < 1) + return 0; + auto row = results.begin(); uint32 id = atoi(row[0]); From ca84040a3939b71e835701e2cc52fe199e386382 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 28 Aug 2014 03:47:28 -0700 Subject: [PATCH 60/89] Crash fixes oh my --- common/database.cpp | 2 +- common/mysql_request_row.cpp | 1 - common/shareddb.cpp | 7 +++++++ common/spdat.h | 2 ++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 0787f396a..b99eac2ea 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -161,7 +161,7 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat return 0; } - if(results.RowCount() < 1) + if(results.RowCount() == 0) return 0; auto row = results.begin(); diff --git a/common/mysql_request_row.cpp b/common/mysql_request_row.cpp index ac5fa1592..9491fd1b2 100644 --- a/common/mysql_request_row.cpp +++ b/common/mysql_request_row.cpp @@ -64,6 +64,5 @@ bool MySQLRequestRow::operator!=(const MySQLRequestRow& rhs) char* MySQLRequestRow::operator[](int index) { - return m_MySQLRow[index]; } diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 8e999da54..58a75a261 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1632,6 +1632,13 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { int tempid = 0; int counter = 0; + + if(result && mysql_field_count(getMySQL()) <= SPELL_LOAD_FIELD_COUNT) { + _log(SPELLS__LOAD_ERR, "Fatal error loading spells: Spell field count < SPELL_LOAD_FIELD_COUNT(%u)", SPELL_LOAD_FIELD_COUNT); + mysql_free_result(result); + return; + } + while (row = mysql_fetch_row(result)) { tempid = atoi(row[0]); if(tempid >= max_spells) { diff --git a/common/spdat.h b/common/spdat.h index 40f5e658f..2dfc016b4 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -621,6 +621,8 @@ typedef enum { // number. note that the id field is counted as 0, this way the numbers // here match the numbers given to sep in the loading function net.cpp // +#define SPELL_LOAD_FIELD_COUNT 231 + struct SPDat_Spell_Struct { /* 000 */ int id; // not used From 11ed698642853cd2e708fa7fafcbda584509f604 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 30 Aug 2014 01:38:49 -0400 Subject: [PATCH 61/89] (noudess) Merchants are more descriptive in their rejections --- changelog.txt | 3 ++ zone/client.cpp | 76 +++++++++++++++++++++++++++++++----------- zone/client.h | 2 +- zone/client_packet.cpp | 33 ++++-------------- zone/string_ids.h | 18 ++++++++++ 5 files changed, 85 insertions(+), 47 deletions(-) diff --git a/changelog.txt b/changelog.txt index 98e1f0606..41d858899 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 08/30/2014 == +demonstar55: (noudess) Merchants should be more descriptive of why they don't sell to you + == 08/26/2014 == Uleat: Implemented 'Smart' Player Trade transfers. Trades are processed by containers, stackables and then all remaining. QueryServ logs have been updated to match these transactions. Note: QueryServ logs previously listed 'Items' on the main entry table. This indicated the number of slots affected and not the actual number of items. diff --git a/zone/client.cpp b/zone/client.cpp index 37740b472..222acc094 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7773,29 +7773,67 @@ int32 Client::GetModCharacterFactionLevel(int32 faction_id) { return Modded; } -bool Client::HatedByClass(uint32 p_race, uint32 p_class, uint32 p_deity, int32 pFaction) +void Client::MerchantRejectMessage(Mob *merchant, int primaryfaction) { + int messageid = 0; + int32 tmpFactionValue = 0; + int32 lowestvalue = 0; + FactionMods fmod; - bool Result = false; - - int32 tmpFactionValue; - FactionMods fmods; - - //First get the NPC's Primary faction - if(pFaction > 0) - { - //Get the faction data from the database - if(database.GetFactionData(&fmods, p_class, p_race, p_deity, pFaction)) - { - tmpFactionValue = GetCharacterFactionLevel(pFaction); - tmpFactionValue += GetFactionBonus(pFaction); - tmpFactionValue += GetItemFactionBonus(pFaction); - CalculateFaction(&fmods, tmpFactionValue); - if(fmods.class_mod < fmods.race_mod) - Result = true; + // If a faction is involved, get the data. + if (primaryfaction > 0) { + if (database.GetFactionData(&fmod, GetClass(), GetRace(), GetDeity(), primaryfaction)) { + tmpFactionValue = GetCharacterFactionLevel(primaryfaction); + lowestvalue = std::min(tmpFactionValue, std::min(fmod.class_mod, fmod.race_mod)); } } - return Result; + // If no primary faction or biggest influence is your faction hit + if (primaryfaction <= 0 || lowestvalue == tmpFactionValue) { + merchant->Say_StringID(MakeRandomInt(WONT_SELL_DEEDS1, WONT_SELL_DEEDS6)); + } else if (lowestvalue == fmod.race_mod) { // race biggest + // Non-standard race (ex. illusioned to wolf) + if (GetRace() > PLAYER_RACE_COUNT) { + messageid = MakeRandomInt(1, 3); // these aren't sequential StringIDs :( + switch (messageid) { + case 1: + messageid = WONT_SELL_NONSTDRACE1; + break; + case 2: + messageid = WONT_SELL_NONSTDRACE2; + break; + case 3: + messageid = WONT_SELL_NONSTDRACE3; + break; + default: // w/e should never happen + messageid = WONT_SELL_NONSTDRACE1; + break; + } + merchant->Say_StringID(messageid); + } else { // normal player races + messageid = MakeRandomInt(1, 4); + switch (messageid) { + case 1: + messageid = WONT_SELL_RACE1; + break; + case 2: + messageid = WONT_SELL_RACE2; + break; + case 3: + messageid = WONT_SELL_RACE3; + break; + case 4: + messageid = WONT_SELL_RACE4; + break; + default: // w/e should never happen + messageid = WONT_SELL_RACE1; + break; + } + merchant->Say_StringID(messageid, itoa(GetRace())); + } + } else if (lowestvalue == fmod.class_mod) { + merchant->Say_StringID(MakeRandomInt(WONT_SELL_CLASS1, WONT_SELL_CLASS5), itoa(GetClass())); + } + return; } //o-------------------------------------------------------------- diff --git a/zone/client.h b/zone/client.h index d3aed5540..6c298ba15 100644 --- a/zone/client.h +++ b/zone/client.h @@ -594,7 +594,7 @@ public: FACTION_VALUE GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 p_race, uint32 p_class, uint32 p_deity, int32 pFaction, Mob* tnpc); int32 GetCharacterFactionLevel(int32 faction_id); int32 GetModCharacterFactionLevel(int32 faction_id); - bool HatedByClass(uint32 p_race, uint32 p_class, uint32 p_deity, int32 pFaction); + void MerchantRejectMessage(Mob *merchant, int primaryfaction); void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 totalvalue, uint8 temp); void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 4314b1c5a..9fffc6a9b 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -5426,36 +5426,15 @@ void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app) Message(0,"You cannot use a merchant right now."); action = 0; } - int factionlvl = GetFactionLevel(CharacterID(), tmp->CastToNPC()->GetNPCTypeID(), GetRace(), GetClass(), GetDeity(), tmp->CastToNPC()->GetPrimaryFaction(), tmp); - if(factionlvl >= 7) - { - char playerp[16] = "players"; - if(HatedByClass(GetRace(), GetClass(), GetDeity(), tmp->CastToNPC()->GetPrimaryFaction())) - strcpy(playerp,GetClassPlural(this)); - else - strcpy(playerp,GetRacePlural(this)); + int primaryfaction = tmp->CastToNPC()->GetPrimaryFaction(); + int factionlvl = GetFactionLevel(CharacterID(), tmp->CastToNPC()->GetNPCTypeID(), GetRace(), GetClass(), GetDeity(), primaryfaction, tmp); + if (factionlvl >= 7) { + MerchantRejectMessage(tmp, primaryfaction); + action = 0; + } - uint8 rand_ = rand() % 4; - switch(rand_){ - case 1: - Message(0,"%s says 'It's not enough that you %s have ruined your own lands. Now get lost!'", tmp->GetCleanName(), playerp); - break; - case 2: - Message(0,"%s says 'I have something here that %s use... let me see... it's the EXIT, now get LOST!'", tmp->GetCleanName(), playerp); - break; - case 3: - Message(0,"%s says 'Don't you %s have your own merchants? Whatever, I'm not selling anything to you!'", tmp->GetCleanName(), playerp); - break; - default: - Message(0,"%s says 'I don't like to speak to %s much less sell to them!'", tmp->GetCleanName(), playerp); - break; - } - action = 0; - } if (tmp->Charmed()) - { action = 0; - } // 1199 I don't have time for that now. etc if (!tmp->CastToNPC()->IsMerchantOpen()) { diff --git a/zone/string_ids.h b/zone/string_ids.h index b1e13edca..056513874 100644 --- a/zone/string_ids.h +++ b/zone/string_ids.h @@ -205,6 +205,24 @@ #define MERCHANT_HANDY_ITEM2 1146 //Greetings, %3. You look like you could use a %4. #define MERCHANT_HANDY_ITEM3 1147 //Hi there %3, just browsing? Have you seen the %4 I just got in? #define MERCHANT_HANDY_ITEM4 1148 //Welcome to my shop, %3. You would probably find a %4 handy. +#define WONT_SELL_RACE1 1154 //I don't like to speak to %B3(12) much less sell to them! +#define WONT_SELL_CLASS1 1155 //It's %B3(13) like you that are ruining the continent...get OUT! +#define WONT_SELL_CLASS2 1156 //Isn't there some kind of ordinance against %B3(13) crawling out from under their rocks? +#define WONT_SELL_CLASS3 1157 //%B3(13) like you don't have any place in my shop..now make way for welcome customers. +#define WONT_SELL_CLASS4 1158 //I thought scumbag %B3(13) like you just stole whatever they need. Now GET OUT! +#define WONT_SELL_CLASS5 1159 //I don't have anything to do with %B3(13)..move along. +#define WONT_SELL_NONSTDRACE1 1160 //I don't have anything to do with your little gang..move along. +#define WONT_SELL_RACE2 1161 //It's not enough that you %B3(12) have ruined your own land. Now get lost! +#define WONT_SELL_RACE3 1162 //I have something here that %B3(12) use..let me see...it's the EXIT, now get LOST! +#define WONT_SELL_RACE4 1163 //Don't you %B3(12) have your own merchants? Whatever, I'm not selling anything to you! +#define WONT_SELL_NONSTDRACE2 1164 //Members of your little "club" have ruined things around here..get lost! +#define WONT_SELL_NONSTDRACE3 1165 //I don't have anything to do with your damned club..move along. +#define WONT_SELL_DEEDS1 1166 //Creatures like you make me sick..the things you do..get out of here Pagan! +#define WONT_SELL_DEEDS2 1167 //After all the things you've done..the things you believe in..leave my shop! +#define WONT_SELL_DEEDS3 1168 //Actions speak louder than beliefs, and I despise both your actions and all you believe in. +#define WONT_SELL_DEEDS4 1169 //Get out of here now! +#define WONT_SELL_DEEDS5 1170 //I am tolerant by nature..but infidels like you push me past my limit..get out! +#define WONT_SELL_DEEDS6 1171 //I cannot abide you or your actions against all that is right..BE GONE! #define AA_POINT 1197 //point #define AA_POINTS 1215 //points #define SPELL_FIZZLE_OTHER 1218 //%1's spell fizzles! From 04dc593df9e1c6ef231f2e9ce39879c7f3edf2ba Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 31 Aug 2014 20:27:02 -0700 Subject: [PATCH 62/89] Various bug fixes --- changelog.txt | 6 ++++++ ucs/database.cpp | 6 +++--- zone/client_packet.cpp | 2 +- zone/embparser.cpp | 4 +++- zone/entity.cpp | 3 ++- zone/forage.cpp | 18 +++++++++--------- zone/lua_entity_list.cpp | 8 +++++++- zone/lua_entity_list.h | 1 + zone/lua_general.cpp | 8 +------- zone/lua_parser_events.cpp | 7 +++++-- zone/trading.cpp | 2 +- 11 files changed, 39 insertions(+), 26 deletions(-) diff --git a/changelog.txt b/changelog.txt index 41d858899..de7572176 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 08/31/2014 == +KLS: Fixed a bug in fishing in S3D zones +KLS: Fixed a bug in turnins with new any abstraction +KLS: Fixed a few quest related inconsistencies. +KLS: Added Lua EntityList::ChannelMessage(from, type, msg, language) + == 08/30/2014 == demonstar55: (noudess) Merchants should be more descriptive of why they don't sell to you diff --git a/ucs/database.cpp b/ucs/database.cpp index 8eb8746b3..a2f61c438 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -522,7 +522,7 @@ void Database::ExpireMail() { query = StringFormat("DELETE FROM `mail` WHERE `status`=4 AND `timestamp` < %i", time(nullptr) - RuleI(Mail, ExpireTrash)); results = QueryDatabase(query); - if(!results.Success()) + if(results.Success()) _log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); else _log(UCS__INIT, "Expired %i trash messages.", results.RowsAffected()); @@ -534,7 +534,7 @@ void Database::ExpireMail() { query = StringFormat("DELETE FROM `mail` WHERE `status` = 3 AND `timestamp` < %i", time(nullptr) - RuleI(Mail, ExpireRead)); results = QueryDatabase(query); - if(!results.Success()) + if(results.Success()) _log(UCS__INIT, "Expired %i read messages.", results.RowsAffected()); else _log(UCS__ERROR, "Error expiring read messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); @@ -545,7 +545,7 @@ void Database::ExpireMail() { query = StringFormat("DELETE FROM `mail` WHERE `status`=1 AND `timestamp` < %i", time(nullptr) - RuleI(Mail, ExpireUnread)); results = QueryDatabase(query); - if(!results.Success()) + if(results.Success()) _log(UCS__INIT, "Expired %i unread messages.", results.RowsAffected()); else _log(UCS__ERROR, "Error expiring unread messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 9fffc6a9b..d56d8386a 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -6225,7 +6225,7 @@ void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app) if(!currentdoor) { Message(0,"Unable to find door, please notify a GM (DoorID: %i).",cd->doorid); - return; + return; } char buf[20]; diff --git a/zone/embparser.cpp b/zone/embparser.cpp index f577bcb11..c7a67c388 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -1130,8 +1130,10 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID case EVENT_TRADE: { if(extra_pointers) { - for(size_t i = 0; i < extra_pointers->size(); ++i) { + size_t sz = extra_pointers->size(); + for(size_t i = 0; i < sz; ++i) { ItemInst *inst = EQEmu::any_cast(extra_pointers->at(i)); + std::string var_name = "item"; var_name += std::to_string(static_cast(i + 1)); diff --git a/zone/entity.cpp b/zone/entity.cpp index 16fbe7077..7054ba8a1 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -3242,7 +3242,8 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z) for (auto iter = events.begin(); iter != events.end(); ++iter) { quest_proximity_event& evt = (*iter); if (evt.npc) { - parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0); + std::vector args; + parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0, &args); } else { std::vector args; args.push_back(&evt.area_id); diff --git a/zone/forage.cpp b/zone/forage.cpp index e85cbda4a..4a39d508d 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -235,7 +235,7 @@ bool Client::CanFish() { dest.y = RodY; dest.z = z_pos+10; - RodZ = zone->zonemap->FindBestZ(dest, nullptr) - 1; + RodZ = zone->zonemap->FindBestZ(dest, nullptr) + 4; bool in_lava = zone->watermap->InLava(RodX, RodY, RodZ); bool in_water = zone->watermap->InWater(RodX, RodY, RodZ) || zone->watermap->InVWater(RodX, RodY, RodZ); //Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava); @@ -355,11 +355,11 @@ void Client::GoFish() safe_delete(inst); inst = m_inv.GetItem(MainCursor); } - } - std::vector args; - args.push_back(inst); - parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst != nullptr ? inst->GetItem()->ID : 0, &args); + std::vector args; + args.push_back(inst); + parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst->GetID(), &args); + } } else { @@ -469,11 +469,11 @@ void Client::ForageItem(bool guarantee) { safe_delete(inst); inst = m_inv.GetItem(MainCursor); } - } - std::vector args; - args.push_back(inst); - parse->EventPlayer(EVENT_FORAGE_SUCCESS, this, "", inst ? inst->GetItem()->ID : 0, &args); + std::vector args; + args.push_back(inst); + parse->EventPlayer(EVENT_FORAGE_SUCCESS, this, "", inst->GetID(), &args); + } int ChanceSecondForage = aabonuses.ForageAdditionalItems + itembonuses.ForageAdditionalItems + spellbonuses.ForageAdditionalItems; if(!guarantee && MakeRandomInt(0,99) < ChanceSecondForage) { diff --git a/zone/lua_entity_list.cpp b/zone/lua_entity_list.cpp index 32bd9a89d..eace84a69 100644 --- a/zone/lua_entity_list.cpp +++ b/zone/lua_entity_list.cpp @@ -416,6 +416,11 @@ void Lua_EntityList::SignalAllClients(int signal) { self->SignalAllClients(signal); } +void Lua_EntityList::ChannelMessage(Lua_Mob from, int channel_num, int language, const char *message) { + Lua_Safe_Call_Void(); + self->ChannelMessage(from, channel_num, language, message); +} + luabind::scope lua_register_entity_list() { return luabind::class_("EntityList") .def(luabind::constructor<>()) @@ -479,7 +484,8 @@ luabind::scope lua_register_entity_list() { .def("GetObjectList", (Lua_Object_List(Lua_EntityList::*)(void))&Lua_EntityList::GetObjectList) .def("GetDoorsList", (Lua_Doors_List(Lua_EntityList::*)(void))&Lua_EntityList::GetDoorsList) .def("GetSpawnList", (Lua_Spawn_List(Lua_EntityList::*)(void))&Lua_EntityList::GetSpawnList) - .def("SignalAllClients", (void(Lua_EntityList::*)(int))&Lua_EntityList::SignalAllClients); + .def("SignalAllClients", (void(Lua_EntityList::*)(int))&Lua_EntityList::SignalAllClients) + .def("ChannelMessage", (void(Lua_EntityList::*)(Lua_Mob,int,int,const char*))&Lua_EntityList::ChannelMessage); } luabind::scope lua_register_mob_list() { diff --git a/zone/lua_entity_list.h b/zone/lua_entity_list.h index dc9c1a5ed..823499f24 100644 --- a/zone/lua_entity_list.h +++ b/zone/lua_entity_list.h @@ -106,6 +106,7 @@ public: Lua_Doors_List GetDoorsList(); Lua_Spawn_List GetSpawnList(); void SignalAllClients(int signal); + void ChannelMessage(Lua_Mob from, int channel_num, int language, const char *message); }; #endif diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 878f82225..ccb35f479 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -1451,11 +1451,7 @@ luabind::scope lua_register_slot() { luabind::value("General6", static_cast(MainGeneral6)), luabind::value("General7", static_cast(MainGeneral7)), luabind::value("General8", static_cast(MainGeneral8)), - //luabind::value("General9", static_cast(MainGeneral9)), - //luabind::value("General10", static_cast(MainGeneral10)), luabind::value("Cursor", static_cast(MainCursor)), - //luabind::value("EquipmentBegin", static_cast(EmuConstants::EQUIPMENT_BEGIN)), - //luabind::value("EquipmentEnd", static_cast(EmuConstants::EQUIPMENT_END)), luabind::value("PersonalBegin", static_cast(EmuConstants::GENERAL_BEGIN)), // deprecated luabind::value("GeneralBegin", static_cast(EmuConstants::GENERAL_BEGIN)), luabind::value("PersonalEnd", static_cast(EmuConstants::GENERAL_END)), // deprecated @@ -1483,7 +1479,6 @@ luabind::scope lua_register_material() { luabind::value("Secondary", static_cast(MaterialSecondary)), luabind::value("Max", static_cast(_MaterialCount)), // deprecated luabind::value("Count", static_cast(_MaterialCount)), - //luabind::value("TintCount", static_cast(_MaterialCount - 2)), luabind::value("Invalid", static_cast(_MaterialInvalid)) ]; } @@ -1498,8 +1493,7 @@ luabind::scope lua_register_client_version() { luabind::value("SoF", static_cast(EQClientSoF)), luabind::value("SoD", static_cast(EQClientSoD)), luabind::value("Underfoot", static_cast(EQClientUnderfoot)), - luabind::value("RoF", static_cast(EQClientRoF))//, - //luabind::value("RoF2", static_cast(EQClientRoF2)) + luabind::value("RoF", static_cast(EQClientRoF)) ]; } diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 87155d97b..89f08a81f 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -54,9 +54,12 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob * ident << npc->GetNPCTypeID(); if(extra_pointers) { - for(size_t i = 0; i < extra_pointers->size(); ++i) { + size_t sz = extra_pointers->size(); + for(size_t i = 0; i < sz; ++i) { std::string prefix = "item" + std::to_string(static_cast(i + 1)); - Lua_ItemInst l_inst = EQEmu::any_cast(extra_pointers->at(i)); + ItemInst *inst = EQEmu::any_cast(extra_pointers->at(i)); + + Lua_ItemInst l_inst = inst; luabind::adl::object l_inst_o = luabind::adl::object(L, l_inst); l_inst_o.push(L); diff --git a/zone/trading.cpp b/zone/trading.cpp index ea9e36a31..c89af4010 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -871,7 +871,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st items[i - EmuConstants::TRADE_BEGIN] = inst->GetItem()->ID; item_list.push_back(inst); } else { - item_list.push_back(nullptr); + item_list.push_back((ItemInst*)nullptr); continue; } From eebe9029172fd172931258d4e4e6712a02002c08 Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 1 Sep 2014 00:07:21 -0400 Subject: [PATCH 63/89] Script update for opcode_handlers.py - changes in file names. --- utils/scripts/opcode_handlers.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/utils/scripts/opcode_handlers.py b/utils/scripts/opcode_handlers.py index 6cad4ade0..ce0e955a3 100644 --- a/utils/scripts/opcode_handlers.py +++ b/utils/scripts/opcode_handlers.py @@ -23,8 +23,8 @@ VERBOSE = False # messaging: {False - minimal, True - robust} base_path = os.getcwd()[:-14] # '/utils/scripts' base_path = base_path.replace('\\', '/') -client_list = ['6.2', 'Titanium', 'SoF', 'SoD', 'Underfoot', 'RoF', 'RoF2', 'ClientTest'] -server_list = ['Login', 'World', 'Zone', 'UCS', 'ServerTest'] +client_list = ['6.2', 'Titanium', 'SoF', 'SoD', 'Underfoot', 'RoF', 'RoF2'] +server_list = ['Login', 'World', 'Zone', 'UCS'] client_opcodes = {} # x[key='Client'][key='OP_CodeName'](value='0x####') server_opcodes = {} # x[key='OP_CodeName'](value=) - opcodes apply to all servers @@ -248,7 +248,7 @@ def loadclientopcodes(): for client in client_list: try: - short_name = '/patch_{0}.conf'.format(client) + short_name = '/patch_{0}.conf'.format(client).lower() file_name = '{0}/utils/patches{1}'.format( base_path, @@ -455,9 +455,9 @@ def loadclienttranslators(): for client in client_list: try: if client == '6.2': - short_name = '/Client62_ops.h' + short_name = '/client62_ops.h' else: - short_name = '/{0}_ops.h'.format(client) + short_name = '/{0}_ops.h'.format(client).lower() file_name = '{0}/common/patches{1}'.format( base_path, @@ -734,15 +734,15 @@ def discoverserverhandlers(): locations[server] = [] if 'Login' in locations: - locations['Login'].append('/loginserver/Client.cpp') - locations['Login'].append('/loginserver/ServerManager.cpp') - locations['Login'].append('/loginserver/WorldServer.cpp') + locations['Login'].append('/loginserver/client.cpp') + locations['Login'].append('/loginserver/server_manager.cpp') + locations['Login'].append('/loginserver/world_server.cpp') if 'World' in locations: locations['World'].append('/world/client.cpp') if 'Zone' in locations: - locations['Zone'].append('/zone/AA.cpp') + locations['Zone'].append('/zone/aa.cpp') locations['Zone'].append('/zone/attack.cpp') locations['Zone'].append('/zone/bot.cpp') locations['Zone'].append('/zone/client.cpp') @@ -762,8 +762,8 @@ def discoverserverhandlers(): locations['Zone'].append('/zone/loottables.cpp') locations['Zone'].append('/zone/merc.cpp') locations['Zone'].append('/zone/mob.cpp') - locations['Zone'].append('/zone/MobAI.cpp') - locations['Zone'].append('/zone/Object.cpp') + locations['Zone'].append('/zone/mob_ai.cpp') + locations['Zone'].append('/zone/object.cpp') locations['Zone'].append('/zone/pathing.cpp') locations['Zone'].append('/zone/petitions.cpp') locations['Zone'].append('/zone/questmgr.cpp') From 842217823366eb5ad16366ec130afaf6108632a3 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Mon, 1 Sep 2014 02:58:52 -0400 Subject: [PATCH 64/89] Fix issue with requesting an adventure --- world/adventure_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/world/adventure_manager.cpp b/world/adventure_manager.cpp index 047aca326..05337e0ad 100644 --- a/world/adventure_manager.cpp +++ b/world/adventure_manager.cpp @@ -715,7 +715,7 @@ bool AdventureManager::LoadAdventureEntries() std::list temp; auto iter = adventure_entries.find(id); - if(iter == adventure_entries.end()) + if(iter != adventure_entries.end()) temp = adventure_entries[id]; temp.push_back(tid); From 15f217b594cc42b90702a0752a4d4bc37dd070f7 Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 1 Sep 2014 15:48:22 -0700 Subject: [PATCH 65/89] Fixed non-conforming sql files. --- .../2014_08_23_Complete_QueryServ_Rules_Disabled.sql} | 0 .../2014_08_23_Complete_QueryServ_Rules_Enabled.sql} | 0 .../2014_08_23_Complete_QueryServ_Table_Structures.sql} | 0 .../2014_08_23_player_events_and_player_aa_rate_hourly.sql} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename utils/sql/git/{queryserv/required/Complete_QueryServ_Rules_Disabled.sql => optional/2014_08_23_Complete_QueryServ_Rules_Disabled.sql} (100%) rename utils/sql/git/{queryserv/required/Complete_QueryServ_Rules_Enabled.sql => optional/2014_08_23_Complete_QueryServ_Rules_Enabled.sql} (100%) rename utils/sql/git/{queryserv/required/Complete_QueryServ_Table_Structures.sql => required/2014_08_23_Complete_QueryServ_Table_Structures.sql} (100%) rename utils/sql/git/{queryserv/required/08_23_2014_player_events_and_player_aa_rate_hourly.sql => required/2014_08_23_player_events_and_player_aa_rate_hourly.sql} (100%) diff --git a/utils/sql/git/queryserv/required/Complete_QueryServ_Rules_Disabled.sql b/utils/sql/git/optional/2014_08_23_Complete_QueryServ_Rules_Disabled.sql similarity index 100% rename from utils/sql/git/queryserv/required/Complete_QueryServ_Rules_Disabled.sql rename to utils/sql/git/optional/2014_08_23_Complete_QueryServ_Rules_Disabled.sql diff --git a/utils/sql/git/queryserv/required/Complete_QueryServ_Rules_Enabled.sql b/utils/sql/git/optional/2014_08_23_Complete_QueryServ_Rules_Enabled.sql similarity index 100% rename from utils/sql/git/queryserv/required/Complete_QueryServ_Rules_Enabled.sql rename to utils/sql/git/optional/2014_08_23_Complete_QueryServ_Rules_Enabled.sql diff --git a/utils/sql/git/queryserv/required/Complete_QueryServ_Table_Structures.sql b/utils/sql/git/required/2014_08_23_Complete_QueryServ_Table_Structures.sql similarity index 100% rename from utils/sql/git/queryserv/required/Complete_QueryServ_Table_Structures.sql rename to utils/sql/git/required/2014_08_23_Complete_QueryServ_Table_Structures.sql diff --git a/utils/sql/git/queryserv/required/08_23_2014_player_events_and_player_aa_rate_hourly.sql b/utils/sql/git/required/2014_08_23_player_events_and_player_aa_rate_hourly.sql similarity index 100% rename from utils/sql/git/queryserv/required/08_23_2014_player_events_and_player_aa_rate_hourly.sql rename to utils/sql/git/required/2014_08_23_player_events_and_player_aa_rate_hourly.sql From 8dd00f52888b8f6227aa75eb4d9325825a12a404 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 2 Sep 2014 02:39:03 -0400 Subject: [PATCH 66/89] Fix crash issue in zone/hate_list.cpp --- changelog.txt | 3 +++ zone/hate_list.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index de7572176..5f24fcba9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 09/02/2014 == +demonstar55: crash fix checking DivineAura in hate_list.cpp + == 08/31/2014 == KLS: Fixed a bug in fishing in S3D zones KLS: Fixed a bug in turnins with new any abstraction diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 86b20d313..f26615877 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -163,7 +163,7 @@ Mob* HateList::GetClosest(Mob *hater) { ++iterator; } - if (close == 0 && hater->IsNPC() || close->DivineAura()) + if ((!close && hater->IsNPC()) || (close && close->DivineAura())) close = hater->CastToNPC()->GetHateTop(); return close; From 41d57ddab6e55a529eb9807f2a74c53c665954d9 Mon Sep 17 00:00:00 2001 From: Arthur Dene Ice Date: Tue, 2 Sep 2014 10:54:42 -0700 Subject: [PATCH 67/89] Fixed bug with loading failing on Guild bank areas --- zone/guild_mgr.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 37cc7a3de..927ca16f6 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -686,19 +686,26 @@ bool GuildBankManager::Load(uint32 guildID) else whoFor[0] = '\0'; - if(slot < 0 || - ((area != GuildBankMainArea || slot >= GUILD_BANK_MAIN_AREA_SIZE) || - (area == GuildBankMainArea || slot >= GUILD_BANK_DEPOSIT_AREA_SIZE))) + if(slot < 0) continue; - bank->Items.MainArea[slot].ItemID = itemID; - bank->Items.MainArea[slot].Quantity = qty; + GuildBankItem *itemSection = nullptr; - strn0cpy(bank->Items.MainArea[slot].Donator, donator, sizeof(donator)); + if (area == GuildBankMainArea && slot < GUILD_BANK_MAIN_AREA_SIZE) + itemSection = bank->Items.MainArea; + else if (area != GuildBankMainArea && slot < GUILD_BANK_DEPOSIT_AREA_SIZE) + itemSection = bank->Items.DepositArea; + else + continue; - bank->Items.MainArea[slot].Permissions = permissions; + itemSection[slot].ItemID = itemID; + itemSection[slot].Quantity = qty; - strn0cpy(bank->Items.MainArea[slot].WhoFor, whoFor, sizeof(whoFor)); + strn0cpy(itemSection[slot].Donator, donator, sizeof(donator)); + + itemSection[slot].Permissions = permissions; + + strn0cpy(itemSection[slot].WhoFor, whoFor, sizeof(whoFor)); } Banks.push_back(bank); From 832e5e90d191e3e31fa364a3683c5bc9362bd7e9 Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Tue, 2 Sep 2014 21:16:20 -0400 Subject: [PATCH 68/89] Secrets: Identified OP_GuildPromote for RoF clients. Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later. Secrets/Akkadius: Fixed an issue involving character name lookup in the new DB code. --- changelog.txt | 5 ++ common/database.cpp | 4 +- common/emu_oplist.h | 1 + common/eq_packet_structs.h | 8 ++++ common/eq_stream.cpp | 2 +- common/guild_base.cpp | 5 ++ common/guild_base.h | 1 + common/patches/rof.cpp | 30 ++++++++++-- utils/patches/patch_RoF.conf | 1 + zone/client_packet.cpp | 93 +++++++++++++++++++++++++++++++++--- zone/client_packet.h | 1 + zone/effects.cpp | 26 +++------- zone/guild.cpp | 10 +++- zone/guild_mgr.cpp | 4 ++ 14 files changed, 158 insertions(+), 33 deletions(-) diff --git a/changelog.txt b/changelog.txt index de7572176..c7421fc97 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,10 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 09/02/2014 == +Secrets: Identified OP_GuildPromote for RoF clients. +Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later. +Secrets/Akkadius: Fixed an issue involving character name lookup in the new DB code. + == 08/31/2014 == KLS: Fixed a bug in fishing in S3D zones KLS: Fixed a bug in turnins with new any abstraction diff --git a/common/database.cpp b/common/database.cpp index b99eac2ea..d1845b82e 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -771,7 +771,9 @@ void Database::GetCharName(uint32 char_id, char* name) { } auto row = results.begin(); - strcpy(name, row[0]); + for (auto row = results.begin(); row != results.end(); ++row) { + strcpy(name, row[0]); + } } bool Database::LoadVariables() { diff --git a/common/emu_oplist.h b/common/emu_oplist.h index edee551a1..c1ceb3c80 100644 --- a/common/emu_oplist.h +++ b/common/emu_oplist.h @@ -540,3 +540,4 @@ N(OP_OpenInventory), N(OP_OpenContainer), N(OP_Marquee), N(OP_ClientTimeStamp), +N(OP_GuildPromote), diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index d2fbcbb76..027039122 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -4461,6 +4461,14 @@ struct GuildBankPromote_Struct /*12*/ uint32 Slot2; // Always appears to be the same as Slot for Action code 3 }; +struct GuildPromoteStruct { +/*000*/ char target[64]; +/*064*/ char name[64]; +/*128*/ uint32 rank; +/*132*/ uint32 myrank; +/*136*/ +}; + struct GuildBankPermissions_Struct { /*00*/ uint32 Action; // 6 diff --git a/common/eq_stream.cpp b/common/eq_stream.cpp index 61dc201be..8cb67e0e0 100644 --- a/common/eq_stream.cpp +++ b/common/eq_stream.cpp @@ -534,7 +534,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req) uint16 opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode); - _log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size); + //_log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size); if (!ack_req) { NonSequencedPush(new EQProtocolPacket(opcode, pack->pBuffer, pack->size)); diff --git a/common/guild_base.cpp b/common/guild_base.cpp index 8f6144270..6546918d0 100644 --- a/common/guild_base.cpp +++ b/common/guild_base.cpp @@ -474,6 +474,11 @@ bool BaseGuildManager::SetBankerFlag(uint32 charid, bool is_banker) { return(true); } +bool BaseGuildManager::ForceRankUpdate(uint32 charid) { + SendRankUpdate(charid); + return(true); +} + bool BaseGuildManager::SetAltFlag(uint32 charid, bool is_alt) { if(!DBSetAltFlag(charid, is_alt)) diff --git a/common/guild_base.h b/common/guild_base.h index 652db0bc8..b59244480 100644 --- a/common/guild_base.h +++ b/common/guild_base.h @@ -54,6 +54,7 @@ public: bool SetGuild(uint32 charid, uint32 guild_id, uint8 rank); bool SetGuildRank(uint32 charid, uint8 rank); bool SetBankerFlag(uint32 charid, bool is_banker); + bool ForceRankUpdate(uint32 charid); bool GetAltFlag(uint32 CharID); bool SetAltFlag(uint32 charid, bool is_alt); bool GetBankerFlag(uint32 CharID); diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 90ff9ab9e..3a83cef93 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -1,4 +1,3 @@ - #include "../debug.h" #include "rof.h" #include "../opcodemgr.h" @@ -1974,7 +1973,14 @@ ENCODE(OP_ZoneSpawns) else { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildID); - VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); + + /* Translate older ranks to new values */ + switch (emu->guildrank) { + case 0: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5); break; } // GUILD_MEMBER 0 + case 1: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3); break; } // GUILD_OFFICER 1 + case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2 + default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } // + } } VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->class_); @@ -2406,7 +2412,15 @@ ENCODE(OP_GuildMemberList) { PutFieldN(level); PutFieldN(banker); PutFieldN(class_); - PutFieldN(rank); + + /* Translate older ranks to new values */ + switch (emu_e->rank) { + case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0 + case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1 + case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2 + default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE + } + PutFieldN(time_last_on); PutFieldN(tribute_enable); e->unknown01 = 0; @@ -3330,7 +3344,15 @@ ENCODE(OP_SetGuildRank) ENCODE_LENGTH_EXACT(GuildSetRank_Struct); SETUP_DIRECT_ENCODE(GuildSetRank_Struct, structs::GuildSetRank_Struct); eq->GuildID = emu->Unknown00; - OUT(Rank); + + /* Translate older ranks to new values */ + switch (emu->Rank) { + case 0: { eq->Rank = 5; break; } // GUILD_MEMBER 0 + case 1: { eq->Rank = 3; break; } // GUILD_OFFICER 1 + case 2: { eq->Rank = 1; break; } // GUILD_LEADER 2 + default: { eq->Rank = emu->Rank; break; } + } + memcpy(eq->MemberName, emu->MemberName, sizeof(eq->MemberName)); OUT(Banker); eq->Unknown76 = 1; diff --git a/utils/patches/patch_RoF.conf b/utils/patches/patch_RoF.conf index c4e0b7955..50bfd5580 100644 --- a/utils/patches/patch_RoF.conf +++ b/utils/patches/patch_RoF.conf @@ -125,6 +125,7 @@ OP_GuildLeader=0x7c6f OP_GuildDelete=0x241b OP_GuildInviteAccept=0x78a5 OP_GuildDemote=0x3100 +OP_GuildPromote=0x2945 OP_GuildPublicNote=0x3c2c OP_GuildManageBanker=0x096d # Was 0x0737 OP_GuildBank=0x2ab0 # Was 0x10c3 diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index d56d8386a..37c58d743 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -190,6 +190,7 @@ void MapOpcodes() { ConnectedOpcodes[OP_GuildWar] = &Client::Handle_OP_GuildWar; ConnectedOpcodes[OP_GuildLeader] = &Client::Handle_OP_GuildLeader; ConnectedOpcodes[OP_GuildDemote] = &Client::Handle_OP_GuildDemote; + ConnectedOpcodes[OP_GuildPromote] = &Client::Handle_OP_GuildPromote; ConnectedOpcodes[OP_GuildInvite] = &Client::Handle_OP_GuildInvite; ConnectedOpcodes[OP_GuildRemove] = &Client::Handle_OP_GuildRemove; ConnectedOpcodes[OP_GetGuildMOTD] = &Client::Handle_OP_GetGuildMOTD; @@ -4088,7 +4089,7 @@ void Client::Handle_OP_GuildLeader(const EQApplicationPacket *app) GuildMakeLeader* gml=(GuildMakeLeader*)app->pBuffer; if (!IsInAGuild()) Message(0, "Error: You arent in a guild!"); - else if (!guild_mgr.IsGuildLeader(GuildID(), CharacterID())) + else if (GuildRank() != GUILD_LEADER) Message(0, "Error: You arent the guild leader!"); else if (!worldserver.Connected()) Message(0, "Error: World server disconnected"); @@ -4169,6 +4170,57 @@ void Client::Handle_OP_GuildDemote(const EQApplicationPacket *app) return; } + +void Client::Handle_OP_GuildPromote(const EQApplicationPacket *app) +{ + mlog(GUILDS__IN_PACKETS, "Received OP_GuildPromote"); + mpkt(GUILDS__IN_PACKET_TRACE, app); + + if(app->size != sizeof(GuildPromoteStruct)) { + mlog(GUILDS__ERROR, "Error: app size of %i != size of GuildDemoteStruct of %i\n",app->size,sizeof(GuildPromoteStruct)); + return; + } + + if (!IsInAGuild()) + Message(0, "Error: You arent in a guild!"); + else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_PROMOTE)) + Message(0, "You dont have permission to invite."); + else if (!worldserver.Connected()) + Message(0, "Error: World server disconnected"); + else { + GuildPromoteStruct* promote = (GuildPromoteStruct*)app->pBuffer; + + CharGuildInfo gci; + if(!guild_mgr.GetCharInfo(promote->target, gci)) { + Message(0, "Unable to find '%s'", promote->target); + return; + } + if(gci.guild_id != GuildID()) { + Message(0, "You aren't in the same guild, what do you think you are doing?"); + return; + } + + uint8 rank = gci.rank + 1; + + if(rank > GUILD_OFFICER) + return; + + + mlog(GUILDS__ACTIONS, "Promoting %s (%d) from rank %s (%d) to %s (%d) in %s (%d)", + promote->target, gci.char_id, + guild_mgr.GetRankName(GuildID(), gci.rank), gci.rank, + guild_mgr.GetRankName(GuildID(), rank), rank, + guild_mgr.GetGuildName(GuildID()), GuildID()); + + if(!guild_mgr.SetGuildRank(gci.char_id, rank)) { + Message(13, "Error while setting rank %d on '%s'.", rank, promote->target); + return; + } + Message(0, "Successfully promoted %s to rank %d", promote->target, rank); + } + return; +} + void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) { mlog(GUILDS__IN_PACKETS, "Received OP_GuildInvite"); @@ -4379,6 +4431,16 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app) GuildInviteAccept_Struct* gj = (GuildInviteAccept_Struct*) app->pBuffer; + if(GetClientVersion() >= EQClientRoF) + { + if(gj->response > 9) + { + //dont care if the check fails (since we dont know the rank), just want to clear the entry. + guild_mgr.VerifyAndClearInvite(CharacterID(), gj->guildeqid, gj->response); + worldserver.SendEmoteMessage(gj->inviter, 0, 0, "%s has declined to join the guild.", this->GetName()); + return; + } + } if (gj->response == 5 || gj->response == 4) { //dont care if the check fails (since we dont know the rank), just want to clear the entry. guild_mgr.VerifyAndClearInvite(CharacterID(), gj->guildeqid, gj->response); @@ -4424,15 +4486,24 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app) guild_mgr.GetGuildName(gj->guildeqid), gj->guildeqid, gj->response); - //change guild and rank. - if(!guild_mgr.SetGuild(CharacterID(), gj->guildeqid, gj->response)) { + //change guild and rank + + uint32 guildrank = gj->response; + + if(GetClientVersion() == EQClientRoF) + { + if(gj->response == 8) + { + guildrank = 0; + } + } + + if(!guild_mgr.SetGuild(CharacterID(), gj->guildeqid, guildrank)) { Message(13, "There was an error during the invite, DB may now be inconsistent."); return; } if(zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks) GuildBanks->SendGuildBank(this); - SendGuildRanks(); - } } } @@ -9301,8 +9372,18 @@ void Client::CompleteConnect() { UpdateAdmin(false); if (IsInAGuild()){ + uint8 rank = GuildRank(); + if(GetClientVersion() >= EQClientRoF) + { + switch (rank) { + case 0: { rank = 5; break; } // GUILD_MEMBER 0 + case 1: { rank = 3; break; } // GUILD_OFFICER 1 + case 2: { rank = 1; break; } // GUILD_LEADER 2 + default: { break; } // GUILD_NONE + } + } SendAppearancePacket(AT_GuildID, GuildID(), false); - SendAppearancePacket(AT_GuildRank, GuildRank(), false); + SendAppearancePacket(AT_GuildRank, rank, false); } for (uint32 spellInt = 0; spellInt < MAX_PP_SPELLBOOK; spellInt++) { diff --git a/zone/client_packet.h b/zone/client_packet.h index 1b687edb9..424a8f78f 100644 --- a/zone/client_packet.h +++ b/zone/client_packet.h @@ -90,6 +90,7 @@ void Handle_OP_GuildWar(const EQApplicationPacket *app); void Handle_OP_GuildLeader(const EQApplicationPacket *app); void Handle_OP_GuildDemote(const EQApplicationPacket *app); + void Handle_OP_GuildPromote(const EQApplicationPacket *app); void Handle_OP_GuildInvite(const EQApplicationPacket *app); void Handle_OP_GuildRemove(const EQApplicationPacket *app); void Handle_OP_GetGuildMOTD(const EQApplicationPacket *app); diff --git a/zone/effects.cpp b/zone/effects.cpp index a24a6b39b..671d010ae 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -175,8 +175,8 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { value -= GetFocusEffect(focusFcDamageAmt, spell_id); - if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) - value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value); + if(itembonuses.SpellDmg) + value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value); return value; } @@ -245,29 +245,15 @@ int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) { value -= extra_dmg; + if(itembonuses.SpellDmg) + value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value) / 6; + return value; } int32 Mob::GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg) { - int total_cast_time = 0; - - if (spells[spell_id].recast_time >= spells[spell_id].recovery_time) - total_cast_time = spells[spell_id].recast_time + spells[spell_id].cast_time; - else - total_cast_time = spells[spell_id].recovery_time + spells[spell_id].cast_time; - - if (total_cast_time > 0 && total_cast_time <= 2500) - extra_spell_amt = extra_spell_amt*25/100; - else if (total_cast_time > 2500 && total_cast_time < 7000) - extra_spell_amt = extra_spell_amt*(0.167*((total_cast_time - 1000)/1000)); - else - extra_spell_amt = extra_spell_amt * total_cast_time / 7000; - - if(extra_spell_amt*2 < base_spell_dmg) - return 0; - - return extra_spell_amt; + return extra_spell_amt; } diff --git a/zone/guild.cpp b/zone/guild.cpp index 92635c185..6512bedec 100644 --- a/zone/guild.cpp +++ b/zone/guild.cpp @@ -160,9 +160,17 @@ void Client::SendGuildSpawnAppearance() { uint8 rank = guild_mgr.GetDisplayedRank(GuildID(), GuildRank(), CharacterID()); mlog(GUILDS__OUT_PACKETS, "Sending spawn appearance for guild %d at rank %d", GuildID(), rank); SendAppearancePacket(AT_GuildID, GuildID()); + if(GetClientVersion() >= EQClientRoF) + { + switch (rank) { + case 0: { rank = 5; break; } // GUILD_MEMBER 0 + case 1: { rank = 3; break; } // GUILD_OFFICER 1 + case 2: { rank = 1; break; } // GUILD_LEADER 2 + default: { break; } // GUILD_NONE + } + } SendAppearancePacket(AT_GuildRank, rank); } - UpdateWho(); } diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 37cc7a3de..19a8c5a61 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -374,6 +374,10 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) { else if(c != nullptr && s->guild_id != GUILD_NONE) { //char is in zone, and has changed into a new guild, send MOTD. c->SendGuildMOTD(); + if(c->GetClientVersion() >= EQClientRoF) + { + c->SendGuildRanks(); + } } From 76d3edc534a7b6f0e78d4260f1ba7b47397ca80f Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 2 Sep 2014 21:19:30 -0400 Subject: [PATCH 69/89] Changed #loc to report the same precision as /loc for Cartesians --- changelog.txt | 1 + zone/command.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 5f24fcba9..9f64c9446 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 09/02/2014 == demonstar55: crash fix checking DivineAura in hate_list.cpp +Uleat: Changed #loc to report the same precision as /loc for Cartesians == 08/31/2014 == KLS: Fixed a bug in fishing in S3D zones diff --git a/zone/command.cpp b/zone/command.cpp index b14a173bc..1f0c17453 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -4692,7 +4692,7 @@ void command_loc(Client *c, const Seperator *sep) { Mob *t=c->GetTarget()?c->GetTarget():c->CastToMob(); - c->Message(0, "%s's Location (XYZ): %1.1f, %1.1f, %1.1f; heading=%1.1f", t->GetName(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); + c->Message(0, "%s's Location (XYZ): %1.2f, %1.2f, %1.2f; heading=%1.1f", t->GetName(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); } void command_goto(Client *c, const Seperator *sep) From b7dfdc506003c7daa600c7ea75073b5f1e2684c4 Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Tue, 2 Sep 2014 22:07:49 -0400 Subject: [PATCH 70/89] Oops. --- zone/effects.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/zone/effects.cpp b/zone/effects.cpp index 671d010ae..a24a6b39b 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -175,8 +175,8 @@ int32 Client::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { value -= GetFocusEffect(focusFcDamageAmt, spell_id); - if(itembonuses.SpellDmg) - value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value); + if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5) + value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value); return value; } @@ -245,15 +245,29 @@ int32 Client::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) { value -= extra_dmg; - if(itembonuses.SpellDmg) - value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value) / 6; - return value; } int32 Mob::GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg) { - return extra_spell_amt; + int total_cast_time = 0; + + if (spells[spell_id].recast_time >= spells[spell_id].recovery_time) + total_cast_time = spells[spell_id].recast_time + spells[spell_id].cast_time; + else + total_cast_time = spells[spell_id].recovery_time + spells[spell_id].cast_time; + + if (total_cast_time > 0 && total_cast_time <= 2500) + extra_spell_amt = extra_spell_amt*25/100; + else if (total_cast_time > 2500 && total_cast_time < 7000) + extra_spell_amt = extra_spell_amt*(0.167*((total_cast_time - 1000)/1000)); + else + extra_spell_amt = extra_spell_amt * total_cast_time / 7000; + + if(extra_spell_amt*2 < base_spell_dmg) + return 0; + + return extra_spell_amt; } From 64c324a42bc277cc8590ad0626ee7a8f5bac795a Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Tue, 2 Sep 2014 22:09:38 -0400 Subject: [PATCH 71/89] changelog.txt --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index df124eb2e..accb7c97e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -5,6 +5,7 @@ Secrets: Identified OP_GuildPromote for RoF clients. Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later. Secrets/Akkadius: Fixed an issue involving character name lookup in the new DB code. demonstar55: crash fix checking DivineAura in hate_list.cpp +Secrets: Reverted some code that got in the main branch that shouldn't have gotten there. Uleat: Changed #loc to report the same precision as /loc for Cartesians == 08/31/2014 == From e6a0b01f373ecc6d3150aa2accca2bfb7c839bba Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Wed, 3 Sep 2014 18:25:21 -0400 Subject: [PATCH 72/89] Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor. --- changelog.txt | 3 + common/eq_packet_structs.h | 11 ++- common/patches/rof.cpp | 9 ++- common/patches/rof_structs.h | 6 +- zone/client_packet.cpp | 140 ++++++++++++++++++++++++++++++++++- zone/command.cpp | 2 - 6 files changed, 158 insertions(+), 13 deletions(-) diff --git a/changelog.txt b/changelog.txt index accb7c97e..37dea5b08 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 09/03/2014 == +Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor. + == 09/02/2014 == Secrets: Identified OP_GuildPromote for RoF clients. Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later. diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 027039122..1751f4b4e 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -2287,10 +2287,13 @@ struct Stun_Struct { // 4 bytes total }; struct AugmentItem_Struct { -/*00*/ int16 container_slot; -/*02*/ char unknown02[2]; -/*04*/ int32 augment_slot; -/*08*/ +/*00*/ uint32 container_index; +/*04*/ int32 container_slot; +/*08*/ uint32 augment_index; +/*12*/ int32 augment_slot; +/*16*/ uint32 dest_inst_id; // The unique serial number for the item instance that is being augmented +/*20*/ int32 augment_action; // Guessed - 0 = augment, 1 = remove with distiller, 3 = delete aug +/*24*/ }; // OP_Emote diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 3a83cef93..d5303ccfb 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -4682,8 +4682,11 @@ DECODE(OP_AugmentItem) { SETUP_DIRECT_DECODE(AugmentItem_Struct, structs::AugmentItem_Struct); emu->container_slot = RoFToServerSlot(eq->container_slot); - //emu->augment_slot = eq->augment_slot; - + emu->augment_slot = RoFToServerSlot(eq->augment_slot); + emu->container_index = eq->container_index; + emu->augment_index = eq->augment_index; + emu->dest_inst_id = eq->dest_inst_id; + emu->augment_action = eq->augment_action; FINISH_DIRECT_DECODE(); } @@ -5090,7 +5093,7 @@ char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint memset(&isbs, 0, sizeof(RoF::structs::ItemSecondaryBodyStruct)); isbs.augtype = item->AugType; - isbs.augdistiller = 0; + isbs.augdistiller = 65535; isbs.augrestrict = item->AugRestrict; diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index 918bbe68d..2d1b5ef18 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -2519,10 +2519,10 @@ struct Stun_Struct { // 8 bytes total struct AugmentItem_Struct { /*00*/ uint32 dest_inst_id; // The unique serial number for the item instance that is being augmented -/*04*/ uint32 unknown04; // Seen 0 +/*04*/ uint32 container_index; // Seen 0 /*08*/ ItemSlotStruct container_slot; // Slot of the item being augmented -/*20*/ uint32 unknown20; // Seen 0 -/*24*/ ItemSlotStruct distiller_slot; // Slot of the distiller to use (if one applies) +/*20*/ uint32 augment_index; // Seen 0 +/*24*/ ItemSlotStruct augment_slot; // Slot of the distiller to use (if one applies) /*36*/ int32 augment_action; // Guessed - 0 = augment, 1 = remove with distiller, 3 = delete aug /*36*/ //int32 augment_slot; /*40*/ diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 37c58d743..fc77e0c82 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -6281,7 +6281,145 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) // Delegate to tradeskill object to perform combine AugmentItem_Struct* in_augment = (AugmentItem_Struct*)app->pBuffer; - Object::HandleAugmentation(this, in_augment, m_tradeskill_object); + bool deleteItems = false; + if(GetClientVersion() >= EQClientRoF) + { + ItemInst *itemOneToPush = nullptr, *itemTwoToPush = nullptr; + + //Message(15, "%i %i %i %i %i %i", in_augment->container_slot, in_augment->augment_slot, in_augment->container_index, in_augment->augment_index, in_augment->augment_action, in_augment->dest_inst_id); + + // Adding augment + if (in_augment->augment_action == 0) + { + ItemInst *tobe_auged, *auged_with = nullptr; + int8 slot=-1; + Inventory& user_inv = GetInv(); + + uint16 slot_id = in_augment->container_slot; + uint16 aug_slot_id = in_augment->augment_slot; + //Message(13, "%i AugSlot", aug_slot_id); + if(slot_id == INVALID_INDEX || aug_slot_id == INVALID_INDEX) + { + Message(13, "Error: Invalid Aug Index."); + return; + } + + tobe_auged = user_inv.GetItem(slot_id); + auged_with = user_inv.GetItem(MainCursor); + + if(tobe_auged && auged_with) + { + if (((slot=tobe_auged->AvailableAugmentSlot(auged_with->GetAugmentType()))!=-1) && + (tobe_auged->AvailableWearSlot(auged_with->GetItem()->Slots))) + { + tobe_auged->PutAugment(slot, *auged_with); + + ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_index); + if(aug) { + std::vector args; + args.push_back(aug); + parse->EventItem(EVENT_AUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args); + + args.assign(1, tobe_auged); + parse->EventItem(EVENT_AUGMENT_INSERT, this, aug, nullptr, "", in_augment->augment_index, &args); + } + else + { + Message(13, "Error: Could not find augmentation at index %i. Aborting."); + return; + } + + itemOneToPush = tobe_auged->Clone(); + // Must push items after the items in inventory are deleted - necessary due to lore items... + if (itemOneToPush) + { + DeleteItemInInventory(slot_id, 0, true); + DeleteItemInInventory(MainCursor, 0, true); + if(PutItemInInventory(slot_id, *itemOneToPush, true)) + { + //Message(13, "Sucessfully added an augment to your item!"); + return; + } + else + { + Message(13, "Error: No available slot for end result. Please free up some bag space."); + } + } + else + { + Message(13, "Error in cloning item for augment. Aborted."); + } + + } + else + { + Message(13, "Error: No available slot for augment in that item."); + } + } + } + else if(in_augment->augment_action == 1) + { + ItemInst *tobe_auged, *auged_with = nullptr; + int8 slot=-1; + Inventory& user_inv = GetInv(); + + uint16 slot_id = in_augment->container_slot; + uint16 aug_slot_id = in_augment->augment_slot; //it's actually solvent slot + if(slot_id == INVALID_INDEX || aug_slot_id == INVALID_INDEX) + { + Message(13, "Error: Invalid Aug Index."); + return; + } + + tobe_auged = user_inv.GetItem(slot_id); + auged_with = user_inv.GetItem(aug_slot_id); + + ItemInst *old_aug = nullptr; + if(!auged_with) + return; + const uint32 id = auged_with->GetID(); + ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_index); + if(aug) { + std::vector args; + args.push_back(aug); + parse->EventItem(EVENT_UNAUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args); + + args.assign(1, tobe_auged); + + args.push_back(false); + + parse->EventItem(EVENT_AUGMENT_REMOVE, this, aug, nullptr, "", in_augment->augment_index, &args); + } + else + { + Message(13, "Error: Could not find augmentation at index %i. Aborting."); + return; + } + old_aug = tobe_auged->RemoveAugment(in_augment->augment_index); + + itemOneToPush = tobe_auged->Clone(); + if (old_aug) + itemTwoToPush = old_aug->Clone(); + if(itemOneToPush && itemTwoToPush && auged_with) + { + DeleteItemInInventory(slot_id, 0, true); + DeleteItemInInventory(aug_slot_id, auged_with->IsStackable() ? 1 : 0, true); + if(!PutItemInInventory(slot_id, *itemOneToPush, true)) + { + Message(15, "Shouldn't happen, contact an admin!"); + } + + if(PutItemInInventory(MainCursor, *itemTwoToPush, true)) + { + //Message(15, "Successfully removed an augmentation!"); + } + } + } + } + else + { + Object::HandleAugmentation(this, in_augment, m_tradeskill_object); + } return; } diff --git a/zone/command.cpp b/zone/command.cpp index 1f0c17453..fbec3b0b3 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -11429,8 +11429,6 @@ void command_augmentitem(Client *c, const Seperator *sep) AugmentItem_Struct* in_augment = new AugmentItem_Struct[sizeof(AugmentItem_Struct)]; in_augment->container_slot = 1000; // - in_augment->unknown02[0] = 0; - in_augment->unknown02[1] = 0; in_augment->augment_slot = -1; if(c->GetTradeskillObject() != nullptr) Object::HandleAugmentation(c, in_augment, c->GetTradeskillObject()); From 891952eb799507746b57f5425399059545db3571 Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Wed, 3 Sep 2014 18:34:31 -0400 Subject: [PATCH 73/89] Bot fixes for previous commit --- zone/bot.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index e782e6db8..9d7dc508f 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -11741,8 +11741,6 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { if(!strcasecmp(sep->arg[1], "augmentitem")) { AugmentItem_Struct* in_augment = new AugmentItem_Struct[sizeof(AugmentItem_Struct)]; in_augment->container_slot = 1000; // - in_augment->unknown02[0] = 0; - in_augment->unknown02[1] = 0; in_augment->augment_slot = -1; Object::HandleAugmentation(c, in_augment, c->GetTradeskillObject()); return; From 22742b6a255e52944fefb05f9fa7e385864e9239 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Wed, 3 Sep 2014 23:50:23 -0400 Subject: [PATCH 74/89] Add #shownumhits workaround command to show numhits --- changelog.txt | 1 + zone/client.cpp | 12 ++++++++++++ zone/client.h | 4 +++- zone/command.cpp | 9 ++++++++- zone/command.h | 1 + 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index 37dea5b08..acd869afa 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 09/03/2014 == Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor. +demonstar55: Added work around command to show numhits on your buffs (#shownumhits) == 09/02/2014 == Secrets: Identified OP_GuildPromote for RoF clients. diff --git a/zone/client.cpp b/zone/client.cpp index 222acc094..30bf428a3 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -8334,3 +8334,15 @@ void Client::ExpeditionSay(const char *str, int ExpID) { mysql_free_result(result); } + +void Client::ShowNumHits() +{ + uint32 buffcount = GetMaxTotalSlots(); + for (uint32 buffslot = 0; buffslot < buffcount; buffslot++) { + const Buffs_Struct &curbuff = buffs[buffslot]; + if (curbuff.spellid != SPELL_UNKNOWN && curbuff.numhits) + Message(0, "You have %d hits left on %s", curbuff.numhits, GetSpellName(curbuff.spellid)); + } + return; +} + diff --git a/zone/client.h b/zone/client.h index 6c298ba15..9d6de336a 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1200,7 +1200,9 @@ public: void SetEngagedRaidTarget(bool value) { EngagedRaidTarget = value; } bool GetEngagedRaidTarget() const { return EngagedRaidTarget; } - + + void ShowNumHits(); // work around function for numhits not showing on buffs + protected: friend class Mob; void CalcItemBonuses(StatBonuses* newbon); diff --git a/zone/command.cpp b/zone/command.cpp index fbec3b0b3..eff53fcf3 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -453,7 +453,8 @@ int command_init(void) { command_add("merchant_open_shop", "Opens a merchants shop", 100, command_merchantopenshop) || command_add("open_shop", nullptr, 100, command_merchantopenshop) || command_add("merchant_close_shop", "Closes a merchant shop", 100, command_merchantcloseshop) || - command_add("close_shop", nullptr, 100, command_merchantcloseshop) + command_add("close_shop", nullptr, 100, command_merchantcloseshop) || + command_add("shownumhits", "Shows buffs numhits for yourself.", 0, command_shownumhits) ) { command_deinit(); @@ -11555,3 +11556,9 @@ void command_merchantcloseshop(Client *c, const Seperator *sep) merchant->CastToNPC()->MerchantCloseShop(); } + +void command_shownumhits(Client *c, const Seperator *sep) +{ + c->ShowNumHits(); + return; +} diff --git a/zone/command.h b/zone/command.h index 6a880625e..4846dd09d 100644 --- a/zone/command.h +++ b/zone/command.h @@ -325,6 +325,7 @@ void command_showspellslist(Client *c, const Seperator *sep); void command_npctype_cache(Client *c, const Seperator *sep); void command_merchantopenshop(Client *c, const Seperator *sep); void command_merchantcloseshop(Client *c, const Seperator *sep); +void command_shownumhits(Client *c, const Seperator *sep); #ifdef EQPROFILE void command_profiledump(Client *c, const Seperator *sep); From 37d3daaf9a5d1b2ceaae4ecfe8e8a5885c575f50 Mon Sep 17 00:00:00 2001 From: Uleat Date: Wed, 3 Sep 2014 23:59:55 -0400 Subject: [PATCH 75/89] Client timer issue fix --- changelog.txt | 1 + zone/mob.h | 1 + zone/mob_ai.cpp | 52 ++++++++++++++++++++++++++----------------------- zone/zone.cpp | 1 + 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/changelog.txt b/changelog.txt index acd869afa..6c2ee0841 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,6 +3,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) == 09/03/2014 == Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor. demonstar55: Added work around command to show numhits on your buffs (#shownumhits) +Uleat: Fix for timer issue introduced by Zone::ShutDown() fix. == 09/02/2014 == Secrets: Identified OP_GuildPromote for RoF clients. diff --git a/zone/mob.h b/zone/mob.h index 55a57892b..80ecaee49 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -727,6 +727,7 @@ public: virtual void AI_Init(); virtual void AI_Start(uint32 iMoveDelay = 0); virtual void AI_Stop(); + virtual void AI_ShutDown(); virtual void AI_Process(); const char* GetEntityVariable(const char *id); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 10d41c78e..125e1d85f 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -550,30 +550,6 @@ void Mob::AI_Stop() { safe_delete(AItarget_check_timer); safe_delete(AIscanarea_timer); safe_delete(AIfeignremember_timer); - safe_delete(PathingLOSCheckTimer); - safe_delete(PathingRouteUpdateTimerShort); - safe_delete(PathingRouteUpdateTimerLong); - - attack_timer.Disable(); - attack_dw_timer.Disable(); - ranged_timer.Disable(); - tic_timer.Disable(); - mana_timer.Disable(); - spellend_timer.Disable(); - projectile_timer.Disable(); - rewind_timer.Disable(); - bindwound_timer.Disable(); - stunned_timer.Disable(); - spun_timer.Disable(); - bardsong_timer.Disable(); - gravity_timer.Disable(); - viral_timer.Disable(); - flee_timer.Disable(); - - for (int sat = 0; sat < MAX_SPECIAL_ATTACK; ++sat) { - if (SpecialAbilities[sat].timer) - SpecialAbilities[sat].timer->Disable(); - } hate_list.Wipe(); } @@ -609,6 +585,34 @@ void Client::AI_Stop() { } } +// only call this on a zone shutdown event +void Mob::AI_ShutDown() { + safe_delete(PathingLOSCheckTimer); + safe_delete(PathingRouteUpdateTimerShort); + safe_delete(PathingRouteUpdateTimerLong); + + attack_timer.Disable(); + attack_dw_timer.Disable(); + ranged_timer.Disable(); + tic_timer.Disable(); + mana_timer.Disable(); + spellend_timer.Disable(); + projectile_timer.Disable(); + rewind_timer.Disable(); + bindwound_timer.Disable(); + stunned_timer.Disable(); + spun_timer.Disable(); + bardsong_timer.Disable(); + gravity_timer.Disable(); + viral_timer.Disable(); + flee_timer.Disable(); + + for (int sat = 0; sat < MAX_SPECIAL_ATTACK; ++sat) { + if (SpecialAbilities[sat].timer) + SpecialAbilities[sat].timer->Disable(); + } +} + //todo: expand the logic here to cover: //redundant debuffs //buffing owner diff --git a/zone/zone.cpp b/zone/zone.cpp index 8f4b211d8..e91e3a4b7 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -733,6 +733,7 @@ void Zone::Shutdown(bool quite) while (mob_itr != mob_list.end()) { Mob* mob_inst = *mob_itr; mob_inst->AI_Stop(); + mob_inst->AI_ShutDown(); ++mob_itr; } From 32b595afb4311124f81c6612c7ec76209a739b83 Mon Sep 17 00:00:00 2001 From: Arthur Ice Date: Thu, 4 Sep 2014 22:51:31 -0700 Subject: [PATCH 76/89] Fix iterator on mercstance crash bug --- zone/zone.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zone/zone.cpp b/zone/zone.cpp index e91e3a4b7..2f1052f73 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -594,15 +594,17 @@ void Zone::LoadMercTemplates(){ tempMercTemplate.Stances[i] = 0; int stanceIndex = 0; - for (std::list::iterator mercStanceListItr = merc_stances.begin(); mercStanceListItr != merc_stances.end(); ++mercStanceListItr, ++stanceIndex) { + for (auto mercStanceListItr = merc_stances.begin(); mercStanceListItr != merc_stances.end(); ++mercStanceListItr) { if(mercStanceListItr->ClassID != tempMercTemplate.ClassID || mercStanceListItr->ProficiencyID != tempMercTemplate.ProficiencyID) continue; zone->merc_stance_list[tempMercTemplate.MercTemplateID].push_back((*mercStanceListItr)); tempMercTemplate.Stances[stanceIndex] = mercStanceListItr->StanceID; + ++stanceIndex; } merc_templates[tempMercTemplate.MercTemplateID] = tempMercTemplate; + } } From da121137e5692c44bf7b658b353f1f961778223f Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 5 Sep 2014 13:26:44 -0400 Subject: [PATCH 77/89] Fix logging macros macros should be fully wrapped in do { ... } while(false) to prevent any accidental coding issues (like else being eaten!!!) --- common/logsys.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/logsys.h b/common/logsys.h index 3933e7062..84741cdb4 100644 --- a/common/logsys.h +++ b/common/logsys.h @@ -92,8 +92,8 @@ extern void log_raw_packet(LogType type, uint16 seq, const BasePacket *p); class Mob; extern void log_message_mob(LogType type, Mob *who, const char *fmt, ...); #define mlog( type, format, ...) \ - if(IsLoggingEnabled()) \ do { \ + if(IsLoggingEnabled()) \ if(log_type_info[ type ].enabled) { \ log_message_mob(type, this, format, ##__VA_ARGS__); \ } \ @@ -150,16 +150,16 @@ extern void log_raw_packet(LogType type, uint16 seq, const BasePacket *p); class Mob; extern void log_hex_mob(LogType type, Mob *who, const char *data, uint32 length); #define mhex( type, data, len) \ - if(IsLoggingEnabled()) \ do { \ + if(IsLoggingEnabled()) \ if(log_type_info[ type ].enabled) { \ log_hex_mob(type, this, data, len); \ } \ } while(false) extern void log_packet_mob(LogType type, Mob *who, const BasePacket *p); #define mpkt( type, packet) \ - if(IsLoggingEnabled()) \ do { \ + if(IsLoggingEnabled()) \ if(log_type_info[ type ].enabled) { \ log_packet_mob(type, this, packet); \ } \ From 1d0a6bdc7192d2a2d030fd77a6611cbd458bdc81 Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 5 Sep 2014 16:16:56 -0400 Subject: [PATCH 78/89] Fix for losing 2nd and 3rd cursor items after zoning --- changelog.txt | 3 + common/shareddb.cpp | 19 +++--- zone/client_process.cpp | 2 - zone/inventory.cpp | 143 +++++++++++++++++++++++++++++++++------- 4 files changed, 134 insertions(+), 33 deletions(-) diff --git a/changelog.txt b/changelog.txt index 6c2ee0841..ef6c5591a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 09/05/2014 == +Uleat: Fix for cursor item loss when zoning. (Thanks to the other devs who traced and fixed the 'macro' issue!) + == 09/03/2014 == Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor. demonstar55: Added work around command to show numhits on your buffs (#shownumhits) diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 58a75a261..4485851c1 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -143,19 +143,22 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) { bool SharedDatabase::SaveCursor(uint32 char_id, std::list::const_iterator &start, std::list::const_iterator &end) { -iter_queue it; -int i; -bool ret=true; + iter_queue it; + int i; + bool ret = true; char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; // Delete cursor items - if ((ret = RunQuery(query, MakeAnyLenString(&query, "DELETE FROM inventory WHERE charid=%i AND ( (slotid >=8000 and slotid<=8999) or slotid=%i or (slotid>=%i and slotid<=%i))", char_id, MainCursor,EmuConstants::CURSOR_BAG_BEGIN,EmuConstants::CURSOR_BAG_END), errbuf))) { - for(it=start,i=8000;it!=end;++it,i++) { - ItemInst *inst=*it; - if (!(ret=SaveInventory(char_id,inst,(i==8000) ? MainCursor : i))) + if ((ret = RunQuery(query, MakeAnyLenString(&query, "DELETE FROM inventory WHERE charid = %i AND ((slotid >= 8000 AND slotid <= 8999) OR slotid = %i OR (slotid >= %i AND slotid <= %i))", + char_id, MainCursor, EmuConstants::CURSOR_BAG_BEGIN, EmuConstants::CURSOR_BAG_END), errbuf))) { + + for (it = start, i = 8000; it != end; ++it, i++) { + ItemInst *inst = *it; + if (!(ret = SaveInventory(char_id, inst, (i == 8000) ? MainCursor : i))) break; } - } else { + } + else { std::cout << "Clearing cursor failed: " << errbuf << std::endl; } safe_delete_array(query); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index e39cef0bd..61f4936c8 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -836,8 +836,6 @@ void Client::BulkSendInventoryItems() { } } - // Where are cursor buffer items processed? They need to be validated as well... -U - bool deletenorent = database.NoRentExpired(GetName()); if(deletenorent){ RemoveNoRent(false); } //client was offline for more than 30 minutes, delete no rent items diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 197841c76..4b35112a8 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -2002,11 +2002,10 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) { } void Client::RemoveNoRent(bool client_update) { + int16 slot_id = 0; - int16 slot_id; - - // personal - for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) { + // equipment + for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) { const ItemInst* inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); @@ -2014,11 +2013,22 @@ void Client::RemoveNoRent(bool client_update) { } } + // general + for (slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; slot_id++) { + const ItemInst* inst = m_inv[slot_id]; + if (inst && !inst->GetItem()->NoRent) { + mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + DeleteItemInInventory(slot_id, 0, client_update); + } + } + // power source - const ItemInst* inst = m_inv[MainPowerSource]; - if(inst && !inst->GetItem()->NoRent) { - mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, MainPowerSource); - DeleteItemInInventory(MainPowerSource, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent + if (m_inv[MainPowerSource]) { + const ItemInst* inst = m_inv[MainPowerSource]; + if (inst && !inst->GetItem()->NoRent) { + mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, MainPowerSource); + DeleteItemInInventory(MainPowerSource, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent + } } // containers @@ -2065,15 +2075,41 @@ void Client::RemoveNoRent(bool client_update) { DeleteItemInInventory(slot_id, 0, false); // Can't delete from client Shared Bank Container slots } } + + // cursor & limbo + if (!m_inv.CursorEmpty()) { + std::list local; + ItemInst* inst = nullptr; + + while (!m_inv.CursorEmpty()) { + inst = m_inv.PopItem(MainCursor); + if (inst) + local.push_back(inst); + } + + std::list::iterator iter = local.begin(); + while (iter != local.end()) { + inst = *iter; + if (!inst->GetItem()->NoRent) + mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from `Limbo`", inst->GetItem()->Name); + else + m_inv.PushCursor(**iter); + + safe_delete(*iter); + iter = local.erase(iter); + } + + database.SaveCursor(this->character_id, m_inv.cursor_begin(), m_inv.cursor_end()); + local.clear(); + } } // Two new methods to alleviate perpetual login desyncs void Client::RemoveDuplicateLore(bool client_update) { - // Split-charge stacking may be added at some point -U - int16 slot_id; + int16 slot_id = 0; - // personal - for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) { + // equipment + for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) { ItemInst* inst = m_inv.PopItem(slot_id); if(inst) { if(CheckLoreConflict(inst->GetItem())) { @@ -2087,17 +2123,34 @@ void Client::RemoveDuplicateLore(bool client_update) { } } + // general + for (slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; slot_id++) { + ItemInst* inst = m_inv.PopItem(slot_id); + if (inst) { + if (CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + database.SaveInventory(character_id, nullptr, slot_id); + } + else { + m_inv.PutItem(slot_id, *inst); + } + safe_delete(inst); + } + } + // power source - ItemInst* inst = m_inv.PopItem(MainPowerSource); - if(inst) { - if(CheckLoreConflict(inst->GetItem())) { - mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); - database.SaveInventory(character_id, nullptr, MainPowerSource); + if (m_inv[MainPowerSource]) { + ItemInst* inst = m_inv.PopItem(MainPowerSource); + if (inst) { + if (CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + database.SaveInventory(character_id, nullptr, MainPowerSource); + } + else { + m_inv.PutItem(MainPowerSource, *inst); + } + safe_delete(inst); } - else { - m_inv.PutItem(MainPowerSource, *inst); - } - safe_delete(inst); } // containers @@ -2146,11 +2199,55 @@ void Client::RemoveDuplicateLore(bool client_update) { } // Shared Bank and Shared Bank Containers are not checked due to their allowing duplicate lore items -U + + // cursor & limbo + if (!m_inv.CursorEmpty()) { + std::list local; + ItemInst* inst = nullptr; + + while (!m_inv.CursorEmpty()) { + inst = m_inv.PopItem(MainCursor); + if (inst) + local.push_back(inst); + } + + std::list::iterator iter = local.begin(); + while (iter != local.end()) { + inst = *iter; + if (CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name); + safe_delete(*iter); + iter = local.erase(iter); + } + else { + ++iter; + } + } + + iter = local.begin(); + while (iter != local.end()) { + inst = *iter; + if (!inst->GetItem()->LoreFlag || + ((inst->GetItem()->LoreGroup == -1) && (m_inv.HasItem(inst->GetID(), 0, invWhereCursor) == INVALID_INDEX)) || + (inst->GetItem()->LoreGroup && ~inst->GetItem()->LoreGroup && (m_inv.HasItemByLoreGroup(inst->GetItem()->LoreGroup, invWhereCursor) == INVALID_INDEX))) { + + m_inv.PushCursor(**iter); + } + else { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name); + } + + safe_delete(*iter); + iter = local.erase(iter); + } + + database.SaveCursor(this->character_id, m_inv.cursor_begin(), m_inv.cursor_end()); + local.clear(); + } } void Client::MoveSlotNotAllowed(bool client_update) { - - int16 slot_id; + int16 slot_id = 0; // equipment for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) { From 6186c3d866ccd7246afa036efb2cce233a590981 Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 5 Sep 2014 16:46:03 -0400 Subject: [PATCH 79/89] Fix for gcc failure - Can't fix stupid! --- zone/inventory.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 4b35112a8..a4625bf80 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -2099,7 +2099,8 @@ void Client::RemoveNoRent(bool client_update) { iter = local.erase(iter); } - database.SaveCursor(this->character_id, m_inv.cursor_begin(), m_inv.cursor_end()); + std::list::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + database.SaveCursor(this->CharacterID(), s, e); local.clear(); } } @@ -2241,7 +2242,8 @@ void Client::RemoveDuplicateLore(bool client_update) { iter = local.erase(iter); } - database.SaveCursor(this->character_id, m_inv.cursor_begin(), m_inv.cursor_end()); + std::list::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + database.SaveCursor(this->CharacterID(), s, e); local.clear(); } } From a1e425f9367fdf9d066140235dfc2c8d01adc2ed Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 5 Sep 2014 21:55:35 -0400 Subject: [PATCH 80/89] Fix indentation of ZoneDatabase::AddWPForSpawn --- zone/waypoints.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index c3a19a6f3..ec5a8dfac 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1245,45 +1245,45 @@ void ZoneDatabase::DeleteWaypoint(Client *client, uint32 grid_num, uint32 wp_num uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading) { uint32 grid_num; // The grid number the spawn is assigned to (if spawn has no grid, will be the grid number we end up creating) - uint32 next_wp_num; // The waypoint number we should be assigning to the new waypoint + uint32 next_wp_num; // The waypoint number we should be assigning to the new waypoint bool createdNewGrid; // Did we create a new grid in this function? // See what grid number our spawn is assigned std::string query = StringFormat("SELECT pathgrid FROM spawn2 WHERE id = %i", spawn2id); auto results = QueryDatabase(query); if (!results.Success()) { - // Query error + // Query error LogFile->write(EQEMuLog::Error, "Error setting pathgrid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return 0; } if (results.RowCount() == 0) - return 0; + return 0; - auto row = results.begin(); - grid_num = atoi(row[0]); + auto row = results.begin(); + grid_num = atoi(row[0]); if (grid_num == 0) { // Our spawn doesn't have a grid assigned to it -- we need to create a new grid and assign it to the spawn createdNewGrid = true; grid_num = GetFreeGrid(zoneid); if(grid_num == 0) // There are no grids for the current zone -- create Grid #1 - grid_num = 1; + grid_num = 1; - query = StringFormat("INSERT INTO grid SET id = '%i', zoneid = %i, type ='%i', type2 = '%i'", - grid_num, zoneid, type1, type2); - results = QueryDatabase(query); + query = StringFormat("INSERT INTO grid SET id = '%i', zoneid = %i, type ='%i', type2 = '%i'", + grid_num, zoneid, type1, type2); + results = QueryDatabase(query); if(!results.Success()) LogFile->write(EQEMuLog::Error, "Error adding grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) - client->LogSQL(query.c_str()); + client->LogSQL(query.c_str()); query = StringFormat("UPDATE spawn2 SET pathgrid = '%i' WHERE id = '%i'", grid_num, spawn2id); results = QueryDatabase(query); if(!results.Success()) LogFile->write(EQEMuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) - client->LogSQL(query.c_str()); + client->LogSQL(query.c_str()); } else // NPC had a grid assigned to it createdNewGrid = false; @@ -1296,20 +1296,20 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, return 0; } - row = results.begin(); - if(row[0] != 0) - next_wp_num = atoi(row[0]) + 1; - else // No waypoints in this grid yet + row = results.begin(); + if(row[0] != 0) + next_wp_num = atoi(row[0]) + 1; + else // No waypoints in this grid yet next_wp_num = 1; query = StringFormat("INSERT INTO grid_entries(gridid, zoneid, `number`, x, y, z, pause, heading) " - "VALUES (%i, %i, %i, %f, %f, %f, %i, %f)", - grid_num, zoneid, next_wp_num, xpos, ypos, zpos, pause, heading); - results = QueryDatabase(query); + "VALUES (%i, %i, %i, %f, %f, %f, %i, %f)", + grid_num, zoneid, next_wp_num, xpos, ypos, zpos, pause, heading); + results = QueryDatabase(query); if(!results.Success()) LogFile->write(EQEMuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) - client->LogSQL(query.c_str()); + client->LogSQL(query.c_str()); return createdNewGrid? grid_num: 0; } From f69eccc42b01807479593dfa40c9339beab3f2f6 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 5 Sep 2014 21:56:49 -0400 Subject: [PATCH 81/89] Add missing QueryDatabase in ZoneDatabase::AddWPForSpawn --- zone/waypoints.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index ec5a8dfac..580b9c51c 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -1291,6 +1291,7 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, // Find out what the next waypoint is for this grid query = StringFormat("SELECT max(`number`) FROM grid_entries WHERE zoneid = '%i' AND gridid = '%i'", zoneid, grid_num); + results = QueryDatabase(query); if(!results.Success()) { // Query error LogFile->write(EQEMuLog::Error, "Error getting next waypoint id '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return 0; From 2ef43212e1706b542860230894204dbbfdcd15cd Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 5 Sep 2014 22:36:44 -0400 Subject: [PATCH 82/89] Fix size issue with Lua_Mob::SendIllusionPacket Mob::SendIllusionPacket was expecting the size to be 0xFFFFFFFF to default rather than -1.0f --- changelog.txt | 3 +++ zone/lua_mob.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index ef6c5591a..5b92fd533 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 09/05/2014 == +demonstar55: Fix size getting nuked with lua's SendIllusionPacket + == 09/05/2014 == Uleat: Fix for cursor item loss when zoning. (Thanks to the other devs who traced and fixed the 'macro' issue!) diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 50a8b50a7..4156a3a5c 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1451,7 +1451,7 @@ void Lua_Mob::SendIllusionPacket(luabind::adl::object illusion) { uint32 drakkin_heritage = 4294967295; uint32 drakkin_tattoo = 4294967295; uint32 drakkin_details = 4294967295; - float size = -1.0f; + float size = 0xFFFFFFFF; auto cur = illusion["race"]; if(luabind::type(cur) != LUA_TNIL) { From 3cda62acf4de8b46ac6b6bd478f99b0f02f3c9c6 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 5 Sep 2014 22:38:32 -0400 Subject: [PATCH 83/89] Fix changelog [skip ci] --- changelog.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/changelog.txt b/changelog.txt index 5b92fd533..dbec89c3d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,10 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- -== 09/05/2014 == -demonstar55: Fix size getting nuked with lua's SendIllusionPacket - == 09/05/2014 == Uleat: Fix for cursor item loss when zoning. (Thanks to the other devs who traced and fixed the 'macro' issue!) +demonstar55: Fix size getting nuked with lua's SendIllusionPacket == 09/03/2014 == Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor. From ba0e4bfc1d8a0f99b3f5733b6bc638140051df40 Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 5 Sep 2014 21:18:35 -0700 Subject: [PATCH 84/89] Bizarre issue reported with SendIllusionPacket corrupting size in lua, dunno if this fixes it but fingers crossed. --- zone/lua_mob.cpp | 2 +- zone/mob.cpp | 2 +- zone/mob.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 4156a3a5c..50a8b50a7 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -1451,7 +1451,7 @@ void Lua_Mob::SendIllusionPacket(luabind::adl::object illusion) { uint32 drakkin_heritage = 4294967295; uint32 drakkin_tattoo = 4294967295; uint32 drakkin_details = 4294967295; - float size = 0xFFFFFFFF; + float size = -1.0f; auto cur = illusion["race"]; if(luabind::type(cur) != LUA_TNIL) { diff --git a/zone/mob.cpp b/zone/mob.cpp index 0d7002253..e3a23efc6 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1460,7 +1460,7 @@ void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture, else this->drakkin_details = in_drakkin_details; - if (in_size == 0xFFFFFFFF) + if (in_size <= 0.0f) this->size = GetSize(); else this->size = in_size; diff --git a/zone/mob.h b/zone/mob.h index 80ecaee49..028f0497f 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -563,7 +563,7 @@ public: uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF, uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF, uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF, - uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = 0xFFFFFFFF); + uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = -1.0f); virtual void Stun(int duration); virtual void UnStun(); inline void Silence(bool newval) { silenced = newval; } From 281b32123716004dff5fc119f484cb3415755f51 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sat, 6 Sep 2014 12:45:45 -0400 Subject: [PATCH 85/89] Changed trade behavior to prioritize all main slots before sub slots --- changelog.txt | 3 +++ common/item.cpp | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index dbec89c3d..23640f7e5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 09/06/2014 == +Uleat: Tweaked 'Smart' trading code to return main slots before sub slots in stackable and free space search processes. (If enough people ask for it, I'll add an optional rule to allow 'bag packing' - the original implementation behavior) + == 09/05/2014 == Uleat: Fix for cursor item loss when zoning. (Thanks to the other devs who traced and fixed the 'macro' issue!) demonstar55: Fix size getting nuked with lua's SendIllusionPacket diff --git a/common/item.cpp b/common/item.cpp index bbb6f14f8..127f85614 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -683,6 +683,13 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { if ((main_inst->GetID() == inst->GetID()) && (main_inst->GetCharges() < main_inst->GetItem()->StackSize)) return free_slot; + } + + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) { + const ItemInst* main_inst = m_inv[free_slot]; + + if (!main_inst) + continue; if (main_inst->IsType(ItemClassContainer)) { // if item-specific containers already have bad items, we won't fix it here... for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) { @@ -732,8 +739,12 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { if (!main_inst) return free_slot; + } - if (main_inst->IsType(ItemClassContainer)) { + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) { + const ItemInst* main_inst = m_inv[free_slot]; + + if (main_inst && main_inst->IsType(ItemClassContainer)) { if ((main_inst->GetItem()->BagSize < inst->GetItem()->Size) || (main_inst->GetItem()->BagType == BagTypeBandolier) || (main_inst->GetItem()->BagType == BagTypeQuiver)) continue; From c3e7c48939518edd40e618841ab60a9055e25f33 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sat, 6 Sep 2014 16:19:32 -0400 Subject: [PATCH 86/89] Fix ItemTimerCheck() range criteria typo --- zone/client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/client.cpp b/zone/client.cpp index 30bf428a3..8340dde9f 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7978,7 +7978,7 @@ void Client::ItemTimerCheck() TryItemTimer(i); } - for(i = EmuConstants::GENERAL_BAGS_BEGIN; i <= MainCursor; i++) + for(i = EmuConstants::GENERAL_BEGIN; i <= MainCursor; i++) { TryItemTimer(i); } From 986a424322fcd9663f8235e3675158cbd6ea38c2 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 6 Sep 2014 14:31:02 -0700 Subject: [PATCH 87/89] Fix for perl api illusion --- zone/perl_mob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 14d84a70e..53a5aade8 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -7140,7 +7140,7 @@ XS(XS_Mob_SendIllusion) uint32 drakkin_heritage = 0xFFFFFFFF; uint32 drakkin_tattoo = 0xFFFFFFFF; uint32 drakkin_details = 0xFFFFFFFF; - float size = 0xFFFFFFFF; + float size = -1.0f; if (sv_derived_from(ST(0), "Mob")) { IV tmp = SvIV((SV*)SvRV(ST(0))); From 92c9ff6e53a6cc12db969630889695438a8e76a5 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 6 Sep 2014 17:58:42 -0400 Subject: [PATCH 88/89] Fix issue with hpregen in command_npcedit --- zone/command.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/command.cpp b/zone/command.cpp index eff53fcf3..aa7e13760 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -6768,7 +6768,7 @@ void command_npcedit(Client *c, const Seperator *sep) char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; c->Message(15,"NPCID %u now regens %i hitpoints per tick.",c->GetTarget()->CastToNPC()->GetNPCTypeID(),atoi(sep->arg[2])); - database.RunQuery(query, MakeAnyLenString(&query, "update npc_types set hp_regen_rate=%i where hp_regen_rate=%i",atoi(sep->argplus[2]),c->GetTarget()->CastToNPC()->GetNPCTypeID()), errbuf); + database.RunQuery(query, MakeAnyLenString(&query, "update npc_types set hp_regen_rate=%i where id=%i",atoi(sep->argplus[2]),c->GetTarget()->CastToNPC()->GetNPCTypeID()), errbuf); c->LogSQL(query); safe_delete_array(query); } From ffed5a9e22284a4aea034171c026ba564b98793c Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 6 Sep 2014 16:43:36 -0700 Subject: [PATCH 89/89] SQL Injection fix on inspect message setting --- common/shareddb.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 4485851c1..10e3d2012 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -2148,7 +2148,8 @@ void SharedDatabase::SetPlayerInspectMessage(char* playername, const InspectMess char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET inspectmessage='%s' WHERE name='%s'", message->text, playername), errbuf)) { + std::string msg = EscapeString(message->text); + if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET inspectmessage='%s' WHERE name='%s'", msg.c_str(), playername), errbuf)) { std::cerr << "Error in SetPlayerInspectMessage query '" << query << "' " << errbuf << std::endl; } @@ -2183,7 +2184,8 @@ void SharedDatabase::SetBotInspectMessage(uint32 botid, const InspectMessage_Str char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE bots SET BotInspectMessage='%s' WHERE BotID=%i", message->text, botid), errbuf)) { + std::string msg = EscapeString(message->text); + if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE bots SET BotInspectMessage='%s' WHERE BotID=%i", msg.c_str(), botid), errbuf)) { std::cerr << "Error in SetBotInspectMessage query '" << query << "' " << errbuf << std::endl; }