Redoing movement to introduce proper rotation

This commit is contained in:
KimLS
2018-09-24 22:41:53 -07:00
parent 1aa97957d8
commit 29ea65a71e
25 changed files with 423 additions and 1311 deletions
+37 -253
View File
@@ -505,7 +505,6 @@ void Client::CompleteConnect()
client_state = CLIENT_CONNECTED;
SendAllPackets();
hpupdate_timer.Start();
position_timer.Start();
autosave_timer.Start();
SetDuelTarget(0);
SetDueling(false);
@@ -895,108 +894,6 @@ void Client::CompleteConnect()
worldserver.RequestTellQueue(GetName());
}
void Client::CheatDetected(CheatTypes CheatType, float x, float y, float z)
{
//ToDo: Break warp down for special zones. Some zones have special teleportation pads or bad .map files which can trigger the detector without a legit zone request.
switch (CheatType)
{
case MQWarp: //Some zones may still have issues. Database updates will eliminate most if not all problems.
if (RuleB(Zone, EnableMQWarpDetector)
&& ((this->Admin() < RuleI(Zone, MQWarpExemptStatus)
|| (RuleI(Zone, MQWarpExemptStatus)) == -1)))
{
Message(13, "Large warp detected.");
char hString[250];
sprintf(hString, "/MQWarp with location %.2f, %.2f, %.2f", GetX(), GetY(), GetZ());
database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName());
}
break;
case MQWarpShadowStep:
if (RuleB(Zone, EnableMQWarpDetector)
&& ((this->Admin() < RuleI(Zone, MQWarpExemptStatus)
|| (RuleI(Zone, MQWarpExemptStatus)) == -1)))
{
char *hString = nullptr;
MakeAnyLenString(&hString, "/MQWarp(SS) with location %.2f, %.2f, %.2f, the target was shadow step exempt but we still found this suspicious.", GetX(), GetY(), GetZ());
database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName());
safe_delete_array(hString);
}
break;
case MQWarpKnockBack:
if (RuleB(Zone, EnableMQWarpDetector)
&& ((this->Admin() < RuleI(Zone, MQWarpExemptStatus)
|| (RuleI(Zone, MQWarpExemptStatus)) == -1)))
{
char *hString = nullptr;
MakeAnyLenString(&hString, "/MQWarp(KB) with location %.2f, %.2f, %.2f, the target was Knock Back exempt but we still found this suspicious.", GetX(), GetY(), GetZ());
database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName());
safe_delete_array(hString);
}
break;
case MQWarpLight:
if (RuleB(Zone, EnableMQWarpDetector)
&& ((this->Admin() < RuleI(Zone, MQWarpExemptStatus)
|| (RuleI(Zone, MQWarpExemptStatus)) == -1)))
{
if (RuleB(Zone, MarkMQWarpLT))
{
char *hString = nullptr;
MakeAnyLenString(&hString, "/MQWarp(LT) with location %.2f, %.2f, %.2f, running fast but not fast enough to get killed, possibly: small warp, speed hack, excessive lag, marked as suspicious.", GetX(), GetY(), GetZ());
database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName());
safe_delete_array(hString);
}
}
break;
case MQZone:
if (RuleB(Zone, EnableMQZoneDetector) && ((this->Admin() < RuleI(Zone, MQZoneExemptStatus) || (RuleI(Zone, MQZoneExemptStatus)) == -1)))
{
char hString[250];
sprintf(hString, "/MQZone used at %.2f, %.2f, %.2f to %.2f %.2f %.2f", GetX(), GetY(), GetZ(), x, y, z);
database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName());
}
break;
case MQZoneUnknownDest:
if (RuleB(Zone, EnableMQZoneDetector) && ((this->Admin() < RuleI(Zone, MQZoneExemptStatus) || (RuleI(Zone, MQZoneExemptStatus)) == -1)))
{
char hString[250];
sprintf(hString, "/MQZone used at %.2f, %.2f, %.2f", GetX(), GetY(), GetZ());
database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName());
}
break;
case MQGate:
if (RuleB(Zone, EnableMQGateDetector) && ((this->Admin() < RuleI(Zone, MQGateExemptStatus) || (RuleI(Zone, MQGateExemptStatus)) == -1))) {
Message(13, "Illegal gate request.");
char hString[250];
sprintf(hString, "/MQGate used at %.2f, %.2f, %.2f", GetX(), GetY(), GetZ());
database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName());
if (zone)
{
this->SetZone(this->GetZoneID(), zone->GetInstanceID()); //Prevent the player from zoning, place him back in the zone where he tried to originally /gate.
}
else
{
this->SetZone(this->GetZoneID(), 0); //Prevent the player from zoning, place him back in the zone where he tried to originally /gate.
}
}
break;
case MQGhost: //Not currently implemented, but the framework is in place - just needs detection scenarios identified
if (RuleB(Zone, EnableMQGhostDetector) && ((this->Admin() < RuleI(Zone, MQGhostExemptStatus) || (RuleI(Zone, MQGhostExemptStatus)) == -1))) {
database.SetMQDetectionFlag(this->account_name, this->name, "/MQGhost", zone->GetShortName());
}
break;
default:
char *hString = nullptr;
MakeAnyLenString(&hString, "Unhandled HackerDetection flag with location %.2f, %.2f, %.2f.", GetX(), GetY(), GetZ());
database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName());
safe_delete_array(hString);
break;
}
}
// connecting opcode handlers
/*
void Client::Handle_Connect_0x3e33(const EQApplicationPacket *app)
@@ -2948,7 +2845,6 @@ void Client::Handle_OP_Assist(const EQApplicationPacket *app)
Mob *new_target = assistee->GetTarget();
if (new_target && (GetGM() ||
Distance(m_Position, assistee->GetPosition()) <= TARGETING_RANGE)) {
SetAssistExemption(true);
eid->entity_id = new_target->GetID();
} else {
eid->entity_id = 0;
@@ -3920,6 +3816,8 @@ void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app)
return;
controlling_boat_id = boat->GetID(); // set the client's BoatID to show that it's on this boat
Message(0, "Board boat: %s", boatname);
return;
}
@@ -4427,9 +4325,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
sizeof(PlayerPositionUpdateClient_Struct), app->size);
return;
}
PlayerPositionUpdateClient_Struct *ppu = (PlayerPositionUpdateClient_Struct *) app->pBuffer;
/* Boat handling */
if (ppu->spawn_id != GetID()) {
/* If player is controlling boat */
@@ -4439,163 +4337,67 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
controlling_boat_id = 0;
return;
}
auto boat_delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading));
boat->SetDelta(boat_delta);
auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct *ppus = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer;
boat->MakeSpawnUpdate(ppus);
entity_list.QueueCloseClients(boat, outapp, true, 300, this, false);
safe_delete(outapp);
/* Update the boat's position on the server, without sending an update */
boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading), false);
return;
} else return;
}
float dist = 0;
float tmp;
tmp = m_Position.x - ppu->x_pos;
dist += tmp * tmp;
tmp = m_Position.y - ppu->y_pos;
dist += tmp * tmp;
dist = sqrt(dist);
/* Hack checks */
if (dist == 0) {
if (m_DistanceSinceLastPositionCheck > 0.0) {
uint32 cur_time = Timer::GetCurrentTime();
if ((cur_time - m_TimeSinceLastPositionCheck) > 0) {
float speed =
(m_DistanceSinceLastPositionCheck * 100) / (float) (cur_time - m_TimeSinceLastPositionCheck);
int runs = GetRunspeed();
if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) {
if (!GetGMSpeed() && (runs >= GetBaseRunspeed() ||
(speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) {
if (IsShadowStepExempted()) {
if (m_DistanceSinceLastPositionCheck > 800) {
CheatDetected(MQWarpShadowStep, ppu->x_pos, ppu->y_pos, ppu->z_pos);
}
} else if (IsKnockBackExempted()) {
if (speed > 30.0f) {
CheatDetected(MQWarpKnockBack, ppu->x_pos, ppu->y_pos, ppu->z_pos);
}
} else if (!IsPortExempted()) {
if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) {
if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) {
m_TimeSinceLastPositionCheck = cur_time;
m_DistanceSinceLastPositionCheck = 0.0f;
CheatDetected(MQWarp, ppu->x_pos, ppu->y_pos, ppu->z_pos);
//Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT);
} else {
CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos);
}
}
}
}
}
SetShadowStepExemption(false);
SetKnockBackExemption(false);
SetPortExemption(false);
m_TimeSinceLastPositionCheck = cur_time;
m_DistanceSinceLastPositionCheck = 0.0f;
m_CheatDetectMoved = false;
}
} else {
m_TimeSinceLastPositionCheck = Timer::GetCurrentTime();
m_CheatDetectMoved = false;
}
} else {
m_DistanceSinceLastPositionCheck += dist;
m_CheatDetectMoved = true;
if (m_TimeSinceLastPositionCheck == 0) {
m_TimeSinceLastPositionCheck = Timer::GetCurrentTime();
} else {
uint32 cur_time = Timer::GetCurrentTime();
if ((cur_time - m_TimeSinceLastPositionCheck) > 2500) {
float speed =
(m_DistanceSinceLastPositionCheck * 100) / (float) (cur_time - m_TimeSinceLastPositionCheck);
int runs = GetRunspeed();
if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) {
if (!GetGMSpeed() && (runs >= GetBaseRunspeed() ||
(speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) {
if (IsShadowStepExempted()) {
if (m_DistanceSinceLastPositionCheck > 800) {
CheatDetected(MQWarpShadowStep, ppu->x_pos, ppu->y_pos, ppu->z_pos);
}
} else if (IsKnockBackExempted()) {
if (speed > 30.0f) {
CheatDetected(MQWarpKnockBack, ppu->x_pos, ppu->y_pos, ppu->z_pos);
}
} else if (!IsPortExempted()) {
if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) {
if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) {
m_TimeSinceLastPositionCheck = cur_time;
m_DistanceSinceLastPositionCheck = 0.0f;
CheatDetected(MQWarp, ppu->x_pos, ppu->y_pos, ppu->z_pos);
} else {
CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos);
}
}
}
}
}
SetShadowStepExemption(false);
SetKnockBackExemption(false);
SetPortExemption(false);
m_TimeSinceLastPositionCheck = cur_time;
m_DistanceSinceLastPositionCheck = 0.0f;
}
}
if (IsDraggingCorpse())
DragCorpses();
}
if (IsDraggingCorpse())
DragCorpses();
/* Check to see if PPU should trigger an update to the rewind position. */
float rewind_x_diff = 0;
float rewind_y_diff = 0;
rewind_x_diff = ppu->x_pos - m_RewindLocation.x;
rewind_x_diff *= rewind_x_diff;
rewind_y_diff = ppu->y_pos - m_RewindLocation.y;
rewind_y_diff *= rewind_y_diff;
/*
We only need to store updated values if the player has moved.
If the player has moved more than units for x or y, then we'll store
his pre-PPU x and y for /rewind, in case he gets stuck.
*/
if ((rewind_x_diff > 750) || (rewind_y_diff > 750))
m_RewindLocation = glm::vec3(m_Position);
/*
If the PPU was a large jump, such as a cross zone gate or Call of Hero,
just update rewind coordinates to the new ppu coordinates. This will prevent exploitation.
*/
if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000))
m_RewindLocation = glm::vec3(ppu->x_pos, ppu->y_pos, ppu->z_pos);
if (proximity_timer.Check()) {
entity_list.ProcessMove(this, glm::vec3(ppu->x_pos, ppu->y_pos, ppu->z_pos));
if (RuleB(TaskSystem, EnableTaskSystem) && RuleB(TaskSystem, EnableTaskProximity))
ProcessTaskProximities(ppu->x_pos, ppu->y_pos, ppu->z_pos);
m_Proximity = glm::vec3(ppu->x_pos, ppu->y_pos, ppu->z_pos);
}
/* Update internal state */
m_Delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading));
if (IsTracking() && ((m_Position.x != ppu->x_pos) || (m_Position.y != ppu->y_pos))) {
if (zone->random.Real(0, 100) < 70)//should be good
CheckIncreaseSkill(EQEmu::skills::SkillTracking, nullptr, -20);
}
/* Break Hide if moving without sneaking and set rewind timer if moved */
if (ppu->y_pos != m_Position.y || ppu->x_pos != m_Position.x) {
if ((hidden || improved_hidden) && !sneaking) {
@@ -4614,17 +4416,17 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
}
rewind_timer.Start(30000, true);
}
/* Handle client aggro scanning timers NPCs */
is_client_moving = (ppu->y_pos == m_Position.y && ppu->x_pos == m_Position.x) ? false : true;
if (is_client_moving) {
Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is moving - scan timer is: %u",
client_scan_npc_aggro_timer.GetDuration());
if (client_scan_npc_aggro_timer.GetDuration() > 1000) {
client_scan_npc_aggro_timer.Disable();
client_scan_npc_aggro_timer.Start(500);
}
} else {
Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is NOT moving - scan timer is: %u",
@@ -4634,15 +4436,15 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
client_scan_npc_aggro_timer.Start(3000);
}
}
float new_heading = EQ12toFloat(ppu->heading);
int32 new_animation = ppu->animation;
/* Update internal server position from what the client has sent */
m_Position.x = ppu->x_pos;
m_Position.y = ppu->y_pos;
m_Position.z = ppu->z_pos;
/* Visual Debugging */
if (RuleB(Character, OPClientUpdateVisualDebug)) {
Log(Logs::General, Logs::Debug, "ClientUpdate: ppu x: %f y: %f z: %f h: %u", ppu->x_pos, ppu->y_pos, ppu->z_pos,
@@ -4650,43 +4452,43 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
this->SendAppearanceEffect(78, 0, 0, 0, 0);
this->SendAppearanceEffect(41, 0, 0, 0, 0);
}
/* Only feed real time updates when client is moving */
if (is_client_moving || new_heading != m_Position.w || new_animation != animation) {
animation = ppu->animation;
m_Position.w = EQ12toFloat(ppu->heading);
/* Broadcast update to other clients */
auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct *position_update = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer;
MakeSpawnUpdate(position_update);
if (gm_hide_me) {
entity_list.QueueClientsStatus(this, outapp, true, Admin(), 250);
} else {
entity_list.QueueCloseClients(this, outapp, true, RuleI(Range, ClientPositionUpdates), nullptr, true);
}
/* Always send position updates to group - send when beyond normal ClientPositionUpdate range */
Group *group = this->GetGroup();
Raid *raid = this->GetRaid();
if (raid) {
raid->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1));
} else if (group) {
group->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1));
}
safe_delete(outapp);
}
if (zone->watermap) {
if (zone->watermap->InLiquid(glm::vec3(m_Position))) {
CheckIncreaseSkill(EQEmu::skills::SkillSwimming, nullptr, -17);
// Dismount horses when entering water
if (GetHorseId() && RuleB(Character, DismountWater)) {
SetHorseId(0);
@@ -4695,7 +4497,6 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
}
CheckRegionTypeChanges();
}
return;
}
void Client::Handle_OP_CombatAbility(const EQApplicationPacket *app)
@@ -13666,12 +13467,6 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
GetTarget()->IsTargeted(1);
return;
}
else if (IsAssistExempted())
{
GetTarget()->IsTargeted(1);
SetAssistExemption(false);
return;
}
else if (GetTarget()->IsClient())
{
//make sure this client is in our raid/group
@@ -13689,17 +13484,6 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
SetTarget((Mob*)nullptr);
return;
}
else if (IsPortExempted())
{
GetTarget()->IsTargeted(1);
return;
}
else if (IsSenseExempted())
{
GetTarget()->IsTargeted(1);
SetSenseExemption(false);
return;
}
else if (IsXTarget(GetTarget()))
{
GetTarget()->IsTargeted(1);