PDA

View Full Version : Ranger tracking skillups after tracking session expires


Uleat
05-01-2012, 07:23 AM
I've been experiencing a rather odd bug with my SoF client.

I'm receiving Ranger Tracking skillups after the tracking sessions times out. After a normal amount of tracking time, and the mob is not killed, I receive the message defined by TRACK_LOST_TARGET. After that, I'm still getting random skillups.

What I would normally do is 'track' a non-specific mob, then go about killing in a random manner - never killing the original track mob. I haven't played it out to see if killing the original mob will stop these skillups, but I can if it's needed. Camping out or zoning stops this activity. This is a repeatable bug and the last occurrence was in "The Umbral Plains" with my GM flag on, but it has happened in the past in different zones and non-flagged..as well as on previous revision builds.


I've looked through the code and noticed that Client::DoTracking() (client_process.cpp) is triggered if the client version is SoD or greater. I've also found that the skillup sequence is handled in Client::Handle_OP_ClientUpdate (client_packet.cpp.) Since I couldn't find a function that enabled/disabled the [TrackingTimer] in the server code, I'm guessing that all tracking events are initiated by the client.

I can't figure out if the tracking session cancellation is a server- or client-side event, but something seems to be cancelling it without releasing the client-side TrackingID.


I have a few scenarios of what could be happening, but none may be true:

1) The client or server cancels the tracking session after ## minutes and the client needs to receive a command to clear its TrackingID, but isn't and continues to resend it (though I'm not getting continuous TRACK_LOST_TARGET messages from Client::DoTracking(), just the one..assuming that it's a server-side event trigger. I placed Message(#, "$$$") markers in the DoTracking() sub and never received them, and since my client is pre-SoD, they probably weren't being processed.)

2) Or, maybe that the packet handler's buffer isn't being cleared of the client packet's TrackingID value and that it is still being processed by the IsTracking() function for skillup, but since it's not actually being sent by the client, it doesn't register in the packet stream and isn't raising the tracking event flag. (Again, a guess since I'm learning that the tracking subroutines are probably client-side for SoF.)

3) Assuming that the TrackingID value is received from the client for pre-SoD, is it possible that the client IsTracking is being set to false, but TrackingID isn't cleared and is continuously being sent back to the server and being processed by Client::Handle_OP_ClientUpdate?

4) All of the above. (If in doubt, always choose 'C', err, I mean '4'!)

I'll go back and review those code segments again, looking at it from a client-side event perspective, and see if I can help you guys out with this. (Probably won't amount to much, but anything is better than nothing.)

(For all I know, this could be a non-patched "SoF" client bug...)


If I didn't explain the bug scenario well enough, please ask for clarification.


Current Specs:
-------------
2.6 GHz P4 (no HT)
32-bit WinXP SP3
2GB Ram
---
EmuLoginServer rev2135 compiled on VC10 (Release/Win32; converted VC9 EQEmuLoginServer.sln - *testing*)
Emu rev2135 compiled on VC10 (ReleaseBots/Win32)
PEQ rev2133
MySQL 5.1.62-win32
Perl 5.12.4.1205-win32
Zlib 1.2.3 (I know I should update to the SVN's)
---
"SoF" EQ Client
"non-SoD" opcodes (login & emu_config)
-------------


U

Uleat
05-01-2012, 07:59 AM
What about something like this:


[client_packet.cpp]

void Client::Handle_OP_TrackTarget(const EQApplicationPacket *app)
{
if(GetClientVersion() < EQClientSoD)
return;

else

int PlayerClass = GetClass();

if((PlayerClass != RANGER) && (PlayerClass != DRUID) && (PlayerClass != BARD))
return;

if (app->size != sizeof(TrackTarget_Struct))
{
LogFile->write(EQEMuLog::Error, "Invalid size for OP_TrackTarget: Expected: %i, Got: %i",
sizeof(TrackTarget_Struct), app->size);
return;
}

TrackTarget_Struct *tts = (TrackTarget_Struct*)app->pBuffer;

TrackingID = tts->EntityID;
}


Just a quick thought..I haven't tried it yet, but will this evening when I get up..takes a while to compile on my cpu... Again, this assumes the same tracking function for an SoF as a Ti client.)

Uleat
05-01-2012, 08:03 AM
Disregard... I just realized this will cancel out the skillups as well... Going to sleep now! :)

Uleat
05-01-2012, 08:35 AM
(Argh! Not sleepy...)

This clears TrackingID after a skillup check (pass or fail) for an SoF or Ti client, and assumes that a new TargetID is sent by the client again for the next check if the client is still tracking:


void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
{...

if(IsTracking() && ((x_pos!=ppu->x_pos) || (y_pos!=ppu->y_pos)))
{
if(MakeRandomFloat(0, 100) < 70)//should be good
{
CheckIncreaseSkill(TRACKING, NULL, -20);

if(GetClientVersion() < EQClientSoD)
{
TrackingID=0;
}
}

else

if(GetClientVersion() < EQClientSoD)
{
TrackingID=0;
}

}

...}


Will try tonight...


U

sorvani
05-01-2012, 12:12 PM
code tags for the love of electrons....

Derision
05-01-2012, 03:21 PM
I just did a test with SoF.

The client sends OP_TrackTarget with the target entity ID once, when you begin tracking, and nothing after that.

Exactly 6 minutes later, the client says you have lost your tracking target and doesn't appear to send anything to the server.

I assume therefore, that we need to start a 6 minute timer when we receive the OP_TrackTarget, and assuming the target is still alive when the timer expires, clear TrackingID server-side.

Uleat
05-01-2012, 04:56 PM
Ok, I've modded my code a little better to handle the tracking reset server-side.

Activation of the 'tracking' window is when the skillup is processed. I'm assuming this is the OP_TrackingCode transaction. Regardless of whether I cancel, or select a target and actually track a mob, I receive no more skillups until the next tracking window call.

Is this proper behavior "Live" behavior? Or was there a change in the tracking model once SoD came out (i.e., skill update chance with each DoTracking() call?)

Since I don't know what the intended EQEmu model is suppose to be for tracking skillups, I can't say if my code reflects that design. It does, however, satisfy my own experience and I'll leave it for now :)


I considered a timer as well, but that still left me with the possibility of free tracking skillups, which is what originally brought me here.


This is what I compiled and had the above results with:


if(IsTracking() && ((x_pos!=ppu->x_pos) || (y_pos!=ppu->y_pos)))
{
if(MakeRandomFloat(0, 100) < 70)
{
CheckIncreaseSkill(TRACKING, NULL, -20);
}

if(GetClientVersion() < EQClientSoD)
{
TrackingID=0;
}
}

else

if(IsTracking() && (GetClientVersion() < EQClientSoD))
{
TrackingID=0;
}


Since it's sequential code, I guess dropping the second nested 'if' statement, the 'else', and leaving in the last 'if' would accomplish essentially the same thing without the additional lines.

I'm through spamming this thread :) I'll only post clarifications, if requested. (I don't sleep well and get a little chatty when I'm depraved, err, I mean deprived.)

U