mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 22:58:34 +00:00
Merge branch 'master' into auras
This commit is contained in:
+91
-146
@@ -1288,7 +1288,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
lsaccountid = atoi(row[2]);
|
||||
gmspeed = atoi(row[3]);
|
||||
revoked = atoi(row[4]);
|
||||
gmhideme = atoi(row[5]);
|
||||
gm_hide_me = atoi(row[5]);
|
||||
account_creation = atoul(row[6]);
|
||||
}
|
||||
|
||||
@@ -1356,7 +1356,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
if (level) { level = m_pp.level; }
|
||||
|
||||
/* If GM, not trackable */
|
||||
if (gmhideme) { trackable = false; }
|
||||
if (gm_hide_me) { trackable = false; }
|
||||
/* Set Con State for Reporting */
|
||||
conn_state = PlayerProfileLoaded;
|
||||
|
||||
@@ -3882,7 +3882,7 @@ void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app)
|
||||
Mob* boat = entity_list.GetMob(boatname);
|
||||
if (!boat || (boat->GetRace() != CONTROLLED_BOAT && boat->GetRace() != 502))
|
||||
return;
|
||||
BoatID = boat->GetID(); // set the client's BoatID to show that it's on this boat
|
||||
controlling_boat_id = boat->GetID(); // set the client's BoatID to show that it's on this boat
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -4373,7 +4373,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
if (dead)
|
||||
return;
|
||||
|
||||
//currently accepting two sizes, one has an extra byte on the end
|
||||
/* Invalid size check */
|
||||
if (app->size != sizeof(PlayerPositionUpdateClient_Struct)
|
||||
&& app->size != (sizeof(PlayerPositionUpdateClient_Struct) + 1)
|
||||
) {
|
||||
@@ -4382,30 +4382,30 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
}
|
||||
PlayerPositionUpdateClient_Struct* ppu = (PlayerPositionUpdateClient_Struct*)app->pBuffer;
|
||||
|
||||
/* Boat handling */
|
||||
if (ppu->spawn_id != GetID()) {
|
||||
// check if the id is for a boat the player is controlling
|
||||
if (ppu->spawn_id == BoatID) {
|
||||
Mob* boat = entity_list.GetMob(BoatID);
|
||||
if (boat == 0) { // if the boat ID is invalid, reset the id and abort
|
||||
BoatID = 0;
|
||||
/* If player is controlling boat */
|
||||
if (ppu->spawn_id == controlling_boat_id) {
|
||||
Mob* boat = entity_list.GetMob(controlling_boat_id);
|
||||
if (boat == 0) {
|
||||
controlling_boat_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// set the boat's position deltas
|
||||
auto boatDelta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading);
|
||||
boat->SetDelta(boatDelta);
|
||||
// send an update to everyone nearby except the client controlling the boat
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
auto boat_delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, 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
|
||||
|
||||
/* Update the boat's position on the server, without sending an update */
|
||||
boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ19toFloat(ppu->heading), false);
|
||||
return;
|
||||
}
|
||||
else return; // if not a boat, do nothing
|
||||
else return;
|
||||
}
|
||||
|
||||
float dist = 0;
|
||||
@@ -4416,51 +4416,34 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
dist += tmp*tmp;
|
||||
dist = sqrt(dist);
|
||||
|
||||
//the purpose of this first block may not be readily apparent
|
||||
//basically it's so people don't do a moderate warp every 2.5 seconds
|
||||
//letting it even out and basically getting the job done without triggering
|
||||
if (dist == 0)
|
||||
{
|
||||
if (m_DistanceSinceLastPositionCheck > 0.0)
|
||||
{
|
||||
/* Hack checks */
|
||||
if (dist == 0) {
|
||||
if (m_DistanceSinceLastPositionCheck > 0.0) {
|
||||
uint32 cur_time = Timer::GetCurrentTime();
|
||||
if ((cur_time - m_TimeSinceLastPositionCheck) > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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())
|
||||
{
|
||||
//still potential to trigger this if you're knocked back off a
|
||||
//HUGE fall that takes > 2.5 seconds
|
||||
if (speed > 30.0f)
|
||||
{
|
||||
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)))
|
||||
{
|
||||
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
|
||||
{
|
||||
else {
|
||||
CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos);
|
||||
}
|
||||
}
|
||||
@@ -4475,64 +4458,42 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
m_CheatDetectMoved = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
m_TimeSinceLastPositionCheck = Timer::GetCurrentTime();
|
||||
m_CheatDetectMoved = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
m_DistanceSinceLastPositionCheck += dist;
|
||||
m_CheatDetectMoved = true;
|
||||
if (m_TimeSinceLastPositionCheck == 0)
|
||||
{
|
||||
if (m_TimeSinceLastPositionCheck == 0) {
|
||||
m_TimeSinceLastPositionCheck = Timer::GetCurrentTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
uint32 cur_time = Timer::GetCurrentTime();
|
||||
if ((cur_time - m_TimeSinceLastPositionCheck) > 2500)
|
||||
{
|
||||
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)
|
||||
{
|
||||
//if(!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos))
|
||||
//{
|
||||
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);
|
||||
//Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT);
|
||||
//}
|
||||
}
|
||||
}
|
||||
else if (IsKnockBackExempted())
|
||||
{
|
||||
//still potential to trigger this if you're knocked back off a
|
||||
//HUGE fall that takes > 2.5 seconds
|
||||
if (speed > 30.0f)
|
||||
{
|
||||
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)))
|
||||
{
|
||||
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
|
||||
{
|
||||
else {
|
||||
CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos);
|
||||
}
|
||||
}
|
||||
@@ -4551,7 +4512,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
DragCorpses();
|
||||
}
|
||||
|
||||
//Check to see if PPU should trigger an update to the rewind position.
|
||||
/* Check to see if PPU should trigger an update to the rewind position. */
|
||||
float rewind_x_diff = 0;
|
||||
float rewind_y_diff = 0;
|
||||
|
||||
@@ -4560,14 +4521,19 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
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.
|
||||
/*
|
||||
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 coords to the new ppu coords. This will prevent exploitation.
|
||||
/*
|
||||
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);
|
||||
@@ -4580,7 +4546,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
m_Proximity = glm::vec3(ppu->x_pos, ppu->y_pos, ppu->z_pos);
|
||||
}
|
||||
|
||||
// Update internal state
|
||||
/* Update internal state */
|
||||
m_Delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading);
|
||||
|
||||
if (IsTracking() && ((m_Position.x != ppu->x_pos) || (m_Position.y != ppu->y_pos))) {
|
||||
@@ -4588,7 +4554,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
CheckIncreaseSkill(EQEmu::skills::SkillTracking, nullptr, -20);
|
||||
}
|
||||
|
||||
// Break Hide if moving without sneaking and set rewind timer if moved
|
||||
/* 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) {
|
||||
hidden = false;
|
||||
@@ -4633,39 +4599,39 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
client_scan_npc_aggro_timer.Start(3000);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
m_Position.w = EQ19toFloat(ppu->heading);
|
||||
|
||||
animation = ppu->animation;
|
||||
|
||||
// Outgoing client packet
|
||||
float tmpheading = EQ19toFloat(ppu->heading);
|
||||
/* The clients send an update at best every 1.3 seconds
|
||||
* We want to avoid reflecting these updates to other clients as much as possible
|
||||
* The client also sends an update every 280 ms while turning, if we prevent
|
||||
* sending these by checking if the location is the same too aggressively, clients end up spinning
|
||||
* so keep a count of how many packets are the same within a tolerance and stop when we get there */
|
||||
|
||||
bool pos_same = FCMP(ppu->y_pos, m_Position.y) && FCMP(ppu->x_pos, m_Position.x) && FCMP(tmpheading, m_Position.w) && ppu->animation == animation;
|
||||
if (!pos_same || (pos_same && position_update_same_count < 6))
|
||||
{
|
||||
if (pos_same)
|
||||
position_update_same_count++;
|
||||
else
|
||||
position_update_same_count = 0;
|
||||
|
||||
m_Position.x = ppu->x_pos;
|
||||
m_Position.y = ppu->y_pos;
|
||||
m_Position.z = ppu->z_pos;
|
||||
m_Position.w = tmpheading;
|
||||
animation = ppu->animation;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
PlayerPositionUpdateServer_Struct* ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
|
||||
MakeSpawnUpdate(ppu);
|
||||
if (gmhideme)
|
||||
entity_list.QueueClientsStatus(this, outapp, true, Admin(), 250);
|
||||
else
|
||||
entity_list.QueueCloseClients(this, outapp, true, 300, nullptr, false);
|
||||
safe_delete(outapp);
|
||||
/* 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, ppu->heading);
|
||||
this->SendAppearanceEffect(78, 0, 0, 0, 0);
|
||||
this->SendAppearanceEffect(41, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
position_update_timer.Start(10000, true);
|
||||
|
||||
if (gm_hide_me) {
|
||||
entity_list.QueueClientsStatus(this, outapp, true, Admin(), 250);
|
||||
}
|
||||
else {
|
||||
entity_list.QueueCloseClients(this, outapp, true, 300, nullptr, true);
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
if (zone->watermap) {
|
||||
if (zone->watermap->InLiquid(glm::vec3(m_Position)))
|
||||
CheckIncreaseSkill(EQEmu::skills::SkillSwimming, nullptr, -17);
|
||||
@@ -4675,27 +4641,6 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
void Client::Handle_OP_CloseContainer(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != sizeof(CloseContainer_Struct)) {
|
||||
LogFile->write(EQEMuLog::Error, "Invalid size on CloseContainer_Struct: Expected %i, Got %i",
|
||||
sizeof(CloseContainer_Struct), app->size);
|
||||
return;
|
||||
}
|
||||
|
||||
SetTradeskillObject(nullptr);
|
||||
|
||||
ClickObjectAck_Struct* oos = (ClickObjectAck_Struct*)app->pBuffer;
|
||||
Entity* entity = entity_list.GetEntityObject(oos->drop_id);
|
||||
if (entity && entity->IsObject()) {
|
||||
Object* object = entity->CastToObject();
|
||||
object->Close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
void Client::Handle_OP_CombatAbility(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != sizeof(CombatAbility_Struct)) {
|
||||
@@ -8946,12 +8891,12 @@ void Client::Handle_OP_LeaveAdventure(const EQApplicationPacket *app)
|
||||
|
||||
void Client::Handle_OP_LeaveBoat(const EQApplicationPacket *app)
|
||||
{
|
||||
Mob* boat = entity_list.GetMob(this->BoatID); // find the mob corresponding to the boat id
|
||||
Mob* boat = entity_list.GetMob(this->controlling_boat_id); // find the mob corresponding to the boat id
|
||||
if (boat) {
|
||||
if ((boat->GetTarget() == this) && boat->GetHateAmount(this) == 0) // if the client somehow left while still controlling the boat (and the boat isn't attacking them)
|
||||
boat->SetTarget(0); // fix it to stop later problems
|
||||
}
|
||||
this->BoatID = 0;
|
||||
this->controlling_boat_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user