Yes, we merged back with the eqemu source and use Wildcard's updates to the zoning stuff (getting all the bugs worked out of it made for an interesting week on our server

).
Here are the source snippets involved in pulling the zonepoints, then checking them against a zone request.
Here's the code that pulls and checks the zone points:
SQL query that pulls the zone points into the code:
from .\zone\zone.cpp
Code:
bool ZoneDatabase::LoadStaticZonePoints(LinkedList<ZonePoint*>* zone_point_list,const char* zonename)
{
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 FROM zone_points WHERE zone='%s' order by number", zonename);
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]);
zone_point_list->Insert(zp);
zone->numzonepoints++;
}
mysql_free_result(result);
}
else
{
cerr << "Error1 in LoadStaticZonePoints query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
return true;
}
Here is the function that checks for the closest zone points.
Code:
ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, int32 to, float max_distance, Client* client) {
LinkedListIterator<ZonePoint*> iterator(zone_point_list);
ZonePoint* closest_zp = 0;
float closest_dist = FLT_MAX;
float max_distance2 = max_distance*max_distance;
iterator.Reset();
while(iterator.MoreElements())
{
ZonePoint* zp = iterator.GetData();
if (zp->target_zone_id == to)
{
float delta_x = zp->x - x;
float delta_y = zp->y - y;
if(zp->x == 999999 || zp->x == -999999)
delta_x = 0;
if(zp->y == 999999 || zp->y == -999999)
delta_y = 0;
float dist = delta_x*delta_x+delta_y*delta_y;///*+(zp->z-z)*(zp->z-z)*/;
if (dist < closest_dist)
{
closest_zp = zp;
closest_dist = dist;
}
}
iterator.Advance();
}
if(closest_dist>(200.0f*200.0f) && closest_dist<max_distance2)
{
client->CheatDetected(MQZone); //[Paddy] Someone is trying to use /zone
LogFile->write(EQEMuLog::Status, "WARNING: Closest zone point for zone id %d is %f, you might need to update your zone_points table if you dont arrive at the right spot.",to,closest_dist);
LogFile->write(EQEMuLog::Status, "<Real Zone Points>. %f x %f y %fz ",x,y,z);
//worldserver.SendEmoteMessage(0,0,0,13,"<Real Zone Points>. %f x %f y %fz ",x,y,z);
closest_zp = NULL; //Lieka: Prevent the zone request from happening.
}
In the `zone_points` table, your current entries are fine - they're just incomplete. If you
Code:
select * from zone_points where y = 0 && x = 0 && z = 0;
then you will see the entries that need to be updated (pretty much all of them). I've already posted the list for old world zones, but kunark+ need to still be updated.
Basically, when there's an unsolicited zone request from the client (i.e. the client requests a zone change):
The function "ZonePoint* Zone::GetClosestZonePoint(float x, float y, float z, int32 to, float max_distance, Client* client)" compares the x, y (not target_x and target_y) in the records that match the target_zone_id within your zone_points table against the client's current x, y. If the (zonepoint->x - client->x) * (zonepoint->y - client->y) > 4000 (200*200), then it assumes that the zone request is the result of a hack (which it most likely is). So, if you have 0, 0 for a value in your x, y in the zone_points table, then unless the client is attempting to use that zone_point from close to that x, y in the zone, it will detect a /MQZone attempt. If the zone that the client is using is a zone wall (like East Commons -> West Freeport), you'll put 999999 for the x or y (whichever is appropriate), and it will exempt it that (x or y) from the check (because it's too damn hard to draw a line in the database).
Once you update these records in your zone_points table, you can #reloadzps from within that zone (the source zone, not the target zone), and retest them.
I hope that helps,
Dax