Исходник Shitty 3months resolver

Начинающий
Статус
Оффлайн
Регистрация
20 Окт 2017
Сообщения
25
Реакции[?]
9
Поинты[?]
0
  1. Код:
    #include "resolver.hpp"
    #include "util_math.hpp"
    #include "tracing.hpp"
    #include "game_tools.hpp"
    #include "profiler.hpp"
    #include "autowall.hpp"
    #include "restore_netvars.hpp"
     
    namespace lambda
    {
        namespace cheat
        {
            namespace resolver
            {
                //Some namespace global variables
                float in_coming_latency = 0;
                float out_going_latency = 0;
                float server_time = 0;
                float lerp_time = 0;
                float correct = 0;
     
                //Config values, putting here set once per tick then just get called from here
                float backtrack_time = 2.0f;
                bool backtracking = false;
                bool fake_lag_fix = false;
                bool lby_resolver = false;
                bool real_resolver = false;
                bool in_attack_resolver = false;
                bool body_hit_resolver = false;
                int logic_history = 10;
                int logic_accuracy = 10;
                bool brute_force_resolver = false;
                bool pitch_resolve = false;
     
                int tick_count_set(const float sim_time)
                {
                    //std::cout << lerp_time << " " << TIME_TO_TICKS(lerp_time) << std::endl;
                    return TIME_TO_TICKS(sim_time + lerp_time) - 1;
                }
     
                void disable_interp()
                {
                    //static auto cl_interpolate = interfaces::cvar->FindVar(XORSTRs("cl_interpolate"));
                    //cl_interpolate->SetValue(0);
                    //return;
                    //Must iterate the entire entity list because rendering is on its own thread
                    static const int max_entities = 64;// Interfaces::ClientEntList->GetHighestEntityIndex();
                    const int localplayerID = interfaces::engine->GetLocalPlayer();
     
                    for (int i = 0; i <= max_entities; i++)
                    {
                        if (i == localplayerID)
                            continue;
     
                        sdk::CCSPlayer* entity = static_cast<sdk::CCSPlayer*>(interfaces::entity_list->GetClientEntity(i));
     
                        if (!entity)
                            continue;
     
                        if (!entity->IsPlayer()
                            || entity->GetDormant()
                            || entity->GetHealth() < 1)
                            continue;
     
                        entity->disable_interp();
                    }
                }
     
                void set_up_netchan()
                {
                    const bool local_player_alive = player_data::local_player_information.health > 0;
     
                    //We want to set up some global values aaccross resolver for net chan here
                    if (local_player_alive)
                    {
                        sdk::INetChannelInfo* nci = interfaces::engine->GetNetChannelInfo();
                        if (nci)
                        {
                            in_coming_latency = nci->GetLatency(int(sdk::INetChannelInfo::FlowDirection::FLOW_INCOMING));
                            out_going_latency = nci->GetLatency(int(sdk::INetChannelInfo::FlowDirection::FLOW_OUTGOING));
                        }
                        else
                        {
                            in_coming_latency = out_going_latency = 0.0f;
                        }
     
                        //TODO: add fake ping calcs
                        const float total_out_latency_fake_ping = out_going_latency;
     
                        server_time = in_coming_latency + out_going_latency + TICKS_TO_TIME(interfaces::globals->tickcount + 1);
                        static sdk::ConVar* cl_interp_ratio = nullptr;
                        static sdk::ConVar* cl_updaterate = nullptr;
     
                        if (!cl_interp_ratio)
                            cl_interp_ratio = interfaces::cvar->FindVar(XORSTRs("cl_interp_ratio"));
     
                        if (!cl_updaterate)
                            cl_updaterate = interfaces::cvar->FindVar(XORSTRs("cl_updaterate"));
     
                        const float interp_ratio = cl_interp_ratio->GetFloat();
                        const float update_rate = cl_updaterate->GetFloat();
                        lerp_time = interp_ratio / update_rate;
     
                        correct = std::clamp(total_out_latency_fake_ping + lerp_time, 0.0f, 1.0f);
                    }
                }
     
                void set_up_idea_points_no_resolve(render::IDrawer* drawer)
                {
                    set_up_netchan();
     
                    for (int i = 0; i < 64; i++)
                    {
                        auto& target = player_data::player_records[i];
                        if (!target.is_player)
                            continue;
     
                        if (target.information.size() <= 0)
                            continue;
     
                        target.ideal_points.clear();
     
                        if (target.breaking_lag_comp)
                        {
                            target.ideal_points.push_back(0);
                            continue;
                        }
     
                        for (size_t a = 0; a < target.information.size(); a++)
                        {
                            if (is_valid_time(target.information[a].sim_time))
                                target.ideal_points.push_back(a);
                        }
                        const auto& p = static_cast<sdk::CCSPlayer*>(target.client_entity);
                        sdk::Vector middle;
                        if(p->get_hitbox_information_detailed(0, middle))
                        {
                            sdk::Vector screen;
                            if (game_tools::world_to_screen(middle, screen))
                            {
                                drawer->rectangle(screen.x, screen.y, 5, 5, 5, sdk::Color::Blue());
                            }
                        }
     
                        restore::restore_netvars_fsn(target.information.at(target.ideal_points.back()),
                            static_cast<sdk::CCSPlayer*>(target.client_entity));
     
                        if (p->get_hitbox_information_detailed(0, middle))
                        {
                            sdk::Vector screen;
                            if (game_tools::world_to_screen(middle, screen))
                            {
                                drawer->rectangle(screen.x, screen.y, 5, 5, 5, sdk::Color::Yellow());
                            }
                        }
     
                    }
     
                }
     
     
                //Begin resolver
                void begin_resolver()
                {
                    PROFILE_FUNCTION();
                    const bool local_player_alive = player_data::local_player_information.health > 0;
                    const int local_player_team_id = player_data::local_player_information.team_id;
     
                    set_up_netchan();
     
     
                    //FIXME: move player data logs before this
                    for (int i = 0; i < 64; i++)
                    {
                        auto& target = player_data::player_records[i];
                        if (target.information.size() < 2)
                            continue;
     
                        if (!target.is_player || local_player_team_id == target.team_id)
                            continue;
     
                        PROFILE_CUSTOM(____loop_prof, "Resolver Single Loop");
     
                        //FIXME: TODO:
                        //Need to do some fake lag stuff in here, involving sim time updating and current_tick updating
                        //Otherweise we will overwrite some normal information, this is different for if breaking lag comp
                        //As we don't care about simtime updating since we cna't backtrack anyway
     
                        auto& current_tick = target.information.front();
                        auto& previous_tick = target.information.at(1);
     
                        const bool lby_updated = current_tick.lby_value != previous_tick.lby_value;
     
                        sdk::QAngle resolver_angle = current_tick.original_viewangle;
                        if (CON(resolve_pitch))
                        {
                            pitch_resolver(resolver_angle.x);
                        }
     
                        //Leaving it as 64 * 64 just to trigger people
     
                        const bool breaking_lag_comp = (current_tick.network_origin - previous_tick.network_origin).LengthSqr() > (64.0f *
                            64.0f
                        );
     
                        if (breaking_lag_comp)
                        {
                            FakeLagFix::get()->extrapolation(current_tick.ticks_since_previous_update, i);
                        }
     
     
                        LogicResolver::get()->log_angles(current_tick.original_viewangle,
                                                         sdk::QAngle(resolver_angle.x, current_tick.lby_value, 0), lby_updated, i);
     
                        if (!local_player_alive)
                        {
                            continue;
                        }
                        //If localplayer isn't alive we don't care about soreing hte backtracking details iircn
     
     
                        //If breaking lag comp can't backtrack.
                        //TODO: find this out, and adjust accordingly:
                        /*
                        If they are breaking lag comp
                        On tick 3
                        but they werne't breaking lag comp on tick 2 can you backtrack them to tick 2.
     
                        And vice versa
                        If they were breaking lag comp on tick 3, but not tick 4 can you backtrack them to tick 4.
     
                        */
     
                        target.breaking_lag_comp = breaking_lag_comp;
                        current_tick.breaking_lag_comp = breaking_lag_comp;
     
                        bool found_better_backtrack = false;
     
                        if (!breaking_lag_comp)
                        {
                            const bool real_angle = target.ticks_since_last_sim_time_update > 1;
                            //NOTE: this could be done with > 0, but i think this is safer
     
                            if (lby_updated && CON(resolve_backtrack_lby))
                            {
                                resolver_angle.y = current_tick.lby_value;
                                target.last_lby_update = current_tick.sim_time;
                                current_tick.lby_updated = true;
                                current_tick.lby_update_time = interfaces::globals->curtime - out_going_latency;//TODO: ping calcs maybe?
                                found_better_backtrack = true;
                            }
     
                            if (real_angle && CON(resolve_backtrack_real))
                            {
                                current_tick.real_angle = true;
                                found_better_backtrack = true;
                                resolver_angle.y = current_tick.original_viewangle.y;
                            }
     
                            //This is stuff we are checking from the previous tick and we will be updating previous_tick not current
                            //TODO: add checks to see if last had a real angle resolve or had a lby resolve then don't bother with this
                            //FIXME: TODO: BUG:
     
                            for (size_t index = 0; index < target.information.size(); index++)
                            {
                                auto& test_tick = target.information.at(index);
                                
                                //Check to see if that tick could be letahl
                                if(test_tick.did_hit)
                                {
                                    const int health = target.health;
                                    test_tick.lethal_damage = health - test_tick.damage_done <= 0;
     
                                    if(test_tick.hitgroup == autowall::HITGROUP_HEAD)
                                    {
                                        test_tick.hit_in_head = true;
                                    }
                                    else if(test_tick.hitgroup > autowall::HITGROUP_HEAD)
                                    {
                                        test_tick.lethal_baim = health - test_tick.damage_done <= 0;
                                    }
                                }
                                else if (!test_tick.lby_updated && CON(resolve_backtrack_real) && !test_tick.real_angle && CON(
                                    resolve_backtrack_real))
                                {
     
                                    if (test_tick.body_hit_perfect)
                                    {
                                        test_tick.viewangle.y = test_tick.body_angle;
                                    }
                                    else if (false)
                                    {
                                        //FIXME: add a check to see if they fired this tick/last tick / how ever this is done
                                    }
                                    else if (test_tick.body_hit)
                                    {
                                        test_tick.viewangle.y = test_tick.body_angle;
                                    }
                                }
                            }
     
                            //It is easier to hit a target, on the ground and if pitch is up so why not take advantage of this
                            if (target.on_ground && CON(resolve_prefer_on_ground))
                            {
                                current_tick.on_ground = true;
                                if ((interfaces::globals->curtime - out_going_latency) - current_tick.lby_update_time > 1.14f)
                                    current_tick.lby_update_time_1p1 = true;
                            }
                            if (CON(resolve_prefer_up) && resolver_angle.x < 10 && resolver_angle.x > -90)
                            {
                                //If they are looking up then lets log this since it is so much easier to hit then if they are using a down aa
                                current_tick.pitch_up = true;
                            }
                        }
     
                        if (!found_better_backtrack || breaking_lag_comp)
                        {
                            //Going to use logic only here, however may want to get brute force added
                            //We use brute force, from logic if it can't resolve  any patterns
     
                            //TODO:
                            //Should apply some logic to do w/ ping fps etc. for future ticks for it
                            //To be more effective
     
                            //If we get to this point reoslver_angles hasn't been set so is the same as original
                            //angles
                            switch (CON(resolver_type))
                            {
                            case 1:
                                BruteForceResolver::get()->brute_force_resolver(resolver_angle, i);
                                break;
                            default:
                                LogicResolver::get()->predict_angles(resolver_angle, 1, i);
                            }
                        }
                        current_tick.viewangle = resolver_angle;
     
                        //Angle has been resolved, now lets create a deque in order of best points to resolve,
                        //Then aimbot can take those and decide based on damage.
                        set_possible_points(i);
     
                        //Update angles
                        restore::restore_netvars_fsn(target.information.at(target.ideal_points.front()),
                            static_cast<sdk::CCSPlayer*>(target.client_entity));
                    }
                }
     
     
                //returns false if resolver angle is not possible
                bool resolver_sanity_check(float angle, float last_lby_update, float curtime, bool on_ground, float lby)
                {
                    if (!on_ground)
                        return true;
                    if (curtime - last_lby_update < 1.1f)
                        return true;
                    if (sdk::math::difference_between_yaw(angle, lby) <= 35)
                        return true;
                    return false;
                }
     
                bool has_local_player_updated(int index, int tick)
                {
                    const auto& local_record = player_data::local_player_information;
                    auto record = player_data::player_records[index].information[tick];
     
                    //Maybe add some margin or error in here.
                    if (record.local_player_duck_amount != local_record.duck_amount)
                        return true;
                    if (record.local_player_origin != local_record.origin)
                        return true;
     
                    return false;
                }
    #ifdef ORIGINAL_RESOLVER_ORDER
     
                void set_possible_points(int index)
                {
                    // TODO: this whole thing can be replaced with a std::sort
     
                    auto& target = player_data::player_records[index];
     
                    target.ideal_points.clear();
     
                    if (target.breaking_lag_comp)
                    {
                        target.ideal_points.push_back(0);
                        return;
                    }
     
                    //All possible resolver types, and where we want them
                    std::deque<int> lby_update_on_ground_head_up;
                    std::deque<int> lby_update_on_ground;
                    std::deque<int> lby_update_on_head_up;
                    std::deque<int> lby_update;
     
                    std::deque<int> real_update_on_ground_head_up;
                    std::deque<int> real_update_on_ground;
                    std::deque<int> real_update_on_head_up;
                    std::deque<int> real_update;
     
                    std::deque<int> body_shot_perfect_update_on_ground_head_up;
                    std::deque<int> body_shot_perfect_update_on_ground;
                    std::deque<int> body_shot_perfect_update_on_head_up;
                    std::deque<int> body_shot_perfect_update;
     
                    std::deque<int> in_attack_update_on_ground_head_up;
                    std::deque<int> in_attack_update_on_ground;
                    std::deque<int> in_attack_update_on_head_up;
                    std::deque<int> in_attack_update;
     
                    std::deque<int> body_shot_update_on_ground_head_up;
                    std::deque<int> body_shot_update_on_ground;
                    std::deque<int> body_shot_updatnoe_on_head_up;
                    std::deque<int> body_shot_update;
     
                    std::deque<int> lby_1p1_update_on_ground_head_up;
                    std::deque<int> lby_1p1_update; //On_ground is a compolsary component of this
     
                    std::deque<int> not_breaking_lag_comp_update_on_ground_head_up;
                    std::deque<int> not_breaking_lag_comp_update_on_ground;
                    std::deque<int> not_breaking_lag_comp_update_on_head_up;
                    std::deque<int> not_breaking_lag_comp_update;
     
                    //once again this needs to be done better will change when way history is stored
                    for (size_t i = 0; i < target.information.size(); i++)
                    {
                        const auto& record = target.information[i];
     
                        //Some tweaking will need to be done to deal with has_local_player_updated
                        if (!is_valid_time(record.sim_time))
                            continue;
     
                        bool on_ground = record.on_ground;
                        bool head_up = record.pitch_up;
     
                        if (record.lby_updated)
                        {
                            if (on_ground && head_up)
                                lby_update_on_ground_head_up.push_back(i);
                            else if (on_ground)
                                lby_update_on_ground.push_back(i);
                            else if (head_up)
                                real_update_on_head_up.push_back(i);
                            else
                                lby_update.push_back(i);
                        }
                        else if (record.real_angle)
                        {
                            if (on_ground && head_up)
                                real_update_on_ground_head_up.push_back(i);
                            else if (on_ground)
                                real_update_on_ground.push_back(i);
                            else if (head_up)
                                real_update_on_head_up.push_back(i);
                            else
                                real_update.push_back(i);
                        }
                        else if (record.body_hit_perfect)
                        {
                            if (on_ground && head_up)
                                body_shot_perfect_update_on_ground_head_up.push_back(i);
                            else if (on_ground)
                                body_shot_perfect_update_on_ground.push_back(i);
                            else if (head_up)
                                real_update_on_head_up.push_back(i);
                            else
                                body_shot_perfect_update.push_back(i);
                        }
                        else if (record.shot_fired)
                        {
                            if (on_ground && head_up)
                                in_attack_update_on_ground_head_up.push_back(i);
                            else if (on_ground)
                                in_attack_update_on_ground.push_back(i);
                            else if (head_up)
                                real_update_on_head_up.push_back(i);
                            else
                                in_attack_update.push_back(i);
                        }
                        else if (record.body_hit)
                        {
                            if (on_ground && head_up)
                                body_shot_update_on_ground_head_up.push_back(i);
                            else if (on_ground)
                                body_shot_update_on_ground.push_back(i);
                            else if (head_up)
                                real_update_on_head_up.push_back(i);
                            else
                                body_shot_update.push_back(i);
                        }
                        else if (record.lby_update_time_1p1)
                        {
                            if (on_ground && head_up)
                                lby_1p1_update_on_ground_head_up.push_back(i);
                            else
                                lby_1p1_update.push_back(i);
                        }
                        else
                        {
                            if (on_ground && head_up)
                                not_breaking_lag_comp_update_on_ground_head_up.push_back(i);
                            else if (on_ground)
                                not_breaking_lag_comp_update_on_ground.push_back(i);
                            else if (head_up)
                                not_breaking_lag_comp_update_on_head_up.push_back(i);
                            else
                                not_breaking_lag_comp_update.push_back(i);
                        }
     
     
                    }
                    std::deque<int> ideal_order;
     
                    //Now apply these into a single deque
                    //There is bound to be a more efficent way to do this
                    ideal_order.insert(ideal_order.end(), lby_update_on_ground_head_up.begin(), lby_update_on_ground_head_up.end());
                    ideal_order.insert(ideal_order.end(), lby_update_on_ground.begin(), lby_update_on_ground.end());
                    ideal_order.insert(ideal_order.end(), lby_update_on_head_up.begin(), lby_update_on_head_up.end());
                    ideal_order.insert(ideal_order.end(), lby_update.begin(), lby_update.end());
                    ideal_order.insert(ideal_order.end(), real_update_on_ground_head_up.begin(), real_update_on_ground_head_up.end());
                    ideal_order.insert(ideal_order.end(), real_update_on_ground.begin(), real_update_on_ground.end());
                    ideal_order.insert(ideal_order.end(), real_update_on_head_up.begin(), real_update_on_head_up.end());
                    ideal_order.insert(ideal_order.end(), real_update.begin(), real_update.end());
                    ideal_order.insert(ideal_order.end(), body_shot_perfect_update_on_ground_head_up.begin(), body_shot_perfect_update_on_ground_head_up.end());
                    ideal_order.insert(ideal_order.end(), body_shot_perfect_update_on_ground.begin(), body_shot_perfect_update_on_ground.end());
                    ideal_order.insert(ideal_order.end(), body_shot_perfect_update_on_head_up.begin(), body_shot_perfect_update_on_head_up.end());
                    ideal_order.insert(ideal_order.end(), body_shot_perfect_update.begin(), body_shot_perfect_update.end());
                    ideal_order.insert(ideal_order.end(), in_attack_update_on_ground_head_up.begin(), in_attack_update_on_ground_head_up.end());
                    ideal_order.insert(ideal_order.end(), in_attack_update_on_ground.begin(), in_attack_update_on_ground.end());
                    ideal_order.insert(ideal_order.end(), in_attack_update_on_head_up.begin(), in_attack_update_on_head_up.end());
                    ideal_order.insert(ideal_order.end(), in_attack_update.begin(), in_attack_update.end());
                    ideal_order.insert(ideal_order.end(), body_shot_update_on_ground_head_up.begin(), body_shot_update_on_ground_head_up.end());
                    ideal_order.insert(ideal_order.end(), body_shot_update_on_ground.begin(), body_shot_update_on_ground.end());
                    ideal_order.insert(ideal_order.end(), body_shot_updatnoe_on_head_up.begin(), body_shot_updatnoe_on_head_up.end());
                    ideal_order.insert(ideal_order.end(), body_shot_update.begin(), body_shot_update.end());
                    ideal_order.insert(ideal_order.end(), lby_1p1_update_on_ground_head_up.begin(), lby_1p1_update_on_ground_head_up.end());
                    ideal_order.insert(ideal_order.end(), lby_1p1_update.begin(), lby_1p1_update.end());
                    ideal_order.insert(ideal_order.end(), not_breaking_lag_comp_update_on_ground_head_up.begin(), not_breaking_lag_comp_update_on_ground_head_up.end());
                    ideal_order.insert(ideal_order.end(), not_breaking_lag_comp_update_on_ground.begin(), not_breaking_lag_comp_update_on_ground.end());
                    ideal_order.insert(ideal_order.end(), not_breaking_lag_comp_update_on_head_up.begin(), not_breaking_lag_comp_update_on_head_up.end());
                    ideal_order.insert(ideal_order.end(), not_breaking_lag_comp_update.begin(), not_breaking_lag_comp_update.end());
     
                    //This deque is used by the aimnot to take the ideal hitbox positions
                    target.ideal_points = ideal_order;
                }
    #else
                bool compare_record_quality(const player_data::PlayerInformation& a, const player_data::PlayerInformation& b)
                {
                    if (a.on_ground && a.pitch_up && b.on_ground && b.pitch_up)
                        return a.sim_time <= b.sim_time;
     
                    if (a.on_ground && b.on_ground)
                        return a.sim_time <= b.sim_time;
     
                    if (a.pitch_up && b.pitch_up)
                        return a.sim_time <= b.sim_time;
     
                    if (a.on_ground && !b.on_ground)
                        return true;
     
                    if (!a.on_ground && b.on_ground)
                        return false;
     
                    if (a.pitch_up && b.pitch_up)
                        return a.sim_time <= b.sim_time;
     
                    if (a.pitch_up && !b.pitch_up)
                        return true;
     
                    if (!a.pitch_up && b.pitch_up)
                        return false;
     
                    return a.sim_time <= b.sim_time;
                }
     
                bool compare_tick_records(const player_data::PlayerInformation& a, const player_data::PlayerInformation& b)
                {
                    if (a.lby_updated && !b.lby_updated)
                        return true;
     
                    if (!a.lby_updated && b.lby_updated)
                        return false;
     
                    if (a.lby_updated && b.lby_updated)
                        return compare_record_quality(a, b);
     
                    // No LBY Updates in either record
     
                    if (a.real_angle && !b.real_angle)
                        return true;
     
                    if (!a.real_angle && b.real_angle)
                        return false;
     
                    if (a.real_angle && b.real_angle)
                        return compare_record_quality(a, b);
     
                    // No real angle updates in either tick
     
                    if (a.body_hit_perfect && !b.body_hit_perfect)
                        return true;
     
                    if (!a.body_hit_perfect && b.body_hit_perfect)
                        return false;
     
                    if (a.body_hit_perfect && b.body_hit_perfect)
                        return compare_record_quality(a, b);
     
                    // No perfect body hit in either tick
     
                    if (a.shot_fired && !b.shot_fired)
                        return true;
     
                    if (!a.shot_fired && b.shot_fired)
                        return false;
     
                    if (a.shot_fired && b.shot_fired)
                        return compare_record_quality(a, b);
     
                    // No shot fired in either tick
     
                    if (a.body_hit && !b.body_hit)
                        return true;
     
                    if (!a.body_hit && !b.body_hit)
                        return false;
     
                    if (a.body_hit && b.body_hit)
                        return compare_record_quality(a, b);
     
                    // No body hit in either tick
     
                    if (a.lby_update_time_1p1 && !b.lby_update_time_1p1)
                        return true;
     
                    if (!a.lby_update_time_1p1 && b.lby_update_time_1p1)
                        return false;
     
                    if (a.lby_update_time_1p1 && b.lby_update_time_1p1)
                    {
                        if (a.on_ground && b.on_ground && a.pitch_up && b.pitch_up)
                        {
                            return a.sim_time <= b.sim_time;
                        }
     
                        if (a.on_ground && a.pitch_up && (!b.pitch_up || !b.on_ground))
                        {
                            return true;
                        }
     
                        if (b.on_ground && b.pitch_up && (!a.pitch_up || !a.on_ground))
                        {
                            return false;
                        }
     
                        return a.sim_time <= b.sim_time;
                    }
     
     
                    // No update time 1p1 in either tick
                    return compare_record_quality(a, b);
                }
     
                bool compare_tick_records_lethal(const player_data::PlayerInformation& a, const player_data::PlayerInformation& b)
                {
                    if (a.lethal_baim && !b.lethal_baim)
                        return true;
     
                    if (!a.lethal_baim && b.lethal_baim)
                        return false;
     
                    if (a.lethal_damage && !b.lethal_damage)
                        return true;
     
                    if (!a.lethal_damage && b.lethal_damage)
                        return false;
     
                    if (a.hit_in_head && !b.hit_in_head)
                        return true;
     
                    if (!a.hit_in_head && b.hit_in_head)
                        return false;
     
                    return compare_tick_records(a, b);
                }
     
                void set_possible_points(const int index)
                {
                    // TODO: this whole thing can be replaced with a std::sort
                    PROFILE_FUNCTION();
                    auto& target = player_data::player_records[index];
     
                    target.ideal_points.clear();
     
                    if (target.breaking_lag_comp)
                    {
                        target.ideal_points.push_back(0);
                        return;
                    }
     
                    std::deque<int> ideal_order(target.information.size());
                    size_t n(0);
                    std::generate(begin(ideal_order), end(ideal_order), [&] { return n++; });
     
                    // Filter invalid times
                    auto new_end = std::remove_if(ideal_order.begin(), ideal_order.end(), [&](int i)
                                              {
                                                  return !is_valid_time(target.information[i].sim_time);
                                              });
     
                    // delete invalid records
                    const auto to_delete = new_end - 1;
                    ideal_order.erase(to_delete);
     
                    // Sort records
                    {
                        PROFILE_CUSTOM(____sort_profiler, "Resolver Sorting");
                        std::sort(ideal_order.begin(), ideal_order.end(), [&](int i1, int i2)
                              {
                                  const auto& a = target.information[i1];
                                  const auto& b = target.information[i2];
                                  return compare_tick_records_lethal(a, b);
                              });
                    }
     
                    //This deque is used by the aimbot to take the ideal hitbox positions
                    target.ideal_points = ideal_order;
                }
    #endif
                bool is_valid_time(const float time)
                {
                    const float target_time = time + lerp_time;
     
                    const float delta_time = correct - (server_time - target_time);
     
                    return (fabsf(delta_time) <= 0.2f);
                }
     
                //--------------------------------------
                // Start logic reoslver, this resolver
                // uses history of angles to attempt to
                // rebuild target's antiaim
                //--------------------------------------
     
                LogicResolver* LogicResolver::get()
                {
                    static LogicResolver* s_logic_resolver = new LogicResolver();
                    return s_logic_resolver;
                }
     
     
                //This should be called once per tick to record the angles for the resolve to access
                void LogicResolver::log_angles(const sdk::QAngle& fake, const sdk::QAngle& real, const bool known_real,
                                               const int index)
                {
                    history = int(CON(resolve_logic_history));
     
                    if (known_real)
                    {
                        auto& target = player_data::player_records[index];
                        if (target.information.size() > 0)
                        {
                            const auto& current_tick = target.information.front();
     
                            //Add real aka lby
                            target.real_yaw.push_back(real.y);
                            while (int(target.real_yaw.size()) > history)
                                target.real_yaw.pop_back();
     
                            target.fake_yaw.push_back(fake.y);
                            while (int(target.fake_yaw.size()) > history)
                                target.fake_yaw.pop_back();
     
                            //Add calc angle from target to local player
                            const sdk::Vector angle_to_local = sdk::math::calc_angle(current_tick.eye_position,
                                                                                     player_data::local_player_information.eye_position);
     
                            target.yaw_to_localplayer.push_front(angle_to_local.y);
     
                            while (int(target.yaw_to_localplayer.size()) > history)
                                target.yaw_to_localplayer.pop_back();
     
     
                            //add target vec velocity here
                            const sdk::Vector velocity = current_tick.velocity;
     
                            target.direction_of_velocity.push_front(sdk::math::velocity_to_yaw(velocity));
     
                            while (int(target.direction_of_velocity.size()) > history)
                                target.direction_of_velocity.pop_back();
     
                            //Add tickcount
                            target.real_ticks_count.push_front(current_user_cmd::cmd->tick_count);
     
                            while (int(target.real_ticks_count.size()) > history)
                                target.real_ticks_count.pop_back();
                        }
                    }
                }
     
                void pitch_resolver(float& pitch)
                {
                    if (pitch < -179.f) pitch += 360.f;
                    else if (pitch > 90.0 || pitch < -90.0) pitch = 89.f;
                    else if (pitch > 89.0 && pitch < 91.0) pitch -= 90.f;
                    else if (pitch > 179.0 && pitch < 181.0) pitch -= 180;
                    else if (pitch > -179.0 && pitch < -181.0) pitch += 180;
                    else if (fabs(pitch) == 0) pitch = copysign(89.0f, pitch);
                }
     
                //This is used to predict an entities angle x ticks into the future
                void LogicResolver::predict_angles(sdk::QAngle& original_angle, int future_ticks, int index)
                {
                    PROFILE_FUNCTION();
                    //TODO: compared currently LBY to previous LBY
     
                    //TODO: predict next fake angle
     
                    //TODO: bool LogicResolver::set_angle(float &angle, int index, int switch_val, float last_real)
                    //Call this function at the start of the predict angles function if we predicted angles last time and we hit the target
                    //If this were the case for the switch_val use the value of the enum that was set last time.
                    //I think maybe if 2 shots at this 'working' value miss, then move on.
     
                    auto& target = player_data::player_records[index];
                    auto& real_yaw_temp = target.real_yaw;
                    const auto& fake_yaw_temp = target.fake_yaw;
                    const auto& yaw_to_localplayer_temp = target.yaw_to_localplayer;
                    const auto& direction_of_velocity_temp = target.direction_of_velocity;
                    const auto& real_ticks_count_temp = target.real_ticks_count;
     
                    if (fake_yaw_temp.size() < 1)
                    {
                        return;
                    }
                    float value_to_return = 0;
                    for (int i = 0; i < future_ticks; i++)
                    {
                        int slots = real_yaw_temp.size();
     
                        float last_lby_update = target.last_lby_update;
                        float current_local_time = 0; //FIXME: get curtime
                        float time_since_lby_update = current_local_time - last_lby_update;
     
                        float last_real = float(real_ticks_count_temp[0]);
     
                        current_fake = original_angle.y;
                        current_angle_to_localplayer = yaw_to_localplayer_temp[0];
                        current_direction_of_velocity = direction_of_velocity_temp[0];
     
                        bool on_ground = true; //FIXME: get if target is on ground
     
                        int shots_missed = 0; //FIXME: get shots missed on target
                        float last_lby = last_real;
                        std::deque<float> test_values;
     
                        std::vector<int> resolve_type;
                        float angle = 0;
     
                        float resolved_angle = last_real;
     
                        //Real vs Fakes
     
                        //FIXME: set up Real vs Fakes, like Real vs Target and the rest of the checks as seen below
     
                        for (int j = 0; j < slots; j++)
                        {
                            test_values.push_back(
                                sdk::math::normalise_yaw(sdk::math::difference_between_yaw(real_yaw_temp[j], fake_yaw_temp[j])));
                        }
     
                        real_vs_fake_static_mean = 0;
     
                        int real_vs_fake_level_jitter = 0;
                        real_vs_fake_jitter_mean = 0;
     
                        int real_vs_fake_level_spin = 0;
                        real_vs_fake_spin_mean = 0;
     
                        if (check_static(test_values, real_vs_fake_static_mean))
                        {
                            set_angle(angle, index, LOGIC_REAL_VS_FAKE_STATIC, last_real);
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                            {
                                resolve_type.push_back(LOGIC_REAL_VS_FAKE_STATIC);
                            }
                        }
                        if (check_jitter(test_values, real_ticks_count_temp, real_vs_fake_jitter_mean, real_vs_fake_level_jitter))
                        {
                            int jitter_level = LOGIC_REAL_VS_FAKE_LEVEL_1_JITTER;
     
                            if (real_vs_fake_level_jitter == 2)
                                jitter_level = LOGIC_REAL_VS_FAKE_LEVEL_2_JITTER;
     
                            set_angle(angle, index, jitter_level, last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                                resolve_type.push_back(jitter_level);
                        }
                        if (check_spin(test_values, real_ticks_count_temp, real_vs_fake_spin_mean, real_vs_fake_level_spin))
                        {
                            int spin_level = LOGIC_REAL_VS_FAKE_LEVEL_1_SPIN;
     
                            if (real_vs_fake_level_spin == 2)
                                spin_level = LOGIC_REAL_VS_FAKE_LEVEL_2_SPIN;
     
                            set_angle(angle, index, spin_level, last_real);
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                            {
                                resolve_type.push_back(spin_level);
                            }
                        }
     
     
                        //Real vs Target
                        for (int j = 0; j < slots; j++)
                        {
                            test_values.push_back(
                                sdk::math::normalise_yaw(sdk::math::difference_between_yaw(real_yaw_temp[j], yaw_to_localplayer_temp[j])));
                        }
     
                        real_vs_target_static_mean = 0;
     
                        int real_vs_target_level_jitter = 0;
                        real_vs_target_jitter_mean = 0;
     
                        int real_vs_target_level_spin = 0;
                        real_vs_target_spin_mean = 0;
     
                        if (check_static(test_values, real_vs_target_static_mean))
                        {
                            set_angle(angle, index, LOGIC_REAL_VS_TARGET_STATIC, last_real);
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                            {
                                resolve_type.push_back(LOGIC_REAL_VS_TARGET_STATIC);
                            }
                        }
     
                        if (check_jitter(test_values, real_ticks_count_temp, real_vs_target_jitter_mean, real_vs_target_level_jitter))
                        {
                            int jitter_level = LOGIC_REAL_VS_TARGET_LEVEL_1_JITTER;
     
                            if (real_vs_target_level_jitter == 2)
                                jitter_level = LOGIC_REAL_VS_TARGET_LEVEL_2_JITTER;
     
                            set_angle(angle, index, jitter_level, last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                                resolve_type.push_back(jitter_level);
                        }
     
                        if (check_spin(test_values, real_ticks_count_temp, real_vs_target_spin_mean, real_vs_target_level_spin))
                        {
                            int spin_level = LOGIC_REAL_VS_TARGET_LEVEL_1_SPIN;
     
                            if (real_vs_target_level_spin == 2)
                                spin_level = LOGIC_REAL_VS_TARGET_LEVEL_2_SPIN;
     
                            set_angle(angle, index, spin_level, last_real);
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                            {
                                resolve_type.push_back(spin_level);
                            }
                        }
     
                        //Real vs Zero
                        for (int j = 0; j < slots; j++)
                        {
                            test_values.push_back(sdk::math::normalise_yaw(sdk::math::difference_between_yaw(real_yaw_temp[j], 0)));
                        }
     
                        real_vs_zero_static_mean = 0;
     
                        int real_vs_zero_level_jitter = 0;
                        real_vs_zero_jitter_mean = 0;
     
                        int real_vs_zero_level_spin = 0;
                        real_vs_zero_spin_mean = 0;
     
                        if (check_static(test_values, real_vs_zero_static_mean))
                        {
                            set_angle(angle, index, int(LOGIC_REAL_VS_ZERO_STATIC), last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                            {
                                resolve_type.push_back(int(LOGIC_REAL_VS_ZERO_STATIC));
                            }
                        }
                        if (check_jitter(test_values, real_ticks_count_temp, real_vs_zero_jitter_mean, real_vs_zero_level_jitter))
                        {
                            int jitter_level = int(LOGIC_REAL_VS_ZERO_LEVEL_1_JITTER);
     
                            if (real_vs_target_level_jitter == 2)
                                jitter_level = int(LOGIC_REAL_VS_ZERO_LEVEL_2_JITTER);
     
                            set_angle(angle, index, int(jitter_level), last_real);
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                            {
                                resolve_type.push_back(jitter_level);
                            }
                        }
                        if (check_spin(test_values, real_ticks_count_temp, real_vs_zero_spin_mean, real_vs_zero_level_spin))
                        {
                            int spin_level = int(LOGIC_REAL_VS_ZERO_LEVEL_1_SPIN);
     
                            if (real_vs_target_level_jitter == 2)
                                spin_level = int(LOGIC_REAL_VS_ZERO_LEVEL_2_SPIN);
     
                            set_angle(angle, index, int(spin_level), last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                                resolve_type.push_back(spin_level);
                        }
     
                        //Real vs perviousReal
                        for (int j = 0; j < slots - 1; j++)
                        {
                            test_values.push_back(
                                sdk::math::normalise_yaw(sdk::math::difference_between_yaw(real_yaw_temp[j], real_yaw_temp[j + 1])));
                        }
     
                        real_vs_previous_real_static_mean = 0;
     
                        int real_vs_previous_real_level_jitter = 0;
                        real_vs_previous_real_jitter_mean = 0;
     
                        int real_vs_previous_real_level_spin = 0;
                        real_vs_previous_real_spin_mean = 0;
     
                        if (check_static(test_values, real_vs_previous_real_static_mean))
                        {
                            set_angle(angle, index, LOGIC_REAL_VS_PERVIOUSREAL_STATIC, last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                            {
                                resolve_type.push_back(LOGIC_REAL_VS_PERVIOUSREAL_STATIC);
                            }
                        }
                        if (check_jitter(test_values, real_ticks_count_temp, real_vs_previous_real_jitter_mean,
                                         real_vs_previous_real_level_jitter))
                        {
                            int jitter_level = LOGIC_REAL_VS_PERVIOUSREAL_LEVEL_1_JITTER;
     
                            if (real_vs_target_level_jitter == 2)
                                jitter_level = LOGIC_REAL_VS_PERVIOUSREAL_LEVEL_2_JITTER;
     
                            set_angle(angle, index, jitter_level, last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                                resolve_type.push_back(jitter_level);
                        }
                        if (check_spin(test_values, real_ticks_count_temp, real_vs_previous_real_spin_mean,
                                       real_vs_previous_real_level_spin))
                        {
                            int spin_level = LOGIC_REAL_VS_PERVIOUSREAL_LEVEL_1_SPIN;
     
                            if (real_vs_target_level_jitter == 2)
                                spin_level = LOGIC_REAL_VS_PERVIOUSREAL_LEVEL_2_SPIN;
     
                            set_angle(angle, index, spin_level, last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                                resolve_type.push_back(spin_level);
                        }
     
     
                        //Real vs Velocity
     
                        for (int j = 0; j < slots; j++)
                        {
                            test_values.push_back(
                                sdk::math::normalise_yaw(sdk::math::difference_between_yaw(real_yaw_temp[j], direction_of_velocity_temp[j])));
                        }
     
     
                        real_vs_velocity_static_mean = 0;
     
                        int real_vs_velocity_level_jitter = 0;
                        real_vs_velocity_jitter_mean = 0;
     
                        int real_vs_velocity_level_spin = 0;
                        real_vs_velocity_spin_mean = 0;
     
                        if (check_static(test_values, real_vs_velocity_static_mean))
                        {
                            set_angle(angle, index, LOGIC_REAL_VS_VELOCITY_STATIC, last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                            {
                                resolve_type.push_back(LOGIC_REAL_VS_VELOCITY_STATIC);
                            }
                        }
     
                        if (check_jitter(test_values, real_ticks_count_temp, real_vs_velocity_jitter_mean, real_vs_velocity_level_jitter))
                        {
                            int jitter_level = LOGIC_REAL_VS_VELOCITY_LEVEL_1_JITTER;
     
                            if (real_vs_target_level_jitter == 2)
                                jitter_level = LOGIC_REAL_VS_VELOCITY_LEVEL_2_JITTER;
     
                            set_angle(angle, index, jitter_level, last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                                resolve_type.push_back(jitter_level);
                        }
     
                        if (check_spin(test_values, real_ticks_count_temp, real_vs_velocity_spin_mean, real_vs_velocity_level_spin))
                        {
                            int spin_level = int(LOGIC_REAL_VS_VELOCITY_LEVEL_1_SPIN);
     
                            if (real_vs_target_level_jitter == 2)
                                spin_level = int(LOGIC_REAL_VS_VELOCITY_LEVEL_2_SPIN);
     
                            set_angle(angle, index, int(spin_level), last_real);
     
                            if (is_valid_angle(angle, on_ground, time_since_lby_update, last_lby))
                                resolve_type.push_back(spin_level);
                        }
     
                        //Angles have been predicted
                        //Let us brute force and set what we want most :)
     
                        //Lets check if any of our algorthyms worked
     
                        //TODO: Check if we  used logic reoslver last and we hit, then we want to
                        //call set_angle using same resolver type
     
                        //FIXME: this can be done much better for logging hits, misses
                        //to use if did hit logic to get best angle. Please can someone
                        //Help me do this. Not sure best way. This will work well enough
                        //I guess
                        if (resolve_type.size() > 0)
                        {
                            int resolve_option = shots_missed % resolve_type.size();
                            set_angle(resolved_angle, index, resolve_type[resolve_option], last_real);
                            target.last_logic_resolve_type = resolve_type[resolve_option];
                        }
                        else if (on_ground && time_since_lby_update > 1.1f)
                        {
                            int resolve_type = LOGIC_LBY + shots_missed % 5;
                            target.last_logic_resolve_type = resolve_type;
                            set_angle(resolved_angle, index, resolve_type, last_lby);
                        }
                        else
                        {
                            //Didn't find any algorthym, have no real idea, so
                            //Lets brute force the shit out of this
                            sdk::QAngle angle = sdk::QAngle(0, resolved_angle, 0);
                            BruteForceResolver::get()->brute_force_resolver(angle, i);
                            resolved_angle = angle.y;
                        }
     
                        value_to_return = resolved_angle;
     
                        //In theory should do the same as above to fake, velocity angles
                        //etc. etc. but I can't see that being cpu efficent
                        //Maybe just compare fake to velocity and just do that one
                        //Who knows, thoughts? feel free to do it :)
     
                        real_yaw_temp.push_front(value_to_return);
                        real_yaw_temp.pop_back(); //To make sure deque stays same size, to avoid crashes
                    }
     
                    original_angle.y = value_to_return;
                }
     
                bool LogicResolver::is_valid_angle(float angle, bool on_ground, float time_since_lby_update, float last_lby)
                {
                    if (on_ground && time_since_lby_update > 1.1f && sdk::math::difference_between_yaw(angle, last_lby) < 35)
                        return true;
     
                    if (!on_ground || time_since_lby_update < 1.1f)
                        return true;
     
                    return false;
                }
     
                //SOMEONE PLEASE CHECK THESE ALGORTHYMS
     
                float LogicResolver::set_static(float mean, float grounding_value)
                {
                    /*
                    Example of a static pattern, comparing real to fake
                    Real: 90, 100, 110, 120, 140
                    Fake:  0,  10,  20,  30,  40
     
                    The static value is +90 from the grounding value, which is fake
     
                    However, this pattern can also be considered a spin with the real being grounded to any static value
     
                    This is what this fix is attempting to replicate and fix
                    */
                    return grounding_value + mean;
                }
     
                float LogicResolver::set_jitter(float mean, float grounding_value, float last_value, float last_jitter_delta,
                                                int ticks)
                {
                    /*
                    Example of a level 1 jitter pattern, comparing real to 0
                    10, -10, 10, -10
     
                    The jitter to the set above is:
                    20
     
                    Example of a level 1 jitter pattern, comparing real to fake
                    Real: -10, 20, 10,  40,  30
                    Fake:   0, 10, 20,  30,  40
     
                    This is what this fix is attempting to replicate and fix
                    */
                    bool even = !(ticks % 2);
     
                    bool should_be_addition = last_jitter_delta < 0;
     
                    if (even)
                        should_be_addition = !should_be_addition;
     
                    if (should_be_addition)
                        return grounding_value + mean;
                    return grounding_value - mean;
                }
     
     
                //FIXME: not doing this correctly
                float LogicResolver::set_jitter_lv2(float mean, float grounding_value, float last_value, float last_jitter_delta,
                                                    int ticks)
                {
                    /*
                    Example of a level 2 jitter pattern, comparing real to 0
                    0, -10, 10, -20, 20
     
                    The set of increments each time as seen below
                    0, -10, 20, -30, 40
     
                    The increment to the absolute value set above is:
                    10
     
                    Example of a level 1 jitter pattern, comparing real to fake
                    Real: -10, 30, -10,  70, -10, 110
                    Fake:   0, 10,  20,  30,  40,  50
     
                    The set of increments each time as seen below
                    -10, 20, -30, 40, -50, 60
     
                    The increment to the absolute value set above is:
                    10
     
                    This is what this fix is attempting to replicate and fix
                    */
                    //bool should_be_addition = last_jitter_delta < 0;
     
                    //for (int i = 0; i < ticks; i++)
                    //{
                    //    should_be_addition = !should_be_addition;
                    //    if (should_be_addition)
                    //    {
     
                    //    }
                    //}
     
                    bool even = !(ticks % 2);
     
                    bool should_be_addition = last_jitter_delta < 0;
     
                    if (even)
                        should_be_addition = !should_be_addition;
     
                    if (should_be_addition)
                        return grounding_value + mean;
     
                    return grounding_value - mean;
                }
     
                float LogicResolver::set_spin(float mean, float grounding_value, float last_spin_amount, int ticks)
                {
                    /*
                    Example of a level 1 spin pattern, comparing real to 0
                    0, 10, 20, 30, 40
     
                    The increment to the set above is:
                    10
     
                    This is what this fix is attempting to replicate and fix
                    */
                    return grounding_value + last_spin_amount + mean * ticks;
                }
     
                float LogicResolver::set_spin_lv2(float mean, float grounding_value, float last_spin_amount,
                                                  float last_lv2_spin_amount, int ticks)
                {
                    /*
                    Example of a level 2 spin pattern, comparing real to 0
                    0, 10, 30, 60, 100
     
                    The set of increments each time as seen below
                    0, 10, 20, 30, 40
     
                    The increment to the set above is:
                    10
     
                    Example of a level 2 spin pattern, comparing real to fake
                    Real: 0, 30, 20, 50, 40
                    Fake: 0, 20,  0, 20,  0
     
                    The set of increments each time as seen below
                    0, 10, 20, 30, 40
     
                    The increment to the set above is:
                    10
     
                    This is what this fix is attempting to replicate and fix
                    */
                    for (int i = 0; i < ticks; i++)
                    {
                        last_spin_amount += last_spin_amount + (last_lv2_spin_amount + mean);
                        last_lv2_spin_amount += mean;
                    }
                    return grounding_value + last_spin_amount;
                }
     
                //FIXME: get the required values for the angle setting and add the appropriate information below
                //Phase the correct information into the set functions
                //grounding_value is the value the real is being compared against, for example, fake, last real, zero etc.
                //ticks = ticks between last real update and current tick
                //rest are pretty self explanitory please someone who isn't jake finish this for him.
                bool LogicResolver::set_angle(float& angle, int index, int switch_val, float last_real)
                {
                    switch (switch_val)
                    {
                    case LOGIC_LBY: //Assuming last_real is current lby from the netvar
                        angle = last_real;
                        break;
                    case LOGIC_LBY_P_35:
                        angle = last_real + 35;
                        break;
                    case LOGIC_LBY_M_35:
                        angle = last_real - 35;
                        break;
                    case LOGIC_LBY_P_20:
                        angle = last_real + 20;
                        break;
                    case LOGIC_LBY_M_20:
                        angle = last_real - 20;
                        break;
                    case LOGIC_REAL_VS_FAKE_STATIC:
                        angle = set_static(real_vs_fake_static_mean, current_fake);
                        break;
                    case LOGIC_REAL_VS_FAKE_LEVEL_1_JITTER:
                        angle = set_jitter(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_FAKE_LEVEL_2_JITTER:
                        angle = set_jitter_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_FAKE_LEVEL_1_SPIN:
                        angle = set_spin(real_vs_fake_jitter_mean, current_fake, 0, 0);
                        break;
                    case LOGIC_REAL_VS_FAKE_LEVEL_2_SPIN:
                        angle = set_spin_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
     
                    case LOGIC_REAL_VS_TARGET_STATIC:
                        angle = set_static(real_vs_target_static_mean, current_angle_to_localplayer);
                        break;
                    case LOGIC_REAL_VS_TARGET_LEVEL_1_JITTER:
                        angle = set_jitter(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_TARGET_LEVEL_2_JITTER:
                        angle = set_jitter_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_TARGET_LEVEL_1_SPIN:
                        angle = set_spin(real_vs_fake_jitter_mean, current_fake, 0, 0);
                        break;
                    case LOGIC_REAL_VS_TARGET_LEVEL_2_SPIN:
                        angle = set_spin_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
     
                    case LOGIC_REAL_VS_ZERO_STATIC:
                        angle = set_static(real_vs_target_static_mean, 0);
                        break;
                    case LOGIC_REAL_VS_ZERO_LEVEL_1_JITTER:
                        angle = set_jitter(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_ZERO_LEVEL_2_JITTER:
                        angle = set_jitter_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_ZERO_LEVEL_1_SPIN:
                        angle = set_spin(real_vs_fake_jitter_mean, current_fake, 0, 0);
                        break;
                    case LOGIC_REAL_VS_ZERO_LEVEL_2_SPIN:
                        angle = set_spin_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
     
                    case LOGIC_REAL_VS_PERVIOUSREAL_STATIC:
                        angle = set_static(real_vs_target_static_mean, last_real);
                        break;
                    case LOGIC_REAL_VS_PERVIOUSREAL_LEVEL_1_JITTER:
                        angle = set_jitter(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_PERVIOUSREAL_LEVEL_2_JITTER:
                        angle = set_jitter_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_PERVIOUSREAL_LEVEL_1_SPIN:
                        angle = set_spin(real_vs_fake_jitter_mean, current_fake, 0, 0);
                        break;
                    case LOGIC_REAL_VS_PERVIOUSREAL_LEVEL_2_SPIN:
                        angle = set_spin_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
     
                    case LOGIC_REAL_VS_VELOCITY_STATIC:
                        angle = set_static(real_vs_target_static_mean, current_direction_of_velocity);
                        break;
                    case LOGIC_REAL_VS_VELOCITY_LEVEL_1_JITTER:
                        angle = set_jitter(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_VELOCITY_LEVEL_2_JITTER:
                        angle = set_jitter_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    case LOGIC_REAL_VS_VELOCITY_LEVEL_1_SPIN:
                        angle = set_spin(real_vs_fake_jitter_mean, current_fake, 0, 0);
                        break;
                    case LOGIC_REAL_VS_VELOCITY_LEVEL_2_SPIN:
                        angle = set_spin_lv2(real_vs_fake_jitter_mean, current_fake, 0, 0, 0);
                        break;
                    }
                    return true;
                }
     
     
                //This function takes a deque of angles finds the standard deviation of these anlges
                //If this SD is smaller then the accuracy
                bool LogicResolver::check_static(const std::deque<float>& angle, float& meanvalue)
                {
                    meanvalue = sdk::math::mean(angle.begin(), angle.end());
     
                    if (sdk::math::standard_deviation(angle.begin(), angle.end(), meanvalue) <= accuracy)
                    {
                        return true;
                    }
     
                    return false;
                }
     
                //This function finds the abs difference between angles for first degree and second
                //degree polynomials, using the SD to check for accuracy.
                //Spin does the same just not the ABS check.
                bool LogicResolver::check_jitter(const std::deque<float>& angle, const std::deque<int>& ticks, float& meanvalue,
                                                 int& level)
                {
                    std::deque<float> difference_lv1;
     
                    int slots = angle.size();
     
                    std::deque<float> difference_lv2;
     
                    std::deque<int> ticks_lv2;
     
                    for (int i = 0; i < slots - 1; i++)
                    {
                        ticks_lv2.push_back(abs(ticks[i + 1] - ticks[i]));
                        if (ticks_lv2[i] == 0)
                            ticks_lv2[i] = 1;
     
                        difference_lv1.push_back(
                            sdk::math::normalise_yaw(abs(sdk::math::difference_between_yaw(angle[i], angle[i + 1]) / ticks_lv2[i])));
                    }
     
                    meanvalue = sdk::math::mean(difference_lv1.begin(), difference_lv1.begin() + (slots - 1));
                    difference_lv1.at(slots - 1);
                    if (sdk::math::standard_deviation(difference_lv1.begin(), difference_lv1.begin() + (slots - 1), meanvalue) <= accuracy)
                    {
                        level = 1;
                        return true;
                    }
     
     
                    for (int i = 0; i < slots - 2; i++)
                    {
                        int tick_diff = abs(ticks_lv2[i + 1] - ticks_lv2[i]);
                        if (tick_diff == 0)
                            tick_diff = 1;
     
                        difference_lv2.push_back(sdk::math::normalise_yaw(
                            abs(sdk::math::difference_between_yaw(difference_lv1[i], difference_lv1[i + 1]) / tick_diff)));
                    }
     
                    meanvalue = sdk::math::mean(difference_lv2.begin(), difference_lv2.begin() + (slots - 2));
     
                    if (sdk::math::standard_deviation(difference_lv2.begin(), difference_lv2.begin() + (slots - 2), meanvalue) <= accuracy)
                    {
                        level = 2;
                        return true;
                    }
     
                    return false;
                }
     
                bool LogicResolver::check_spin(const std::deque<float>& angle, const std::deque<int>& ticks, float& meanvalue,
                                               int& level)
                {
                    std::deque<float> difference_lv1;
     
                    int slots = angle.size();
     
                    std::deque<int> ticks_lv2;
                    std::deque<float> difference_lv2;
     
                    for (int i = 0; i < slots - 1; i++)
                    {
                        ticks_lv2.push_back(abs(ticks[i + 1] - ticks[i]));
                        if (ticks_lv2[i] == 0)
                            ticks_lv2[i] = 1;
     
                        difference_lv1.push_back(
                            sdk::math::normalise_yaw(sdk::math::difference_between_yaw(angle[i], angle[i + 1]) / ticks_lv2[i]));
                    }
     
                    meanvalue = sdk::math::mean(difference_lv1.begin(), difference_lv1.begin() + (slots - 1));
     
                    if (sdk::math::standard_deviation(difference_lv1.begin(), difference_lv1.begin() + (slots - 1), meanvalue) <= accuracy)
                    {
                        level = 1;
                        return true;
                    }
     
     
                    for (int i = 0; i < slots - 2; i++)
                    {
                        int tick_diff = abs(ticks_lv2[i + 1] - ticks_lv2[i]);
                        if (tick_diff == 0)
                            tick_diff = 1;
     
                        difference_lv2.push_back(
                            sdk::math::normalise_yaw(
                                sdk::math::difference_between_yaw(difference_lv1[i], difference_lv1[i + 1]) / tick_diff));
                    }
     
                    meanvalue = sdk::math::mean(difference_lv2.begin(), difference_lv2.begin() + (slots - 2));
     
                    if (sdk::math::standard_deviation(difference_lv2.begin(), difference_lv2.begin() + (slots - 2), meanvalue) <= accuracy)
                    {
                        level = 2;
                        return true;
                    }
     
                    return false;
                }
     
                BruteForceResolver* BruteForceResolver::get()
                {
                    static BruteForceResolver* s_brute_force_resolver = new BruteForceResolver();
                    return s_brute_force_resolver;
                }
     
                void BruteForceResolver::brute_force_resolver(sdk::QAngle& original_angles, int index)
                {
                    PROFILE_FUNCTION();
                    auto& target = player_data::player_records[index];
     
                    float curtime = 0; //FIXME: get curtime
     
                    //Check history
                    if (target.brute_force_sticky_point > 0 && set_angle(original_angles, index, target.last_brute_force_resolver_type))
                    {
                        return;
                    }
     
                    //Check lby update confitions
                    if (target.on_ground && curtime - target.last_lby_update > 1.1f)
                        lby_brute_force(original_angles, index);
     
                    int number_of_brute_force_options = LAST_BRUTE_FORCE_TYPE - BRUTE_NONE - 2;
     
                    int shots_missed = 0; //FIXME: go to shots missed.
     
                    int switch_value = LAST_BRUTE_FORCE_TYPE - 1 - shots_missed % number_of_brute_force_options;
     
                    if (!set_angle(original_angles, index, switch_value))
                    {
                        //Something has really fucked up here, as it shouldn't get to this point if it returning false
                        original_angles.y = target.lby;
                        target.last_brute_force_resolver_type = BRUTE_LBY;
                    }
                }
     
                void BruteForceResolver::lby_brute_force(sdk::QAngle& original_angles, int index)
                {
                    auto& target = player_data::player_records[index];
     
                    int shots_missed = 0; //FIXME: go to shots missed.
     
                    int switch_value = shots_missed % 5 + BRUTE_LBY;
     
                    set_angle(original_angles, index, switch_value);
                }
     
                bool BruteForceResolver::set_angle(sdk::QAngle& original_angles, int index, int switch_val)
                {
                    auto& target = player_data::player_records[index];
     
                    switch (switch_val)
                    {
                    case BRUTE_LBY:
                        original_angles.y = target.lby;
                        break;
                    case BRUTE_LBY_P_35:
                        original_angles.y = target.lby + 35;
                        break;
                    case BRUTE_LBY_M_35:
                        original_angles.y = target.lby - 35;
                        break;
                    case BRUTE_LBY_P_17:
                        original_angles.y = target.lby + 17;
                        break;
                    case BRUTE_LBY_M_17:
                        original_angles.y = target.lby - 17;
                        break;
                    case BRUTE_DIRECTION_TO_TARGET_M_135:
                        original_angles.y = target.yaw_to_localplayer[0] - 135;
                        break;
                    case BRUTE_DIRECTION_TO_TARGET_M_45:
                        original_angles.y = target.yaw_to_localplayer[0] - 45;
                        break;
                    case BRUTE_DIRECTION_TO_TARGET_P_45:
                        original_angles.y = target.yaw_to_localplayer[0] + 45;
                        break;
                    case BRUTE_DIRECTION_TO_TARGET_P_135:
                        original_angles.y = target.yaw_to_localplayer[0] + 135;
                        break;
                    case BRUTE_LBY_M_90:
                        original_angles.y = target.lby - 90;
                        break;
                    case BRUTE_LBY_P_90:
                        original_angles.y = target.lby + 90;
                        break;
                    case BRUTE_LBY_P_180:
                        original_angles.y = target.lby + 180;
                        break;
                    case BRUTE_FAKE_M_135:
                        original_angles.y -= 135;
                        break;
                    case BRUTE_FAKE_M_45:
                        original_angles.y -= 45;
                        break;
                    case BRUTE_FAKE_P_45:
                        original_angles.y += 45;
                        break;
                    case BRUTE_FAKE_P_135:
                        original_angles.y += 135;
                        break;
                    case BRUTE_DIRECTION_TO_TARGET:
                        original_angles.y = target.yaw_to_localplayer[0];
                        break;
                    case BRUTE_DIRECTION_TO_TARGET_M_90:
                        original_angles.y = target.yaw_to_localplayer[0] - 90;
                        break;
                    case BRUTE_DIRECTION_TO_TARGET_P_90:
                        original_angles.y = target.yaw_to_localplayer[0] + 90;
                        break;
                    case BRUTE_DIRECTION_TO_TARGET_P_180:
                        original_angles.y = target.yaw_to_localplayer[0] + 180;
                        break;
                    case BRUTE_LBY_M_135:
                        original_angles.y = target.lby - 135;
                        break;
                    case BRUTE_LBY_M_45:
                        original_angles.y = target.lby - 45;
                        break;
                    case BRUTE_LBY_P_45:
                        original_angles.y = target.lby + 45;
                        break;
                    case BRUTE_LBY_P_135:
                        original_angles.y = target.lby + 135;
                        break;
                    case BRUTE_FAKE:
                        break;
                    case BRUTE_FAKE_M_90:
                        original_angles.y -= 90;
                        break;
                    case BRUTE_FAKE_P_90:
                        original_angles.y += 90;
                        break;
                    case BRUTE_FAKE_P_180:
                        original_angles.y += 180;
                        break;
                    }
     
                    float curtime = 0;//FIXME
                    if (!resolver_sanity_check(original_angles.y, target.last_lby_update, curtime, target.on_ground, target.lby))
                        return false;
     
                    target.last_brute_force_resolver_type = switch_val;
     
                    return true;
                }
     
                void BruteForceResolver::perfect_resolver(sdk::QAngle& original_angles)
                {
                    original_angles.y = sdk::math::normalise_yaw(std::uniform_real_distribution<float>(-180, 180)(g_random_engine));
                    original_angles.x = sdk::math::normalise_pitch(std::uniform_real_distribution<float>(-89, 89)(g_random_engine));
                }
     
                using namespace sdk;
     
     
                //Fake lag fix, lets simulate movement for 1 tick and make sure they don't go through walls
                FakeLagFix* FakeLagFix::get()
                {
                    static FakeLagFix* s_fake_lag_fix = new FakeLagFix();
                    return s_fake_lag_fix;
                }
     
                void FakeLagFix::SimulateMovement(CSimulationData& data, bool in_air)
                {
                    float gravity = 9.8f; //FIXME: get gravity
     
                    float interval_per_tick = interfaces::globals->interval_per_tick;
                    if (!(data.flags & FL_ONGROUND))
                        data.velocity.z -= interval_per_tick * gravity;
                    else if (in_air)
                        data.velocity.z = sqrt(91200.f);
     
                    auto mins = data.current_tick.vec_min;
                    auto maxs = data.current_tick.vec_max;
     
                    auto src = data.network_origin;
                    auto end = src + data.velocity * interval_per_tick;
     
                    Ray_t ray;
                    ray.Init(src, end, mins, maxs);
     
                    trace_t trace;
                    CTraceFilter filter;
                    filter.m_icollisionGroup = COLLISION_GROUP_NONE;
                    filter.pSkip = static_cast<IHandleEntity*>(data.entity);
                    interfaces::engine_trace->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);
     
                            float 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 * (interval_per_tick * (1.f - trace.fraction));
                            ray.Init(trace.endpos, end, mins, maxs);
                            interfaces::engine_trace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
     
                            if (trace.fraction == 1.f)
                                break;
                        }
                    }
     
                    data.network_origin = trace.endpos;
                    end = trace.endpos;
                    end.z -= 2.f;
     
                    ray.Init(data.network_origin, end, mins, maxs);
                    interfaces::engine_trace->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;
                }
     
                void FakeLagFix::extrapolation(int ticksChoked, int index)
                {
                    auto target = player_data::player_records[index];
                    auto current_tick = target.information.front();
                    auto previous_tick = target.information.at(1);
     
                    float interval_per_tick = interfaces::globals->interval_per_tick;
     
                    Vector velocity = current_tick.velocity;
                    Vector current_position = current_tick.network_origin;
     
                    INetChannelInfo* nci = interfaces::engine->GetNetChannelInfo();
     
                    CSimulationData data;
                    data.network_origin = current_position;
                    data.velocity = velocity;
                    data.flags = current_tick.flags;
     
                    //Not sure if this should be avg or current shouldn't relaly matter
                    float latency = nci->GetAvgLatency(int(INetChannelInfo::FlowDirection::FLOW_INCOMING))
                        + nci->GetAvgLatency(int(INetChannelInfo::FlowDirection::FLOW_OUTGOING));
     
                    float time_until_next_frame = 0;//Use this for FPS issues, iircn
     
                    //FIXME: need to take into account psilent/fakelag packets. For now, just assume we choked ticksChoked is the amount of ticks the firing packet will be held back
                    float time_when_packet_reaches_server = TICKS_TO_TIME(
                        current_user_cmd::cmd->tick_count + TIME_TO_TICKS(latency + time_until_next_frame) + 1 + ticksChoked);
     
                    //Time we reach the server - time the player was simulated on the server , clamped to sv_maxunlag (1.0 seconds)
                    float delta_time = fminf(time_when_packet_reaches_server - current_tick.sim_time, 1.0f);
     
                    int delta_ticks = TIME_TO_TICKS(delta_time);
     
                    //How many choked ticks to simulate.
                    int ticks = current_tick.ticks_since_previous_update;
     
                    //Since I am not happy about just using last ticks for tick prediction I'm going to write up a polynomial pattern gusseer
                    int current_choked_ticks = target.ticks_since_last_sim_time_update;
                    if (current_choked_ticks > 15)
                        current_choked_ticks = 15;
     
                    ticks = predict_ticks_choked(index, current_choked_ticks);
     
                    if (ticks > 20) //Something has clearly gone wrong with prediction so lets just completlely abort and go to last set
                        ticks = current_tick.ticks_since_previous_update;
     
                    int choked_ticks = std::clamp(ticks, 1, 15);
     
                    int target_ticks = delta_ticks - choked_ticks;
     
                    auto acceleartion = (current_tick.velocity - previous_tick.velocity) / float(
                        TIME_TO_TICKS(current_tick.sim_time - previous_tick.sim_time)) / interval_per_tick;
     
                    int predicted = 0;
                    while (target_ticks >= 0)
                    {
                        for (int i = 0; i < choked_ticks; i++)
                        {
                            predicted++;
                            bool in_air = false;// !(current_tick.flags & FL_ONGROUND);
                            SimulateMovement(data, in_air);
     
                            data.velocity.x += acceleartion.x * interval_per_tick;
                            data.velocity.y += acceleartion.y * interval_per_tick;
                        }
                        target_ticks -= choked_ticks;
                    }
     
     
                    //FIXME:
                    //TODO:
                    //Update entities origin and flags from data
                }
     
                //Call this every single tick that the player's information updates (ie they send a tick again).
                //Then compare it to the number of ticks they did choke
                //If they are the same assume they are using this adaptive
                //This fake lag is a common method to break lag comp with sending least number of ticks
                //This is a reverse for [censored]'s adaptive should be similar to all other cheats also
                int FakeLagFix::using_adapive(int index)
                {
                    auto& target = player_data::player_records[index];
                    auto current_tick = target.information.front();
     
                    float velocity_y = current_tick.velocity.y;
                    float velocity_x = current_tick.velocity.x;
     
                    int wish_ticks_1 = 0;
                    int adapt_ticks = 2;
     
                    double extrapolated_speed = sqrt(velocity_x * velocity_x + velocity_y * velocity_y)
                        * interfaces::globals->interval_per_tick;
     
                    while (wish_ticks_1 * extrapolated_speed <= 68.0)
                    {
                        if ((adapt_ticks - 1) * extrapolated_speed > 68.0)
                        {
                            ++wish_ticks_1;
                            break;
                        }
                        if (adapt_ticks * extrapolated_speed > 68.0)
                        {
                            wish_ticks_1 += 2;
                            break;
                        }
                        if ((adapt_ticks + 1) * extrapolated_speed > 68.0)
                        {
                            wish_ticks_1 += 3;
                            break;
                        }
                        if ((adapt_ticks + 2) * extrapolated_speed > 68.0)
                        {
                            wish_ticks_1 += 4;
                            break;
                        }
                        adapt_ticks += 5;
                        wish_ticks_1 += 5;
                        if (adapt_ticks > 16)
                            break;
                    }
     
                    if (wish_ticks_1 > 16)
                        wish_ticks_1 = 15;
     
                    return wish_ticks_1;
                }
     
                int FakeLagFix::predict_ticks_choked(int index, int current_ticks_chocked)
                {
                    //Assuming polnomial expansions, lets just keep differentialting the equation until we get something which works ;)
                    //But they probably aren't using a polynomial, it is probably based on lag comp so velocity or step or static or random
                    //Who knows but I'm going to enjoy writting this so fuck you
     
                    auto& target = player_data::player_records[index];
                    const auto& choke_history = target.history_ticks_chocked_amounts;
                    auto current_tick = target.information.front();
     
                    if (choke_history.size() < 1)
                        return current_ticks_chocked;
     
                    if (choke_history.size() < 4)
                        return choke_history.front();
     
                    const float average = float(round(math::mean(choke_history.begin(), choke_history.end())));
                    const float standard_deviation = math::standard_deviation(choke_history.begin(), choke_history.end(), average);
     
                    if (standard_deviation <= 2 && current_ticks_chocked <= average)
                        return (int)average; // Probably average if SD is so low
     
                    if (target.using_adaptive_fakelag)
                        return using_adapive(index);
     
     
                    //See if its a linear step
                    int total_step = 0;
     
                    //2nd degree step
                    std::deque<int> difference2;
                    int total_step2 = 0;
     
                    //3rd degree step
                    std::deque<int> difference3;
                    int total_step3 = 0;
     
                    //4th order polynomial
                    std::deque<int> difference4;
     
     
                    for (size_t i = 0; i < choke_history.size() - 1; i++)
                    {
                        difference2.push_back(choke_history[i + 1] - choke_history[i]);
                        total_step += difference2[i];
                    }
     
                    const float average_step = (float)(total_step / choke_history.size() - 1);
     
                    const float standard_deviation_step = math::standard_deviation(difference2.begin(), difference2.end(), average_step);
     
                    if (standard_deviation_step <= 1 && current_ticks_chocked <= average_step)
                        return (int)average_step; // Probably average if SD is so l
     
     
                    for (size_t i = 0; i < difference2.size() - 1; i++)
                    {
                        difference3.push_back(difference2[i + 1] - difference2[i]);
                        total_step2 += difference3[i];
                    }
                    const float average_step2 = (float)(total_step2 / difference2.size() - 1);
     
                    const float standard_deviation_step2 = math::standard_deviation(difference3.begin(), difference3.end(), average_step2);
     
                    if (standard_deviation_step2 <= 1 && current_ticks_chocked <= average_step2)
                        return (int)average_step2; // Probably average if SD is so l
     
     
                    for (size_t i = 0; i < difference3.size() - 1; i++)
                    {
                        difference4.push_back(difference3[i + 1] - difference3[i]);
                        total_step3 += difference3[i];
                    }
                    const float average_step3 = (float)(total_step3 / 17);
     
                    const float standard_deviation_step3 = math::standard_deviation(difference4.begin(), difference4.end(), average_step3);
     
                    if (standard_deviation_step3 <= 1 && current_ticks_chocked <= average_step3)
                        return (int)average_step3; // Probably average if SD is so l
     
                    //We have now checked if they are following a polynomial up to degree 4
                    //See here for complete complex algorthym http://www.johansens.us/sane/education/formula.htm
                    int lastamount = choke_history.front();
                    if (current_ticks_chocked <= lastamount)
                        return lastamount;
     
                    return current_ticks_chocked;
                }
     
                EffectsResolver* EffectsResolver::get()
                {
                    static EffectsResolver* s_effect_resolver = new EffectsResolver();
                    return s_effect_resolver;
                }
     
     
                //DO NOT TELL PEOPLE WE ARE USING THIS FOR A RESOLVER FOR FUCKS SAKE
     
                //TODO: check my logic I may be doing it wrong.
     
                //We are now getting hitbox, but we need to get actaul time they were hit since this is delayed
                //Apply ping calculations too
                //From mutiny credit to sharklazer + myself
                void EffectsResolver::begin_blood(C_TEEffectDispatch* thisptr, DataUpdateType_t updateType, render::IDrawer* draw)
                {
                    if (!CON(resolver_enabled))
                        return;
                    if (thisptr->m_EffectData.m_hEntity <= 0)
                        return;
     
                    const auto client_entity = interfaces::entity_list->GetClientEntityFromHandle(thisptr->m_EffectData.m_hEntity);
     
                    auto entity = static_cast<CCSPlayer*>(client_entity);
     
                    const int player_index = entity->GetIndex();
     
                    if (!(entity && entity->IsPlayer() && (CBasePlayer*)entity != player_data::local_player_information.entity))
                        return;
     
                    if (player_index > 128)
                        return;
     
                    auto target = player_data::player_records[player_index];
     
                    //prevent access viloation
                    if (target.information.size() <= 0)
                        return;
     
                    auto& current_tick = target.information.front();
     
                    const float simulation_time = current_tick.sim_time;
     
                    //Since effects are delayed we need to find out how to get actual time for backtracking puroses
     
                    const float time_player_was_shot = target.simtime_last_get_body_spot;
     
     
                    //Santity check to make sure it is dealing with possible values
                    if (simulation_time - time_player_was_shot > 0.5f)
                        return;
     
                    //Okay so we have established we want to resolve for blood spawning on this target.
     
                    //Vector startorigin = pEntity->GetOrigin() + thisptr->m_EffectData.m_vStart;
                    //Vector blood_origin = thisptr->m_EffectData.m_vOrigin;
                    //TODO: Check if thi is correct
                    const Vector blood_origin = entity->GetOrigin() + thisptr->m_EffectData.m_vOrigin;
                    const Vector blood_direction = thisptr->m_EffectData.m_vNormal;
     
                    const int hit_group_player_was_shot = thisptr->m_EffectData.m_nHitBox;
     
                    //TODO: add some distance calculations in here too
     
                    //Get start point of trace
                    const Vector trace_start = blood_origin + (blood_direction * 64.0f);
                    const Vector trace_ignore = blood_origin + (blood_direction * 1.0f);
                    //don't count as valid if trace still hits slightly outside of the origin to get a more accurate angle
     
                    player_data::PlayerInformation history_when_hit;
     
                    bool found = false;
     
                    for (auto& info : target.information)
                    {
                        if (info.sim_time != time_player_was_shot)
                            continue;
                        found = true;
                        history_when_hit = info;
                        break;
                    }
     
                    if (!found)
                        return;
     
                    entity->SetAbsOrigin(history_when_hit.network_origin);
     
                    float first_yaw_found = 0;
                    float first_body_yaw_found = 0;
                    bool found_general_head = false;
                    bool found_real_head = false;
     
                    matrix3x4_t bonematrix[MAXSTUDIOBONES];
     
                    float current_yaw = history_when_hit.angle.y;
     
                    CTraceFilter filter;
                    filter.m_icollisionGroup = COLLISION_GROUP_NONE;
                    Ray_t ray;
                    trace_t tr;
     
     
                    //Rotate player angles by i
     
                    //Run trace from trace_start to origin
     
                    //If it goes through the target and the ideal hitbox, then we are gucci
     
                    //Now we want to scan orgin vs trace_ignore.
                    //So if this is true the orgin is inside the hitbox and not actaully as perfect as trace_start.
                    //So this provides a possible point but nowhere near as accurate. This should be considered an okay guess at best
     
                    //If found good angle set resolver time to that of when the target was hit, the game event and this hook are both delayed so we need to get it more accurately, however in general it doesn't
                    //have to be as acurate as say an in attack resolver, may fuck up if they are using some jitter or w/e
     
                    for (int angle = 0; angle <= 1080; angle += 4)
                    {
                        float body_yaw = angle <= 360.0f ? 0.0f : angle <= 720.0f ? -1.0f : 1.0f;
                        entity->SetPoseParameterScaled(11, body_yaw);
     
                        entity->SetAbsAngles(QAngle(history_when_hit.angle.x, current_yaw, history_when_hit.angle.z));
     
                        //entity->SetupBones(bonematrix, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, interfaces::globals->curtime);
                        if (!entity->SetupBones_invalid(bonematrix, MAXSTUDIOBONES, BONE_USED_BY_HITBOX, interfaces::engine->GetLastTimeStamp()))
                            return;
     
                        //Setup custom hitboxs
     
                        mstudiohitboxset_t* set = interfaces::model_info->GetStudiomodel(entity->GetModel())->GetHitboxSet(
                            entity->GetHitboxSet());
                        std::vector<tracing::CSphere> m_cSpheres;
                        std::vector<tracing::COBB> m_cOBBs;
     
                        for (int i = 0; i < set->numHitBoxes; i++)
                        {
                            mstudiobbox_t* pbox = set->GetHitbox(i);
                            if (pbox->group == hit_group_player_was_shot)
                            {
                                if (pbox->radius != -1.0f)
                                {
                                    Vector vMin, vMax;
                                    math::vector_transform(pbox->bbmin, bonematrix[pbox->bone], vMin);
                                    math::vector_transform(pbox->bbmax, bonematrix[pbox->bone], vMax);
                                    Vector Screen, Screen1;
                                    if (game_tools::world_to_screen(vMin, Screen) && game_tools::world_to_screen(vMax, Screen1))
                                    {
                                        draw->line(Vector2D(Screen.x, Screen.y), Vector2D(Screen1.x, Screen1.y), Color::Green(), 6);
                                    }
     
                                    SetupCapsule(vMin, vMax, pbox->radius, pbox->group, m_cSpheres);
                                }
                                else
                                {
                                    m_cOBBs.push_back(tracing::COBB(pbox->bbmin, pbox->bbmax, &bonematrix[pbox->bone], pbox->group));
                                }
                            }
                        }
     
                        ray.Init(trace_start, blood_origin);
     
                        //TODO: make trace for just one hitbox not all of them.
     
                        trace_hitbox(entity, ray, tr, m_cSpheres, m_cOBBs);
     
                        if (tr.m_pEnt == entity && tr.hitgroup == hit_group_player_was_shot)
                        {
                            if (!found_general_head)
                            {
                                first_body_yaw_found = body_yaw;
                                first_yaw_found = current_yaw;
                                found_general_head = true;
                            }
                            //TODO: not sure if this logic is right, I am very tired and a little drunk
                            //Make sure if we trace slightly out of the impact origin, we don't still hit the same thing, otherwise the angle isn't correct
                            ray.Init(trace_start, trace_ignore);
     
                            //TODO: make trace for just one hitbox not all of them.
     
                            trace_hitbox(entity, ray, tr, m_cSpheres, m_cOBBs);
     
                            if (!tr.m_pEnt || tr.hitgroup != hit_group_player_was_shot)
                            {
                                found_real_head = true;
                                break;
                            }
                        }
                        current_yaw++;
     
                        if (current_yaw > 360.0f)
                            current_yaw -= 360.0f;
     
                        if (current_yaw < 0.0f)
                            current_yaw += 360.0f;
                    }
     
                    //We gucci we done all tracing we need, yippie ki ayyy mother fucker
                    if(found_real_head)
                    {
                        history_when_hit.body_hit_perfect = true;
                        history_when_hit.body_hit = true;
                        history_when_hit.body_angle = current_yaw;
                    }
                    else if (!found_real_head && found_general_head)
                    {
                        current_yaw = first_yaw_found;
                        history_when_hit.body_hit = true;
                        history_when_hit.body_angle = current_yaw;
                    }
     
                    //Apply to resolver logic now
                }
     
                //void EffectsResolver::playerhit33(C_TEEffectDispatch* thisptr, DataUpdateType_t updateType, render::IDrawer* draw)
                //{
                //    if (thisptr->m_EffectData.m_hEntity <= 0)
                //        return;
     
                //    auto client_entity = interfaces::entity_list->GetClientEntityFromHandle(thisptr->m_EffectData.m_hEntity);
                //    auto entity = static_cast<CBasePlayer*>(client_entity);
     
                //    int player_index = entity->GetIndex();
     
                //    if (!(entity && entity->IsPlayer() && entity != player_data::local_player_information.entity))
                //        return;
     
                //    if (player_index > 128)
                //        return;
     
                //    auto& target = player_data::player_records[player_index];
     
                //    //prevent access viloation
                //    if (target.information.size() <= 0)
                //        return;
     
                //    auto& current_tick = target.information.front();
     
                //    float simulation_time = current_tick.sim_time;
     
                //    target.simtime_last_get_body_spot = simulation_time;
                //}
     
                void EffectsResolver::resolver_sanitiser()
                {
                    /*
                    I'm not really in the mode to even write sudo code for this, it is just an idea.
     
                    So it is a not boolean hit resolver
     
                    The idea about it is get bullet impact, get the direction of inpact, trace back a fuck ton way
     
                    Then trace and see that it doesn't hit the entity as we expected, then we can spin the entity fulll 360 degrees and determin which angle ranges the trace hits the entity,
                    these angles where it hits the entity clealry can't be the real angle.
     
                    From this we cna apply like 1.1s since lby updated and some other logic or even just to sanities our resolver angles for logic reoslver, backtrack here for some more accuracy
                    
                    This will not tell us the angle, rather it will tell us what angles they couldn't be
     
                    */
                }
     
                void enable_interp()
                {
                    int MaxEntities = 64;// Interfaces::ClientEntList->GetHighestEntityIndex();
     
                    for (int i = 0; i <= MaxEntities; i++)
                    {
                        CCSPlayer* Entity = (CCSPlayer*)interfaces::entity_list->GetClientEntity(i);
     
                        if (Entity && Entity->IsPlayer())
                        {
                            if (!Entity->GetDormant() && i != interfaces::engine->GetLocalPlayer())
                            {
                                Entity->enable_interp();
                            }
                        }
                    }
                }
            }
        }
    }
 
Забаненный
Статус
Оффлайн
Регистрация
7 Мар 2017
Сообщения
753
Реакции[?]
364
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Нормальный вид этой хуйни
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
return 0;
Забаненный
Статус
Оффлайн
Регистрация
6 Мар 2017
Сообщения
405
Реакции[?]
237
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
найс резольвер в 2269 строк :FeelsBadMan:
 
zZzZzZzzZzZZz
Пользователь
Статус
Оффлайн
Регистрация
10 Янв 2017
Сообщения
322
Реакции[?]
82
Поинты[?]
0
Скажите сразу, он стоит пастинга в свою хуйню или не?
 
return 0;
Забаненный
Статус
Оффлайн
Регистрация
6 Мар 2017
Сообщения
405
Реакции[?]
237
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Обижаю детей <3
Забаненный
Статус
Оффлайн
Регистрация
1 Сен 2017
Сообщения
32
Реакции[?]
11
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Боже сколько дерьма лишнего тут.
 
Начинающий
Статус
Оффлайн
Регистрация
20 Янв 2018
Сообщения
574
Реакции[?]
397
Поинты[?]
62K
Если честно, здесь очень много ненужного кода (прям очень). Вот один вопрос -зачем? Зачем столько ненужного кода????? Чтобы сделать пРесольвер 3к строк не надо
 
big resseler
Забаненный
Статус
Оффлайн
Регистрация
19 Мар 2018
Сообщения
17
Реакции[?]
0
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Боже если убрать все лишнее останется 100-200 строк чистого кода.
 
Начинающий
Статус
Оффлайн
Регистрация
13 Май 2017
Сообщения
35
Реакции[?]
4
Поинты[?]
0
Последнее редактирование:
Сверху Снизу