ставь чайник, зажигай плиту
-
Автор темы
- #1
Предикшн взят с wok sdk с небольшими изменениями.
EnginePrediction.cpp:
EnginePrediction.hpp:
EnginePrediction.cpp:
Код:
int post_think(IBasePlayer* player) {
getvfunc<void(__thiscall*)(void*)>(interfaces.model_cache, 33)(interfaces.model_cache);
if (player->isAlive()
|| *reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(player) + 0x3A81)) {
getvfunc<void(__thiscall*)(void*)>(player, 339)(player);
player->GetFlags()& FL_ONGROUND ? player->GetFallVelocity() = 0.f : 0;
player->GetSequence() == -1 ? getvfunc<void(__thiscall*)(void*, int)>(player, 218)(player, 0) : 0;
getvfunc<void(__thiscall*)(void*)>(player, 219)(player);
static auto post_think_v_physics = reinterpret_cast <bool(__thiscall*)(IBasePlayer*)> (csgo->Utils.FindSignature("client.dll", "55 8B EC 83 E4 F8 81 EC ? ? ? ? 53 8B D9 56 57 83 BB"));
post_think_v_physics(player);
}
static auto simulate_player_simulated_entities = reinterpret_cast <bool(__thiscall*)(IBasePlayer*)> (csgo->Utils.FindSignature("client.dll", "56 8B F1 57 8B BE ? ? ? ? 83 EF 01 78 72"));
simulate_player_simulated_entities(player);
return getvfunc<int(__thiscall*)(void*)>(interfaces.model_cache, 34)(interfaces.model_cache);
}
void CEnginePrediction::Start(CUserCmd* cmd, IBasePlayer* local) {
if (!local)
return;
backup_data.flags = local->GetFlags();
backup_data.velocity = local->GetVelocity();
interfaces.prediction->Update(csgo->client_state->iDeltaTick, csgo->client_state->iDeltaTick > 0, csgo->client_state->nLastCommandAck,
csgo->client_state->nLastOutgoingCommand + csgo->client_state->iChokedCommands);
old_vars.curtime = interfaces.global_vars->curtime;
old_vars.frametime = interfaces.global_vars->frametime;
old_vars.tickcount = interfaces.global_vars->tickcount;
old_vars.m_in_prediction = interfaces.prediction->bInPrediction;
old_vars.m_first_time_predicted = interfaces.prediction->bIsFirstTimePredicted;
interfaces.global_vars->curtime = TICKS_TO_TIME(local->GetTickBase());
interfaces.global_vars->frametime = interfaces.prediction->bEnginePaused ? 0.f : interfaces.global_vars->interval_per_tick;
interfaces.global_vars->tickcount = TIME_TO_TICKS(interfaces.global_vars->curtime);
interfaces.prediction->bInPrediction = true;
interfaces.prediction->bIsFirstTimePredicted = false;
*reinterpret_cast<CUserCmd**>(reinterpret_cast<uintptr_t>(local) + 0x3288) = cmd;
if (!prediction_random_seed)
prediction_random_seed = *reinterpret_cast <int**> (csgo->Utils.FindSignature("client.dll", "A3 ? ? ? ? 66 0F 6E 86") + 0x1);
if (!prediction_player)
prediction_player = *reinterpret_cast <int**> (csgo->Utils.FindSignature("client.dll", "89 35 ? ? ? ? F3 0F 10 48") + 0x2);
auto buttons_forced = *reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(local) + 0x3334);
auto buttons_disabled = *reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(local) + 0x3330);
cmd->buttons |= buttons_forced;
cmd->buttons &= ~buttons_disabled;
interfaces.move_helper->SetHost(local);
interfaces.game_movement->StartTrackPredictionErrors(local);
if (cmd->weaponselect) {
auto weapon = reinterpret_cast<IBaseCombatWeapon*>(interfaces.ent_list->GetClientEntity(cmd->weaponselect));
if (weapon) {
auto weapon_data = weapon->GetCSWpnData();
weapon_data ? local->select_item(weapon_data->m_szWeaponName, cmd->weaponsubtype) : 0;
}
}
if (cmd->impulse)
*local->GetImpulse() = cmd->impulse;
auto buttons = cmd->buttons;
auto buttons_changed = buttons ^ *local->GetButtons();
local->GetButtonLast() = *local->GetButtons();
*local->GetButtons() = buttons;
local->GetButtonPressed() = buttons_changed & buttons;
local->GetButtonReleased() = buttons_changed & ~buttons;
interfaces.prediction->CheckMovingGround(local, interfaces.global_vars->frametime);
local->SetLocalViewAngles(cmd->viewangles);
local->PhysicsRunThink(0) ? local->PreThink() : 0;
if (local->GetNextThinkTick()
&& *local->GetNextThinkTick() != -1
&& *local->GetNextThinkTick() <= local->GetTickBase()) {
*local->GetNextThinkTick() = -1;
local->UnknownThink(0);
local->Think();
}
memset(&data, 0, sizeof(data));
interfaces.prediction->SetupMove(local, cmd, interfaces.move_helper, &data);
interfaces.game_movement->ProcessMovement(local, &data);
interfaces.prediction->FinishMove(local, cmd, &data);
interfaces.move_helper->ProcessImpacts();
post_think(local);
interfaces.prediction->bInPrediction = old_vars.m_in_prediction;
interfaces.prediction->bIsFirstTimePredicted = old_vars.m_first_time_predicted;
}
void CEnginePrediction::Finish(IBasePlayer* local) {
if (!local)
return;
interfaces.game_movement->FinishTrackPredictionErrors(local);
interfaces.move_helper->SetHost(nullptr);
interfaces.game_movement->Reset();
*prediction_random_seed = -1;
*prediction_player = 0;
!interfaces.prediction->bEnginePaused && interfaces.global_vars->frametime ? local->GetTickBasePtr()++ : 0;
interfaces.global_vars->curtime = old_vars.curtime;
interfaces.global_vars->frametime = old_vars.frametime;
}
EnginePrediction.hpp:
Код:
struct backup
{
int flags = 0;
Vector velocity = Vector(0, 0, 0);
};
class CEnginePrediction : public Singleton<CEnginePrediction>
{
public:
void Start(CUserCmd* cmd, IBasePlayer* local);
void Finish(IBasePlayer* local);
backup backup_data;
private:
CMoveData data;
struct {
float curtime, frametime;
int tickcount, tickbase;
bool m_in_prediction, m_first_time_predicted;
}old_vars;
int* prediction_random_seed = nullptr;
int* prediction_player = nullptr;
};
C++:
void fake_duck(bool& send_packet)
{
csgo->cmd->buttons |= IN_BULLRUSH; // force IN_BULLRUSH
csgo->fake_duck = false;
if (csgo->cmd->buttons & IN_JUMP ||
!(csgo->local->GetFlags() & FL_ONGROUND) ||
!vars.antiaim.enable ||
!vars.antiaim.fakeduck->active)
return;
csgo->fake_duck = true;
if (csgo->client_state->iChokedCommands < 7)
csgo->cmd->buttons &= ~IN_DUCK;
else
csgo->cmd->buttons |= IN_DUCK;
}
После начала предикшна:
C++:
auto velocity_predicted = csgo->local->GetVelocity();
auto abs_velocity_predicted = csgo->local->GetAbsVelocity();
csgo->local->GetVelocity() = CEnginePrediction::Get().backup_data.velocity;
csgo->local->GetAbsVelocity() = CEnginePrediction::Get().backup_data.velocity;
csgo->local->GetWeapon()->UpdateAccuracyPenalty(); // delete updateaccpen from hitchance
csgo->local->GetVelocity() = velocity_predicted;
csgo->local->GetAbsVelocity() = abs_velocity_predicted;
C++:
static auto dmg_reduction_bullets = interfaces.cvars->FindVar("ff_damage_reduction_bullets")->GetFloat();
static auto dmg_bullet_penetration = interfaces.cvars->FindVar("ff_damage_bullet_penetration")->GetFloat();
if (enter_material == CHAR_TEX_GRATE || enter_material == CHAR_TEX_GLASS)
{
compined_penetration_modifier = 3.0f;
final_damage_modifier = 0.05f;
}
else if (light_surf || solid_surf)
{
compined_penetration_modifier = 1.0f;
final_damage_modifier = 0.16f;
}
else if (enter_material == CHAR_TEX_FLESH && data.m_enter_trace.m_pEnt->GetTeam() != csgo->local->GetTeam() && !dmg_reduction_bullets)
{
if (!dmg_bullet_penetration)
return false;
compined_penetration_modifier = dmg_bullet_penetration;
final_damage_modifier = 0.16f;
}
else
{
compined_penetration_modifier = (enter_surf_penetration_modifier + exit_surf_penetration_modifier) * 0.5f;
final_damage_modifier = 0.16f;
}
if (enter_material == exit_material)
{
if (exit_material == CHAR_TEX_CARDBOARD || exit_material == CHAR_TEX_WOOD)
compined_penetration_modifier = 3.f;
else if (exit_material == CHAR_TEX_PLASTIC)
compined_penetration_modifier = 2.0f;
}
C++:
float get_at_targets()
{
IBasePlayer* found_player;
auto best_fov = FLT_MAX;
for (auto i = 1; i < interfaces.global_vars->maxClients; i++)
{
auto e = interfaces.ent_list->GetClientEntity(i);
if (!e->valid())
continue;
Vector angles;
interfaces.engine->GetViewAngles(angles);
auto cur_fov = Math::GetFov(angles, Math::CalculateAngle(csgo->local->GetEyePosition(), e->GetAbsOrigin()));
if (cur_fov < best_fov)
{
best_fov = cur_fov;
target = e;
}
}
if (!target)
return csgo->cmd->viewangles.y;
return Math::CalculateAngle(csgo->local->GetEyePosition(), target->GetAbsOrigin()).y + 180.f;
}
C++:
csgo->cmd->viewangles.y -= desync_amount;
if (side > 0)
csgo->cmd->viewangles.y += desync_amount * ((float)vars.antiaim.body_lean / 100.f);
else
csgo->cmd->viewangles.y += desync_amount * ((float)vars.antiaim.inv_body_lean / 100.f);
C++:
Vector Ragebot::GetAimVector(IBasePlayer* pTarget, float& simtime, Vector& origin, animation*& best_anims, int& hitbox)
{
if (GetHitboxesToScan(pTarget).size() == 0)
return Vector(0, 0, 0);
float m_damage = 100.f;
if (!csgo->local->GetWeapon()->IsZeus())
m_damage = vars.ragebot.override_dmg->active ? CurrentSettings().mindamage_override : CurrentSettings().mindamage;
auto latest_animation = g_Animfix->get_latest_animation(pTarget);
auto record = latest_animation;
if (!record.has_value() || !record.value()->player)
return Vector(0, 0, 0);
BackupPlayer(record.value());
if (!vars.ragebot.posadj) {
float damage = -1.f;
best_anims = record.value();
return FullScan(record.value(), hitbox, simtime, damage, m_damage);
}
if (vars.ragebot.backshoot_bt && !vars.ragebot.force_body->active && csgo->local->GetWeapon()->GetItemDefinitionIndex() != WEAPON_AWP) {
record = g_Animfix->get_latest_firing_animation(pTarget);
if (record.has_value() && record.value()->player) {
float damage = -1.f;
best_anims = record.value();
simtime = record.value()->sim_time;
Vector backshoot = HeadScan(record.value(), hitbox, damage, m_damage);
if (backshoot != Vector(0, 0, 0))
return backshoot;
}
}
auto oldest_animation = g_Animfix->get_oldest_animation(pTarget);
Vector latest_origin = Vector(0, 0, 0);
float best_damage_0 = -1.f, best_damage_1 = -1.f;
record = latest_animation;
Vector full_0;
if (record.has_value())
{
latest_origin = record.value()->origin;
float damage = -1.f;
full_0 = FullScan(record.value(), hitbox, simtime, damage, m_damage);
if (full_0 != Vector(0, 0, 0))
{
best_damage_0 = damage;
if (best_damage_0 > pTarget->GetHealth())
{
best_anims = record.value();
return full_0;
}
}
}
record = oldest_animation;
Vector full_1;
if (record.has_value())
{
float damage = -1.f;
full_1 = FullScan(record.value(), hitbox, simtime, damage, m_damage);
if (full_1 != Vector(0, 0, 0))
{
best_damage_1 = damage;
if (best_damage_1 > pTarget->GetHealth())
{
best_anims = record.value();
return full_1;
}
}
}
if (best_damage_0 >= best_damage_1 && best_damage_0 >= 1.f)
{
record = latest_animation;
best_anims = record.value();
return full_0;
}
else if (best_damage_1 >= 1.f)
{
record = oldest_animation;
best_anims = record.value();
return full_1;
}
return Vector(0, 0, 0);
}
C++:
// did we hit the hitbox?
if (vars.ragebot.hitchance_consider_hitbox
&& box != (int)CSGOHitboxID::LeftFoot
&& box != (int)CSGOHitboxID::RightFoot) {
if (CanHitHitbox(start, end, _animation, studio_model, box))
current++;
}
else
{
auto bullet_data = g_AutoWall.Think(position, _animation->player);
if (bullet_data.m_damage >= 1 && bullet_data.m_hitbox == box)
current++;
}
C++:
void animation::build_server_bones(IBasePlayer* player)
{
const auto backup_occlusion_flags = player->GetOcclusionFlags();
const auto backup_occlusion_framecount = player->GetOcclusionFramecount();
player->GetOcclusionFlags() = 0;
player->GetOcclusionFramecount() = 0;
player->GetReadableBones() = player->GetWritableBones() = 0;
player->InvalidateBoneCache();
player->GetEffects() |= 0x8;
const auto backup_bone_array = player->GetBoneArrayForWrite();
player->GetBoneArrayForWrite() = bones;
csgo->UpdateMatrix = true;
player->SetupBones(nullptr, -1, 0x7FF00, player->GetSimulationTime());
csgo->UpdateMatrix = false;
player->GetBoneArrayForWrite() = backup_bone_array;
player->GetOcclusionFlags() = backup_occlusion_flags;
player->GetOcclusionFramecount() = backup_occlusion_framecount;
player->GetEffects() &= ~0x8;
}
Код:
if (csgo->UpdateMatrix)
return false;
C++:
void CMAnimationFix::update_player(IBasePlayer* player, animation* record, animation* previous)
{
static auto& enable_bone_cache_invalidation = **reinterpret_cast<bool**>(
reinterpret_cast<uint32_t>((void*)csgo->Utils.FindPatternIDA(GetModuleHandleA(g_Modules[fnv::hash(hs::client_dll::s().c_str())].c_str()),
hs::bone_cache_validation::s().c_str())) + 2);
//// make a backup of globals
const auto backup_frametime = interfaces.global_vars->frametime;
const auto backup_curtime = interfaces.global_vars->curtime;
const auto old_flags = player->GetFlagsPtr();
// get player anim state
auto state = player->GetPlayerAnimState();
if (state->m_iLastClientSideAnimationUpdateFramecount == interfaces.global_vars->framecount)
state->m_iLastClientSideAnimationUpdateFramecount -= 1.f;
// fixes for networked players
interfaces.global_vars->frametime = interfaces.global_vars->interval_per_tick;
interfaces.global_vars->curtime = player->GetSimulationTime();
if (player->GetAnimOverlay(5)->m_flWeight > 0.0f)
player->GetFlagsPtr() |= FL_ONGROUND;
player->GetEFlags() &= ~0x1000;
player->GetAbsVelocity() = player->GetVelocity();
//player->InvalidatePhysicsRecursive(ANIMATION_CHANGED);
// make sure we keep track of the original invalidation state
const auto old_invalidation = enable_bone_cache_invalidation;
// notify the other hooks to instruct animations and pvs fix
csgo->EnableBones = player->GetClientSideAnims() = true;
resolver->Do(player, record);
player->UpdateClientSideAnimation();
csgo->EnableBones = player->GetClientSideAnims() = false;
//player->InvalidatePhysicsRecursive(BOUNDS_CHANGED);
player->InvalidatePhysicsRecursive(ANGLES_CHANGED);
player->InvalidatePhysicsRecursive(ANIMATION_CHANGED);
player->InvalidatePhysicsRecursive(SEQUENCE_CHANGED);
// we don't want to enable cache invalidation by accident
enable_bone_cache_invalidation = old_invalidation;
// restore globals
interfaces.global_vars->curtime = backup_curtime;
interfaces.global_vars->frametime = backup_frametime;
player->GetFlagsPtr() = old_flags;
}
Последнее редактирование: