Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "LagFix.h"
- #include "Aimbot.h"
- #include "cvars.h"
- #include "GameMovement.h"
- #include <map>
- void LagFix::save_entity_updates(CBaseEntity* player, float yaw)
- {
- int index = player->GetIndex();
- float entity_simulation_time = player->m_flSimulationTime();
- Record current_record;
- auto& entity_records = update_records[index];
- auto& entity_sim = simulated_records[index];
- drop_old_records(entity_records);
- drop_old_records(vars.ticks);
- if (entity_sim.size() > 8)
- entity_sim.pop_back();
- if (entity_records.size() > 20)
- entity_records.pop_back();
- if (current_record.m_flSimulationTime == entity_simulation_time)
- return;
- current_record.fill_data(player);
- INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
- if (update_record_old[index].m_bFilled && nci)
- {
- //auto PredictedCmdArrivalTick = g_pGlobalVarsBase->tickcount + TIME_TO_TICKS(nci->GetAvgLatency(FLOW_INCOMING) + nci->GetAvgLatency(FLOW_OUTGOING));
- //auto Correct = clamp(get_lerp_time() + nci->GetLatency(FLOW_OUTGOING), 0.f, 1.f) - TICKS_TO_TIME(PredictedCmdArrivalTick + TIME_TO_TICKS(get_lerp_time() - current_record.m_flSimulationTime));
- //current_record.choked_ticks = TIME_TO_TICKS(Correct);
- auto simulation_time_delta = update_record_new[index].m_flSimulationTime - update_record_old[index].m_flSimulationTime;
- auto simulation_tick_delta = clamp(TIME_TO_TICKS(simulation_time_delta), 1, 15);
- auto delta_ticks = (clamp(TIME_TO_TICKS(nci->GetAvgLatency(1) + nci->GetAvgLatency(0)) + g_pGlobalVarsBase->tickcount - TIME_TO_TICKS(update_record_new[index].m_flSimulationTime + get_lerp_time()), 0, 100)) - simulation_tick_delta;
- current_record.choked_ticks = delta_ticks;
- }
- else
- current_record.choked_ticks = player->GetChokedTicks();
- current_record.m_iPriority = 20;
- current_record.m_iPriority -= current_record.choked_ticks;
- auto local = g_pTools->GetLocalPlayer();
- //if (local && local->IsValid2() && vars.RagebotSimulateIfBacktrackFails)
- //{
- // if (g_pTools->IsVisible(local->GetEyePosition(), player->GetHitboxPosition(0), local, player))
- // current_record.m_iPriority += 2; // prioritize visible backtracks over non visible -> shoots visible b4 it shoots through walls
- // //technically itll shoot behind a wall if the player is choking 3 less ticks at the time
- //}
- if (local)
- current_record.m_bTeammate = local->GetTeam() == player->GetTeam();
- if (vars.AntiAimAdjustAngles)
- current_record.m_angAngles.y = yaw;
- if (update_record_new[index].m_bFilled)
- update_record_old[index] = update_record_new[index];
- if (current_record.m_bFilled)
- update_record_new[index] = current_record;
- if (current_record.m_bFilled)
- {
- entity_records.emplace_front(current_record);
- entity_sim.emplace_front(current_record);
- vars.ticks.emplace_front(current_record);
- }
- }
- void LagFix::push_update(CBaseEntity* player, float yaw, int priority, float_t correct_time)
- {
- int index = player->GetIndex();
- Record current_record;
- auto& entity_records = update_records[index];
- auto& entity_sim = simulated_records[index];
- if (!check_tick_validity(TIME_TO_TICKS(correct_time)))
- return;
- current_record.fill_data(player);
- INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
- if (update_record_old[index].m_bFilled && nci)
- {
- //auto simulation_time_delta = current_record.m_flSimulationTime - update_record_old[index].m_flSimulationTime;
- //auto simulation_tick_delta = clamp(TIME_TO_TICKS(simulation_time_delta), 1, 15);
- //auto delta_ticks = (clamp(TIME_TO_TICKS(get_incoming_latency() + get_outgoing_latency()) + g_pGlobalVarsBase->tickcount - TIME_TO_TICKS(current_record.m_flSimulationTime), 0, 16)) - simulation_tick_delta;
- auto simulation_time_delta = update_record_new[index].m_flSimulationTime - update_record_old[index].m_flSimulationTime;
- auto simulation_tick_delta = clamp(TIME_TO_TICKS(simulation_time_delta), 1, 15);
- auto delta_ticks = (clamp(TIME_TO_TICKS(nci->GetAvgLatency(1) + nci->GetAvgLatency(0)) + g_pGlobalVarsBase->tickcount - TIME_TO_TICKS(update_record_new[index].m_flSimulationTime + get_lerp_time()), 0, 64)) - simulation_tick_delta;
- current_record.choked_ticks = delta_ticks;
- }
- else
- current_record.choked_ticks = player->GetChokedTicks();
- current_record.m_iPriority = 64;
- current_record.m_iPriority -= current_record.choked_ticks;
- if (current_record.m_vecVelocity.Length() > 100)
- current_record.m_iPriority *= 2;
- auto local = g_pTools->GetLocalPlayer();
- if (local && local->IsValid2() && vars.RagebotSimulateIfBacktrackFails)
- {
- if (g_pTools->IsVisible(local->GetEyePosition(), player->GetHitboxPosition(0), local, player))
- current_record.m_iPriority += 10;
- }
- if (local)
- current_record.m_bTeammate = local->GetTeam() == player->GetTeam();
- current_record.m_angAngles.y = yaw;
- current_record.m_iPriority += priority;
- current_record.m_flSimulationTime = correct_time;
- entity_records.emplace_front(current_record);
- vars.ticks.emplace_front(current_record);
- }
- float LagFix::normalize_float(float angle)
- {
- int tmpAngNorm = (int)round(angle / 360.f);
- if (angle > 180 || angle < -180)
- angle -= tmpAngNorm * 360.f;
- return angle;
- }
- float LagFix::generate_average_movement_curvature(CBaseEntity* player)
- {
- int index = player->GetIndex();
- Vector p1 = Vector(0, 0, 0);
- Vector p2 = Vector(0, 0, 0);
- float ret = 0;
- int ticks = 0;
- auto& entity_records = update_records[index];
- for (size_t i = 0; i < entity_records.size(); i++)
- {
- if (g_pGlobalVarsBase->curtime - entity_records.at(i).m_flSimulationTime > 0.5f && i > 3)
- break;
- else if (i > 2)
- {
- float angle = 0;
- QAngle a1, a2;
- g_pTools->VectorAngles(p1, a1);
- g_pTools->VectorAngles(p2, a2);
- if (a1.y < 0.0f)
- a1.y += 360.0f;
- if (a2.y < 0.0f)
- a2.y += 360.0f;
- angle = a2.y - a1.y;
- if (angle > 180.0f)
- angle -= 360.0f;
- ret += angle;
- ticks++;
- }
- p1 = p2;
- if (i > 0)
- p2 = (entity_records.at(i).m_vecOrigin - entity_records.at(i - 1).m_vecOrigin);
- p2.z = 0;
- p2.NormalizeInPlace();
- }
- ret /= std::fmaxf(1, ticks);
- return ret;
- }
- float LagFix::entity_average_acceleration(CBaseEntity* player)
- {
- float vel = player->GetVelocity().Length2D();
- int index = player->GetIndex();
- float ret = 0;
- int ticks = 0;
- auto& entity_records = simulated_records[index];
- for (size_t i = 0; i < entity_records.size(); i++)
- if (g_pGlobalVarsBase->curtime - entity_records.at(i).m_flSimulationTime > 0.3f && ticks++ > 1)
- break;
- else
- ret += entity_records.at(i).m_vecVelocity.Length2D() - vel;
- ret /= std::fmaxf(1, ticks);
- return ret;
- }
- float LagFix::get_incoming_latency()
- {
- SDK::INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
- if (nci)
- {
- float IncomingLatency = nci->GetAvgLatency(FLOW_INCOMING);
- return IncomingLatency;
- }
- else
- {
- return 0.0f;
- }
- }
- float LagFix::get_outgoing_latency()
- {
- SDK::INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
- if (nci)
- {
- float OutgoingLatency = nci->GetAvgLatency(FLOW_OUTGOING);
- return OutgoingLatency;
- }
- else
- {
- return 0.0f;
- }
- }
- void LagFix::adjust_tick_to_record(int index, CUserCmd *usercmd, Record rec)
- {
- if (!check_tick_validity(TIME_TO_TICKS(rec.m_flSimulationTime)))
- {
- usercmd->tick_count = TIME_TO_TICKS(g_pEntityList->GetBaseEntity(index)->m_flSimulationTime() + get_lerp_time());
- }
- else
- {
- usercmd->tick_count = TIME_TO_TICKS(rec.m_flSimulationTime + get_lerp_time());
- }
- }
- void LagFix::extrapolate_data(SimulationData* data)
- {
- int index = data->m_pEntity->GetIndex();
- //CBaseEntity* pLocal = g_pTools->GetLocalPlayer();
- //IEngineTrace::trace_t trace;
- //IEngineTrace::CTraceFilter filter;
- //IEngineTrace::Ray_t ray;
- //filter.pSkip = pLocal;
- //
- //auto sv_gravity = g_pICvar->FindVar("sv_gravity")->GetFloat();
- //auto sv_jump_impulse = g_pICvar->FindVar("sv_jump_impulse")->GetFloat(); // math.sqrt(91200) = 301.1
- //auto gravity_per_tick = sv_gravity *g_pGlobalVarsBase->interval_per_tick;
- //auto predicted_origin = data->origin;
- ////bool on_ground = (data->m_pEntity->GetFlags() & FL_ONGROUND);
- //
- //if (data->on_ground)
- // data->velocity.z -= gravity_per_tick;
- //
- //predicted_origin += data->velocity * g_pGlobalVarsBase->interval_per_tick;
- //
- //ray.Init(data->origin, predicted_origin, data->maxs, data->mins);
- //
- //g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
- //
- //if (trace.fraction == 1.f)
- // data->origin = predicted_origin;
- //
- //ray.Init(data->origin, data->origin - Vector(0.f, 0.f, 2.f), data->maxs, data->mins);
- //
- //g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
- //
- //data->on_ground = trace.fraction == 0.f;
- auto mins = data->m_pEntity->GetCollideable()->OBBMins();
- auto maxs = data->m_pEntity->GetCollideable()->OBBMaxs();
- auto src = data->origin;
- auto end = src + (data->velocity * g_pGlobalVarsBase->interval_per_tick);
- SDK::IEngineTrace::Ray_t ray;
- ray.Init(src, end, mins, maxs);
- SDK::IEngineTrace::trace_t trace;
- SDK::IEngineTrace::CTraceFilter filter;
- filter.pSkip = (IHandleEntity*)data->m_pEntity;
- g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
- if (trace.fraction != 1.f)
- {
- for (int i = 0; i < 2; ++i)
- {
- data->velocity -= trace.plane.normal * data->velocity.Dot(trace.plane.normal);
- auto dot = data->velocity.Dot(trace.plane.normal);
- if (dot < 0.f)
- {
- data->velocity.x -= dot * trace.plane.normal.x;
- data->velocity.y -= dot * trace.plane.normal.y;
- data->velocity.z -= dot * trace.plane.normal.z;
- }
- end = trace.endpos + (data->velocity * (g_pGlobalVarsBase->interval_per_tick * (1.f - trace.fraction)));
- ray.Init(trace.endpos, end, mins, maxs);
- g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
- if (trace.fraction == 1.f)
- break;
- }
- }
- data->origin = trace.endpos;
- end = trace.endpos;
- end.z -= 2.f;
- ray.Init(data->origin, end, mins, maxs);
- g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
- data->flags &= ~FL_ONGROUND;
- if (trace.fraction != 1.f && trace.plane.normal.z > 0.7f)
- data->flags |= FL_ONGROUND;
- }
- bool LagFix::do_aimbot_validity_checks_rebuild(CBaseEntity* entity, Vector &aim_point, bool &hitchanced, bool &valid)
- {
- auto *g_LocalPlayer = g_pTools->GetLocalPlayer();
- matrix3x4_t matrix[128];
- if (!entity->SetupBones(matrix, 128, BONE_USED_BY_HITBOX, g_pIVEngineClient->GetLastTimeStamp()))
- return false;
- aim_point = AimbotR->LagFixFindBestPoint(entity, 0, vars.RagebotMinimumDamage, vars.RagebotHitscan, matrix);
- if (!aim_point.IsValid())
- {
- valid = false;
- return false;
- }
- SDK::Vector aimAngle;
- g_pTools->CalcAngle(g_LocalPlayer->GetEyePosition(), aim_point, aimAngle);
- valid = true;
- hitchanced = AimbotR->HitChance(aimAngle, entity, vars.RagebotHitchanceValue);
- return true;
- }
- bool LagFix::do_aimbot_validity_checks(CBaseEntity* entity, Vector &aim_point, Record& entity_records, bool &hitchanced, bool &valid)
- {
- auto *g_LocalPlayer = g_pTools->GetLocalPlayer();
- entity->SetBoneMatrix(entity_records.matrix);
- aim_point = AimbotR->FindBestPoint(entity, 0, vars.RagebotMinimumDamage, vars.RagebotHitscan);
- if (!aim_point.IsValid())
- {
- valid = false;
- return false;
- }
- SDK::Vector aimAngle;
- g_pTools->CalcAngle(g_LocalPlayer->GetEyePosition(), aim_point, aimAngle);
- valid = true;
- hitchanced = AimbotR->HitChance(aimAngle, entity, vars.RagebotHitchanceValue);
- return true;
- }
- void LagFix::predict_player(CBaseEntity* entity, Record current_record, Record next_record, Vector &aim_point, bool &hitchanced, bool &validsim)
- {
- INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
- if (!nci)
- return;
- // Create Simulation Data
- SimulationData simulation_data;
- simulation_data.m_pEntity = entity;
- simulation_data.origin = current_record.m_vecOrigin;
- simulation_data.velocity = current_record.m_vecVelocity;
- simulation_data.on_ground = current_record.m_nFlags & FL_ONGROUND;
- simulation_data.data_complete = true;
- // Calculate Delta's
- auto simulation_time_delta = current_record.m_flSimulationTime - next_record.m_flSimulationTime;
- auto simulation_tick_delta = clamp(TIME_TO_TICKS(simulation_time_delta), 1, 16);
- //auto delta_ticks = (clamp(TIME_TO_TICKS(get_incoming_latency() + get_outgoing_latency()) + g_pGlobalVarsBase->tickcount - TIME_TO_TICKS(current_record.m_flSimulationTime), 0, 16)) - simulation_tick_delta;
- auto PredictedCmdArrivalTick = g_pGlobalVarsBase->tickcount + TIME_TO_TICKS(nci->GetAvgLatency(FLOW_INCOMING) + nci->GetAvgLatency(FLOW_OUTGOING));
- auto Correct = clamp(get_lerp_time() + nci->GetLatency(FLOW_OUTGOING), 0.f, 1.f) - TICKS_TO_TIME(PredictedCmdArrivalTick + TIME_TO_TICKS(get_lerp_time() - current_record.m_flSimulationTime));
- auto delta_ticks = TIME_TO_TICKS(Correct);
- // Calculate movement delta
- auto current_velocity_angle = RAD2DEG(atan2(current_record.m_vecVelocity.y, current_record.m_vecVelocity.x));
- auto next_velocity_angle = RAD2DEG(atan2(next_record.m_vecVelocity.y, next_record.m_vecVelocity.x));
- auto velocity_angle_delta = normalize_float(current_velocity_angle - next_velocity_angle);
- auto velocity_movement_delta = velocity_angle_delta / simulation_time_delta;
- auto average_velocity_acceleration = entity_average_acceleration(entity);
- auto speed = current_record.m_vecVelocity.Length2D();
- if (delta_ticks > 0 && simulation_data.data_complete)
- {
- for (; delta_ticks >= 0; delta_ticks -= simulation_tick_delta)
- {
- auto ticks_left = simulation_tick_delta;
- do
- {
- current_velocity_angle += average_velocity_acceleration * g_pGlobalVarsBase->interval_per_tick;
- simulation_data.velocity.x = std::cos(DEG2RAD(current_velocity_angle)) * speed;
- simulation_data.velocity.y = std::sin(DEG2RAD(current_velocity_angle)) * speed;
- bool InAir = !(entity->GetFlags() & FL_ONGROUND);
- if (!(simulation_data.flags & FL_ONGROUND))
- simulation_data.velocity.z -= (g_pGlobalVarsBase->interval_per_tick * g_pICvar->FindVar("sv_gravity")->GetFloat());
- else if (InAir)
- simulation_data.velocity.z = sqrt(91200.f);
- extrapolate_data(&simulation_data);
- current_record.m_flSimulationTime += g_pGlobalVarsBase->interval_per_tick;
- --ticks_left;
- } while (ticks_left);
- }
- if (move_entity_to_simulation(&simulation_data))
- do_aimbot_validity_checks_rebuild(entity, aim_point, hitchanced, validsim);
- return;
- }
- }
- Record LagFix::find_best_record(CBaseEntity* entity)
- {
- int index = entity->GetIndex();
- auto& entity_records = update_records[index];
- Record new_record;
- Record best_record;
- int best_priority = 0;
- int best_damage = 0;
- backtrack_records.clear();
- for (auto it : entity_records)
- {
- if (it.m_flSimulationTime > update_record_old->m_flSimulationTime)
- new_record = it;
- if (check_tick_validity(TIME_TO_TICKS(it.m_flSimulationTime)))
- {
- backtrack_records.emplace_front(it);
- float damage = 0;
- AimbotR->CanWallbang(entity->GetHitboxPosition(0), damage);
- if (damage > best_damage)
- {
- best_record = it;
- best_damage = damage;
- best_priority = it.m_iPriority;
- if (damage > entity->GetHealth())
- return it;
- }
- }
- }
- //backtrack_records.emplace_front(new_record);
- //std::sort(backtrack_records.begin(), backtrack_records.end(), [](Record const &a, Record const &b) { return a.m_iPriority > b.m_iPriority; });
- //backtrack_records.emplace_front(best_record);
- //return backtrack_records.front();
- if (best_record.m_bFilled)
- return best_record;
- else
- return new_record;
- }
- void LagFix::handle_entity(CUserCmd *cmd, CBaseEntity* entity, Vector &aim_point, bool &hitchanced, bool &validsim)
- {
- int index = entity->GetIndex();
- auto& entity_records = update_records[index];
- bool breaking_lagcomp = false;
- if (!update_record_new[entity->GetIndex()].m_bFilled || !update_record_old[entity->GetIndex()].m_bFilled)
- {
- validsim = false;
- return;
- }
- if (entity_records.size() > 0)
- {
- if (update_record_old[index].m_bFilled)
- {
- breaking_lagcomp = (entity->GetAbsOrigin() - update_record_old[index].m_vecOrigin).Length2DSqr() > 4096;
- }
- int choked_ticks = update_record_new[index].choked_ticks;
- if (!breaking_lagcomp)
- {
- if (vars.lagfixmode[0].selected)
- {
- Record rec = find_best_record(entity);
- if (rec.m_bFilled)
- {
- if (move_entity_to_record(entity, rec))
- {
- if (do_aimbot_validity_checks_rebuild(entity, aim_point, hitchanced, validsim))
- adjust_tick_to_record(index, cmd, rec);
- move_entity_to_current(entity);
- if (vars.lagfixmode[2].selected)
- {
- if (!validsim && entity->GetVelocity().Length() > 20)
- {
- for (; choked_ticks > 0; choked_ticks--)
- RebuildGameMovement::Get().FullWalkMove(entity);
- do_aimbot_validity_checks_rebuild(entity, aim_point, hitchanced, validsim);
- move_entity_to_record(entity, update_record_new[index], true);
- }
- }
- }
- }
- }
- }
- else
- {
- if (vars.lagfixmode[1].selected)
- {
- for (; choked_ticks > 0; choked_ticks--)
- RebuildGameMovement::Get().FullWalkMove(entity);
- do_aimbot_validity_checks_rebuild(entity, aim_point, hitchanced, validsim);
- move_entity_to_record(entity, update_record_new[index], true);
- }
- }
- }
- }
- bool LagFix::move_entity_to_simulation(SimulationData* data)
- {
- int ent_index = data->m_pEntity->GetIndex();
- CBaseEntity* player = data->m_pEntity;
- player->InvalidateBoneCache();
- player->GetCollideable()->OBBMins() = data->mins;
- player->GetCollideable()->OBBMaxs() = data->maxs;
- player->SetAbsOrigin(data->origin);
- player->UpdateClientSideAnimation();
- return true;
- }
- bool LagFix::move_entity_to_current(CBaseEntity* player)
- {
- int ent_index = player->GetIndex();
- auto cur = update_record_new[ent_index];
- player->InvalidateBoneCache();
- player->GetCollideable()->OBBMins() = cur.m_vecMins;
- player->GetCollideable()->OBBMaxs() = cur.m_vecMax;
- player->m_flPoseParameter() = cur.m_arrflPoseParameters;
- int layerCount = player->GetNumAnimOverlays();
- for (int i = 0; i < layerCount; ++i)
- {
- AnimationLayer *currentLayer = player->GetAnimOverlay(i);
- currentLayer->m_nOrder = cur.m_LayerRecords[i].m_nOrder;
- currentLayer->m_nSequence = cur.m_LayerRecords[i].m_nSequence;
- currentLayer->m_flWeight = cur.m_LayerRecords[i].m_flWeight;
- currentLayer->m_flCycle = cur.m_LayerRecords[i].m_flCycle;
- }
- player->GetEyeAngles().y = cur.m_angAngles.y;
- player->SetPoseAngles(cur.m_angAngles.y, cur.m_angAngles.x);
- player->SetAbsAngles(QAngle(0, cur.m_angAngles.y, 0));
- player->m_angRotation() = QAngle(0, 0, 0);
- player->SetAbsOrigin(cur.m_vecOrigin);
- *player->GetOriginPtr() = cur.m_vecOrigin;
- if (!player->SetupBones(cur.matrix, 128, BONE_USED_BY_HITBOX, g_pIVEngineClient->GetLastTimeStamp()))
- return false;
- return true;
- }
- static AnimationLayer empty;
- void LagFix::fix_anims(ClientFrameStage_t stage)
- {
- auto g_LocalPlayer = g_pTools->GetLocalPlayer();
- if (!g_LocalPlayer)
- return;
- static int userId[64];
- static AnimationLayer
- backupLayersUpdate[64][15],
- backupLayersInterp[64][15];
- for (int i = 1; i < g_pEntityList->GetHighestEntityIndex(); i++)
- {
- CBaseEntity* player;
- if (!(player = g_pEntityList->GetBaseEntity(i)))
- continue;
- if (!player ||
- player == g_LocalPlayer ||
- player->GetTeam() == g_LocalPlayer->GetTeam() ||
- !player->IsValid())
- continue;
- player_info_t player_info;
- if (!g_pIVEngineClient->GetPlayerInfo(i, &player_info))
- continue;
- auto overlays = player->GetAnimOverlays();
- if (!overlays)
- continue;
- auto numoverlays = player->GetNumAnimOverlays();
- if (!numoverlays)
- continue;
- switch (stage)
- {
- case ClientFrameStage_t::FRAME_NET_UPDATE_START: // Copy new, server layers to use when drawing.
- userId[i] = player_info.userId;
- memcpy(&backupLayersUpdate[i], overlays, (sizeof AnimationLayer) * numoverlays);
- break;
- case ClientFrameStage_t::FRAME_RENDER_START: // Render started, don't use inaccurately extrapolated layers but save them to not mess shit up either.
- if (userId[i] != player_info.userId) continue;
- memcpy(&backupLayersInterp[i], overlays, (sizeof AnimationLayer) * numoverlays);
- memcpy(overlays, &backupLayersUpdate[i], (sizeof AnimationLayer) * numoverlays);
- break;
- case ClientFrameStage_t::FRAME_RENDER_END: // Restore layers to keep being accurate when backtracking.
- if (userId[i] != player_info.userId) continue;
- memcpy(overlays, &backupLayersInterp[i], (sizeof AnimationLayer) * numoverlays);
- break;
- default:
- return;
- }
- }
- }
- bool LagFix::move_entity_to_record(CBaseEntity* player, Record& entity_records, bool rebuild)
- {
- int ent_index = player->GetIndex();
- player->InvalidateBoneCache();
- player->GetCollideable()->OBBMins() = entity_records.m_vecMins;
- player->GetCollideable()->OBBMaxs() = entity_records.m_vecMax;
- player->m_flPoseParameter() = entity_records.m_arrflPoseParameters;
- int layerCount = player->GetNumAnimOverlays();
- for (int i = 0; i < layerCount; ++i)
- {
- AnimationLayer *currentLayer = player->GetAnimOverlay(i);
- currentLayer->m_nOrder = entity_records.m_LayerRecords[i].m_nOrder;
- currentLayer->m_nSequence = entity_records.m_LayerRecords[i].m_nSequence;
- currentLayer->m_flWeight = entity_records.m_LayerRecords[i].m_flWeight;
- currentLayer->m_flCycle = entity_records.m_LayerRecords[i].m_flCycle;
- }
- player->GetEyeAngles().y = entity_records.m_angAngles.y;
- player->SetPoseAngles(entity_records.m_angAngles.y, entity_records.m_angAngles.x);
- player->SetAbsAngles(QAngle(0, entity_records.m_angAngles.y, 0));
- player->SetAbsOrigin(entity_records.m_vecOrigin);
- *player->GetOriginPtr() = entity_records.m_vecOrigin;
- if (rebuild)
- if (!player->SetupBones(entity_records.matrix, 128, BONE_USED_BY_HITBOX, g_pIVEngineClient->GetLastTimeStamp()))
- return false;
- return true;
- }
- void LagFix::drop_all_records(std::deque<Record>& records)
- {
- auto& m_LagRecords = records;
- for (auto lag_record = m_LagRecords.begin(); lag_record != m_LagRecords.end(); lag_record++)
- {
- m_LagRecords.erase(lag_record);
- }
- }
- void LagFix::drop_all_log_records()
- {
- //for (int i = 0; i < 64; i++)
- int i = 0;
- while (i != 64)
- {
- auto& m_LagRecords = update_records[i];
- for (auto lag_record = m_LagRecords.begin(); lag_record != m_LagRecords.end(); lag_record++)
- {
- m_LagRecords.erase(lag_record);
- }
- i++;
- }
- }
- void LagFix::drop_old_records(std::deque<Record>& records)
- {
- auto& m_LagRecords = records;
- for (auto lag_record = m_LagRecords.begin(); lag_record != m_LagRecords.end(); lag_record++)
- {
- if (!check_tick_validity(TIME_TO_TICKS(lag_record->m_flSimulationTime)))
- {
- m_LagRecords.erase(lag_record);
- if (!m_LagRecords.empty())
- lag_record = m_LagRecords.begin();
- else break;
- }
- }
- }
- bool LagFix::check_tick_validity(int tick)
- {
- INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
- if (!nci)
- return false;
- //float correct = clamp(nci->GetLatency(FLOW_OUTGOING) + get_lerp_time(), 0.f, 1.f);
- //float deltaTime = correct - (g_pGlobalVarsBase->curtime - TICKS_TO_TIME(tick));
- //return fabsf(deltaTime) < 0.2f;
- auto PredictedCmdArrivalTick = g_pGlobalVarsBase->tickcount + TIME_TO_TICKS(nci->GetAvgLatency(FLOW_INCOMING) + nci->GetAvgLatency(FLOW_OUTGOING));
- auto Correct = clamp(get_lerp_time() + nci->GetLatency(FLOW_OUTGOING), 0.f, 1.f) - TICKS_TO_TIME(PredictedCmdArrivalTick + TIME_TO_TICKS(get_lerp_time()) - tick);
- //auto delta_ticks = (clamp(TIME_TO_TICKS(get_incoming_latency() + get_outgoing_latency()) + g_pGlobalVarsBase->tickcount - tick, 0, 20));
- return fabsf(Correct) < 0.2f;
- }
- std::map<float *, Entry> m_Map;
- float mirv_cycle_mod(float value)
- {
- if (value < 0)
- while (value < 0) value += 1.0f;
- else
- while (1 < value) value -= 1.0f;
- return value;
- }
- bool check_if_changed(float_t new_cycle, float_t old_cycle, float_t* output)
- {
- float newNetValue = new_cycle;
- float newEngineValue = old_cycle;
- const std::pair<const std::map<float *, Entry>::iterator, bool> & res = m_Map.insert(std::make_pair(&old_cycle, Entry(newNetValue, newEngineValue, 0)));
- if (!res.second)
- {
- if (0.0f != newNetValue)
- {
- float oldNetValue = res.first->second.oldNet;
- res.first->second.oldNet = newNetValue;
- float oldEngineValue = res.first->second.oldEngine;
- res.first->second.oldEngine = newEngineValue;
- float deltaNet = newNetValue >= oldNetValue ? newNetValue - oldNetValue : newNetValue + 1.0f - oldNetValue;
- float net = oldNetValue;
- float engine = newEngineValue;
- float totalError;
- // I wish I was better at math, the correction values could need some numerical optimization!
- if (net >= engine)
- {
- if (0.5f >= net - engine)
- totalError = net - engine;
- else
- totalError = net - 1.0f - engine;
- }
- else
- {
- if (0.5f >= net + 1.0f - engine)
- totalError = net + 1.0f - engine;
- else
- totalError = net + 1.0f - 1.0f - engine;
- }
- if (totalError < -0.5f)
- {
- // actually should never happen, just for readability.
- totalError = -0.5f;
- }
- else
- if (0.5f < totalError)
- {
- // actually should never happen, just for readability.
- totalError = 0.5f;
- }
- res.first->second.oldError = totalError;
- float targetVal;
- if (0.3f <= abs(totalError))
- {
- targetVal = newNetValue; // give up
- }
- else
- {
- float targetDelta = deltaNet + totalError;
- if (targetDelta < 0) targetDelta = 0;
- targetVal = mirv_cycle_mod(newEngineValue + targetDelta);
- //float targetDelta = 0;
- //targetVal = newEngineValue;
- }
- *output = targetVal;
- return true;
- }
- }
- return false;
- }
- void LagFix::update_player_animations()
- {
- for (auto i = 0; i < g_pEntityList->GetHighestEntityIndex(); i++)
- {
- SDK::CBaseEntity* player = nullptr;
- if (!(player = g_pEntityList->GetBaseEntity(i)))
- continue;
- SDK::player_info_t pTemp;
- if (!g_pIVEngineClient->GetPlayerInfo(i, &pTemp))
- continue;
- if (player->IsValid2())
- continue;
- //int layerCount = player->GetNumAnimOverlays();
- //auto animstate = player->GetAnimState();
- int idx = player->GetIndex();
- auto update_player = [&](CBaseEntity* e) {
- // the refhandle is something that changes when the entity is updated
- // (entity disconnected and a new player joined at it's index)
- player_info_t info;
- g_pIVEngineClient->GetPlayerInfo(e->GetIndex(), &info);
- auto handle = info.szSteamID;
- e->m_bClientSideAnimation() = true;
- if (e->GetAnimState()->m_flLastClientSideAnimationUpdateTime >= g_pGlobalVarsBase->curtime) {
- // decrement update time
- e->GetAnimState()->m_flLastClientSideAnimationUpdateTime = g_pGlobalVarsBase->curtime - g_pGlobalVarsBase->interval_per_tick;
- }
- // framecount is also a factor
- if (e->GetAnimState()->m_iLastClientSideAnimationUpdateFramecount >= g_pGlobalVarsBase->framecount) {
- // decrement framecount
- e->GetAnimState()->m_iLastClientSideAnimationUpdateFramecount = g_pGlobalVarsBase->framecount - 1;
- }
- // force an update on the client-side animation
- e->UpdateClientSideAnimation();
- e->m_bClientSideAnimation() = false;
- };
- update_player(player);
- }
- }
- void LagFix::adjust_cycle(ClientFrameStage_t curStage)
- {
- for (auto i = 0; i < g_pEntityList->GetHighestEntityIndex(); i++)
- {
- SDK::CBaseEntity* player = nullptr;
- if (!(player = g_pEntityList->GetBaseEntity(i)))
- continue;
- SDK::player_info_t pTemp;
- if (!g_pIVEngineClient->GetPlayerInfo(i, &pTemp))
- continue;
- if (player->IsValid2())
- continue;
- //int layerCount = player->GetNumAnimOverlays();
- //auto animstate = player->GetAnimState();
- int idx = player->GetIndex();
- auto update_player = [&](CBaseEntity* e) {
- // the refhandle is something that changes when the entity is updated
- // (entity disconnected and a new player joined at it's index)
- player_info_t info;
- g_pIVEngineClient->GetPlayerInfo(e->GetIndex(), &info);
- auto handle = info.szSteamID;
- e->m_bClientSideAnimation() = true;
- if (e->GetAnimState()->m_flLastClientSideAnimationUpdateTime >= g_pGlobalVarsBase->curtime) {
- // decrement update time
- e->GetAnimState()->m_flLastClientSideAnimationUpdateTime = g_pGlobalVarsBase->curtime - g_pGlobalVarsBase->interval_per_tick;
- }
- // framecount is also a factor
- if (e->GetAnimState()->m_iLastClientSideAnimationUpdateFramecount >= g_pGlobalVarsBase->framecount) {
- // decrement framecount
- e->GetAnimState()->m_iLastClientSideAnimationUpdateFramecount = g_pGlobalVarsBase->framecount - 1;
- }
- // force an update on the client-side animation
- e->UpdateClientSideAnimation();
- e->m_bClientSideAnimation() = false;
- };
- auto fix_animation = [&](CBaseEntity* e) {
- // the refhandle is something that changes when the entity is updated
- // (entity disconnected and a new player joined at it's index)
- player_info_t info;
- g_pIVEngineClient->GetPlayerInfo(e->GetIndex(), &info);
- auto handle = info.szSteamID;
- // do the appropriate action in the appropriate stage
- switch (curStage) {
- // in this case, we've only just received fresh, uninterpolated animation data
- case FRAME_NET_UPDATE_START:
- {
- steamid[idx] = handle;
- memcpy(&m_anim_uninterpolated[idx], e->GetAnimOverlays(), sizeof(AnimationLayer) * e->GetNumAnimOverlays());
- for (int i = 0; i < 24; i++)
- m_poses_uninterpolated[i][idx] = player->get_pose_parameter(i);
- }break;
- // haven't done much reversing into this, however, i assume that the localplayer has interpolated
- // the data, so we swap it with the uninterpolated, fresh data instead
- case FRAME_RENDER_START:
- {
- // the entity changed
- if (handle != steamid[idx]) {
- return;
- }
- memcpy(&m_anim_interpolated[idx], e->GetAnimOverlays(), sizeof(AnimationLayer) * e->GetNumAnimOverlays());
- for (int i = 0; i < 24; i++)
- m_poses_interpolated[i][idx] = player->get_pose_parameter(i);
- memcpy(e->GetAnimOverlays(), &m_anim_uninterpolated[idx], sizeof(AnimationLayer) * e->GetNumAnimOverlays());
- for (int i = 0; i < 24; i++)
- player->get_pose_parameter(i) = m_poses_uninterpolated[i][idx];
- }break;
- case FRAME_RENDER_END:
- {
- // the entity changed
- if (handle != steamid[idx]) {
- return;
- }
- memcpy(e->GetAnimOverlays(), &m_anim_interpolated[idx], sizeof(AnimationLayer) * e->GetNumAnimOverlays());
- for (int i = 0; i < 24; i++)
- player->get_pose_parameter(i) = m_poses_interpolated[i][idx];
- }break;
- default: {
- break;
- }break;
- }
- };
- fix_animation(player);
- // backup ------------------------------------------------------------------------------------------------------------------
- //if (curStage == FRAME_NET_UPDATE_START)
- //{
- // for (int i = 0; i < 24; i++)
- // backup_poses[i][idx] = player->get_pose_parameter(i);
- // for (int i = 0; i < 13; i++) {
- // backup_layers[i][idx].m_flCycle = player->GetAnimOverlay(i)->m_flCycle;
- // backup_layers[i][idx].m_flPlaybackRate = player->GetAnimOverlay(i)->m_flPlaybackRate;
- // backup_layers[i][idx].m_flPrevCycle = player->GetAnimOverlay(i)->m_flPrevCycle;
- // backup_layers[i][idx].m_flWeight = player->GetAnimOverlay(i)->m_flWeight;
- // backup_layers[i][idx].m_flWeightDeltaRate = player->GetAnimOverlay(i)->m_flWeightDeltaRate;
- // backup_layers[i][idx].m_nOrder = player->GetAnimOverlay(i)->m_nOrder;
- // backup_layers[i][idx].m_nSequence = player->GetAnimOverlay(i)->m_nSequence;
- // }
- //}
- //// restore -----------------------------------------------------------------------------------------------------------------
- //if (curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_START)
- //{
- // player->SetAbsOrigin(backup_absorigin[idx]);
- // player->SetAbsAngles(backup_absangles[idx]);
- // for (int i = 0; i < 24; i++)
- // player->get_pose_parameter(i) = backup_poses[i][idx];
- // for (int i = 0; i < 13; i++) {
- // player->GetAnimOverlay(i)->m_flCycle = backup_layers[i][idx].m_flCycle;
- // player->GetAnimOverlay(i)->m_flPlaybackRate = backup_layers[i][idx].m_flPlaybackRate;
- // player->GetAnimOverlay(i)->m_flPrevCycle = backup_layers[i][idx].m_flPrevCycle;
- // player->GetAnimOverlay(i)->m_flWeight = backup_layers[i][idx].m_flWeight;
- // player->GetAnimOverlay(i)->m_flWeightDeltaRate = backup_layers[i][idx].m_flWeightDeltaRate;
- // player->GetAnimOverlay(i)->m_nOrder = backup_layers[i][idx].m_nOrder;
- // player->GetAnimOverlay(i)->m_nSequence = backup_layers[i][idx].m_nSequence;
- // }
- //}
- //if (curStage == FRAME_NET_UPDATE_START)
- //{
- // for (int i = 0; i < layerCount; ++i)
- // {
- // AnimationLayer *currentLayer = player->GetAnimOverlay(i);
- // m_nsaved_Order[i][idx] = currentLayer->m_nOrder;
- // m_nsaved_Sequence[i][idx] = currentLayer->m_nSequence;
- // m_flsaved_Weight[i][idx] = currentLayer->m_flWeight;
- // m_flsaved_Cycle[i][idx] = currentLayer->m_flCycle;
- // m_flsaved_PrevCycle[i][idx] = currentLayer->m_flPrevCycle;
- // m_flsaved_PlaybackRate[i][idx] = currentLayer->m_flPlaybackRate;
- // m_flsaved_WeightDeltaRate[i][idx] = currentLayer->m_flWeightDeltaRate;
- // }
- //}
- //if (curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_START || curStage == FRAME_RENDER_END || curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_END)
- //{
- // for (int i = 0; i < layerCount; ++i)
- // {
- // auto new_cycle = m_flsaved_Cycle[i][idx];
- // auto old_cycle = m_flsaved_PrevCycle[i][idx];
- // float_t new_value;
- // AnimationLayer *currentLayer = player->GetAnimOverlay(i);
- // currentLayer->m_nOrder = m_nsaved_Order[i][idx];
- // currentLayer->m_nSequence = m_nsaved_Sequence[i][idx];
- // currentLayer->m_flWeight = m_flsaved_Weight[i][idx];
- // currentLayer->m_flPrevCycle = m_flsaved_PrevCycle[i][idx];
- // currentLayer->m_flPlaybackRate = m_flsaved_PlaybackRate[i][idx];
- // currentLayer->m_flWeightDeltaRate = m_flsaved_WeightDeltaRate[i][idx];
- // //if (check_if_changed(new_cycle, old_cycle, &new_value))
- // // currentLayer->m_flCycle = new_value;
- // currentLayer->m_flCycle = m_flsaved_Cycle[i][idx];
- // }
- //}
- //for (int i = 0; i < layerCount; ++i)
- //{
- // AnimationLayer *currentLayer = player->GetAnimOverlay(i);
- // auto new_cycle = currentLayer->m_flCycle;
- // auto old_cycle = currentLayer->m_flPrevCycle;
- // float_t new_value;
- // //currentLayer->m_nOrder = entity_records.m_LayerRecords[i].m_nOrder;
- // //currentLayer->m_nSequence = entity_records.m_LayerRecords[i].m_nSequence;
- // //currentLayer->m_flWeight = entity_records.m_LayerRecords[i].m_flWeight;
- // //currentLayer->m_flCycle = entity_records.m_LayerRecords[i].m_flCycle;
- // bool broken = 0.0f != new_cycle && (
- // old_cycle > new_cycle && 0.5f > old_cycle - new_cycle
- // || old_cycle < new_cycle && 0.5f < new_cycle - old_cycle
- // );
- // if (check_if_changed(new_cycle, old_cycle, new_value))
- // {
- // currentLayer->m_flCycle = new_value;
- // animstate->m_flLastClientSideAnimationUpdateTime = g_pGlobalVarsBase->curtime;
- // animstate->m_iLastClientSideAnimationUpdateFramecount = g_pGlobalVarsBase->framecount;
- // }
- //}
- }
- }
- float LagFix::get_lerp_time()
- {
- int ud_rate = g_pICvar->FindVar("cl_updaterate")->GetFloat();
- ConVar *min_ud_rate = g_pICvar->FindVar("sv_minupdaterate");
- ConVar *max_ud_rate = g_pICvar->FindVar("sv_maxupdaterate");
- if (min_ud_rate && max_ud_rate)
- ud_rate = max_ud_rate->GetFloat();
- float ratio = g_pICvar->FindVar("cl_interp_ratio")->GetFloat();
- if (ratio == 0)
- ratio = 1.0f;
- float lerp = g_pICvar->FindVar("cl_interp")->GetFloat();
- ConVar *c_min_ratio = g_pICvar->FindVar("sv_client_min_interp_ratio");
- ConVar *c_max_ratio = g_pICvar->FindVar("sv_client_max_interp_ratio");
- if (c_min_ratio && c_max_ratio && c_min_ratio->GetFloat() != 1)
- ratio = clamp(ratio, c_min_ratio->GetFloat(), c_max_ratio->GetFloat());
- return max(lerp, (ratio / ud_rate));
- }
- template<class T, class U>
- T LagFix::clamp(T in, U low, U high)
- {
- if (in <= low)
- return low;
- if (in >= high)
- return high;
- return in;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement