EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Archive::Bugs (https://www.eqemulator.org/forums/forumdisplay.php?f=622)
-   -   Ubound characters that die seem to get sent to -3,-3,-3 (https://www.eqemulator.org/forums/showthread.php?t=11856)

vesuvias 02-11-2004 02:59 AM

Ubound characters that die seem to get sent to -3,-3,-3
 
I am not sure if this has been reported before. I am using the latest code from CVS running the MW 053 alpha3 DB.

Apprently If you die while not having been bound yet (perhaps we should make a startingbindpoints db table) you get sent to -3,-3,-3 in the same zone. This is a problem in some zones but in others (ie vahlshar) it can lead to repeated falling death loops.

I inspected the code and traced the problem to handlepacket inside client_process.cpp. The offending bug I believe is centered on this section:
Code:

if (!database.GetSafePoints(target_zone, &tarx, &tary, &tarz, &minstatus, &minlevel)) {
                                                target_zone[0] = 0;
                                        }
                                        int8 tmpzonesummon_ignorerestrictions = zonesummon_ignorerestrictions;
                                        if (zonesummon_ignorerestrictions) {
                                                minstatus = 0;
                                                minlevel = 0;
                                        }
                                        zonesummon_ignorerestrictions = 0;
                                       
                                        ZonePoint* zone_point = zone->GetClosestZonePoint(x_pos, y_pos, z_pos, zc->zoneID);
               
                                        tarx=zonesummon_x;
                                        tary=zonesummon_y;
                                        tarz=zonesummon_z;
                                       
                                        // -1, -1, -1 = code for zone safe point
                                        if ((x_pos == -1 && y_pos == -1 && (z_pos == -1 || z_pos == -10)) ||
                                                (zonesummon_x == -1 && zonesummon_y == -1 && (zonesummon_z == -1 || zonesummon_z == -10))) {
                                                cout << "Zoning to safe coords: " << target_zone << " (" << database.GetZoneID(target_zone) << ")" << endl;
                                                tarx=database.GetSafePoint(target_zone, "x");
                                                tary=database.GetSafePoint(target_zone, "y");
                                                tarz=database.GetSafePoint(target_zone, "z");
                                                zonesummon_x = -2;
                                                zonesummon_y = -2;
                                                zonesummon_z = -2;
                                        }
                                        // -3 -3 -3 = bind point
                                        else if (zonesummon_x == -3 && zonesummon_y == -3 && (zonesummon_z == -3 || zonesummon_z == -30) && database.GetZoneName(m_pp.bind_zone_id)) {
                                                strcpy(target_zone, database.GetZoneName(m_pp.bind_zone_id));
                                                tarx = m_pp.bind_x;
                                                tary = m_pp.bind_y;
                                                tarz = m_pp.bind_z;
                                                zonesummon_x = -2;
                                                zonesummon_y = -2;
                                                zonesummon_z = -2;
                                                minstatus = 0;
                                                minlevel = 0;
                                        }
                                        else if (zone_point != 0) {
                                                if(zone_point->target_x==999999)
                                                        tarx=GetX();
                                                else
                                                        tarx = zone_point->target_x;
                                                if(zone_point->target_y==999999)
                                                        tary=GetY();
                                                else
                                                        tary = zone_point->target_y;
                                                if(zone_point->target_z==999999)
                                                        tarz=GetZ();
                                                else
                                                        tarz = zone_point->target_z;
                                                tarheading = zone_point->target_heading;
                                        }
                                        // if not -2 -2 -2, zone to these coords. -2, -2, -2 = not a zonesummon zonerequest
                                        else if (!(zonesummon_x == -2 && zonesummon_y == -2 && (zonesummon_z == -2 || zonesummon_z == -20))) {
                                                tarx = zonesummon_x;
                                                tary = zonesummon_y;
                                                tarz = zonesummon_z;
                                                zonesummon_x = -2;
                                                zonesummon_y = -2;
                                                zonesummon_z = -2;
                                        }
                                        else {
                                                cout << "WARNING: No target coords for this zone in DB found" << endl;
                                                cout << "Zoning to safe coords: " << target_zone << " (" << database.GetZoneID(target_zone) << ")" << ", x=" << tarx << ", y=" << tary << ", z=" << tarz << endl;
                                                tarx=-1;
                                                tary=-1;
                                                tarz=-1;
                                                zonesummon_x = -2;
                                                zonesummon_y = -2;
                                                zonesummon_z = -2;
                                        }

Now my C++ is rather rusty (but its coming back, I am a Java guy by trade) but this
Code:

else {
                                                cout << "WARNING: No target coords for this zone in DB found" << endl;
                                                cout << "Zoning to safe coords: " << target_zone << " (" << database.GetZoneID(target_zone) << ")" << ", x=" << tarx << ", y=" << tary << ", z=" << tarz << endl;
                                                tarx=-1;
                                                tary=-1;
                                                tarz=-1;
                                                zonesummon_x = -2;
                                                zonesummon_y = -2;
                                                zonesummon_z = -2;
                                        }

Seems really strange. Why would you print out the correct loc of the safe area and then proceed to wipe out your only record of those coords? Anyway like I said I am still a little rusty so I was hoping some more code experienced devs might be able to shed some light on the situation.

Try not to give me too much shit, at least I took the time to track down where I think the problem lies as oppossed to just whinning about it. :D

Ves

farce 02-11-2004 03:07 AM

I agree that looks fishy.

toolh3 02-11-2004 05:00 AM

Have you tried changing that else block to this:
Code:

else
{
  cout << "WARNING: No target coords for this zone in DB found" << endl;
  cout << "Zoning to safe coords: " << target_zone << " (" << database.GetZoneID(target_zone) << ")" << ", x=" << tarx << ", y=" << tary << ", z=" << tarz << endl;
  tarx=database.GetSafePoint(target_zone, "x");
  tary=database.GetSafePoint(target_zone, "y");
  tarz=database.GetSafePoint(target_zone, "z");
  zonesummon_x = -2;
  zonesummon_y = -2;
  zonesummon_z = -2;
}

If it is truly supposed to send you to the safe point in the zone (which the cout message certainly explains) then I believe this is the code to do it. I just took the code from the first if block which does send you to the safe point.

I think the original idea the devs have here is that this OP_ZoneChange case block is going to be hit again because of this code block:
Code:

if (m_pp.zone_id == zone->GetZoneID())
{
  // No need to ask worldserver if we're zoning to ourselves (most
  // likely to a bind point), also fixes a bug since the default response was failure
  APPLAYER* outapp = new APPLAYER(OP_ZoneChange,sizeof(ZoneChange_Struct));
  ZoneChange_Struct* zc2 = (ZoneChange_Struct*) outapp->pBuffer;
  strcpy(zc2->char_name, GetName());
  zc2->zoneID = m_pp.zone_id;
  zc2->success = 1;
  QueuePacket(outapp);
  safe_delete(outapp);
  zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000);
}

That block gets executed if you are zoning to the same zone, I believe. So then next time through the loop, x_pos, y_pos, and z_pos should equal 1 which should hit the first if block and send you to the zone safe points. Now this is all just speculation from looking at the code for about 10 minutes. A real dev would probably have a better answer to this.

vesuvias 02-11-2004 06:10 AM

Quote:

Originally Posted by toolh3
I think the original idea the devs have here is that this OP_ZoneChange case block is going to be hit again because of this code block:
Code:

if (m_pp.zone_id == zone->GetZoneID())
{
  // No need to ask worldserver if we're zoning to ourselves (most
  // likely to a bind point), also fixes a bug since the default response was failure
  APPLAYER* outapp = new APPLAYER(OP_ZoneChange,sizeof(ZoneChange_Struct));
  ZoneChange_Struct* zc2 = (ZoneChange_Struct*) outapp->pBuffer;
  strcpy(zc2->char_name, GetName());
  zc2->zoneID = m_pp.zone_id;
  zc2->success = 1;
  QueuePacket(outapp);
  safe_delete(outapp);
  zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000);
}


I think your right about that, however what prevents us from hitting this same block of code when we run through OP_ZoneChange a second time?

Quote:

Originally Posted by toolh3
Code:

else
{
  cout << "WARNING: No target coords for this zone in DB found" << endl;
  cout << "Zoning to safe coords: " << target_zone << " (" << database.GetZoneID(target_zone) << ")" << ", x=" << tarx << ", y=" << tary << ", z=" << tarz << endl;
  tarx=database.GetSafePoint(target_zone, "x");
  tary=database.GetSafePoint(target_zone, "y");
  tarz=database.GetSafePoint(target_zone, "z");
  zonesummon_x = -2;
  zonesummon_y = -2;
  zonesummon_z = -2;
}


When I get home today I think I will try this out. But actually since
Code:

if (!database.GetSafePoints(target_zone, &tarx, &tary, &tarz, &minstatus, &minlevel)) {
                                                target_zone[0] = 0;
                                        }

was called before we even enter that compound branch I don't think I even have to specify what tarx, tary and tarz are, they should already have the right values (and we just cout'd them :) )

Interesting... thanks for the input.
Ves

toolh3 02-11-2004 08:01 AM

Quote:

I think your right about that, however what prevents us from hitting this same block of code when we run through OP_ZoneChange a second time?
I was thinking the same thing, but it was the only way I could explain what was happening. The block of code looks kinda messed up anyway. I agree with you that I see no point in calling the function GetSafePoints() and then overwriting them about 5 lines later. And then when we actually want the safe points we call GetSafePoint() for each variable. We are doing two hits on the database when there only needs to be one.


All times are GMT -4. The time now is 03:16 PM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.