like amiri in my mind
Пользователь
-
Автор темы
- #1
продолжаю кринжевать, на 60% уверен что все правильно
pred.cpp:
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
#include "prediction_system.h"
void engineprediction::store_netvars()
{
auto data = &netvars_data[m_clientstate()->iCommandAck % MULTIPLAYER_BACKUP];
data->tickbase = g_ctx.local()->m_nTickBase();
data->m_velocity_modifier = g_ctx.local()->m_flVelocityModifier();
data->m_velocity = g_ctx.local()->m_vecVelocity();
data->m_aimPunchAngle = g_ctx.local()->m_aimPunchAngle();
data->m_aimPunchAngleVel = g_ctx.local()->m_aimPunchAngleVel();
data->m_viewPunchAngle = g_ctx.local()->m_viewPunchAngle();
data->m_vecViewOffset = g_ctx.local()->m_vecViewOffset();
data->m_duckAmount = g_ctx.local()->m_flDuckAmount();
data->index = g_ctx.local()->EntIndex();
data->m_duckSpeed = g_ctx.local()->m_flDuckSpeed();
}
void engineprediction::restore_netvars()
{
auto data = &netvars_data[(m_clientstate()->iCommandAck - 0) % MULTIPLAYER_BACKUP];
if (data->tickbase != g_ctx.local()->m_nTickBase())
return;
int repredict = 0;
auto aim_punch_angle_delta = g_ctx.local()->m_aimPunchAngle() - data->m_aimPunchAngle;
auto aim_punch_angle_vel_delta = g_ctx.local()->m_aimPunchAngleVel() - data->m_aimPunchAngleVel;
auto view_punch_angle_delta = g_ctx.local()->m_viewPunchAngle() - data->m_viewPunchAngle;
auto view_offset_delta = g_ctx.local()->m_vecViewOffset() - data->m_vecViewOffset;
auto duck_amount = g_ctx.local()->m_flDuckAmount() - data->m_duckAmount;
auto m_velocity_modifier = g_ctx.local()->m_flVelocityModifier() - data->m_velocity_modifier;
const auto velocity_diff = data->m_velocity - g_ctx.local()->m_vecVelocity();
if (fabs(aim_punch_angle_delta.x) > 0.03425f && fabs(aim_punch_angle_delta.y) > 0.03425f && fabs(aim_punch_angle_delta.z) > 0.03425f)
g_ctx.local()->m_aimPunchAngle() = data->m_aimPunchAngle;
if (fabs(aim_punch_angle_vel_delta.x) > 0.03425f && fabs(aim_punch_angle_vel_delta.y) > 0.03425f && fabs(aim_punch_angle_vel_delta.z) > 0.03425f)
g_ctx.local()->m_aimPunchAngleVel() = data->m_aimPunchAngleVel;
if (fabs(view_punch_angle_delta.x) > 0.03425f && fabs(view_punch_angle_delta.y) > 0.03425f && fabs(view_punch_angle_delta.z) > 0.03425f)
g_ctx.local()->m_viewPunchAngle() = data->m_viewPunchAngle;
if (fabs(view_offset_delta.x) > 0.03425f && fabs(view_offset_delta.y) > 0.03425f && fabs(view_offset_delta.z) > 0.03425f)
g_ctx.local()->m_vecViewOffset() = data->m_vecViewOffset;
if (std::abs(velocity_diff.x) <= 0.03125f && std::abs(velocity_diff.y) <= 0.03125f && std::abs(velocity_diff.z) <= 0.03125f)
g_ctx.local()->m_vecVelocity() = data->m_velocity;
if (std::abs(g_ctx.local()->m_flVelocityModifier() - data->m_velocity_modifier) <= 0.00625f)
g_ctx.local()->m_flVelocityModifier() = data->m_velocity_modifier;
if (std::abs(g_ctx.local()->m_nTickBase() - data->tickbase) <= 0.00625f)
g_ctx.local()->m_nTickBase() = data->tickbase;
if (std::abs(g_ctx.local()->EntIndex() - data->index) <= 0.00625f)
g_ctx.local()->EntIndex() != data->index;
if (fabs(duck_amount) > 0.03425f)
{
g_ctx.local()->m_flDuckAmount() = data->m_duckAmount;
g_ctx.local()->m_flDuckSpeed() = data->m_duckSpeed;
}
}
void engineprediction::setup(CUserCmd* m_pcmd)
{
if (prediction_data.prediction_stage != SETUP)
return;
backup_data.flags = g_ctx.local()->m_fFlags(); //-V807
backup_data.velocity = g_ctx.local()->m_vecVelocity();
backup_data.old_tick = g_ctx.local()->m_nTickBase(); //runcmd fixes tickbase
backup_data.old_first_pred = m_prediction()->IsFirstTimePredicted;
backup_data.old_in_pred = m_prediction()->InPrediction;
prediction_data.old_curtime = m_globals()->m_curtime; //-V807
prediction_data.old_frametime = m_globals()->m_frametime;
//comment this or ur backtrack will fail(we do tickbase manipulation in runcommand)
//prediction_data.old_tick = m_globals()->m_tickcount;
//
//
m_globals()->m_curtime++;
m_globals()->m_frametime++;
m_globals()->m_curtime = TICKS_TO_TIME(g_ctx.globals.fixed_tickbase); //use already fixed tickbase
m_globals()->m_frametime = m_prediction()->EnginePaused ? 0.0f : m_globals()->m_intervalpertick;
//comment this or ur backtrack will fail (we do tickbase manipulation in runcommand)
//m_globals()->m_tickcount = GetTickBase(m_pcmd, g_ctx.local());
m_prediction()->IsFirstTimePredicted = false;
m_prediction()->InPrediction = false;
prediction_data.prediction_stage = PREDICT;
}
void engineprediction::predict(CUserCmd* m_pcmd)
{
if (prediction_data.prediction_stage != PREDICT)
return;
if (m_clientstate()->iDeltaTick > 0) //-V807
m_prediction()->Update(m_clientstate()->iDeltaTick, true, m_clientstate()->nLastCommandAck, m_clientstate()->nLastOutgoingCommand + m_clientstate()->iChokedCommands);
if (!prediction_data.prediction_random_seed)
prediction_data.prediction_random_seed = *reinterpret_cast <int**> (util::FindSignature(crypt_str("client.dll"), crypt_str("A3 ? ? ? ? 66 0F 6E 86")) + 0x1);
*prediction_data.prediction_random_seed = MD5_PseudoRandom(m_pcmd->m_command_number) & INT_MAX;
if (!prediction_data.prediction_player)
prediction_data.prediction_player = *reinterpret_cast <int**> (util::FindSignature(crypt_str("client.dll"), crypt_str("89 35 ? ? ? ? F3 0F 10 48")) + 0x2);
*prediction_data.prediction_player = reinterpret_cast <int> (g_ctx.local());
m_gamemovement()->StartTrackPredictionErrors(g_ctx.local()); //-V807
m_prediction()->CheckMovingGround(g_ctx.local(), m_globals()->m_frametime);
CMoveData move_data;
memset(&move_data, 0, sizeof(CMoveData));
//think
if (g_ctx.local()->physics_run_think(0))
g_ctx.local()->pre_think();
// run think
if (int* iNextThinkTick = g_ctx.local()->GetNextThinkTick(); *iNextThinkTick > 0 && *iNextThinkTick <= g_ctx.globals.fixed_tickbase)
{
*iNextThinkTick = -1;
/*
* handle no think function
* pseudo i guess didnt seen before but not sure, most likely unnecessary
nEFlags = pPlayer->GetEFlags();
result = pPlayer->GetEFlags() & EFL_NO_THINK_FUNCTION;
if (!result)
{
result = [&]()
{
if (pPlayer->GetNextThinkTick() > 0)
return 1;
v3 = *(_DWORD *)(pPlayer + 0x2BC);
v4 = 0;
if (v3 > 0)
{
v5 = (_DWORD *)(*(_DWORD *)(pPlayer + 0x2B0) + 0x14);
while (*v5 <= 0)
{
++v4;
v5 += 8;
if (v4 >= v3)
return 0;
}
return 1;
}();
if (!result)
pPlayer->GetEFlags() = nEFlags | EFL_NO_THINK_FUNCTION;
}
*/
g_ctx.local()->think();
}
m_movehelper()->set_host(g_ctx.local());
m_prediction()->SetupMove(g_ctx.local(), m_pcmd, m_movehelper(), &move_data);
m_gamemovement()->ProcessMovement(g_ctx.local(), &move_data);
m_prediction()->FinishMove(g_ctx.local(), m_pcmd, &move_data);
m_movehelper()->process_impacts();
g_ctx.local()->post_think();
//iam not sure its gonna be like dat
g_ctx.local()->m_nTickBase() = backup_data.old_tick;
m_prediction()->InPrediction = backup_data.old_in_pred;
m_prediction()->IsFirstTimePredicted = backup_data.old_first_pred;
m_gamemovement()->FinishTrackPredictionErrors(g_ctx.local());
m_movehelper()->set_host(nullptr);
//why not to update accuracy penalty? we must
const auto weapon = g_ctx.local()->m_hActiveWeapon().Get();
if (!weapon) {
weapon->get_spread();
weapon->get_inaccuracy();
}
else {
weapon->get_spread();
weapon->get_inaccuracy();
}
weapon->update_accuracy_penality();
auto viewmodel = g_ctx.local()->m_hViewModel().Get();
if (viewmodel)
{
viewmodel_data.weapon = viewmodel->m_hWeapon().Get();
viewmodel_data.viewmodel_index = viewmodel->m_nViewModelIndex();
viewmodel_data.sequence = viewmodel->m_nSequence();
viewmodel_data.animation_parity = viewmodel->m_nAnimationParity();
viewmodel_data.cycle = viewmodel->m_flCycle();
viewmodel_data.animation_time = viewmodel->m_flAnimTime();
}
prediction_data.prediction_stage = FINISH;
}
void engineprediction::finish()
{
if (prediction_data.prediction_stage != FINISH)
return;
*prediction_data.prediction_random_seed = -1;
*prediction_data.prediction_player = 0;
m_globals()->m_curtime = prediction_data.old_curtime;
m_globals()->m_frametime = prediction_data.old_frametime;
//comment this or ur backtrack will fail(we do tickbase manipulation in runcommand)
//m_globals()->m_tickcount = prediction_data.old_tick;
m_gamemovement()->Reset();
}
//note that we already done it in runcommand hook
/*
int engineprediction::GetTickBase(CUserCmd* pCmd, player_t* pLocal)
{
static int iTick = 0;
if (pCmd != nullptr)
{
static CUserCmd* pLastCmd = nullptr;
// if command was not predicted - increment tickbase
if (pLastCmd == nullptr || pLastCmd->m_predicted)
iTick = pLocal->m_nTickBase();
else
iTick++;
pLastCmd = pCmd;
}
return iTick;
}
*/