May god have mercy on my soul for trying to diff this. I apologize that a lot of it will be redundant checks, but we've had to tweak it quite a bit to get it to the point where it is now. We only have false alarms when we hit a massive lag spike (which happens on occasion), but the only way around that would be to allow massive distance updates all the time - which defeats the purpose.
I know this won't fit into one post, and probably won't even fit into 3 or 4, but I'll do my best to get it all in.
Ok, *gulp* here goes.
Anti-MQ /Warp, Anti-MQ /Gate, Anti-MQ /zone, Anti-MQ /ghost code from the Vallon Zek/Tallon Zek Server:
In addition to myself, contributions to this code came from Rancar and Null.
.\common\ruletypes.h
After:
Code:
RULE_BOOL ( Zone, EnableShadowrest, 0 ) // enables or disables the shadowrest zone feature for player corpses. Default is turned off.
Add:
Code:
RULE_INT ( Zone, MQWarpExemptStatus, 50 ) //Lieka: Required status level to exempt the MQWarpDetector. Set to -1 to disable this feature.
RULE_INT ( Zone, MQZoneExemptStatus, 50 ) //Lieka: Required status level to exempt the MQWarpDetector. Set to -1 to disable this feature.
RULE_INT ( Zone, MQGateExemptStatus, 50 ) //Lieka: Required status level to exempt the MQWarpDetector. Set to -1 to disable this feature.
RULE_INT ( Zone, MQGhostExemptStatus, 50 ) //Lieka: Required status level to exempt the MQWarpDetector. Set to -1 to disable this feature.
RULE_BOOL ( Zone, EnableMQWarpDetector, False ) //Lieka: Enable the MQWarp Detector. Set to False to disable this feature.
RULE_BOOL ( Zone, EnableMQZoneDetector, False ) //Lieka: Enable the MQZone Detector. Set to False to disable this feature.
RULE_BOOL ( Zone, EnableMQGateDetector, False ) //Lieka: Enable the MQGate Detector. Set to False to disable this feature.
RULE_BOOL ( Zone, EnableMQGhostDetector, False ) //Lieka: Enable the MQGhost Detector. Set to False to disable this feature.
RULE_REAL ( Zone, MQWarpDetectorDistance, 30 ) //Lieka: Distance a player must travel between client to server location updates before a warp is registered. 30 allows for beyond GM speed without lag.
RULE_REAL ( Zone, MQWarpLagThreshold, 140 ) //Lieka: Distance beyond the Zone:MQWarpDetectorDistance that a player must travel within the MQWarpThresholdTimer amount of time before tripping the MQWarp detector. Set to 0 to disable this feature.
RULE_REAL ( Zone, MQWarpThresholdTimer, 90000 ) //Lieka: Amount of time before the warp_threshold resets to the Zone:MQWarpLagThreshold value. Default: 90000 (900 seconds/15 minutes). Set to -1 to disable this feature.
RULE_INT ( Zone, MQWarpDetectionSpellID, 757 ) //Lieka: Which spell ID will be cast on players that incur the hammer of the MQ Detector. This spell will be actually cast, don't pick a resistible spell. Default: 757 (Resurrection Effects)
RULE_INT ( Zone, MQGateDetectionSpellID, 757 ) //Lieka: Which spell ID debuff will be cast on players that incur the hammer of the MQGateDetector. This spell will be added as a debuff while zoning. Default: 757 (Resurrection Effects)
RULE_INT ( Zone, MQZoneDetectionSpellID, 757 ) //Lieka: Which spell ID debuff will be cast on players that incur the hammer of the MQGateDetector. This spell will be added as a debuff while zoning. Default: 757 (Resurrection Effects)
RULE_INT ( Zone, MQGhostDetectionSpellID, 757 ) //Lieka: Which spell ID will be cast on players that incur the hammer of the MQGhostDetector. This spell will be actually cast, don't pick a resistable spell. Default: 757 (Resurrection Effects)
.\common\database.h
After:
Code:
bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked);
Add:
Code:
bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone);
.\common\database.cpp
After:
Code:
bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
int32 affected_rows = 0;
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO hackers(account,name,hacked) values('%s','%s','%s')", accountname, charactername, hacked), errbuf, 0,&affected_rows)) {
cerr << "Error in SetHackerFlag query '" << query << "' " << errbuf << endl;
return false;
}
safe_delete_array(query);
if (affected_rows == 0)
{
return false;
}
return true;
}
Add:
Code:
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) { //Lieka: Utilize the "hacker" table, but also give zone information.
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
int32 affected_rows = 0;
if (!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone), errbuf, 0,&affected_rows)) {
cerr << "Error in SetMQDetectionFlag query '" << query << "' " << errbuf << endl;
return false;
}
safe_delete_array(query);
if (affected_rows == 0)
{
return false;
}
return true;
}
.\zone\client.h
After:
Code:
typedef enum {
ZoneToSafeCoords, // Always send ZonePlayerToBind_Struct to client: Succor/Evac
GMSummon, // Always send ZonePlayerToBind_Struct to client: Only a GM Summon
ZoneToBindPoint, // Always send ZonePlayerToBind_Struct to client: Death Only
ZoneSolicited, // Always send ZonePlayerToBind_Struct to client: Portal, Translocate, Evac spells that have a x y z coord in the spell data
ZoneUnsolicited,
GateToBindPoint, // Always send RequestClientZoneChange_Struct to client: Gate spell or Translocate To Bind Point spell
SummonPC, // In-zone GMMove() always: Call of the Hero spell or some other type of in zone only summons
EvacToSafeCoords
} ZoneMode;
Add:
Code:
typedef enum {
MQWarp,
MQZone,
MQGate,
MQGhost
} CheatTypes;
After:
Code:
void AI_Init();
void AI_Start(int32 iMoveDelay = 0);
void AI_Stop();
void Trader_ShowItems();
void Trader_EndTrader();
void Trader_StartTrader();
int8 WithCustomer();
bool CheckCheat();
Add:
Code:
void CheatDetected(CheatTypes Cheat);
bool WarpDetection(bool CTimer, float Distance);
.\zone\client.cpp
Change (Insert Red Lines):
Code:
bool Client::CheckCheat(){
float dx=cheat_x-x_pos;
float dy=cheat_y-y_pos;
float result=sqrtf((dx*dx)+(dy*dy));
return result>(RuleR(Zone, MQWarpDetectorDistance)); //Lieka: Integrated into Rules System; default value is 30, this allows for beyond GM speed without lag.