Code:
Index: zone/mob.h
===================================================================
--- zone/mob.h (revision 110)
+++ zone/mob.h (working copy)
@@ -455,7 +455,8 @@
inline Mob* GetTarget() const { return target; }
virtual void SetTarget(Mob* mob);
virtual inline float GetHPRatio() const { return max_hp == 0 ? 0 : ((float)cur_hp/max_hp*100); }
-
+ float GetLWDistance() { return last_warp_distance; } //Null: these are used to return the values to #showstats
+ float GetWarpThreshold() { return warp_threshold; } //this one too
bool IsLoggingEnabled() const { return(logging_enabled); }
void EnableLogging() { logging_enabled = true; }
void DisableLogging() { logging_enabled = false; }
@@ -783,6 +784,10 @@
//temporary:
bool fix_pathing;
+ Timer cheat_timer; //Lieka: Timer used to check for movement exemptions/client-based, unsolicited zone exemptions
+ Timer threshold_timer; //Null: threshold timer
+ float warp_threshold; //Null: threshold for warp detector
+ float last_warp_distance; //Null: last distance logged as a warp, used for logs and #showstats
inline float GetCWPX() const { return(cur_wp_x); }
inline float GetCWPY() const { return(cur_wp_y); }
inline float GetCWPZ() const { return(cur_wp_z); }
Index: zone/zoning.cpp
===================================================================
--- zone/zoning.cpp (revision 110)
+++ zone/zoning.cpp (working copy)
@@ -55,6 +55,7 @@
case ZoneToSafeCoords:
//going to safe coords, but client dosent know where?
//assume it is this zone for now.
+ cheat_timer.Start(35000,false); //Lieka: Allow Zone/Evac to Safe Coords without triggering MQWarp detector.
target_zone_id = zone->GetZoneID();
break;
case GMSummon:
@@ -74,10 +75,13 @@
if(zone_point) {
//we found a zone point, which is a reasonable distance away
//assume that is the one were going with.
+ cheat_timer.Start(3500,false); //Lieka: Allow Zone normal zoning without triggering MQZone detector.
target_zone_id = zone_point->target_zone_id;
} else {
//unable to find a zone point... is there anything else
//that can be a valid un-zolicited zone request?
+
+ this->CheatDetected(MQZone); //Lieka: Bring down the hammer, they are trying to zone without meeting any of the above criteria.
Message(13, "Invalid unsolicited zone request.");
LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
@@ -105,6 +109,11 @@
if(!zone_point || zone_point->target_zone_id != target_zone_id) {
Message(13, "Invalid unsolicited zone request.");
LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
+
+ if ((this->cheat_timer.GetRemainingTime())<1 || (!this->cheat_timer.Enabled())){ //Lieka: Disable MQGate Detector if timer is active.
+ this->CheatDetected(MQGate);
+ }
+
SendZoneCancel(zc);
return;
}
@@ -168,6 +177,7 @@
ignorerestrictions = 1; //can always get to our bind point? seems exploitable
break;
case ZoneSolicited: //we told the client to zone somewhere, so we know where they are going.
+ cheat_timer.Start(3500,false); //Lieka: Allow Server Forced Zoning without triggering MQZone detector.
//recycle zonesummon variables
dest_x = zonesummon_x;
dest_y = zonesummon_y;
@@ -204,6 +214,7 @@
//for now, there are no other cases...
//could not find a valid reason for them to be zoning, stop it.
+ this->CheatDetected(MQZone); //Lieka: Bring down the hammer, we don't let hackers off that easily...
Message(13, "Invalid unsolicited zone request.");
LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%s'. Not near a zone point.", GetName(), target_zone_name);
SendZoneCancel(zc);
@@ -218,12 +229,15 @@
//not sure when we would use ZONE_ERROR_NOTREADY
//enforce min status and level
- if (!ignorerestrictions && (Admin() < minstatus || GetLevel() < minlevel))
+ if (!ignorerestrictions && (Admin() < minstatus || GetLevel() < minlevel)) {
+ this->cheat_timer.Start(3500,false); //Lieka: Don't set off warp detector for when a player is moved to the safe-spot for trying to access a zone without the appropriate level or status requirements (i.e. zoning into FearPlane at level 30, etc)
myerror = ZONE_ERROR_NOEXPERIENCE;
+ }
if(!ignorerestrictions && flag_needed[0] != '\0') {
//the flag needed string is not empty, meaning a flag is required.
if(Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(target_zone_id)) {
+ this->cheat_timer.Start(3500,false); //Lieka: Don't set off warp detector for when a player is moved to the safe-spot for trying to access a zone without the appropriate flag.
Message(13, "You must have the flag %s to enter this zone.");
myerror = ZONE_ERROR_NOEXPERIENCE;
}
@@ -265,6 +279,7 @@
//effectively zone them right back to where they were
//unless we find a better way to stop the zoning process.
EQApplicationPacket *outapp;
+ cheat_timer.Start(3500,false); //Lieka: Disable MQ Warp & MQ Gate Detector when zoning fails. (not high enough level, etc)
outapp = new EQApplicationPacket(OP_ZoneChange, sizeof(ZoneChange_Struct));
ZoneChange_Struct *zc2 = (ZoneChange_Struct*)outapp->pBuffer;
strcpy(zc2->char_name, zc->char_name);
@@ -279,6 +294,7 @@
void Client::SendZoneError(ZoneChange_Struct *zc, sint8 err) {
LogFile->write(EQEMuLog::Error, "Zone %i is not available because target wasn't found or character insufficent level", zc->zoneID);
+ cheat_timer.Start(3500,false);//Lieka: Disable /Warp & /Gate Detector when zoning fails. (not high enough level, etc)
EQApplicationPacket *outapp;
outapp = new EQApplicationPacket(OP_ZoneChange, sizeof(ZoneChange_Struct));
@@ -424,57 +440,64 @@
database.GetZoneLongName(pShortZoneName, &pZoneName);
iZoneNameLength = strlen(pZoneName);
- switch(zm) {
- case EvacToSafeCoords:
- case ZoneToSafeCoords:
- x = zone->safe_x();
- y = zone->safe_y();
- z = zone->safe_z();
- heading = heading;
- break;
- case GMSummon:
- zonesummon_x = x_pos = x;
- zonesummon_y = y_pos = y;
- zonesummon_z = z_pos = z;
- heading = heading;
-
- zonesummon_id = zoneID;
- zonesummon_ignorerestrictions = 1;
- break;
- case ZoneSolicited:
- zonesummon_x = x;
- zonesummon_y = y;
- zonesummon_z = z;
- heading = heading;
-
- zonesummon_id = zoneID;
- zonesummon_ignorerestrictions = ignorerestrictions;
- break;
- case GateToBindPoint:
- x = x_pos = m_pp.binds[0].x;
- y = y_pos = m_pp.binds[0].y;
- z = z_pos = m_pp.binds[0].z;
- heading = m_pp.binds[0].heading;
- break;
- case ZoneToBindPoint:
- x = x_pos = m_pp.binds[0].x;
- y = y_pos = m_pp.binds[0].y;
- z = z_pos = m_pp.binds[0].z;
- heading = m_pp.binds[0].heading;
-
- zonesummon_ignorerestrictions = 1;
- LogFile->write(EQEMuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading);
- break;
- case SummonPC:
- zonesummon_x = x_pos = x;
- zonesummon_y = y_pos = y;
- zonesummon_z = z_pos = z;
- heading = heading;
- break;
- default:
- LogFile->write(EQEMuLog::Error, "Client::ZonePC() received a reguest to perform an unsupported client zone operation.");
- ReadyToZone = false;
- break;
+ switch(zm) {
+ case EvacToSafeCoords:
+ this->cheat_timer.Start(2500,false);// Null: added a timers to this location because sometimes the ones in the other locations of code were not doing the job
+ case ZoneToSafeCoords:
+ this->cheat_timer.Start(2500,false);
+ x = zone->safe_x();
+ y = zone->safe_y();
+ z = zone->safe_z();
+ heading = heading;
+ break;
+ case GMSummon:
+ this->cheat_timer.Start(2500,false);
+ zonesummon_x = x_pos = x;
+ zonesummon_y = y_pos = y;
+ zonesummon_z = z_pos = z;
+ heading = heading;
+
+ zonesummon_id = zoneID;
+ zonesummon_ignorerestrictions = 1;
+ break;
+ case ZoneSolicited:
+ this->cheat_timer.Start(2500,false);
+ zonesummon_x = x;
+ zonesummon_y = y;
+ zonesummon_z = z;
+ heading = heading;
+
+ zonesummon_id = zoneID;
+ zonesummon_ignorerestrictions = ignorerestrictions;
+ break;
+ case GateToBindPoint:
+ this->cheat_timer.Start(2500,false);
+ x = x_pos = m_pp.binds[0].x;
+ y = y_pos = m_pp.binds[0].y;
+ z = z_pos = m_pp.binds[0].z;
+ heading = m_pp.binds[0].heading;
+ break;
+ case ZoneToBindPoint:
+ this->cheat_timer.Start(2500,false);
+ x = x_pos = m_pp.binds[0].x;
+ y = y_pos = m_pp.binds[0].y;
+ z = z_pos = m_pp.binds[0].z;
+ heading = m_pp.binds[0].heading;
+
+ zonesummon_ignorerestrictions = 1;
+ LogFile->write(EQEMuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading);
+ break;
+ case SummonPC:
+ this->cheat_timer.Start(2500,false);
+ zonesummon_x = x_pos = x;
+ zonesummon_y = y_pos = y;
+ zonesummon_z = z_pos = z;
+ heading = heading;
+ break;
+ default:
+ LogFile->write(EQEMuLog::Error, "Client::ZonePC() received a reguest to perform an unsupported client zone operation.");
+ ReadyToZone = false;
+ break;
}
if(ReadyToZone) {