Facebook
From Torrid Moth, 6 Months ago, written in Plain Text.
This paste is a reply to src from Ivory Pheasant - go back
Embed
Viewing differences between src and Re: src
#include "Menu.h"
#include "Controls.h"
#include "Hooks.h" // for the unload meme
#include "Interfaces.h"

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600

AimWareWindow Menu::Window;

void UnLoadCallbk()
{
    DoUnload = true;
}

void KnifeApplyCallbk()
{
    static ConVar* Meme = Interfaces::CVar->FindVar("cl_fullupdate");
    Meme->nFlags &= ~FCVAR_CHEAT;
    Interfaces::Engine->ClientCmd_Unrestricted("cl_fullupdate");
}

void AimWareWindow::Setup()
{
    SetPosition(50, 50);
    SetSize(WINDOW_WIDTH, WINDOW_HEIGHT);
    SetTitle(" PatrickHook-BestPrivateCheats);

    RegisterTab(&RageBotTab);
    RegisterTab(&LegitBotTab);
    RegisterTab(&VisualsTab);
    RegisterTab(&MiscTab);

    RECT Client = GetClientArea();
    Client.bottom -= 29;

    RageBotTab.Setup();
    LegitBotTab.Setup();
    VisualsTab.Setup();
    MiscTab.Setup();

#pragma region Bottom Buttons
    UnloadButton.SetText("PANIC");
    UnloadButton.SetCallback(UnLoadCallbk);
    UnloadButton.SetPosition(16, Client.bottom - 42);

    RageBotTab.RegisterControl(&UnloadButton);
    LegitBotTab.RegisterControl(&UnloadButton);
    VisualsTab.RegisterControl(&UnloadButton);
    MiscTab.RegisterControl(&UnloadButton);

    //SaveButton.SetText("Save Settings");
    //SaveButton.SetCallback(Call);
    //SaveButton.SetPosition(112, Client.bottom - 42);

    //RageBotTab.RegisterControl(&SaveButton);
    //LegitBotTab.RegisterControl(&SaveButton);
    //VisualsTab.RegisterControl(&SaveButton);
    //MiscTab.RegisterControl(&SaveButton);


#pragma endregion Setting up the settings buttons
}

void CRageBotTab::Setup()
{
    SetTitle("Rage Aimbot");

    ActiveLabel.SetPosition(16, 16);
    ActiveLabel.SetText("Active");
    RegisterControl(&ActiveLabel);

    Active.SetFileId("active");
    Active.SetPosition(66, 16);
    RegisterControl(&Active);

#pragma region Aimbot

    AimbotGroup.SetPosition(16, 48);
    AimbotGroup.SetText("Aimbot");
    AimbotGroup.SetSize(376, 280);
    RegisterControl(&AimbotGroup);

    AimbotEnable.SetFileId("aim_enable");
    AimbotGroup.PlaceLabledControl("Enable", this, &AimbotEnable);

    AimbotAutoFire.SetFileId("aim_autofire");
    AimbotGroup.PlaceLabledControl("Auto Fire", this, &AimbotAutoFire);

    AimbotFov.SetFileId("aim_fov");
    AimbotFov.SetBoundaries(0.f, 180.f);
    AimbotFov.SetValue(39.f);
    AimbotGroup.PlaceLabledControl("FOV Range", this, &AimbotFov);

    AimbotSilentAim.SetFileId("aim_silent");
    AimbotGroup.PlaceLabledControl("Silent Aim", this, &AimbotSilentAim);

    AimbotPSilent.SetFileId("aim_psilent");
    AimbotGroup.PlaceLabledControl("Perfect Silent", this, &AimbotPSilent);

    AimbotAutoPistol.SetFileId("aim_autopistol");
    AimbotGroup.PlaceLabledControl("Auto Pistol", this, &AimbotAutoPistol);

    AimbotAimStep.SetFileId("aim_aimstep");
    AimbotGroup.PlaceLabledControl("Aim Step", this, &AimbotAimStep);

    AimbotKeyPress.SetFileId("aim_usekey");
    AimbotGroup.PlaceLabledControl("On Key Press", this, &AimbotKeyPress);

    AimbotKeyBind.SetFileId("aim_key");
    AimbotGroup.PlaceLabledControl("Key", this, &AimbotKeyBind);

    AimbotChicken.SetFileId("aim_chicken");
    AimbotGroup.PlaceLabledControl("Chikens", this, &AimbotChicken);

#pragma endregion Aimbot Controls Get Setup in here

#pragma region Target
    TargetGroup.SetPosition(16, 344);
    TargetGroup.SetText("Target");
    TargetGroup.SetSize(376, 134);
    RegisterControl(&TargetGroup);

    TargetSelection.SetFileId("tgt_selection");
    TargetSelection.AddItem("Closest To Crosshair");
    TargetSelection.AddItem("Distance");
    TargetSelection.AddItem("Lowest Health");
    TargetGroup.PlaceLabledControl("Selection", this, &TargetSelection);

    TargetFriendlyFire.SetFileId("tgt_friendlyfire");
    TargetGroup.PlaceLabledControl("Friendly Fire", this, &TargetFriendlyFire);

    TargetHitbox.SetFileId("tgt_hitbox");
    TargetHitbox.AddItem("Head");
    TargetHitbox.AddItem("Neck");
    TargetHitbox.AddItem("Chest");
    TargetHitbox.AddItem("Stomach");
    TargetGroup.PlaceLabledControl("Hitbox", this, &TargetHitbox);

    TargetHitscan.SetFileId("tgt_hitscan");
    TargetHitscan.AddItem("Off"); //0
    TargetHitscan.AddItem("Head / Body"); // 1
    TargetHitscan.AddItem("All Basic"); // 2
    TargetHitscan.AddItem("All Fucking Heaps"); // 3
    TargetGroup.PlaceLabledControl("Hit Scan", this, &TargetHitscan);
#pragma endregion Targetting controls 

#pragma region Accuracy
    AccuracyGroup.SetPosition(408, 48);
    AccuracyGroup.SetText("Accuracy");
    AccuracyGroup.SetSize(360, 280);
    RegisterControl(&AccuracyGroup);

    AccuracySpread.SetFileId("acc_nospread");
    AccuracyGroup.PlaceLabledControl("Anti Spread", this, &AccuracySpread);

    AccuracyRecoil.SetFileId("acc_norecoil");
    AccuracyGroup.PlaceLabledControl("Anti Recoil", this, &AccuracyRecoil);

    AccuracyAutoWall.SetFileId("acc_awall");
    AccuracyGroup.PlaceLabledControl("Auto Wall", this, &AccuracyAutoWall);

    AccuracyMinimumDamage.SetFileId("acc_mindmg");
    AccuracyMinimumDamage.SetBoundaries(1.f, 100.f);
    AccuracyMinimumDamage.SetValue(1.f);
    AccuracyGroup.PlaceLabledControl("Min AWall Damage", this, &AccuracyMinimumDamage);

    AccuracyAutoStop.SetFileId("acc_stop");
    AccuracyGroup.PlaceLabledControl("Auto Stop", this, &AccuracyAutoStop);

    AccuracyAutoCrouch.SetFileId("acc_crouch");
    AccuracyGroup.PlaceLabledControl("Auto Crouch", this, &AccuracyAutoCrouch);

    AccuracyAutoScope.SetFileId("acc_scope");
    AccuracyGroup.PlaceLabledControl("Auto Scope", this, &AccuracyAutoScope);

    AccuracySpreadLimit.SetFileId("acc_spreadlimon");
    AccuracyGroup.PlaceLabledControl("Spread Limit", this, &AccuracySpreadLimit);

    AccuracyMinimumSpread.SetFileId("acc_spreadlim");
    AccuracyMinimumSpread.SetBoundaries(0.f, 5.0f);
    AccuracyMinimumSpread.SetValue(1.5f);
    AccuracyGroup.PlaceLabledControl("Spread Limit Value", this, &AccuracyMinimumSpread);

    AccuracyAngleFix.SetFileId("acc_aaa");
    AccuracyGroup.PlaceLabledControl("AngleFix", this, &AccuracyAngleFix);
#pragma endregion  Accuracy controls get Setup in here

#pragma region AntiAim
    AntiAimGroup.SetPosition(408, 344);
    AntiAimGroup.SetText("Anti-Aim");
    AntiAimGroup.SetSize(360, 134);
    RegisterControl(&AntiAimGroup);

    AntiAimEnable.SetFileId("aa_enable");
    AntiAimGroup.PlaceLabledControl("Enable", this, &AntiAimEnable);

    AntiAimPitch.SetFileId("aa_x");
    AntiAimPitch.AddItem("None");
    AntiAimPitch.AddItem("Up");
    AntiAimPitch.AddItem("Down");
    AntiAimPitch.AddItem("Jitter");
    AntiAimGroup.PlaceLabledControl("X", this, &AntiAimPitch);

    AntiAimYaw.SetFileId("aa_y");
    AntiAimYaw.AddItem("None");
    AntiAimYaw.AddItem("Spin Fast");
    AntiAimYaw.AddItem("Spin Slow");
    AntiAimYaw.AddItem("Inverse");
    AntiAimYaw.AddItem("Jitter");
    AntiAimYaw.AddItem("Flip");
    AntiAimGroup.PlaceLabledControl("Y", this, &AntiAimYaw);

#pragma endregion  AntiAim controls get setup in here
}

void CLegitBotTab::Setup()
{
    SetTitle("Legit Aimbot");

    ActiveLabel.SetPosition(16, 16);
    ActiveLabel.SetText("Active");
    RegisterControl(&ActiveLabel);

    Active.SetFileId("active");
    Active.SetPosition(66, 16);
    RegisterControl(&Active);

#pragma region Aimbot
    AimbotGroup.SetPosition(16, 48);
    AimbotGroup.SetText("Aimbot");
    AimbotGroup.SetSize(240, 210);
    RegisterControl(&AimbotGroup);

    AimbotEnable.SetFileId("aim_enable");
    AimbotGroup.PlaceLabledControl("Enable", this, &AimbotEnable);

    AimbotAutoFire.SetFileId("aim_autofire");
    AimbotGroup.PlaceLabledControl("Auto Fire", this, &AimbotAutoFire);

    AimbotFriendlyFire.SetFileId("aim_friendfire");
    AimbotGroup.PlaceLabledControl("Friendly Fire", this, &AimbotFriendlyFire);

    AimbotKeyPress.SetFileId("aim_usekey");
    AimbotGroup.PlaceLabledControl("On Key Press", this, &AimbotKeyPress);

    AimbotKeyBind.SetFileId("aim_key");
    AimbotGroup.PlaceLabledControl("Key Bind", this, &AimbotKeyBind);

    AimbotAutoPistol.SetFileId("aim_apistol");
    AimbotGroup.PlaceLabledControl("Auto Pistol", this, &AimbotAutoPistol);

#pragma endregion Aimbot shit

#pragma region Triggerbot
    TriggerGroup.SetPosition(272, 48);
    TriggerGroup.SetText("Triggerbot");
    TriggerGroup.SetSize(240, 210);
    RegisterControl(&TriggerGroup);

    TriggerEnable.SetFileId("trig_enable");
    TriggerGroup.PlaceLabledControl("Enable", this, &TriggerEnable);

    TriggerKeyPress.SetFileId("trig_onkey");
    TriggerGroup.PlaceLabledControl("On Key Press", this, &TriggerKeyPress);

    TriggerKeyBind.SetFileId("trig_key");
    TriggerGroup.PlaceLabledControl("Key Bind", this, &TriggerKeyBind);

    TriggerDelay.SetFileId("trig_delay");
    TriggerDelay.SetBoundaries(1, 1000);
    TriggerDelay.SetValue(50);
    TriggerGroup.PlaceLabledControl("Delay", this, &TriggerDelay);
#pragma endregion Triggerbot stuff

#pragma region Main Weapon
    WeaponMainGroup.SetPosition(16, 274);
    WeaponMainGroup.SetText("Rifles/Other");
    WeaponMainGroup.SetSize(240, 210);
    RegisterControl(&WeaponMainGroup);

    WeaponMainSpeed.SetFileId("main_speed");
    WeaponMainSpeed.SetBoundaries(0.1f, 2.f);
    WeaponMainSpeed.SetValue(1.0f);
    WeaponMainGroup.PlaceLabledControl("Max Speed", this, &WeaponMainSpeed);

    WeaponMainFoV.SetFileId("main_fov");
    WeaponMainFoV.SetBoundaries(0.1f, 30.f);
    WeaponMainFoV.SetValue(5.f);
    WeaponMainGroup.PlaceLabledControl("FOV", this, &WeaponMainFoV);

    WeaponMainRecoil.SetFileId("main_recoil");
    WeaponMainGroup.PlaceLabledControl("Recoil", this, &WeaponMainRecoil);

    WeaponMainHitbox.SetFileId("main_hitbox");
    WeaponMainHitbox.AddItem("Head");
    WeaponMainHitbox.AddItem("Neck");
    WeaponMainHitbox.AddItem("Chest");
    WeaponMainHitbox.AddItem("Stomach");
    WeaponMainGroup.PlaceLabledControl("Hitbox", this, &WeaponMainHitbox);
#pragma endregion

#pragma region Pistols
    WeaponPistGroup.SetPosition(272, 274);
    WeaponPistGroup.SetText("Pistols");
    WeaponPistGroup.SetSize(240, 210);
    RegisterControl(&WeaponPistGroup);

    WeaponPistSpeed.SetFileId("pist_speed");
    WeaponPistSpeed.SetBoundaries(0.1f, 2.f);
    WeaponPistSpeed.SetValue(1.0f);
    WeaponPistGroup.PlaceLabledControl("Max Speed", this, &WeaponPistSpeed);

    WeaponPistFoV.SetFileId("pist_fov");
    WeaponPistFoV.SetBoundaries(0.1f, 30.f);
    WeaponPistFoV.SetValue(5.f);
    WeaponPistGroup.PlaceLabledControl("FOV", this, &WeaponPistFoV);

    WeaponPistRecoil.SetFileId("pist_recoil");
    WeaponPistGroup.PlaceLabledControl("Recoil", this, &WeaponPistRecoil);

    WeaponPistHitbox.SetFileId("pist_hitbox");
    WeaponPistHitbox.AddItem("Head");
    WeaponPistHitbox.AddItem("Neck");
    WeaponPistHitbox.AddItem("Chest");
    WeaponPistHitbox.AddItem("Stomach");
    WeaponPistGroup.PlaceLabledControl("Hitbox", this, &WeaponPistHitbox);
#pragma endregion

#pragma region Snipers
    WeaponSnipGroup.SetPosition(528, 274);
    WeaponSnipGroup.SetText("Snipers");
    WeaponSnipGroup.SetSize(240, 210);
    RegisterControl(&WeaponSnipGroup);

    WeaponSnipSpeed.SetFileId("snip_speed");
    WeaponSnipSpeed.SetBoundaries(0.1f, 2.f);
    WeaponSnipSpeed.SetValue(1.0f);
    WeaponSnipGroup.PlaceLabledControl("Max Speed", this, &WeaponSnipSpeed);

    WeaponSnipFoV.SetFileId("snip_fov");
    WeaponSnipFoV.SetBoundaries(0.1f, 30.f);
    WeaponSnipFoV.SetValue(5.f);
    WeaponSnipGroup.PlaceLabledControl("FOV", this, &WeaponSnipFoV);

    WeaponSnipRecoil.SetFileId("snip_recoil");
    WeaponSnipGroup.PlaceLabledControl("Recoil", this, &WeaponSnipRecoil);

    WeaponSnipHitbox.SetFileId("snip_hitbox");
    WeaponSnipHitbox.AddItem("Head");
    WeaponSnipHitbox.AddItem("Neck");
    WeaponSnipHitbox.AddItem("Chest");
    WeaponSnipHitbox.AddItem("Stomach");
    WeaponSnipGroup.PlaceLabledControl("Hitbox", this, &WeaponSnipHitbox);
#pragma endregion
}

void CVisualTab::Setup()
{
    SetTitle("Visuals & Misc");

    ActiveLabel.SetPosition(16, 16);
    ActiveLabel.SetText("Active");
    RegisterControl(&ActiveLabel);

    Active.SetFileId("active");
    Active.SetPosition(66, 16);
    RegisterControl(&Active);

#pragma region Options
    OptionsGroup.SetText("Options");
    OptionsGroup.SetPosition(16, 48);
    OptionsGroup.SetSize(193, 430);
    RegisterControl(&OptionsGroup);

    OptionsBox.SetFileId("opt_box");
    OptionsGroup.PlaceLabledControl("Box", this, &OptionsBox);

    OptionsName.SetFileId("opt_name");
    OptionsGroup.PlaceLabledControl("Name", this, &OptionsName);

    OptionsHealth.SetFileId("opt_hp");
    OptionsGroup.PlaceLabledControl("Health", this, &OptionsHealth);

    OptionsWeapon.SetFileId("opt_weapon");
    OptionsGroup.PlaceLabledControl("Weapon", this, &OptionsWeapon);

    OptionsInfo.SetFileId("opt_info");
    OptionsGroup.PlaceLabledControl("Info", this, &OptionsInfo);

    OptionsChams.SetFileId("opt_chams");
    OptionsChams.AddItem("Off");
    OptionsChams.AddItem("Normal");
    OptionsChams.AddItem("Flat");
    OptionsGroup.PlaceLabledControl("Chams", this, &OptionsChams);

    OptionsSkeleton.SetFileId("opt_bone");
    OptionsGroup.PlaceLabledControl("Skeleton", this, &OptionsSkeleton);

    OptionsAimSpot.SetFileId("opt_aimspot");
    OptionsGroup.PlaceLabledControl("Aim Spot", this, &OptionsAimSpot);

    OptionsCompRank.SetFileId("opt_comprank");
    OptionsGroup.PlaceLabledControl("Competitive Rank", this, &OptionsCompRank);

#pragma endregion Setting up the Options controls

#pragma region Filters
    FiltersGroup.SetText("Filters");
    FiltersGroup.SetPosition(225, 48);
    FiltersGroup.SetSize(193, 430);
    RegisterControl(&FiltersGroup);

    FiltersAll.SetFileId("ftr_all");
    FiltersGroup.PlaceLabledControl("All", this, &FiltersAll);

    FiltersPlayers.SetFileId("ftr_players");
    FiltersGroup.PlaceLabledControl("Players", this, &FiltersPlayers);

    FiltersEnemiesOnly.SetFileId("ftr_enemyonly");
    FiltersGroup.PlaceLabledControl("Enemies Only", this, &FiltersEnemiesOnly);

    FiltersWeapons.SetFileId("ftr_weaps");
    FiltersGroup.PlaceLabledControl("Weapons", this, &FiltersWeapons);

    FiltersChickens.SetFileId("ftr_chickens");
    FiltersGroup.PlaceLabledControl("Chickens", this, &FiltersChickens);

    FiltersC4.SetFileId("ftr_c4");
    FiltersGroup.PlaceLabledControl("C4", this, &FiltersC4);
#pragma endregion Setting up the Filters controls

#pragma region Other
    OtherGroup.SetText("Other");
    OtherGroup.SetPosition(434, 48);
    OtherGroup.SetSize(334, 430);
    RegisterControl(&OtherGroup);

    OtherCrosshair.SetFileId("otr_xhair");
    OtherGroup.PlaceLabledControl("Crosshair", this, &OtherCrosshair);

    OtherRecoilCrosshair.SetFileId("otr_recoilhair");
    OtherRecoilCrosshair.AddItem("Off");
    OtherRecoilCrosshair.AddItem("Recoil Position");
    OtherRecoilCrosshair.AddItem("Radius");
    OtherGroup.PlaceLabledControl("Recoil Crosshair", this, &OtherRecoilCrosshair);

    OtherRadar.SetFileId("otr_radar");
    OtherGroup.PlaceLabledControl("Radar", this, &OtherRadar);

    OtherNoVisualRecoil.SetFileId("otr_visrecoil");
    OtherGroup.PlaceLabledControl("No Visual Recoil", this, &OtherNoVisualRecoil);

    OtherNoSky.SetFileId("otr_nosky");
    OtherGroup.PlaceLabledControl("No Sky", this, &OtherNoSky);

    OtherNoFlash.SetFileId("otr_noflash");
    OtherGroup.PlaceLabledControl("No Flash", this, &OtherNoFlash);

    OtherNoSmoke.SetFileId("otr_nosmoke");
    OtherGroup.PlaceLabledControl("No Smoke", this, &OtherNoSmoke);

    OtherNoHands.SetFileId("otr_hands");
    OtherNoHands.AddItem("Off");
    OtherNoHands.AddItem("None");
    OtherNoHands.AddItem("Transparent");
    OtherNoHands.AddItem("Chams");
    OtherNoHands.AddItem("Rainbow");
    OtherGroup.PlaceLabledControl("Hands", this, &OtherNoHands);

    OtherAutoJump.SetFileId("otr_autojump");
    OtherGroup.PlaceLabledControl("Auto Jump", this, &OtherAutoJump);

    OtherAutoStrafe.SetFileId("otr_autostrafe");
    OtherGroup.PlaceLabledControl("Auto Strafe", this, &OtherAutoStrafe);

    OtherSafeMode.SetFileId("otr_safemode");
    OtherSafeMode.SetState(true);
    OtherGroup.PlaceLabledControl("Safe Mode", this, &OtherSafeMode);

    OtherChatSpam.SetFileId("otr_spam");
    OtherChatSpam.AddItem("Off");
    OtherChatSpam.AddItem("Round-Say");
    OtherChatSpam.AddItem("Regular");
    OtherChatSpam.AddItem("Report Text Spam");
    OtherGroup.PlaceLabledControl("Chat Spam", this, &OtherChatSpam);

    OtherAirStuck.SetFileId("otr_astuck");
    OtherGroup.PlaceLabledControl("Air Stuck", this, &OtherAirStuck);

    OtherSpectators.SetFileId("otr_speclist");
    OtherGroup.PlaceLabledControl("Spectators List", this, &OtherSpectators);
#pragma endregion Setting up the Other controls
}

void CMiscTab::Setup()
{
    SetTitle("Skins");

#pragma region Knife
    KnifeGroup.SetPosition(16, 16);
    KnifeGroup.SetSize(360, 400);
    KnifeGroup.SetText("Skin Changer");
    RegisterControl(&KnifeGroup);

    KnifeEnable.SetFileId("knife_enable");
    KnifeGroup.PlaceLabledControl("Enable", this, &KnifeEnable);

    KnifeModel.SetFileId("knife_model");
    KnifeModel.AddItem("Karambit");
    KnifeModel.AddItem("Bayonet");
    KnifeModel.AddItem("Huntsman Knife");
    KnifeModel.AddItem("Gut Knife");
    KnifeModel.AddItem("Walmart Knife");
    KnifeModel.AddItem("Shadow Daggers");
    KnifeModel.AddItem("Butterfly Knife");
    KnifeModel.AddItem("Flip Knife");
    KnifeGroup.PlaceLabledControl("Knife", this, &KnifeModel);

    KnifeSkin.SetFileId("knife_skin");
    KnifeSkin.AddItem("Fade");
    KnifeSkin.AddItem("Damascus Steel");
    KnifeSkin.AddItem("Doppler Phase 1");
    KnifeSkin.AddItem("Doppler Phase 2");
    KnifeSkin.AddItem("Doppler Phase 3");
    KnifeSkin.AddItem("Doppler Phase 4");
    KnifeSkin.AddItem("Doppler (Ruby)");
    KnifeSkin.AddItem("Doppler (Sapphire)");
    KnifeSkin.AddItem("Doppler (Blackpearl)");
    KnifeSkin.AddItem("Marble Fade");
    KnifeSkin.AddItem("Tiger Tooth");
    KnifeSkin.AddItem("Ultraviolet");
    KnifeSkin.AddItem("Crimson Web");
    KnifeSkin.AddItem("Slaughter");
    KnifeSkin.AddItem("Night");
    KnifeGroup.PlaceLabledControl("Skin", this, &KnifeSkin);

    M41SSkin.SetFileId("m4a1s_skin");
    M41SSkin.AddItem("Masterpiece");
    M41SSkin.AddItem("Hyper Beast");
    M41SSkin.AddItem("Cyrex");
    M41SSkin.AddItem("Hot Rod");
    KnifeGroup.PlaceLabledControl("M4A1-S", this, &M41SSkin);

    M4A4Skin.SetFileId("m4a4_skin");
    M4A4Skin.AddItem("Royal Paladin");
    M4A4Skin.AddItem("Howl");
    M4A4Skin.AddItem("Bullet Rain");
    M4A4Skin.AddItem("Dragon King");
    M4A4Skin.AddItem("Asiimov");
    KnifeGroup.PlaceLabledControl("M4A4", this, &M4A4Skin);

    AK47Skin.SetFileId("ak47_skin");
    AK47Skin.AddItem("Point Disarray");
    AK47Skin.AddItem("Aquamarine Revenge");
    AK47Skin.AddItem("Vulcan");
    AK47Skin.AddItem("Fire Serpent");
    AK47Skin.AddItem("Jaguar");
    KnifeGroup.PlaceLabledControl("AK-47", this, &AK47Skin);

    AWPSkin.SetFileId("awp_skin");
    AWPSkin.AddItem("Hyper Beast");
    AWPSkin.AddItem("Asiimov");
    AWPSkin.AddItem("Dragon Lore");
    AWPSkin.AddItem("Lightning Strike");
    KnifeGroup.PlaceLabledControl("AWP", this, &AWPSkin);

    GLOCKSkin.SetFileId("glock_skin");
    GLOCKSkin.AddItem("Water Elemental");
    GLOCKSkin.AddItem("Fade");
    GLOCKSkin.AddItem("Twilight Galaxy");
    GLOCKSkin.AddItem("Bunsen Burner");
    KnifeGroup.PlaceLabledControl("Glock", this, &GLOCKSkin);

    USPSSkin.SetFileId("m4a1s_skin");
    USPSSkin.AddItem("Kill Confirmed");
    USPSSkin.AddItem("Caiman");
    USPSSkin.AddItem("Orion");
    USPSSkin.AddItem("Guardian");
    KnifeGroup.PlaceLabledControl("USP-S", this, &USPSSkin);

    MAGNUMSkin.SetFileId("357_skin");
    MAGNUMSkin.AddItem("Crimson Web");
    MAGNUMSkin.AddItem("Fade");
    MAGNUMSkin.AddItem("Amber Fade");
    KnifeGroup.PlaceLabledControl("R8 Revolver", this, &MAGNUMSkin);

    KnifeApply.SetText("Apply Changes");
    KnifeApply.SetCallback(KnifeApplyCallbk);
    KnifeGroup.PlaceLabledControl("", this, &KnifeApply);






#pragma endregion

#pragma endregion other random options
}

void Menu::SetupMenu()
{
    Window.Setup();

    GUI.RegisterWindow(&Window);
    GUI.BindWindow(VK_INSERT, &Window);
}

void Menu::DoUIFrame()
{
    // General Processing

    // If the "all filter is selected tick all the others
    if (Window.VisualsTab.FiltersAll.GetState())
    {
        Window.VisualsTab.FiltersC4.SetState(true);
        Window.VisualsTab.FiltersChickens.SetState(true);
        Window.VisualsTab.FiltersPlayers.SetState(true);
        Window.VisualsTab.FiltersWeapons.SetState(true);
    }

    GUI.Update();
    GUI.Draw();


}


#include "GUI.h"

#include "RenderManager.h"

#include 
#include "tinyxml2.h"
#include "Controls.h"

CGUI GUI;

CGUI::CGUI()
{

}

// Draws all windows 
void CGUI::Draw()
{
    bool ShouldDrawCursor = false;

    for (auto window : Windows)
    {
        if (window->m_bIsOpen)
        {
            ShouldDrawCursor = true;
            DrawWindow(window);
        }

    }

    if (ShouldDrawCursor)
    {
        static Vertex_t MouseVt[3];

        MouseVt[0].Init(Vector2D(Mouse.x, Mouse.y));
        MouseVt[1].Init(Vector2D(Mouse.x + 16, Mouse.y));
        MouseVt[2].Init(Vector2D(Mouse.x, Mouse.y + 16));

        Render::PolygonOutline(3, MouseVt, Color(150, 0, 0, 230), Color(0, 0, 0, 150));
    }
}

// Handle all input etc
void CGUI::Update()
{
    //Key Array
    std::copy(keys, keys + 255, oldKeys);
    for (int x = 0; x < 255; x++)
    {
        //oldKeys[x] = oldKeys[x] & keys[x];
        keys[x] = (GetAsyncKeyState(x));
    }

    // Mouse Location
    POINT mp; GetCursorPos(&mp);
    Mouse.x = mp.x; Mouse.y = mp.y;

    RECT Screen = Render::GetViewport();

    // Window Binds
    for (auto & bind : WindowBinds)
    {
        if (GetKeyPress(bind.first))
        {
            bind.second->Toggle();
        }
    }

    // Stop dragging
    if (IsDraggingWindow && !GetKeyState(VK_LBUTTON))
    {
        IsDraggingWindow = false;
        DraggingWindow = nullptr;
    }

    // If we are in the proccess of dragging a window
    if (IsDraggingWindow && GetKeyState(VK_LBUTTON) && !GetKeyPress(VK_LBUTTON))
    {
        if (DraggingWindow)
        {
            DraggingWindow->m_x = Mouse.x - DragOffsetX;
            DraggingWindow->m_y = Mouse.y - DragOffsetY;
        }
    }

    // Process some windows
    for (auto window : Windows)
    {
        if (window->m_bIsOpen)
        {
            // Used to tell the widget processing that there could be a click
            bool bCheckWidgetClicks = false;

            // If the user clicks inside the window
            if (GetKeyPress(VK_LBUTTON))
            {
                if (IsMouseInRegion(window->m_x, window->m_y, window->m_x + window->m_iWidth, window->m_y + window->m_iHeight))
                {
                    // Is it inside the client area?
                    if (IsMouseInRegion(window->GetClientArea()))
                    {
                        // User is selecting a new tab
                        if (IsMouseInRegion(window->GetTabArea()))
                        {
                            // Loose focus on the control
                            window->IsFocusingControl = false;
                            window->FocusedControl = nullptr;

                            int iTab = 0;
                            int TabCount = window->Tabs.size();
                            if (TabCount) // If there are some tabs
                            {
                                int TabSize = (window->m_iWidth - 4 - 12) / TabCount;
                                int Dist = Mouse.x - (window->m_x + 8);
                                while (Dist > TabSize)
                                {
                                    if (Dist > TabSize)
                                    {
                                        iTab++;
                                        Dist -= TabSize;
                                    }
                                }
                                window->SelectedTab = window->Tabs[iTab];
                            }

                        }
                        else
                            bCheckWidgetClicks = true;
                    }
                    else
                    {
                        // Must be in the around the title or side of the window
                        // So we assume the user is trying to drag the window
                        IsDraggingWindow = true;
                        DraggingWindow = window;
                        DragOffsetX = Mouse.x - window->m_x;
                        DragOffsetY = Mouse.y - window->m_y;

                        // Loose focus on the control
                        window->IsFocusingControl = false;
                        window->FocusedControl = nullptr;
                    }
                }
                else
                {
                    // Loose focus on the control
                    window->IsFocusingControl = false;
                    window->FocusedControl = nullptr;
                }
            }


            // Controls 
            if (window->SelectedTab != nullptr)
            {
                // Focused widget
                bool SkipWidget = false;
                CControl* SkipMe = nullptr;

                // this window is focusing on a widget??
                if (window->IsFocusingControl)
                {
                    if (window->FocusedControl != nullptr)
                    {
                        // We've processed it once, skip it later
                        SkipWidget = true;
                        SkipMe = window->FocusedControl;

                        POINT cAbs = window->FocusedControl->GetAbsolutePos();
                        RECT controlRect = { cAbs.x, cAbs.y, window->FocusedControl->m_iWidth, window->FocusedControl->m_iHeight };
                        window->FocusedControl->OnUpdate();

                        if (window->FocusedControl->Flag(UIFlags::UI_Clickable) && IsMouseInRegion(controlRect) && bCheckWidgetClicks)
                        {
                            window->FocusedControl->OnClick();

                            // If it gets clicked we loose focus
                            window->IsFocusingControl = false;
                            window->FocusedControl = nullptr;
                            bCheckWidgetClicks = false;
                        }
                    }
                }

                // Itterate over the rest of the control
                for (auto control : window->SelectedTab->Controls)
                {
                    if (control != nullptr)
                    {
                        if (SkipWidget && SkipMe == control)
                            continue;

                        POINT cAbs = control->GetAbsolutePos();
                        RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                        control->OnUpdate();

                        if (control->Flag(UIFlags::UI_Clickable) && IsMouseInRegion(controlRect) && bCheckWidgetClicks)
                        {
                            control->OnClick();
                            bCheckWidgetClicks = false;

                            // Change of focus
                            if (control->Flag(UIFlags::UI_Focusable))
                            {
                                window->IsFocusingControl = true;
                                window->FocusedControl = control;
                            }
                            else
                            {
                                window->IsFocusingControl = false;
                                window->FocusedControl = nullptr;
                            }

                        }
                    }
                }

                // We must have clicked whitespace
                if (bCheckWidgetClicks)
                {
                    // Loose focus on the control
                    window->IsFocusingControl = false;
                    window->FocusedControl = nullptr;
                }
            }
        }
    }
}

// Returns 
bool CGUI::GetKeyPress(unsigned int key)
{
    if (keys[key] == true && oldKeys[key] == false)
        return true;
    else
        return false;
}

bool CGUI::GetKeyState(unsigned int key)
{
    return keys[key];
}

bool CGUI::IsMouseInRegion(int x, int y, int x2, int y2)
{
    if (Mouse.x > x && Mouse.y > y && Mouse.x < x2 && Mouse.y < y2)
        return true;
    else
        return false;
}

bool CGUI::IsMouseInRegion(RECT region)
{
    return IsMouseInRegion(region.left, region.top, region.left + region.right, region.top + region.bottom);
}

POINT CGUI::GetMouse()
{
    return Mouse;
}

bool CGUI::DrawWindow(CWindow* window)
{
    // Main Window
    Render::Outline(window->m_x, window->m_y, window->m_iWidth, window->m_iHeight, Color(20, 20, 20, 80));
    Render::GradientV(window->m_x + 2, window->m_y + 2, window->m_iWidth - 4, 26, Color(0, 0, 0, 255), Color(0, 0, 0, 255));
    Render::Clear(window->m_x + 2, window->m_y + 2 + 26, window->m_iWidth - 4, window->m_iHeight - 4 - 26, Color(0, 0, 0, 255));
    Render::Outline(window->m_x + 1, window->m_y + 1, window->m_iWidth - 2, window->m_iHeight - 2, Color(255, 0, 0, 255));
    Render::Text(window->m_x + 8, window->m_y + 8, Color(255, 255, 255, 255), Render::Fonts::MenuBold, window->Title.c_str());

    //Inner
    Render::Outline(window->m_x + 7, window->m_y + 1 + 26, window->m_iWidth - 4 - 10, window->m_iHeight - 2 - 6 - 26, Color(255, 0, 0, 255));
    Render::Clear(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, window->m_iHeight - 2 - 8 - 26, Color(255, 255, 255, 255));

    //Tab
    Render::GradientV(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, 29, Color(52, 52, 52, 255), Color(6, 6, 6, 255));
    int TabCount = window->Tabs.size();
    if (TabCount) // If there are some tabs
    {
        int TabSize = (window->m_iWidth - 4 - 12) / TabCount;
        for (int i = 0; i < TabCount; i++)
        {
            RECT TabArea = { window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29 };
            CTab* tab = window->Tabs[i];
            if (window->SelectedTab == tab)
            {
                Render::GradientV(window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29, Color(52, 52, 52, 255), Color(106, 106, 106, 255));
            }
            else if (IsMouseInRegion(TabArea))
            {
                Render::GradientV(window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29, Color(106, 106, 106, 255), Color(52, 52, 52, 255));
            }
            RECT TextSize = Render::GetTextSize(Render::Fonts::MenuBold, tab->Title.c_str());
            Render::Text(TabArea.left + (TabSize / 2) - (TextSize.right / 2), TabArea.top + 8, Color(255, 255, 255, 255), Render::Fonts::MenuBold, tab->Title.c_str());
            Render::Clear(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, 2, Color(66, 66, 66, 255));
        }
    }


    // Controls 
    if (window->SelectedTab != nullptr)
    {
        // Focused widget
        bool SkipWidget = false;
        CControl* SkipMe = nullptr;

        // this window is focusing on a widget??
        if (window->IsFocusingControl)
        {
            if (window->FocusedControl != nullptr)
            {
                // We need to draw it last, so skip it in the regular loop
                SkipWidget = true;
                SkipMe = window->FocusedControl;
            }
        }


        // Itterate over all the other controls
        for (auto control : window->SelectedTab->Controls)
        {
            if (SkipWidget && SkipMe == control)
                continue;

            if (control != nullptr && control->Flag(UIFlags::UI_Drawable))
            {
                POINT cAbs = control->GetAbsolutePos();
                RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                bool hover = false;
                if (IsMouseInRegion(controlRect))
                {
                    hover = true;
                }
                control->Draw(hover);
            }
        }

        // Draw the skipped widget last
        if (SkipWidget)
        {
            auto control = window->FocusedControl;

            if (control != nullptr && control->Flag(UIFlags::UI_Drawable))
            {
                POINT cAbs = control->GetAbsolutePos();
                RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                bool hover = false;
                if (IsMouseInRegion(controlRect))
                {
                    hover = true;
                }
                control->Draw(hover);
            }
        }

    }


    return true;
}

void CGUI::RegisterWindow(CWindow* window)
{
    Windows.push_back(window);

    // Resorting to put groupboxes at the start
    for (auto tab : window->Tabs)
    {
        for (auto control : tab->Controls)
        {
            if (control->Flag(UIFlags::UI_RenderFirst))
            {
                CControl* c = control;
                tab->Controls.erase(std::remove(tab->Controls.begin(), tab->Controls.end(), control), tab->Controls.end());
                tab->Controls.insert(tab->Controls.begin(), control);
            }
        }
    }
}

void CGUI::BindWindow(unsigned char Key, CWindow* window)
{
    if (window)
        WindowBinds[Key] = window;
    else
        WindowBinds.erase(Key);
}

void CGUI::SaveWindowState(CWindow* window, std::string Filename)
{
    // Create a whole new document and we'll just save over top of the old one
    tinyxml2::XMLDocument Doc;

    // Root Element is called "ayy"
    tinyxml2::XMLElement* Root = Doc.NewElement("ayy");
    Doc.LinkEndChild(Root);

    Utilities::Log("Saving Window %s", window->Title.c_str());

    // If the window has some tabs..
    if (Root && window->Tabs.size() > 0)
    {
        for (auto Tab : window->Tabs)
        {
            // Add a new section for this tab
            tinyxml2::XMLElement* TabElement = Doc.NewElement(Tab->Title.c_str());
            Root->LinkEndChild(TabElement);

            Utilities::Log("Saving Tab %s", Tab->Title.c_str());

            // Now we itterate the controls this tab contains
            if (TabElement && Tab->Controls.size() > 0)
            {
                for (auto Control : Tab->Controls)
                {
                    // If the control is ok to be saved
                    if (Control && Control->Flag(UIFlags::UI_SaveFile) && Control->FileIdentifier.length() > 1 && Control->FileControlType)
                    {
                        // Create an element for the control
                        tinyxml2::XMLElement* ControlElement = Doc.NewElement(Control->FileIdentifier.c_str());
                        TabElement->LinkEndChild(ControlElement);

                        Utilities::Log("Saving control %s", Control->FileIdentifier.c_str());

                        if (!ControlElement)
                        {
                            Utilities::Log("Errorino :(");
                            return;
                        }

                        CCheckBox* cbx = nullptr;
                        CComboBox* cbo = nullptr;
                        CKeyBind* key = nullptr;
                        CSlider* sld = nullptr;

                        // Figure out what kind of control and data this is
                        switch (Control->FileControlType)
                        {
                            case UIControlTypes::UIC_CheckBox:
                                cbx = (CCheckBox*)Control;
                                ControlElement->SetText(cbx->GetState());
                                break;
                            case UIControlTypes::UIC_ComboBox:
                                cbo = (CComboBox*)Control;
                                ControlElement->SetText(cbo->GetIndex());
                                break;
                            case UIControlTypes::UIC_KeyBind:
                                key = (CKeyBind*)Control;
                                ControlElement->SetText(key->GetKey());
                                break;
                            case UIControlTypes::UIC_Slider:
                                sld = (CSlider*)Control;
                                ControlElement->SetText(sld->GetValue());
                                break;
                        }
                    }
                }
            }
        }
    }

    //Save the file
    if (Doc.SaveFile(Filename.c_str()) != tinyxml2::XML_NO_ERROR)
    {
        MessageBox(NULL, "Failed To Save Config File!", "AyyWare", MB_OK);
    }

}

void CGUI::LoadWindowState(CWindow* window, std::string Filename)
{
    // Lets load our meme
    tinyxml2::XMLDocument Doc;
    if (Doc.LoadFile(Filename.c_str()) == tinyxml2::XML_NO_ERROR)
    {
        tinyxml2::XMLElement* Root = Doc.RootElement();

        // The root "ayy" element
        if (Root)
        {
            // If the window has some tabs..
            if (Root && window->Tabs.size() > 0)
            {
                for (auto Tab : window->Tabs)
                {
                    // We find the corresponding element for this tab
                    tinyxml2::XMLElement* TabElement = Root->FirstChildElement(Tab->Title.c_str());
                    if (TabElement)
                    {
                        // Now we itterate the controls this tab contains
                        if (TabElement && Tab->Controls.size() > 0)
                        {
                            for (auto Control : Tab->Controls)
                            {
                                // If the control is ok to be saved
                                if (Control && Control->Flag(UIFlags::UI_SaveFile) && Control->FileIdentifier.length() > 1 && Control->FileControlType)
                                {
                                    // Get the controls element
                                    tinyxml2::XMLElement* ControlElement = TabElement->FirstChildElement(Control->FileIdentifier.c_str());

                                    if (ControlElement)
                                    {
                                        Utilities::Log("We tryin to load fam");
                                        CCheckBox* cbx = nullptr;
                                        CComboBox* cbo = nullptr;
                                        CKeyBind* key = nullptr;
                                        CSlider* sld = nullptr;

                                        // Figure out what kind of control and data this is
                                        switch (Control->FileControlType)
                                        {
                                            case UIControlTypes::UIC_CheckBox:
                                                cbx = (CCheckBox*)Control;
                                                cbx->SetState(ControlElement->GetText()[0] == '1' ? true : false);
                                                break;
                                            case UIControlTypes::UIC_ComboBox:
                                                cbo = (CComboBox*)Control;
                                                cbo->SelectIndex(atoi(ControlElement->GetText()));
                                                break;
                                            case UIControlTypes::UIC_KeyBind:
                                                key = (CKeyBind*)Control;
                                                key->SetKey(atoi(ControlElement->GetText()));
                                                break;
                                            case UIControlTypes::UIC_Slider:
                                                sld = (CSlider*)Control;
                                                sld->SetValue(atof(ControlElement->GetText()));
                                                break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}/*
Syn's AYYWAREFramework 2015
*/

// Credits to Valve and Shad0w
#include "Interfaces.h"
#include "Menu.h"

// Shad0ws Yaw fix
// (FIX ME UP LATER)
void FixY(const CRecvProxyData* pData, void* pStruct, void* pOut)
{
    static Vector vLast[65];
    static bool bShotLastTime[65];
    static bool bJitterFix[65];

    float* flPitch = (float*)((DWORD)pOut - 4);
    float flYaw = pData->m_Value.m_Float;
    bool bHasAA;
    bool bSpinbot;

    if (Menu::Window.RageBotTab.AccuracyAngleFix.GetState())
    {
        bHasAA = ((*flPitch == 90.0f) || (*flPitch == 270.0f));
        bSpinbot = false;

        if (!bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()]
            && (fabsf(flYaw - vLast[((IClientEntity*)(pStruct))->GetIndex()].y) > 15.0f) && !bHasAA)
        {
            flYaw = vLast[((IClientEntity*)(pStruct))->GetIndex()].y;
            bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()] = true;
        }
        else
        {
            if (bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()]
                && (fabsf(flYaw - vLast[((IClientEntity*)(pStruct))->GetIndex()].y) > 15.0f))
            {
                bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()] = true;
                bSpinbot = true;
            }
            else
            {
                bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()] = false;
            }
        }

        vLast[((IClientEntity*)(pStruct))->GetIndex()].y = flYaw;


        bool bTmp = bJitterFix[((IClientEntity*)(pStruct))->GetIndex()];

        bJitterFix[((IClientEntity*)(pStruct))->GetIndex()] = (flYaw >= 180.0f && flYaw <= 360.0f);

        if (bTmp && (flYaw >= 0.0f && flYaw <= 180.0f))
        {
            flYaw += 359.0f;
        }

    }

    *(float*)(pOut) = flYaw;
}

// Simple fix for some Fake-Downs
void FixX(const CRecvProxyData* pData, void* pStruct, void* pOut)
{
    float* ang = (float*)pOut;
    *ang = pData->m_Value.m_Float;

    if (!Menu::Window.RageBotTab.AccuracyAngleFix.GetState()) return;

    if (pData->m_Value.m_Float > 180.0f)
        *ang -= 360.0f;
    else if (pData->m_Value.m_Float < -180.0f)
        *ang += 360.0f;
}


RecvVarProxyFn oRecvnModelIndex;

void Hooked_RecvProxy_Viewmodel(CRecvProxyData* pData, void* pStruct, void* pOut)
{
    // Get the knife view model id's
    static int default_t = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_default_t.mdl");
    static int default_ct = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_default_ct.mdl");
    int iBayonet = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_bayonet.mdl");
    int iButterfly = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_butterfly.mdl");
    int iFlip = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_flip.mdl");
    int iGunGame = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_gg.mdl");
    int iGut = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_gut.mdl");
    int iKarambit = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_karam.mdl");
    int iM9Bayonet = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_m9_bay.mdl");
    int iHuntsman = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_tactical.mdl");

    int iFalchion = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_falchion_advanced.mdl");
    int iDagger = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_push.mdl");

    // Get local player (just to stop replacing spectators knifes)
    IClientEntity* pLocal = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    if (Menu::Window.MiscTab.KnifeEnable.GetState() && pLocal)
    {
        // If we are alive and holding a default knife(if we already have a knife don't worry about changing)
        if (pLocal->IsAlive() && (pData->m_Value.m_Int == default_t || pData->m_Value.m_Int == default_ct))
        {
            // Set whatever knife we want
            if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 0)
                pData->m_Value.m_Int = iKarambit;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 1)
                pData->m_Value.m_Int = iBayonet;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 2)
                pData->m_Value.m_Int = iHuntsman;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 3)
                pData->m_Value.m_Int = iGut;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 4)
                pData->m_Value.m_Int = iFalchion;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 5)
                pData->m_Value.m_Int = iDagger;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 6)
                pData->m_Value.m_Int = iButterfly;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 7)
                pData->m_Value.m_Int = iFlip;
        }
    }

    // Carry on the to original proxy
    oRecvnModelIndex(pData, pStruct, pOut);
}

void ApplyAAAHooks()
{
    ClientClass* pClass = Interfaces::Client->GetAllClasses();
    while (pClass)
    {
        const char* pszName = pClass->m_pRecvTable->m_pNetTableName;
        if (!strcmp(pszName, "DT_CSPlayer"))
        {
            for (int i = 0; i < pClass->m_pRecvTable->m_nProps; i++)
            {
                RecvProp* pProp = &(pClass->m_pRecvTable->m_pProps[i]);
                const char* name = pProp->m_pVarName;

                // Pitch Fix
                if (!strcmp(name, "m_angEyeAngles[0]"))
                {
                    pProp->m_ProxyFn = FixX;
                }

                // Yaw Fix
                if (!strcmp(name, "m_angEyeAngles[1]"))
                {
                    //Utilities::Log("Yaw Fix Applied");
                    pProp->m_ProxyFn = FixY;
                }
            }
        }
        else if (!strcmp(pszName, "DT_BaseViewModel"))
        {
            for (int i = 0; i < pClass->m_pRecvTable->m_nProps; i++)
            {
                RecvProp* pProp = &(pClass->m_pRecvTable->m_pProps[i]);
                const char* name = pProp->m_pVarName;

                // Knives
                if (!strcmp(name, "m_nModelIndex"))
                {
                    oRecvnModelIndex = (RecvVarProxyFn)pProp->m_ProxyFn;
                    pProp->m_ProxyFn = Hooked_RecvProxy_Viewmodel;
                }
            }
        }
        pClass = pClass->m_pNext;
    }
}/*
Syn's AYYWAREFramework 2015
*/

// Credits to Valve and Shad0w
#pragma once

void ApplyAAAHooks();
#include "AutoWall.h"

#define    HITGROUP_GENERIC    0
#define    HITGROUP_HEAD        1
#define    HITGROUP_CHEST        2
#define    HITGROUP_STOMACH    3
#define HITGROUP_LEFTARM    4    
#define HITGROUP_RIGHTARM    5
#define HITGROUP_LEFTLEG    6
#define HITGROUP_RIGHTLEG    7
#define HITGROUP_GEAR        10

inline bool CGameTrace::DidHitWorld() const
{
        return m_pEnt->GetIndex() == 0;
}

inline bool CGameTrace::DidHitNonWorldEntity() const
{
        return m_pEnt != NULL && !DidHitWorld();
}

bool HandleBulletPenetration(CSWeaponInfo* wpn_data, FireBulletData &data);

float GetHitgroupDamageMult(int iHitGroup)
{
    switch (iHitGroup)
    {
        case HITGROUP_GENERIC:
            return 1.0f;

        case HITGROUP_HEAD:
            return 2.0f;

        case HITGROUP_CHEST:
            return 1.0f;

        case HITGROUP_STOMACH:
            return 1.0f;

        case HITGROUP_LEFTARM:
        case HITGROUP_RIGHTARM:
            return 1.0f;

        case HITGROUP_LEFTLEG:
        case HITGROUP_RIGHTLEG:
            return 1.0f;

        default:
            return 1.0f;
    }
}

void ScaleDamage(int hitgroup, IClientEntity* enemy, float weapon_armor_ratio, float ¤t_damage)
{
    current_damage *= GetHitgroupDamageMult(hitgroup);

    if (enemy->ArmorValue() > 0)
    {
        if (hitgroup == HITGROUP_HEAD)
        {
            if (enemy->HasHelmet())
                current_damage *= (weapon_armor_ratio * .5f);
        }
        else
        {
            current_damage *= (weapon_armor_ratio * .5f);
        }
    }
}

bool SimulateFireBullet(IClientEntity* local, CBaseCombatWeapon* weapon, FireBulletData &data)
{
    //Utils::ToLog("SimulateFireBullet");
    data.penetrate_count = 4;
    data.trace_length = 0.0f;
    auto* wpn_data = weapon->GetCSWpnData();

    data.current_damage = (float)wpn_data->m_iDamage;

    while ((data.penetrate_count > 0) && (data.current_damage >= 1.0f))
    {
        data.trace_length_remaining = wpn_data->m_flRange - data.trace_length;

        Vector end = data.src + data.direction * data.trace_length_remaining;

        UTIL_TraceLine(data.src, end, 0x4600400B, local, 0, &data.enter_trace);
        UTIL_ClipTraceToPlayers(data.src, end + data.direction * 40.f, 0x4600400B, &data.filter, &data.enter_trace);

        if (data.enter_trace.fraction == 1.0f)
            break;

        if ((data.enter_trace.hitgroup <= 7)
            && (data.enter_trace.hitgroup > 0)
            && (local->GetTeamNum() != data.enter_trace.m_pEnt->GetTeamNum())
            /*&& (DoesRayTouchHitbox(end, &data))*/)
        {
            data.trace_length += data.enter_trace.fraction * data.trace_length_remaining;
            data.current_damage *= pow(wpn_data->m_flRangeModifier, data.trace_length * 0.002);
            ScaleDamage(data.enter_trace.hitgroup, data.enter_trace.m_pEnt, wpn_data->m_flArmorRatio, data.current_damage);

            return true;
        }

        if (!HandleBulletPenetration(wpn_data, data))
            break;
    }

    return false;
}

bool HandleBulletPenetration(CSWeaponInfo* wpn_data, FireBulletData &data)
{
    surfacedata_t* enter_surface_data = Interfaces::PhysProps->GetSurfaceData(data.enter_trace.surface.surfaceProps);
    int enter_material = enter_surface_data->game.material;
    float enter_surf_penetration_mod = enter_surface_data->game.flPenetrationModifier;


    data.trace_length += data.enter_trace.fraction * data.trace_length_remaining;
    data.current_damage *= pow(wpn_data->m_flRangeModifier, (data.trace_length * 0.002));

    if ((data.trace_length > 3000.f) || (enter_surf_penetration_mod < 0.1f))
        data.penetrate_count = 0;

    if (data.penetrate_count <= 0)
        return false;

    Vector dummy;
    trace_t trace_exit;
    if (!TraceToExit(dummy, data.enter_trace, data.enter_trace.endpos, data.direction, &trace_exit))
        return false;

    surfacedata_t* exit_surface_data = Interfaces::PhysProps->GetSurfaceData(trace_exit.surface.surfaceProps);
    int exit_material = exit_surface_data->game.material;

    float exit_surf_penetration_mod = exit_surface_data->game.flPenetrationModifier;
    float final_damage_modifier = 0.16f;
    float combined_penetration_modifier = 0.0f;

    if (((data.enter_trace.contents & CONTENTS_GRATE) != 0) || (enter_material == 89) || (enter_material == 71))
    {
        combined_penetration_modifier = 3.0f;
        final_damage_modifier = 0.05f;
    }
    else
    {
        combined_penetration_modifier = (enter_surf_penetration_mod + exit_surf_penetration_mod) * 0.5f;
    }

    if (enter_material == exit_material)
    {
        if (exit_material == 87 || exit_material == 85)
            combined_penetration_modifier = 3.0f;
        else if (exit_material == 76)
            combined_penetration_modifier = 2.0f;
    }

    float v34 = fmaxf(0.f, 1.0f / combined_penetration_modifier);
    float v35 = (data.current_damage * final_damage_modifier) + v34 * 3.0f * fmaxf(0.0f, (3.0f / wpn_data->m_flPenetration) * 1.25f);
    float thickness = VectorLength(trace_exit.endpos - data.enter_trace.endpos);

    thickness *= thickness;
    thickness *= v34;
    thickness /= 24.0f;


    float lost_damage = fmaxf(0.0f, v35 + thickness);

    if (lost_damage > data.current_damage)
        return false;

    if (lost_damage >= 0.0f)
        data.current_damage -= lost_damage;

    if (data.current_damage < 1.0f)
        return false;

    data.src = trace_exit.endpos;
    data.penetrate_count--;

    return true;
}


/*
*    CanHit() - example of how to use the code
*     @in  point: target hitbox vector
*     @out damage_given: amount of damage the shot would do
*/
bool CanHit(const Vector &point, float* damage_given)
{
    auto* local = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    auto data = FireBulletData(local->GetOrigin() + local->GetViewOffset());
    data.filter = CTraceFilter();
    data.filter.pSkip = local;

    Vector angles;
    CalcAngle(data.src, point, angles);
    AngleVectors(angles, &data.direction);
    VectorNormalize(data.direction);

    if (SimulateFireBullet(local, (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle((HANDLE)local->GetActiveWeaponHandle()), data))
    {
        *damage_given = data.current_damage;
        return true;
    }

    return false;
}
#pragma once

# include "Hacks.h"

struct FireBulletData
{
    FireBulletData(const Vector &eye_pos):src(eye_pos)
    {
    }

    Vector src;
    trace_t enter_trace;
    Vector direction;
    CTraceFilter filter;
    float trace_length;
    float trace_length_remaining;
    float current_damage;
    int penetrate_count;
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"

class IBaseClientDLL
{
    public:

        ClientClass* GetAllClasses(void)
    {
        typedef ClientClass*(__thiscall * OriginalFn)(PVOID); //Anything inside a VTable is a __thiscall unless it completly disregards the thisptr. You can also call them as __stdcalls, but you won't have access to the __thisptr.
        return call_vfunc(this, Offsets::VMT::CHL_GetAllClasses)(this); //Return the pointer to the head CClientClass.
    }
};//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $Workfile:     $
// $Date:         $
// $NoKeywords: $
//=============================================================================//

#ifndef BSPFLAGS_H
#define BSPFLAGS_H

#ifdef _WIN32
#pragma once
#endif

// contents flags are seperate bits
// a given brush can contribute multiple content bits
// multiple brushes can be in a single leaf

// these definitions also need to be in q_shared.h!

// lower bits are stronger, and will eat weaker brushes completely
#define        CONTENTS_EMPTY                        0                // No contents

#define        CONTENTS_SOLID                        0x1                // an eye is never valid in a solid
#define        CONTENTS_WINDOW                        0x2                // translucent, but not watery (glass)
#define        CONTENTS_AUX                        0x4
#define        CONTENTS_GRATE                        0x8                // alpha-tested "grate" textures.  Bullets/sight pass through, but solids don't
#define        CONTENTS_SLIME                        0x10
#define        CONTENTS_WATER                        0x20
#define        CONTENTS_BLOCKLOS                0x40        // block AI line of sight
#define CONTENTS_OPAQUE                        0x80        // things that cannot be seen through (may be non-solid though)
#define        LAST_VISIBLE_CONTENTS        0x80

#define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1))

#define CONTENTS_TESTFOGVOLUME        0x100
#define CONTENTS_UNUSED                        0x200        

// unused 
// NOTE: If it's visible, grab from the top + update LAST_VISIBLE_CONTENTS
// if not visible, then grab from the bottom.
#define CONTENTS_UNUSED6                0x400

#define CONTENTS_TEAM1                        0x800        // per team contents used to differentiate collisions 
#define CONTENTS_TEAM2                        0x1000        // between players and objects on different teams

// ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW
#define CONTENTS_IGNORE_NODRAW_OPAQUE        0x2000

// hits entities which are MOVETYPE_PUSH (doors, plats, etc.)
#define CONTENTS_MOVEABLE                0x4000

// remaining contents are non-visible, and don't eat brushes
#define        CONTENTS_AREAPORTAL                0x8000

#define        CONTENTS_PLAYERCLIP                0x10000
#define        CONTENTS_MONSTERCLIP        0x20000

// currents can be added to any other contents, and may be mixed
#define        CONTENTS_CURRENT_0                0x40000
#define        CONTENTS_CURRENT_90                0x80000
#define        CONTENTS_CURRENT_180        0x100000
#define        CONTENTS_CURRENT_270        0x200000
#define        CONTENTS_CURRENT_UP                0x400000
#define        CONTENTS_CURRENT_DOWN        0x800000

#define        CONTENTS_ORIGIN                        0x1000000        // removed before bsping an entity

#define        CONTENTS_MONSTER                0x2000000        // should never be on a brush, only in game
#define        CONTENTS_DEBRIS                        0x4000000
#define        CONTENTS_DETAIL                        0x8000000        // brushes to be added after vis leafs
#define        CONTENTS_TRANSLUCENT        0x10000000        // auto set if any surface has trans
#define        CONTENTS_LADDER                        0x20000000
#define CONTENTS_HITBOX                        0x40000000        // use accurate hitboxes on trace


// NOTE: These are stored in a short in the engine now.  Don't use more than 16 bits
#define        SURF_LIGHT                0x0001                // value will hold the light strength
#define        SURF_SKY2D                0x0002                // don't draw, indicates we should skylight + draw 2d sky but not draw the 3D skybox
#define        SURF_SKY                0x0004                // don't draw, but add to skybox
#define        SURF_WARP                0x0008                // turbulent water warp
#define        SURF_TRANS                0x0010
#define SURF_NOPORTAL        0x0020        // the surface can not have a portal placed on it
#define        SURF_TRIGGER        0x0040        // FIXME: This is an xbox hack to work around elimination of trigger surfaces, which breaks occluders
#define        SURF_NODRAW                0x0080        // don't bother referencing the texture

#define        SURF_HINT                0x0100        // make a primary bsp splitter

#define        SURF_SKIP                0x0200        // completely ignore, allowing non-closed brushes
#define SURF_NOLIGHT        0x0400        // Don't calculate light
#define SURF_BUMPLIGHT        0x0800        // calculate three lightmaps for the surface for bumpmapping
#define SURF_NOSHADOWS        0x1000        // Don't receive shadows
#define SURF_NODECALS        0x2000        // Don't receive decals
#define SURF_NOCHOP                0x4000        // Don't subdivide patches on this surface 
#define SURF_HITBOX                0x8000        // surface is part of a hitbox



// -----------------------------------------------------
// spatial content masks - used for spatial queries (traceline,etc.)
// -----------------------------------------------------
#define        MASK_ALL                                        (0xFFFFFFFF)
// everything that is normally solid
#define        MASK_SOLID                                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)
// everything that blocks player movement
#define        MASK_PLAYERSOLID                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)
// blocks npc movement
#define        MASK_NPCSOLID                                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)
// water physics in these contents
#define        MASK_WATER                                        (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME)
// everything that blocks lighting
#define        MASK_OPAQUE                                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE)
// everything that blocks lighting, but with monsters added.
#define MASK_OPAQUE_AND_NPCS                (MASK_OPAQUE|CONTENTS_MONSTER)
// everything that blocks line of sight for AI
#define MASK_BLOCKLOS                                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_BLOCKLOS)
// everything that blocks line of sight for AI plus NPCs
#define MASK_BLOCKLOS_AND_NPCS                (MASK_BLOCKLOS|CONTENTS_MONSTER)
// everything that blocks line of sight for players
#define        MASK_VISIBLE                                        (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE)
// everything that blocks line of sight for players, but with monsters added.
#define MASK_VISIBLE_AND_NPCS                (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE)
// bullets see these as solid
#define        MASK_SHOT                                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX)
// non-raycasted weapons see this as solid (includes grates)
#define MASK_SHOT_HULL                                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE)
// hits solids (not grates) and passes through everything else
#define MASK_SHOT_PORTAL                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER)
// everything normally solid, except monsters (world+brush only)
#define MASK_SOLID_BRUSHONLY                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE)
// everything normally solid for player movement, except monsters (world+brush only)
#define MASK_PLAYERSOLID_BRUSHONLY        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE)
// everything normally solid for npc movement, except monsters (world+brush only)
#define MASK_NPCSOLID_BRUSHONLY                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE)
// just the world, used for route rebuilding
#define MASK_NPCWORLDSTATIC                        (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE)
// These are things that can split areaportals
#define MASK_SPLITAREAPORTAL                (CONTENTS_WATER|CONTENTS_SLIME)

// UNDONE: This is untested, any moving water
#define MASK_CURRENT                                (CONTENTS_CURRENT_0|CONTENTS_CURRENT_90|CONTENTS_CURRENT_180|CONTENTS_CURRENT_270|CONTENTS_CURRENT_UP|CONTENTS_CURRENT_DOWN)

// everything that blocks corpse movement
// UNDONE: Not used yet / may be deleted
#define        MASK_DEADSOLID                                (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_GRATE)

#endif // BSPFLAGS_H

bool CanHit(const Vector &point, float* damage_given);

#include "Chams.h"
#include "offsets.h"
#include "SDK.h"
#include "Interfaces.h"

void InitKeyValues(KeyValues* keyValues, char* name)
{
    DWORD dwFunction = (DWORD)Offsets::Functions::KeyValues_KeyValues;
    __asm

    {
        push name

            mov ecx, keyValues

            call dwFunction

    }
}

void LoadFromBuffer(KeyValues* keyValues, char const *resourceName, const char* pBuffer)
{
    DWORD dwFunction = (DWORD)Offsets::Functions::KeyValues_LoadFromBuffer;

    __asm

    {
        push 0

            push 0

            push 0

            push pBuffer

            push resourceName

            mov ecx, keyValues

            call dwFunction

    }
}

IMaterial* CreateMaterial(bool shouldIgnoreZ, bool isLit, bool isWireframe) //credits to ph0ne
{
    static int created = 0;

    static const char tmp[] =
    {
        "\"%s\"\
                \n{\
                \n\t\"$basetexture\" \"vgui/white_additive\"\
                \n\t\"$envmap\" \"\"\
                \n\t\"$model\" \"1\"\
                \n\t\"$flat\" \"1\"\
                \n\t\"$nocull\" \"0\"\
                \n\t\"$selfillum\" \"1\"\
                \n\t\"$halflambert\" \"1\"\
                \n\t\"$nofog\" \"0\"\
                \n\t\"$ignorez\" \"%i\"\
                \n\t\"$znearer\" \"0\"\
                \n\t\"$wireframe\" \"%i\"\
        \n}\n"
    };

    char* baseType = (isLit == true ? "VertexLitGeneric" : "UnlitGeneric");
    char material[512];
    sprintf_s(material, sizeof(material), tmp, baseType, (shouldIgnoreZ) ? 1 : 0, (isWireframe) ? 1 : 0);

    char name[512];
    sprintf_s(name, sizeof(name), "#ayy_meme_%i.vmt", created);
    ++created;

    KeyValues* keyValues = (KeyValues*)malloc(sizeof(KeyValues));
    InitKeyValues(keyValues, baseType);
    LoadFromBuffer(keyValues, name, material);

    IMaterial* createdMaterial = Interfaces::MaterialSystem->CreateMaterial(name, keyValues);
    createdMaterial->IncrementReferenceCount();

    return createdMaterial;
}

void ForceMaterial(Color color, IMaterial* material, bool useColor, bool forceMaterial)
{
    if (useColor)
    {
        float temp[3] =
        {
            color.r(),
            color.g(),
            color.b()
        };

        temp[0] /= 255.f;
        temp[1] /= 255.f;
        temp[2] /= 255.f;


        float alpha = color.a();

        Interfaces::RenderView->SetBlend(1.0f);
        Interfaces::RenderView->SetColorModulation(temp);
    }

    if (forceMaterial)
        Interfaces::ModelRender->ForcedMaterialOverride(material);
    else
        Interfaces::ModelRender->ForcedMaterialOverride(NULL);

}/*
Syn's AYYWAREFramework 2015
*/

#pragma once
#include "SDK.h"

void InitKeyValues(KeyValues* keyValues, char* name);

void LoadFromBuffer(KeyValues* keyValues, char const *resourceName, const char* pBuffer);

void ForceMaterial(Color color, IMaterial* material, bool useColor = true, bool forceMaterial = true);

IMaterial* CreateMaterial(bool shouldIgnoreZ, bool isLit = true, bool isWireframe = false);
/*
Syn's AYYWAREFramework 2015
*/

// Credits to Valve and Shad0w

#pragma once

struct RecvProp;

class DVariant
{
    public:
        union
        {
                float m_Float;
    long m_Int;
    char* m_pString;
    void* m_pData;
    float m_Vector[3];
};
};

class CRecvProxyData
{
    public:
        const RecvProp* m_pRecvProp;
    char _pad[4];//csgo ( for l4d keep it commented out :) )
    DVariant m_Value;
    int m_iElement;
    int m_ObjectID;
};

typedef void(* RecvVarProxyFn)(const CRecvProxyData* pData, void* pStruct, void* pOut);

struct RecvTable
{
    RecvProp* m_pProps;
    int m_nProps;
    void* m_pDecoder;
    char* m_pNetTableName;
    bool m_bInitialized;
    bool m_bInMainList;
};

struct RecvProp
{
    char* m_pVarName;
    int m_RecvType;
    int m_Flags;
    int m_StringBufferSize;
    bool m_bInsideArray;
    const void* m_pExtraData;
    RecvProp* m_pArrayProp;
    void* m_ArrayLengthProxy;
    void* m_ProxyFn;
    void* m_DataTableProxyFn;
    RecvTable* m_pDataTable;
    int m_Offset;
    int m_ElementStride;
    int m_nElements;
    const char* m_pParentArrayPropName;
};

class ClientClass
{
    public:
        void* m_pCreateFn;
    void* m_pCreateEventFn;
    char* m_pNetworkName;
    RecvTable* m_pRecvTable;
    ClientClass* m_pNext;
    int m_ClassID;
};
#pragma once
#define _WINSOCKAPI_

// Includes
# include 
# include 
# include 
# include 
# include 
# include 
# include 
#pragma once
#define _WINSOCKAPI_

// Includes
# include 
# include 
# include 
# include 
# include 
# include 
# include 
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

# include "GUI.h"

class CCheckBox : public CControl
{
public:

    CCheckBox();
void SetState(bool s);
bool GetState();
protected:
        bool Checked;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CLabel : public CControl
{
public:

    CLabel();
void SetText(std::string text);
protected:
        std::string Text;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CGroupBox : public CControl
{
public:

    CGroupBox();
void SetText(std::string text);
void PlaceLabledControl(std::string Label, CTab* Tab, CControl* control);
protected:
        int Items;
std::string Text;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CSlider : public CControl
{
public:

    CSlider();
float GetValue();
void SetValue(float v);
void SetBoundaries(float min, float max);
protected:
        float Value;
float Min;
float Max;
bool DoDrag;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CKeyBind : public CControl
{
public:

    CKeyBind();
int GetKey();
void SetKey(int key);
protected:
        int Key;
bool IsGettingKey;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CButton : public CControl
{
public:
        typedef void(* ButtonCallback_t)(void);

    CButton();
void SetCallback(ButtonCallback_t callback);
void SetText(std::string text);
protected:
        ButtonCallback_t CallBack;
std::string Text;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CComboBox : public CControl
{
public:

    CComboBox();
void AddItem(std::string text);
void SelectIndex(int idx);
int GetIndex();
std::string GetItem();
protected:
        std::vector Items;
int SelectedIndex;
bool IsOpen;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};/*
Syn's AYYWAREFramework 2015
*/

#include "CRC32.h"

unsigned int uiCRC32_Table[256] = {
    0x00000000L, 0x77073096L, 0xEE0E612CL,
    0x990951BAL, 0x076DC419L, 0x706AF48FL,
    0xE963A535L, 0x9E6495A3L, 0x0EDB8832L,
    0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
    0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L,
    0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L,
    0xF3B97148L, 0x84BE41DEL, 0x1ADAD47DL,
    0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
    0x136C9856L, 0x646BA8C0L, 0xFD62F97AL,
    0x8A65C9ECL, 0x14015C4FL, 0x63066CD9L,
    0xFA0F3D63L, 0x8D080DF5L, 0x3B6E20C8L,
    0x4C69105EL, 0xD56041E4L, 0xA2677172L,
    0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL,
    0xA50AB56BL, 0x35B5A8FAL, 0x42B2986CL,
    0xDBBBC9D6L, 0xACBCF940L, 0x32D86CE3L,
    0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
    0x26D930ACL, 0x51DE003AL, 0xC8D75180L,
    0xBFD06116L, 0x21B4F4B5L, 0x56B3C423L,
    0xCFBA9599L, 0xB8BDA50FL, 0x2802B89EL,
    0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
    0x2F6F7C87L, 0x58684C11L, 0xC1611DABL,
    0xB6662D3DL, 0x76DC4190L, 0x01DB7106L,
    0x98D220BCL, 0xEFD5102AL, 0x71B18589L,
    0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
    0x7807C9A2L, 0x0F00F934L, 0x9609A88EL,
    0xE10E9818L, 0x7F6A0DBBL, 0x086D3D2DL,
    0x91646C97L, 0xE6635C01L, 0x6B6B51F4L,
    0x1C6C6162L, 0x856530D8L, 0xF262004EL,
    0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L,
    0xF50FC457L, 0x65B0D9C6L, 0x12B7E950L,
    0x8BBEB8EAL, 0xFCB9887CL, 0x62DD1DDFL,
    0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
    0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L,
    0xD4BB30E2L, 0x4ADFA541L, 0x3DD895D7L,
    0xA4D1C46DL, 0xD3D6F4FBL, 0x4369E96AL,
    0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
    0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL,
    0xDD0D7CC9L, 0x5005713CL, 0x270241AAL,
    0xBE0B1010L, 0xC90C2086L, 0x5768B525L,
    0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
    0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L,
    0xC7D7A8B4L, 0x59B33D17L, 0x2EB40D81L,
    0xB7BD5C3BL, 0xC0BA6CADL, 0xEDB88320L,
    0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
    0xEAD54739L, 0x9DD277AFL, 0x04DB2615L,
    0x73DC1683L, 0xE3630B12L, 0x94643B84L,
    0x0D6D6A3EL, 0x7A6A5AA8L, 0xE40ECF0BL,
    0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
    0xF00F9344L, 0x8708A3D2L, 0x1E01F268L,
    0x6906C2FEL, 0xF762575DL, 0x806567CBL,
    0x196C3671L, 0x6E6B06E7L, 0xFED41B76L,
    0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
    0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L,
    0x60B08ED5L, 0xD6D6A3E8L, 0xA1D1937EL,
    0x38D8C2C4L, 0x4FDFF252L, 0xD1BB67F1L,
    0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
    0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L,
    0x41047A60L, 0xDF60EFC3L, 0xA867DF55L,
    0x316E8EEFL, 0x4669BE79L, 0xCB61B38CL,
    0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
    0xCC0C7795L, 0xBB0B4703L, 0x220216B9L,
    0x5505262FL, 0xC5BA3BBEL, 0xB2BD0B28L,
    0x2BB45A92L, 0x5CB36A04L, 0xC2D7FFA7L,
    0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
    0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL,
    0x026D930AL, 0x9C0906A9L, 0xEB0E363FL,
    0x72076785L, 0x05005713L, 0x95BF4A82L,
    0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
    0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L,
    0x0BDBDF21L, 0x86D3D2D4L, 0xF1D4E242L,
    0x68DDB3F8L, 0x1FDA836EL, 0x81BE16CDL,
    0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
    0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL,
    0x11010B5CL, 0x8F659EFFL, 0xF862AE69L,
    0x616BFFD3L, 0x166CCF45L, 0xA00AE278L,
    0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
    0xA7672661L, 0xD06016F7L, 0x4969474DL,
    0x3E6E77DBL, 0xAED16A4AL, 0xD9D65ADCL,
    0x40DF0B66L, 0x37D83BF0L, 0xA9BCAE53L,
    0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
    0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L,
    0x24B4A3A6L, 0xBAD03605L, 0xCDD70693L,
    0x54DE5729L, 0x23D967BFL, 0xB3667A2EL,
    0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
    0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL,
    0x2D02EF8DL };

unsigned int CRC32(void* pData, size_t iLen)
{
    unsigned int uiCRC32 = 0xFFFFFFFF;
    unsigned char* pszData = (unsigned char*)pData;

    for (size_t i = 0; i < iLen; ++i)
        uiCRC32 = ((uiCRC32 >> 8) & 0x00FFFFFF) ^ uiCRC32_Table[(uiCRC32 ^ (unsigned int)*pszData++) &0xFF];

    return (uiCRC32 ^ 0xFFFFFFFF);
}/*
Syn's AYYWAREFramework 2015
*/

// Credits Valve / Shad0w

#pragma once

unsigned int CRC32(void* pData, size_t iLen);
/*
Syn's AYYWAREFramework 2015
*/

#include "Utilities.h"

// Stuff to initialise
#include "Offsets.h"
#include "Interfaces.h"
#include "Hooks.h"
#include "RenderManager.h"
#include "Hacks.h"
#include "Menu.h"
#include "AntiAntiAim.h"

#include "Dumping.h"

bool DoUnload;

HINSTANCE HThisModule;

// Our thread we use to setup everything we need
// Everything appart from code in hooks get's called from inside 
// here.

int InitialThread(LPVOID lpArguments)
{
    Utilities::OpenConsole("Cebula.dll");

    //---------------------------------------------------------
    // Initialise all our shit

    Offsets::Initialise(); // Set our VMT offsets and do any pattern scans
    Interfaces::Initialise(); // Get pointers to the valve classes
    NetVar.RetrieveClasses(); // Setup our NetVar manager (thanks shad0w bby)
    Render::Initialise();
    Hacks::SetupHacks();
    Menu::SetupMenu();
    Hooks::Initialise();
    ApplyAAAHooks();
    // Dumping
    //Dump::DumpClassIds();

    //---------------------------------------------------------
    Utilities::Log("Ready");

    // While our cheat is running
    while (DoUnload == false)
    {
        Sleep(1000);
    }

    Hooks::UndoHooks();
    Sleep(2000); // Make sure none of our hooks are running
    FreeLibraryAndExitThread(HThisModule, 0);

    return 0;
}

// DllMain
// Entry point for our module
bool _stdcall DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)InitialThread, NULL, NULL, NULL);
    }
    return true;
}
#include "Dumping.h"

#define DUMPIDTOFILE

void Dump::DumpClassIds()
{
# ifdef DUMPIDTOFILE
    Utilities::EnableLogFile("ClassID.txt");
#endif
    ClientClass* cClass = Interfaces::Client->GetAllClasses();
    while (cClass)
    {
        Utilities::Log("%s = %d,", cClass->m_pNetworkName, cClass->m_ClassID);
        cClass = cClass->m_pNext;
    }
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Interfaces.h"
#include "Utilities.h"

namespace Dump
{
    void DumpClassIds();
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"

// EngineClient
class IVEngineClient
{
    public:
        void GetScreenSize(int& width, int& height)
    {
        typedef void(__thiscall * oGetScreenSize)(PVOID, int &, int &);
        return call_vfunc(this, Offsets::VMT::Engine_GetScreenSize)(this, width, height);
    }
    bool GetPlayerInfo(int ent_num, player_info_t* pinfo)
    {
        typedef bool(__thiscall * oGetPlayerInfo)(PVOID, int, player_info_t *);
        return call_vfunc(this, Offsets::VMT::Engine_GetPlayerInfo)(this, ent_num, pinfo);
    }
    int GetLocalPlayer()
    {
        typedef int(__thiscall * oLocal)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_GetLocalPlayer)(this);
    }
    float Time()
    {
        typedef float(__thiscall * oTime)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_Time)(this);
    }
    void GetViewAngles(Vector& vAngles)
    {
        typedef void(__thiscall * oSetViewAngles)(PVOID, Vector &);
        return call_vfunc(this, Offsets::VMT::Engine_GetViewAngles)(this, vAngles);
    }
    void SetViewAngles(Vector& vAngles)
    {
        typedef void(__thiscall * oSetViewAngles)(PVOID, Vector &);
        return call_vfunc(this, Offsets::VMT::Engine_SetViewAngles)(this, vAngles);
    }
    int GetMaxClients()
    {
        typedef bool(__thiscall * oGetMaxClients)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_GetMaxClients)(this);
    }
    bool IsConnected()
    {
        typedef bool(__thiscall * oGetScreenSize)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_IsConnected)(this);
    }
    bool IsInGame()
    {
        typedef bool(__thiscall * oLocal)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_IsInGame)(this);
    }
    const matrix3x4& WorldToScreenMatrix()
    {
        typedef const matrix3x4&(__thiscall * oWorldToScreenMatrix)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_WorldToScreenMatrix)(this);
    }
    void ClientCmd_Unrestricted(char  const* cmd)
        {

        typedef void(__thiscall* oClientCmdUnres)(PVOID, const char*);
                return call_vfunc(this, Offsets::VMT::Engine_ClientCmd_Unrestricted)(this, cmd);
        }
};/*
Syn's AyyWare Framework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"

#define TEAM_CS_T 2
#define TEAM_CS_CT 3

#define BONE_USED_BY_HITBOX                        0x00000100

class IClientRenderable;
class IClientNetworkable;
class IClientUnknown;
class IClientThinkable;
class IClientEntity;
class CSWeaponInfo;

class CSWeaponInfo
{
    public:
        virtual void Function0(); //
    virtual void Function1(); //
    virtual void Parse(KeyValues* pKeyValuesData, const char* szWeaponName); //
    virtual void RefreshDynamicParameters(void); //
    virtual void Function4(); //
    virtual void Function5(); //
    virtual void Function6(); //
    virtual void Function7(); //
    virtual void Function8(); //

    char pad_0x0004[0x2]; //0x0004
    char m_pszName[32]; //0x0006 
    char pad_0x0026[0x7E]; //0x0026
    __int16 N0000002E; //0x00A4 
    char m_pszModelName[32]; //0x00A6 
    char pad_0x00C6[0x6DE]; //0x00C6
    BYTE m_IsFullAuto; //0x07A4 
    char pad_0x07A5[0x7]; //0x07A5
    __int32 m_iPrice; //0x07AC 
    float m_flArmorRatio; //0x07B0 
    char pad_0x07B4[0x10]; //0x07B4
    float m_flPenetration; //0x07C4 
    __int32 m_iDamage; //0x07C8 
    float m_flRange; //0x07CC 
    float m_flRangeModifier; //0x07D0 
    char pad_0x07D4[0x4]; //0x07D4
    float m_flCycleTime; //0x07D8 

};

enum class CSGOClassID
{
    CTestTraceline = 189,
        CTEWorldDecal = 190,
        CTESpriteSpray = 187,
        CTESprite = 186,
        CTESparks = 185,
        CTESmoke = 184,
        CTEShowLine = 182,
        CTEProjectedDecal = 179,
        CTEPlayerDecal = 178,
        CTEPhysicsProp = 175,
        CTEParticleSystem = 174,
        CTEMuzzleFlash = 173,
        CTELargeFunnel = 171,
        CTEKillPlayerAttachments = 170,
        CTEImpact = 169,
        CTEGlowSprite = 168,
        CTEShatterSurface = 181,
        CTEFootprintDecal = 165,
        CTEFizz = 164,
        CTEExplosion = 162,
        CTEEnergySplash = 161,
        CTEEffectDispatch = 160,
        CTEDynamicLight = 159,
        CTEDecal = 157,
        CTEClientProjectile = 156,
        CTEBubbleTrail = 155,
        CTEBubbles = 154,
        CTEBSPDecal = 153,
        CTEBreakModel = 152,
        CTEBloodStream = 151,
        CTEBloodSprite = 150,
        CTEBeamSpline = 149,
        CTEBeamRingPoint = 148,
        CTEBeamRing = 147,
        CTEBeamPoints = 146,
        CTEBeamLaser = 145,
        CTEBeamFollow = 144,
        CTEBeamEnts = 143,
        CTEBeamEntPoint = 142,
        CTEBaseBeam = 141,
        CTEArmorRicochet = 140,
        CTEMetalSparks = 172,
        CSteamJet = 135,
        CSmokeStack = 128,
        DustTrail = 238,
        CFireTrail = 62,
        SporeTrail = 244,
        SporeExplosion = 243,
        RocketTrail = 241,
        SmokeTrail = 242,
        CPropVehicleDriveable = 117,
        ParticleSmokeGrenade = 240,
        CParticleFire = 96,
        MovieExplosion = 239,
        CTEGaussExplosion = 167,
        CEnvQuadraticBeam = 55,
        CEmbers = 45,
        CEnvWind = 59,
        CPrecipitation = 111,
        CPrecipitationBlocker = 112,
        CBaseTempEntity = 18,
        NextBotCombatCharacter = 0,
        CBaseAttributableItem = 4,
        CEconEntity = 44,
        CWeaponXM1014 = 236,
        CWeaponTaser = 231,
        CSmokeGrenade = 126,
        CWeaponSG552 = 228,
        CWeaponSawedoff = 224,
        CWeaponNOVA = 220,
        CIncendiaryGrenade = 85,
        CMolotovGrenade = 93,
        CWeaponM3 = 212,
        CKnifeGG = 90,
        CKnife = 89,
        CHEGrenade = 82,
        CFlashbang = 64,
        CWeaponElite = 203,
        CDecoyGrenade = 40,
        CDEagle = 39,
        CWeaponUSP = 235,
        CWeaponM249 = 211,
        CWeaponUMP45 = 234,
        CWeaponTMP = 233,
        CWeaponTec9 = 232,
        CWeaponSSG08 = 230,
        CWeaponSG556 = 229,
        CWeaponSG550 = 227,
        CWeaponScout = 226,
        CWeaponSCAR20 = 225,
        CSCAR17 = 122,
        CWeaponP90 = 223,
        CWeaponP250 = 222,
        CWeaponP228 = 221,
        CWeaponNegev = 219,
        CWeaponMP9 = 218,
        CWeaponMP7 = 217,
        CWeaponMP5Navy = 216,
        CWeaponMag7 = 215,
        CWeaponMAC10 = 214,
        CWeaponM4A1 = 213,
        CWeaponHKP2000 = 210,
        CWeaponGlock = 209,
        CWeaponGalilAR = 208,
        CWeaponGalil = 207,
        CWeaponG3SG1 = 206,
        CWeaponFiveSeven = 205,
        CWeaponFamas = 204,
        CWeaponBizon = 199,
        CWeaponAWP = 198,
        CWeaponAug = 197,
        CAK47 = 1,
        CWeaponCSBaseGun = 201,
        CWeaponCSBase = 200,
        CC4 = 29,
        CBaseCSGrenade = 8,
        CSmokeGrenadeProjectile = 127,
        CMolotovProjectile = 94,
        CDecoyProjectile = 41,
        CFireCrackerBlast = 60,
        CInferno = 86,
        CChicken = 31,
        CFootstepControl = 66,
        CCSGameRulesProxy = 34,
        CWeaponCubemap = 0,
        CWeaponCycler = 202,
        CTEPlantBomb = 176,
        CTEFireBullets = 163,
        CTERadioIcon = 180,
        CPlantedC4 = 104,
        CCSTeam = 38,
        CCSPlayerResource = 36,
        CCSPlayer = 35,
        CCSRagdoll = 37,
        CTEPlayerAnimEvent = 177,
        CHostage = 83,
        CHostageCarriableProp = 84,
        CBaseCSGrenadeProjectile = 9,
        CHandleTest = 81,
        CTeamplayRoundBasedRulesProxy = 139,
        CSpriteTrail = 133,
        CSpriteOriented = 132,
        CSprite = 131,
        CRagdollPropAttached = 120,
        CRagdollProp = 119,
        CPredictedViewModel = 113,
        CPoseController = 109,
        CGameRulesProxy = 80,
        CInfoLadderDismount = 87,
        CFuncLadder = 72,
        CTEFoundryHelpers = 166,
        CEnvDetailController = 51,
        CWorld = 237,
        CWaterLODControl = 196,
        CWaterBullet = 195,
        CVoteController = 194,
        CVGuiScreen = 193,
        CPropJeep = 116,
        CPropVehicleChoreoGeneric = 0,
        CTriggerSoundOperator = 192,
        CBaseVPhysicsTrigger = 22,
        CTriggerPlayerMovement = 191,
        CBaseTrigger = 20,
        CTest_ProxyToggle_Networkable = 188,
        CTesla = 183,
        CBaseTeamObjectiveResource = 17,
        CTeam = 138,
        CSunlightShadowControl = 137,
        CSun = 136,
        CParticlePerformanceMonitor = 97,
        CSpotlightEnd = 130,
        CSpatialEntity = 129,
        CSlideshowDisplay = 125,
        CShadowControl = 124,
        CSceneEntity = 123,
        CRopeKeyframe = 121,
        CRagdollManager = 118,
        CPhysicsPropMultiplayer = 102,
        CPhysBoxMultiplayer = 100,
        CPropDoorRotating = 115,
        CBasePropDoor = 16,
        CDynamicProp = 43,
        CProp_Hallucination = 114,
        CPostProcessController = 110,
        CPointCommentaryNode = 108,
        CPointCamera = 107,
        CPlayerResource = 106,
        CPlasma = 105,
        CPhysMagnet = 103,
        CPhysicsProp = 101,
        CStatueProp = 134,
        CPhysBox = 99,
        CParticleSystem = 98,
        CMovieDisplay = 95,
        CMaterialModifyControl = 92,
        CLightGlow = 91,
        CInfoOverlayAccessor = 88,
        CFuncTrackTrain = 79,
        CFuncSmokeVolume = 78,
        CFuncRotating = 77,
        CFuncReflectiveGlass = 76,
        CFuncOccluder = 75,
        CFuncMoveLinear = 74,
        CFuncMonitor = 73,
        CFunc_LOD = 68,
        CTEDust = 158,
        CFunc_Dust = 67,
        CFuncConveyor = 71,
        CFuncBrush = 70,
        CBreakableSurface = 28,
        CFuncAreaPortalWindow = 69,
        CFish = 63,
        CFireSmoke = 61,
        CEnvTonemapController = 58,
        CEnvScreenEffect = 56,
        CEnvScreenOverlay = 57,
        CEnvProjectedTexture = 54,
        CEnvParticleScript = 53,
        CFogController = 65,
        CEnvDOFController = 52,
        CCascadeLight = 30,
        CEnvAmbientLight = 50,
        CEntityParticleTrail = 49,
        CEntityFreezing = 48,
        CEntityFlame = 47,
        CEntityDissolve = 46,
        CDynamicLight = 42,
        CColorCorrectionVolume = 33,
        CColorCorrection = 32,
        CBreakableProp = 27,
        CBeamSpotlight = 25,
        CBaseButton = 5,
        CBaseToggle = 19,
        CBasePlayer = 15,
        CBaseFlex = 12,
        CBaseEntity = 11,
        CBaseDoor = 10,
        CBaseCombatCharacter = 6,
        CBaseAnimatingOverlay = 3,
        CBoneFollower = 26,
        CBaseAnimating = 2,
        CAI_BaseNPC = 0,
        CBeam = 24,
        CBaseViewModel = 21,
        CBaseParticleEntity = 14,
        CBaseGrenade = 13,
        CBaseCombatWeapon = 7,
        CBaseWeaponWorldModel = 23
};

enum class CSGOHitboxID
{
    Head = 0,
        Neck,
        NeckLower,
        Pelvis,
        Stomach,
        LowerChest,
        Chest,
        UpperChest,
        RightThigh,
        LeftThigh,
        RightShin,
        LeftShin,
        RightFoot,
        LeftFoot,
        RightHand,
        LeftHand,
        RightUpperArm,
        RightLowerArm,
        LeftUpperArm,
        LeftLowerArm
};

class ScriptCreatedItem
{
    public:

    CPNETVAR_FUNC(int*, ItemDefinitionIndex, 0xE67AB3B8); //m_iItemDefinitionIndex

    CPNETVAR_FUNC(int*, ItemIDHigh, 0x714778A); //m_iItemIDHigh

    CPNETVAR_FUNC(int*, ItemIDLow, 0x3A3DFC74); //m_iItemIDLow
};

class AttributeContainer
{
    public:

    CPNETVAR_FUNC(ScriptCreatedItem*, m_Item, 0x7E029CE5);
};


class CBaseCombatWeapon
{
    public:

    CNETVAR_FUNC(float, GetNextPrimaryAttack, 0xDB7B106E); //m_flNextPrimaryAttack

    CNETVAR_FUNC(int, GetAmmoInClip, 0x97B6F70C); //m_iClip1

    CNETVAR_FUNC(HANDLE, GetOwnerHandle, 0xC32DF98D); //m_hOwner

    CNETVAR_FUNC(Vector, GetOrigin, 0x1231CE10); //m_vecOrigin


    CPNETVAR_FUNC(int*, FallbackPaintKit, 0xADE4C870); // m_nFallbackPaintKit

    CPNETVAR_FUNC(int*, FallbackSeed, 0xC2D0683D); // m_nFallbackSeed

    CPNETVAR_FUNC(float*, FallbackWear, 0xA263576C); //m_flFallbackWear

    CPNETVAR_FUNC(int*, FallbackStatTrak, 0x1ED78768); //m_nFallbackStatTrak

    CPNETVAR_FUNC(int*, OwnerXuidLow, 0xAD8D897F);

    CPNETVAR_FUNC(int*, OwnerXuidHigh, 0x90511E77);

    CPNETVAR_FUNC(int*, ViewModelIndex, 0x7F7C89C1);

    CPNETVAR_FUNC(int*, WorldModelIndex, 0x4D8AD9F3);


    CPNETVAR_FUNC(AttributeContainer*, m_AttributeManager, 0xCFFCE089);

    float GetInaccuracy()
    {
        typedef float(__thiscall * oGetSpread)(PVOID);
        return call_vfunc(this, Offsets::VMT::Weapon_GetSpread)(this);
    }

    float GetSpread()
    {
        typedef float(__thiscall * oGetInac)(PVOID);
        return call_vfunc(this, Offsets::VMT::Weapon_GetSpread + 1)(this);
    }

    void UpdateAccuracyPenalty()
    {
        typedef void(__thiscall * oUpdateAccuracyPenalty)(PVOID);
        return call_vfunc(this, Offsets::VMT::Weapon_GetSpread + 2)(this);
    }

    CSWeaponInfo* GetCSWpnData()
    {
        static DWORD GetCSWpnDataAddr = Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x55\x8B\xEC\x81\xEC\x00\x00\x00\x00\xB8\x00\x00\x00\x00\x57", "xxxxx????x????x");
        if (GetCSWpnDataAddr)
        {
            CSWeaponInfo* retData;
            __asm

            {
                mov ecx, this

                    call GetCSWpnDataAddr

                    mov retData, eax

            }
            return retData;
        }
        else
        {
            return nullptr;
        }
    }
};

class CCSBomb
{
    public:

    CNETVAR_FUNC(HANDLE, GetOwnerHandle, 0xC32DF98D); //m_hOwner

    CNETVAR_FUNC(float, GetC4BlowTime, 0xB5E0CA1C); //m_flC4Blow

    CNETVAR_FUNC(float, GetC4DefuseCountDown, 0xB959B4A6); //m_flDefuseCountDown
};

class CLocalPlayerExclusive
{
    public:

    CNETVAR_FUNC(Vector, GetViewPunchAngle, 0x68F014C0);//m_viewPunchAngle

    CNETVAR_FUNC(Vector, GetAimPunchAngle, 0xBF25C290);//m_aimPunchAngle

    CNETVAR_FUNC(Vector, GetAimPunchAngleVel, 0x8425E045);//m_aimPunchAngleVel
};

class CollisionProperty
{
    public:

    CNETVAR_FUNC(Vector, GetMins, 0xF6F78BAB);//m_vecMins

    CNETVAR_FUNC(Vector, GetMaxs, 0xE47C6FC4);//m_vecMaxs

    CNETVAR_FUNC(unsigned char, GetSolidType, 0xB86722A1);//m_nSolidType

    CNETVAR_FUNC(unsigned short, GetSolidFlags, 0x63BB24C1);//m_usSolidFlags

    CNETVAR_FUNC(int, GetSurroundsType, 0xB677A0BB); //m_nSurroundType

    bool IsSolid()
    {
        return (GetSolidType() != SOLID_NONE) && ((GetSolidFlags() & FSOLID_NOT_SOLID) == 0);
    }
};

class IClientRenderable
{
    public:
        //virtual void*                                        GetIClientUnknown() = 0;
        virtual Vector const&                        GetRenderOrigin(void) = 0;
        virtual Vector const&                        GetRenderAngles(void) = 0;
        virtual bool ShouldDraw(void) = 0;
        virtual bool IsTransparent(void) = 0;
        virtual bool UsesPowerOfTwoFrameBufferTexture() = 0;
        virtual bool UsesFullFrameBufferTexture() = 0;
        virtual void GetShadowHandle() const = 0;
    virtual void* RenderHandle() = 0;
        virtual const model_t* GetModel() const = 0;
    virtual int DrawModel(int flags) = 0;
        virtual int GetBody() = 0;
        virtual void ComputeFxBlend() = 0;

        bool SetupBones(matrix3x4* pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime)
    {
        typedef bool(__thiscall * oSetupBones)(PVOID, matrix3x4 *, int, int, float);
        return call_vfunc(this, 13)(this, pBoneToWorldOut, nMaxBones, boneMask, currentTime);
    }
};

class IClientNetworkable
{
    public:
        virtual IClientUnknown* GetIClientUnknown() = 0;
        virtual void Release() = 0;
        virtual ClientClass* GetClientClass() = 0;// FOR NETVARS FIND YOURSELF ClientClass* stuffs
        virtual void NotifyShouldTransmit( /* ShouldTransmitState_t state*/) = 0;
        virtual void OnPreDataChanged( /*DataUpdateType_t updateType*/) = 0;
        virtual void OnDataChanged( /*DataUpdateType_t updateType*/) = 0;
        virtual void PreDataUpdate( /*DataUpdateType_t updateType*/) = 0;
        virtual void PostDataUpdate( /*DataUpdateType_t updateType*/) = 0;
        virtual void unknown();
    virtual bool IsDormant(void) = 0;
        virtual int GetIndex(void) const = 0;
    virtual void ReceiveMessage(int classID /*, bf_read &msg*/) = 0;
        virtual void* GetDataTableBasePtr() = 0;
        virtual void SetDestroyedOnRecreateEntities(void) = 0;
};

class IClientUnknown
{
    public:
        virtual void* GetCollideable() = 0;
        virtual IClientNetworkable* GetClientNetworkable() = 0;
        virtual IClientRenderable* GetClientRenderable() = 0;
        virtual IClientEntity* GetIClientEntity() = 0;
        virtual IClientEntity* GetBaseEntity() = 0;
        virtual IClientThinkable* GetClientThinkable() = 0;
};

class IClientThinkable
{
    public:
        virtual IClientUnknown* GetIClientUnknown() = 0;
        virtual void ClientThink() = 0;
        virtual void* GetThinkHandle() = 0;
        virtual void SetThinkHandle(void* hThink) = 0;
        virtual void Release() = 0;
};

class __declspec (novtable)IClientEntity : public IClientUnknown, public IClientRenderable, public IClientNetworkable, public IClientThinkable
{
public:
public:
        virtual void Release(void) = 0;
        virtual void blahblahpad(void) = 0;
        virtual Vector&        GetAbsOrigin(void) const = 0;//in broken place use GetOrigin Below
virtual const Vector&        GetAbsAngles(void) const = 0;

    //---                 NetVars                  ---//

    CPNETVAR_FUNC(CLocalPlayerExclusive*, localPlayerExclusive, 0x7177BC3E);// m_Local

    CPNETVAR_FUNC(CollisionProperty*, collisionProperty, 0xE477CBD0);//m_Collision


    CNETVAR_FUNC(int, GetFlags, 0xE456D580); //m_fFlags

    CNETVAR_FUNC(Vector, GetOrigin, 0x1231CE10); //m_vecOrigin

    CNETVAR_FUNC(Vector, GetRotation, 0x6BEA197A); //m_angRotation

    CNETVAR_FUNC(int, GetTeamNum, 0xC08B6C6E); //m_iTeamNum

    CNETVAR_FUNC(int, GetMaxHealth, 0xC52E1C28); //m_iMaxHealth

    CNETVAR_FUNC(int, GetHealth, 0xA93054E3); //m_iHealth

    CNETVAR_FUNC(unsigned char, GetLifeState, 0xD795CCFC); //m_lifeState

    CNETVAR_FUNC(HANDLE, GetActiveWeaponHandle, 0xB4FECDA3); //m_hActiveWeapon

    CNETVAR_FUNC(int, GetTickBase, 0xD472B079); //m_nTickBase

    CNETVAR_FUNC(Vector, GetViewOffset, 0xA9F74931); //m_vecViewOffset[0]

    CNETVAR_FUNC(Vector, GetVelocity, 0x40C1CA24); //m_vecVelocity[0]

    CNETVAR_FUNC(bool, HasGunGameImmunity, 0x6AD6FA0D); //m_bGunGameImmunity

    CNETVAR_FUNC(bool, IsDefusing, 0xA2C14106); //m_bIsDefusing

    CNETVAR_FUNC(int, ArmorValue, 0x3898634); //m_ArmorValue

    CNETVAR_FUNC(bool, HasHelmet, 0x7B97F18A); //m_bHasHelmet

    CNETVAR_FUNC(bool, IsScoped, 0x61B9C22C); //m_bIsScoped

    CNETVAR_FUNC(int, GetMoney, 0xF4B3E183); //m_iAccount

    CNETVAR_FUNC(HANDLE, GetObserverTargetHandle, 0x8660FD83); //m_hObserverTarget
                                                               // ----------------------------------------------//

bool IsAlive()
{
    return (GetLifeState() == LIFE_ALIVE && GetHealth() > 0);
}

Vector GetBonePos(int i)
{
    matrix3x4 boneMatrix[128];
    if (this->SetupBones(boneMatrix, 128, BONE_USED_BY_HITBOX, GetTickCount64()))
    {
        return Vector(boneMatrix[i][0][3], boneMatrix[i][1][3], boneMatrix[i][2][3]);
    }
    return Vector(0, 0, 0);
}

Vector GetHeadPos()
{
    return this->GetBonePos(6);
}

};/*
Syn's AYYWAREFramework 2015
*/

#include "ESP.h"
#include "Interfaces.h"
#include "RenderManager.h"

void CEsp::Init()
{
    BombCarrier = nullptr;
}

// Yeah dude we're defo gunna do some sick moves for the esp yeah
void CEsp::Move(CUserCmd* pCmd) { }

// Main ESP Drawing loop
void CEsp::Draw()
{
    IClientEntity* pLocal = hackManager.pLocal();

    // Loop through all active entitys
    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        // Get the entity
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        player_info_t pinfo;

        // The entity isn't some laggy peice of shit or something
        if (pEntity && pEntity != pLocal && !pEntity->IsDormant())
        {
            // Is it a player?!
            if (Menu::Window.VisualsTab.FiltersPlayers.GetState() && Interfaces::Engine->GetPlayerInfo(i, &pinfo) && pEntity->IsAlive())
            {
                DrawPlayer(pEntity, pinfo);
            }

            // ~ Other ESP's here (items and shit) ~ //
            ClientClass* cClass = (ClientClass*)pEntity->GetClientClass();

            // Dropped weapons
            if (Menu::Window.VisualsTab.FiltersWeapons.GetState() && cClass->m_ClassID != (int)CSGOClassID::CBaseWeaponWorldModel && ((strstr(cClass->m_pNetworkName, "Weapon") || cClass->m_ClassID == (int)CSGOClassID::CDEagle || cClass->m_ClassID == (int)CSGOClassID::CAK47)))
            {
                DrawDrop(pEntity, cClass);
            }

            // If entity is the bomb
            if (Menu::Window.VisualsTab.FiltersC4.GetState())
            {
                if (cClass->m_ClassID == (int)CSGOClassID::CPlantedC4)
                    DrawBombPlanted(pEntity, cClass);

                if (cClass->m_ClassID == (int)CSGOClassID::CC4)
                    DrawBomb(pEntity, cClass);
            }

            // If entity is a chicken
            if (Menu::Window.VisualsTab.FiltersChickens.GetState())
            {
                if (cClass->m_ClassID == (int)CSGOClassID::CChicken)
                    DrawChicken(pEntity, cClass);
            }
        }
    }
}

//  Yeah m8
void CEsp::DrawPlayer(IClientEntity* pEntity, player_info_t pinfo)
{
    ESPBox Box;
    Color Color;

    // Show own team false? well gtfo teammate
    if (Menu::Window.VisualsTab.FiltersEnemiesOnly.GetState() && (pEntity->GetTeamNum() == hackManager.pLocal()->GetTeamNum()))
        return;

    if (GetBox(pEntity, Box))
    {
        Color = GetPlayerColor(pEntity);

        if (Menu::Window.VisualsTab.OptionsBox.GetState())
            DrawBox(Box, Color);

        if (Menu::Window.VisualsTab.OptionsName.GetState())
            DrawName(pinfo, Box);

        if (Menu::Window.VisualsTab.OptionsHealth.GetState())
            DrawHealth(pEntity, Box);

        if (Menu::Window.VisualsTab.OptionsInfo.GetState() || Menu::Window.VisualsTab.OptionsWeapon.GetState())
            DrawInfo(pEntity, Box);

        if (Menu::Window.VisualsTab.OptionsAimSpot.GetState())
            DrawCross(pEntity);

        if (Menu::Window.VisualsTab.OptionsSkeleton.GetState())
            DrawSkeleton(pEntity);
    }
}

// Gets the 2D bounding box for the entity
// Returns false on failure nigga don't fail me
bool CEsp::GetBox(IClientEntity* pEntity, CEsp::ESPBox &result)
{
    // Variables
    Vector vOrigin, min, max, sMin, sMax, sOrigin,
        flb, brt, blb, frt, frb, brb, blt, flt;
    float left, top, right, bottom;

    // Get the locations
    vOrigin = pEntity->GetOrigin();
    min = pEntity->collisionProperty()->GetMins() + vOrigin;
    max = pEntity->collisionProperty()->GetMaxs() + vOrigin;

    // Points of a 3d bounding box
    Vector points[] = { Vector(min.x, min.y, min.z),
        Vector(min.x, max.y, min.z),
        Vector(max.x, max.y, min.z),
        Vector(max.x, min.y, min.z),
        Vector(max.x, max.y, max.z),
        Vector(min.x, max.y, max.z),
        Vector(min.x, min.y, max.z),
        Vector(max.x, min.y, max.z) };

    // Get screen positions
    if (!Render::WorldToScreen(points[3], flb) || !Render::WorldToScreen(points[5], brt)
        || !Render::WorldToScreen(points[0], blb) || !Render::WorldToScreen(points[4], frt)
        || !Render::WorldToScreen(points[2], frb) || !Render::WorldToScreen(points[1], brb)
        || !Render::WorldToScreen(points[6], blt) || !Render::WorldToScreen(points[7], flt))
        return false;

    // Put them in an array (maybe start them off in one later for speed?)
    Vector arr[] = { flb, brt, blb, frt, frb, brb, blt, flt };

    // Init this shit
    left = flb.x;
    top = flb.y;
    right = flb.x;
    bottom = flb.y;

    // Find the bounding corners for our box
    for (int i = 1; i < 8; i++)
    {
        if (left > arr[i].x)
            left = arr[i].x;
        if (bottom < arr[i].y)
            bottom = arr[i].y;
        if (right < arr[i].x)
            right = arr[i].x;
        if (top > arr[i].y)
            top = arr[i].y;
    }

    // Width / height
    result.x = left;
    result.y = top;
    result.w = right - left;
    result.h = bottom - top;

    return true;
}

// Get an entities color depending on team and vis ect
Color CEsp::GetPlayerColor(IClientEntity* pEntity)
{
    int TeamNum = pEntity->GetTeamNum();
    bool IsVis = GameUtils::IsVisible(hackManager.pLocal(), pEntity, (int)CSGOHitboxID::Head);

    Color color;

    if (TeamNum == TEAM_CS_T)
    {
        if (IsVis)
            color = Color(235, 200, 0, 255);
        else
            color = Color(235, 50, 0, 255);
    }
    else
    {
        if (IsVis)
            color = Color(120, 210, 26, 255);
        else
            color = Color(15, 110, 220, 255);
    }


    return color;
}

// 2D  Esp box
void CEsp::DrawBox(CEsp::ESPBox size, Color color)
{
    //if (PlayerBoxes->GetStringIndex() == 1)
    //{
    //        // Full Box
    //        renderMan->Outline(size.x, size.y, size.w, size.h, color);
    //        renderMan->Outline(size.x - 1, size.y - 1, size.w + 2, size.h + 2, COLORCODE(10, 10, 10, 150));
    //        renderMan->Outline(size.x + 1, size.y + 1, size.w - 2, size.h - 2, COLORCODE(10, 10, 10, 150));
    //}
    //else
    //{
    // Corner Box
    int VertLine = (((float)size.w) * (0.20f));
    int HorzLine = (((float)size.h) * (0.20f));

    Render::Clear(size.x, size.y - 1, VertLine, 1, Color(10, 10, 10, 150));
    Render::Clear(size.x + size.w - VertLine, size.y - 1, VertLine, 1, Color(10, 10, 10, 150));
    Render::Clear(size.x, size.y + size.h - 1, VertLine, 1, Color(10, 10, 10, 150));
    Render::Clear(size.x + size.w - VertLine, size.y + size.h - 1, VertLine, 1, Color(10, 10, 10, 150));

    Render::Clear(size.x - 1, size.y, 1, HorzLine, Color(10, 10, 10, 150));
    Render::Clear(size.x - 1, size.y + size.h - HorzLine, 1, HorzLine, Color(10, 10, 10, 150));
    Render::Clear(size.x + size.w - 1, size.y, 1, HorzLine, Color(10, 10, 10, 150));
    Render::Clear(size.x + size.w - 1, size.y + size.h - HorzLine, 1, HorzLine, Color(10, 10, 10, 150));

    Render::Clear(size.x, size.y, VertLine, 1, color);
    Render::Clear(size.x + size.w - VertLine, size.y, VertLine, 1, color);
    Render::Clear(size.x, size.y + size.h, VertLine, 1, color);
    Render::Clear(size.x + size.w - VertLine, size.y + size.h, VertLine, 1, color);

    Render::Clear(size.x, size.y, 1, HorzLine, color);
    Render::Clear(size.x, size.y + size.h - HorzLine, 1, HorzLine, color);
    Render::Clear(size.x + size.w, size.y, 1, HorzLine, color);
    Render::Clear(size.x + size.w, size.y + size.h - HorzLine, 1, HorzLine, color);
    //}
}

// Unicode Conversions
static wchar_t* CharToWideChar(const char* text)
{
    size_t size = strlen(text) + 1;
    wchar_t* wa = new wchar_t[size];
    mbstowcs_s(NULL, wa, size / 4, text, size);
    return wa;
}

// Player name
void CEsp::DrawName(player_info_t pinfo, CEsp::ESPBox size)
{
    RECT nameSize = Render::GetTextSize(Render::Fonts::ESP, pinfo.name);
    Render::Text(size.x + (size.w / 2) - (nameSize.right / 2), size.y - 16,
        Color(255, 255, 255, 255), Render::Fonts::ESP, pinfo.name);
}

// Draw a health bar. For Tf2 when a bar is bigger than max health a second bar is displayed
void CEsp::DrawHealth(IClientEntity* pEntity, CEsp::ESPBox size)
{
    ESPBox HealthBar = size;
    HealthBar.y += (HealthBar.h + 6);
    HealthBar.h = 4;

    float HealthValue = pEntity->GetHealth();
    float HealthPerc = HealthValue / 100.f;
    float Width = (size.w * HealthPerc);
    HealthBar.w = Width;

    // --  Main Bar -- //

    Vertex_t Verts[4];
    Verts[0].Init(Vector2D(HealthBar.x, HealthBar.y));
    Verts[1].Init(Vector2D(HealthBar.x + size.w + 5, HealthBar.y));
    Verts[2].Init(Vector2D(HealthBar.x + size.w, HealthBar.y + 5));
    Verts[3].Init(Vector2D(HealthBar.x - 5, HealthBar.y + 5));

    Render::PolygonOutline(4, Verts, Color(10, 10, 10, 255), Color(255, 255, 255, 170));

    Vertex_t Verts2[4];
    Verts2[0].Init(Vector2D(HealthBar.x + 1, HealthBar.y + 1));
    Verts2[1].Init(Vector2D(HealthBar.x + HealthBar.w + 4, HealthBar.y + 1));
    Verts2[2].Init(Vector2D(HealthBar.x + HealthBar.w, HealthBar.y + 5));
    Verts2[3].Init(Vector2D(HealthBar.x - 4, HealthBar.y + 5));

    Color c = GetPlayerColor(pEntity);
    Render::Polygon(4, Verts2, c);

    Verts2[0].Init(Vector2D(HealthBar.x + 1, HealthBar.y + 1));
    Verts2[1].Init(Vector2D(HealthBar.x + HealthBar.w + 2, HealthBar.y + 1));
    Verts2[2].Init(Vector2D(HealthBar.x + HealthBar.w, HealthBar.y + 2));
    Verts2[3].Init(Vector2D(HealthBar.x - 2, HealthBar.y + 2));

    Render::Polygon(4, Verts2, Color(255, 255, 255, 40));

}

// Cleans the internal class name up to something human readable and nice
std::string CleanItemName(std::string name)
{
    std::string Name = name;
    // Tidy up the weapon Name
    if (Name[0] == 'C')
        Name.erase(Name.begin());

    // Remove the word Weapon
    auto startOfWeap = Name.find("Weapon");
    if (startOfWeap != std::string::npos)
                Name.erase(Name.begin() + startOfWeap, Name.begin() + startOfWeap + 6);

    return Name;
}

// Anything else: weapons, class state? idk
void CEsp::DrawInfo(IClientEntity* pEntity, CEsp::ESPBox size)
{
    std::vector < std::string> Info;

    // Player Weapon ESP
    IClientEntity* pWeapon = Interfaces::EntList->GetClientEntityFromHandle((HANDLE)pEntity->GetActiveWeaponHandle());
    if (Menu::Window.VisualsTab.OptionsWeapon.GetState() && pWeapon)
    {
        ClientClass* cClass = (ClientClass*)pWeapon->GetClientClass();
        if (cClass)
        {
            // Draw it
            Info.push_back(CleanItemName(cClass->m_pNetworkName));
        }
    }

    // Bomb Carrier
    if (Menu::Window.VisualsTab.OptionsInfo.GetState() && pEntity == BombCarrier)
    {
        Info.push_back("Bomb Carrier");
    }

    // Comp Rank
    if (Menu::Window.VisualsTab.OptionsInfo.GetState())
    {
        int CompRank = GameUtils::GetPlayerCompRank(pEntity);
        static const char* Ranks[] =
        {
            "",
            "Silver I",
            "Silver II",
            "Silver III",
            "Silver IV",
            "Silver Elite",
            "Silver Elite Master",

            "Gold Nova I",
            "Gold Nova II",
            "Gold Nova III",
            "Gold Nova Master",
            "Master Guardian I",
            "Master Guardian II",

            "Master Guardian Elite",
            "Distinguished Master Guardian",
            "Legendary Eagle",
            "Legendary Eagle Master",
            "Supreme Master First Class",
            "Global Elite"
        };
        if (CompRank >= 0 && CompRank <= 18)
            Info.push_back(Ranks[CompRank]);
    }

    static RECT Size = Render::GetTextSize(Render::Fonts::Default, "Hi");
    int i = 0;
    for (auto Text : Info)
    {
        Render::Text(size.x + size.w + 3, size.y + (i * (Size.bottom + 2)), Color(255, 255, 255, 255), Render::Fonts::ESP, Text.c_str());
        i++;
    }

}

// Little cross on their heads
void CEsp::DrawCross(IClientEntity* pEntity)
{
    Vector cross = pEntity->GetHeadPos(), screen;
    static int Scale = 2;
    if (Render::WorldToScreen(cross, screen))
    {
        Render::Clear(screen.x - Scale, screen.y - (Scale * 2), (Scale * 2), (Scale * 4), Color(20, 20, 20, 160));
        Render::Clear(screen.x - (Scale * 2), screen.y - Scale, (Scale * 4), (Scale * 2), Color(20, 20, 20, 160));
        Render::Clear(screen.x - Scale - 1, screen.y - (Scale * 2) - 1, (Scale * 2) - 2, (Scale * 4) - 2, Color(250, 250, 250, 160));
        Render::Clear(screen.x - (Scale * 2) - 1, screen.y - Scale - 1, (Scale * 4) - 2, (Scale * 2) - 2, Color(250, 250, 250, 160));
    }
}

// Draws a dropped CS:GO Item
void CEsp::DrawDrop(IClientEntity* pEntity, ClientClass* cClass)
{
    Vector Box;
    CBaseCombatWeapon* Weapon = (CBaseCombatWeapon*)pEntity;
    IClientEntity* plr = Interfaces::EntList->GetClientEntityFromHandle((HANDLE)Weapon->GetOwnerHandle());
    if (!plr && Render::WorldToScreen(Weapon->GetOrigin(), Box))
    {
        if (Menu::Window.VisualsTab.OptionsBox.GetState())
        {
            Render::Outline(Box.x - 2, Box.y - 2, 4, 4, Color(255, 255, 255, 255));
            Render::Outline(Box.x - 3, Box.y - 3, 6, 6, Color(10, 10, 10, 150));
        }

        if (Menu::Window.VisualsTab.OptionsInfo.GetState())
        {
            std::string ItemName = CleanItemName(cClass->m_pNetworkName);
            RECT TextSize = Render::GetTextSize(Render::Fonts::ESP, ItemName.c_str());
            Render::Text(Box.x - (TextSize.right / 2), Box.y - 16, Color(255, 255, 255, 255), Render::Fonts::ESP, ItemName.c_str());
        }
    }
}

// Draws a chicken
void CEsp::DrawChicken(IClientEntity* pEntity, ClientClass* cClass)
{
    ESPBox Box;

    if (GetBox(pEntity, Box))
    {
        player_info_t pinfo; strcpy_s(pinfo.name, "Chicken");
        if (Menu::Window.VisualsTab.OptionsBox.GetState())
            DrawBox(Box, Color(255, 255, 255, 255));

        if (Menu::Window.VisualsTab.OptionsName.GetState())
            DrawName(pinfo, Box);
    }
}

// Draw the planted bomb and timer
void CEsp::DrawBombPlanted(IClientEntity* pEntity, ClientClass* cClass)
{
    // Null it out incase bomb has been dropped or planted
    BombCarrier = nullptr;

    Vector vOrig; Vector vScreen;
    vOrig = pEntity->GetOrigin();
    CCSBomb* Bomb = (CCSBomb*)pEntity;

    if (Render::WorldToScreen(vOrig, vScreen))
    {
        float flBlow = Bomb->GetC4BlowTime();
        float TimeRemaining = flBlow - (Interfaces::Globals->interval_per_tick * hackManager.pLocal()->GetTickBase());
        char buffer[64];
        sprintf_s(buffer, "Bomb: %.1f", TimeRemaining);
        Render::Text(vScreen.x, vScreen.y, Color(250, 42, 42, 255), Render::Fonts::ESP, buffer);
    }
}

// Draw the bomb if it's dropped, or store the player who's carrying 
void CEsp::DrawBomb(IClientEntity* pEntity, ClientClass* cClass)
{
    // Null it out incase bomb has been dropped or planted
    BombCarrier = nullptr;
    CBaseCombatWeapon* BombWeapon = (CBaseCombatWeapon*)pEntity;
    Vector vOrig; Vector vScreen;
    vOrig = pEntity->GetOrigin();
    bool adopted = true;
    HANDLE parent = BombWeapon->GetOwnerHandle();
    if (parent || (vOrig.x == 0 && vOrig.y == 0 && vOrig.z == 0))
    {
        IClientEntity* pParentEnt = (Interfaces::EntList->GetClientEntityFromHandle(parent));
        if (pParentEnt && pParentEnt->IsAlive())
        {
            BombCarrier = pParentEnt;
            adopted = false;
        }
    }

    if (adopted)
    {
        if (Render::WorldToScreen(vOrig, vScreen))
        {
            Render::Text(vScreen.x, vScreen.y, Color(112, 230, 20, 255), Render::Fonts::ESP, "Bomb");
        }
    }
}

void DrawBoneArray(int* boneNumbers, int amount, IClientEntity* pEntity, Color color)
{
    Vector LastBoneScreen;
    for (int i = 0; i < amount; i++)
    {
        Vector Bone = pEntity->GetBonePos(boneNumbers[i]);
        Vector BoneScreen;

        if (Render::WorldToScreen(Bone, BoneScreen))
        {
            if (i > 0)
            {
                Render::Line(LastBoneScreen.x, LastBoneScreen.y, BoneScreen.x, BoneScreen.y, color);
            }
        }
        LastBoneScreen = BoneScreen;
    }
}

void DrawBoneTest(IClientEntity* pEntity)
{
    for (int i = 0; i < 127; i++)
    {
        Vector BoneLoc = pEntity->GetBonePos(i);
        Vector BoneScreen;
        if (Render::WorldToScreen(BoneLoc, BoneScreen))
        {
            char buf[10];
            _itoa_s(i, buf, 10);
            Render::Text(BoneScreen.x, BoneScreen.y, Color(255, 255, 255, 180), Render::Fonts::ESP, buf);
        }
    }
}

void CEsp::DrawSkeleton(IClientEntity* pEntity)
{
    studiohdr_t* pStudioHdr = Interfaces::ModelInfo->GetStudiomodel(pEntity->GetModel());

    if (!pStudioHdr)
        return;

    Vector vParent, vChild, sParent, sChild;

    for (int j = 0; j < pStudioHdr->numbones; j++)
    {
        mstudiobone_t* pBone = pStudioHdr->GetBone(j);

        if (pBone && (pBone->flags & BONE_USED_BY_HITBOX) && (pBone->parent != -1))
        {
            vChild = pEntity->GetBonePos(j);
            vParent = pEntity->GetBonePos(pBone->parent);

            if (Render::WorldToScreen(vParent, sParent) && Render::WorldToScreen(vChild, sChild))
            {
                Render::Line(sParent[0], sParent[1], sChild[0], sChild[1], Color(255, 255, 255, 255));
            }
        }
    }
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

class CEsp : public CHack
{
public:
        void Init();
void Draw();
void Move(CUserCmd* pCmd);
private:

        // Other shit
        IClientEntity* BombCarrier;

struct ESPBox
{
    int x, y, w, h;
};

// Draw a player
void DrawPlayer(IClientEntity* pEntity, player_info_t pinfo);

// Get player info
Color GetPlayerColor(IClientEntity* pEntity);
bool GetBox(IClientEntity* pEntity, ESPBox &result);

// Draw shit about player
void DrawBox(ESPBox size, Color color);
void DrawName(player_info_t pinfo, ESPBox size);
void DrawHealth(IClientEntity* pEntity, ESPBox size);
void DrawInfo(IClientEntity* pEntity, ESPBox size);
void DrawCross(IClientEntity* pEntity);
void DrawSkeleton(IClientEntity* pEntity);

void DrawChicken(IClientEntity* pEntity, ClientClass* cClass);
void DrawDrop(IClientEntity* pEntity, ClientClass* cClass);
void DrawBombPlanted(IClientEntity* pEntity, ClientClass* cClass);
void DrawBomb(IClientEntity* pEntity, ClientClass* cClass);
};



#include "GUI.h"

#include "RenderManager.h"

#include 
#include "tinyxml2.h"
#include "Controls.h"

CGUI GUI;

CGUI::CGUI()
{

}

// Draws all windows 
void CGUI::Draw()
{
    bool ShouldDrawCursor = false;

    for (auto window : Windows)
    {
        if (window->m_bIsOpen)
        {
            ShouldDrawCursor = true;
            DrawWindow(window);
        }

    }

    if (ShouldDrawCursor)
    {
        static Vertex_t MouseVt[3];

        MouseVt[0].Init(Vector2D(Mouse.x, Mouse.y));
        MouseVt[1].Init(Vector2D(Mouse.x + 16, Mouse.y));
        MouseVt[2].Init(Vector2D(Mouse.x, Mouse.y + 16));

        Render::PolygonOutline(3, MouseVt, Color(255, 0, 0, 230), Color(0, 0, 0, 240));
    }
}

// Handle all input etc
void CGUI::Update()
{
    //Key Array
    std::copy(keys, keys + 255, oldKeys);
    for (int x = 0; x < 255; x++)
    {
        //oldKeys[x] = oldKeys[x] & keys[x];
        keys[x] = (GetAsyncKeyState(x));
    }

    // Mouse Location
    POINT mp; GetCursorPos(&mp);
    Mouse.x = mp.x; Mouse.y = mp.y;

    RECT Screen = Render::GetViewport();

    // Window Binds
    for (auto & bind : WindowBinds)
    {
        if (GetKeyPress(bind.first))
        {
            bind.second->Toggle();
        }
    }

    // Stop dragging
    if (IsDraggingWindow && !GetKeyState(VK_LBUTTON))
    {
        IsDraggingWindow = false;
        DraggingWindow = nullptr;
    }

    // If we are in the proccess of dragging a window
    if (IsDraggingWindow && GetKeyState(VK_LBUTTON) && !GetKeyPress(VK_LBUTTON))
    {
        if (DraggingWindow)
        {
            DraggingWindow->m_x = Mouse.x - DragOffsetX;
            DraggingWindow->m_y = Mouse.y - DragOffsetY;
        }
    }

    // Process some windows
    for (auto window : Windows)
    {
        if (window->m_bIsOpen)
        {
            // Used to tell the widget processing that there could be a click
            bool bCheckWidgetClicks = false;

            // If the user clicks inside the window
            if (GetKeyPress(VK_LBUTTON))
            {
                if (IsMouseInRegion(window->m_x, window->m_y, window->m_x + window->m_iWidth, window->m_y + window->m_iHeight))
                {
                    // Is it inside the client area?
                    if (IsMouseInRegion(window->GetClientArea()))
                    {
                        // User is selecting a new tab
                        if (IsMouseInRegion(window->GetTabArea()))
                        {
                            // Loose focus on the control
                            window->IsFocusingControl = false;
                            window->FocusedControl = nullptr;

                            int iTab = 0;
                            int TabCount = window->Tabs.size();
                            if (TabCount) // If there are some tabs
                            {
                                int TabSize = (window->m_iWidth - 4 - 12) / TabCount;
                                int Dist = Mouse.x - (window->m_x + 8);
                                while (Dist > TabSize)
                                {
                                    if (Dist > TabSize)
                                    {
                                        iTab++;
                                        Dist -= TabSize;
                                    }
                                }
                                window->SelectedTab = window->Tabs[iTab];
                            }

                        }
                        else
                            bCheckWidgetClicks = true;
                    }
                    else
                    {
                        // Must be in the around the title or side of the window
                        // So we assume the user is trying to drag the window
                        IsDraggingWindow = true;
                        DraggingWindow = window;
                        DragOffsetX = Mouse.x - window->m_x;
                        DragOffsetY = Mouse.y - window->m_y;

                        // Loose focus on the control
                        window->IsFocusingControl = false;
                        window->FocusedControl = nullptr;
                    }
                }
                else
                {
                    // Loose focus on the control
                    window->IsFocusingControl = false;
                    window->FocusedControl = nullptr;
                }
            }


            // Controls 
            if (window->SelectedTab != nullptr)
            {
                // Focused widget
                bool SkipWidget = false;
                CControl* SkipMe = nullptr;

                // this window is focusing on a widget??
                if (window->IsFocusingControl)
                {
                    if (window->FocusedControl != nullptr)
                    {
                        // We've processed it once, skip it later
                        SkipWidget = true;
                        SkipMe = window->FocusedControl;

                        POINT cAbs = window->FocusedControl->GetAbsolutePos();
                        RECT controlRect = { cAbs.x, cAbs.y, window->FocusedControl->m_iWidth, window->FocusedControl->m_iHeight };
                        window->FocusedControl->OnUpdate();

                        if (window->FocusedControl->Flag(UIFlags::UI_Clickable) && IsMouseInRegion(controlRect) && bCheckWidgetClicks)
                        {
                            window->FocusedControl->OnClick();

                            // If it gets clicked we loose focus
                            window->IsFocusingControl = false;
                            window->FocusedControl = nullptr;
                            bCheckWidgetClicks = false;
                        }
                    }
                }

                // Itterate over the rest of the control
                for (auto control : window->SelectedTab->Controls)
                {
                    if (control != nullptr)
                    {
                        if (SkipWidget && SkipMe == control)
                            continue;

                        POINT cAbs = control->GetAbsolutePos();
                        RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                        control->OnUpdate();

                        if (control->Flag(UIFlags::UI_Clickable) && IsMouseInRegion(controlRect) && bCheckWidgetClicks)
                        {
                            control->OnClick();
                            bCheckWidgetClicks = false;

                            // Change of focus
                            if (control->Flag(UIFlags::UI_Focusable))
                            {
                                window->IsFocusingControl = true;
                                window->FocusedControl = control;
                            }
                            else
                            {
                                window->IsFocusingControl = false;
                                window->FocusedControl = nullptr;
                            }

                        }
                    }
                }

                // We must have clicked whitespace
                if (bCheckWidgetClicks)
                {
                    // Loose focus on the control
                    window->IsFocusingControl = false;
                    window->FocusedControl = nullptr;
                }
            }
        }
    }
}

// Returns 
bool CGUI::GetKeyPress(unsigned int key)
{
    if (keys[key] == true && oldKeys[key] == false)
        return true;
    else
        return false;
}

bool CGUI::GetKeyState(unsigned int key)
{
    return keys[key];
}

bool CGUI::IsMouseInRegion(int x, int y, int x2, int y2)
{
    if (Mouse.x > x && Mouse.y > y && Mouse.x < x2 && Mouse.y < y2)
        return true;
    else
        return false;
}

bool CGUI::IsMouseInRegion(RECT region)
{
    return IsMouseInRegion(region.left, region.top, region.left + region.right, region.top + region.bottom);
}

POINT CGUI::GetMouse()
{
    return Mouse;
}

bool CGUI::DrawWindow(CWindow* window)
{
    // Main Window
    Render::Outline(window->m_x, window->m_y, window->m_iWidth, window->m_iHeight, Color(20, 20, 20, 80));
    Render::GradientV(window->m_x + 2, window->m_y + 2, window->m_iWidth - 4, 26, Color(0, 0, 0, 255), Color(0, 0, 0, 255));
    Render::Clear(window->m_x + 2, window->m_y + 2 + 26, window->m_iWidth - 4, window->m_iHeight - 4 - 26, Color(0, 0, 0, 255));
    Render::Outline(window->m_x + 1, window->m_y + 1, window->m_iWidth - 2, window->m_iHeight - 2, Color(255, 0, 0, 255));
    Render::Text(window->m_x + 8, window->m_y + 8, Color(255, 255, 255, 255), Render::Fonts::MenuBold, window->Title.c_str());

    //Inner
    Render::Outline(window->m_x + 7, window->m_y + 1 + 26, window->m_iWidth - 4 - 10, window->m_iHeight - 2 - 6 - 26, Color(255, 0, 0, 255));
    Render::Clear(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, window->m_iHeight - 2 - 8 - 26, Color(255, 255, 255, 255));

    //Tab
    Render::GradientV(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, 29, Color(52, 52, 52, 255), Color(6, 6, 6, 255));
    int TabCount = window->Tabs.size();
    if (TabCount) // If there are some tabs
    {
        int TabSize = (window->m_iWidth - 4 - 12) / TabCount;
        for (int i = 0; i < TabCount; i++)
        {
            RECT TabArea = { window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29 };
            CTab* tab = window->Tabs[i];
            if (window->SelectedTab == tab)
            {
                Render::GradientV(window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29, Color(52, 52, 52, 255), Color(106, 106, 106, 255));
            }
            else if (IsMouseInRegion(TabArea))
            {
                Render::GradientV(window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29, Color(106, 106, 106, 255), Color(52, 52, 52, 255));
            }
            RECT TextSize = Render::GetTextSize(Render::Fonts::MenuBold, tab->Title.c_str());
            Render::Text(TabArea.left + (TabSize / 2) - (TextSize.right / 2), TabArea.top + 8, Color(255, 255, 255, 255), Render::Fonts::MenuBold, tab->Title.c_str());
            Render::Clear(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, 2, Color(66, 66, 66, 255));
        }
    }


    // Controls 
    if (window->SelectedTab != nullptr)
    {
        // Focused widget
        bool SkipWidget = false;
        CControl* SkipMe = nullptr;

        // this window is focusing on a widget??
        if (window->IsFocusingControl)
        {
            if (window->FocusedControl != nullptr)
            {
                // We need to draw it last, so skip it in the regular loop
                SkipWidget = true;
                SkipMe = window->FocusedControl;
            }
        }


        // Itterate over all the other controls
        for (auto control : window->SelectedTab->Controls)
        {
            if (SkipWidget && SkipMe == control)
                continue;

            if (control != nullptr && control->Flag(UIFlags::UI_Drawable))
            {
                POINT cAbs = control->GetAbsolutePos();
                RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                bool hover = false;
                if (IsMouseInRegion(controlRect))
                {
                    hover = true;
                }
                control->Draw(hover);
            }
        }

        // Draw the skipped widget last
        if (SkipWidget)
        {
            auto control = window->FocusedControl;

            if (control != nullptr && control->Flag(UIFlags::UI_Drawable))
            {
                POINT cAbs = control->GetAbsolutePos();
                RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                bool hover = false;
                if (IsMouseInRegion(controlRect))
                {
                    hover = true;
                }
                control->Draw(hover);
            }
        }

    }


    return true;
}

void CGUI::RegisterWindow(CWindow* window)
{
    Windows.push_back(window);

    // Resorting to put groupboxes at the start
    for (auto tab : window->Tabs)
    {
        for (auto control : tab->Controls)
        {
            if (control->Flag(UIFlags::UI_RenderFirst))
            {
                CControl* c = control;
                tab->Controls.erase(std::remove(tab->Controls.begin(), tab->Controls.end(), control), tab->Controls.end());
                tab->Controls.insert(tab->Controls.begin(), control);
            }
        }
    }
}

void CGUI::BindWindow(unsigned char Key, CWindow* window)
{
    if (window)
        WindowBinds[Key] = window;
    else
        WindowBinds.erase(Key);
}

void CGUI::SaveWindowState(CWindow* window, std::string Filename)
{
    // Create a whole new document and we'll just save over top of the old one
    tinyxml2::XMLDocument Doc;

    // Root Element is called "ayy"
    tinyxml2::XMLElement* Root = Doc.NewElement("ayy");
    Doc.LinkEndChild(Root);

    Utilities::Log("Saving Window %s", window->Title.c_str());

    // If the window has some tabs..
    if (Root && window->Tabs.size() > 0)
    {
        for (auto Tab : window->Tabs)
        {
            // Add a new section for this tab
            tinyxml2::XMLElement* TabElement = Doc.NewElement(Tab->Title.c_str());
            Root->LinkEndChild(TabElement);

            Utilities::Log("Saving Tab %s", Tab->Title.c_str());

            // Now we itterate the controls this tab contains
            if (TabElement && Tab->Controls.size() > 0)
            {
                for (auto Control : Tab->Controls)
                {
                    // If the control is ok to be saved
                    if (Control && Control->Flag(UIFlags::UI_SaveFile) && Control->FileIdentifier.length() > 1 && Control->FileControlType)
                    {
                        // Create an element for the control
                        tinyxml2::XMLElement* ControlElement = Doc.NewElement(Control->FileIdentifier.c_str());
                        TabElement->LinkEndChild(ControlElement);

                        Utilities::Log("Saving control %s", Control->FileIdentifier.c_str());

                        if (!ControlElement)
                        {
                            Utilities::Log("Errorino :(");
                            return;
                        }

                        CCheckBox* cbx = nullptr;
                        CComboBox* cbo = nullptr;
                        CKeyBind* key = nullptr;
                        CSlider* sld = nullptr;

                        // Figure out what kind of control and data this is
                        switch (Control->FileControlType)
                        {
                            case UIControlTypes::UIC_CheckBox:
                                cbx = (CCheckBox*)Control;
                                ControlElement->SetText(cbx->GetState());
                                break;
                            case UIControlTypes::UIC_ComboBox:
                                cbo = (CComboBox*)Control;
                                ControlElement->SetText(cbo->GetIndex());
                                break;
                            case UIControlTypes::UIC_KeyBind:
                                key = (CKeyBind*)Control;
                                ControlElement->SetText(key->GetKey());
                                break;
                            case UIControlTypes::UIC_Slider:
                                sld = (CSlider*)Control;
                                ControlElement->SetText(sld->GetValue());
                                break;
                        }
                    }
                }
            }
        }
    }

    //Save the file
    if (Doc.SaveFile(Filename.c_str()) != tinyxml2::XML_NO_ERROR)
    {
        MessageBox(NULL, "Failed To Save Config File!", "AyyWare", MB_OK);
    }

}

void CGUI::LoadWindowState(CWindow* window, std::string Filename)
{
    // Lets load our meme
    tinyxml2::XMLDocument Doc;
    if (Doc.LoadFile(Filename.c_str()) == tinyxml2::XML_NO_ERROR)
    {
        tinyxml2::XMLElement* Root = Doc.RootElement();

        // The root "ayy" element
        if (Root)
        {
            // If the window has some tabs..
            if (Root && window->Tabs.size() > 0)
            {
                for (auto Tab : window->Tabs)
                {
                    // We find the corresponding element for this tab
                    tinyxml2::XMLElement* TabElement = Root->FirstChildElement(Tab->Title.c_str());
                    if (TabElement)
                    {
                        // Now we itterate the controls this tab contains
                        if (TabElement && Tab->Controls.size() > 0)
                        {
                            for (auto Control : Tab->Controls)
                            {
                                // If the control is ok to be saved
                                if (Control && Control->Flag(UIFlags::UI_SaveFile) && Control->FileIdentifier.length() > 1 && Control->FileControlType)
                                {
                                    // Get the controls element
                                    tinyxml2::XMLElement* ControlElement = TabElement->FirstChildElement(Control->FileIdentifier.c_str());

                                    if (ControlElement)
                                    {
                                        Utilities::Log("We tryin to load fam");
                                        CCheckBox* cbx = nullptr;
                                        CComboBox* cbo = nullptr;
                                        CKeyBind* key = nullptr;
                                        CSlider* sld = nullptr;

                                        // Figure out what kind of control and data this is
                                        switch (Control->FileControlType)
                                        {
                                            case UIControlTypes::UIC_CheckBox:
                                                cbx = (CCheckBox*)Control;
                                                cbx->SetState(ControlElement->GetText()[0] == '1' ? true : false);
                                                break;
                                            case UIControlTypes::UIC_ComboBox:
                                                cbo = (CComboBox*)Control;
                                                cbo->SelectIndex(atoi(ControlElement->GetText()));
                                                break;
                                            case UIControlTypes::UIC_KeyBind:
                                                key = (CKeyBind*)Control;
                                                key->SetKey(atoi(ControlElement->GetText()));
                                                break;
                                            case UIControlTypes::UIC_Slider:
                                                sld = (CSlider*)Control;
                                                sld->SetValue(atof(ControlElement->GetText()));
                                                break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "CommonIncludes.h"

#include 

class CControl;
class CTab;
class CWindow;
class CGUI;

extern CGUI GUI;

enum UIFlags
{
    UI_None = 0x00,
    UI_Drawable = 0x01,
    UI_Clickable = 0x02,
    UI_Focusable = 0x04,
    UI_RenderFirst = 0x08,
    UI_SaveFile = 0x10
};

enum UIControlTypes
{
    UIC_CheckBox = 1,
    UIC_Slider,
    UIC_KeyBind,
    UIC_ComboBox
};

// Base class for GUI controls
class CControl
{
    friend class CGUI;
    friend class CTab;
    friend class CWindow;
    public:
        void SetPosition(int x, int y);
    void SetSize(int w, int h);
    void GetSize(int &w, int &h);
    void SetFileId(std::string fid);

    bool Flag(int f);
    protected:
        int m_x, m_y;
    int m_iWidth, m_iHeight;
    int m_Flags;
    CWindow* parent;

    std::string FileIdentifier;
    int FileControlType;

    virtual void Draw(bool) = 0;
        virtual void OnUpdate() = 0;
        virtual void OnClick() = 0;

        POINT GetAbsolutePos();
};

// A GUI Control Container
class CTab
{
    friend class CControl;
    friend class CGUI;
    friend class CWindow;
    public:
        void SetTitle(std::string name);
    void RegisterControl(CControl* control);
    private:
        std::string Title;
    std::vector Controls;
    CWindow* parent;
};

// Base class for a simple GUI window
class CWindow
{
    friend class CControl;
    friend class CGUI;
    public:
        void SetPosition(int x, int y);
    void SetSize(int w, int h);
    void SetTitle(std::string title);
    void Open();
    void Close();
    void Toggle();
    CControl* GetFocus();

    void RegisterTab(CTab* Tab);

    RECT GetClientArea();
    RECT GetTabArea();

    private:
        void DrawControls();

    bool m_bIsOpen;

    std::vector Tabs;
    CTab* SelectedTab;

    bool IsFocusingControl;
    CControl* FocusedControl;

    std::string Title;
    int m_x;
    int m_y;
    int m_iWidth;
    int m_iHeight;

};

// User interface manager
class CGUI
{
    public:
        CGUI();

    // Draws all windows 
    void Draw();

    // Handle all input etc
    void Update();

    // Draws a single window
    bool DrawWindow(CWindow* window);

    // Registers a window
    void RegisterWindow(CWindow* window);

    // Config saving/loading
    void SaveWindowState(CWindow* window, std::string Filename);
    void LoadWindowState(CWindow* window, std::string Filename);

    // Window Binds
    void BindWindow(unsigned char Key, CWindow* window);

    // Input
    bool GetKeyPress(unsigned int key);
    bool GetKeyState(unsigned int key);
    bool IsMouseInRegion(int x, int y, int x2, int y2);
    bool IsMouseInRegion(RECT region);
    POINT GetMouse();

    private:
        // Input
        // keyboard
        bool keys[256];
    bool oldKeys[256];
    // Mouse
    POINT Mouse;
    bool MenuOpen;

    // Window Dragging
    bool IsDraggingWindow;
    CWindow* DraggingWindow;
    int DragOffsetX; int DragOffsetY;

    // Windows
    std::vector Windows;

    // KeyBinds -> Windows Map
    std::map WindowBinds;

};/*
Syn's Payhake Framework for Insanity & Razor
*/

#include "Hacks.h"
#include "Interfaces.h"
#include "RenderManager.h"

#include "ESP.h"
#include "Visuals.h"
#include "RageBot.h"
#include "MiscHacks.h"
#include "LegitBot.h"

CEsp Esp;
CVisuals Visuals;
CMiscHacks MiscHacks;
CRageBot RageBot;
CLegitBot LegitBot;

// Initialise and register ALL hackmanager hacks in here nigga
void Hacks::SetupHacks()
{
    Esp.Init();
    Visuals.Init();
    MiscHacks.Init();
    RageBot.Init();
    LegitBot.Init();

    hackManager.RegisterHack(&Esp);
    hackManager.RegisterHack(&Visuals);
    hackManager.RegisterHack(&MiscHacks);
    hackManager.RegisterHack(&RageBot);
    hackManager.RegisterHack(&LegitBot);

    //--------------------------------
    hackManager.Ready();
}

void SpecList()
{
    IClientEntity* pLocal = hackManager.pLocal();

    RECT scrn = Render::GetViewport();
    int ayy = 0;

    // Loop through all active entitys
    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        // Get the entity
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        player_info_t pinfo;

        // The entity isn't some laggy peice of shit or something
        if (pEntity && pEntity != pLocal)
        {
            if (Interfaces::Engine->GetPlayerInfo(i, &pinfo) && !pEntity->IsAlive() && !pEntity->IsDormant())
            {
                HANDLE obs = pEntity->GetObserverTargetHandle();

                if (obs)
                {
                    IClientEntity* pTarget = Interfaces::EntList->GetClientEntityFromHandle(obs);
                    player_info_t pinfo2;
                    if (pTarget)
                    {
                        if (Interfaces::Engine->GetPlayerInfo(pTarget->GetIndex(), &pinfo2))
                        {
                            char buf[255]; sprintf_s(buf, "%s => %s", pinfo.name, pinfo2.name);
                            RECT TextSize = Render::GetTextSize(Render::Fonts::ESP, buf);
                            Render::Clear(scrn.right - 260, (scrn.bottom / 2) + (16 * ayy), 260, 16, Color(0, 0, 0, 140));
                            Render::Text(scrn.right - TextSize.right - 4, (scrn.bottom / 2) + (16 * ayy), pTarget->GetIndex() == pLocal->GetIndex() ? Color(240, 70, 80, 255) : Color(255, 255, 255, 255), Render::Fonts::ESP, buf);
                            ayy++;
                        }
                    }
                }
            }
        }
    }

    Render::Outline(scrn.right - 261, (scrn.bottom / 2) - 1, 262, (16 * ayy) + 2, Color(23, 23, 23, 255));
    Render::Outline(scrn.right - 260, (scrn.bottom / 2), 260, (16 * ayy), Color(90, 90, 90, 255));
}

// Only gets called in game, use a seperate draw UI call for menus in the hook
void Hacks::DrawHacks()
{
    // Spectator List
    if (Menu::Window.VisualsTab.OtherSpectators.GetState())
        SpecList();

    // Check the master visuals switch, just to be sure
    if (!Menu::Window.VisualsTab.Active.GetState())
        return;

    hackManager.Draw();
    //--------------------------------

}

// Game Cmd Changes
void Hacks::MoveHacks(CUserCmd* pCmd)
{
    Vector origView = pCmd->viewangles;
    hackManager.Move(pCmd);
    // ------------------------------

    // Put it in here so it's applied AFTER the aimbot
    int AirStuckKey = Menu::Window.VisualsTab.OtherAirStuck.GetKey();
    if (AirStuckKey > 0 && GUI.GetKeyState(AirStuckKey))
    {
        if (!(pCmd->buttons & IN_ATTACK))
            pCmd->tick_count = 0xFFFFF;
    }
}

//---------------------------------------------------------------------//
HackManager hackManager;

// Register a new hack
void HackManager::RegisterHack(CHack* hake)
{
    Hacks.push_back(hake);
    hake->Init();
}

// Draw all the hakes
void HackManager::Draw()
{
    if (!IsReady)
        return;

    // Grab the local player for drawing related hacks
    pLocalInstance = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    if (!pLocalInstance) return;

    for (auto & hack : Hacks)
    {
        hack->Draw();
    }
}

// Handle all the move hakes
void HackManager::Move(CUserCmd* pCmd)
{
    if (!IsReady)
        return;

    // Grab the local player for move related hacks
    pLocalInstance = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    if (!pLocalInstance) return;

    for (auto & hack : Hacks)
    {
        hack->Move(pCmd);
    }
}

//---------------------------------------------------------------------//
// Other Utils and shit

// Saves hacks needing to call a bunch of virtuals to get the instance
// Saves on cycles and file size. Recycle your plastic kids
IClientEntity* HackManager::pLocal()
{
    return pLocalInstance;
}

// Makes sure none of the hacks are called in their 
// hooks until they are completely ready for use
void HackManager::Ready()
{
    IsReady = true;
}
#pragma once

#pragma once

# include "SDK.h"
# include "Menu.h"
# include 

namespace Hacks
{
    void SetupHacks();
    void DrawHacks();
    void MoveHacks(CUserCmd* pCmd);
}

class CHack
{
    public:
        virtual void Draw() = 0;
        virtual void Move(CUserCmd* pCmd) = 0;
        virtual void Init() = 0;
};

class HackManager
{
    public:
        void RegisterHack(CHack* hake);
    void Ready();

    void Draw();
    void Move(CUserCmd* pCmd);
    IClientEntity* pLocal();
    private:
        std::vector Hacks;
    IClientEntity* pLocalInstance;
    bool IsReady;
};

extern HackManager hackManager;
    /*
Syn's AYYWAREFramework 2015
*/

#include "Hooks.h"
#include "Hacks.h"
#include "Chams.h"
#include "Menu.h"

#include "Interfaces.h"
#include "RenderManager.h"
#include "MiscHacks.h"

// Funtion Typedefs
typedef void(__thiscall* DrawModelEx_)(void*, void*, void*, const ModelRenderInfo_t&, matrix3x4*);
typedef void(__thiscall* PaintTraverse_)(PVOID, unsigned int, bool, bool);
typedef bool(__thiscall* InPrediction_)(PVOID);
typedef void(__stdcall* FrameStageNotifyFn)(ClientFrameStage_t);

// Function Pointers to the originals
PaintTraverse_ oPaintTraverse;
DrawModelEx_ oDrawModelExecute;
FrameStageNotifyFn oFrameStageNotify;

// Hook function prototypes
void __fastcall PaintTraverse_Hooked(PVOID pPanels, int edx, unsigned int vguiPanel, bool forceRepaint, bool allowForce);
bool __stdcall Hooked_InPrediction();
void __fastcall Hooked_DrawModelExecute(void* thisptr, int edx, void* ctx, void* state, const ModelRenderInfo_t &pInfo, matrix3x4* pCustomBoneToWorld);
bool __fastcall CreateMoveClient_Hooked(void* self, int edx, float frametime, CUserCmd* pCmd);
void __stdcall Hooked_FrameStageNotify(ClientFrameStage_t curStage);

// VMT Managers
namespace Hooks
{
    // VMT Managers
    Utilities::Memory::VMTManager VMTPanel; // Hooking drawing functions
    Utilities::Memory::VMTManager VMTClient; // Maybe CreateMove
    Utilities::Memory::VMTManager VMTClientMode; // CreateMove for functionality
    Utilities::Memory::VMTManager VMTModelRender; // DrawModelEx for chams
    Utilities::Memory::VMTManager VMTPrediction; // InPrediction for no vis recoil
};

// Initialise all our hooks
void Hooks::Initialise()
{
    // Panel hooks for drawing to the screen via surface functions
    VMTPanel.Initialise((DWORD*)Interfaces::Panels);
    oPaintTraverse = (PaintTraverse_)VMTPanel.HookMethod((DWORD) & PaintTraverse_Hooked, Offsets::VMT::Panel_PaintTraverse);
    Utilities::Log("Paint Traverse Hooked");

    // No Visual Recoil
    VMTPrediction.Initialise((DWORD*)Interfaces::Prediction);
    VMTPrediction.HookMethod((DWORD) & Hooked_InPrediction, 14);
    Utilities::Log("InPrediction Hooked");

    // Chams
    VMTModelRender.Initialise((DWORD*)Interfaces::ModelRender);
    oDrawModelExecute = (DrawModelEx_)VMTModelRender.HookMethod((DWORD) & Hooked_DrawModelExecute, Offsets::VMT::ModelRender_DrawModelExecute);
    Utilities::Log("DrawModelExecute Hooked");

    // Setup ClientMode Hooks
    VMTClientMode.Initialise((DWORD*)Interfaces::ClientMode);
    VMTClientMode.HookMethod((DWORD) & CreateMoveClient_Hooked, 24);
    //oFrameStageNotify = (FrameStageNotifyFn)VMTClientMode.HookMethod((DWORD)Hooked_FrameStageNotify, 36);
    Utilities::Log("CreateMove");

    // Setup client hooks
    VMTClient.Initialise((DWORD*)Interfaces::Client);
    oFrameStageNotify = (FrameStageNotifyFn)VMTClient.HookMethod((DWORD) & Hooked_FrameStageNotify, 36);
    Utilities::Log("FrameStage Hey whats up hello?");
}

// Undo our hooks
void Hooks::UndoHooks()
{
    VMTPanel.RestoreOriginal();
    VMTPrediction.RestoreOriginal();
    VMTModelRender.RestoreOriginal();
    VMTClientMode.RestoreOriginal();
    VMTClient.RestoreOriginal();
}

void MovementCorrection(CUserCmd* pCmd)
{

}

//---------------------------------------------------------------------------------------------------------
//                                         Hooked Functions
//---------------------------------------------------------------------------------------------------------

// Paint Traverse Hooked function
void __fastcall PaintTraverse_Hooked(PVOID pPanels, int edx, unsigned int vguiPanel, bool forceRepaint, bool allowForce)
{
    oPaintTraverse(pPanels, vguiPanel, forceRepaint, allowForce);

    static unsigned int FocusOverlayPanel = 0;
    static bool FoundPanel = false;

    if (!FoundPanel)
    {
        PCHAR szPanelName = (PCHAR)Interfaces::Panels->GetName(vguiPanel);
        if (strstr(szPanelName, "MatSystemTopPanel"))
        {
            FocusOverlayPanel = vguiPanel;
            FoundPanel = true;
        }
    }
    else if (FocusOverlayPanel == vguiPanel)
    {

        Render::Text(10, 10, Color(255, 255, 255, 220), Render::Fonts::Menu, "AYYWARE New Meme of 2015 Fixed By UnnAmE1337");
        if (Interfaces::Engine->IsConnected() && Interfaces::Engine->IsInGame())
            Hacks::DrawHacks();

        // Update and draw the menu
        Menu::DoUIFrame();
    }
}

// InPrediction Hooked Function
bool __stdcall Hooked_InPrediction()
{
    bool result;
    static InPrediction_ origFunc = (InPrediction_)Hooks::VMTPrediction.GetOriginalFunction(14);
    static DWORD* ecxVal = Interfaces::Prediction;
    result = origFunc(ecxVal);

    // If we are in the right place where the player view is calculated
    // Calculate the change in the view and get rid of it
    if (Menu::Window.VisualsTab.OtherNoVisualRecoil.GetState() && (DWORD)(_ReturnAddress()) == Offsets::Functions::dwCalcPlayerView)
    {
        IClientEntity* pLocalEntity = NULL;

        float* m_LocalViewAngles = NULL;

        __asm

        {
            MOV pLocalEntity, ESI

            MOV m_LocalViewAngles, EBX

        }

        Vector viewPunch = pLocalEntity->localPlayerExclusive()->GetViewPunchAngle();
        Vector aimPunch = pLocalEntity->localPlayerExclusive()->GetAimPunchAngle();

        m_LocalViewAngles[0] -= (viewPunch[0] + (aimPunch[0] * 2 * 0.4499999f));
        m_LocalViewAngles[1] -= (viewPunch[1] + (aimPunch[1] * 2 * 0.4499999f));
        m_LocalViewAngles[2] -= (viewPunch[2] + (aimPunch[2] * 2 * 0.4499999f));
        return true;
    }

    return result;
}

// DrawModelExec for chams and shit
void __fastcall Hooked_DrawModelExecute(void* thisptr, int edx, void* ctx, void* state, const ModelRenderInfo_t &pInfo, matrix3x4* pCustomBoneToWorld)
{
    Color color;
    float flColor[3] = { 0.f };
    static IMaterial* CoveredLit = CreateMaterial(true);
    static IMaterial* OpenLit = CreateMaterial(false);
    static IMaterial* CoveredFlat = CreateMaterial(true, false);
    static IMaterial* OpenFlat = CreateMaterial(false, false);
    bool DontDraw = false;

    const char* ModelName = Interfaces::ModelInfo->GetModelName((model_t*)pInfo.pModel);
    IClientEntity* pModelEntity = (IClientEntity*)Interfaces::EntList->GetClientEntity(pInfo.entity_index);
    IClientEntity* pLocal = (IClientEntity*)Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());

    if (Menu::Window.VisualsTab.Active.GetState())
    {
        // Player Chams
        int ChamsStyle = Menu::Window.VisualsTab.OptionsChams.GetIndex();
        int HandsStyle = Menu::Window.VisualsTab.OtherNoHands.GetIndex();
        if (ChamsStyle != 0 && Menu::Window.VisualsTab.FiltersPlayers.GetState() && strstr(ModelName, "models/player"))
        {
            if (pLocal && (!Menu::Window.VisualsTab.FiltersEnemiesOnly.GetState() ||
                pModelEntity->GetTeamNum() != pLocal->GetTeamNum()))
            {
                IMaterial* covered = ChamsStyle == 1 ? CoveredLit : CoveredFlat;
                IMaterial* open = ChamsStyle == 1 ? OpenLit : OpenFlat;

                IClientEntity* pModelEntity = (IClientEntity*)Interfaces::EntList->GetClientEntity(pInfo.entity_index);
                if (pModelEntity)
                {
                    IClientEntity* local = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
                    if (local)
                    {
                        if (pModelEntity->IsAlive() && pModelEntity->GetHealth() > 0 /*&& pModelEntity->GetTeamNum() != local->GetTeamNum()*/)
                        {
                            float alpha = 1.f;

                            if (pModelEntity->HasGunGameImmunity())
                                alpha = 0.5f;

                            if (pModelEntity->GetTeamNum() == 2)
                            {
                                flColor[0] = 240.f / 255.f;
                                flColor[1] = 30.f / 255.f;
                                flColor[2] = 35.f / 255.f;
                            }
                            else
                            {
                                flColor[0] = 63.f / 255.f;
                                flColor[1] = 72.f / 255.f;
                                flColor[2] = 205.f / 255.f;
                            }

                            Interfaces::RenderView->SetColorModulation(flColor);
                            Interfaces::RenderView->SetBlend(alpha);
                            Interfaces::ModelRender->ForcedMaterialOverride(covered);
                            oDrawModelExecute(thisptr, ctx, state, pInfo, pCustomBoneToWorld);

                            if (pModelEntity->GetTeamNum() == 2)
                            {
                                flColor[0] = 247.f / 255.f;
                                flColor[1] = 180.f / 255.f;
                                flColor[2] = 20.f / 255.f;
                            }
                            else
                            {
                                flColor[0] = 32.f / 255.f;
                                flColor[1] = 180.f / 255.f;
                                flColor[2] = 57.f / 255.f;
                            }

                            Interfaces::RenderView->SetColorModulation(flColor);
                            Interfaces::RenderView->SetBlend(alpha);
                            Interfaces::ModelRender->ForcedMaterialOverride(open);
                        }
                        else
                        {
                            color.SetColor(255, 255, 255, 255);
                            ForceMaterial(color, open);
                        }
                    }
                }
            }
        }
        else if (HandsStyle != 0 && strstr(ModelName, "arms"))
        {
            if (HandsStyle == 1)
            {
                DontDraw = true;
            }
            else if (HandsStyle == 2)
            {
                Interfaces::RenderView->SetBlend(0.3);
            }
            else if (HandsStyle == 3)
            {
                IMaterial* covered = ChamsStyle == 1 ? CoveredLit : CoveredFlat;
                IMaterial* open = ChamsStyle == 1 ? OpenLit : OpenFlat;
                if (pLocal)
                {
                    if (pLocal->IsAlive())
                    {
                        int alpha = pLocal->HasGunGameImmunity() ? 150 : 255;

                        if (pLocal->GetTeamNum() == 2)
                            color.SetColor(240, 30, 35, alpha);
                        else
                            color.SetColor(63, 72, 205, alpha);

                        ForceMaterial(color, covered);
                        oDrawModelExecute(thisptr, ctx, state, pInfo, pCustomBoneToWorld);

                        if (pLocal->GetTeamNum() == 2)
                            color.SetColor(247, 180, 20, alpha);
                        else
                            color.SetColor(32, 180, 57, alpha);
                    }
                    else
                    {
                        color.SetColor(255, 255, 255, 255);
                    }

                    ForceMaterial(color, open);
                }
            }
            else
            {
                static int counter = 0;
                static float colors[3] = { 1.f, 0.f, 0.f };

                if (colors[counter] >= 1.0f)
                {
                    colors[counter] = 1.0f;
                    counter += 1;
                    if (counter > 2)
                        counter = 0;
                }
                else
                {
                    int prev = counter - 1;
                    if (prev < 0) prev = 2;
                    colors[prev] -= 0.05f;
                    colors[counter] += 0.05f;
                }

                Interfaces::RenderView->SetColorModulation(colors);
                Interfaces::RenderView->SetBlend(0.3);
                Interfaces::ModelRender->ForcedMaterialOverride(OpenLit);
            }
        }
        else if (ChamsStyle != 0 && Menu::Window.VisualsTab.FiltersWeapons.GetState() && strstr(ModelName, "_dropped.mdl"))
        {
            IMaterial* covered = ChamsStyle == 1 ? CoveredLit : CoveredFlat;
            color.SetColor(255, 255, 255, 255);
            ForceMaterial(color, covered);
        }
    }

    if (!DontDraw)
        oDrawModelExecute(thisptr, ctx, state, pInfo, pCustomBoneToWorld);
    Interfaces::ModelRender->ForcedMaterialOverride(NULL);
}

// ClientMode CreateMove
bool __fastcall CreateMoveClient_Hooked(void* self, int edx, float frametime, CUserCmd* pCmd)
{
    // Backup for safety
    Vector origView = pCmd->viewangles;
    Vector viewforward, viewright, viewup, aimforward, aimright, aimup;
    Vector qAimAngles;
    qAimAngles.Init(0.0f, pCmd->viewangles.y, 0.0f);
    AngleVectors(qAimAngles, &viewforward, &viewright, &viewup);

    // Do da hacks
    IClientEntity* pLocal = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    if (Interfaces::Engine->IsConnected() && Interfaces::Engine->IsInGame() && pLocal && pLocal->IsAlive())
        Hacks::MoveHacks(pCmd);

    //Movement Fix
    //GameUtils::CL_FixMove(pCmd, origView);
    qAimAngles.Init(0.0f, GetAutostrafeView().y, 0.0f);
    AngleVectors(qAimAngles, &viewforward, &viewright, &viewup);
    qAimAngles.Init(0.0f, pCmd->viewangles.y, 0.0f);
    AngleVectors(qAimAngles, &aimforward, &aimright, &aimup);
    Vector vForwardNorm; Normalize(viewforward, vForwardNorm);
    Vector vRightNorm; Normalize(viewright, vRightNorm);
    Vector vUpNorm; Normalize(viewup, vUpNorm);

    // Original shit for movement correction
    float forward = pCmd->forwardmove;
    float right = pCmd->sidemove;
    float up = pCmd->upmove;
    if (forward > 450) forward = 450;
    if (right > 450) right = 450;
    if (up > 450) up = 450;
    if (forward < -450) forward = -450;
    if (right < -450) right = -450;
    if (up < -450) up = -450;
    pCmd->forwardmove = DotProduct(forward * vForwardNorm, aimforward) + DotProduct(right * vRightNorm, aimforward) + DotProduct(up * vUpNorm, aimforward);
    pCmd->sidemove = DotProduct(forward * vForwardNorm, aimright) + DotProduct(right * vRightNorm, aimright) + DotProduct(up * vUpNorm, aimright);
    pCmd->upmove = DotProduct(forward * vForwardNorm, aimup) + DotProduct(right * vRightNorm, aimup) + DotProduct(up * vUpNorm, aimup);

    // Angle normalisation
    if (Menu::Window.VisualsTab.OtherSafeMode.GetState())
    {
        GameUtils::NormaliseViewAngle(pCmd->viewangles);

        if (pCmd->viewangles.z != 0.0f)
        {
            pCmd->viewangles.z = 0.00;
        }

        if (pCmd->viewangles.x < -89 || pCmd->viewangles.x > 89 || pCmd->viewangles.y < -180 || pCmd->viewangles.y > 180)
        {
            Utilities::Log("Having to re-normalise!");
            GameUtils::NormaliseViewAngle(pCmd->viewangles);
            Beep(750, 800);
            if (pCmd->viewangles.x < -89 || pCmd->viewangles.x > 89 || pCmd->viewangles.y < -180 || pCmd->viewangles.y > 180)
            {
                pCmd->viewangles = origView;
                pCmd->sidemove = right;
                pCmd->forwardmove = forward;
            }
        }
    }

    return false;
}

/*void  __stdcall Hooked_FrameStageNotify(ClientFrameStage_t curStage)
{
        oFrameStageNotify(curStage);

        if (curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_START)
        {
                IClientEntity *pLocal = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
                if (Menu::Window.MiscTab.KnifeEnable.GetState() && pLocal)
                {
                        IClientEntity* WeaponEnt = Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
                        CBaseCombatWeapon* Weapon = (CBaseCombatWeapon*)WeaponEnt;
                        if (Weapon)
                        {
                                //Utilities::Log("NIGGA WE CLOSE!");
                                static bool LastItemWasKnife = false;
                                if (WeaponEnt->GetClientClass()->m_ClassID == (int)CSGOClassID::CKnife)
                                {
                                        *Weapon->FallbackStatTrak() = 1337;
                                        int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();
                                        if (Skin == 0) *Weapon->FallbackPaintKit() = 416;
                                        if (Skin == 1) *Weapon->FallbackPaintKit() = 415;
                                        if (Skin == 3) *Weapon->FallbackPaintKit() = 409;
                                        if (Skin == 4) *Weapon->FallbackPaintKit() = 0;
                                        *Weapon->FallbackWear() = 0.0001;

                                        *Weapon->m_AttributeManager()->m_Item()->ItemIDLow() = 7;
                                        int Model = Menu::Window.MiscTab.KnifeModel.GetIndex();
                                        *Weapon->m_AttributeManager()->m_Item()->ItemIDHigh() = (Model == 0) ? 507 : 500;
                                        *Weapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = (Model == 0) ? 507 : 500;

                                        if (GUI.GetKeyState(VK_END))
                                                ForceUpdate();
                                }
                        }
                }
        }
}*/


void __stdcall Hooked_FrameStageNotify(ClientFrameStage_t curStage)
{
    oFrameStageNotify(curStage);

    //Utilities::Log("plsplspls");

    if (curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_START)
    {
        //Utilities::Log("APPLY SKIN APPLY SKIN");
        IClientEntity* pLocal = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
        int iBayonet = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_bayonet.mdl");
        int iButterfly = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_butterfly.mdl");
        int iFlip = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_flip.mdl");
        int iGunGame = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_gg.mdl");
        int iGut = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_gut.mdl");
        int iKarambit = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_karam.mdl");
        int iM9Bayonet = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_m9_bay.mdl");
        int iHuntsman = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_tactical.mdl");

        int iFalchion = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_falchion_advanced.mdl");
        int iDagger = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_push.mdl");

        for (int i = Interfaces::EntList->GetHighestEntityIndex(); i >= 0; --i)
        {
            IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);

            if (pEntity)
            {
                ULONG hOwnerEntity = *(PULONG)((DWORD)pEntity + 0x148);

                IClientEntity* pOwner = Interfaces::EntList->GetClientEntityFromHandle((HANDLE)hOwnerEntity);

                if (pOwner)
                {
                    if (pOwner == pLocal)
                    {
                        std::string sWeapon = Interfaces::ModelInfo->GetModelName(pEntity->GetModel());

                        if (!(sWeapon.find("models/weapons", 0) != std::string::npos))
                                                        continue;

        if (sWeapon.find("c4_planted", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("thrown", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("smokegrenade", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("flashbang", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("fraggrenade", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("molotov", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("decoy", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("incendiarygrenade", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("ied", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("w_eq_", 0) != std::string::npos)
                                                        continue;

        CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)pEntity;

        ClientClass* pClass = Interfaces::Client->GetAllClasses();

        if (Menu::Window.MiscTab.KnifeEnable.GetState())
        {
            int Model = Menu::Window.MiscTab.KnifeModel.GetIndex();

            int M41S = Menu::Window.MiscTab.M41SSkin.GetIndex();
            int M4A4 = Menu::Window.MiscTab.M4A4Skin.GetIndex();
            int AK47 = Menu::Window.MiscTab.AK47Skin.GetIndex();
            int AWP = Menu::Window.MiscTab.AWPSkin.GetIndex();
            int Glock = Menu::Window.MiscTab.GLOCKSkin.GetIndex();
            int USPS = Menu::Window.MiscTab.USPSSkin.GetIndex();
            int Deagle = Menu::Window.MiscTab.DEAGLESkin.GetIndex();
            int Magnum = Menu::Window.MiscTab.DEAGLESkin.GetIndex();

            if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 26) // M41S
            {
                if (M41S == 0)
                {
                    *pWeapon->FallbackPaintKit() = 321;
                }
                else if (M41S == 1)
                {
                    *pWeapon->FallbackPaintKit() = 430;
                }
                else if (M41S == 2)
                {
                    *pWeapon->FallbackPaintKit() = 360;
                }
                else if (M41S == 3)
                {
                    *pWeapon->FallbackPaintKit() = 445;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 60) // M4A4
            {
                if (M4A4 == 0)
                {
                    *pWeapon->FallbackPaintKit() = 512;
                }
                else if (M4A4 == 1)
                {
                    *pWeapon->FallbackPaintKit() = 309;
                }
                else if (M4A4 == 2)
                {
                    *pWeapon->FallbackPaintKit() = 155;
                }
                else if (M4A4 == 3)
                {
                    *pWeapon->FallbackPaintKit() = 400;
                }
                else if (M4A4 == 4)
                {
                    *pWeapon->FallbackPaintKit() = 255;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 7) // AK47
            {
                if (AK47 == 0)
                {
                    *pWeapon->FallbackPaintKit() = 506;
                }
                else if (AK47 == 1)
                {
                    *pWeapon->FallbackPaintKit() = 474;
                }
                else if (AK47 == 2)
                {
                    *pWeapon->FallbackPaintKit() = 302;
                }
                else if (AK47 == 3)
                {
                    *pWeapon->FallbackPaintKit() = 180;
                }
                else if (AK47 == 4)
                {
                    *pWeapon->FallbackPaintKit() = 316;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 9) // AWP
            {
                if (AWP == 0)
                {
                    *pWeapon->FallbackPaintKit() = 475;
                }
                else if (AWP == 1)
                {
                    *pWeapon->FallbackPaintKit() = 279;
                }
                else if (AWP == 2)
                {
                    *pWeapon->FallbackPaintKit() = 344;
                }
                else if (AWP == 3)
                {
                    *pWeapon->FallbackPaintKit() = 51;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 4) // GLOCK
            {
                if (Glock == 0)
                {
                    *pWeapon->FallbackPaintKit() = 353;
                }
                else if (Glock == 1)
                {
                    *pWeapon->FallbackPaintKit() = 38;
                }
                else if (Glock == 2)
                {
                    *pWeapon->FallbackPaintKit() = 437;
                }
                else if (Glock == 3)
                {
                    *pWeapon->FallbackPaintKit() = 479;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 61) // USPS
            {
                if (USPS == 0)
                {
                    *pWeapon->FallbackPaintKit() = 504;
                }
                else if (USPS == 1)
                {
                    *pWeapon->FallbackPaintKit() = 339;
                }
                else if (USPS == 2)
                {
                    *pWeapon->FallbackPaintKit() = 313;
                }
                else if (USPS == 3)
                {
                    *pWeapon->FallbackPaintKit() = 290;
                }
            }

            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 64) // USPS
            {
                if (Magnum == 0)
                {
                    *pWeapon->FallbackPaintKit() = 12;
                }
                else if (Magnum == 1)
                {
                    *pWeapon->FallbackPaintKit() = 522;
                }
                else if (Magnum == 2)
                {
                    *pWeapon->FallbackPaintKit() = 523;
                }
            }

            if (pEntity->GetClientClass()->m_ClassID == (int)CSGOClassID::CKnife)
            {
                if (Model == 0) // Karambit
                {
                    *pWeapon->ViewModelIndex() = iKarambit;
                    *pWeapon->WorldModelIndex() = iKarambit + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 507;

                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 1) // Bayonet
                {

                    *pWeapon->ViewModelIndex() = iBayonet;
                    *pWeapon->WorldModelIndex() = iBayonet + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 500;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 2) // Huntsman Knife
                {

                    *pWeapon->ViewModelIndex() = iHuntsman;
                    *pWeapon->WorldModelIndex() = iHuntsman + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 509;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 3) // Gut Knife
                {

                    *pWeapon->ViewModelIndex() = iGut;
                    *pWeapon->WorldModelIndex() = iGut + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 506;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 4) // Walmart Knife
                {

                    *pWeapon->ViewModelIndex() = iFalchion;
                    *pWeapon->WorldModelIndex() = iFalchion + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 512;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 5) // Shadow Daggers Knife
                {

                    *pWeapon->ViewModelIndex() = iDagger;
                    *pWeapon->WorldModelIndex() = iDagger + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 516;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 6) // Butterfly Knife
                {

                    *pWeapon->ViewModelIndex() = iButterfly;
                    *pWeapon->WorldModelIndex() = iButterfly + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 515;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 7) // Flip Knife
                {

                    *pWeapon->ViewModelIndex() = iFlip;
                    *pWeapon->WorldModelIndex() = iFlip + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 505;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 8) // M9 Bayonet
                {

                    *pWeapon->ViewModelIndex() = iM9Bayonet;
                    *pWeapon->WorldModelIndex() = iM9Bayonet + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 508;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
            }
            *pWeapon->OwnerXuidLow() = 0;
            *pWeapon->OwnerXuidHigh() = 0;
            *pWeapon->FallbackWear() = 0.001f;
            *pWeapon->m_AttributeManager()->m_Item()->ItemIDHigh() = 1;
        }
    }
}

                        }
                }
        }
}
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

// It's actually in DLLMain but w/e
extern bool DoUnload;

#include "Utilities.h"

namespace Hooks
{
    void Initialise();
    void UndoHooks();

        // VMT Managers
        extern Utilities::Memory::VMTManager VMTPanel; // Hooking drawing functions
        extern Utilities::Memory::VMTManager VMTClient; // Maybe CreateMove
        extern Utilities::Memory::VMTManager VMTClientMode; // CreateMove for functionality
        extern Utilities::Memory::VMTManager VMTModelRender; // DrawModelEx for chams
        extern Utilities::Memory::VMTManager VMTPrediction; // InPrediction for no vis recoil
};/*
Syn's AYYWAREFramework 2015
*/

#include "Interfaces.h"
#include "Utilities.h"
#include "Menu.h"

//SDK Specific Definitions
typedef void* (__cdecl* CreateInterface_t)(const char*, int*);
typedef void* (* CreateInterfaceFn)(const char* pName, int* pReturnCode);

//Some globals for later
CreateInterface_t EngineFactory = NULL; // These are used to store the individual
CreateInterface_t ClientFactory = NULL; //  CreateInterface functions for each game
CreateInterface_t VGUISurfaceFactory = NULL; //  dll that we need access to. Can call
CreateInterface_t VGUI2Factory = NULL; //  them to recieve pointers to game classes.
CreateInterface_t MatFactory = NULL;
CreateInterface_t PhysFactory = NULL;
CreateInterface_t StdFactory = NULL;

void Interfaces::Initialise()
{

    //Get function pointers to the CreateInterface function of each module
    EngineFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::Engine, "CreateInterface");
    ClientFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::Client, "CreateInterface");
    VGUI2Factory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::VGUI2, "CreateInterface");
    VGUISurfaceFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::VGUISurface, "CreateInterface");
    MatFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::Material, "CreateInterface");
    PhysFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::VPhysics, "CreateInterface");
    StdFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::Stdlib, "CreateInterface");

    //Get the interface names regardless of their version number by scanning for each string
    char* CHLClientInterfaceName = (char*)Utilities::Memory::FindTextPattern("client.dll", "VClient0");
    char* VGUI2PanelsInterfaceName = (char*)Utilities::Memory::FindTextPattern("vgui2.dll", "VGUI_Panel0");
    char* VGUISurfaceInterfaceName = (char*)Utilities::Memory::FindTextPattern("vguimatsurface.dll", "VGUI_Surface0");
    char* EntityListInterfaceName = (char*)Utilities::Memory::FindTextPattern("client.dll", "VClientEntityList0");
    char* EngineDebugThingInterface = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VDebugOverlay0");
    char* EngineClientInterfaceName = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VEngineClient0");
    char* ClientPredictionInterface = (char*)Utilities::Memory::FindTextPattern("client.dll", "VClientPrediction0");
    char* MatSystemInterfaceName = (char*)Utilities::Memory::FindTextPattern("materialsystem.dll", "VMaterialSystem0");
    char* EngineRenderViewInterface = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VEngineRenderView0");
    char* EngineModelRenderInterface = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VEngineModel0");
    char* EngineModelInfoInterface = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VModelInfoClient0");
    char* EngineTraceInterfaceName = (char*)Utilities::Memory::FindTextPattern("engine.dll", "EngineTraceClient0");
    char* PhysPropsInterfaces = (char*)Utilities::Memory::FindTextPattern("client.dll", "VPhysicsSurfaceProps0");
    char* VEngineCvarName = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VEngineCvar00");

    // Use the factory function pointers along with the interface versions to grab
    //  pointers to the interfaces
    Client = (IBaseClientDLL*)ClientFactory(CHLClientInterfaceName, NULL);
    Engine = (IVEngineClient*)EngineFactory(EngineClientInterfaceName, NULL);
    Panels = (IPanel*)VGUI2Factory(VGUI2PanelsInterfaceName, NULL);
    Surface = (ISurface*)VGUISurfaceFactory(VGUISurfaceInterfaceName, NULL);
    EntList = (IClientEntityList*)ClientFactory(EntityListInterfaceName, NULL);
    DebugOverlay = (IVDebugOverlay*)EngineFactory(EngineDebugThingInterface, NULL);
    Prediction = (DWORD*)ClientFactory(ClientPredictionInterface, NULL);
    MaterialSystem = (CMaterialSystem*)MatFactory(MatSystemInterfaceName, NULL);
    RenderView = (CVRenderView*)EngineFactory(EngineRenderViewInterface, NULL);
    ModelRender = (IVModelRender*)EngineFactory(EngineModelRenderInterface, NULL);
    ModelInfo = (CModelInfo*)EngineFactory(EngineModelInfoInterface, NULL);
    Trace = (IEngineTrace*)EngineFactory(EngineTraceInterfaceName, NULL);
    PhysProps = (IPhysicsSurfaceProps*)PhysFactory(PhysPropsInterfaces, NULL);
    CVar = (ICVar*)StdFactory(VEngineCvarName, NULL);

    // Get ClientMode Pointer
    DWORD* ppClientMode;
    ppClientMode = nullptr; // before "scripts/vgui_screens.txt"
    DWORD p = Utilities::Memory::FindPattern("client.dll", (BYTE*)"\xC7\x05\x00\x00\x00\x00\x00\x00\x00\x00\xA8\x01\x75\x1A\x83\xC8\x01\xA3\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x68\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x83\xC4\x04\xA1\x00\x00\x00\x00\xB9\x00\x00\x00\x00\x56", "xx????????xxxxxxxx????x????x????x????xxxx????x????x");
    if (p)
    {
        ppClientMode = **(DWORD***)(p + 2);
        ClientMode = ppClientMode;
    }

    // Search through the first entry of the Client VTable
    // The initializer contains a pointer to the 'GlobalsVariables' Table
    PDWORD pdwClient = (PDWORD) * (PDWORD)Client;
    DWORD dwInitAddr = (DWORD)(pdwClient[0]);
    for (DWORD dwIter = 0; dwIter <= 0xFF; dwIter++)
    {
        if (*(PBYTE)(dwInitAddr + dwIter - 1) == 0x08 && *(PBYTE)(dwInitAddr + dwIter) == 0xA3)
        {
            Globals = (CGlobalVarsBase*)*(PDWORD) * (PDWORD)(dwInitAddr + dwIter + 1);
            break;
        }
    }
    Utilities::Log("Interfaces Readyz");
}

// Namespace to contain all the valve interfaces
namespace Interfaces
{
    IBaseClientDLL* Client;
    IVEngineClient* Engine;
    IPanel* Panels;
    IClientEntityList* EntList;
    ISurface* Surface;
    IVDebugOverlay* DebugOverlay;
    DWORD* ClientMode;
    CGlobalVarsBase* Globals;
    DWORD* Prediction;
    CMaterialSystem* MaterialSystem;
    CVRenderView* RenderView;
    IVModelRender* ModelRender;
    CModelInfo* ModelInfo;
    IEngineTrace* Trace;
    IPhysicsSurfaceProps* PhysProps;
    ICVar* CVar;
};/*
Syn's AYYWAREFramework
*/

#pragma once

// Includes
#include "SDK.h"

// Namespace to contain all the valve interfaces
namespace Interfaces
{
    // Gets handles to all the interfaces needed
    void Initialise();

        extern IBaseClientDLL* Client;
        extern IVEngineClient* Engine;
        extern IPanel* Panels;
        extern IClientEntityList* EntList;
        extern ISurface* Surface;
        extern IVDebugOverlay* DebugOverlay;
        extern DWORD * ClientMode;
        extern CGlobalVarsBase * Globals;
        extern DWORD * Prediction;
        extern CMaterialSystem* MaterialSystem;
        extern CVRenderView* RenderView;
        extern IVModelRender* ModelRender;
        extern CModelInfo* ModelInfo;
        extern IEngineTrace* Trace;
        extern IPhysicsSurfaceProps* PhysProps;
        exte
#include "LegitBot.h"
#include "RenderManager.h"

void CLegitBot::Init()
{
        IsLocked = false;
        TargetID = -1;
}

void CLegitBot::Draw()
{
        
}

void CLegitBot::Move(CUserCmd *pCmd)
{
        // Master switch
        if (!Menu::Window.LegitBotTab.Active.GetState())
                return;

        // Aimbot
        if (Menu::Window.LegitBotTab.AimbotEnable.GetState())
                DoAimbot(pCmd);

        // Triggerbot / Trigger Delay
        static size_t CustomDelay = 0;
        if (Menu::Window.LegitBotTab.TriggerEnable.GetState() && (!Menu::Window.LegitBotTab.TriggerKeyPress.GetState() || GUI.GetKeyState(Menu::Window.LegitBotTab.TriggerKeyBind.GetKey())))
        {

                if (Menu::Window.LegitBotTab.TriggerDelay.GetValue() > 1)
                {
                        if (GetTickCount() > CustomDelay)
                        {

                                DoTrigger(pCmd);
                                CustomDelay = GetTickCount() + Menu::Window.LegitBotTab.TriggerDelay.GetValue();
                        }
                }
                else
                        DoTrigger(pCmd);
        }
}

void CLegitBot::SyncWeaponSettings()
{
        IClientEntity* pLocal = hackManager.pLocal();
        CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());

        if (!pWeapon)
                return;

        if (GameUtils::IsPistol(pWeapon))
        {
                Speed = Menu::Window.LegitBotTab.WeaponPistSpeed.GetValue();
                FoV = Menu::Window.LegitBotTab.WeaponPistFoV.GetValue();
                RecoilControl = Menu::Window.LegitBotTab.WeaponPistRecoil.GetState();

                switch (Menu::Window.LegitBotTab.WeaponPistHitbox.GetIndex())
                {
                case 0:
                        HitBox = ((int)CSGOHitboxID::Head);
                        break;
                case 1:
                        HitBox = ((int)CSGOHitboxID::Neck);
                        break;
                case 2:
                        HitBox = ((int)CSGOHitboxID::Chest);
                        break;
                case 3:
                        HitBox = ((int)CSGOHitboxID::Stomach);
                        break;
                }
        }
        else if (GameUtils::IsSniper(pWeapon))
        {
                Speed = Menu::Window.LegitBotTab.WeaponSnipSpeed.GetValue();
                FoV = Menu::Window.LegitBotTab.WeaponSnipFoV.GetValue();
                RecoilControl = Menu::Window.LegitBotTab.WeaponSnipRecoil.GetState();

                switch (Menu::Window.LegitBotTab.WeaponSnipHitbox.GetIndex())
                {
                case 0:
                        HitBox = ((int)CSGOHitboxID::Head);
                        break;
                case 1:
                        HitBox = ((int)CSGOHitboxID::Neck);
                        break;
                case 2:
                        HitBox = ((int)CSGOHitboxID::Chest);
                        break;
                case 3:
                        HitBox = ((int)CSGOHitboxID::Stomach);
                        break;
                }
        }
        else
        {
                Speed = Menu::Window.LegitBotTab.WeaponMainSpeed.GetValue();
                FoV = Menu::Window.LegitBotTab.WeaponMainFoV.GetValue();
                RecoilControl = Menu::Window.LegitBotTab.WeaponMainRecoil.GetState();

                switch (Menu::Window.LegitBotTab.WeaponMainHitbox.GetIndex())
                {
                case 0:
                        HitBox = ((int)CSGOHitboxID::Head);
                        break;
                case 1:
                        HitBox = ((int)CSGOHitboxID::Neck);
                        break;
                case 2:
                        HitBox = ((int)CSGOHitboxID::Chest);
                        break;
                case 3:
                        HitBox = ((int)CSGOHitboxID::Stomach);
                        break;
                }
        }
}

// Functionality
void CLegitBot::DoAimbot(CUserCmd *pCmd)
{
        IClientEntity* pTarget = nullptr;
        IClientEntity* pLocal = hackManager.pLocal();
        bool FindNewTarget = true;
        //IsLocked = false;

        // Don't aimbot with the knife..
        CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
        if (pWeapon)
        {
                if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
                {
                        //TargetID = 0;
                        //pTarget = nullptr;
                        //HitBox = -1;
                        return;
                }
                SyncWeaponSettings();
                
        }
        else
                return;

        // Make sure we have a good target
        if (IsLocked && TargetID >= 0 && HitBox >= 0)
        {
                pTarget = Interfaces::EntList->GetClientEntity(TargetID);
                if (pTarget  && TargetMeetsRequirements(pTarget))
                {
                        SyncWeaponSettings();
                        if (HitBox >= 0)
                        {
                                Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
                                Vector View; Interfaces::Engine->GetViewAngles(View);
                                View += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;
                                float nFoV = FovToPlayer(ViewOffset, View, pTarget, HitBox);
                                if (nFoV < FoV)
                                        FindNewTarget = false;
                        }
                }
        }

        // Find a new target, apparently we need to
        if (FindNewTarget)
        {
                TargetID = 0;
                pTarget = nullptr;
                HitBox = -1;

                TargetID = GetTargetCrosshair();

                // Memes
                if (TargetID >= 0)
                {
                        pTarget = Interfaces::EntList->GetClientEntity(TargetID);
                }
                else
                {
                        pTarget = nullptr;
                        HitBox = -1;
                }
        }

        SyncWeaponSettings();

        // If we finally have a good target
        if (TargetID >= 0 && pTarget)
        {
                //HitBox = (int)CSGOHitboxID::Head;//
                SyncWeaponSettings();

                // Key
                if (Menu::Window.LegitBotTab.AimbotKeyPress.GetState())
                {
                        int Key = Menu::Window.LegitBotTab.AimbotKeyBind.GetKey();
                        if (Key >= 0 && !GUI.GetKeyState(Key))
                        {
                                TargetID = -1;
                                pTarget = nullptr;
                                HitBox = -1;
                                return;
                        }
                }

                Vector AimPoint = GetHitboxPosition(pTarget, HitBox);

                if (AimAtPoint(pLocal, AimPoint, pCmd))
                {
                        //IsLocked = true;
                        if (Menu::Window.LegitBotTab.AimbotAutoFire.GetState() && !(pCmd->buttons & IN_ATTACK))
                        {
                                pCmd->buttons |= IN_ATTACK;
                        }
                }
        }

        // Auto Pistol
        static bool WasFiring = false;
        CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
        if (!WeaponInfo->m_IsFullAuto && Menu::Window.LegitBotTab.AimbotAutoPistol.GetState())
        {
                if (pCmd->buttons & IN_ATTACK)
                {
                        if (WasFiring)
                        {
                                pCmd->buttons &= ~IN_ATTACK;
                        }
                }

                WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
        }
}

bool TargetMeetsTriggerRequirements(IClientEntity* pEntity)
{
        // Is a valid player
        if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
        {
                // Entity Type checks
                ClientClass *pClientClass = pEntity->GetClientClass();
                player_info_t pinfo;
                if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
                {
                        // Team Check
                        if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.LegitBotTab.AimbotFriendlyFire.GetState())
                        {
                                // Spawn Check
                                if (!pEntity->HasGunGameImmunity())
                                {
                                        return true;
                                }
                        }
                }
        }

        // They must have failed a requirement
        return false;
}

void CLegitBot::DoTrigger(CUserCmd *pCmd)
{
        IClientEntity* pLocal = hackManager.pLocal();

        // Don't triggerbot with the knife..
        CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
        if (pWeapon)
        {
                if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
                {
                        return;
                }
        }
        else
                return;

        // Triggerbot
        // Get the view with the recoil
        Vector ViewAngles;
        Interfaces::Engine->GetViewAngles(ViewAngles);
        ViewAngles += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;

        // Build a ray going fowards at that angle
        Vector fowardVec;
        AngleVectors(ViewAngles, &fowardVec);
        fowardVec *= 10000;

        // Get ray start / end
        Vector start = pLocal->GetOrigin() + pLocal->GetViewOffset();
        Vector end = start + fowardVec, endScreen;

        trace_t Trace;
        UTIL_TraceLine(start, end, MASK_SOLID, pLocal, 0, &Trace);

        if (Trace.m_pEnt && 0 < Trace.hitgroup <= 7)
        {
                if (TargetMeetsTriggerRequirements(Trace.m_pEnt))
                {
                        pCmd->buttons |= IN_ATTACK;
                }
        }

        // Auto Pistol
        static bool WasFiring = false;
        CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
        if (!WeaponInfo->m_IsFullAuto && Menu::Window.LegitBotTab.AimbotAutoPistol.GetState())
        {
                if (pCmd->buttons & IN_ATTACK)
                {
                        if (WasFiring)
                        {
                                pCmd->buttons &= ~IN_ATTACK;
                        }
                }

                WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
        }
}

bool CLegitBot::TargetMeetsRequirements(IClientEntity* pEntity)
{
        // Is a valid player
        if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
        {
                // Entity Type checks
                ClientClass *pClientClass = pEntity->GetClientClass();
                player_info_t pinfo;
                if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
                {
                        // Team Check
                        if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.LegitBotTab.AimbotFriendlyFire.GetState())
                        {
                                // Spawn Check
                                if (!pEntity->HasGunGameImmunity() && GameUtils::IsVisible(hackManager.pLocal(), pEntity, HitBox))
                                {
                                        return true;
                                }
                        }
                }
        }

        // They must have failed a requirement
        return false;
}

float CLegitBot::FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int aHitBox)
{
        // Anything past 180 degrees is just going to wrap around
        CONST FLOAT MaxDegrees = 180.0f;

        // Get local angles
        Vector Angles = View;

        // Get local view / eye position
        Vector Origin = ViewOffSet;

        // Create and intiialize vectors for calculations below
        Vector Delta(0, 0, 0);
        //Vector Origin(0, 0, 0);
        Vector Forward(0, 0, 0);

        // Convert angles to normalized directional forward vector
        AngleVectors(Angles, &Forward);
        Vector AimPos = GetHitboxPosition(pEntity, aHitBox);
        // Get delta vector between our local eye position and passed vector
        VectorSubtract(AimPos, Origin, Delta);
        //Delta = AimPos - Origin;

        // Normalize our delta vector
        Normalize(Delta, Delta);

        // Get dot product between delta position and directional forward vectors
        FLOAT DotProduct = Forward.Dot(Delta);

        // Time to calculate the field of view
        return (acos(DotProduct) * (MaxDegrees / PI));
}

int CLegitBot::GetTargetCrosshair()
{
        // Target selection
        SyncWeaponSettings();
        int target = -1;
        float minFoV = FoV;

        IClientEntity* pLocal = hackManager.pLocal();
        Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
        Vector View; Interfaces::Engine->GetViewAngles(View);
        View += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;

        for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
        {
                IClientEntity *pEntity = Interfaces::EntList->GetClientEntity(i);
                if (TargetMeetsRequirements(pEntity))
                {
                        int NewHitBox = HitBox;
                        if (NewHitBox >= 0)
                        {
                                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                                if (fov < minFoV)
                                {
                                        minFoV = fov;
                                        target = i;
                                }
                        }
                }
        }

        return target;
}

bool CLegitBot::AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd *pCmd)
{
        // Get the full angles
        if (point.Length() == 0) return false;

        Vector angles;
        Vector src = pLocal->GetOrigin() + pLocal->GetViewOffset();

        CalcAngle(src, point, angles);
        GameUtils::NormaliseViewAngle(angles);

        if (angles[0] != angles[0] || angles[1] != angles[1])
        {
                return false;
        }

        if (RecoilControl)
        {
                Vector AimPunch = pLocal->localPlayerExclusive()->GetAimPunchAngle();
                if (AimPunch.Length2D() > 0 && AimPunch.Length2D() < 150)
                {
                        angles -= AimPunch * 2;
                        GameUtils::NormaliseViewAngle(angles);
                }
        }

        IsLocked = true;
        //-----------------------------------------------

        Vector shit = angles - pCmd->viewangles;
        bool v = false;

        if (shit.Length() > Speed)
        {
                Normalize(shit, shit);
                shit *= Speed;
        }
        else
        {
                v = true;
        }

        pCmd->viewangles += shit;
        Interfaces::Engine->SetViewAngles(pCmd->viewangles);

        return v;
}
rn ICVar * CVar;
};
#include "LegitBot.h"
#include "RenderManager.h"

void CLegitBot::Init()
{
    IsLocked = false;
    TargetID = -1;
}

void CLegitBot::Draw()
{

}

void CLegitBot::Move(CUserCmd* pCmd)
{
    // Master switch
    if (!Menu::Window.LegitBotTab.Active.GetState())
        return;

    // Aimbot
    if (Menu::Window.LegitBotTab.AimbotEnable.GetState())
        DoAimbot(pCmd);

    // Triggerbot / Trigger Delay
    static size_t CustomDelay = 0;
    if (Menu::Window.LegitBotTab.TriggerEnable.GetState() && (!Menu::Window.LegitBotTab.TriggerKeyPress.GetState() || GUI.GetKeyState(Menu::Window.LegitBotTab.TriggerKeyBind.GetKey())))
    {

        if (Menu::Window.LegitBotTab.TriggerDelay.GetValue() > 1)
        {
            if (GetTickCount() > CustomDelay)
            {

                DoTrigger(pCmd);
                CustomDelay = GetTickCount() + Menu::Window.LegitBotTab.TriggerDelay.GetValue();
            }
        }
        else
            DoTrigger(pCmd);
    }
}

void CLegitBot::SyncWeaponSettings()
{
    IClientEntity* pLocal = hackManager.pLocal();
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());

    if (!pWeapon)
        return;

    if (GameUtils::IsPistol(pWeapon))
    {
        Speed = Menu::Window.LegitBotTab.WeaponPistSpeed.GetValue();
        FoV = Menu::Window.LegitBotTab.WeaponPistFoV.GetValue();
        RecoilControl = Menu::Window.LegitBotTab.WeaponPistRecoil.GetState();

        switch (Menu::Window.LegitBotTab.WeaponPistHitbox.GetIndex())
        {
            case 0:
                HitBox = ((int)CSGOHitboxID::Head);
                break;
            case 1:
                HitBox = ((int)CSGOHitboxID::Neck);
                break;
            case 2:
                HitBox = ((int)CSGOHitboxID::Chest);
                break;
            case 3:
                HitBox = ((int)CSGOHitboxID::Stomach);
                break;
        }
    }
    else if (GameUtils::IsSniper(pWeapon))
    {
        Speed = Menu::Window.LegitBotTab.WeaponSnipSpeed.GetValue();
        FoV = Menu::Window.LegitBotTab.WeaponSnipFoV.GetValue();
        RecoilControl = Menu::Window.LegitBotTab.WeaponSnipRecoil.GetState();

        switch (Menu::Window.LegitBotTab.WeaponSnipHitbox.GetIndex())
        {
            case 0:
                HitBox = ((int)CSGOHitboxID::Head);
                break;
            case 1:
                HitBox = ((int)CSGOHitboxID::Neck);
                break;
            case 2:
                HitBox = ((int)CSGOHitboxID::Chest);
                break;
            case 3:
                HitBox = ((int)CSGOHitboxID::Stomach);
                break;
        }
    }
    else
    {
        Speed = Menu::Window.LegitBotTab.WeaponMainSpeed.GetValue();
        FoV = Menu::Window.LegitBotTab.WeaponMainFoV.GetValue();
        RecoilControl = Menu::Window.LegitBotTab.WeaponMainRecoil.GetState();

        switch (Menu::Window.LegitBotTab.WeaponMainHitbox.GetIndex())
        {
            case 0:
                HitBox = ((int)CSGOHitboxID::Head);
                break;
            case 1:
                HitBox = ((int)CSGOHitboxID::Neck);
                break;
            case 2:
                HitBox = ((int)CSGOHitboxID::Chest);
                break;
            case 3:
                HitBox = ((int)CSGOHitboxID::Stomach);
                break;
        }
    }
}

// Functionality
void CLegitBot::DoAimbot(CUserCmd* pCmd)
{
    IClientEntity* pTarget = nullptr;
    IClientEntity* pLocal = hackManager.pLocal();
    bool FindNewTarget = true;
    //IsLocked = false;

    // Don't aimbot with the knife..
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
    if (pWeapon)
    {
        if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
        {
            //TargetID = 0;
            //pTarget = nullptr;
            //HitBox = -1;
            return;
        }
        SyncWeaponSettings();

    }
    else
        return;

    // Make sure we have a good target
    if (IsLocked && TargetID >= 0 && HitBox >= 0)
    {
        pTarget = Interfaces::EntList->GetClientEntity(TargetID);
        if (pTarget && TargetMeetsRequirements(pTarget))
        {
            SyncWeaponSettings();
            if (HitBox >= 0)
            {
                Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
                Vector View; Interfaces::Engine->GetViewAngles(View);
                View += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;
                float nFoV = FovToPlayer(ViewOffset, View, pTarget, HitBox);
                if (nFoV < FoV)
                    FindNewTarget = false;
            }
        }
    }

    // Find a new target, apparently we need to
    if (FindNewTarget)
    {
        TargetID = 0;
        pTarget = nullptr;
        HitBox = -1;

        TargetID = GetTargetCrosshair();

        // Memes
        if (TargetID >= 0)
        {
            pTarget = Interfaces::EntList->GetClientEntity(TargetID);
        }
        else
        {
            pTarget = nullptr;
            HitBox = -1;
        }
    }

    SyncWeaponSettings();

    // If we finally have a good target
    if (TargetID >= 0 && pTarget)
    {
        //HitBox = (int)CSGOHitboxID::Head;//
        SyncWeaponSettings();

        // Key
        if (Menu::Window.LegitBotTab.AimbotKeyPress.GetState())
        {
            int Key = Menu::Window.LegitBotTab.AimbotKeyBind.GetKey();
            if (Key >= 0 && !GUI.GetKeyState(Key))
            {
                TargetID = -1;
                pTarget = nullptr;
                HitBox = -1;
                return;
            }
        }

        Vector AimPoint = GetHitboxPosition(pTarget, HitBox);

        if (AimAtPoint(pLocal, AimPoint, pCmd))
        {
            //IsLocked = true;
            if (Menu::Window.LegitBotTab.AimbotAutoFire.GetState() && !(pCmd->buttons & IN_ATTACK))
            {
                pCmd->buttons |= IN_ATTACK;
            }
        }
    }

    // Auto Pistol
    static bool WasFiring = false;
    CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
    if (!WeaponInfo->m_IsFullAuto && Menu::Window.LegitBotTab.AimbotAutoPistol.GetState())
    {
        if (pCmd->buttons & IN_ATTACK)
        {
            if (WasFiring)
            {
                pCmd->buttons &= ~IN_ATTACK;
            }
        }

        WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
    }
}

bool TargetMeetsTriggerRequirements(IClientEntity* pEntity)
{
    // Is a valid player
    if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
    {
        // Entity Type checks
        ClientClass* pClientClass = pEntity->GetClientClass();
        player_info_t pinfo;
        if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
        {
            // Team Check
            if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.LegitBotTab.AimbotFriendlyFire.GetState())
            {
                // Spawn Check
                if (!pEntity->HasGunGameImmunity())
                {
                    return true;
                }
            }
        }
    }

    // They must have failed a requirement
    return false;
}

void CLegitBot::DoTrigger(CUserCmd* pCmd)
{
    IClientEntity* pLocal = hackManager.pLocal();

    // Don't triggerbot with the knife..
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
    if (pWeapon)
    {
        if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
        {
            return;
        }
    }
    else
        return;

    // Triggerbot
    // Get the view with the recoil
    Vector ViewAngles;
    Interfaces::Engine->GetViewAngles(ViewAngles);
    ViewAngles += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;

    // Build a ray going fowards at that angle
    Vector fowardVec;
    AngleVectors(ViewAngles, &fowardVec);
    fowardVec *= 10000;

    // Get ray start / end
    Vector start = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector end = start + fowardVec, endScreen;

    trace_t Trace;
    UTIL_TraceLine(start, end, MASK_SOLID, pLocal, 0, &Trace);

    if (Trace.m_pEnt && 0 < Trace.hitgroup <= 7)
    {
        if (TargetMeetsTriggerRequirements(Trace.m_pEnt))
        {
            pCmd->buttons |= IN_ATTACK;
        }
    }

    // Auto Pistol
    static bool WasFiring = false;
    CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
    if (!WeaponInfo->m_IsFullAuto && Menu::Window.LegitBotTab.AimbotAutoPistol.GetState())
    {
        if (pCmd->buttons & IN_ATTACK)
        {
            if (WasFiring)
            {
                pCmd->buttons &= ~IN_ATTACK;
            }
        }

        WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
    }
}

bool CLegitBot::TargetMeetsRequirements(IClientEntity* pEntity)
{
    // Is a valid player
    if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
    {
        // Entity Type checks
        ClientClass* pClientClass = pEntity->GetClientClass();
        player_info_t pinfo;
        if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
        {
            // Team Check
            if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.LegitBotTab.AimbotFriendlyFire.GetState())
            {
                // Spawn Check
                if (!pEntity->HasGunGameImmunity() && GameUtils::IsVisible(hackManager.pLocal(), pEntity, HitBox))
                {
                    return true;
                }
            }
        }
    }

    // They must have failed a requirement
    return false;
}

float CLegitBot::FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int aHitBox)
{
    // Anything past 180 degrees is just going to wrap around
    CONST FLOAT MaxDegrees = 180.0f;

    // Get local angles
    Vector Angles = View;

    // Get local view / eye position
    Vector Origin = ViewOffSet;

    // Create and intiialize vectors for calculations below
    Vector Delta(0, 0, 0);
    //Vector Origin(0, 0, 0);
    Vector Forward(0, 0, 0);

    // Convert angles to normalized directional forward vector
    AngleVectors(Angles, &Forward);
    Vector AimPos = GetHitboxPosition(pEntity, aHitBox);
    // Get delta vector between our local eye position and passed vector
    VectorSubtract(AimPos, Origin, Delta);
    //Delta = AimPos - Origin;

    // Normalize our delta vector
    Normalize(Delta, Delta);

    // Get dot product between delta position and directional forward vectors
    FLOAT DotProduct = Forward.Dot(Delta);

    // Time to calculate the field of view
    return (acos(DotProduct) * (MaxDegrees / PI));
}

int CLegitBot::GetTargetCrosshair()
{
    // Target selection
    SyncWeaponSettings();
    int target = -1;
    float minFoV = FoV;

    IClientEntity* pLocal = hackManager.pLocal();
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector View; Interfaces::Engine->GetViewAngles(View);
    View += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        if (TargetMeetsRequirements(pEntity))
        {
            int NewHitBox = HitBox;
            if (NewHitBox >= 0)
            {
                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                if (fov < minFoV)
                {
                    minFoV = fov;
                    target = i;
                }
            }
        }
    }

    return target;
}

bool CLegitBot::AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd* pCmd)
{
    // Get the full angles
    if (point.Length() == 0) return false;

    Vector angles;
    Vector src = pLocal->GetOrigin() + pLocal->GetViewOffset();

    CalcAngle(src, point, angles);
    GameUtils::NormaliseViewAngle(angles);

    if (angles[0] != angles[0] || angles[1] != angles[1])
    {
        return false;
    }

    if (RecoilControl)
    {
        Vector AimPunch = pLocal->localPlayerExclusive()->GetAimPunchAngle();
        if (AimPunch.Length2D() > 0 && AimPunch.Length2D() < 150)
        {
            angles -= AimPunch * 2;
            GameUtils::NormaliseViewAngle(angles);
        }
    }

    IsLocked = true;
    //-----------------------------------------------

    Vector shit = angles - pCmd->viewangles;
    bool v = false;

    if (shit.Length() > Speed)
    {
        Normalize(shit, shit);
        shit *= Speed;
    }
    else
    {
        v = true;
    }

    pCmd->viewangles += shit;
    Interfaces::Engine->SetViewAngles(pCmd->viewangles);

    return v;
}
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

class CLegitBot : public CHack
{
public:
        void Init();
void Draw();
void Move(CUserCmd* pCmd);
private:
        // Targetting
        int GetTargetCrosshair();
bool TargetMeetsRequirements(IClientEntity* pEntity);
float FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int HitBox);
bool AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd* pCmd);

void SyncWeaponSettings();

// Functionality
void DoAimbot(CUserCmd* pCmd);
void DoTrigger(CUserCmd* pCmd);

// Aimbot
bool IsLocked;
int TargetID;
int HitBox;
Vector AimPoint;

float Speed;
float FoV;
bool RecoilControl;

};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"
#include "MiscClasses.h"
#include "Vector2D.h"


class IMaterial
{
    public:
        const char* GetName()
        {

        typedef const char*(__thiscall * oGetName)(PVOID);
                return call_vfunc(this, Offsets::VMT::Material_GetName)(this);
        }

void SetMaterialVarFlag(MaterialVarFlags_t flag, bool value)
{
    typedef void(__thiscall * oSetMatFlag)(PVOID, MaterialVarFlags_t, bool);
    return call_vfunc(this, Offsets::VMT::Material_SetMaterialVarFlag)(this, flag, value);
}

bool GetMaterialVarFlag(MaterialVarFlags_t flag)
{
    typedef bool(__thiscall * oGetMatFlag)(PVOID, MaterialVarFlags_t);
    return call_vfunc(this, Offsets::VMT::Material_GetMaterialVarFlag)(this, flag);
}

void AlphaModulate(float a)
{
    typedef void(__thiscall * oAlphaModulate)(PVOID, float);
    return call_vfunc(this, Offsets::VMT::Material_AlphaModulate)(this, a);
}

void ColorModulate(float r, float g, float b)
{
    typedef void(__thiscall * oColorModulate)(PVOID, float, float, float);
    return call_vfunc(this, Offsets::VMT::Material_ColorModulate)(this, r, g, b);
}

void IncrementReferenceCount(void)
{
    typedef void(__thiscall * oIncrementReferenceCount)(PVOID);
    return call_vfunc(this, Offsets::VMT::Material_IncrementReferenceCount)(this);
}
};

class CMaterialSystem
{
    public:
        IMaterial* FindMaterial(char const* pMaterialName, const char* pTextureGroupName, bool complain = true, const char* pComplainPrefix = NULL)
        {

        typedef IMaterial*(__thiscall* oFindMaterial)(PVOID, char const*, char const*, bool, char const*);
                return call_vfunc(this, Offsets::VMT::MaterialSystem_FindMaterial)(this, pMaterialName, pTextureGroupName, complain, pComplainPrefix);
        }

IMaterial* CreateMaterial(const char* pMaterialName, KeyValues* pVMTKeyValues)
{
    typedef IMaterial*(__thiscall * oCreateMaterial)(PVOID, const char*, KeyValues*);
    return call_vfunc(this, Offsets::VMT::MaterialSystem_CreateMaterial)(this, pMaterialName, pVMTKeyValues);
}
};

class IVModelRender
{
    public:
        void ForcedMaterialOverride(IMaterial* material, OverrideType_t type = OVERRIDE_NORMAL, int idk = NULL)
    {
        typedef void(__thiscall * Fn)(void*, IMaterial*, OverrideType_t, int);
        return call_vfunc(this, Offsets::VMT::ModelRender_ForcedMaterialOverride)(this, material, type, idk);
    }

};

class CModelInfo
{
    public:
        int GetModelIndex(const char* name)
        {

        typedef int (__thiscall* oGetModelName)(PVOID, const char*);
                return call_vfunc(this, 2)(this, name);
        }
const char* GetModelName(const model_t * mod)
        {
                typedef const char*(__thiscall * oGetModelName)(PVOID, const model_t *);
                return call_vfunc(this, Offsets::VMT::ModelInfo_GetModelName)(this, mod);
}

studiohdr_t* GetStudiomodel(const model_t* mod)
{
    typedef studiohdr_t *(__stdcall * oGetStudiomodel)(const model_t*);
    return call_vfunc(this, Offsets::VMT::ModelInfo_GetStudiomodel)(mod);
}
};

class CVRenderView
{
    public:
        void SetBlend(float alpha)
    {
        typedef void(__thiscall * oDrawModelExecute)(PVOID, float);
        return call_vfunc(this, Offsets::VMT::RenderView_SetBlend)(this, alpha);
    }

    void SetColorModulation(float const* colors)
        {

        typedef void(__thiscall* oDrawModelExecute)(PVOID, float const*);
                return call_vfunc(this, Offsets::VMT::RenderView_SetColorModulation)(this, colors);
        }
};#include "MathFunctions.h"

void AngleVectors(const Vector &angles, Vector* forward)
{
    Assert(s_bMathlibInitialized);
    Assert(forward);

    float sp, sy, cp, cy;

    sy = sin(DEG2RAD(angles[1]));
    cy = cos(DEG2RAD(angles[1]));

    sp = sin(DEG2RAD(angles[0]));
    cp = cos(DEG2RAD(angles[0]));

    forward->x = cp * cy;
    forward->y = cp * sy;
    forward->z = -sp;
}

void VectorTransform(const Vector in1, float in2[3][4], Vector &out)
{
        out[0] = DotProduct(in1, Vector(in2[0][0], in2[0][1], in2[0][2])) + in2[0][3];
        out[1] = DotProduct(in1, Vector(in2[1][0], in2[1][1], in2[1][2])) + in2[1][3];
        out[2] = DotProduct(in1, Vector(in2[2][0], in2[2][1], in2[2][2])) + in2[2][3];
}

void SinCos(float a, float* s, float* c)
{
    *s = sin(a);
    *c = cos(a);
}

void VectorAngles(Vector forward, Vector &angles)
{
    float tmp, yaw, pitch;

    if (forward[2] == 0 && forward[0] == 0)
    {
        yaw = 0;

        if (forward[2] > 0)
            pitch = 90;
        else
            pitch = 270;
    }
    else
    {
        yaw = (atan2(forward[1], forward[0]) * 180 / PI);

        if (yaw < 0)
            yaw += 360;

        tmp = sqrt(forward[0] * forward[0] + forward[1] * forward[1]);
        pitch = (atan2(-forward[2], tmp) * 180 / PI);

        if (pitch < 0)
            pitch += 360;
    }

    if (pitch > 180)
        pitch -= 360;
    else if (pitch < -180)
        pitch += 360;

    if (yaw > 180)
        yaw -= 360;
    else if (yaw < -180)
        yaw += 360;

    if (pitch > 89)
        pitch = 89;
    else if (pitch < -89)
        pitch = -89;

    if (yaw > 180)
        yaw = 180;
    else if (yaw < -180)
        yaw = -180;

    angles[0] = pitch;
    angles[1] = yaw;
    angles[2] = 0;
}

void AngleVectors(const Vector &angles, Vector* forward, Vector* right, Vector* up)
{
    float sr, sp, sy, cr, cp, cy;

    SinCos(DEG2RAD(angles[1]), &sy, &cy);
    SinCos(DEG2RAD(angles[0]), &sp, &cp);
    SinCos(DEG2RAD(angles[2]), &sr, &cr);

    if (forward)
    {
        forward->x = cp * cy;
        forward->y = cp * sy;
        forward->z = -sp;
    }

    if (right)
    {
        right->x = (-1 * sr * sp * cy + -1 * cr * -sy);
        right->y = (-1 * sr * sp * sy + -1 * cr * cy);
        right->z = -1 * sr * cp;
    }

    if (up)
    {
        up->x = (cr * sp * cy + -sr * -sy);
        up->y = (cr * sp * sy + -sr * cy);
        up->z = cr * cp;
    }
}

void Normalize(Vector &vIn, Vector &vOut)
{
    float flLen = vIn.Length();
    if (flLen == 0)
    {
        vOut.Init(0, 0, 1);
        return;
    }
    flLen = 1 / flLen;
    vOut.Init(vIn.x * flLen, vIn.y * flLen, vIn.z * flLen);
}


void CalcAngle(Vector src, Vector dst, Vector &angles)
{
    Vector delta = src - dst;
    double hyp = delta.Length2D();
    angles.y = (atan(delta.y / delta.x) * 57.295779513082f);
    angles.x = (atan(delta.z / hyp) * 57.295779513082f);
    angles[2] = 0.00;

    if (delta.x >= 0.0)
        angles.y += 180.0f;
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Vector.h"

#include 

#define PI 3.14159265358979323846f
#define DEG2RAD( x ) ( ( float )( x ) * ( float )( ( float )( PI ) / 180.0f ) )
#define RAD2DEG( x ) ( ( float )( x ) * ( float )( 180.0f / ( float )( PI ) ) )
#define RADPI 57.295779513082f

void AngleVectors(const Vector &angles, Vector* forward);
void VectorTransform(const Vector in1, float in2[3][4], Vector &out);
void SinCos(float a, float* s, float* c);
void VectorAngles(Vector forward, Vector &angles);
void AngleVectors(const Vector &angles, Vector* forward, Vector* right, Vector* up);
void Normalize(Vector &vIn, Vector &vOut);
void CalcAngle(Vector src, Vector dst, Vector &angles);
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "GUI.h"
#include "Controls.h"

class CRageBotTab : public CTab
{
public:
        void Setup();

// Master Switch
CLabel ActiveLabel;
CCheckBox Active;

// Aimbot Settings
CGroupBox AimbotGroup;
CCheckBox AimbotEnable;
CCheckBox AimbotAutoFire;
CSlider AimbotFov;
CCheckBox AimbotSilentAim;
CCheckBox AimbotPSilent;
CCheckBox AimbotAutoPistol;
CCheckBox AimbotAimStep;
CCheckBox AimbotKeyPress;
CKeyBind AimbotKeyBind;
CCheckBox AimbotChicken;

// Target Selection Settings
CGroupBox TargetGroup;
CComboBox TargetSelection;
CCheckBox TargetFriendlyFire;
CComboBox TargetHitbox;
CComboBox TargetHitscan;

// Accuracy Settings
CGroupBox AccuracyGroup;
CCheckBox AccuracySpread;
CCheckBox AccuracyRecoil;
CCheckBox AccuracyAutoWall;
CSlider AccuracyMinimumDamage;
CCheckBox AccuracyAutoStop;
CCheckBox AccuracyAutoCrouch;
CCheckBox AccuracyAutoScope;
CCheckBox AccuracySpreadLimit;
CSlider AccuracyMinimumSpread;
CCheckBox AccuracyAngleFix;


// Anti-Aim Settings
CGroupBox AntiAimGroup;
CCheckBox AntiAimEnable;
CComboBox AntiAimPitch;
CComboBox AntiAimYaw;
};

class CLegitBotTab : public CTab
{
public:
        void Setup();

// Master Switch
CLabel ActiveLabel;
CCheckBox Active;

// Aimbot Settings
CGroupBox AimbotGroup;
CCheckBox AimbotEnable;
CCheckBox AimbotAutoFire;
CCheckBox AimbotFriendlyFire;
CCheckBox AimbotKeyPress;
CKeyBind AimbotKeyBind;
CCheckBox AimbotAutoPistol;

// Main
CGroupBox TriggerGroup;
CCheckBox TriggerEnable;
CCheckBox TriggerKeyPress;
CKeyBind TriggerKeyBind;
CSlider TriggerDelay;

// Main
CGroupBox WeaponMainGroup;
CSlider WeaponMainSpeed;
CSlider WeaponMainFoV;
CCheckBox WeaponMainRecoil;
CComboBox WeaponMainHitbox;

// Pistol
CGroupBox WeaponPistGroup;
CSlider WeaponPistSpeed;
CSlider WeaponPistFoV;
CCheckBox WeaponPistRecoil;
CComboBox WeaponPistHitbox;

// Sniper
CGroupBox WeaponSnipGroup;
CSlider WeaponSnipSpeed;
CSlider WeaponSnipFoV;
CCheckBox WeaponSnipRecoil;
CComboBox WeaponSnipHitbox;

};

class CVisualTab : public CTab
{
public:
        void Setup();

// Master Switch
CLabel ActiveLabel;
CCheckBox Active;

// Options Settings
CGroupBox OptionsGroup;
CCheckBox OptionsBox;
CCheckBox OptionsName;
CCheckBox OptionsHealth;
CCheckBox OptionsWeapon;
CCheckBox OptionsInfo;
CComboBox OptionsChams;
CCheckBox OptionsSkeleton;
CCheckBox OptionsAimSpot;
CCheckBox OptionsCompRank;

// Filters Settings
CGroupBox FiltersGroup;
CCheckBox FiltersAll;
CCheckBox FiltersPlayers;
CCheckBox FiltersEnemiesOnly;
CCheckBox FiltersWeapons;
CCheckBox FiltersChickens;
CCheckBox FiltersC4;

// Other Settings
CGroupBox OtherGroup;
CCheckBox OtherCrosshair;
CComboBox OtherRecoilCrosshair;
CCheckBox OtherRadar;
CCheckBox OtherNoVisualRecoil;
CCheckBox OtherNoSky;
CCheckBox OtherNoFlash;
CCheckBox OtherNoSmoke;
CComboBox OtherNoHands;
CCheckBox OtherAutoJump;
CCheckBox OtherAutoStrafe;
CCheckBox OtherSafeMode;
CComboBox OtherChatSpam;
CKeyBind OtherAirStuck;
CCheckBox OtherSpectators;
};

class CMiscTab : public CTab
{
public:
        void Setup();

// Fake Lag Settings
CGroupBox FakeLagGroup;
CCheckBox FakeLagEnable;
CSlider FakeLagAmount;
CCheckBox FakeLagWhileShooting;

// Knife Changer/Skin Changer
CGroupBox KnifeGroup;
CCheckBox KnifeEnable;
CComboBox KnifeModel;
CComboBox KnifeSkin;
CComboBox M41SSkin;
CComboBox M4A4Skin;
CComboBox AK47Skin;
CComboBox AWPSkin;
CComboBox GLOCKSkin;
CComboBox USPSSkin;
CComboBox DEAGLESkin;
CComboBox MAGNUMSkin;
CButton KnifeApply;
};

class AimWareWindow : public CWindow
{
public:
        void Setup();

CRageBotTab RageBotTab;
CLegitBotTab LegitBotTab;
CVisualTab VisualsTab;
CMiscTab MiscTab;

CButton SaveButton;
CButton LoadButton;
CButton UnloadButton;
};

namespace Menu
{
    void SetupMenu();
    void DoUIFrame();

        extern AimWareWindow Window;
};/*
Syn's AYYWAREFramework
*/
#include "Utilities.h"

#define AimWare_META_GAME "Counter-Strike: Global Offensive"

void PrintMetaHeader()
{
    printf("                                  Ayy");
    Utilities::SetConsoleColor(FOREGROUND_INTENSE_GREEN);
    printf("Ware\n");
    Utilities::SetConsoleColor(FOREGROUND_WHITE);
    Utilities::Log("Build %s", __DATE__);
    Utilities::Log("Setting Up AYYWAREfor %s", AimWare_META_GAME);
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"
#include "bspflags.h"

// Entity List
class IClientEntityList
{
    public:
        virtual void Function0();
    virtual void Function1();
    virtual void Function2();
    virtual IClientEntity* GetClientEntity(int entnum);
    virtual IClientEntity* GetClientEntityFromHandle(HANDLE hEnt) = 0;
        virtual int NumberOfEntities(bool bIncludeNonNetworkable) = 0;
        virtual int GetHighestEntityIndex(void);
    virtual void SetMaxEntities(int maxents);
    virtual int GetMaxEntities();
};

// Panels
class IPanel
{
    public:
        const char* GetName(unsigned int vguiPanel)
        {

        typedef const char* (__thiscall * OriginalFn)(PVOID, unsigned int);
                return call_vfunc(this, Offsets::VMT::Panel_GetName)(this, vguiPanel);
        }
};

// Colors
class Color
{
    public:
        // constructors
        Color()
    {
        *((int*)this) = 0;
    }
    Color(int r, int g, int b)
    {
        SetColor(r, g, b, 0);
    }
    Color(int r, int g, int b, int a)
    {
        SetColor(r, g, b, a);
    }
    void SetColor(int r, int g, int b, int a = 0)
    {
        _color[0] = (unsigned char)r;
        _color[1] = (unsigned char)g;
        _color[2] = (unsigned char)b;
        _color[3] = (unsigned char)a;
    }

    void GetColor(int &r, int &g, int &b, int &a) const
        {

        r = _color[0];
                g = _color[1];
                b = _color[2];
                a = _color[3];
        }

void SetRawColor(int color32)
{
    *((int*)this) = color32;
}

int GetRawColor() const
        {
                return *((int*)this);
}

inline int r() const    { return _color[0]; }
        inline int g() const    { return _color[1]; }
        inline int b() const    { return _color[2]; }
        inline int a() const    { return _color[3]; }

        void SetAlpha(int a) { _color[0] = (unsigned char)a; }
int GetAlpha() { return _color[0]; }


unsigned char &operator[] (int index)
{
    return _color[index];
}

const unsigned char &operator[] (int index) const
        {
                return _color[index];
        }

        bool operator ==(const Color &rhs) const
        {
                return (*((int*)this) == *((int *)&rhs));
}

bool operator !=(const Color &rhs) const
        {
                return !(operator ==(rhs));
        }

        Color &operator=(const Color &rhs)
{
    SetRawColor(rhs.GetRawColor());
    return *this;
}

private:
        unsigned char _color[4];
};

// Debug Overlay
class IVDebugOverlay
{
    public:
        virtual void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0;
    virtual void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, int r, int g, int b, int a, float duration) = 0;
    virtual void AddSphereOverlay(const Vector& vOrigin, float flRadius, int nTheta, int nPhi, int r, int g, int b, int a, float flDuration) = 0;
    virtual void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) = 0;
    virtual void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, bool noDepthTest, float duration) = 0;
    virtual void AddTextOverlay(const Vector& origin, float duration, const char* format, ...) = 0;
    virtual void AddTextOverlay(const Vector& origin, int line_offset, float duration, const char* format, ...) = 0;
    virtual void AddScreenTextOverlay(float flXPos, float flYPos, float flDuration, int r, int g, int b, int a, const char* text) = 0;
    virtual void AddSweptBoxOverlay(const Vector& start, const Vector& end, const Vector& mins, const Vector& max, const Vector & angles, int r, int g, int b, int a, float flDuration) = 0;
    virtual void AddGridOverlay(const Vector& origin) = 0;
        virtual void AddCoordFrameOverlay(const matrix3x4& frame, float flScale, int vColorTable[3][3] = NULL) = 0;

        virtual int ScreenPosition(const Vector& point, Vector& screen) = 0;
        virtual int ScreenPosition(float flXPos, float flYPos, Vector& screen) = 0;

        virtual void* GetFirst(void) = 0;
        virtual void* GetNext(void* current) = 0;
        virtual void ClearDeadOverlays(void) = 0;
        virtual void ClearAllOverlays() = 0;

        virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, const char* format, ...) = 0;
    virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0;

    virtual void AddLineOverlayAlpha(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float duration) = 0;
    virtual void AddBoxOverlay2(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, const Color& faceColor, const Color& edgeColor, float duration) = 0;

    virtual void PurgeTextOverlays() = 0;
};

// User Cmd's
class CUserCmd
{
    public:
        virtual ~CUserCmd() { }; //Destructor 0
    CUserCmd()
    {
        Reset();
    }

    void Reset()
    {
        command_number = 0;
        tick_count = 0;
        viewangles.Init();
        forwardmove = 0.0f;
        sidemove = 0.0f;
        upmove = 0.0f;
        buttons = 0;
        impulse = 0;
        weaponselect = 0;
        weaponsubtype = 0;
        random_seed = 0;
        mousedx = 0;
        mousedy = 0;
        headangles.Init();
        headoffset.Init();

        hasbeenpredicted = false;
    }

    CUserCmd& operator =(const CUserCmd& src)
        {
                if (this == &src)
                        return *this;

                command_number = src.command_number;
                tick_count = src.tick_count;
                viewangles = src.viewangles;
                forwardmove = src.forwardmove;
                sidemove = src.sidemove;
                upmove = src.upmove;
                buttons = src.buttons;
                impulse = src.impulse;
                weaponselect = src.weaponselect;
                weaponsubtype = src.weaponsubtype;
                random_seed = src.random_seed;
                mousedx = src.mousedx;
                mousedy = src.mousedy;

                hasbeenpredicted = src.hasbeenpredicted;
                headangles = src.headangles;
                headoffset = src.headoffset;
                return *this;
        }


    CUserCmd(const CUserCmd& src)
{
    *this = src;
}


int command_number;
int tick_count;
Vector viewangles;
Vector aimdirection;
float forwardmove;
float sidemove;
float upmove;
int buttons;
BYTE impulse;
int weaponselect;
int weaponsubtype;
int random_seed;
short mousedx;
short mousedy;
bool hasbeenpredicted;
Vector headangles;
Vector headoffset;
};

class CGlobalVarsBase
{
    public:
        float realtime;
    int framecount;
    float absoluteframetime;
    float absoluteframestarttimestddev;
    float curtime;
    float frametime;
    int maxClients;
    int tickcount;
    float interval_per_tick;
    float interpolation_amount;
    int simTicksThisFrame;
    int network_protocol;
    void* pSaveData;
    bool m_bClient;
    int nTimestampNetworkingBase;
    int nTimestampRandomizeWindow;
};

struct Ray_t
{

    __declspec(align(16)) Vector m_Start;

    __declspec(align(16)) Vector m_Delta;

    __declspec(align(16)) Vector m_StartOffset;

    __declspec(align(16)) Vector m_Extents;
    //without your matrix3x4
    bool m_IsRay;
    bool m_IsSwept;

    void Init(Vector& vecStart, Vector& vecEnd)
    {
        m_Delta = vecEnd - vecStart;

        m_IsSwept = (m_Delta.LengthSqr() != 0);

        m_Extents.x = m_Extents.y = m_Extents.z = 0.0f;

        m_IsRay = true;

        m_StartOffset.x = m_StartOffset.y = m_StartOffset.z = 0.0f;

        m_Start = vecStart;
    }
};

struct cplane_t
{
    Vector normal;
    float dist;
    BYTE type;
    BYTE signbits;
    BYTE pad[2];
};

class CBaseTrace
{
    public:
        Vector startpos;
    Vector endpos;
    cplane_t plane;
    float fraction;
    int contents;
    unsigned short dispFlags;
    bool allsolid;
    bool startsolid;
};

struct csurface_t
{
    const char* name;
    short surfaceProps;
    unsigned short flags;
};

class CGameTrace : public CBaseTrace
{
public:
        bool DidHitWorld() const;
bool DidHitNonWorldEntity() const;
int GetEntityIndex() const;
bool DidHit() const;
public:
        float fractionleftsolid;
csurface_t surface;
int hitgroup;
short physicsbone;
unsigned short worldSurfaceIndex;
IClientEntity* m_pEnt;
int hitbox;
char shit[0x24];
};

inline bool CGameTrace::DidHit() const
{
        return fraction< 1.0f || allsolid || startsolid;
}

typedef CGameTrace trace_t;

enum TraceType_t
{
    TRACE_EVERYTHING = 0,
    TRACE_WORLD_ONLY,
    TRACE_ENTITIES_ONLY,
    TRACE_EVERYTHING_FILTER_PROPS,
};

class ITraceFilter
{
    public:
        virtual bool ShouldHitEntity(IClientEntity* pEntity, int contentsMask) = 0;
        virtual TraceType_t GetTraceType() const = 0;
};

class CTraceFilter : public ITraceFilter
{
public:
        bool ShouldHitEntity(IClientEntity* pEntityHandle, int contentsMask)
{
    return !(pEntityHandle == pSkip);
}

TraceType_t GetTraceType() const
        {
                return TRACE_EVERYTHING;
        }

        void* pSkip;
};

class IEngineTrace
{
    public:
        int GetPointContents(const Vector &vecAbsPosition, int contentsMask = MASK_ALL, IClientEntity** ppEntity = NULL)
        {
                typedef int(__thiscall* fnGetPointContents)(void*, const Vector&, int, IClientEntity**);
                return call_vfunc(this, 0)(this, vecAbsPosition, contentsMask, ppEntity);
        }

void TraceRay(const Ray_t &ray, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace)
{
    typedef void(__thiscall * fnTraceRay)(void*, const Ray_t&, unsigned int, ITraceFilter*, trace_t *);
    call_vfunc(this, 5)(this, ray, fMask, pTraceFilter, pTrace);
}
};

struct mstudiobbox_t
{
    int bone;
    int group;
    Vector bbmin;
    Vector bbmax;
    int szhitboxnameindex;
    int unused[8];

    char* GetHitboxName(void)
    {
        if (szhitboxnameindex == 0)
            return "";

        return ((char*)this) + szhitboxnameindex;
    }
};
struct mstudiohitboxset_t
{
    int sznameindex;
    inline char* const GetName(void) const { return ((char*)this) + sznameindex; }
int numhitboxes;
int hitboxindex;
inline mstudiobbox_t* GetHitbox(int i) const { return (mstudiobbox_t*)(((byte*)this) + hitboxindex) + i; };
};
struct mstudiobone_t
{
    int sznameindex;
    inline char* const GetName(void) const { return ((char*)this) + sznameindex; }
int parent;
int bonecontroller[6];

Vector pos;
float quat[4];
Vector rot;
Vector posscale;
Vector rotscale;

matrix3x4 poseToBone;
float qAlignment[4];
int flags;
int proctype;
int procindex;              // procedural rule
mutable int physicsbone;    // index into physically simulated bone
inline void* GetProcedure() const { if (procindex == 0) return NULL; else return  (void*)(((byte*)this) + procindex); };
int surfacepropidx; // index into string tablefor property name
inline char* const GetSurfaceProps(void) const { return ((char*)this) + surfacepropidx; }
        int contents;               // See BSPFlags.h for the contents flags

int unused[8];              // remove as appropriate
};
struct studiohdr_t
{
    int id;
    int version;

    int checksum;

    char name[64];
    int length;


    Vector eyeposition;

    Vector illumposition;

    Vector hull_min;
    Vector hull_max;

    Vector view_bbmin;
    Vector view_bbmax;

    int flags;

    int numbones;
    int boneindex;

    inline mstudiobone_t *GetBone(int i) const { return (mstudiobone_t*)(((byte*)this) + boneindex) + i; };
//        inline mstudiobone_t *pBone(int i) const { Assert(i >= 0 && i < numbones); return (mstudiobone_t *)(((byte *)this) + boneindex) + i; };

int numbonecontrollers;
int bonecontrollerindex;

int numhitboxsets;
int hitboxsetindex;

mstudiohitboxset_t* GetHitboxSet(int i) const
        {
                return (mstudiohitboxset_t*)(((byte*)this) + hitboxsetindex) + i;
}

inline mstudiobbox_t* GetHitbox(int i, int set) const
        {
                mstudiohitboxset_t const* s = GetHitboxSet(set);

                if (!s)
                        return NULL;

                return s->GetHitbox(i);
        }

        inline int GetHitboxCount(int set) const
        {
                mstudiohitboxset_t const* s = GetHitboxSet(set);

                if (!s)
                        return 0;

                return s->numhitboxes;
        }

        int numlocalanim;
int localanimindex;

int numlocalseq;
int localseqindex;

mutable int activitylistversion;
mutable int eventsindexed;

int numtextures;
int textureindex;

int numcdtextures;
int cdtextureindex;

int numskinref;
int numskinfamilies;
int skinindex;

int numbodyparts;
int bodypartindex;

int numlocalattachments;
int localattachmentindex;

int numlocalnodes;
int localnodeindex;
int localnodenameindex;

int numflexdesc;
int flexdescindex;

int numflexcontrollers;
int flexcontrollerindex;

int numflexrules;
int flexruleindex;

int numikchains;
int ikchainindex;

int nummouths;
int mouthindex;

int numlocalposeparameters;
int localposeparamindex;

int surfacepropindex;

int keyvalueindex;
int keyvaluesize;


int numlocalikautoplaylocks;
int localikautoplaylockindex;

float mass;
int contents;

int numincludemodels;
int includemodelindex;

mutable void* virtualModel;

int szanimblocknameindex;
int numanimblocks;
int animblockindex;

mutable void* animblockModel;

int bonetablebynameindex;

void* pVertexBase;
void* pIndexBase;

byte constdirectionallightdot;

byte rootLOD;

byte numAllowedRootLODs;

byte unused[1];

int unused4;

int numflexcontrollerui;
int flexcontrolleruiindex;
float flVertAnimFixedPointScale;
int unused3[1];
int studiohdr2index;
int unused2[1];
};

struct surfacephysicsparams_t
{
    float friction;
    float elasticity; // collision elasticity - used to compute coefficient of restitution
    float density;    // physical density (in kg / m^3)
    float thickness;    // material thickness if not solid (sheet materials) in inches
    float dampening;
};

struct surfaceaudioparams_t
{
    float reflectivity;            // like elasticity, but how much sound should be reflected by this surface
    float hardnessFactor;            // like elasticity, but only affects impact sound choices
    float roughnessFactor;        // like friction, but only affects scrape sound choices   
    float roughThreshold;            // surface roughness > this causes "rough" scrapes, < this causes "smooth" scrapes
    float hardThreshold;            // surface hardness > this causes "hard" impacts, < this causes "soft" impacts
    float hardVelocityThreshold;    // collision velocity > this causes "hard" impacts, < this causes "soft" impacts   
};

struct surfacesoundnames_t
{
    unsigned short stepleft;
    unsigned short stepright;
    unsigned short impactSoft;
    unsigned short impactHard;
    unsigned short scrapeSmooth;
    unsigned short scrapeRough;
    unsigned short bulletImpact;
    unsigned short rolling;
    unsigned short breakSound;
    unsigned short strainSound;
};

struct surfacegameprops_t
{
    public:
        float maxSpeedFactor; //0x0000
    float jumpFactor; //0x0004
    char pad00[0x4]; //0x0008
    float flPenetrationModifier; //0x000C
    float flDamageModifier; //0x0010
    unsigned short material; //0x0014
    char pad01[0x3];

};//Size=0x0019

struct surfacedata_t
{
    surfacephysicsparams_t physics;
    surfaceaudioparams_t audio;
    surfacesoundnames_t sounds;
    surfacegameprops_t game;
};

class IPhysicsSurfaceProps
{
    public:

        surfacedata_t* GetSurfaceData(int surfaceDataIndex)
    {
        typedef surfacedata_t*(__thiscall * fnGetSurfaceData)(void*, int);
        return call_vfunc(this, 5)(this, surfaceDataIndex);
    }
};

class ConVar
{
    public:
        //void SetString(const char *pValue)
        //{
        //        typedef void(__thiscall* SetStringFn)(void*, const char *);
        //        call_vfunc(this, 17)(this, pValue);
        //}

        void SetString(const char* str)
        {

        typedef void(__thiscall* SetStringFn)(void*, const char*);
                return call_vfunc(this, 13)(this, str);
        }

void InternalSetString(const char* str)
{
    typedef void(__thiscall * SetStringFn)(void*, const char*);
    return call_vfunc(this, 17)(this, str);
}

char* GetBaseName()
{
    typedef char*(__thiscall * SetStringFn)(void*);
    return call_vfunc(this, 6)(this);
}

char pad_0x0000[0x4]; //0x0000
ConVar* pNext; //0x0004 
__int32 bRegistered; //0x0008 
char* pszName; //0x000C 
char* pszHelpString; //0x0010 
__int32 nFlags; //0x0014 
char pad_0x0018[0x4]; //0x0018
ConVar* pParent; //0x001C 
char* pszDefaultValue; //0x0020 
char* strString; //0x0024 
__int32 StringLength; //0x0028 
float fValue; //0x002C 
__int32 nValue; //0x0030 
__int32 bHasMin; //0x0034 
float fMinVal; //0x0038 
__int32 bHasMax; //0x003C 
float fMaxVal; //0x0040 
void* fnChangeCallback; //0x0044 

};//Size=0x0048

class ICVar
{
    public:
        ConVar* FindVar(const char* var_name)
        {

        typedef ConVar*(__thiscall* FindVarFn)(void*, const char*);
                return call_vfunc(this, 15)(this, var_name);
        }
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"
#include "bspflags.h"

// Entity List
class IClientEntityList
{
    public:
        virtual void Function0();
    virtual void Function1();
    virtual void Function2();
    virtual IClientEntity* GetClientEntity(int entnum);
    virtual IClientEntity* GetClientEntityFromHandle(HANDLE hEnt) = 0;
        virtual int NumberOfEntities(bool bIncludeNonNetworkable) = 0;
        virtual int GetHighestEntityIndex(void);
    virtual void SetMaxEntities(int maxents);
    virtual int GetMaxEntities();
};

// Panels
class IPanel
{
    public:
        const char* GetName(unsigned int vguiPanel)
        {

        typedef const char* (__thiscall * OriginalFn)(PVOID, unsigned int);
                return call_vfunc(this, Offsets::VMT::Panel_GetName)(this, vguiPanel);
        }
};

// Colors
class Color
{
    public:
        // constructors
        Color()
    {
        *((int*)this) = 0;
    }
    Color(int r, int g, int b)
    {
        SetColor(r, g, b, 0);
    }
    Color(int r, int g, int b, int a)
    {
        SetColor(r, g, b, a);
    }
    void SetColor(int r, int g, int b, int a = 0)
    {
        _color[0] = (unsigned char)r;
        _color[1] = (unsigned char)g;
        _color[2] = (unsigned char)b;
        _color[3] = (unsigned char)a;
    }

    void GetColor(int &r, int &g, int &b, int &a) const
        {

        r = _color[0];
                g = _color[1];
                b = _color[2];
                a = _color[3];
        }

void SetRawColor(int color32)
{
    *((int*)this) = color32;
}

int GetRawColor() const
        {
                return *((int*)this);
}

inline int r() const    { return _color[0]; }
        inline int g() const    { return _color[1]; }
        inline int b() const    { return _color[2]; }
        inline int a() const    { return _color[3]; }

        void SetAlpha(int a) { _color[0] = (unsigned char)a; }
int GetAlpha() { return _color[0]; }


unsigned char &operator[] (int index)
{
    return _color[index];
}

const unsigned char &operator[] (int index) const
        {
                return _color[index];
        }

        bool operator ==(const Color &rhs) const
        {
                return (*((int*)this) == *((int *)&rhs));
}

bool operator !=(const Color &rhs) const
        {
                return !(operator ==(rhs));
        }

        Color &operator=(const Color &rhs)
{
    SetRawColor(rhs.GetRawColor());
    return *this;
}

private:
        unsigned char _color[4];
};

// Debug Overlay
class IVDebugOverlay
{
    public:
        virtual void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0;
    virtual void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, int r, int g, int b, int a, float duration) = 0;
    virtual void AddSphereOverlay(const Vector& vOrigin, float flRadius, int nTheta, int nPhi, int r, int g, int b, int a, float flDuration) = 0;
    virtual void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) = 0;
    virtual void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, bool noDepthTest, float duration) = 0;
    virtual void AddTextOverlay(const Vector& origin, float duration, const char* format, ...) = 0;
    virtual void AddTextOverlay(const Vector& origin, int line_offset, float duration, const char* format, ...) = 0;
    virtual void AddScreenTextOverlay(float flXPos, float flYPos, float flDuration, int r, int g, int b, int a, const char* text) = 0;
    virtual void AddSweptBoxOverlay(const Vector& start, const Vector& end, const Vector& mins, const Vector& max, const Vector & angles, int r, int g, int b, int a, float flDuration) = 0;
    virtual void AddGridOverlay(const Vector& origin) = 0;
        virtual void AddCoordFrameOverlay(const matrix3x4& frame, float flScale, int vColorTable[3][3] = NULL) = 0;

        virtual int ScreenPosition(const Vector& point, Vector& screen) = 0;
        virtual int ScreenPosition(float flXPos, float flYPos, Vector& screen) = 0;

        virtual void* GetFirst(void) = 0;
        virtual void* GetNext(void* current) = 0;
        virtual void ClearDeadOverlays(void) = 0;
        virtual void ClearAllOverlays() = 0;

        virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, const char* format, ...) = 0;
    virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0;

    virtual void AddLineOverlayAlpha(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float duration) = 0;
    virtual void AddBoxOverlay2(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, const Color& faceColor, const Color& edgeColor, float duration) = 0;

    virtual void PurgeTextOverlays() = 0;
};

// User Cmd's
class CUserCmd
{
    public:
        virtual ~CUserCmd() { }; //Destructor 0
    CUserCmd()
    {
        Reset();
    }

    void Reset()
    {
        command_number = 0;
        tick_count = 0;
        viewangles.Init();
        forwardmove = 0.0f;
        sidemove = 0.0f;
        upmove = 0.0f;
        buttons = 0;
        impulse = 0;
        weaponselect = 0;
        weaponsubtype = 0;
        random_seed = 0;
        mousedx = 0;
        mousedy = 0;
        headangles.Init();
        headoffset.Init();

        hasbeenpredicted = false;
    }

    CUserCmd& operator =(const CUserCmd& src)
        {
                if (this == &src)
                        return *this;

                command_number = src.command_number;
                tick_count = src.tick_count;
                viewangles = src.viewangles;
                forwardmove = src.forwardmove;
                sidemove = src.sidemove;
                upmove = src.upmove;
                buttons = src.buttons;
                impulse = src.impulse;
                weaponselect = src.weaponselect;
                weaponsubtype = src.weaponsubtype;
                random_seed = src.random_seed;
                mousedx = src.mousedx;
                mousedy = src.mousedy;

                hasbeenpredicted = src.hasbeenpredicted;
                headangles = src.headangles;
                headoffset = src.headoffset;
                return *this;
        }


    CUserCmd(const CUserCmd& src)
{
    *this = src;
}


int command_number;
int tick_count;
Vector viewangles;
Vector aimdirection;
float forwardmove;
float sidemove;
float upmove;
int buttons;
BYTE impulse;
int weaponselect;
int weaponsubtype;
int random_seed;
short mousedx;
short mousedy;
bool hasbeenpredicted;
Vector headangles;
Vector headoffset;
};

class CGlobalVarsBase
{
    public:
        float realtime;
    int framecount;
    float absoluteframetime;
    float absoluteframestarttimestddev;
    float curtime;
    float frametime;
    int maxClients;
    int tickcount;
    float interval_per_tick;
    float interpolation_amount;
    int simTicksThisFrame;
    int network_protocol;
    void* pSaveData;
    bool m_bClient;
    int nTimestampNetworkingBase;
    int nTimestampRandomizeWindow;
};

struct Ray_t
{

    __declspec(align(16)) Vector m_Start;

    __declspec(align(16)) Vector m_Delta;

    __declspec(align(16)) Vector m_StartOffset;

    __declspec(align(16)) Vector m_Extents;
    //without your matrix3x4
    bool m_IsRay;
    bool m_IsSwept;

    void Init(Vector& vecStart, Vector& vecEnd)
    {
        m_Delta = vecEnd - vecStart;

        m_IsSwept = (m_Delta.LengthSqr() != 0);

        m_Extents.x = m_Extents.y = m_Extents.z = 0.0f;

        m_IsRay = true;

        m_StartOffset.x = m_StartOffset.y = m_StartOffset.z = 0.0f;

        m_Start = vecStart;
    }
};

struct cplane_t
{
    Vector normal;
    float dist;
    BYTE type;
    BYTE signbits;
    BYTE pad[2];
};

class CBaseTrace
{
    public:
        Vector startpos;
    Vector endpos;
    cplane_t plane;
    float fraction;
    int contents;
    unsigned short dispFlags;
    bool allsolid;
    bool startsolid;
};

struct csurface_t
{
    const char* name;
    short surfaceProps;
    unsigned short flags;
};

class CGameTrace : public CBaseTrace
{
public:
        bool DidHitWorld() const;
bool DidHitNonWorldEntity() const;
int GetEntityIndex() const;
bool DidHit() const;
public:
        float fractionleftsolid;
csurface_t surface;
int hitgroup;
short physicsbone;
unsigned short worldSurfaceIndex;
IClientEntity* m_pEnt;
int hitbox;
char shit[0x24];
};

inline bool CGameTrace::DidHit() const
{
        return fraction< 1.0f || allsolid || startsolid;
}

typedef CGameTrace trace_t;

enum TraceType_t
{
    TRACE_EVERYTHING = 0,
    TRACE_WORLD_ONLY,
    TRACE_ENTITIES_ONLY,
    TRACE_EVERYTHING_FILTER_PROPS,
};

class ITraceFilter
{
    public:
        virtual bool ShouldHitEntity(IClientEntity* pEntity, int contentsMask) = 0;
        virtual TraceType_t GetTraceType() const = 0;
};

class CTraceFilter : public ITraceFilter
{
public:
        bool ShouldHitEntity(IClientEntity* pEntityHandle, int contentsMask)
{
    return !(pEntityHandle == pSkip);
}

TraceType_t GetTraceType() const
        {
                return TRACE_EVERYTHING;
        }

        void* pSkip;
};

class IEngineTrace
{
    public:
        int GetPointContents(const Vector &vecAbsPosition, int contentsMask = MASK_ALL, IClientEntity** ppEntity = NULL)
        {
                typedef int(__thiscall* fnGetPointContents)(void*, const Vector&, int, IClientEntity**);
                return call_vfunc(this, 0)(this, vecAbsPosition, contentsMask, ppEntity);
        }

void TraceRay(const Ray_t &ray, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace)
{
    typedef void(__thiscall * fnTraceRay)(void*, const Ray_t&, unsigned int, ITraceFilter*, trace_t *);
    call_vfunc(this, 5)(this, ray, fMask, pTraceFilter, pTrace);
}
};

struct mstudiobbox_t
{
    int bone;
    int group;
    Vector bbmin;
    Vector bbmax;
    int szhitboxnameindex;
    int unused[8];

    char* GetHitboxName(void)
    {
        if (szhitboxnameindex == 0)
            return "";

        return ((char*)this) + szhitboxnameindex;
    }
};
struct mstudiohitboxset_t
{
    int sznameindex;
    inline char* const GetName(void) const { return ((char*)this) + sznameindex; }
int numhitboxes;
int hitboxindex;
inline mstudiobbox_t* GetHitbox(int i) const { return (mstudiobbox_t*)(((byte*)this) + hitboxindex) + i; };
};
struct mstudiobone_t
{
    int sznameindex;
    inline char* const GetName(void) const { return ((char*)this) + sznameindex; }
int parent;
int bonecontroller[6];

Vector pos;
float quat[4];
Vector rot;
Vector posscale;
Vector rotscale;

matrix3x4 poseToBone;
float qAlignment[4];
int flags;
int proctype;
int procindex;              // procedural rule
mutable int physicsbone;    // index into physically simulated bone
inline void* GetProcedure() const { if (procindex == 0) return NULL; else return  (void*)(((byte*)this) + procindex); };
int surfacepropidx; // index into string tablefor property name
inline char* const GetSurfaceProps(void) const { return ((char*)this) + surfacepropidx; }
        int contents;               // See BSPFlags.h for the contents flags

int unused[8];              // remove as appropriate
};
struct studiohdr_t
{
    int id;
    int version;

    int checksum;

    char name[64];
    int length;


    Vector eyeposition;

    Vector illumposition;

    Vector hull_min;
    Vector hull_max;

    Vector view_bbmin;
    Vector view_bbmax;

    int flags;

    int numbones;
    int boneindex;

    inline mstudiobone_t *GetBone(int i) const { return (mstudiobone_t*)(((byte*)this) + boneindex) + i; };
//        inline mstudiobone_t *pBone(int i) const { Assert(i >= 0 && i < numbones); return (mstudiobone_t *)(((byte *)this) + boneindex) + i; };

int numbonecontrollers;
int bonecontrollerindex;

int numhitboxsets;
int hitboxsetindex;

mstudiohitboxset_t* GetHitboxSet(int i) const
        {
                return (mstudiohitboxset_t*)(((byte*)this) + hitboxsetindex) + i;
}

inline mstudiobbox_t* GetHitbox(int i, int set) const
        {
                mstudiohitboxset_t const* s = GetHitboxSet(set);

                if (!s)
                        return NULL;

                return s->GetHitbox(i);
        }

        inline int GetHitboxCount(int set) const
        {
                mstudiohitboxset_t const* s = GetHitboxSet(set);

                if (!s)
                        return 0;

                return s->numhitboxes;
        }

        int numlocalanim;
int localanimindex;

int numlocalseq;
int localseqindex;

mutable int activitylistversion;
mutable int eventsindexed;

int numtextures;
int textureindex;

int numcdtextures;
int cdtextureindex;

int numskinref;
int numskinfamilies;
int skinindex;

int numbodyparts;
int bodypartindex;

int numlocalattachments;
int localattachmentindex;

int numlocalnodes;
int localnodeindex;
int localnodenameindex;

int numflexdesc;
int flexdescindex;

int numflexcontrollers;
int flexcontrollerindex;

int numflexrules;
int flexruleindex;

int numikchains;
int ikchainindex;

int nummouths;
int mouthindex;

int numlocalposeparameters;
int localposeparamindex;

int surfacepropindex;

int keyvalueindex;
int keyvaluesize;


int numlocalikautoplaylocks;
int localikautoplaylockindex;

float mass;
int contents;

int numincludemodels;
int includemodelindex;

mutable void* virtualModel;

int szanimblocknameindex;
int numanimblocks;
int animblockindex;

mutable void* animblockModel;

int bonetablebynameindex;

void* pVertexBase;
void* pIndexBase;

byte constdirectionallightdot;

byte rootLOD;

byte numAllowedRootLODs;

byte unused[1];

int unused4;

int numflexcontrollerui;
int flexcontrolleruiindex;
float flVertAnimFixedPointScale;
int unused3[1];
int studiohdr2index;
int unused2[1];
};

struct surfacephysicsparams_t
{
    float friction;
    float elasticity; // collision elasticity - used to compute coefficient of restitution
    float density;    // physical density (in kg / m^3)
    float thickness;    // material thickness if not solid (sheet materials) in inches
    float dampening;
};

struct surfaceaudioparams_t
{
    float reflectivity;            // like elasticity, but how much sound should be reflected by this surface
    float hardnessFactor;            // like elasticity, but only affects impact sound choices
    float roughnessFactor;        // like friction, but only affects scrape sound choices   
    float roughThreshold;            // surface roughness > this causes "rough" scrapes, < this causes "smooth" scrapes
    float hardThreshold;            // surface hardness > this causes "hard" impacts, < this causes "soft" impacts
    float hardVelocityThreshold;    // collision velocity > this causes "hard" impacts, < this causes "soft" impacts   
};

struct surfacesoundnames_t
{
    unsigned short stepleft;
    unsigned short stepright;
    unsigned short impactSoft;
    unsigned short impactHard;
    unsigned short scrapeSmooth;
    unsigned short scrapeRough;
    unsigned short bulletImpact;
    unsigned short rolling;
    unsigned short breakSound;
    unsigned short strainSound;
};

struct surfacegameprops_t
{
    public:
        float maxSpeedFactor; //0x0000
    float jumpFactor; //0x0004
    char pad00[0x4]; //0x0008
    float flPenetrationModifier; //0x000C
    float flDamageModifier; //0x0010
    unsigned short material; //0x0014
    char pad01[0x3];

};//Size=0x0019

struct surfacedata_t
{
    surfacephysicsparams_t physics;
    surfaceaudioparams_t audio;
    surfacesoundnames_t sounds;
    surfacegameprops_t game;
};

class IPhysicsSurfaceProps
{
    public:

        surfacedata_t* GetSurfaceData(int surfaceDataIndex)
    {
        typedef surfacedata_t*(__thiscall * fnGetSurfaceData)(void*, int);
        return call_vfunc(this, 5)(this, surfaceDataIndex);
    }
};

class ConVar
{
    public:
        //void SetString(const char *pValue)
        //{
        //        typedef void(__thiscall* SetStringFn)(void*, const char *);
        //        call_vfunc(this, 17)(this, pValue);
        //}

        void SetString(const char* str)
        {

        typedef void(__thiscall* SetStringFn)(void*, const char*);
                return call_vfunc(this, 13)(this, str);
        }

void InternalSetString(const char* str)
{
    typedef void(__thiscall * SetStringFn)(void*, const char*);
    return call_vfunc(this, 17)(this, str);
}

char* GetBaseName()
{
    typedef char*(__thiscall * SetStringFn)(void*);
    return call_vfunc(this, 6)(this);
}

char pad_0x0000[0x4]; //0x0000
ConVar* pNext; //0x0004 
__int32 bRegistered; //0x0008 
char* pszName; //0x000C 
char* pszHelpString; //0x0010 
__int32 nFlags; //0x0014 
char pad_0x0018[0x4]; //0x0018
ConVar* pParent; //0x001C 
char* pszDefaultValue; //0x0020 
char* strString; //0x0024 
__int32 StringLength; //0x0028 
float fValue; //0x002C 
__int32 nValue; //0x0030 
__int32 bHasMin; //0x0034 
float fMinVal; //0x0038 
__int32 bHasMax; //0x003C 
float fMaxVal; //0x0040 
void* fnChangeCallback; //0x0044 

};//Size=0x0048

class ICVar
{
    public:
        ConVar* FindVar(const char* var_name)
        {

        typedef ConVar*(__thiscall* FindVarFn)(void*, const char*);
                return call_vfunc(this, 15)(this, var_name);
        }
};#pragma once

#include "NetVars.h"
#include "Vector.h"

//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------

// For calling VMT functions in our classes
template Function call_vfunc(PVOID Base, DWORD Index)
{
    PDWORD* VTablePointer = (PDWORD*)Base;
    PDWORD VTableFunctionBase = *VTablePointer;
    DWORD dwAddress = VTableFunctionBase[Index];
    return (Function)(dwAddress);
}

// Netvar shit
#define dwThis (DWORD)this
#define NETVAR(type,offset) *(type*)(dwThis + offset)
#define CNETVAR(type,offset) (type)(dwThis + offset)

//CNETVAR_FUNC - creates a netvar function in a class that returns value(s) [type=class type & return type] [name=function name] [netvar_crc=crc32 of netvar of choice]
#define CNETVAR_FUNC(type,name,netvar_crc) \
type name() \
        { \
                static DWORD dwObserverTarget = NetVar.GetNetVar(netvar_crc); \
                return NETVAR(type, dwObserverTarget); \
        }

//CPNETVAR_FUNC - creates a netvar function in a class that returns a pointer [type=class type & return type] [name=function name] [netvar_crc=crc32 of netvar of choice]
#define CPNETVAR_FUNC(type,name,netvar_crc) \
        type name() \
        { \
                static DWORD dwObserverTarget = NetVar.GetNetVar(netvar_crc); \
                return CNETVAR(type, dwObserverTarget); \
        }

// Lifestates
enum source_lifestates
{
    LIFE_ALIVE,
    LIFE_DYING,
    LIFE_DEAD,
    LIFE_RESPAWNABLE,
    LIFE_DISCARDBODY,
};

// Player Controls for CS:GO
enum playercontrols
{
    IN_ATTACK = (1 << 0),
    IN_JUMP = (1 << 1),
    IN_DUCK = (1 << 2),
    IN_FORWARD = (1 << 3),
    IN_BACK = (1 << 4),
    IN_USE = (1 << 5),
    IN_CANCEL = (1 << 6),
    IN_LEFT = (1 << 7),
    IN_RIGHT = (1 << 8),
    IN_MOVELEFT = (1 << 9),
    IN_MOVERIGHT = (1 << 10),
    IN_ATTACK2 = (1 << 11),
    IN_RUN = (1 << 12),
    IN_RELOAD = (1 << 13),
    IN_ALT1 = (1 << 14),
    IN_ALT2 = (1 << 15),
    IN_SCORE = (1 << 16),   // Used by client.dll for when scoreboard is held down
    IN_SPEED = (1 << 17),   // Player is holding the speed key
    IN_WALK = (1 << 18),    // Player holding walk key
    IN_ZOOM = (1 << 19),    // Zoom key for HUD zoom
    IN_WEAPON1 = (1 << 20), // weapon defines these bits
    IN_WEAPON2 = (1 << 21), // weapon defines these bits
    IN_BULLRUSH = (1 << 22),
};

typedef float matrix3x4[3][4];

class player_info_t
{
    public:
        char pad_0x0000[0x10]; //0x0000
    char name[64]; //0x0010 
    char pad_0x0050[0x40]; //0x0050
    __int32 userID; //0x0090 
    char guid[32]; //0x0094 
    char pad_0x00B4[0x180]; //0x00B4
};

enum SolidType_t
{
    SOLID_NONE = 0, // no solid model
    SOLID_BSP = 1,  // a BSP tree
    SOLID_BBOX = 2, // an AABB
    SOLID_OBB = 3,  // an OBB (not implemented yet)
    SOLID_OBB_YAW = 4,  // an OBB, constrained so that it can only yaw
    SOLID_CUSTOM = 5,   // Always call into the entity for tests
    SOLID_VPHYSICS = 6, // solid vphysics object, get vcollide from the model and collide with that
    SOLID_LAST,
};

enum SolidFlags_t
{
    FSOLID_CUSTOMRAYTEST = 0x0001,  // Ignore solid type + always call into the entity for ray tests
    FSOLID_CUSTOMBOXTEST = 0x0002,  // Ignore solid type + always call into the entity for swept box tests
    FSOLID_NOT_SOLID = 0x0004,  // Are we currently not solid?
    FSOLID_TRIGGER = 0x0008,    // This is something may be collideable but fires touch functions
                                // even when it's not collideable (when the FSOLID_NOT_SOLID flag is set)
    FSOLID_NOT_STANDABLE = 0x0010,  // You can't stand on this
    FSOLID_VOLUME_CONTENTS = 0x0020,    // Contains volumetric contents (like water)
    FSOLID_FORCE_WORLD_ALIGNED = 0x0040,    // Forces the collision rep to be world-aligned even if it's SOLID_BSP or SOLID_VPHYSICS
    FSOLID_USE_TRIGGER_BOUNDS = 0x0080, // Uses a special trigger bounds separate from the normal OBB
    FSOLID_ROOT_PARENT_ALIGNED = 0x0100,    // Collisions are defined in root parent's local coordinate space
    FSOLID_TRIGGER_TOUCH_DEBRIS = 0x0200,   // This trigger will touch debris objects

    FSOLID_MAX_BITS = 10
};

// KeyValues
class KeyValues
{
    public:
        char _pad[0x20];//csgo, for css its a diff size
};

// Memes
struct ModelRenderInfo_t
{
    Vector origin;
    Vector angles;
    void* pRenderable;
    const void* pModel;
    const matrix3x4* pModelToWorld;
    const matrix3x4* pLightingOffset;
    const Vector* pLightingOrigin;
    int flags;
    int entity_index;
    int skin;
    int body;
    int hitboxset;
    unsigned short instance;

    ModelRenderInfo_t()
    {
        pModelToWorld = NULL;
        pLightingOffset = NULL;
        pLightingOrigin = NULL;
    }
};

typedef float vec_t;

inline unsigned long& FloatBits(vec_t& f)
{
    return *reinterpret_cast < unsigned long*> (&f);
}

inline bool IsFinite(vec_t f)
{
    return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
}

struct model_t;

enum OverrideType_t
{
    OVERRIDE_NORMAL = 0,
    OVERRIDE_BUILD_SHADOWS,
    OVERRIDE_DEPTH_WRITE,
};

enum MaterialVarFlags_t
{
    MATERIAL_VAR_DEBUG = (1 << 0),
    MATERIAL_VAR_NO_DEBUG_OVERRIDE = (1 << 1),
    MATERIAL_VAR_NO_DRAW = (1 << 2),
    MATERIAL_VAR_USE_IN_FILLRATE_MODE = (1 << 3),

    MATERIAL_VAR_VERTEXCOLOR = (1 << 4),
    MATERIAL_VAR_VERTEXALPHA = (1 << 5),
    MATERIAL_VAR_SELFILLUM = (1 << 6),
    MATERIAL_VAR_ADDITIVE = (1 << 7),
    MATERIAL_VAR_ALPHATEST = (1 << 8),
    MATERIAL_VAR_MULTIPASS = (1 << 9),
    MATERIAL_VAR_ZNEARER = (1 << 10),
    MATERIAL_VAR_MODEL = (1 << 11),
    MATERIAL_VAR_FLAT = (1 << 12),
    MATERIAL_VAR_NOCULL = (1 << 13),
    MATERIAL_VAR_NOFOG = (1 << 14),
    MATERIAL_VAR_IGNOREZ = (1 << 15),
    MATERIAL_VAR_DECAL = (1 << 16),
    MATERIAL_VAR_ENVMAPSPHERE = (1 << 17),
    MATERIAL_VAR_NOALPHAMOD = (1 << 18),
    MATERIAL_VAR_ENVMAPCAMERASPACE = (1 << 19),
    MATERIAL_VAR_BASEALPHAENVMAPMASK = (1 << 20),
    MATERIAL_VAR_TRANSLUCENT = (1 << 21),
    MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK = (1 << 22),
    MATERIAL_VAR_NEEDS_SOFTWARE_SKINNING = (1 << 23),
    MATERIAL_VAR_OPAQUETEXTURE = (1 << 24),
    MATERIAL_VAR_ENVMAPMODE = (1 << 25),
    MATERIAL_VAR_SUPPRESS_DECALS = (1 << 26),
    MATERIAL_VAR_HALFLAMBERT = (1 << 27),
    MATERIAL_VAR_WIREFRAME = (1 << 28),

    // NOTE: Only add flags here that either should be read from
    // .vmts or can be set directly from client code. Other, internal
    // flags should to into the flag enum in IMaterialInternal.h
};

#define        FL_ONGROUND                                (1<<0)        // At rest / on the ground
#define FL_DUCKING                                (1<<1)        // Player flag -- Player is fully crouched
#define        FL_WATERJUMP                        (1<<2)        // player jumping out of water
#define FL_ONTRAIN                                (1<<3) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
#define FL_INRAIN                                (1<<4)        // Indicates the entity is standing in rain
#define FL_FROZEN                                (1<<5) // Player is frozen for 3rd person camera
#define FL_ATCONTROLS                        (1<<6) // Player can't move, but keeps key inputs for controlling another entity
#define        FL_CLIENT                                (1<<7)        // Is a player
#define FL_FAKECLIENT                        (1<<8)        // Fake client, simulated server side; don't send network messages to them
// NON-PLAYER SPECIFIC (i.e., not used by GameMovement or the client .dll ) -- Can still be applied to players, though
#define        FL_INWATER                                (1<<9)        // In water

// NOTE if you move things up, make sure to change this value
#define PLAYER_FLAG_BITS                10

#define        FL_FLY                                        (1<<10)        // Changes the SV_Movestep() behavior to not need to be on ground
#define        FL_SWIM                                        (1<<11)        // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
#define        FL_CONVEYOR                                (1<<12)
#define        FL_NPC                                        (1<<13)
#define        FL_GODMODE                                (1<<14)
#define        FL_NOTARGET                                (1<<15)
#define        FL_AIMTARGET                        (1<<16)        // set if the crosshair needs to aim onto the entity
#define        FL_PARTIALGROUND                (1<<17)        // not all corners are valid
#define FL_STATICPROP                        (1<<18)        // Eetsa static prop!                
#define FL_GRAPHED                                (1<<19) // worldgraph has this ent listed as something that blocks a connection
#define FL_GRENADE                                (1<<20)
#define FL_STEPMOVEMENT                        (1<<21)        // Changes the SV_Movestep() behavior to not do any processing
#define FL_DONTTOUCH                        (1<<22)        // Doesn't generate touch functions, generates Untouch() for anything it was touching when this flag was set
#define FL_BASEVELOCITY                        (1<<23)        // Base velocity has been applied this frame (used to convert base velocity into momentum)
#define FL_WORLDBRUSH                        (1<<24)        // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something)
#define FL_OBJECT                                (1<<25) // Terrible name. This is an object that NPCs should see. Missiles, for example.
#define FL_KILLME                                (1<<26)        // This entity is marked for death -- will be freed by game DLL
#define FL_ONFIRE                                (1<<27)        // You know...
#define FL_DISSOLVING                        (1<<28) // We're dissolving!
#define FL_TRANSRAGDOLL                        (1<<29) // In the process of turning into a client side ragdoll.
#define FL_UNBLOCKABLE_BY_PLAYER (1<<30) // pusher that can't be blocked by the player

enum ClientFrameStage_t
{
    FRAME_UNDEFINED = -1,           // (haven't run any frames yet)
    FRAME_START,

    // A network packet is being recieved
    FRAME_NET_UPDATE_START,
    // Data has been received and we're going to start calling PostDataUpdate
    FRAME_NET_UPDATE_POSTDATAUPDATE_START,
    // Data has been received and we've called PostDataUpdate on all data recipients
    FRAME_NET_UPDATE_POSTDATAUPDATE_END,
    // We've received all packets, we can now do interpolation, prediction, etc..
    FRAME_NET_UPDATE_END,

    // We're about to start rendering the scene
    FRAME_RENDER_START,
    // We've finished rendering the scene.
    FRAME_RENDER_END
};

// ConVar flags
#define FCVAR_NONE                                0 

#define FCVAR_UNREGISTERED                (1<<0)
#define FCVAR_DEVELOPMENTONLY        (1<<1)
#define FCVAR_GAMEDLL                        (1<<2)
#define FCVAR_CLIENTDLL                        (1<<3)
#define FCVAR_HIDDEN                        (1<<4)

#define FCVAR_PROTECTED                        (1<<5)
#define FCVAR_SPONLY                        (1<<6)
#define FCVAR_ARCHIVE                        (1<<7)
#define FCVAR_NOTIFY                        (1<<8)
#define FCVAR_USERINFO                        (1<<9)
#define FCVAR_CHEAT                                (1<<14)

#define FCVAR_PRINTABLEONLY                (1<<10)
#define FCVAR_UNLOGGED                        (1<<11)
#define FCVAR_NEVER_AS_STRING        (1<<12)
#define FCVAR_RELEASE                        (1<<19)

#define FCVAR_REPLICATED                (1<<13)
#define FCVAR_DEMO                                (1<<16)
#define FCVAR_DONTRECORD                (1<<17)

#define FCVAR_NOT_CONNECTED                (1<<22)
#define FCVAR_ARCHIVE_XBOX                (1<<24)
#define FCVAR_SERVER_CAN_EXECUTE        (1<<28)
#define FCVAR_SERVER_CANNOT_QUERY        (1<<29)
#define FCVAR_CLIENTCMD_CAN_EXECUTE        (1<<30)
/*
Syn's AYYWAREFramework 2015
*/

# include "MiscHacks.h"
# include "Interfaces.h"
# include "RenderManager.h"

# include 

Vector AutoStrafeView;

void CMiscHacks::Init()
{
    // Any init
}

void CMiscHacks::Draw()
{
    // Any drawing        
}

void CMiscHacks::Move(CUserCmd* pCmd)
{
    // Any Move Stuff

    // Bhop
    if (Menu::Window.VisualsTab.OtherAutoJump.GetState())
        AutoJump(pCmd);

    // Strafe
    Interfaces::Engine->GetViewAngles(AutoStrafeView);
    if (Menu::Window.VisualsTab.OtherAutoStrafe.GetState())
        AutoStrafe(pCmd);

    // Spams
    switch (Menu::Window.VisualsTab.OtherChatSpam.GetIndex())
    {
        case 0:
            // No Chat Spam
            break;
        case 1:
            // Round Say
            break;
        case 2:
            // Regular
            ChatSpamRegular();
            break;
        case 3:
            // Report Spam
            ChatSpamReports();
            break;
    }

}

void CMiscHacks::AutoJump(CUserCmd* pCmd)
{
    if (pCmd->buttons & IN_JUMP && GUI.GetKeyState(VK_SPACE))
    {
        int iFlags = hackManager.pLocal()->GetFlags();
        if (!(iFlags & FL_ONGROUND))
            pCmd->buttons &= ~IN_JUMP;

        if (hackManager.pLocal()->GetVelocity().Length() <= 50)
        {
            pCmd->forwardmove = 450.f;
        }
    }
}

void CMiscHacks::AutoStrafe(CUserCmd* pCmd)
{
    IClientEntity* pLocal = hackManager.pLocal();
    static bool bDirection = true;

    bool bKeysPressed = true;
    if (GUI.GetKeyState(0x41) || GUI.GetKeyState(0x57) || GUI.GetKeyState(0x53) || GUI.GetKeyState(0x44)) bKeysPressed = false;
    if (pCmd->buttons & IN_ATTACK) bKeysPressed = false;

    float flYawBhop = 0.f;
    if (pLocal->GetVelocity().Length() > 50.f)
    {
        float x = 30.f, y = pLocal->GetVelocity().Length(), z = 0.f, a = 0.f;

        z = x / y;
        z = fabsf(z);

        a = x * z;

        flYawBhop = a;
    }

    if ((GetAsyncKeyState(VK_SPACE) && !(pLocal->GetFlags() & FL_ONGROUND)) && bKeysPressed)
    {

        if (bDirection)
        {
            AutoStrafeView -= flYawBhop;
            GameUtils::NormaliseViewAngle(AutoStrafeView);
            pCmd->sidemove = -400.f;
            bDirection = false;
        }
        else
        {
            AutoStrafeView += flYawBhop;
            GameUtils::NormaliseViewAngle(AutoStrafeView);
            pCmd->sidemove = 400.f;
            bDirection = true;
        }

        if (pCmd->mousedx < 0)
        {
            pCmd->sidemove = -450.f;
        }

        if (pCmd->mousedx > 0)
        {
            pCmd->sidemove = 450.f;
        }
    }
}

Vector GetAutostrafeView()
{
    return AutoStrafeView;
}

void CMiscHacks::ChatSpamReports()
{
    // Don't spam it too fast so you can still do stuff
    static clock_t start_t = clock();
    double timeSoFar = (double)(clock() - start_t) / CLOCKS_PER_SEC;
    if (timeSoFar < 0.5)
        return;

    // Loop through all active entitys
    std::vector < std::string > Names;

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        // Get the entity
        IClientEntity* entity = Interfaces::EntList->GetClientEntity(i);

        player_info_t pInfo;
        // If it's a valid entity and isn't the player
        if (entity && hackManager.pLocal()->GetTeamNum() != entity->GetTeamNum())
        {
            ClientClass* cClass = (ClientClass*)entity->GetClientClass();

            // If entity is a player
            if (cClass->m_ClassID == (int)CSGOClassID::CCSPlayer)
            {
                if (Interfaces::Engine->GetPlayerInfo(i, &pInfo))
                {
                    if (!strstr(pInfo.name, "GOTV"))
                        Names.push_back(pInfo.name);
                }
            }
        }
    }

    int randomIndex = rand() % Names.size();
    char buffer[128];
    static unsigned long int meme = 3091961887844204720;
    sprintf_s(buffer, "Report for %s submitted, report id %lu.", Names[randomIndex].c_str(), meme);
    meme += 1;
    SayInChat(buffer);
    start_t = clock();
}

void CMiscHacks::ChatSpamRegular()
{
    // Don't spam it too fast so you can still do stuff
    static clock_t start_t = clock();
    double timeSoFar = (double)(clock() - start_t) / CLOCKS_PER_SEC;
    if (timeSoFar < 0.5)
        return;

    SayInChat("Aliens exist. #AliensInCSGOConfirmed");

    start_t = clock();
}
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

Vector GetAutostrafeView();

class CMiscHacks : public CHack
{
public:
        void Init();
void Draw();
void Move(CUserCmd* pCmd);
private:
        void AutoJump(CUserCmd* pCmd);
void AutoStrafe(CUserCmd* pCmd);
void ChatSpamRegular();
void ChatSpamReports();
};/*
Syn's AYYWAREFramework 2015
*/

// Credits to Valve and Shad0w

#include "NetVars.h"
#include "ClientRecvProps.h"
#include "CRC32.h"
#include "Utilities.h"

#include "SDK.h"

CNetVar NetVar;

const char* AlignText(int align)
{
        static char buffer[256];
int i = 0;
        for (i = 0; i         {
                buffer[i] = ' ';
        }
        buffer[i + 1] = 0;
        return buffer;
}

void CNetVar::RetrieveClasses()
{
    Utilities::EnableLogFile(NETVAR_FILENAME);

    ClientClass* clientClass = Interfaces::Client->GetAllClasses();

    if (!clientClass)
        return;

    //Clear netvar vector incase of another call, not necesarry as it doesnt add duplicates

    vars.clear();

    while (clientClass != 0)
    {
        if (clientClass == 0)
            break;

        LogNetVar(clientClass->m_pRecvTable, 0);

        clientClass = clientClass->m_pNext;
    }
}

void CNetVar::LogNetVar(RecvTable* table, int align)
{
    if (table->m_nProps < 0)
        return;

    if (align)
        Utilities::Log("%s===%s===", AlignText(20 + align), table->m_pNetTableName);
    else
        Utilities::Log(table->m_pNetTableName);

    for (auto i = 0; i < table->m_nProps; ++i)
    {
        RecvProp* prop = &table->m_pProps[i];

        if (!prop)
            continue;

        char szCRC32[150];

        sprintf_s(szCRC32, "%s%s", table->m_pNetTableName, prop->m_pVarName);

        DWORD_PTR dwCRC32 = CRC32((void*)szCRC32, strlen(szCRC32));

        Utilities::Log("%s%s [0x%X] [CRC32::0x%X]", AlignText(15 + align), prop->m_pVarName, prop->m_Offset, dwCRC32);

        //Dont add duplicates

        bool bAddNetVar = true;

        for (auto netvar = 0; netvar < (int)vars.size(); ++netvar)
        {
            netvar_info_s* netvars = &vars[netvar];

            if (netvars->dwCRC32 == dwCRC32)
                bAddNetVar = false;


            if (netvars->dwCRC32 == dwCRC32 && netvars->dwOffset != prop->m_Offset) //just a test if any crc collide with another (didnt happen obviously)
            {
                Utilities::Log("^^^^ ERROR HASH %s%s::%s [0x%X] [CRC32::0x%X] ^^^^", AlignText(15 + align), table->m_pNetTableName, prop->m_pVarName, prop->m_Offset, dwCRC32);
                Utilities::Log("^^^^ CONFLICT %s%s::%s [0x%X] [CRC32::0x%X] ^^^^", AlignText(15 + align), netvars->szTableName, netvars->szPropName, netvars->dwOffset, netvars->dwCRC32);
            }
        }

        if (bAddNetVar) //avoid adding duplicates (faster lookup)
        {
            netvar_info_s tmp;
            strcpy_s(tmp.szTableName, table->m_pNetTableName);
            strcpy_s(tmp.szPropName, prop->m_pVarName);
            tmp.dwCRC32 = dwCRC32;

            tmp.dwOffset = prop->m_Offset;

            vars.push_back(tmp);
        }

        if (prop->m_pDataTable)
            LogNetVar(prop->m_pDataTable, 5);
    }
}

DWORD_PTR CNetVar::GetNetVar(DWORD_PTR dwCRC32) //returns 0xFFFFFFFF (-1) if not found (ex: if(GetNetVar(0xD34DB33F)==-1) return false;
{
    for (auto i = 0; i < (int)vars.size(); ++i)
    {
        if (vars[i].dwCRC32 == dwCRC32)
            return vars[i].dwOffset;
    }

    return 0xFFFFFFFF;
}/*
Syn's AYYWAREFramework 2015
*/

#include "Offsets.h"

void Offsets::Initialise()
{
    // Modules
    Modules::Client = Utilities::Memory::WaitOnModuleHandle("client.dll");
    Modules::Engine = Utilities::Memory::WaitOnModuleHandle("engine.dll");
    Modules::VGUI2 = Utilities::Memory::WaitOnModuleHandle("vgui2.dll");
    Modules::VGUISurface = Utilities::Memory::WaitOnModuleHandle("vguimatsurface.dll");
    Modules::Material = Utilities::Memory::WaitOnModuleHandle("materialsystem.dll");
    Modules::VPhysics = Utilities::Memory::WaitOnModuleHandle("vphysics.dll");
    Modules::Stdlib = Utilities::Memory::WaitOnModuleHandle("vstdlib.dll");

    //------------------------------------------------------------------------
    // VTables
#pragma region VTables
    VMT::CHL_GetAllClasses = 8;

    VMT::Engine_GetScreenSize = 5;
    VMT::Engine_GetPlayerInfo = 8;
    VMT::Engine_GetLocalPlayer = 12;
    VMT::Engine_Time = 14;
    VMT::Engine_GetViewAngles = 18;
    VMT::Engine_SetViewAngles = 19;
    VMT::Engine_GetMaxClients = 20;
    VMT::Engine_IsConnected = 27;
    VMT::Engine_IsInGame = 26;
    VMT::Engine_WorldToScreenMatrix = 37;
    VMT::Engine_ClientCmd_Unrestricted = 114;

    VMT::Panel_GetName = 36;
    VMT::Panel_PaintTraverse = 41;

    VMT::Surface_DrawSetColorA = 14;
    VMT::Surface_DrawSetColorB = 15;
    VMT::Surface_DrawFilledRect = 16;
    VMT::Surface_DrawOutlinedRect = 18;
    VMT::Surface_DrawLine = 19;
    VMT::Surface_DrawSetTextFont = 23;
    VMT::Surface_DrawSetTextColorA = 24;
    VMT::Surface_DrawSetTextColorB = 25;
    VMT::Surface_DrawSetTextPos = 26;
    VMT::Surface_DrawPrintText = 28;
    VMT::Surface_DrawSetTextureRGBA = 37;
    VMT::Surface_DrawSetTexture = 38;
    VMT::Surface_CreateNewTextureID = 43;
    VMT::Surface_FontCreate = 71;
    VMT::Surface_SetFontGlyphSet = 72;
    VMT::Surface_GetTextSize = 79;
    VMT::Surface_DrawOutlinedCircle = 103;
    VMT::Surface_SurfaceGetCursorPos = 66;
    VMT::Surface_DrawTexturedPolygon = 106;

    VMT::Material_GetName = 0;
    VMT::Material_SetMaterialVarFlag = 30;
    VMT::Material_GetMaterialVarFlag = 31;
    VMT::Material_AlphaModulate = 28;
    VMT::Material_ColorModulate = 29;
    VMT::Material_IncrementReferenceCount = 14;

    VMT::MaterialSystem_FindMaterial = 84;
    VMT::MaterialSystem_CreateMaterial = 83;

    VMT::ModelRender_ForcedMaterialOverride = 1;
    VMT::ModelRender_DrawModelExecute = 21;

    VMT::ModelInfo_GetModelName = 3;
    VMT::ModelInfo_GetStudiomodel = 30;

    VMT::RenderView_SetBlend = 4;
    VMT::RenderView_SetColorModulation = 6;

#pragma endregion Contains the VTable Indexs

    // An update changed the VTable offset for GetSpread.
    // Just incase ;)
    DWORD VMT_SpreadAddress = (DWORD)Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x8B\x80\x00\x00\x00\x00\xFF\xD0\x51\xD9\x1C\x24\x0F\xB6\xC3\x8B\x5C\x24\x30", "xx????xxxxxxxxxxxxx");
    if (VMT_SpreadAddress)
    {
        VMT::Weapon_GetSpread = *(DWORD*)(VMT_SpreadAddress + 2);
        VMT::Weapon_GetSpread = (VMT::Weapon_GetSpread / 4);
    }

    // I cbf trying to get the KeyValues part of the SDK working solo, so we'll just
    // Do some dirty shit
    Functions::KeyValues_KeyValues = Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x68\x00\x00\x00\x00\x8B\xC8\xE8\x00\x00\x00\x00\x89\x45\xFC\xEB\x07\xC7\x45\x00\x00\x00\x00\x00\x8B\x03\x56", "x????xxx????xxxxxxx?????xxx");
    Functions::KeyValues_KeyValues += 7;
    Functions::KeyValues_KeyValues = Functions::KeyValues_KeyValues + *reinterpret_cast(Functions::KeyValues_KeyValues + 1) + 5;

    Functions::KeyValues_LoadFromBuffer = Utilities::Memory::FindPattern("client.dll", (PBYTE)"\xE8\x00\x00\x00\x00\x8A\xD8\xFF\x15\x00\x00\x00\x00\x84\xDB", "x????xxxx????xx");
    Functions::KeyValues_LoadFromBuffer = Functions::KeyValues_LoadFromBuffer + *reinterpret_cast(Functions::KeyValues_LoadFromBuffer + 1) + 5;

    Functions::dwCalcPlayerView = Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x84\xC0\x75\x08\x57\x8B\xCE\xE8\x00\x00\x00\x00\x8B\x06", "xxxxxxxx????xx");

    Utilities::Log("Offsets/Indexes Up to Date");
}

namespace Offsets
{
    // Addresses of loaded game modules
    namespace Modules
    {
        DWORD Client;
        DWORD Engine;
        DWORD VGUI2;
        DWORD VGUISurface;
        DWORD Material;
        DWORD VPhysics;
        DWORD Stdlib;
    };

    // Virtual Method Table Indexes
    namespace VMT
    {
        //CHL Client
        DWORD CHL_GetAllClasses;

        //Engine Client
        DWORD Engine_GetScreenSize;
        DWORD Engine_GetPlayerInfo;
        DWORD Engine_GetLocalPlayer;
        DWORD Engine_Time;
        DWORD Engine_GetViewAngles;
        DWORD Engine_SetViewAngles;
        DWORD Engine_GetMaxClients;
        DWORD Engine_IsConnected;
        DWORD Engine_IsInGame;
        DWORD Engine_WorldToScreenMatrix;
        DWORD Engine_ClientCmd_Unrestricted;

        // Panels
        DWORD Panel_GetName;
        DWORD Panel_PaintTraverse;

        // Surface
        DWORD Surface_DrawSetColorA;
        DWORD Surface_DrawSetColorB;
        DWORD Surface_DrawFilledRect;
        DWORD Surface_DrawOutlinedRect;
        DWORD Surface_DrawLine;
        DWORD Surface_DrawSetTextFont;
        DWORD Surface_DrawSetTextColorA;
        DWORD Surface_DrawSetTextColorB;
        DWORD Surface_DrawSetTextPos;
        DWORD Surface_DrawPrintText;
        DWORD Surface_DrawSetTextureRGBA;
        DWORD Surface_DrawSetTexture;
        DWORD Surface_CreateNewTextureID;
        DWORD Surface_FontCreate;
        DWORD Surface_SetFontGlyphSet;
        DWORD Surface_GetTextSize;
        DWORD Surface_DrawOutlinedCircle;
        DWORD Surface_SurfaceGetCursorPos;
        DWORD Surface_DrawTexturedPolygon;

        DWORD Material_GetName;
        DWORD Material_SetMaterialVarFlag;
        DWORD Material_GetMaterialVarFlag;
        DWORD Material_AlphaModulate;
        DWORD Material_ColorModulate;
        DWORD Material_IncrementReferenceCount;

        DWORD MaterialSystem_FindMaterial;
        DWORD MaterialSystem_CreateMaterial;

        DWORD ModelRender_ForcedMaterialOverride;
        DWORD ModelRender_DrawModelExecute;

        DWORD ModelInfo_GetModelName;
        DWORD ModelInfo_GetStudiomodel;

        DWORD RenderView_SetBlend;
        DWORD RenderView_SetColorModulation;

        // Weapon entities
        DWORD Weapon_GetSpread;
    };

    // Addresses of engine functions to call
    namespace Functions
    {
        DWORD KeyValues_KeyValues;
        DWORD KeyValues_LoadFromBuffer;
        DWORD dwCalcPlayerView;
    };

};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Utilities.h"

// Various offsets
namespace Offsets
{
    // Sets up all the shit we need
    void Initialise();

    // Addresses of loaded game modules
    namespace Modules
    {
        extern DWORD Client;
                extern DWORD Engine;
                extern DWORD VGUI2;
                extern DWORD VGUISurface;
                extern DWORD Material;
                extern DWORD VPhysics;
                extern DWORD Stdlib;
        };

    // Virtual Method Table Indexes
    namespace VMT
    {
        //CHL Client
        extern DWORD CHL_GetAllClasses;

                //Engine Client
                extern DWORD Engine_GetScreenSize;
                extern DWORD Engine_GetPlayerInfo;
                extern DWORD Engine_GetLocalPlayer;
                extern DWORD Engine_Time;
                extern DWORD Engine_GetViewAngles;
                extern DWORD Engine_SetViewAngles;
                extern DWORD Engine_GetMaxClients;
                extern DWORD Engine_IsConnected;
                extern DWORD Engine_IsInGame;
                extern DWORD Engine_WorldToScreenMatrix;
                extern DWORD Engine_ClientCmd_Unrestricted;

                // Panels
                extern DWORD Panel_GetName;
                extern DWORD Panel_PaintTraverse;

                // Surface
                extern DWORD Surface_DrawSetColorA;
                extern DWORD Surface_DrawSetColorB;
                extern DWORD Surface_DrawFilledRect;
                extern DWORD Surface_DrawOutlinedRect;
                extern DWORD Surface_DrawLine;
                extern DWORD Surface_DrawSetTextFont;
                extern DWORD Surface_DrawSetTextColorA;
                extern DWORD Surface_DrawSetTextColorB;
                extern DWORD Surface_DrawSetTextPos;
                extern DWORD Surface_DrawPrintText;
                extern DWORD Surface_DrawSetTextureRGBA;
                extern DWORD Surface_DrawSetTexture;
                extern DWORD Surface_CreateNewTextureID;
                extern DWORD Surface_FontCreate;
                extern DWORD Surface_SetFontGlyphSet;
                extern DWORD Surface_GetTextSize;
                extern DWORD Surface_DrawOutlinedCircle;
                extern DWORD Surface_SurfaceGetCursorPos;
                extern DWORD Surface_DrawTexturedPolygon;

                extern DWORD Material_GetName;
                extern DWORD Material_SetMaterialVarFlag;
                extern DWORD Material_GetMaterialVarFlag;
                extern DWORD Material_AlphaModulate;
                extern DWORD Material_ColorModulate;
                extern DWORD Material_IncrementReferenceCount;

                extern DWORD MaterialSystem_FindMaterial;
                extern DWORD MaterialSystem_CreateMaterial;

                extern DWORD ModelRender_ForcedMaterialOverride;
                extern DWORD ModelRender_DrawModelExecute;

                extern DWORD ModelInfo_GetModelName;
                extern DWORD ModelInfo_GetStudiomodel;
                
                extern DWORD RenderView_SetBlend;
                extern DWORD RenderView_SetColorModulation;

                // Weapon entities
                extern DWORD Weapon_GetSpread;
        };

    // Addresses of engine functions to call
    namespace Functions
    {
        extern DWORD KeyValues_KeyValues;
                extern DWORD KeyValues_LoadFromBuffer;
                extern DWORD dwCalcPlayerView;
        };

};#include "RageBot.h"
#include "RenderManager.h"
#include "Autowall.h"

void CRageBot::Init()
{
    IsAimStepping = false;
    IsLocked = false;
    TargetID = -1;
}

void CRageBot::Draw()
{

}

void CRageBot::Move(CUserCmd* pCmd)
{
    // Master switch
    if (!Menu::Window.RageBotTab.Active.GetState())
        return;

    // Aimbot
    if (Menu::Window.RageBotTab.AimbotEnable.GetState())
        DoAimbot(pCmd);

    // Recoil
    if (Menu::Window.RageBotTab.AccuracyRecoil.GetState())
        DoNoRecoil(pCmd);

    // No Spread
    if (Menu::Window.RageBotTab.AccuracySpread.GetState())
        DoNoSpread(pCmd);

    // Anti-Aim
    if (Menu::Window.RageBotTab.AntiAimEnable.GetState())
        DoAntiAim(pCmd);

    if (Menu::Window.RageBotTab.AimbotAimStep.GetState())
    {
        Vector AddAngs = pCmd->viewangles - LastAngle;
        if (AddAngs.Length2D() > 25.f)
        {
            Normalize(AddAngs, AddAngs);
            AddAngs *= 25;
            pCmd->viewangles = LastAngle + AddAngs;
            GameUtils::NormaliseViewAngle(pCmd->viewangles);
        }
    }

    LastAngle = pCmd->viewangles;
}

// Functionality
void CRageBot::DoAimbot(CUserCmd* pCmd)
{
    IClientEntity* pTarget = nullptr;
    IClientEntity* pLocal = hackManager.pLocal();
    bool FindNewTarget = true;
    //IsLocked = false;

    // Don't aimbot with the knife..
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
    if (pWeapon)
    {
        if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
        {
            //TargetID = 0;
            //pTarget = nullptr;
            //HitBox = -1;
            return;
        }
    }
    else
        return;

    // Make sure we have a good target
    if (IsLocked && TargetID >= 0 && HitBox >= 0)
    {
        pTarget = Interfaces::EntList->GetClientEntity(TargetID);
        if (pTarget && TargetMeetsRequirements(pTarget))
        {
            HitBox = HitScan(pTarget);
            if (HitBox >= 0)
            {
                Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
                Vector View; Interfaces::Engine->GetViewAngles(View);
                float FoV = FovToPlayer(ViewOffset, View, pTarget, HitBox);
                if (FoV < Menu::Window.RageBotTab.AimbotFov.GetValue())
                    FindNewTarget = false;
            }
        }
    }

    // Find a new target, apparently we need to
    if (FindNewTarget)
    {
        TargetID = 0;
        pTarget = nullptr;
        HitBox = -1;

        // Target selection type
        switch (Menu::Window.RageBotTab.TargetSelection.GetIndex())
        {
            case 0:
                TargetID = GetTargetCrosshair();
                break;
            case 1:
                TargetID = GetTargetDistance();
                break;
            case 2:
                TargetID = GetTargetHealth();
                break;
        }

        // Memes
        if (TargetID >= 0)
        {
            pTarget = Interfaces::EntList->GetClientEntity(TargetID);
        }
        else
        {
            pTarget = nullptr;
            HitBox = -1;
        }
    }

    // If we finally have a good target
    if (TargetID >= 0 && pTarget)
    {
        HitBox = HitScan(pTarget);

        // Key
        if (Menu::Window.RageBotTab.AimbotKeyPress.GetState())
        {
            int Key = Menu::Window.RageBotTab.AimbotKeyBind.GetKey();
            if (Key >= 0 && !GUI.GetKeyState(Key))
            {
                TargetID = -1;
                pTarget = nullptr;
                HitBox = -1;
                return;
            }
        }

        Vector AimPoint = GetHitboxPosition(pTarget, HitBox);

        float Spread = pWeapon->GetInaccuracy();

        if (!Menu::Window.RageBotTab.AccuracySpreadLimit.GetState() || Spread <= (Menu::Window.RageBotTab.AccuracyMinimumSpread.GetValue() / 100.f))
        {
            if (AimAtPoint(pLocal, AimPoint, pCmd))
            {
                //IsLocked = true;
                if (Menu::Window.RageBotTab.AimbotAutoFire.GetState() && !(pCmd->buttons & IN_ATTACK))
                {
                    pCmd->buttons |= IN_ATTACK;
                }
            }
        }

        if (Menu::Window.RageBotTab.AccuracyAutoStop.GetState())
        {
            pCmd->forwardmove = 0.f;
            pCmd->sidemove = 0.f;
        }

        if (Menu::Window.RageBotTab.AccuracyAutoCrouch.GetState())
        {
            pCmd->buttons |= IN_DUCK;
        }

    }

    // Auto Pistol
    static bool WasFiring = false;
    CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
    if (!WeaponInfo->m_IsFullAuto && Menu::Window.RageBotTab.AimbotAutoPistol.GetState())
    {
        if (pCmd->buttons & IN_ATTACK)
        {
            if (WasFiring)
            {
                pCmd->buttons &= ~IN_ATTACK;
            }
        }

        WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
    }


}

bool CRageBot::TargetMeetsRequirements(IClientEntity* pEntity)
{
    // Is a valid player
    if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
    {
        // Entity Type checks
        ClientClass* pClientClass = pEntity->GetClientClass();
        player_info_t pinfo;
        if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
        {
            // Team Check
            if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.RageBotTab.TargetFriendlyFire.GetState())
            {
                // Spawn Check
                if (!pEntity->HasGunGameImmunity())
                {
                    return true;
                }
            }
        }
    }

    // They must have failed a requirement
    return false;
}

float CRageBot::FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int aHitBox)
{
    // Anything past 180 degrees is just going to wrap around
    CONST FLOAT MaxDegrees = 180.0f;

    // Get local angles
    Vector Angles = View;

    // Get local view / eye position
    Vector Origin = ViewOffSet;

    // Create and intiialize vectors for calculations below
    Vector Delta(0, 0, 0);
    //Vector Origin(0, 0, 0);
    Vector Forward(0, 0, 0);

    // Convert angles to normalized directional forward vector
    AngleVectors(Angles, &Forward);
    Vector AimPos = GetHitboxPosition(pEntity, aHitBox);
    // Get delta vector between our local eye position and passed vector
    VectorSubtract(AimPos, Origin, Delta);
    //Delta = AimPos - Origin;

    // Normalize our delta vector
    Normalize(Delta, Delta);

    // Get dot product between delta position and directional forward vectors
    FLOAT DotProduct = Forward.Dot(Delta);

    // Time to calculate the field of view
    return (acos(DotProduct) * (MaxDegrees / PI));
}

int CRageBot::GetTargetCrosshair()
{
    // Target selection
    int target = -1;
    float minFoV = Menu::Window.RageBotTab.AimbotFov.GetValue();

    IClientEntity* pLocal = hackManager.pLocal();
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector View; Interfaces::Engine->GetViewAngles(View);

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        if (TargetMeetsRequirements(pEntity))
        {
            int NewHitBox = HitScan(pEntity);
            if (NewHitBox >= 0)
            {
                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                if (fov < minFoV)
                {
                    minFoV = fov;
                    target = i;
                }
            }
        }
    }

    return target;
}

int CRageBot::GetTargetDistance()
{
    // Target selection
    int target = -1;
    int minDist = 99999;

    IClientEntity* pLocal = hackManager.pLocal();
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector View; Interfaces::Engine->GetViewAngles(View);

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        if (TargetMeetsRequirements(pEntity))
        {
            int NewHitBox = HitScan(pEntity);
            if (NewHitBox >= 0)
            {
                Vector Difference = pLocal->GetOrigin() - pEntity->GetOrigin();
                int Distance = Difference.Length();
                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                if (Distance < minDist && fov < Menu::Window.RageBotTab.AimbotFov.GetValue())
                {
                    minDist = Distance;
                    target = i;
                }
            }
        }
    }

    return target;
}

int CRageBot::GetTargetHealth()
{
    // Target selection
    int target = -1;
    int minHealth = 101;

    IClientEntity* pLocal = hackManager.pLocal();
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector View; Interfaces::Engine->GetViewAngles(View);

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        if (TargetMeetsRequirements(pEntity))
        {
            int NewHitBox = HitScan(pEntity);
            if (NewHitBox >= 0)
            {
                int Health = pEntity->GetHealth();
                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                if (Health < minHealth && fov < Menu::Window.RageBotTab.AimbotFov.GetValue())
                {
                    minHealth = Health;
                    target = i;
                }
            }
        }
    }

    return target;
}

int CRageBot::HitScan(IClientEntity* pEntity)
{
    std::vector HitBoxesToScan;
    bool AWall = Menu::Window.RageBotTab.AccuracyAutoWall.GetState();

    // Get the hitboxes to scan
#pragma region GetHitboxesToScan
    int HitScanMode = Menu::Window.RageBotTab.TargetHitscan.GetIndex();
    if (HitScanMode == 0)
    {
        // No Hitscan, just a single hitbox
        switch (Menu::Window.RageBotTab.TargetHitbox.GetIndex())
        {
            case 0:
                HitBoxesToScan.push_back((int)CSGOHitboxID::Head);
                break;
            case 1:
                HitBoxesToScan.push_back((int)CSGOHitboxID::Neck);
                break;
            case 2:
                HitBoxesToScan.push_back((int)CSGOHitboxID::Chest);
                break;
            case 3:
                HitBoxesToScan.push_back((int)CSGOHitboxID::Stomach);
                break;
        }
    }
    else
    {
        switch (HitScanMode)
        {
            case 1:
                // head/body
                HitBoxesToScan.push_back((int)CSGOHitboxID::Head);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Neck);
                HitBoxesToScan.push_back((int)CSGOHitboxID::UpperChest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Chest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Stomach);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Pelvis);
                break;
            case 2:
                // basic +(arms, thighs)
                HitBoxesToScan.push_back((int)CSGOHitboxID::Head);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Neck);
                HitBoxesToScan.push_back((int)CSGOHitboxID::UpperChest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Chest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Stomach);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Pelvis);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftUpperArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightUpperArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftThigh);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightThigh);
            case 3:
                // heaps ++(just all the random shit)
                HitBoxesToScan.push_back((int)CSGOHitboxID::Head);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Neck);
                HitBoxesToScan.push_back((int)CSGOHitboxID::UpperChest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Chest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Stomach);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Pelvis);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftUpperArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightUpperArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftThigh);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightThigh);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftHand);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightHand);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftFoot);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightFoot);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftShin);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightShin);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftLowerArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightLowerArm);
        }
    }
#pragma endregion Get the list of shit to scan

    // check hits
    for (auto HitBoxID : HitBoxesToScan)
    {
        if (AWall)
        {
            Vector Point = GetHitboxPosition(pEntity, HitBoxID);
            float Damage = 0.f;
            Color c = Color(255, 255, 255, 255);
            if (CanHit(Point, &Damage))
            {
                c = Color(0, 255, 0, 255);
                if (Damage >= Menu::Window.RageBotTab.AccuracyMinimumDamage.GetValue())
                {
                    return HitBoxID;
                }
            }
        }
        else
        {
            if (GameUtils::IsVisible(hackManager.pLocal(), pEntity, HitBoxID))
                return HitBoxID;
        }
    }

    return -1;
}

void CRageBot::DoNoSpread(CUserCmd* pCmd)
{

}

void CRageBot::DoNoRecoil(CUserCmd* pCmd)
{
    // Ghetto rcs shit, implement properly later
    IClientEntity* pLocal = hackManager.pLocal();
    if (pLocal)
    {
        Vector AimPunch = pLocal->localPlayerExclusive()->GetAimPunchAngle();
        if (AimPunch.Length2D() > 0 && AimPunch.Length2D() < 150)
        {
            pCmd->viewangles -= AimPunch * 2;
            GameUtils::NormaliseViewAngle(pCmd->viewangles);
        }
    }
}

bool CRageBot::AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd* pCmd)
{
    bool ReturnValue = false;
    // Get the full angles
    if (point.Length() == 0) return ReturnValue;

    Vector angles;
    Vector src = pLocal->GetOrigin() + pLocal->GetViewOffset();

    CalcAngle(src, point, angles);
    GameUtils::NormaliseViewAngle(angles);

    if (angles[0] != angles[0] || angles[1] != angles[1])
    {
        return ReturnValue;
    }


    IsLocked = true;
    //-----------------------------------------------

    // Aim Step Calcs
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    if (!IsAimStepping)
        LastAimstepAngle = LastAngle; // Don't just use the viewangs because you need to consider aa

    float fovLeft = FovToPlayer(ViewOffset, LastAimstepAngle, Interfaces::EntList->GetClientEntity(TargetID), 0);

    if (fovLeft > 25.0f && Menu::Window.RageBotTab.AimbotAimStep.GetState())
    {
        Vector AddAngs = angles - LastAimstepAngle;
        Normalize(AddAngs, AddAngs);
        AddAngs *= 25;
        LastAimstepAngle += AddAngs;
        GameUtils::NormaliseViewAngle(LastAimstepAngle);
        angles = LastAimstepAngle;
    }
    else
    {
        ReturnValue = true;
    }

    pCmd->viewangles = angles;
    if (!Menu::Window.RageBotTab.AimbotSilentAim.GetState())
        Interfaces::Engine->SetViewAngles(angles);

    return ReturnValue;
}

namespace AntiAims
{
    // Pitches
    void StaticPitch(CUserCmd* pCmd, bool up)
    {
        if (up)
            // Up
            pCmd->viewangles.x = -88;
        else
            // Up
            pCmd->viewangles.x = 88;
    }

    void JitterPitch(CUserCmd* pCmd)
    {
        static bool up = true;
        if (up) pCmd->viewangles.x = -88;
        else pCmd->viewangles.x = 88;
        up = !up;
    }

    // Yaws
    void FastSpint(CUserCmd* pCmd)
    {
        int random = 160 + rand() % 40;
        static float current_y = pCmd->viewangles.y;
        current_y += random;
        pCmd->viewangles.y = current_y;
    }

    void SlowSpin(CUserCmd* pCmd)
    {
        int random = rand() % 100;
        int random2 = rand() % 1000;

        static bool dir;
        static float current_y = pCmd->viewangles.y;

        if (random == 1) dir = !dir;

        if (dir)
            current_y += 5;
        else
            current_y -= 5;

        pCmd->viewangles.y = current_y;

        if (random == random2)
            pCmd->viewangles.y += random;

    }

    void BackJitter(CUserCmd* pCmd)
    {
        int random = rand() % 100;

        // Small chance of starting fowards
        if (random < 98)
            // Look backwards
            pCmd->viewangles.y -= 180;

        // Some gitter
        if (random < 15)
        {
            float change = -70 + (rand() % (int)(140 + 1));
            pCmd->viewangles.y += change;
        }
        if (random == 69)
        {
            float change = -90 + (rand() % (int)(180 + 1));
            pCmd->viewangles.y += change;
        }

    }

    void Flip(CUserCmd* pCmd)
    {
        static bool back = false;
        back = !back;
        if (back)
            pCmd->viewangles.y -= 180;
    }
}

// AntiAim
void CRageBot::DoAntiAim(CUserCmd* pCmd)
{
    // If the aimbot is doing something don't do anything
    if (IsAimStepping || pCmd->buttons & IN_ATTACK)
        return;

    // Weapon shit
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(hackManager.pLocal()->GetActiveWeaponHandle());
    if (pWeapon)
    {
        CSWeaponInfo* pWeaponInfo = pWeapon->GetCSWpnData();
        // Knives or grenades
        if (!GameUtils::IsBallisticWeapon(pWeapon))
            return;
    }

    // Don't do antiaim
    // if (DoExit) return;

    // Anti-Aim Pitch
    switch (Menu::Window.RageBotTab.AntiAimPitch.GetIndex())
    {
        case 0:
            // No Pitch AA
            break;
        case 1:
            // up
            AntiAims::StaticPitch(pCmd, true);
            break;
        case 2:
            // Down
            AntiAims::StaticPitch(pCmd, false);
            break;
        case 3:
            // Jitter
            AntiAims::JitterPitch(pCmd);
            break;
    }

    //Anti-Aim Yaw
    switch (Menu::Window.RageBotTab.AntiAimYaw.GetIndex())
    {
        case 0:
            // No Yaw AA
            break;
        case 1:
            // Fast Spin
            AntiAims::FastSpint(pCmd);
            break;
        case 2:
            // Slow Spin
            AntiAims::SlowSpin(pCmd);
            break;
        case 3:
            // Inverse
            pCmd->viewangles.y -= 180;
            break;
        case 4:
            // Jitter
            AntiAims::BackJitter(pCmd);
            break;
        case 5:
            // Flip
            AntiAims::Flip(pCmd);
            break;
    }
}
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

class CRageBot : public CHack
{
public:
        void Init();
void Draw();
void Move(CUserCmd* pCmd);
private:
        // Targetting
        int GetTargetCrosshair();
int GetTargetDistance();
int GetTargetHealth();
bool TargetMeetsRequirements(IClientEntity* pEntity);
float CRageBot::FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int HitBox);
int HitScan(IClientEntity* pEntity);
bool AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd* pCmd);

// Functionality
void DoAimbot(CUserCmd* pCmd);
void DoNoSpread(CUserCmd* pCmd);
void DoNoRecoil(CUserCmd* pCmd);

// AntiAim
void DoAntiAim(CUserCmd* pCmd);

// AimStep
bool IsAimStepping;
Vector LastAimstepAngle;
Vector LastAngle;

// Aimbot
bool IsLocked;
int TargetID;
int HitBox;
Vector AimPoint;
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "RenderManager.h"

#define _CRT_SECURE_NO_WARNINGS

// Font Instances
namespace Render
{
    // Text functions
    namespace Fonts
    {
        DWORD Default;
        DWORD Menu;
        DWORD MenuBold;
        DWORD ESP;
    };
};

// We don't use these anywhere else, no reason for them to be
// available anywhere else
enum EFontFlags
{
    FONTFLAG_NONE,
    FONTFLAG_ITALIC = 0x001,
    FONTFLAG_UNDERLINE = 0x002,
    FONTFLAG_STRIKEOUT = 0x004,
    FONTFLAG_SYMBOL = 0x008,
    FONTFLAG_ANTIALIAS = 0x010,
    FONTFLAG_GAUSSIANBLUR = 0x020,
    FONTFLAG_ROTARY = 0x040,
    FONTFLAG_DROPSHADOW = 0x080,
    FONTFLAG_ADDITIVE = 0x100,
    FONTFLAG_OUTLINE = 0x200,
    FONTFLAG_CUSTOM = 0x400,
    FONTFLAG_BITMAP = 0x800,
};

// Initialises the rendering system, setting up fonts etc
void Render::Initialise()
{
    Fonts::Default = 0x1D; // MainMenu Font from vgui_spew_fonts 
    Fonts::Menu = Interfaces::Surface->FontCreate();
    Fonts::MenuBold = Interfaces::Surface->FontCreate();
    Fonts::ESP = Interfaces::Surface->FontCreate();

    Interfaces::Surface->SetFontGlyphSet(Fonts::Menu, "Terminal", 14, 500, 0, 0, FONTFLAG_ANTIALIAS);
    Interfaces::Surface->SetFontGlyphSet(Fonts::MenuBold, "Terminal", 14, 900, 0, 0, FONTFLAG_ANTIALIAS);
    Interfaces::Surface->SetFontGlyphSet(Fonts::ESP, "Terminal", 14, 500, 0, 0, FONTFLAG_ANTIALIAS /*| FONTFLAG_DROPSHADOW*/);

    Utilities::Log("Render System Ready");
}

RECT Render::GetViewport()
{
    RECT Viewport = { 0, 0, 0, 0 };
    int w, h;
    Interfaces::Engine->GetScreenSize(w, h);
    Viewport.right = w; Viewport.bottom = h;
    return Viewport;
}

void Render::Clear(int x, int y, int w, int h, Color color)
{
    Interfaces::Surface->DrawSetColor(color);
    Interfaces::Surface->DrawFilledRect(x, y, x + w, y + h);
}

void Render::Outline(int x, int y, int w, int h, Color color)
{
    Interfaces::Surface->DrawSetColor(color);
    Interfaces::Surface->DrawOutlinedRect(x, y, x + w, y + h);
}

void Render::Line(int x, int y, int x2, int y2, Color color)
{
    Interfaces::Surface->DrawSetColor(color);
    Interfaces::Surface->DrawLine(x, y, x2, y2);
}

void Render::PolyLine(int* x, int* y, int count, Color color)
{
    Interfaces::Surface->DrawSetColor(color);
    Interfaces::Surface->DrawPolyLine(x, y, count);
}

bool Render::WorldToScreen(Vector &in, Vector &out)
{
    const matrix3x4&worldToScreen = Interfaces::Engine->WorldToScreenMatrix(); //Grab the world to screen matrix from CEngineClient::WorldToScreenMatrix

    float w = worldToScreen[3][0] * in[0] + worldToScreen[3][1] * in[1] + worldToScreen[3][2] * in[2] + worldToScreen[3][3]; //Calculate the angle in compareson to the player's camera.
        out.z = 0; //Screen doesn't have a 3rd dimension.

        if (w > 0.001) //If the object is within view.
        {
                RECT ScreenSize = GetViewport();
float fl1DBw = 1 / w; //Divide 1 by the angle.
                out.x = (ScreenSize.right / 2) + (0.5f * ((worldToScreen[0][0] * in[0] + worldToScreen[0][1] * in[1] + worldToScreen[0][2] * in[2] + worldToScreen[0][3]) * fl1DBw) * ScreenSize.right + 0.5f); //Get the X dimension and push it in to the Vector.
                out.y = (ScreenSize.bottom / 2) - (0.5f * ((worldToScreen[1][0] * in[0] + worldToScreen[1][1] * in[1] + worldToScreen[1][2] * in[2] + worldToScreen[1][3]) * fl1DBw) * ScreenSize.bottom + 0.5f); //Get the Y dimension and push it in to the Vector.
                return true;
        }

        return false;
}

void Render::Text(int x, int y, Color color, DWORD font, const char* text)
{
    size_t origsize = strlen(text) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, text, _TRUNCATE);

    Interfaces::Surface->DrawSetTextFont(font);

    Interfaces::Surface->DrawSetTextColor(color);
    Interfaces::Surface->DrawSetTextPos(x, y);
    Interfaces::Surface->DrawPrintText(wcstring, wcslen(wcstring));
    return;
}

void Render::Text(int x, int y, Color color, DWORD font, const wchar_t* text)
{
    Interfaces::Surface->DrawSetTextFont(font);
    Interfaces::Surface->DrawSetTextColor(color);
    Interfaces::Surface->DrawSetTextPos(x, y);
    Interfaces::Surface->DrawPrintText(text, wcslen(text));
}

void Render::Textf(int x, int y, Color color, DWORD font, const char* fmt, ...)
{
    if (!fmt) return; //if the passed string is null return
    if (strlen(fmt) < 2) return;

    //Set up va_list and buffer to hold the params 
    va_list va_alist;
    char logBuf[256] = { 0 };

    //Do sprintf with the parameters
    va_start(va_alist, fmt);
    _vsnprintf_s(logBuf + strlen(logBuf), 256 - strlen(logBuf), sizeof(logBuf) - strlen(logBuf), fmt, va_alist);
    va_end(va_alist);

    Text(x, y, color, font, logBuf);
}

RECT Render::GetTextSize(DWORD font, const char* text)
{
    size_t origsize = strlen(text) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, text, _TRUNCATE);

    RECT rect; int x, y;
    Interfaces::Surface->GetTextSize(font, wcstring, x, y);
    rect.left = x; rect.bottom = y;
    rect.right = x;
    return rect;
}

void Render::GradientV(int x, int y, int w, int h, Color c1, Color c2)
{
    Clear(x, y, w, h, c1);
    BYTE first = c2.r();
    BYTE second = c2.g();
    BYTE third = c2.b();
    for (int i = 0; i < h; i++)
    {
        float fi = i, fh = h;
        float a = fi / fh;
        DWORD ia = a * 255;
        Clear(x, y + i, w, 1, Color(first, second, third, ia));
    }
}

void Render::GradientH(int x, int y, int w, int h, Color c1, Color c2)
{
    Clear(x, y, w, h, c1);
    BYTE first = c2.r();
    BYTE second = c2.g();
    BYTE third = c2.b();
    for (int i = 0; i < w; i++)
    {
        float fi = i, fw = w;
        float a = fi / fw;
        DWORD ia = a * 255;
        Clear(x + i, y, 1, h, Color(first, second, third, ia));
    }
}

void Render::Polygon(int count, Vertex_t* Vertexs, Color color)
{
    static int Texture = Interfaces::Surface->CreateNewTextureID(true); //need to make a texture with procedural true
    unsigned char buffer[4] = { 255, 255, 255, 255 };//{ color.r(), color.g(), color.b(), color.a() };

    Interfaces::Surface->DrawSetTextureRGBA(Texture, buffer, 1, 1); //Texture, char array of texture, width, height
    Interfaces::Surface->DrawSetColor(color); // keep this full color and opacity use the RGBA @top to set values.
    Interfaces::Surface->DrawSetTexture(Texture); // bind texture

    Interfaces::Surface->DrawTexturedPolygon(count, Vertexs);
}

void Render::PolygonOutline(int count, Vertex_t* Vertexs, Color color, Color colorLine)
{
    static int x[128];
    static int y[128];

    Render::Polygon(count, Vertexs, color);

    for (int i = 0; i < count; i++)
    {
        x[i] = Vertexs[i].m_Position.x;
        y[i] = Vertexs[i].m_Position.y;
    }

    Render::PolyLine(x, y, count, colorLine);
}

void Render::PolyLine(int count, Vertex_t* Vertexs, Color colorLine)
{
    static int x[128];
    static int y[128];

    for (int i = 0; i < count; i++)
    {
        x[i] = Vertexs[i].m_Position.x;
        y[i] = Vertexs[i].m_Position.y;
    }

    Render::PolyLine(x, y, count, colorLine);
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Interfaces.h"

#include "Vector2D.h"

void Quad();


namespace Render
{
    void Initialise();

    // Normal Drawing functions
    void Clear(int x, int y, int w, int h, Color color);
    void Outline(int x, int y, int w, int h, Color color);
    void Line(int x, int y, int x2, int y2, Color color);
    void PolyLine(int* x, int* y, int count, Color color);
    void Polygon(int count, Vertex_t* Vertexs, Color color);
    void PolygonOutline(int count, Vertex_t* Vertexs, Color color, Color colorLine);
    void PolyLine(int count, Vertex_t* Vertexs, Color colorLine);

    // Gradient Functions
    void GradientV(int x, int y, int w, int h, Color c1, Color c2);
    void GradientH(int x, int y, int w, int h, Color c1, Color c2);

    // Text functions
    namespace Fonts
    {
        extern DWORD Default;
                extern DWORD Menu;
                extern DWORD MenuBold;
                extern DWORD ESP;

        };

    void Text(int x, int y, Color color, DWORD font, const char* text);
    void Textf(int x, int y, Color color, DWORD font, const char* fmt, ...);
    void Text(int x, int y, Color color, DWORD font, const wchar_t* text);
    RECT GetTextSize(DWORD font, const char* text);

    // Other rendering functions
    bool WorldToScreen(Vector &in, Vector &out);
    RECT GetViewport();
};

/*
Syn's AYYWAREFramework 2015
*/

#pragma once

// Our stuff
# include "Entities.h"
# include "offsets.h"
# include "ClientRecvProps.h"
# include "BaseClient.h"
# include "EngineClient.h"
# include "MiscClasses.h"
# include "Surface.h"
# include "Materials.h"


// Valve
# include "Vector.h"
# include "Vector2D.h"
# include "bspflags.h"

// Management Classes
# include "Interfaces.h"

// Functions
# include "UTIL Functions.h"
# include "MathFunctions.h"
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

# include "MiscDefinitions.h"
# include "ClientRecvProps.h"
# include "offsets.h"
# include "Vector.h"
# include "MiscClasses.h"
# include "Vector2D.h"

struct Vertex_t
{
    Vector2D m_Position;
    Vector2D m_TexCoord;

    Vertex_t() { }
    Vertex_t(const Vector2D &pos, const Vector2D &coord = Vector2D(0, 0))
        {
                m_Position = pos;
                m_TexCoord = coord;
        }
void Init(const Vector2D &pos, const Vector2D &coord = Vector2D(0, 0))
{
    m_Position = pos;
    m_TexCoord = coord;
}
};

typedef Vertex_t FontVertex_t;

// Surface Drawing
class ISurface
{
    public:
        void DrawSetColor(Color col)
    {
        typedef void(__thiscall * oDrawSetColor)(PVOID, Color);
        return call_vfunc(this, Offsets::VMT::Surface_DrawSetColorA)(this, col);
    }

    void DrawSetColor(int r, int g, int b, int a)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawSetColorB)(this, r, g, b, a);
    }

    void DrawFilledRect(int x0, int y0, int x1, int y1)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawFilledRect)(this, x0, y0, x1, y1);
    }

    void DrawOutlinedRect(int x0, int y0, int x1, int y1)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawOutlinedRect)(this, x0, y0, x1, y1);
    }

    void DrawLine(int x0, int y0, int x1, int y1)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawLine)(this, x0, y0, x1, y1);
    }

    void DrawPolyLine(int* x, int* y, int count)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int *, int *, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawLine + 1)(this, x, y, count);
    }

    void DrawSetTextFont(unsigned long font)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, unsigned long);
        call_vfunc(this, Offsets::VMT::Surface_DrawSetTextFont)(this, font);
    }

    void DrawSetTextColor(int r, int g, int b, int a)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawSetTextColorB)(this, r, g, b, a);
    }

    void DrawSetTextColor(Color col)
    {
        typedef void(__thiscall * oDrawSetTextColor)(PVOID, Color);
        return call_vfunc(this, Offsets::VMT::Surface_DrawSetTextColorA)(this, col);
    }

    void DrawSetTextPos(int x, int y)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawSetTextPos)(this, x, y);
    }

    void DrawPrintText(const wchar_t* text, int textLen)
        {

        typedef void(__thiscall* OriginalFn)(PVOID, const wchar_t*, int, int);
                call_vfunc(this, Offsets::VMT::Surface_DrawPrintText)(this, text, textLen, 0);
        }

void DrawSetTexture(int textureID)
{
    typedef void(__thiscall * oDrawSetTextColor)(PVOID, int);
    return call_vfunc(this, Offsets::VMT::Surface_DrawSetTexture)(this, textureID);
}

void DrawSetTextureRGBA(int textureID, unsigned char  const* colors, int w, int h)
{
    typedef void(__thiscall * oDrawSetTextColor)(PVOID, int, unsigned char  const*, int, int);
    return call_vfunc(this, Offsets::VMT::Surface_DrawSetTextureRGBA)(this, textureID, colors, w, h);
}

int CreateNewTextureID(bool procedural)
{
    typedef int(__thiscall * oDrawSetTextColor)(PVOID, bool);
    return call_vfunc(this, Offsets::VMT::Surface_CreateNewTextureID)(this, procedural);
}

void DrawTexturedPolygon(int vtxCount, FontVertex_t* vtx, bool bClipVertices = true)
{
    typedef void(__thiscall * oDrawSetTextColor)(PVOID, int, FontVertex_t *, bool);
    return call_vfunc(this, Offsets::VMT::Surface_DrawTexturedPolygon)(this, vtxCount, vtx, bClipVertices);
}

unsigned long FontCreate()
{
    typedef unsigned int(__thiscall * OriginalFn)(PVOID);
    return call_vfunc(this, Offsets::VMT::Surface_FontCreate)(this);
}

void SetFontGlyphSet(unsigned long font, const char* windowsFontName, int tall, int weight, int blur, int scanlines, int flags)
{
    typedef void(__thiscall * OriginalFn)(PVOID, unsigned long, const char*, int, int, int, int, int, int, int);
    call_vfunc(this, Offsets::VMT::Surface_SetFontGlyphSet)(this, font, windowsFontName, tall, weight, blur, scanlines, flags, 0, 0);
}

void GetTextSize(unsigned long font, const wchar_t* text, int& wide, int& tall)
{
    typedef void(__thiscall * OriginalFn)(PVOID, unsigned long, const wchar_t*, int&, int&);
    call_vfunc(this, Offsets::VMT::Surface_GetTextSize)(this, font, text, wide, tall);
}

void DrawOutlinedCircle(int x, int y, int r, int seg)
{
    typedef void(__thiscall * oDrawOutlinedCircle)(PVOID, int, int, int, int);
    return call_vfunc(this, Offsets::VMT::Surface_DrawOutlinedCircle)(this, x, y, r, seg);
}

void SurfaceGetCursorPos(int &x, int &y)
{
    typedef void(__thiscall * oSurfaceGetCursorPos)(PVOID, int &, int &);
    return call_vfunc(this, Offsets::VMT::Surface_SurfaceGetCursorPos)(this, x, y);
}
};/*
Original code by Lee Thomason (www.grinninglizard.com)

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.
*/

#include "tinyxml2.h"

#include                 // yes, this one new style header, is in the Android SDK.
#if defined(ANDROID_NDK) || defined(__QNXNTO__)
#   include 
#   include 
#else
#   include 
#   include 
#endif

#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
        // Microsoft Visual Studio, version 2005 and higher. Not WinCE.
        /*int _snprintf_s(
           char *buffer,
           size_t sizeOfBuffer,
           size_t count,
           const char *format [,
                  argument] ...
        );*/
        static inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
        {
                va_list va;
                va_start( va, format );
                int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
                va_end( va );
                return result;
        }

        static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va )
        {
                int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
                return result;
        }

        #define TIXML_VSCPRINTF        _vscprintf
        #define TIXML_SSCANF        sscanf_s
#elif defined _MSC_VER
        // Microsoft Visual Studio 2003 and earlier or WinCE
        #define TIXML_SNPRINTF        _snprintf
        #define TIXML_VSNPRINTF _vsnprintf
        #define TIXML_SSCANF        sscanf
        #if (_MSC_VER < 1400 ) && (!defined WINCE)
                // Microsoft Visual Studio 2003 and not WinCE.
                #define TIXML_VSCPRINTF   _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have.
        #else
                // Microsoft Visual Studio 2003 and earlier or WinCE.
                static inline int TIXML_VSCPRINTF( const char* format, va_list va )
                {
                        int len = 512;
                        for (;;) {
                                len = len*2;
                                char* str = new char[len]();
                                const int required = _vsnprintf(str, len, format, va);
                                delete[] str;
                                if ( required != -1 ) {
                                        TIXMLASSERT( required >= 0 );
                                        len = required;
                                        break;
                                }
                        }
                        TIXMLASSERT( len >= 0 );
                        return len;
                }
        #endif
#else
        // GCC version 3 and higher
        //#warning( "Using sn* functions." )
        #define TIXML_SNPRINTF        snprintf
        #define TIXML_VSNPRINTF        vsnprintf
        static inline int TIXML_VSCPRINTF( const char* format, va_list va)
{
    int len = vsnprintf(0, 0, format, va);
    TIXMLASSERT(len >= 0);
    return len;
}
#define TIXML_SSCANF   sscanf
#endif


static const char LINE_FEED = (char)0x0a;                        // all line endings are normalized to LF
static const char LF = LINE_FEED;
static const char CARRIAGE_RETURN = (char)0x0d;                        // CR gets filtered out
static const char CR = CARRIAGE_RETURN;
static const char SINGLE_QUOTE = '\'';
static const char DOUBLE_QUOTE = '\"';

// Bunch of unicode info at:
//                http://www.unicode.org/faq/utf_bom.html
//        ef bb bf (Microsoft "lead bytes") - designates UTF-8

static const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;

namespace tinyxml2
{

    struct Entity
    {
        const char* pattern;
        int length;
        char value;
    };

    static const int NUM_ENTITIES = 5;
    static const Entity entities[NUM_ENTITIES] = {
    { "quot", 4,    DOUBLE_QUOTE },
    { "amp", 3,     '&'  },
    { "apos", 4,    SINGLE_QUOTE },
    { "lt", 2,      '<'  },
    { "gt", 2,      '>'  }
};


    StrPair::~StrPair()
    {
        Reset();
    }


    void StrPair::TransferTo(StrPair* other)
    {
        if (this == other)
        {
            return;
        }
        // This in effect implements the assignment operator by "moving"
        // ownership (as in auto_ptr).

        TIXMLASSERT(other->_flags == 0);
        TIXMLASSERT(other->_start == 0);
        TIXMLASSERT(other->_end == 0);

        other->Reset();

        other->_flags = _flags;
        other->_start = _start;
        other->_end = _end;

        _flags = 0;
        _start = 0;
        _end = 0;
    }

    void StrPair::Reset()
    {
        if (_flags & NEEDS_DELETE)
        {
            delete[] _start;
        }
        _flags = 0;
        _start = 0;
        _end = 0;
    }


    void StrPair::SetStr( const char* str, int flags)
    {
        Reset();
        size_t len = strlen(str);
        TIXMLASSERT(_start == 0);
        _start = new char[len + 1];
        memcpy(_start, str, len + 1);
        _end = _start + len;
        _flags = flags | NEEDS_DELETE;
    }


    char* StrPair::ParseText(char* p, const char* endTag, int strFlags)
    {
        TIXMLASSERT(endTag && *endTag);

        char* start = p;
        char endChar = *endTag;
        size_t length = strlen(endTag);

        // Inner loop of text parsing.
        while (*p)
        {
            if (*p == endChar && strncmp(p, endTag, length) == 0)
            {
                Set(start, p, strFlags);
                return p + length;
            }
            ++p;
        }
        return 0;
    }


    char* StrPair::ParseName(char* p)
    {
        if (!p || !(*p))
        {
            return 0;
        }
        if (!XMLUtil::IsNameStartChar(*p))
        {
            return 0;
        }

        char* const start = p;
        ++p;
        while (*p && XMLUtil::IsNameChar(*p))
        {
            ++p;
        }

        Set(start, p, 0);
        return p;
    }


    void StrPair::CollapseWhitespace()
    {
        // Adjusting _start would cause undefined behavior on delete[]
        TIXMLASSERT((_flags & NEEDS_DELETE) == 0);
        // Trim leading space.
        _start = XMLUtil::SkipWhiteSpace(_start);

        if (*_start)
        {
            char* p = _start;   // the read pointer
            char* q = _start;   // the write pointer

            while (*p)
            {
                if (XMLUtil::IsWhiteSpace(*p))
                {
                    p = XMLUtil::SkipWhiteSpace(p);
                    if (*p == 0)
                    {
                        break;    // don't write to q; this trims the trailing space.
                    }
                    *q = ' ';
                    ++q;
                }
                *q = *p;
                ++q;
                ++p;
            }
            *q = 0;
        }
    }


    const char* StrPair::GetStr()
    {
        TIXMLASSERT(_start);
        TIXMLASSERT(_end);
        if (_flags & NEEDS_FLUSH)
        {
            *_end = 0;
            _flags ^= NEEDS_FLUSH;

            if (_flags)
            {
                char* p = _start;   // the read pointer
                char* q = _start;   // the write pointer

                while (p < _end)
                {
                    if ((_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR)
                    {
                        // CR-LF pair becomes LF
                        // CR alone becomes LF
                        // LF-CR becomes LF
                        if (*(p + 1) == LF)
                        {
                            p += 2;
                        }
                        else
                        {
                            ++p;
                        }
                        *q++ = LF;
                    }
                    else if ((_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF)
                    {
                        if (*(p + 1) == CR)
                        {
                            p += 2;
                        }
                        else
                        {
                            ++p;
                        }
                        *q++ = LF;
                    }
                    else if ((_flags & NEEDS_ENTITY_PROCESSING) && *p == '&')
                    {
                        // Entities handled by tinyXML2:
                        // - special entities in the entity table [in/out]
                        // - numeric character reference [in]
                        //   中 or 中

                        if (*(p + 1) == '#')
                        {
                            const int buflen = 10;
                            char buf[buflen] = { 0 };
                            int len = 0;
                            char* adjusted = const_cast(XMLUtil::GetCharacterRef(p, buf, &len));
                            if (adjusted == 0)
                            {
                                *q = *p;
                                ++p;
                                ++q;
                            }
                            else
                            {
                                TIXMLASSERT(0 <= len && len <= buflen);
                                TIXMLASSERT(q + len <= adjusted);
                                p = adjusted;
                                memcpy(q, buf, len);
                                q += len;
                            }
                        }
                        else
                        {
                            bool entityFound = false;
                            for (int i = 0; i < NUM_ENTITIES; ++i)
                            {
                                const Entity&entity = entities[i];
                                if (strncmp(p + 1, entity.pattern, entity.length) == 0
                                        && *(p + entity.length + 1) == ';')
                                {
                                    // Found an entity - convert.
                                    *q = entity.value;
                                    ++q;
                                    p += entity.length + 2;
                                    entityFound = true;
                                    break;
                                }
                            }
                            if (!entityFound)
                            {
                                // fixme: treat as error?
                                ++p;
                                ++q;
                            }
                        }
                    }
                    else
                    {
                        *q = *p;
                        ++p;
                        ++q;
                    }
                }
                *q = 0;
            }
            // The loop below has plenty going on, and this
            // is a less useful mode. Break it out.
            if (_flags & NEEDS_WHITESPACE_COLLAPSING)
            {
                CollapseWhitespace();
            }
            _flags = (_flags & NEEDS_DELETE);
        }
        TIXMLASSERT(_start);
        return _start;
    }




    // --------- XMLUtil ----------- //

    const char* XMLUtil::ReadBOM( const char* p, bool* bom)
    {
        TIXMLASSERT(p);
        TIXMLASSERT(bom);
        *bom = false;
        const unsigned char* pu = reinterpret_cast  (p);
        // Check for BOM:
        if (*(pu + 0) == TIXML_UTF_LEAD_0
                && *(pu + 1) == TIXML_UTF_LEAD_1
                && *(pu + 2) == TIXML_UTF_LEAD_2)
        {
            *bom = true;
            p += 3;
        }
        TIXMLASSERT(p);
        return p;
    }


    void XMLUtil::ConvertUTF32ToUTF8(unsigned long input, char* output, int* length)
    {
        const unsigned long BYTE_MASK = 0xBF;
        const unsigned long BYTE_MARK = 0x80;
        const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };

        if (input < 0x80)
        {
            *length = 1;
        }
        else if (input < 0x800)
        {
            *length = 2;
        }
        else if (input < 0x10000)
        {
            *length = 3;
        }
        else if (input < 0x200000)
        {
            *length = 4;
        }
        else
        {
            *length = 0;    // This code won't convert this correctly anyway.
            return;
        }

        output += *length;

        // Scary scary fall throughs.
        switch (*length)
        {
            case 4:
                --output;
                *output = (char)((input | BYTE_MARK) & BYTE_MASK);
                input >>= 6;
            case 3:
                --output;
                *output = (char)((input | BYTE_MARK) & BYTE_MASK);
                input >>= 6;
            case 2:
                --output;
                *output = (char)((input | BYTE_MARK) & BYTE_MASK);
                input >>= 6;
            case 1:
                --output;
                *output = (char)(input | FIRST_BYTE_MARK[*length]);
                break;
            default:
                TIXMLASSERT(false);
        }
    }


    const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length)
    {
        // Presume an entity, and pull it out.
        *length = 0;

        if (*(p + 1) == '#' && *(p + 2))
        {
            unsigned long ucs = 0;
            TIXMLASSERT(sizeof(ucs) >= 4);
            ptrdiff_t delta = 0;
            unsigned mult = 1;
            static const char SEMICOLON = ';';

            if (*(p + 2) == 'x')
            {
                // Hexadecimal.
                const char* q = p + 3;
                if (!(*q))
                {
                    return 0;
                }

                q = strchr(q, SEMICOLON);

                if (!q)
                {
                    return 0;
                }
                TIXMLASSERT(*q == SEMICOLON);

                delta = q - p;
                --q;

                while (*q != 'x')
                {
                    unsigned int digit = 0;

                    if (*q >= '0' && *q <= '9')
                    {
                        digit = *q - '0';
                    }
                    else if (*q >= 'a' && *q <= 'f')
                    {
                        digit = *q - 'a' + 10;
                    }
                    else if (*q >= 'A' && *q <= 'F')
                    {
                        digit = *q - 'A' + 10;
                    }
                    else
                    {
                        return 0;
                    }
                    TIXMLASSERT(digit >= 0 && digit < 16);
                    TIXMLASSERT(digit == 0 || mult <= UINT_MAX / digit);
                    const unsigned int digitScaled = mult * digit;
                    TIXMLASSERT(ucs <= ULONG_MAX - digitScaled);
                    ucs += digitScaled;
                    TIXMLASSERT(mult <= UINT_MAX / 16);
                    mult *= 16;
                    --q;
                }
            }
            else
            {
                // Decimal.
                const char* q = p + 2;
                if (!(*q))
                {
                    return 0;
                }

                q = strchr(q, SEMICOLON);

                if (!q)
                {
                    return 0;
                }
                TIXMLASSERT(*q == SEMICOLON);

                delta = q - p;
                --q;

                while (*q != '#')
                {
                    if (*q >= '0' && *q <= '9')
                    {
                        const unsigned int digit = *q - '0';
                        TIXMLASSERT(digit >= 0 && digit < 10);
                        TIXMLASSERT(digit == 0 || mult <= UINT_MAX / digit);
                        const unsigned int digitScaled = mult * digit;
                        TIXMLASSERT(ucs <= ULONG_MAX - digitScaled);
                        ucs += digitScaled;
                    }
                    else
                    {
                        return 0;
                    }
                    TIXMLASSERT(mult <= UINT_MAX / 10);
                    mult *= 10;
                    --q;
                }
            }
            // convert the UCS to UTF-8
            ConvertUTF32ToUTF8(ucs, value, length);
            return p + delta + 1;
        }
        return p + 1;
    }


    void XMLUtil::ToStr(int v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%d", v);
    }


    void XMLUtil::ToStr(unsigned v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%u", v);
    }


    void XMLUtil::ToStr(bool v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%d", v ? 1 : 0);
    }

    /*
        ToStr() of a number is a very tricky topic.
        https://github.com/leethomason/tinyxml2/issues/106
    */
    void XMLUtil::ToStr(float v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%.8g", v);
    }


    void XMLUtil::ToStr(double v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%.17g", v);
    }


    bool XMLUtil::ToInt( const char* str, int* value)
    {
        if (TIXML_SSCANF(str, "%d", value) == 1)
        {
            return true;
        }
        return false;
    }

    bool XMLUtil::ToUnsigned( const char* str, unsigned* value)
    {
        if (TIXML_SSCANF(str, "%u", value) == 1)
        {
            return true;
        }
        return false;
    }

    bool XMLUtil::ToBool( const char* str, bool* value)
    {
        int ival = 0;
        if (ToInt(str, &ival))
        {
            *value = (ival == 0) ? false : true;
            return true;
        }
        if (StringEqual(str, "true"))
        {
            *value = true;
            return true;
        }
        else if (StringEqual(str, "false"))
        {
            *value = false;
            return true;
        }
        return false;
    }


    bool XMLUtil::ToFloat( const char* str, float* value)
    {
        if (TIXML_SSCANF(str, "%f", value) == 1)
        {
            return true;
        }
        return false;
    }

    bool XMLUtil::ToDouble( const char* str, double* value)
    {
        if (TIXML_SSCANF(str, "%lf", value) == 1)
        {
            return true;
        }
        return false;
    }


    char* XMLDocument::Identify(char* p, XMLNode** node)
    {
        TIXMLASSERT(node);
        TIXMLASSERT(p);
        char* const start = p;
        p = XMLUtil::SkipWhiteSpace(p);
        if (!*p)
        {
            *node = 0;
            TIXMLASSERT(p);
            return p;
        }

        // These strings define the matching patterns:
        static const char* xmlHeader = { "         static const char* commentHeader = { "
    //
    // With a special case:
    //                
    //                

    //                
    //
    // Where the closing element (/foo) *must* be the next thing after the opening
    // element, and the names must match. BUT the tricky bit is that the closing
    // element will be read by the child.
    //
    // 'endTag' is the end tag for this node, it is returned by a call to a child.
    // 'parentEnd' is the end tag for the parent, which is filled in and returned.

    while (p && *p)
    {
        XMLNode* node = 0;

        p = _document->Identify(p, &node);
        if (node == 0)
        {
            break;
        }

        StrPair endTag;
        p = node->ParseDeep(p, &endTag);
        if (!p)
        {
            DeleteNode(node);
            if (!_document->Error())
            {
                _document->SetError(XML_ERROR_PARSING, 0, 0);
            }
            break;
        }

        XMLDeclaration* decl = node->ToDeclaration();
        if (decl)
        {
            // A declaration can only be the first child of a document.
            // Set error, if document already has children.
            if (!_document->NoChildren())
            {
                _document->SetError(XML_ERROR_PARSING_DECLARATION, decl->Value(), 0);
                DeleteNode(decl);
                break;
            }
        }

        XMLElement* ele = node->ToElement();
        if (ele)
        {
            // We read the end tag. Return it to the parent.
            if (ele->ClosingType() == XMLElement::CLOSING)
            {
                if (parentEnd)
                {
                    ele->_value.TransferTo(parentEnd);
                }
                node->_memPool->SetTracked();   // created and then immediately deleted.
                DeleteNode(node);
                return p;
            }

            // Handle an end tag returned to this level.
            // And handle a bunch of annoying errors.
            bool mismatch = false;
            if (endTag.Empty())
            {
                if (ele->ClosingType() == XMLElement::OPEN)
                {
                    mismatch = true;
                }
            }
            else
            {
                if (ele->ClosingType() != XMLElement::OPEN)
                {
                    mismatch = true;
                }
                else if (!XMLUtil::StringEqual(endTag.GetStr(), ele->Name()))
                {
                    mismatch = true;
                }
            }
            if (mismatch)
            {
                _document->SetError(XML_ERROR_MISMATCHED_ELEMENT, ele->Name(), 0);
                DeleteNode(node);
                break;
            }
        }
        InsertEndChild(node);
    }
    return 0;
}

void XMLNode::DeleteNode(XMLNode* node)
{
    if (node == 0)
    {
        return;
    }
    MemPool* pool = node->_memPool;
    node->~XMLNode();
    pool->Free(node);
}

void XMLNode::InsertChildPreamble(XMLNode* insertThis) const
{
    TIXMLASSERT(insertThis );
    TIXMLASSERT(insertThis->_document == _document );

    if ( insertThis->_parent )
        insertThis->_parent->Unlink(insertThis );
    else
        insertThis->_memPool->SetTracked();
}

// --------- XMLText ---------- //
char* XMLText::ParseDeep(char* p, StrPair* )
{
    const char* start = p;
    if (this->CData())
    {
        p = _value.ParseText(p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION);
        if (!p)
        {
            _document->SetError(XML_ERROR_PARSING_CDATA, start, 0);
        }
        return p;
    }
    else
    {
        int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES;
        if (_document->WhitespaceMode() == COLLAPSE_WHITESPACE)
        {
            flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING;
        }

        p = _value.ParseText(p, "<", flags);
        if (p && *p)
        {
            return p - 1;
        }
        if (!p)
        {
            _document->SetError(XML_ERROR_PARSING_TEXT, start, 0);
        }
    }
    return 0;
}


XMLNode* XMLText::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLText* text = doc->NewText(Value());  // fixme: this will always allocate memory. Intern?
text->SetCData(this->CData() );
    return text;
}


bool XMLText::ShallowEqual( const XMLNode* compare) const
{
    const XMLText* text = compare->ToText();
    return ( text && XMLUtil::StringEqual( text->Value(), Value() ) );
}


bool XMLText::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    return visitor->Visit( *this );
}


// --------- XMLComment ---------- //

XMLComment::XMLComment( XMLDocument* doc ) : XMLNode(doc )
{
}


XMLComment::~XMLComment()
{
}


char* XMLComment::ParseDeep(char* p, StrPair* )
{
    // Comment parses as text.
    const char* start = p;
    p = _value.ParseText(p, "-->", StrPair::COMMENT);
    if (p == 0)
    {
        _document->SetError(XML_ERROR_PARSING_COMMENT, start, 0);
    }
    return p;
}


XMLNode* XMLComment::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLComment* comment = doc->NewComment(Value());        // fixme: this will always allocate memory. Intern?
    return comment;
}


bool XMLComment::ShallowEqual( const XMLNode* compare) const
{
    TIXMLASSERT(compare );
const XMLComment* comment = compare->ToComment();
    return ( comment && XMLUtil::StringEqual( comment->Value(), Value() ));
}


bool XMLComment::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    return visitor->Visit( *this );
}


// --------- XMLDeclaration ---------- //

XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode(doc )
{
}


XMLDeclaration::~XMLDeclaration()
{
    //printf( "~XMLDeclaration\n" );
}


char* XMLDeclaration::ParseDeep(char* p, StrPair* )
{
    // Declaration parses as text.
    const char* start = p;
    p = _value.ParseText(p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION);
    if (p == 0)
    {
        _document->SetError(XML_ERROR_PARSING_DECLARATION, start, 0);
    }
    return p;
}


XMLNode* XMLDeclaration::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLDeclaration* dec = doc->NewDeclaration(Value());        // fixme: this will always allocate memory. Intern?
    return dec;
}


bool XMLDeclaration::ShallowEqual( const XMLNode* compare) const
{
    TIXMLASSERT(compare );
const XMLDeclaration* declaration = compare->ToDeclaration();
    return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() ));
}



bool XMLDeclaration::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    return visitor->Visit( *this );
}

// --------- XMLUnknown ---------- //

XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode(doc )
{
}


XMLUnknown::~XMLUnknown()
{
}


char* XMLUnknown::ParseDeep(char* p, StrPair* )
{
    // Unknown parses as text.
    const char* start = p;

    p = _value.ParseText(p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION);
    if (!p)
    {
        _document->SetError(XML_ERROR_PARSING_UNKNOWN, start, 0);
    }
    return p;
}


XMLNode* XMLUnknown::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLUnknown* text = doc->NewUnknown(Value());        // fixme: this will always allocate memory. Intern?
    return text;
}


bool XMLUnknown::ShallowEqual( const XMLNode* compare) const
{
    TIXMLASSERT(compare );
const XMLUnknown* unknown = compare->ToUnknown();
    return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() ));
}


bool XMLUnknown::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    return visitor->Visit( *this );
}

// --------- XMLAttribute ---------- //

const char* XMLAttribute::Name() const
{
    return _name.GetStr();
}

const char* XMLAttribute::Value() const
{
    return _value.GetStr();
}

char* XMLAttribute::ParseDeep(char* p, bool processEntities)
{
    // Parse using the name rules: bug fix, was using ParseText before
    p = _name.ParseName(p);
    if (!p || !*p)
    {
        return 0;
    }

    // Skip white space before =
    p = XMLUtil::SkipWhiteSpace(p);
    if (*p != '=')
    {
        return 0;
    }

    ++p;        // move up to opening quote
    p = XMLUtil::SkipWhiteSpace(p);
    if (*p != '\"' && *p != '\'')
    {
        return 0;
    }

    char endTag[2] = { *p, 0 };
    ++p;        // move past opening quote

    p = _value.ParseText(p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES);
    return p;
}


void XMLAttribute::SetName( const char* n)
{
    _name.SetStr(n);
}


XMLError XMLAttribute::QueryIntValue(int* value) const
{
    if ( XMLUtil::ToInt( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


XMLError XMLAttribute::QueryUnsignedValue(unsigned int* value) const
{
    if ( XMLUtil::ToUnsigned( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


XMLError XMLAttribute::QueryBoolValue(bool* value) const
{
    if ( XMLUtil::ToBool( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


XMLError XMLAttribute::QueryFloatValue(float* value) const
{
    if ( XMLUtil::ToFloat( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


XMLError XMLAttribute::QueryDoubleValue(double* value) const
{
    if ( XMLUtil::ToDouble( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


void XMLAttribute::SetAttribute( const char* v)
{
    _value.SetStr(v);
}


void XMLAttribute::SetAttribute(int v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}


void XMLAttribute::SetAttribute(unsigned v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}


void XMLAttribute::SetAttribute(bool v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}

void XMLAttribute::SetAttribute(double v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}

void XMLAttribute::SetAttribute(float v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}


// --------- XMLElement ---------- //
XMLElement::XMLElement( XMLDocument* doc ) : XMLNode(doc ),
    _closingType( 0 ),
    _rootAttribute( 0 )
{
}


XMLElement::~XMLElement()
{
    while (_rootAttribute)
    {
        XMLAttribute* next = _rootAttribute->_next;
        DeleteAttribute(_rootAttribute);
        _rootAttribute = next;
    }
}


const XMLAttribute* XMLElement::FindAttribute( const char* name) const
{
    for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) {
        if ( XMLUtil::StringEqual( a->Name(), name ) ) {
            return a;
        }
    }
    return 0;
}


const char* XMLElement::Attribute( const char* name, const char* value) const
{
    const XMLAttribute* a = FindAttribute(name);
    if ( !a ) {
        return 0;
    }
    if ( !value || XMLUtil::StringEqual( a->Value(), value )) {
        return a->Value();
    }
    return 0;
}


const char* XMLElement::GetText() const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        return FirstChild()->Value();
    }
    return 0;
}


void XMLElement::SetText( const char* inText)
{
    if (FirstChild() && FirstChild()->ToText())
        FirstChild()->SetValue(inText);
    else
    {
        XMLText* theText = GetDocument()->NewText(inText);
        InsertFirstChild(theText);
    }
}


void XMLElement::SetText(int v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


void XMLElement::SetText(unsigned v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


void XMLElement::SetText(bool v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


void XMLElement::SetText(float v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


void XMLElement::SetText(double v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


XMLError XMLElement::QueryIntText(int* ival) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToInt( t, ival ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}


XMLError XMLElement::QueryUnsignedText(unsigned* uval) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToUnsigned( t, uval ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}


XMLError XMLElement::QueryBoolText(bool* bval) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToBool( t, bval ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}


XMLError XMLElement::QueryDoubleText(double* dval) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToDouble( t, dval ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}


XMLError XMLElement::QueryFloatText(float* fval) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToFloat( t, fval ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}



XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name)
{
    XMLAttribute* last = 0;
    XMLAttribute* attrib = 0;
    for (attrib = _rootAttribute;
            attrib;
            last = attrib, attrib = attrib->_next)
    {
        if (XMLUtil::StringEqual(attrib->Name(), name))
        {
            break;
        }
    }
    if (!attrib)
    {
        TIXMLASSERT(sizeof(XMLAttribute) == _document->_attributePool.ItemSize());
        attrib = new (_document->_attributePool.Alloc()) XMLAttribute();
        attrib->_memPool = &_document->_attributePool;
        if (last)
        {
            last->_next = attrib;
        }
        else
        {
            _rootAttribute = attrib;
        }
        attrib->SetName(name);
        attrib->_memPool->SetTracked(); // always created and linked.
    }
    return attrib;
}


void XMLElement::DeleteAttribute( const char* name)
{
    XMLAttribute* prev = 0;
    for (XMLAttribute* a = _rootAttribute; a; a = a->_next)
    {
        if (XMLUtil::StringEqual(name, a->Name()))
        {
            if (prev)
            {
                prev->_next = a->_next;
            }
            else
            {
                _rootAttribute = a->_next;
            }
            DeleteAttribute(a);
            break;
        }
        prev = a;
    }
}


char* XMLElement::ParseAttributes(char* p)
{
    const char* start = p;
    XMLAttribute* prevAttribute = 0;

    // Read the attributes.
    while (p)
    {
        p = XMLUtil::SkipWhiteSpace(p);
        if (!(*p))
        {
            _document->SetError(XML_ERROR_PARSING_ELEMENT, start, Name());
            return 0;
        }

        // attribute.
        if (XMLUtil::IsNameStartChar(*p))
        {
            TIXMLASSERT(sizeof(XMLAttribute) == _document->_attributePool.ItemSize());
            XMLAttribute* attrib = new (_document->_attributePool.Alloc()) XMLAttribute();
            attrib->_memPool = &_document->_attributePool;
            attrib->_memPool->SetTracked();

            p = attrib->ParseDeep(p, _document->ProcessEntities());
            if (!p || Attribute(attrib->Name()))
            {
                DeleteAttribute(attrib);
                _document->SetError(XML_ERROR_PARSING_ATTRIBUTE, start, p);
                return 0;
            }
            // There is a minor bug here: if the attribute in the source xml
            // document is duplicated, it will not be detected and the
            // attribute will be doubly added. However, tracking the 'prevAttribute'
            // avoids re-scanning the attribute list. Preferring performance for
            // now, may reconsider in the future.
            if (prevAttribute)
            {
                prevAttribute->_next = attrib;
            }
            else
            {
                _rootAttribute = attrib;
            }
            prevAttribute = attrib;
        }
        // end of the tag
        else if (*p == '>')
        {
            ++p;
            break;
        }
        // end of the tag
        else if (*p == '/' && *(p + 1) == '>')
        {
            _closingType = CLOSED;
            return p + 2;        // done; sealed element.
        }
        else
        {
            _document->SetError(XML_ERROR_PARSING_ELEMENT, start, p);
            return 0;
        }
    }
    return p;
}

void XMLElement::DeleteAttribute(XMLAttribute* attribute)
{
    if (attribute == 0)
    {
        return;
    }
    MemPool* pool = attribute->_memPool;
    attribute->~XMLAttribute();
    pool->Free(attribute);
}

//
//        
//        foobar
//
char* XMLElement::ParseDeep(char* p, StrPair* strPair)
{
    // Read the element name.
    p = XMLUtil::SkipWhiteSpace(p);

    // The closing element is the  form. It is
    // parsed just like a regular element then deleted from
    // the DOM.
    if (*p == '/')
    {
        _closingType = CLOSING;
        ++p;
    }

    p = _value.ParseName(p);
    if (_value.Empty())
    {
        return 0;
    }

    p = ParseAttributes(p);
    if (!p || !*p || _closingType)
    {
        return p;
    }

    p = XMLNode::ParseDeep(p, strPair);
    return p;
}



XMLNode* XMLElement::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLElement* element = doc->NewElement(Value());                                        // fixme: this will always allocate memory. Intern?
    for( const XMLAttribute* a = FirstAttribute(); a; a=a->Next() ) {
        element->SetAttribute(a->Name(), a->Value() );                                        // fixme: this will always allocate memory. Intern?
    }
    return element;
}


bool XMLElement::ShallowEqual( const XMLNode* compare) const
{
    TIXMLASSERT(compare );
const XMLElement* other = compare->ToElement();
    if ( other && XMLUtil::StringEqual( other->Name(), Name() )) {

        const XMLAttribute* a = FirstAttribute();
const XMLAttribute* b = other->FirstAttribute();

        while ( a && b ) {
            if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) {
                return false;
            }
            a = a->Next();
b = b->Next();
        }
        if ( a || b ) {
            // different count
            return false;
        }
        return true;
    }
    return false;
}


bool XMLElement::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    if ( visitor->VisitEnter( *this, _rootAttribute ) ) {
        for ( const XMLNode* node = FirstChild(); node; node=node->NextSibling() ) {
            if ( !node->Accept(visitor ) ) {
                break;
            }
        }
    }
    return visitor->VisitExit( *this );
}


// --------- XMLDocument ----------- //

// Warning: List must match 'enum XMLError'
const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = {
    "XML_SUCCESS",
    "XML_NO_ATTRIBUTE",
    "XML_WRONG_ATTRIBUTE_TYPE",
    "XML_ERROR_FILE_NOT_FOUND",
    "XML_ERROR_FILE_COULD_NOT_BE_OPENED",
    "XML_ERROR_FILE_READ_ERROR",
    "XML_ERROR_ELEMENT_MISMATCH",
    "XML_ERROR_PARSING_ELEMENT",
    "XML_ERROR_PARSING_ATTRIBUTE",
    "XML_ERROR_IDENTIFYING_TAG",
    "XML_ERROR_PARSING_TEXT",
    "XML_ERROR_PARSING_CDATA",
    "XML_ERROR_PARSING_COMMENT",
    "XML_ERROR_PARSING_DECLARATION",
    "XML_ERROR_PARSING_UNKNOWN",
    "XML_ERROR_EMPTY_DOCUMENT",
    "XML_ERROR_MISMATCHED_ELEMENT",
    "XML_ERROR_PARSING",
    "XML_CAN_NOT_CONVERT_TEXT",
    "XML_NO_TEXT_NODE"
};


XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) :
    XMLNode( 0 ),
    _writeBOM( false ),
    _processEntities(processEntities ),
    _errorID(XML_NO_ERROR ),
    _whitespace(whitespace ),
    _errorStr1( 0 ),
    _errorStr2( 0 ),
    _charBuffer( 0 )
{
    // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+)
    _document = this;
}


XMLDocument::~XMLDocument()
{
    Clear();
}


void XMLDocument::Clear()
{
    DeleteChildren();

#ifdef DEBUG
    const bool hadError = Error();
#endif
    _errorID = XML_NO_ERROR;
    _errorStr1 = 0;
    _errorStr2 = 0;

    delete[] _charBuffer;
    _charBuffer = 0;

#if 0
    _textPool.Trace( "text" );
    _elementPool.Trace( "element" );
    _commentPool.Trace( "comment" );
    _attributePool.Trace( "attribute" );
#endif

# ifdef DEBUG
    if (!hadError)
    {
        TIXMLASSERT(_elementPool.CurrentAllocs() == _elementPool.Untracked());
        TIXMLASSERT(_attributePool.CurrentAllocs() == _attributePool.Untracked());
        TIXMLASSERT(_textPool.CurrentAllocs() == _textPool.Untracked());
        TIXMLASSERT(_commentPool.CurrentAllocs() == _commentPool.Untracked());
    }
#endif
}


XMLElement* XMLDocument::NewElement( const char* name)
{
    TIXMLASSERT(sizeof(XMLElement) == _elementPool.ItemSize());
    XMLElement* ele = new (_elementPool.Alloc()) XMLElement(this);
    ele->_memPool = &_elementPool;
    ele->SetName(name);
    return ele;
}


XMLComment* XMLDocument::NewComment( const char* str)
{
    TIXMLASSERT(sizeof(XMLComment) == _commentPool.ItemSize());
    XMLComment* comment = new (_commentPool.Alloc()) XMLComment(this);
    comment->_memPool = &_commentPool;
    comment->SetValue(str);
    return comment;
}


XMLText* XMLDocument::NewText( const char* str)
{
    TIXMLASSERT(sizeof(XMLText) == _textPool.ItemSize());
    XMLText* text = new (_textPool.Alloc()) XMLText(this);
    text->_memPool = &_textPool;
    text->SetValue(str);
    return text;
}


XMLDeclaration* XMLDocument::NewDeclaration( const char* str)
{
    TIXMLASSERT(sizeof(XMLDeclaration) == _commentPool.ItemSize());
    XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration(this);
    dec->_memPool = &_commentPool;
    dec->SetValue(str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"");
    return dec;
}


XMLUnknown* XMLDocument::NewUnknown( const char* str)
{
    TIXMLASSERT(sizeof(XMLUnknown) == _commentPool.ItemSize());
    XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown(this);
    unk->_memPool = &_commentPool;
    unk->SetValue(str);
    return unk;
}

static FILE* callfopen( const char* filepath, const char* mode)
{
    TIXMLASSERT(filepath);
    TIXMLASSERT(mode);
#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
    FILE* fp = 0;
    errno_t err = fopen_s( &fp, filepath, mode );
    if ( err ) {
        return 0;
    }
#else
    FILE* fp = fopen(filepath, mode);
#endif
    return fp;
}

void XMLDocument::DeleteNode(XMLNode* node)
{
    TIXMLASSERT(node);
    TIXMLASSERT(node->_document == this);
    if (node->_parent)
    {
        node->_parent->DeleteChild(node);
    }
    else
    {
        // Isn't in the tree.
        // Use the parent delete.
        // Also, we need to mark it tracked: we 'know'
        // it was never used.
        node->_memPool->SetTracked();
        // Call the static XMLNode version:
        XMLNode::DeleteNode(node);
    }
}


XMLError XMLDocument::LoadFile( const char* filename)
{
    Clear();
    FILE* fp = callfopen(filename, "rb");
    if (!fp)
    {
        SetError(XML_ERROR_FILE_NOT_FOUND, filename, 0);
        return _errorID;
    }
    LoadFile(fp);
    fclose(fp);
    return _errorID;
}


XMLError XMLDocument::LoadFile(FILE* fp)
{
    Clear();

    fseek(fp, 0, SEEK_SET);
    if (fgetc(fp) == EOF && ferror(fp) != 0)
    {
        SetError(XML_ERROR_FILE_READ_ERROR, 0, 0);
        return _errorID;
    }

    fseek(fp, 0, SEEK_END);
    const long filelength = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    if (filelength == -1L)
    {
        SetError(XML_ERROR_FILE_READ_ERROR, 0, 0);
        return _errorID;
    }

    if ((unsigned long)filelength >= (size_t) - 1 ) {
        // Cannot handle files which won't fit in buffer together with null terminator
        SetError(XML_ERROR_FILE_READ_ERROR, 0, 0);
        return _errorID;
    }

    if (filelength == 0)
    {
        SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0);
        return _errorID;
    }

    const size_t size = filelength;
    TIXMLASSERT(_charBuffer == 0);
    _charBuffer = new char[size + 1];
    size_t read = fread(_charBuffer, 1, size, fp);
    if (read != size)
    {
        SetError(XML_ERROR_FILE_READ_ERROR, 0, 0);
        return _errorID;
    }

    _charBuffer[size] = 0;

    Parse();
    return _errorID;
}


XMLError XMLDocument::SaveFile( const char* filename, bool compact)
{
    FILE* fp = callfopen(filename, "w");
    if (!fp)
    {
        SetError(XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0);
        return _errorID;
    }
    SaveFile(fp, compact);
    fclose(fp);
    return _errorID;
}


XMLError XMLDocument::SaveFile(FILE* fp, bool compact)
{
    // Clear any error from the last save, otherwise it will get reported
    // for *this* call.
    SetError(XML_NO_ERROR, 0, 0);
    XMLPrinter stream(fp, compact);
    Print(&stream);
    return _errorID;
}


XMLError XMLDocument::Parse( const char* p, size_t len)
{
    Clear();

    if (len == 0 || !p || !*p)
    {
        SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0);
        return _errorID;
    }
    if (len == (size_t)(-1))
    {
        len = strlen(p);
    }
    TIXMLASSERT(_charBuffer == 0);
    _charBuffer = new char[len + 1];
    memcpy(_charBuffer, p, len);
    _charBuffer[len] = 0;

    Parse();
    if (Error())
    {
        // clean up now essentially dangling memory.
        // and the parse fail can put objects in the
        // pools that are dead and inaccessible.
        DeleteChildren();
        _elementPool.Clear();
        _attributePool.Clear();
        _textPool.Clear();
        _commentPool.Clear();
    }
    return _errorID;
}


void XMLDocument::Print(XMLPrinter* streamer) const
{
    if ( streamer ) {
        Accept(streamer );
    }
    else {
        XMLPrinter stdoutStreamer(stdout );
        Accept( &stdoutStreamer );
    }
}


void XMLDocument::SetError(XMLError error, const char* str1, const char* str2)
{
    TIXMLASSERT(error >= 0 && error < XML_ERROR_COUNT);
    _errorID = error;
    _errorStr1 = str1;
    _errorStr2 = str2;
}

const char* XMLDocument::ErrorName() const
{

    TIXMLASSERT(_errorID >= 0 && _errorID const char* errorName = _errorNames[_errorID];
    TIXMLASSERT(errorName && errorName[0] );
    return errorName;
}

void XMLDocument::Prin