├── README.md ├── Rust-Internal-Recode.vcxproj.user ├── utils ├── string_format.h ├── pattern │ ├── pattern.hpp │ └── pattern.cpp ├── xor_float.hpp ├── no_crt.hpp ├── xorstr.hpp └── vector.hpp ├── Keybind.h ├── memory ├── memory.hpp ├── il2cpp.hpp └── lazy_importer.hpp ├── offsets.h ├── dllmain.cpp ├── Rust-Internal-Recode.vcxproj.filters ├── settings.hpp ├── rust ├── unity.hpp ├── rust.hpp └── features │ └── player_esp.hpp ├── Rust-Internal-Recode.vcxproj ├── projectile.hpp └── hooks.hpp /README.md: -------------------------------------------------------------------------------- 1 | # rust-internal-source 2 | 3 | Amogushook internal source - paste of nekocheat but added alot of shit code is messy but idc 4 | -------------------------------------------------------------------------------- /Rust-Internal-Recode.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /utils/string_format.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stb_sprintf.h" 3 | 4 | namespace string 5 | { 6 | 7 | inline char buffer[512]; 8 | 9 | inline const char* format(const char* fmt, ...) { 10 | va_list args; 11 | va_start(args, fmt); 12 | LI_FIND(vsnprintf)(buffer, 512, fmt, args); 13 | va_end(args); 14 | return buffer; 15 | } 16 | } -------------------------------------------------------------------------------- /Keybind.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //keys: A-Z Mouse0-6 0-9 4 | 5 | namespace keybinds { 6 | auto psilentk = rust::classes::KeyCode::Mouse4; // the bind 7 | bool psilentb = true; //if you want the bind enable or not 8 | auto speedhackk = rust::classes::KeyCode::X; 9 | bool speedhackb = true; 10 | auto silentwalkk = rust::classes::KeyCode::Mouse3; 11 | bool silentwalkb = true; 12 | auto fakelagk = rust::classes::KeyCode::X; 13 | bool fakelagb = false; 14 | auto speedkeyk = rust::classes::KeyCode::X; 15 | bool speedkeyb = true; 16 | } -------------------------------------------------------------------------------- /utils/pattern/pattern.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rb { 4 | namespace pattern 5 | { 6 | uintptr_t find(uintptr_t range_start, uintptr_t range_end, const char* pattern); 7 | uintptr_t find(const char* mod, const char* pattern); 8 | 9 | uintptr_t find_rel(const char* mod, const char* pattern, ptrdiff_t position = 0, ptrdiff_t jmp_size = 3, ptrdiff_t instruction_size = 7); 10 | uint32_t find_offset32(const char* mod, const char* pattern, ptrdiff_t position = 0); 11 | uint32_t find_offset32_rel(const char* mod, const char* pattern, ptrdiff_t position = 0, ptrdiff_t jmp_size = 3, ptrdiff_t instruction_size = 7); 12 | } 13 | } -------------------------------------------------------------------------------- /memory/memory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "lazy_importer.hpp" 3 | 4 | #include "../utils/xorstr.hpp" 5 | 6 | #include "../utils/pattern/pattern.hpp" 7 | 8 | namespace mem { 9 | uintptr_t game_assembly_base = LI_MODULE_SAFE_(_("GameAssembly.dll")); 10 | uintptr_t unity_player_base = LI_MODULE_SAFE_(_("UnityPlayer.dll")); 11 | template 12 | t read(uintptr_t addr) { 13 | if (addr < 0xffffff) 14 | return t(); 15 | if (addr > 0x7fffffff0000) 16 | return t(); 17 | 18 | return *reinterpret_cast(addr); 19 | } 20 | 21 | template 22 | bool write(uintptr_t addr, t buffer) { 23 | *reinterpret_cast(addr) = buffer; 24 | return true; 25 | } 26 | 27 | uintptr_t hook_virtual_function(const char* classname, const char* function_to_hook, void* target, const char* name_space); 28 | } -------------------------------------------------------------------------------- /offsets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace offsets { 4 | constexpr auto Method_BaseEntity_ServerRPC_string_bool_address = 52434560;//address "Name": "Method$BaseEntity.ServerRPC()", 5 | constexpr auto BaseEntity$$ServerRPC_string_bool_Address = 23305920;//method address 6 | constexpr auto Method$BaseEntity_ServerRPC_PlayerProjectileAttack___ = 52436024; //"Name": "Method$BaseEntity.ServerRPC()", 7 | constexpr auto Method$Facepunch_Pool_GetList_TraceInfo_Address = 52880416; // "Name": "Method$Facepunch.Pool.GetList()", 8 | constexpr auto Method$Facepunch_Pool_GetList_TraceInfo_MethodAddress = 8359856; // 9 | constexpr auto Method$BaseEntity_ServerRPC_uint = 52433712; // "Address":,"Method$BaseEntity.ServerRPC()", 10 | constexpr auto BaseEntity$$ServerRPC_uint_ = 23304480; // "Address":, "Name": "BaseEntity$$ServerRPC", 11 | } -------------------------------------------------------------------------------- /utils/xor_float.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define xf(n) xor_float::convert(n) 7 | namespace xor_float 8 | { 9 | constexpr uint32_t gen_key() 10 | { 11 | return (~(__TIME__[0] * 0xa24a7c) ^ 12 | 0xcfc9 ^ 13 | (__TIME__[4] * 0x5a99) ^ 14 | 0x57f3aaa9 ^ 15 | ~(__TIME__[6] * 0x84575a) ^ 16 | 0x51f6 ^ 17 | (__TIME__[3] * 0x1cd2) ^ 18 | 0x7dee4b90 ^ 19 | ~(__TIME__[7] * 0x38ab64) ^ 20 | 0x661198b); 21 | } 22 | 23 | constexpr uint32_t xor_key = xor_float::gen_key(); 24 | __forceinline float convert_back(const uint32_t val) 25 | { 26 | const auto xor_key_m128 = _mm_castsi128_ps(_mm_cvtsi32_si128(xor_float::xor_key)); 27 | const auto val_m128 = _mm_castsi128_ps(_mm_cvtsi32_si128(val)); 28 | const auto xored_val_m128 = _mm_xor_ps(val_m128, xor_key_m128); 29 | return _mm_cvtss_f32(xored_val_m128); 30 | } 31 | __forceinline float convert(float val) 32 | { 33 | uint32_t cache; 34 | reinterpret_cast(cache) = val; 35 | cache ^= xor_float::xor_key; 36 | return xor_float::convert_back(cache); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "rust/rust.hpp" 10 | 11 | #include "projectile.hpp" 12 | 13 | #include "memory/memory.hpp" 14 | #include "memory/lazy_importer.hpp" 15 | #include "memory/il2cpp.hpp" 16 | 17 | #include "utils/no_crt.hpp" 18 | #include "utils/xorstr.hpp" 19 | #include "utils/pattern/pattern.hpp" 20 | 21 | #include "gui/OnGUI.hpp" 22 | 23 | #include "assets/assets.hpp" 24 | 25 | #include "rust/unity.hpp" 26 | #include "rust/features/player_esp.hpp" 27 | 28 | #include "hooks.hpp" 29 | 30 | bool has_initialized = false; 31 | 32 | bool DllMain(uintptr_t hmodule) 33 | { 34 | 35 | if (!has_initialized) { 36 | mem::game_assembly_base = LI_MODULE_SAFE_(_("GameAssembly.dll")); 37 | mem::unity_player_base = LI_MODULE_SAFE_(_("UnityPlayer.dll")); 38 | 39 | //mem::try_pattern(_("53 C3")); 40 | 41 | il2cpp::init(); 42 | unity::init_unity(); 43 | gui::init_gui(); 44 | hooks::init_hooks(); 45 | init_bp(); 46 | init_projectile(); 47 | has_initialized = true; 48 | } 49 | il2cpp::hook(&gui::OnGUI, _("OnGUI"), _("DDraw"), _("UnityEngine"), 0); 50 | il2cpp::hook(&hooks::hk_OnNetworkMessage, _("OnNetworkMessage"), _("Client"), _(""), 1); 51 | //il2cpp::hook(&OnFatBullet, _("Update"), _("Projectile"), _(""), 0); 52 | 53 | mem::hook_virtual_function(_("BasePlayer"), _("ClientInput"), &hooks::hk_baseplayer_ClientInput); 54 | //mem::hook_virtual_function(_("BasePlayer"), _("BlockSprint"), &hooks::hk_blocksprint); 55 | //mem::hook_virtual_function(_("Client"), _("IsConnected"), &hooks::is_connected_hk, _("Network")); 56 | 57 | return true; 58 | } 59 | -------------------------------------------------------------------------------- /utils/pattern/pattern.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "pattern.hpp" 8 | #include "../../memory/lazy_importer.hpp" 9 | 10 | #define in_range(x,a,b) (x>=a&&x<=b) 11 | #define get_bits(x) (in_range((x&(~0x20)),'A','F')?((x&(~0x20))-'A'+0xa):(in_range(x,'0','9')?x-'0':0)) 12 | #define get_byte(x) (get_bits(x[0])<<4|get_bits(x[1])) 13 | 14 | uintptr_t rb::pattern::find(uintptr_t range_start, uintptr_t range_end, const char* pattern) { 15 | const char* pattern_bytes = pattern; 16 | 17 | uintptr_t first_match = 0; 18 | 19 | for (uintptr_t cur_byte = range_start; cur_byte < range_end; cur_byte++) { 20 | if (!*pattern_bytes) 21 | return first_match; 22 | 23 | if (*(uint8_t*)pattern_bytes == '\?' || *(uint8_t*)cur_byte == static_cast(get_byte(pattern_bytes))) { 24 | if (!first_match) 25 | first_match = cur_byte; 26 | 27 | if (!pattern_bytes[2]) 28 | return first_match; 29 | 30 | if (*(uint16_t*)pattern_bytes == '\?\?' || *(uint8_t*)pattern_bytes != '\?') 31 | pattern_bytes += 3; 32 | else 33 | pattern_bytes += 2; 34 | } 35 | else { 36 | pattern_bytes = pattern; 37 | first_match = 0; 38 | } 39 | } 40 | 41 | return 0; 42 | } 43 | 44 | uintptr_t rb::pattern::find(const char* mod, const char* pattern) { 45 | const char* pattern_bytes = pattern; 46 | 47 | uintptr_t range_start = (uintptr_t)LI_MODULE_SAFE_(mod); 48 | 49 | uintptr_t range_end = range_start + LI_MODULESIZE_SAFE_(mod); 50 | 51 | return find(range_start, range_end, pattern); 52 | } 53 | 54 | uintptr_t rb::pattern::find_rel(const char* mod, const char* pattern, ptrdiff_t position, ptrdiff_t jmp_size, ptrdiff_t instruction_size) { 55 | auto result = find(mod, pattern); 56 | 57 | if (!result) return 0; 58 | 59 | result += position; 60 | 61 | auto rel_addr = *reinterpret_cast(result + jmp_size); 62 | auto abs_addr = result + instruction_size + rel_addr; 63 | 64 | return abs_addr; 65 | } 66 | 67 | uint32_t rb::pattern::find_offset32(const char* mod, const char* pattern, ptrdiff_t position) { 68 | auto result = find(mod, pattern); 69 | 70 | if (!result) return 0; 71 | 72 | result += position; 73 | 74 | auto mod_base = LI_MODULE_SAFE_(mod); 75 | 76 | return result - mod_base; 77 | } 78 | 79 | uint32_t rb::pattern::find_offset32_rel(const char* mod, const char* pattern, ptrdiff_t position, ptrdiff_t jmp_size, ptrdiff_t instruction_size) { 80 | auto result = find_rel(mod, pattern, position, jmp_size, instruction_size); 81 | 82 | if (!result) return 0; 83 | 84 | auto mod_base = LI_MODULE_SAFE_(mod); 85 | 86 | return result - mod_base; 87 | } -------------------------------------------------------------------------------- /Rust-Internal-Recode.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {f62c0e42-6cbd-44a9-b461-3e9661627894} 6 | 7 | 8 | {e8b0e535-5d6b-417a-b924-f167259b4417} 9 | 10 | 11 | {23de1357-6616-4cd7-a8a4-0bfcc928fcf5} 12 | 13 | 14 | {77dbc598-e99c-453f-a741-542d31478b22} 15 | 16 | 17 | {57934f36-8bac-4225-9b7f-08128dd70049} 18 | 19 | 20 | {f445962f-3823-44e3-a251-1780323b069b} 21 | 22 | 23 | {a2ef4bae-6621-4684-9dd7-6d1cab55ba82} 24 | 25 | 26 | 27 | 28 | 29 | utils\pattern 30 | 31 | 32 | 33 | 34 | assets 35 | 36 | 37 | gui 38 | 39 | 40 | 41 | memory 42 | 43 | 44 | memory 45 | 46 | 47 | memory 48 | 49 | 50 | rust 51 | 52 | 53 | rust 54 | 55 | 56 | rust\features 57 | 58 | 59 | rust 60 | 61 | 62 | rust 63 | 64 | 65 | 66 | utils 67 | 68 | 69 | utils\pattern 70 | 71 | 72 | utils 73 | 74 | 75 | utils 76 | 77 | 78 | utils 79 | 80 | 81 | 82 | utils 83 | 84 | 85 | utils 86 | 87 | 88 | -------------------------------------------------------------------------------- /settings.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace settings { 4 | namespace weapon { 5 | bool hitbox_override = false; 6 | bool magic_bullet = false; 7 | bool fastshoot = false; 8 | float aimbotfov = 500; 9 | float thickness = 0.5; 10 | bool random_hitbox = false; 11 | bool silent_melee = false; 12 | bool weapon_removals = false; 13 | bool always_shoot = false; 14 | bool psilent = false; 15 | bool psilentvis = true; 16 | bool thick_bullet = false; 17 | bool legit_recoil = false; 18 | bool fast_bullet = false; 19 | bool ultraBullet = false; 20 | bool norecoil = false; 21 | bool nospread = false; 22 | bool nosway = false; 23 | bool automatic = false; 24 | bool mods = false; 25 | } 26 | 27 | namespace visuals { 28 | bool player_esp = false; 29 | bool rainbow_chams = false; 30 | bool hotbar_esp = false; 31 | bool chams = false; 32 | bool boxesp = false; 33 | bool spriteitem = false; 34 | bool cancer = false; 35 | bool misc_esp = true; 36 | bool sleeper_esp = false; 37 | bool heli_esp = false; 38 | bool outline = false; 39 | bool npc_esp = false; 40 | bool dropped_items = false; 41 | float VisRcolor = 1; 42 | float VisGcolor = 0.6; 43 | float VisBcolor = 0; 44 | float InvRcolor = 0.3828125; 45 | float InvGcolor = 0.109375; 46 | float InvBcolor = 0.30078125; 47 | float TeamRcolor = 0.984375; 48 | float TeamGcolor = 0.01171875; 49 | float TeamBcolor = 0.984375; 50 | bool stash = false; 51 | bool materials = false; 52 | bool sulfur_ore = false; 53 | bool stone_ore = false; 54 | bool metal_ore = false; 55 | bool weapon = false; 56 | bool midhealth = false; 57 | bool midname = false; 58 | bool traps = false; 59 | bool vehicles = false; 60 | bool airdrops = false; 61 | bool cloth = false; 62 | bool corpses = false; 63 | bool tc_esp = false; 64 | bool raid_esp = false; 65 | bool hackable_crate_esp = false; 66 | bool full_box = false; 67 | bool corner_box = false; 68 | bool bottomhealth = false; 69 | bool steamid = false; 70 | bool sidehealth = false; 71 | bool nameesp = false; 72 | bool woundedflag = false; 73 | 74 | bool weaponesp = false; 75 | bool vehicle = false; 76 | } 77 | 78 | namespace misc { 79 | float m_idebugcam_speed = 1.f; 80 | float code_lock_code = 1000; 81 | bool playerfovtoggle = true; 82 | float playerfov = 90; 83 | bool zoomtoggle = true; 84 | float zoomfov = 10; 85 | bool Movement = false; 86 | bool eyeoffset = false; 87 | float playereyes = 1.4; 88 | bool spinbot = false; 89 | bool always_shoot = false; 90 | bool attack_on_mountables = false; 91 | bool speedhack = false; 92 | bool hitsound = true; 93 | float speedhackspeed = 5; 94 | bool TakeFallDamage = false; 95 | bool silent_farm = false; 96 | bool auto_lock = false; 97 | bool always_sprint = false; 98 | bool gravity = false; 99 | bool infinite_jump = false; 100 | bool fake_lag = false; 101 | bool brightnight = true; 102 | float staramount = 350; 103 | bool admin_mode = false; 104 | bool view_offset = false; 105 | bool instant_med = false; 106 | bool instant_revive = false; 107 | bool no_playercollision = false; 108 | bool spiderman = false; 109 | bool Crosshair = false; 110 | bool silentwalk = false; 111 | bool interactive_debug = false; 112 | bool trollface = false; 113 | 114 | } 115 | } -------------------------------------------------------------------------------- /utils/no_crt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | int _purecall(void); 5 | 6 | namespace std 7 | { 8 | 9 | [[noreturn]] inline void __cdecl _Xbad_function_call() { __ud2(); } 10 | [[noreturn]] inline void __cdecl _Xbad_alloc() { __ud2(); } 11 | [[noreturn]] inline void __cdecl _Xlength_error(char const*) { __ud2(); } 12 | [[noreturn]] inline void __cdecl _Xout_of_range(char const*) { __ud2(); } 13 | [[noreturn]] inline void __cdecl __security_check_cookie() { __ud2(); } 14 | } // namespace std 15 | 16 | #ifndef _DEBUG 17 | extern "C" void __chkstk() {} // Disables stack allocation size limits. 18 | extern "C" void __CxxFrameHandler4() { __ud2(); } 19 | extern "C" void __std_terminate() { __ud2(); } 20 | extern "C" void _fltused() { __ud2(); } 21 | #endif 22 | 23 | #define _Xlength_error(x) __ud2() 24 | #define ABS(N) ((N<0)?(-N):(N)) 25 | 26 | unsigned short lfsr = 0xACE1u; 27 | unsigned int bit = 0; 28 | 29 | unsigned my_rand() 30 | { 31 | if (!lfsr) { 32 | lfsr = 0xACE1u; bit = 0; 33 | } 34 | bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5)) & 1; 35 | return lfsr = (lfsr >> 1) | (bit << 15); 36 | } 37 | 38 | float my_floor(float x) 39 | { 40 | if (x == 0.0) 41 | return 0; 42 | 43 | union { 44 | float input; 45 | int output; 46 | } data; 47 | 48 | data.input = x; 49 | 50 | int exp = data.output & (255 << 23); 51 | exp = exp >> 23; 52 | 53 | int man = data.output & ((1 << 23) - 1); 54 | 55 | int pow = exp - 127; 56 | int mulFactor = 1; 57 | 58 | int i = ABS(pow); 59 | while (i--) 60 | mulFactor *= 2; 61 | 62 | unsigned long long denominator = 1 << 23; 63 | unsigned long long numerator = man + denominator; 64 | 65 | bool negative = (data.output >> 31) != 0; 66 | 67 | if (pow < 0) 68 | denominator *= mulFactor; 69 | else 70 | numerator *= mulFactor; 71 | 72 | float res = 0.0; 73 | while (numerator >= denominator) { 74 | res++; 75 | numerator -= denominator; 76 | } 77 | 78 | if (negative) { 79 | res = -res; 80 | if (numerator != 0) 81 | res -= 1; 82 | } 83 | 84 | return res; 85 | } 86 | 87 | float my_fmod(float a, float b) { return (a - b * my_floor(a / b)); } 88 | 89 | bool m_wcsicmp(wchar_t* a, const wchar_t* b) { 90 | if (!a) 91 | return false; 92 | int ret = 0; 93 | wchar_t* p1 = (wchar_t*)a; 94 | wchar_t* p2 = (wchar_t*)b; 95 | while (!(ret = *p1 - *p2) && *p2) 96 | ++p1, ++p2; 97 | 98 | return ret == 0; 99 | } 100 | 101 | char* m_strstr(char* input, const char* find) 102 | { 103 | do { 104 | const char* p, * q; 105 | for (p = input, q = find; *q != '\0' && *p == *q; p++, q++) {} 106 | if (*q == '\0') { 107 | return input; 108 | } 109 | } while (*(input++) != '\0'); 110 | return 0; 111 | } 112 | 113 | bool m_strcmp(char* a, char* b) { 114 | if ((uintptr_t)a == 0x00000000ffffffff || (uintptr_t)b == 0x00000000ffffffff) 115 | return false; 116 | if ((uintptr_t)a == 0x000000000000007d || (uintptr_t)b == 0x000000000000007d) 117 | return false; 118 | 119 | if (!a || !b) return !a && !b; 120 | 121 | int ret = 0; 122 | unsigned char* p1 = (unsigned char*)a; 123 | unsigned char* p2 = (unsigned char*)b; 124 | while (!(ret = *p1 - *p2) && *p2) 125 | ++p1, ++p2; 126 | 127 | return ret == 0; 128 | } 129 | 130 | unsigned int m_wcslen(wchar_t* str) 131 | { 132 | int cnt = 0; 133 | if (!str) 134 | return 0; 135 | for (; *str != '\0'; ++str) 136 | ++cnt; 137 | return cnt; 138 | } -------------------------------------------------------------------------------- /rust/unity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../memory/il2cpp.hpp" 4 | 5 | #include "rust.hpp" 6 | 7 | namespace unity { 8 | static auto set_lockstate = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Cursor"), _("set_lockState"), 1, _("value"), _("UnityEngine")))); 9 | 10 | static auto get_width = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Screen"), _("get_width"), 0, _(""), _("UnityEngine")))); 11 | 12 | static auto get_height = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Screen"), _("get_height"), 0, _(""), _("UnityEngine")))); 13 | 14 | static auto GetKeyDown = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Input"), _("GetKeyDown"), 1, _("key"), _("UnityEngine"), 1))); 15 | 16 | static auto get_main_camera = reinterpret_cast(il2cpp::methods::resolve_icall(_("UnityEngine.Camera::get_main()"))); 17 | 18 | static auto IgnoreLayerCollision = reinterpret_cast(il2cpp::methods::resolve_icall(_("UnityEngine.Physics::IgnoreLayerCollision()"))); 19 | 20 | static auto get_keyCode = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Event"), _("get_keyCode"), 0, _(""), _("UnityEngine")))); 21 | 22 | static auto LineOfSight = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("GamePhysics"), _("LineOfSight"), -1, _(""), _("")))); 23 | 24 | static auto GetKey = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Input"), _("GetKeyInt"), 1, _(""), _("UnityEngine")))); 25 | 26 | static auto set_visible = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Cursor"), _("set_visible"), 1, _("value"), _("UnityEngine")))); 27 | 28 | static auto get_shader = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Material"), _("get_shader"), 0, _(""), _("UnityEngine")))); 29 | 30 | static auto set_shader = reinterpret_cast(il2cpp::methods::resolve_icall(_("UnityEngine.Material::set_shader()"))); 31 | 32 | void init_unity() { 33 | get_shader = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Material"), _("get_shader"), 0, _(""), _("UnityEngine")))); 34 | 35 | set_shader = reinterpret_cast(il2cpp::methods::resolve_icall(_("UnityEngine.Material::set_shader()"))); 36 | 37 | set_lockstate = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Cursor"), _("set_lockState"), 1, _("value"), _("UnityEngine")))); 38 | 39 | set_visible = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Cursor"), _("set_visible"), 1, _("value"), _("UnityEngine")))); 40 | 41 | get_width = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Screen"), _("get_width"), 0, _(""), _("UnityEngine")))); 42 | 43 | get_height = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Screen"), _("get_height"), 0, _(""), _("UnityEngine")))); 44 | 45 | GetKeyDown = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Input"), _("GetKeyDown"), 1, _("key"), _("UnityEngine"), 1))); 46 | 47 | get_main_camera = reinterpret_cast(il2cpp::methods::resolve_icall(_("UnityEngine.Camera::get_main()"))); 48 | 49 | IgnoreLayerCollision = reinterpret_cast(il2cpp::methods::resolve_icall(_("UnityEngine.Physics::IgnoreLayerCollision()"))); 50 | 51 | get_keyCode = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Event"), _("get_keyCode"), 0, _(""), _("UnityEngine")))); 52 | 53 | LineOfSight = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("GamePhysics"), _("LineOfSight"), -1, _(""), _("")))); 54 | 55 | GetKey = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Input"), _("GetKeyInt"), 1, _(""), _("UnityEngine")))); 56 | } 57 | 58 | bool is_visible(vector3 source, vector3 destination) { 59 | auto layer = (int)rust::classes::Layers::ProjectileLineOfSightCheck | (int)rust::classes::Layers::Terrain; 60 | 61 | return LineOfSight(source, destination, rust::classes::Layers(layer), 0); 62 | } 63 | 64 | auto camera = unity::get_main_camera(); 65 | 66 | VMatrix get_view_matrix() { 67 | if (!camera) { 68 | camera = unity::get_main_camera(); 69 | } 70 | 71 | auto camera_ = mem::read(camera + 0x10); 72 | if (!camera_) { 73 | camera = unity::get_main_camera(); 74 | return {}; 75 | } 76 | 77 | auto matrix = mem::read(camera_ + 0x2E4); 78 | if (!matrix.m) { 79 | camera = unity::get_main_camera(); 80 | return {}; 81 | } 82 | 83 | return matrix; 84 | } 85 | 86 | vector3 get_camera_pos() { 87 | if (!camera) { 88 | camera = unity::get_main_camera(); 89 | } 90 | 91 | auto camera_ = mem::read(camera + 0x10); 92 | if (!camera_) { 93 | camera = unity::get_main_camera(); 94 | return {}; 95 | } 96 | 97 | auto matrix = mem::read(camera_ + 0x42C); 98 | if (!matrix.x || !matrix.y) { 99 | camera = unity::get_main_camera(); 100 | return {}; 101 | } 102 | 103 | 104 | return matrix; 105 | } 106 | float get_fov(vector3 Pos); 107 | } -------------------------------------------------------------------------------- /memory/il2cpp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../utils/no_crt.hpp" 3 | #include "../utils/xorstr.hpp" 4 | 5 | #include "memory.hpp" 6 | 7 | namespace il2cpp { 8 | namespace methods { 9 | using il2cpp_domain_get = uintptr_t (*)(); 10 | 11 | static auto domain_get = LI_FIND_DEF(il2cpp_domain_get); 12 | 13 | using il2cpp_class_get_methods = uintptr_t (*)(uintptr_t, uintptr_t*); 14 | 15 | static auto class_get_methods = LI_FIND_DEF(il2cpp_class_get_methods); 16 | 17 | using il2cpp_method_get_param_count = int (*)(uintptr_t); 18 | 19 | static auto method_get_param_count = LI_FIND_DEF(il2cpp_method_get_param_count); 20 | 21 | using il2cpp_assembly_get_image = uintptr_t (*)(uintptr_t); 22 | 23 | static auto assembly_get_image = LI_FIND_DEF(il2cpp_assembly_get_image); 24 | 25 | using il2cpp_domain_get_assemblies = uintptr_t * (*)(void* domain, uintptr_t* size); 26 | 27 | static auto domain_get_assemblies = LI_FIND_DEF(il2cpp_domain_get_assemblies); 28 | 29 | using il2cpp_object_new = uintptr_t(*)(uintptr_t); 30 | 31 | static auto object_new = LI_FIND_DEF(il2cpp_object_new); 32 | 33 | using il2cpp_class_from_name = uintptr_t (*)(uintptr_t, const char*, const char*); 34 | 35 | static auto class_from_name = LI_FIND_DEF(il2cpp_class_from_name); 36 | 37 | using il2cpp_resolve_icall = uintptr_t (*)(const char*); 38 | 39 | static auto resolve_icall = LI_FIND_DEF(il2cpp_resolve_icall); 40 | 41 | using il2cpp_field_static_get_value = uintptr_t (*)(uintptr_t, uintptr_t*); 42 | 43 | static auto field_static_get_value = LI_FIND_DEF(il2cpp_field_static_get_value); 44 | 45 | using il2cpp_class_get_fields = uintptr_t (*)(uintptr_t, uintptr_t*); 46 | 47 | static auto class_get_fields = LI_FIND_DEF(il2cpp_class_get_fields); 48 | 49 | using il2cpp_field_get_offset = uintptr_t (*)(uintptr_t); 50 | 51 | static auto field_get_offset = LI_FIND_DEF(il2cpp_field_get_offset); 52 | 53 | using il2cpp_runtime_class_init = uintptr_t (*)(uintptr_t); 54 | 55 | static auto runtime_class_init = LI_FIND_DEF(il2cpp_runtime_class_init); 56 | 57 | static auto intialize_method = rb::pattern::find(_("GameAssembly.dll"), _("48 83 EC 48 48 8B 05 ? ? ? ? 48 63 90 ? ? ? ?")); 58 | 59 | using il2cpp_string_new_wrapper = uintptr_t(*)(const char*); 60 | static auto new_string = LI_FIND_DEF(il2cpp_string_new_wrapper); 61 | } 62 | 63 | void init() { 64 | methods::intialize_method = rb::pattern::find(_("GameAssembly.dll"), _("48 83 EC 48 48 8B 05 ? ? ? ? 48 63 90 ? ? ? ?")); 65 | 66 | using il2cpp_string_new_wrapper = uintptr_t(*)(const char*); 67 | methods::new_string = LI_FIND_DEF(il2cpp_string_new_wrapper); 68 | 69 | using il2cpp_domain_get = uintptr_t(*)(); 70 | 71 | methods::domain_get = LI_FIND_DEF(il2cpp_domain_get); 72 | 73 | using il2cpp_class_get_methods = uintptr_t(*)(uintptr_t, uintptr_t*); 74 | 75 | methods::class_get_methods = LI_FIND_DEF(il2cpp_class_get_methods); 76 | 77 | using il2cpp_method_get_param_count = int (*)(uintptr_t); 78 | 79 | methods::method_get_param_count = LI_FIND_DEF(il2cpp_method_get_param_count); 80 | 81 | using il2cpp_assembly_get_image = uintptr_t(*)(uintptr_t); 82 | 83 | methods::assembly_get_image = LI_FIND_DEF(il2cpp_assembly_get_image); 84 | 85 | using il2cpp_domain_get_assemblies = uintptr_t * (*)(void* domain, uintptr_t* size); 86 | 87 | methods::domain_get_assemblies = LI_FIND_DEF(il2cpp_domain_get_assemblies); 88 | 89 | using il2cpp_class_from_name = uintptr_t(*)(uintptr_t, const char*, const char*); 90 | 91 | methods::class_from_name = LI_FIND_DEF(il2cpp_class_from_name); 92 | 93 | using il2cpp_resolve_icall = uintptr_t(*)(const char*); 94 | 95 | methods::resolve_icall = LI_FIND_DEF(il2cpp_resolve_icall); 96 | 97 | using il2cpp_field_static_get_value = uintptr_t(*)(uintptr_t, uintptr_t*); 98 | 99 | methods::field_static_get_value = LI_FIND_DEF(il2cpp_field_static_get_value); 100 | 101 | using il2cpp_class_get_fields = uintptr_t(*)(uintptr_t, uintptr_t*); 102 | 103 | methods::class_get_fields = LI_FIND_DEF(il2cpp_class_get_fields); 104 | 105 | using il2cpp_field_get_offset = uintptr_t(*)(uintptr_t); 106 | 107 | methods::field_get_offset = LI_FIND_DEF(il2cpp_field_get_offset); 108 | 109 | using il2cpp_object_new = uintptr_t(*)(uintptr_t); 110 | 111 | methods::object_new = LI_FIND_DEF(il2cpp_object_new); 112 | 113 | using il2cpp_runtime_class_init = uintptr_t(*)(uintptr_t); 114 | 115 | methods::runtime_class_init = LI_FIND_DEF(il2cpp_runtime_class_init); 116 | } 117 | 118 | uintptr_t init_class(const char* name, const char* name_space = _("")) { 119 | 120 | uintptr_t domain = methods::domain_get(); 121 | 122 | uintptr_t nrofassemblies = 0; 123 | uintptr_t* assemblies; 124 | assemblies = methods::domain_get_assemblies( (void*)domain, &nrofassemblies); 125 | 126 | for (int i = 0; i < nrofassemblies; i++) { 127 | uintptr_t img = methods::assembly_get_image( assemblies[i]); 128 | 129 | uintptr_t kl = methods::class_from_name( img, name_space, name); 130 | if (!kl) continue; 131 | 132 | return kl; 133 | } 134 | return 0; 135 | } 136 | 137 | //selected_argument is the argument to be checked if the name is right 138 | uintptr_t method(const char* kl, const char* name, int argument_number = -1, char* arg_name = _(""), const char* name_space = _(""), int selected_argument = -1) { 139 | uintptr_t iter = 0; 140 | uintptr_t f; 141 | auto klass = init_class(kl, name_space); 142 | 143 | while (f = methods::class_get_methods(klass, &iter)) { 144 | 145 | char* st = *reinterpret_cast(f + 0x10); 146 | 147 | if (m_strcmp(st, (char*)name)) { 148 | if (selected_argument >= 0 && arg_name) { 149 | uintptr_t args = mem::read(f + 0x28); 150 | int method_count = methods::method_get_param_count( f); 151 | if (selected_argument > method_count || (argument_number >= 0 && method_count != argument_number)) continue; 152 | 153 | char* argname; 154 | if (method_count > 0) { 155 | argname = *reinterpret_cast(args + (selected_argument - 1) * 0x18); 156 | } 157 | else 158 | argname = (char*)_("-"); 159 | 160 | if (!argname || !m_strcmp(argname, arg_name)) continue; 161 | } 162 | 163 | return f; 164 | } 165 | } 166 | return 0; 167 | } 168 | 169 | uintptr_t hook( void* our_func, const char* function_to_hook,const char* class_to_hook, const char* name_space = _(""), int argument_number = -1, char* argument_name = _("")) { 170 | auto il2cpp_method = method(class_to_hook, function_to_hook, argument_number, argument_name, name_space); 171 | 172 | *reinterpret_cast(il2cpp_method) = our_func; 173 | return il2cpp_method; 174 | } 175 | 176 | uintptr_t field(uintptr_t klass, char* field_name, bool get_offset = true) { 177 | uintptr_t out = 0; 178 | uintptr_t il2cpp_field; 179 | 180 | while (il2cpp_field = methods::class_get_fields( klass, &out)) { 181 | 182 | char* name = (char*)*reinterpret_cast(il2cpp_field); 183 | if (!name) 184 | break; 185 | 186 | if (!m_strcmp(name, field_name)) { 187 | continue; 188 | } 189 | if (!get_offset) 190 | return il2cpp_field; 191 | 192 | uintptr_t offset = methods::field_get_offset( il2cpp_field); 193 | return offset; 194 | } 195 | return 0; 196 | } 197 | 198 | uintptr_t value(const char* kl, char* name, bool get_offset = true) { 199 | 200 | auto klass = init_class(kl); 201 | 202 | if (get_offset) { 203 | auto field_offset = field(klass, name); 204 | return field_offset; 205 | } 206 | else 207 | { 208 | auto _field = field(klass, name, false); 209 | 210 | uintptr_t ret; 211 | methods::field_static_get_value(_field, &ret); 212 | return ret; 213 | } 214 | return 0; 215 | } 216 | } 217 | 218 | uintptr_t mem::hook_virtual_function(const char* classname, const char* function_to_hook, void* our_func, const char* name_space = _("")) { 219 | uintptr_t search = *reinterpret_cast(il2cpp::method(classname, function_to_hook, -1, _(""), name_space)); 220 | uintptr_t table = il2cpp::init_class(classname, name_space); 221 | 222 | if (search == (uintptr_t)our_func) 223 | return (uintptr_t)our_func; 224 | 225 | for (uintptr_t i = table; i <= table + 0x1500; i += 0x1) { 226 | uintptr_t addr = *reinterpret_cast(i); 227 | if (addr == search) { 228 | *reinterpret_cast(i) = (uintptr_t)our_func; 229 | return addr; 230 | } 231 | } 232 | } -------------------------------------------------------------------------------- /utils/xorstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 - 2020 Justas Masiulis 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef JM_XORSTR_HPP 18 | #define JM_XORSTR_HPP 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #ifdef _DEBUG 26 | #define LOG(...) printf("\n" __VA_ARGS__) 27 | #else 28 | #define LOG(...) 29 | #endif 30 | 31 | #define xorstr(str) \ 32 | ::jm::make_xorstr( \ 33 | []() { return str; }, \ 34 | std::make_index_sequence{}, \ 35 | std::make_index_sequence<::jm::detail::_buffer_size()>{}) 36 | #define _(str) xorstr(str).crypt_get() 37 | 38 | #ifdef _MSC_VER 39 | #define XORSTR_FORCEINLINE __forceinline 40 | #else 41 | #define XORSTR_FORCEINLINE __attribute__((always_inline)) inline 42 | #endif 43 | 44 | namespace jm { 45 | 46 | namespace detail { 47 | 48 | template 49 | struct unsigned_; 50 | 51 | template<> 52 | struct unsigned_<1> { 53 | using type = std::uint8_t; 54 | }; 55 | template<> 56 | struct unsigned_<2> { 57 | using type = std::uint16_t; 58 | }; 59 | template<> 60 | struct unsigned_<4> { 61 | using type = std::uint32_t; 62 | }; 63 | 64 | template 65 | struct pack_value_type { 66 | using type = decltype(C); 67 | }; 68 | 69 | template 70 | XORSTR_FORCEINLINE constexpr std::size_t _buffer_size() 71 | { 72 | return ((Size / 16) + (Size % 16 != 0)) * 2; 73 | } 74 | 75 | template 76 | struct tstring_ { 77 | using value_type = typename pack_value_type::type; 78 | constexpr static std::size_t size = sizeof...(Cs); 79 | constexpr static value_type str[size] = { Cs... }; 80 | 81 | constexpr static std::size_t buffer_size = _buffer_size(); 82 | constexpr static std::size_t buffer_align = 83 | #ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS 84 | ((sizeof(str) > 16) ? 32 : 16); 85 | #else 86 | 16; 87 | #endif 88 | }; 89 | 90 | template 91 | struct _ki { 92 | constexpr static std::size_t idx = I; 93 | constexpr static std::uint64_t key = K; 94 | }; 95 | 96 | template 97 | XORSTR_FORCEINLINE constexpr std::uint32_t key4() noexcept 98 | { 99 | std::uint32_t value = Seed; 100 | for (char c : __TIME__) 101 | value = static_cast((value ^ c) * 16777619ull); 102 | return value; 103 | } 104 | 105 | template 106 | XORSTR_FORCEINLINE constexpr std::uint64_t key8() 107 | { 108 | constexpr auto first_part = key4<2166136261 + S>(); 109 | constexpr auto second_part = key4(); 110 | return (static_cast(first_part) << 32) | second_part; 111 | } 112 | 113 | // loads up to 8 characters of string into uint64 and xors it with the key 114 | template 115 | XORSTR_FORCEINLINE constexpr std::uint64_t 116 | load_xored_str8(std::uint64_t key, std::size_t idx) noexcept 117 | { 118 | using cast_type = typename unsigned_::type; 119 | constexpr auto value_size = sizeof(typename T::value_type); 120 | constexpr auto idx_offset = 8 / value_size; 121 | 122 | std::uint64_t value = key; 123 | for (std::size_t i = 0; i < idx_offset && i + idx * idx_offset < T::size; ++i) 124 | value ^= 125 | (std::uint64_t{ static_cast(T::str[i + idx * idx_offset]) } 126 | << ((i % idx_offset) * 8 * value_size)); 127 | 128 | return value; 129 | } 130 | 131 | // forces compiler to use registers instead of stuffing constants in rdata 132 | XORSTR_FORCEINLINE std::uint64_t load_from_reg(std::uint64_t value) noexcept 133 | { 134 | #if defined(__clang__) || defined(__GNUC__) 135 | asm("" : "=r"(value) : "0"(value) : ); 136 | #endif 137 | return value; 138 | } 139 | 140 | XORSTR_FORCEINLINE void xor128(std::uint64_t* value, 141 | const std::uint64_t* key) noexcept 142 | { 143 | _mm_store_si128( 144 | reinterpret_cast<__m128i*>(value), 145 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(value)), 146 | _mm_load_si128(reinterpret_cast(key)))); 147 | } 148 | 149 | XORSTR_FORCEINLINE void xor256(std::uint64_t* value, 150 | const std::uint64_t* key) noexcept 151 | { 152 | _mm256_store_si256( 153 | reinterpret_cast<__m256i*>(value), 154 | _mm256_xor_si256( 155 | _mm256_load_si256(reinterpret_cast(value)), 156 | _mm256_load_si256(reinterpret_cast(key)))); 157 | } 158 | 159 | template 160 | struct uint64_v { 161 | constexpr static std::uint64_t value = V; 162 | }; 163 | 164 | } // namespace detail 165 | 166 | template 167 | class xor_string { 168 | alignas(T::buffer_align) std::uint64_t _storage[T::buffer_size]; 169 | 170 | template 171 | XORSTR_FORCEINLINE void _crypt_256(const std::uint64_t* keys, 172 | std::index_sequence) noexcept 173 | { 174 | (detail::xor256(_storage + Idxs * 4, keys + Idxs * 4), ...); 175 | } 176 | 177 | template 178 | XORSTR_FORCEINLINE void _crypt_128(const std::uint64_t* keys, 179 | std::index_sequence) noexcept 180 | { 181 | (detail::xor128(_storage + Idxs * 2, keys + Idxs * 2), ...); 182 | } 183 | 184 | public: 185 | using value_type = typename T::value_type; 186 | using size_type = std::size_t; 187 | using pointer = value_type*; 188 | using const_pointer = const value_type*; 189 | 190 | XORSTR_FORCEINLINE xor_string() noexcept 191 | : _storage{ detail::load_from_reg(detail::uint64_v( 192 | Keys::key, Keys::idx)>::value)... } 193 | {} 194 | 195 | XORSTR_FORCEINLINE constexpr size_type size() const noexcept 196 | { 197 | return T::size - 1; 198 | } 199 | 200 | XORSTR_FORCEINLINE void crypt() noexcept 201 | { 202 | #if defined(__clang__) 203 | alignas(T::buffer_align) 204 | std::uint64_t arr[sizeof...(Keys)]{ detail::load_from_reg(Keys::key)... }; 205 | std::uint64_t* keys = 206 | (std::uint64_t*)detail::load_from_reg((std::uint64_t)arr); 207 | #else 208 | alignas(T::buffer_align) std::uint64_t keys[sizeof...(Keys)]{ 209 | detail::load_from_reg(Keys::key)... 210 | }; 211 | #endif 212 | 213 | #ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS 214 | _crypt_256(keys, std::make_index_sequence{}); 215 | if constexpr (T::buffer_size % 4 != 0) 216 | _crypt_128(keys, std::index_sequence{}); 217 | #else 218 | _crypt_128(keys, std::make_index_sequence{}); 219 | #endif 220 | } 221 | 222 | XORSTR_FORCEINLINE const_pointer get() const noexcept 223 | { 224 | return reinterpret_cast(_storage); 225 | } 226 | 227 | XORSTR_FORCEINLINE pointer get() noexcept 228 | { 229 | return reinterpret_cast(_storage); 230 | } 231 | 232 | XORSTR_FORCEINLINE pointer crypt_get() noexcept 233 | { 234 | crypt(); 235 | return (pointer)(_storage); 236 | } 237 | }; 238 | 239 | template 240 | XORSTR_FORCEINLINE constexpr auto 241 | make_xorstr(Tstr str_lambda, 242 | std::index_sequence, 243 | std::index_sequence) noexcept 244 | { 245 | return xor_string, 246 | detail::_ki()>...>{}; 247 | } 248 | 249 | } // namespace jm 250 | 251 | #endif // include guard 252 | -------------------------------------------------------------------------------- /Rust-Internal-Recode.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {14cee1a1-5c1a-4ecc-91dc-618666acbda0} 25 | RustInternalRecode 26 | 10.0 27 | amogus 28 | 29 | 30 | 31 | DynamicLibrary 32 | true 33 | v142 34 | Unicode 35 | 36 | 37 | DynamicLibrary 38 | false 39 | v142 40 | true 41 | Unicode 42 | 43 | 44 | DynamicLibrary 45 | true 46 | v142 47 | Unicode 48 | false 49 | 50 | 51 | DynamicLibrary 52 | false 53 | v142 54 | false 55 | Unicode 56 | false 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | true 79 | 80 | 81 | false 82 | 83 | 84 | true 85 | 86 | 87 | true 88 | false 89 | C:\Users\mm\Desktop\Exceptis Socket Auth\client\include;$(IncludePath) 90 | 91 | 92 | 93 | Level3 94 | true 95 | WIN32;_DEBUG;RUSTINTERNALRECODE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 96 | true 97 | Use 98 | pch.h 99 | 100 | 101 | Windows 102 | true 103 | false 104 | 105 | 106 | 107 | 108 | Level3 109 | true 110 | true 111 | true 112 | WIN32;NDEBUG;RUSTINTERNALRECODE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 113 | true 114 | Use 115 | pch.h 116 | 117 | 118 | Windows 119 | true 120 | true 121 | true 122 | false 123 | 124 | 125 | 126 | 127 | Level3 128 | false 129 | _DEBUG;RUSTINTERNALRECODE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 130 | true 131 | NotUsing 132 | pch.h 133 | stdcpp17 134 | false 135 | Default 136 | MultiThreadedDebug 137 | false 138 | 139 | 140 | Windows 141 | DebugFull 142 | false 143 | 144 | 145 | false 146 | 147 | 148 | 149 | 150 | Level3 151 | false 152 | false 153 | false 154 | ;NDEBUG;RUSTINTERNALRECODE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 155 | true 156 | NotUsing 157 | pch.h 158 | stdcpp17 159 | false 160 | true 161 | Disabled 162 | false 163 | false 164 | Cdecl 165 | 166 | 167 | Windows 168 | 169 | 170 | 171 | 172 | false 173 | false 174 | true 175 | false 176 | dxguid.lib;%(AdditionalDependencies) 177 | 178 | 179 | 180 | 181 | 182 | 183 | DllMain 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /rust/rust.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../utils/vector.hpp" 3 | #include "../memory/il2cpp.hpp" 4 | 5 | #define STR_MERGE_IMPL(a, b) a##b 6 | #define STR_MERGE(a, b) STR_MERGE_IMPL(a, b) 7 | #define MAKE_PAD(size) STR_MERGE(_pad, __COUNTER__)[size] 8 | #define DEFINE_MEMBER_N(type, name, offset) struct {unsigned char MAKE_PAD(offset); type name;} 9 | #define min(a,b) (((a) < (b)) ? (a) : (b)) 10 | 11 | namespace rust { 12 | template 13 | class list { 14 | public: 15 | T get(uint32_t idx) 16 | { 17 | const auto internal_list = reinterpret_cast(this + 0x20); 18 | return *reinterpret_cast(internal_list + idx * sizeof(T)); 19 | } 20 | 21 | T get_value(uint32_t idx) 22 | { 23 | const auto list = *reinterpret_cast((uintptr_t)this + 0x10); 24 | const auto internal_list = list + 0x20; 25 | return *reinterpret_cast(internal_list + idx * sizeof(T)); 26 | } 27 | 28 | T operator[](uint32_t idx) { return get(idx); } 29 | 30 | const uint32_t get_size() { return *reinterpret_cast((uintptr_t)this + 0x18); } 31 | 32 | template 33 | void for_each(const F callback) 34 | { 35 | for (auto i = 0; i < get_size(); i++) { 36 | auto object = this->get(i); 37 | if (!object) 38 | continue; 39 | callback(object, i); 40 | } 41 | } 42 | }; 43 | 44 | namespace classes { 45 | enum class layer : uint32_t { 46 | Default = 0, 47 | TransparentFX = 1, 48 | Ignore_Raycast = 2, 49 | Reserved1 = 3, 50 | Water = 4, 51 | UI = 5, 52 | Reserved2 = 6, 53 | Reserved3 = 7, 54 | Deployed = 8, 55 | Ragdoll = 9, 56 | Invisible = 10, 57 | AI = 11, 58 | PlayerMovement = 12, 59 | Vehicle_Detailed = 13, 60 | Game_Trace = 14, 61 | Vehicle_World = 15, 62 | World = 16, 63 | Player_Server = 17, 64 | Trigger = 18, 65 | Player_Model_Rendering = 19, 66 | Physics_Projectile = 20, 67 | Construction = 21, 68 | Construction_Socket = 22, 69 | Terrain = 23, 70 | Transparent = 24, 71 | Clutter = 25, 72 | Debris = 26, 73 | Vehicle_Large = 27, 74 | Prevent_Movement = 28, 75 | Prevent_Building = 29, 76 | Tree = 30, 77 | Unused2 = 31 78 | }; 79 | 80 | enum objects 81 | { 82 | MAINCAMERA = 5, 83 | PLAYER = 6, 84 | TERRAIN = 20001, 85 | CORPSE = 20009, //Animals & Players 86 | MISC = 20006, //Trash cans, Sleeping Bags, Storage Box, etc 87 | ANIMAL = 20008, 88 | SKYDOME = 20012, 89 | RIVERMESH = 20014, 90 | MONUMENT = 20015 //Airport, Powerplant, etc 91 | }; 92 | 93 | enum class HitTestType 94 | { 95 | Generic = 0, 96 | ProjectileEffect = 1, 97 | Projectile = 2, 98 | MeleeAttack = 3, 99 | Use = 4, 100 | }; 101 | 102 | class Attack { 103 | public: 104 | union { 105 | DEFINE_MEMBER_N(vector3, pointStart, 0x14); 106 | DEFINE_MEMBER_N(vector3, pointEnd, 0x18); 107 | DEFINE_MEMBER_N(unsigned int, hitID, 0x2C); 108 | DEFINE_MEMBER_N(unsigned int, hitBone, 0x30); 109 | DEFINE_MEMBER_N(vector3, hitNormalLocal, 0x34); 110 | DEFINE_MEMBER_N(vector3, hitPositionLocal, 0x40); 111 | DEFINE_MEMBER_N(vector3, hitNormalWorld, 0x4C); 112 | DEFINE_MEMBER_N(vector3, hitPositionWorld, 0x48); 113 | DEFINE_MEMBER_N(unsigned int, hitPartID, 0x64); 114 | DEFINE_MEMBER_N(unsigned int, hitMaterialID, 0x68); 115 | DEFINE_MEMBER_N(unsigned int, hitItem, 0x6C); 116 | }; 117 | }; 118 | 119 | class game_object { 120 | public: 121 | template 122 | T get_class() 123 | { 124 | return *reinterpret_cast((uintptr_t)this + 0x30); 125 | } 126 | 127 | template 128 | T get_class(uint32_t second_offset) 129 | { 130 | const auto object = *reinterpret_cast((uintptr_t)this + 0x30); 131 | if (!object) 132 | return nullptr; 133 | 134 | return *reinterpret_cast(object + second_offset); 135 | } 136 | 137 | char* get_prefab_name() { return *reinterpret_cast((uintptr_t)this + 0x60); } 138 | 139 | uint32_t get_tag() { return *reinterpret_cast((uintptr_t)this + 0x54); } 140 | 141 | layer get_layer() { return *reinterpret_cast(this + 0x50); } 142 | }; 143 | 144 | class PlayerAttack { 145 | public: 146 | union { 147 | DEFINE_MEMBER_N(Attack*, attack, 0x18); 148 | }; 149 | }; 150 | 151 | class PlayerProjectileAttack { 152 | public: 153 | union { 154 | DEFINE_MEMBER_N(PlayerAttack*, playerAttack, 0x18); 155 | DEFINE_MEMBER_N(vector3, hitVelocity, 0x20); 156 | DEFINE_MEMBER_N(float, hitDistance, 0x2C); 157 | DEFINE_MEMBER_N(float, travelTime, 0x30); 158 | }; 159 | }; 160 | enum class Layers 161 | { 162 | Terrain = 8388608, 163 | World = 65536, 164 | Ragdolls = 512, 165 | Construction = 2097152, 166 | ConstructionSocket = 4194304, 167 | Craters = 1, 168 | GameTrace = 16384, 169 | Trigger = 262144, 170 | VehiclesDetailed = 8192, 171 | RainFall = 1101070337, 172 | Deploy = 1235288065, 173 | DefaultDeployVolumeCheck = 537001984, 174 | BuildLineOfSightCheck = 2097152, 175 | ProjectileLineOfSightCheck = 2162688, 176 | ProjectileLineOfSightCheckTerrain = 10551296, 177 | MeleeLineOfSightCheck = 2162688, 178 | EyeLineOfSightCheck = 2162688, 179 | EntityLineOfSightCheck = 1218519041, 180 | PlayerBuildings = 18874624, 181 | PlannerPlacement = 161546496, 182 | Solid = 1218652417, 183 | VisCulling = 10551297, 184 | AltitudeCheck = 1218511105, 185 | HABGroundEffect = 1218511105, 186 | AILineOfSight = 1218519297, 187 | DismountCheck = 1486946561, 188 | AIPlacement = 278986753, 189 | WheelRay = 1235321089, 190 | }; 191 | 192 | enum class Bone_List : int 193 | { 194 | pelvis = 1, 195 | l_hip, 196 | l_knee, 197 | l_foot, 198 | l_toe, 199 | l_ankle_scale, 200 | penis, 201 | GenitalCensor, 202 | GenitalCensor_LOD0, 203 | Inner_LOD0, 204 | Inner_LOD01, 205 | GenitalCensor_LOD1, 206 | GenitalCensor_LOD2, 207 | r_hip, r_knee, r_foot, r_toe, r_ankle_scale, spine1, spine1_scale, spine2, spine3, spine4, l_clavicle, l_upperarm, l_forearm, l_hand, l_index1, 208 | l_index2, l_index3, l_little1, l_little2, l_little3, l_middle1, l_middle2, l_middle3, l_prop, l_ring1, l_ring2, l_ring3, l_thumb1, l_thumb2, l_thumb3, 209 | IKtarget_righthand_min, IKtarget_righthand_max, l_ulna, neck, head, jaw, eyeTranform, l_eye, l_Eyelid, r_eye, r_Eyelid, r_clavicle, 210 | r_upperarm, r_forearm, r_hand, r_index1, r_index2, r_index3, r_little1, r_little2, r_little3, r_middle1, r_middle2, r_middle3, r_prop, 211 | r_ring1, r_ring2, r_ring3, r_thumb1, r_thumb2, r_thumb3, IKtarget_lefthand_min, IKtarget_lefthand_max, r_ulna, l_breast, r_breast, BoobCensor, 212 | BreastCensor_LOD0, Inner_LOD02, Inner_LOD03, BreastCensor_LOD1, BreastCensor_LOD2 213 | }; 214 | 215 | class list { 216 | public: 217 | template 218 | T get_value() { 219 | auto list = *reinterpret_cast(this + 0x10); 220 | if (!list) 221 | return 0; 222 | 223 | auto value = *reinterpret_cast(list + 0x28); 224 | if (!value) 225 | return 0; 226 | return value; 227 | } 228 | 229 | int get_size() { 230 | auto value = get_value(); 231 | if (!value) 232 | return 0; 233 | 234 | auto size = mem::read(value + 0x10); 235 | if (!size) 236 | return 0; 237 | } 238 | 239 | template 240 | T get_buffer() { 241 | auto value = get_value(); 242 | 243 | return *reinterpret_cast(value + 0x18); 244 | } 245 | }; 246 | 247 | enum class KeyCode 248 | { 249 | Backspace = 8, 250 | Delete = 127, 251 | Tab = 9, 252 | Clear = 12, 253 | Return = 13, 254 | Pause = 19, 255 | Escape = 27, 256 | Space = 32, 257 | Keypad0 = 256, 258 | Keypad1 = 257, 259 | Keypad2 = 258, 260 | Keypad3 = 259, 261 | Keypad4 = 260, 262 | Keypad5 = 261, 263 | Keypad6 = 262, 264 | Keypad7 = 263, 265 | Keypad8 = 264, 266 | Keypad9 = 265, 267 | KeypadPeriod = 266, 268 | KeypadDivide = 267, 269 | KeypadMultiply = 268, 270 | KeypadMinus = 269, 271 | KeypadPlus = 270, 272 | KeypadEnter = 271, 273 | KeypadEquals = 272, 274 | UpArrow = 273, 275 | DownArrow = 274, 276 | RightArrow = 275, 277 | LeftArrow = 276, 278 | Insert = 277, 279 | Home = 278, 280 | End = 279, 281 | PageUp = 280, 282 | PageDown = 281, 283 | F1 = 282, 284 | F2 = 283, 285 | F3 = 284, 286 | F4 = 285, 287 | F5 = 286, 288 | F6 = 287, 289 | F7 = 288, 290 | F8 = 289, 291 | F9 = 290, 292 | F10 = 291, 293 | F11 = 292, 294 | F12 = 293, 295 | F13 = 294, 296 | F14 = 295, 297 | F15 = 296, 298 | Alpha0 = 48, 299 | Alpha1 = 49, 300 | Alpha2 = 50, 301 | Alpha3 = 51, 302 | Alpha4 = 52, 303 | Alpha5 = 53, 304 | Alpha6 = 54, 305 | Alpha7 = 55, 306 | Alpha8 = 56, 307 | Alpha9 = 57, 308 | Exclaim = 33, 309 | DoubleQuote = 34, 310 | Hash = 35, 311 | Dollar = 36, 312 | Percent = 37, 313 | Ampersand = 38, 314 | Quote = 39, 315 | LeftParen = 40, 316 | RightParen = 41, 317 | Asterisk = 42, 318 | Plus = 43, 319 | Comma = 44, 320 | Minus = 45, 321 | Period = 46, 322 | Slash = 47, 323 | Colon = 58, 324 | Semicolon = 59, 325 | Less = 60, 326 | Equals = 61, 327 | Greater = 62, 328 | Question = 63, 329 | At = 64, 330 | LeftBracket = 91, 331 | Backslash = 92, 332 | RightBracket = 93, 333 | Caret = 94, 334 | Underscore = 95, 335 | BackQuote = 96, 336 | A = 97, 337 | B = 98, 338 | C = 99, 339 | D = 100, 340 | E = 101, 341 | F = 102, 342 | G = 103, 343 | H = 104, 344 | I = 105, 345 | J = 106, 346 | K = 107, 347 | L = 108, 348 | M = 109, 349 | N = 110, 350 | O = 111, 351 | P = 112, 352 | Q = 113, 353 | R = 114, 354 | S = 115, 355 | T = 116, 356 | U = 117, 357 | V = 118, 358 | W = 119, 359 | X = 120, 360 | Y = 121, 361 | Z = 122, 362 | LeftCurlyBracket = 123, 363 | Pipe = 124, 364 | RightCurlyBracket = 125, 365 | Tilde = 126, 366 | Numlock = 300, 367 | CapsLock = 301, 368 | ScrollLock = 302, 369 | RightShift = 303, 370 | LeftShift = 304, 371 | RightControl = 305, 372 | LeftControl = 306, 373 | RightAlt = 307, 374 | LeftAlt = 308, 375 | LeftCommand = 310, 376 | LeftApple = 310, 377 | LeftWindows = 311, 378 | RightCommand = 309, 379 | RightApple = 309, 380 | RightWindows = 312, 381 | AltGr = 313, 382 | Help = 315, 383 | Pr = 316, 384 | SysReq = 317, 385 | Break = 318, 386 | Menu = 319, 387 | Mouse0 = 323, 388 | Mouse1 = 324, 389 | Mouse2 = 325, 390 | Mouse3 = 326, 391 | Mouse4 = 327, 392 | Mouse5 = 328, 393 | Mouse6 = 329 394 | }; 395 | 396 | enum class CursorLockMode 397 | { 398 | None = 0, 399 | Locked = 1, 400 | Confined = 2 401 | }; 402 | 403 | enum class PlayerFlags 404 | { 405 | Unused1 = 1, 406 | Unused2 = 2, 407 | IsAdmin = 4, 408 | ReceivingSnapshot = 8, 409 | Sleeping = 16, 410 | Spectating = 32, 411 | Wounded = 64, 412 | IsDeveloper = 128, 413 | Connected = 256, 414 | ThirdPersonViewmode = 1024, 415 | EyesViewmode = 2048, 416 | ChatMute = 4096, 417 | NoSprint = 8192, 418 | Aiming = 16384, 419 | DisplaySash = 32768, 420 | Relaxed = 65536, 421 | SafeZone = 131072, 422 | ServerFall = 262144, 423 | Workbench1 = 1048576, 424 | Workbench2 = 2097152, 425 | Workbench3 = 4194304, 426 | }; 427 | 428 | enum class ModelState_Flag 429 | { 430 | Ducked = 1, 431 | Jumped = 2, 432 | OnGround = 4, 433 | Sleeping = 8, 434 | Sprinting = 16, 435 | OnLadder = 32, 436 | Flying = 64, 437 | Aiming = 128, 438 | Prone = 256, 439 | Mounted = 512, 440 | Relaxed = 1024, 441 | Crawling = 4096, 442 | }; 443 | 444 | class string { 445 | public: 446 | char zpad[0x10]; 447 | 448 | int size; 449 | wchar_t str[128 + 1]; 450 | string(const wchar_t* st) { 451 | size = min(m_wcslen((wchar_t*)st), 128); 452 | for (int i = 0; i < size; i++) { 453 | str[i] = st[i]; 454 | } 455 | str[size] = 0; 456 | } 457 | }; 458 | 459 | class Rect { 460 | public: 461 | float x; // 0x10 462 | float y; // 0x14 463 | float wid; // 0x18 464 | float hei; // 0x1C 465 | Rect(float x, float y/*top left*/, float x_rightsize, float y_downsize) { 466 | this->x = x; 467 | this->y = y; 468 | wid = x_rightsize; 469 | hei = y_downsize; 470 | } 471 | Rect() { 472 | this->x = 0; 473 | this->y = 0; 474 | wid = 0; 475 | hei = 0; 476 | } 477 | bool Contains(vector2 point) 478 | { 479 | return point.x >= x && point.x < (x + wid) && point.y >= y && point.y < (y + hei); 480 | } 481 | }; 482 | 483 | enum class EventType : int { 484 | MouseDown = 0, 485 | MouseUp = 1, 486 | MouseDrag = 3, 487 | KeyDown = 4, 488 | KeyUp = 5, 489 | Repaint = 7 490 | }; 491 | 492 | class HitTest { 493 | public: 494 | union { 495 | // Type Name Offset 496 | DEFINE_MEMBER_N(uintptr_t, type, 0x10); 497 | DEFINE_MEMBER_N(vector3, AttackRay, 0x14); 498 | DEFINE_MEMBER_N(float, Radius, 0x2C); 499 | DEFINE_MEMBER_N(float, Forgiveness, 0x30); 500 | DEFINE_MEMBER_N(float, MaxDistance, 0x34); 501 | DEFINE_MEMBER_N(uintptr_t, RayHit, 0x38); 502 | DEFINE_MEMBER_N(bool, MultiHit, 0x64); 503 | DEFINE_MEMBER_N(bool, BestHit, 0x65); 504 | DEFINE_MEMBER_N(bool, DidHit, 0x66); 505 | DEFINE_MEMBER_N(uintptr_t, damageProperties, 0x68); 506 | DEFINE_MEMBER_N(uintptr_t, gameObject, 0x70); 507 | DEFINE_MEMBER_N(uintptr_t, collider, 0x78); 508 | DEFINE_MEMBER_N(uintptr_t, ignoreEntity, 0x80); 509 | DEFINE_MEMBER_N(uintptr_t, HitEntity, 0x88); 510 | DEFINE_MEMBER_N(vector3, HitPoint, 0x90); 511 | DEFINE_MEMBER_N(vector3, HitNormal, 0x9C); 512 | DEFINE_MEMBER_N(vector3, HitNormal, 0x9C); 513 | DEFINE_MEMBER_N(float, HitDistance, 0xA8); 514 | DEFINE_MEMBER_N(uintptr_t, HitTransform, 0xB0); 515 | DEFINE_MEMBER_N(unsigned int, HitPart, 0xB8); 516 | DEFINE_MEMBER_N(string, HitMaterial, 0xC0); 517 | }; 518 | }; 519 | } 520 | 521 | } -------------------------------------------------------------------------------- /rust/features/player_esp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "../../memory/il2cpp.hpp" 6 | #include "../../settings.hpp" 7 | 8 | #include "../classes.hpp" 9 | #include "../rust.hpp" 10 | 11 | namespace esp { 12 | uintptr_t client_entities; 13 | base_player* local_player; 14 | VMatrix matrix; 15 | 16 | struct bounds_t { 17 | float left, right, top, bottom; 18 | }; 19 | 20 | struct rust_str 21 | { 22 | char zpad[ 128 ]; 23 | }; 24 | 25 | bool out_w2s(const vector3& position, vector2& screen_pos) { 26 | if (!matrix.m) { 27 | return false; 28 | } 29 | 30 | vector2 out; 31 | const auto temp = matrix.transpose( ); 32 | 33 | auto translation_vector = vector3{temp[ 3 ][ 0 ], temp[ 3 ][ 1 ], temp[ 3 ][ 2 ]}; 34 | auto up = vector3{temp[ 1 ][ 0 ], temp[ 1 ][ 1 ], temp[ 1 ][ 2 ]}; 35 | auto right = vector3{temp[ 0 ][ 0 ], temp[ 0 ][ 1 ], temp[ 0 ][ 2 ]}; 36 | 37 | float w = translation_vector.dot(position) + temp[ 3 ][ 3 ]; 38 | 39 | if (w < 0.098f) { 40 | return false; 41 | } 42 | 43 | float x = up.dot(position) + temp._24; 44 | float y = right.dot(position) + temp._14; 45 | 46 | out.x = (static_cast(unity::get_width( )) / 2) * (1 + y / w); 47 | out.y = (static_cast(unity::get_height( )) / 2) * (1 - x / w); 48 | 49 | screen_pos = out; 50 | 51 | return true; 52 | } 53 | 54 | //struct str 55 | //{ 56 | // char buffer[128]; 57 | //}; 58 | 59 | void draw_heli(float x, float y, float w, float h); 60 | 61 | void draw_tool_cupboard(vector2 w2s_position, uintptr_t label, vector4 color, rust::list* authorizedPlayers_list); 62 | 63 | void draw_hackable_crate(vector2 w2s_position, uintptr_t crate, vector4 color); 64 | 65 | void draw_item(vector2 w2s_position, uintptr_t label, vector4 color, wchar_t* name = _(L"")); 66 | 67 | void draw_player(base_player* player, bool is_npc); 68 | 69 | void draw_target_hotbar(aim_target target); 70 | 71 | void draw_name(vector3 position, wchar_t* name); 72 | 73 | void draw_middle(aim_target target); 74 | 75 | void draw_weapon_icon(weapon* item, vector2 w2s_position); 76 | 77 | uintptr_t shader; 78 | 79 | void iterate_players(bool draw = true) { 80 | aim_target best_target = aim_target( ); 81 | 82 | auto get_client_entities = [ & ]( ) { 83 | client_entities = il2cpp::value(_("BaseNetworkable"), _("clientEntities"), false); 84 | }; 85 | if (!client_entities) 86 | get_client_entities( ); 87 | 88 | rust::classes::list* entity_list = (rust::classes::list*)client_entities; 89 | 90 | auto list_value = entity_list->get_value( ); 91 | if (!list_value) { 92 | get_client_entities( ); 93 | return; 94 | } 95 | 96 | auto size = entity_list->get_size( ); 97 | if (!size) { 98 | get_client_entities( ); 99 | return; 100 | } 101 | 102 | auto buffer = entity_list->get_buffer( ); 103 | if (!buffer) { 104 | get_client_entities( ); 105 | return; 106 | } 107 | 108 | for (int i = 0; i <= size; i++) { 109 | auto current_object = *reinterpret_cast(buffer + 0x20 + (i * 0x8)); 110 | if (!current_object || current_object <= 100000) 111 | continue; 112 | 113 | auto base_object = *reinterpret_cast(current_object + 0x10); 114 | if (!base_object || base_object <= 100000) 115 | continue; 116 | 117 | auto object = *reinterpret_cast(base_object + 0x30); 118 | if (!object || object <= 100000) 119 | continue; 120 | 121 | WORD tag = *reinterpret_cast(object + 0x54); 122 | 123 | auto do_melee_attack = [ & ](base_projectile* baseprojectile) 124 | { 125 | auto ent = *reinterpret_cast(base_object + 0x28); 126 | 127 | auto ent_class = *reinterpret_cast(ent); 128 | auto entity_class_name = (char*)*reinterpret_cast(ent_class + 0x10); 129 | 130 | auto attack = [ & ](bool is_tree) { 131 | auto _class = *reinterpret_cast(base_object + 0x30); 132 | 133 | auto game_object = *reinterpret_cast(_class + 0x30); 134 | 135 | auto transform = *reinterpret_cast(game_object + 0x8); 136 | auto visual_state = *reinterpret_cast(transform + 0x38); 137 | 138 | 139 | auto world_position = *reinterpret_cast(visual_state + 0x90); 140 | 141 | auto local = ClosestPoint(esp::local_player, world_position); 142 | if (local.get_3d_dist(world_position) >= 5) 143 | return; 144 | 145 | auto gathering = baseprojectile->Gathering( ); 146 | 147 | if (is_tree) { 148 | if (!(gathering->tree( )->gatherDamage( ) > 1)) { 149 | return; 150 | } 151 | } 152 | else { 153 | if (!(gathering->ore( )->gatherDamage( ) > 1)) { 154 | return; 155 | } 156 | } 157 | 158 | aim_target target; 159 | 160 | target.pos = world_position; 161 | target.player = (base_player*)ent; 162 | target.visible = true; 163 | attack_melee(target, baseprojectile); 164 | }; 165 | 166 | auto name = *(int*)(entity_class_name); 167 | 168 | if (name == 'eerT') { 169 | attack(true); 170 | } 171 | else if (name == 'HerO') { 172 | attack(false); 173 | } 174 | }; 175 | 176 | auto ent = *reinterpret_cast(base_object + 0x28); 177 | if (!ent) 178 | continue; 179 | 180 | auto ent_class = *reinterpret_cast(ent); 181 | if (!ent_class) 182 | continue; 183 | 184 | auto entity_class_name = (char*)*reinterpret_cast(ent_class + 0x10); 185 | if (!entity_class_name) 186 | continue; 187 | 188 | vector4 esp_color(1, 0, 1, 1); 189 | uintptr_t esp_name; 190 | 191 | auto game_object = *reinterpret_cast(object + 0x30); 192 | if (!game_object) 193 | continue; 194 | 195 | auto transform = *reinterpret_cast(game_object + 0x8); 196 | if (!transform) 197 | continue; 198 | 199 | auto visual_state = *reinterpret_cast(transform + 0x38); 200 | if (!visual_state) 201 | continue; 202 | 203 | auto world_position = *reinterpret_cast(visual_state + 0x90); 204 | if (world_position.is_empty( )) 205 | continue; 206 | 207 | uintptr_t object_name_ptr = mem::read(object + 0x60); 208 | if (!object_name_ptr) 209 | continue; 210 | 211 | auto object_name = *reinterpret_cast(object_name_ptr); 212 | if (!object_name.zpad) 213 | continue; 214 | 215 | if (*(int*)(entity_class_name) == 'kcaH' && *(int*)(entity_class_name + 14) == 'tarC') { 216 | auto flag = *reinterpret_cast(ent + 0x128); 217 | if (flag != 128 && flag != 256) 218 | continue; 219 | 220 | vector2 w2s_position = {}; 221 | if (out_w2s(world_position, w2s_position)) 222 | esp::draw_hackable_crate(w2s_position, ent, {0.45, 0.72, 1, 0.8}); 223 | } 224 | 225 | if (settings::visuals::misc_esp) { 226 | if (*(int*)(entity_class_name) == 'porD') { 227 | if (!settings::visuals::dropped_items) 228 | continue; 229 | 230 | if (*(int*)(entity_class_name + 40) == 'kcab') 231 | continue; 232 | 233 | if (*(int*)(object_name.zpad) == 'orra') 234 | continue; 235 | 236 | if (*(int*)(object_name.zpad + 12) == 'ian.') 237 | continue; 238 | 239 | auto Item = *reinterpret_cast(ent + 0x158); 240 | if (!Item) 241 | continue; 242 | 243 | auto item = reinterpret_cast(Item); 244 | 245 | auto item_name = item->get_weapon_name( ); 246 | 247 | esp_color = vector4(196, 124, 0, 255); 248 | 249 | vector2 w2s_position = {}; 250 | if (out_w2s(world_position, w2s_position)) 251 | draw_weapon_icon(item, w2s_position); 252 | //esp::draw_item(w2s_position, 0, esp_color, item_name); 253 | 254 | continue; 255 | } 256 | 257 | if (settings::visuals::tc_esp && *(int*)(entity_class_name) == 'liuB' && *(int*)(entity_class_name + 8) == 'virP') { 258 | auto authorizedPlayers_wrapper = *reinterpret_cast(ent + 0x570); 259 | if (!authorizedPlayers_wrapper) 260 | continue; 261 | const auto authorizedPlayers_list = *reinterpret_cast**>(authorizedPlayers_wrapper + 0x10); 262 | if (!authorizedPlayers_list) 263 | continue; 264 | 265 | vector2 w2s_position = {}; 266 | if (out_w2s(world_position, w2s_position)) 267 | esp::draw_tool_cupboard(w2s_position, il2cpp::methods::new_string(_("Tool Cupboard")), vector4(255, 0, 0, 255), authorizedPlayers_list); 268 | } 269 | 270 | 271 | if (*(int*)(entity_class_name + 4) == 'ileH' && settings::visuals::heli_esp && settings::visuals::vehicle) { 272 | auto base_heli = reinterpret_cast(ent); 273 | 274 | vector2 rearrotor, beam, mainrotor; 275 | out_w2s(base_heli->get_bone_transform(22)->get_bone_position( ), rearrotor); 276 | out_w2s(base_heli->get_bone_transform(19)->get_bone_position( ), mainrotor); 277 | out_w2s(base_heli->get_bone_transform(56)->get_bone_position( ), beam); 278 | esp_name = il2cpp::methods::new_string(("Heli")); 279 | esp_color = vector4(232, 232, 232, 255); 280 | 281 | uintptr_t transform = mem::read(base_heli->get_model( ) + 0x48); //boneTransforms; // 0x48 282 | 283 | const vector2 diff = {(beam.x + rearrotor.x) / 2, (beam.y + rearrotor.y) / 2}; 284 | 285 | const float h = max(beam.y, rearrotor.y) - min(beam.y, rearrotor.y); 286 | const float y = diff.y; 287 | const float w = (max(beam.x, rearrotor.x) - min(beam.x, rearrotor.x)); 288 | float x = diff.x - h / 4; 289 | 290 | vector2 w2s_position = {}; 291 | if (out_w2s(world_position, w2s_position)) 292 | esp::draw_item(w2s_position, esp_name, esp_color); 293 | 294 | draw_heli(x, y, w, h); 295 | } 296 | 297 | if (settings::visuals::stash && *(int*)(object_name.zpad + 46) == '_hsa') { 298 | esp_name = il2cpp::methods::new_string(_("Stash")); 299 | } 300 | else if (settings::visuals::stone_ore && settings::visuals::materials && (*(int*)(object_name.zpad + 52) == 'nots' || *(int*)(object_name.zpad + 47) == 'nots')) { 301 | esp_name = il2cpp::methods::new_string(_("Stone Ore")); 302 | esp_color = vector4(232, 232, 232, 255); 303 | } 304 | else if (settings::visuals::sulfur_ore && settings::visuals::materials && (*(int*)(object_name.zpad + 52) == 'flus' || *(int*)(object_name.zpad + 47) == 'flus')) { 305 | esp_name = il2cpp::methods::new_string((_("Sulfur Ore"))); 306 | esp_color = vector4(203, 207, 0, 255); 307 | } 308 | else if (settings::visuals::metal_ore && settings::visuals::materials && (*(int*)(object_name.zpad + 52) == 'atem' || *(int*)(object_name.zpad + 47) == 'atem')) { 309 | esp_name = il2cpp::methods::new_string(_("Metal Ore")); 310 | esp_color = vector4(145, 145, 145, 255); 311 | } 312 | else if (settings::visuals::traps && (*(int*)(object_name.zpad + 36) == 'terr' || *(int*)(object_name.zpad + 43) == 'tnug' || *(int*)(object_name.zpad + 38) == 'rtra')) { 313 | if (*(int*)(object_name.zpad + 36) == 'terr') 314 | esp_name = il2cpp::methods::new_string(_("Auto Turret*")); 315 | else if (*(int*)(object_name.zpad + 43) == 'tnug') 316 | esp_name = il2cpp::methods::new_string(_("Shotgun Trap*")); 317 | else if (*(int*)(object_name.zpad + 38) == 'rtra') 318 | esp_name = il2cpp::methods::new_string(_("Bear Trap*")); 319 | 320 | esp_color = vector4(255, 166, 0, 255); 321 | } 322 | else if (settings::visuals::vehicles && settings::visuals::vehicle && *(int*)(entity_class_name + 4) == 'iheV') { 323 | esp_name = il2cpp::methods::new_string(_("Vehicle")); 324 | esp_color = vector4(0, 161, 219, 255); 325 | } 326 | else if (settings::visuals::airdrops && *(int*)(object_name.zpad + 39) == 'pord') { 327 | esp_name = il2cpp::methods::new_string(_("Airdrop")); 328 | esp_color = vector4(0, 161, 219, 255); 329 | } 330 | else if (settings::visuals::cloth && settings::visuals::materials && *(int*)(object_name.zpad + 52) == 'c-pm') { 331 | esp_name = il2cpp::methods::new_string(_("Cloth")); 332 | esp_color = vector4(0, 219, 58, 255); 333 | } 334 | else if (settings::visuals::corpses && *(int*)(object_name.zpad + 29) == 'proc') { 335 | esp_name = il2cpp::methods::new_string(_("Player Corpse")); 336 | esp_color = vector4(230, 230, 230, 255); 337 | } 338 | else if (tag != 6) 339 | continue; 340 | 341 | if (tag != 6) { 342 | if (*(int*)(entity_class_name) == 'satS') { 343 | auto flag = *reinterpret_cast(ent + 0x128); 344 | if (flag != 2048) 345 | continue; 346 | } 347 | 348 | vector2 w2s_position = {}; 349 | if (out_w2s(world_position, w2s_position)) 350 | esp::draw_item(w2s_position, esp_name, esp_color); 351 | 352 | continue; 353 | } 354 | } 355 | else if (tag != 6) 356 | continue; 357 | 358 | esp::matrix = unity::get_view_matrix( ); 359 | 360 | if (tag == 6 && !settings::visuals::player_esp) 361 | continue; 362 | 363 | 364 | auto player = reinterpret_cast(ent); 365 | 366 | auto hit_player = [ & ]( ) { 367 | auto weapon = esp::local_player->get_active_weapon( ); 368 | if (weapon) { 369 | auto baseprojectile = weapon->get_base_projetile( ); 370 | if (baseprojectile) { 371 | auto class_name = baseprojectile->get_class_name( ); 372 | if (*(int*)(class_name + 4) == 'eleM' || *(int*)(class_name + 4) == 'mmah') { 373 | auto world_position = player->get_bone_transform(48)->get_bone_position( ); 374 | auto local = ClosestPoint(esp::local_player, world_position); 375 | auto camera = esp::local_player->get_bone_transform(48)->get_bone_position( ); 376 | 377 | if (camera.get_3d_dist(world_position) >= 4.5f) 378 | return; 379 | 380 | aim_target target = esp::local_player->get_aimbot_target(camera); 381 | 382 | attack_melee(target, baseprojectile, true); 383 | } 384 | } 385 | } 386 | }; 387 | 388 | if (!player->is_alive( )) 389 | continue; 390 | 391 | if (player->is_sleeping( ) && !settings::visuals::sleeper_esp) 392 | continue; 393 | 394 | bool is_npc = false; 395 | 396 | if (get_IsNpc(player->get_player_model( ))) { 397 | is_npc = true; 398 | 399 | if (!settings::visuals::npc_esp) 400 | continue; 401 | } 402 | 403 | if (player->is_local_player( )) 404 | local_player = reinterpret_cast(ent); 405 | else { 406 | if (esp::local_player) { 407 | auto target = aim_target( ); 408 | target.pos = player->get_bone_transform(19)->get_bone_position( ); 409 | 410 | auto distance = esp::local_player->get_bone_transform(48)->get_bone_position( ).get_3d_dist(target.pos); 411 | target.distance = distance; 412 | 413 | auto fov = unity::get_fov(target.pos); 414 | target.fov = fov; 415 | 416 | target.player = player; 417 | 418 | if (target < best_target) 419 | best_target = target; 420 | } 421 | 422 | 423 | if (draw) { 424 | if (settings::visuals::chams) { 425 | static int cases = 0; 426 | static float r = 1.00f, g = 0.00f, b = 1.00f; 427 | switch (cases) { 428 | case 0: { r -= 0.0004f; if (r <= 0) cases += 1; break; } 429 | case 1: { g += 0.0004f; b -= 0.0004f; if (g >= 1) cases += 1; break; } 430 | case 2: { r += 0.0004f; if (r >= 1) cases += 1; break; } 431 | case 3: { b += 0.0004f; g -= 0.0004f; if (b >= 1) cases = 0; break; } 432 | default: { r = 1.00f; g = 0.00f; b = 1.00f; break; } 433 | } 434 | auto _multiMesh = mem::read(player->get_player_model( ) + 0x2B0); //SkinnedMultiMesh _multiMesh; 435 | if (_multiMesh) { 436 | auto render = get_Renderers(_multiMesh); 437 | 438 | for (int i = 0; i < render->get_size( ); i++) { 439 | auto renderer = render->get_value(i); 440 | 441 | //////// CHAMMINGS /////// 442 | 443 | if (renderer) { 444 | auto material = get_material(renderer); 445 | if (material) { 446 | if (!shader) 447 | shader = Find(_(L"Hidden/Internal-Colored")); 448 | unity::set_shader(material, shader); 449 | SetInt(material, _(L"_ZTest"), 8); // through walls 450 | 451 | if (settings::visuals::rainbow_chams) { 452 | SetColor(material, _(L"_Color"), col(r, g, b, 1)); 453 | } else if (get_IsNpc(player->get_player_model()) && player->is_visible(local_player->get_bone_transform((int)rust::classes::Bone_List::head)->get_bone_position(), player->get_bone_transform((int)rust::classes::Bone_List::head)->get_bone_position())) { 454 | SetColor(material, _(L"_Color"), col(0, 0.5, 1, 0.5)); 455 | } else if (get_IsNpc(player->get_player_model())) { 456 | SetColor(material, _(L"_Color"), col(0, 0, 0.6, 0.5)); 457 | } else if (get_IsNpc(player->get_player_model())) { 458 | SetColor(material, _(L"_Color"), col(0, 0, 0.6, 0.5)); 459 | } else if (player->is_teammate(local_player)) { 460 | SetColor(material, _(L"_Color"), col(0, 1, 1, 1)); 461 | } else if (player->is_visible(local_player->get_bone_transform((int)rust::classes::Bone_List::head)->get_bone_position(), player->get_bone_transform((int)rust::classes::Bone_List::head)->get_bone_position())) { 462 | SetColor(material, _(L"_Color"), col(settings::visuals::VisRcolor, settings::visuals::VisGcolor, settings::visuals::VisBcolor, 1)); 463 | } else { 464 | SetColor(material, _(L"_Color"), col(settings::visuals::InvRcolor, settings::visuals::InvGcolor, settings::visuals::InvBcolor, 1)); 465 | } 466 | } 467 | } 468 | } 469 | } 470 | } 471 | 472 | if (draw) { 473 | if (settings::visuals::cancer) { 474 | static int cases = 0; 475 | static float r = 1.00f, g = 0.00f, b = 1.00f; 476 | switch (cases) { 477 | case 0: { r -= 0.0208f; if (r <= 0) cases += 1; break; } 478 | case 1: { g += 0.0208f; b -= 0.0208f; if (g >= 1) cases += 1; break; } 479 | case 2: { r += 0.0208f; if (r >= 1) cases += 1; break; } 480 | case 3: { b += 0.0208f; g -= 0.0208f; if (b >= 1) cases = 0; break; } 481 | default: { r = 1.00f; g = 0.00f; b = 1.00f; break; } 482 | } 483 | auto _multiMesh = mem::read(player->get_player_model() + 0x2B0); 484 | if (_multiMesh) { 485 | auto render = get_Renderers(_multiMesh); 486 | 487 | for (int i = 0; i < render->get_size(); i++) { 488 | auto renderer = render->get_value(i); 489 | 490 | if (renderer) { 491 | auto material = get_material(renderer); 492 | if (material) { 493 | if (!shader) 494 | shader = Find(_(L"Hidden/Internal-Colored")); 495 | SetInt(material, _(L"_ZTest"), 8); // through walls 496 | SetColor(material, _(L"_Color"), col(1, 0, 0, 2)); 497 | 498 | unity::set_shader(material, shader); 499 | 500 | 501 | 502 | } 503 | } 504 | } 505 | } 506 | } 507 | } 508 | 509 | draw_player(player, is_npc); 510 | 511 | if (settings::weapon::silent_melee) 512 | hit_player( ); 513 | } 514 | } 515 | } 516 | esp::draw_target_hotbar(best_target); 517 | esp::draw_middle(best_target); 518 | } 519 | 520 | void draw_teammates( ) { 521 | if (!esp::local_player) 522 | return; 523 | 524 | auto team = mem::read((uintptr_t)local_player + clientTeam); 525 | 526 | auto member = mem::read(team + 0x30); 527 | 528 | auto size = mem::read(member + 0x18); 529 | 530 | auto list = mem::read(member + 0x10); 531 | 532 | for (int i = 0; i < size; i++) { 533 | auto player = mem::read(list + 0x20 + i * 0x8); 534 | 535 | auto online = mem::read(player + 0x38); 536 | 537 | if (!online && !settings::visuals::sleeper_esp) 538 | continue; 539 | 540 | auto id = mem::read(player + 0x20); 541 | 542 | if (id == esp::local_player->get_steam_id( )) 543 | continue; 544 | 545 | auto position = mem::read(player + 0x2C); 546 | auto distance = esp::local_player->get_bone_transform(48)->get_bone_position( ).distance(position); 547 | if (distance < 350.f) 548 | continue; 549 | 550 | auto player_name = (str)(*reinterpret_cast(player + 0x18)); 551 | auto name = player_name->str; 552 | vector2 out; 553 | esp::out_w2s(position, out); 554 | esp::draw_name({out.x, out.y, 0}, name); 555 | } 556 | } 557 | 558 | 559 | 560 | void start( ) { 561 | //esp::draw_target_snap_line(); 562 | //draw_raid(); 563 | draw_teammates( ); 564 | iterate_players( ); 565 | } 566 | } -------------------------------------------------------------------------------- /projectile.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rust/features/player_esp.hpp" 4 | #include "rust/classes.hpp" 5 | 6 | #include 7 | #include "offsets.h" 8 | 9 | namespace O::Projectile { 10 | constexpr auto initialVelocity = 0x18; 11 | constexpr auto drag = 0x24; 12 | constexpr auto gravityModifier = 0x28; 13 | constexpr auto thickness = 0x2c; 14 | constexpr auto initialDistance = 0x30; 15 | constexpr auto remainInWorld = 0x34; 16 | constexpr auto stickProbability = 0x38; 17 | constexpr auto breakProbability = 0x3c; 18 | constexpr auto conditionLoss = 0x40; 19 | constexpr auto ricochetChance = 0x44; 20 | constexpr auto penetrationPower = 0x48; 21 | constexpr auto damageProperties = 0x50; 22 | constexpr auto damageDistances = 0x58; 23 | constexpr auto damageMultipliers = 0x60; 24 | constexpr auto damageTypes = 0x68; 25 | constexpr auto rendererToScale = 0x70; 26 | constexpr auto firstPersonRenderer = 0x78; 27 | constexpr auto createDecals = 0x80; 28 | constexpr auto flybySound = 0x88; 29 | constexpr auto flybySoundDistance = 0x90; 30 | constexpr auto closeFlybySound = 0x98; 31 | constexpr auto closeFlybyDistance = 0xa0; 32 | constexpr auto tumbleSpeed = 0xa4; 33 | constexpr auto tumbleAxis = 0xa8; 34 | constexpr auto swimScale = 0xb4; 35 | constexpr auto swimSpeed = 0xc0; 36 | constexpr auto owner = 0xd0; 37 | constexpr auto sourceWeaponPrefab = 0xd8; 38 | constexpr auto sourceProjectilePrefab = 0xe0; 39 | constexpr auto mod = 0xe8; 40 | constexpr auto projectileID = 0xf0; 41 | constexpr auto seed = 0xf4; 42 | constexpr auto clientsideEffect = 0xf8; 43 | constexpr auto clientsideAttack = 0xf9; 44 | constexpr auto integrity = 0xfc; 45 | constexpr auto maxDistance = 0x100; 46 | constexpr auto modifier = 0x104; 47 | constexpr auto invisible = 0x114; 48 | constexpr auto currentVelocity = 0x118; 49 | constexpr auto currentPosition = 0x124; 50 | constexpr auto traveledDistance = 0x130; 51 | constexpr auto traveledTime = 0x134; 52 | constexpr auto launchTime = 0x138; 53 | constexpr auto sentPosition = 0x13c; 54 | constexpr auto previousPosition = 0x148; 55 | constexpr auto previousVelocity = 0x154; 56 | constexpr auto previousTraveledTime = 0x160; 57 | constexpr auto isRicochet = 0x164; 58 | constexpr auto isRetiring = 0x165; 59 | constexpr auto flybyPlayed = 0x166; 60 | constexpr auto wasFacingPlayer = 0x167; 61 | constexpr auto flybyPlane = 0x168; 62 | constexpr auto flybyRay = 0x178; 63 | constexpr auto cleanupAction = 0x190; 64 | constexpr auto hitTest = 0x198; 65 | constexpr auto swimRandom = 0x1a0; 66 | constexpr auto _waterMaterialID = 0x4; 67 | constexpr auto cachedWaterString = 0x8; 68 | }; 69 | 70 | #define safe_read(Addr, Type) mem::read((DWORD64)Addr) 71 | #define safe_write(Addr, Data, Type) mem::write((DWORD64)Addr, Data); 72 | 73 | class Projectile; 74 | 75 | static auto Retire = reinterpret_cast(0); 76 | static auto Update = reinterpret_cast(0); 77 | static auto Do_Hit = reinterpret_cast(0); 78 | 79 | 80 | static auto GetName = reinterpret_cast(0); 81 | 82 | static auto HitPointWorld = reinterpret_cast(0); 83 | static auto HitNormalWorld = reinterpret_cast(0); 84 | 85 | static auto Trace_All = reinterpret_cast(0); 86 | static auto get_magnitude = reinterpret_cast(0); 87 | 88 | static auto Sphere = reinterpret_cast(0); 89 | 90 | 91 | void init_projectile() { 92 | Update = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Projectile"), _("Update"), 0, _(""), _("")))); 93 | Sphere = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("DDraw"), _("Sphere"), 5, _(""), _("UnityEngine")))); 94 | Retire = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Projectile"), _("Retire"), 0, _(""), _("")))); 95 | Trace_All = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("GameTrace"), _("TraceAll"), 3, _(""), _("")))); 96 | 97 | HitPointWorld = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("HitTest"), _("HitPointWorld"), 0, _(""), _("")))); 98 | HitNormalWorld = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("HitTest"), _("HitNormalWorld"), 0, _(""), _("")))); 99 | 100 | GetName = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("AssetNameCache"), _("GetName"), 1, _(""), _("")))); 101 | Do_Hit = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Projectile"), _("DoHit"), 0, _(""), _("")))); 102 | get_magnitude = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Vector3"), _("get_magnitude"), 0, _(""), _("UnityEngine"))));; 103 | } 104 | 105 | class Projectile { 106 | public: 107 | void initialVelocity(vector3 d) { safe_write(this + O::Projectile::initialVelocity, d, vector3); } 108 | vector3 initialVelocity() { return safe_read(this + O::Projectile::initialVelocity, vector3); } 109 | 110 | vector3 sentPosition() { return safe_read(this + O::Projectile::sentPosition, vector3); } 111 | void sentPosition(vector3 d) { safe_write(this + O::Projectile::sentPosition, d, vector3); } 112 | 113 | void currentVelocity(vector3 d) { safe_write(this + O::Projectile::currentVelocity, d, vector3); } 114 | vector3 currentVelocity() { return safe_read(this + O::Projectile::currentVelocity, vector3); } 115 | 116 | float drag() { return safe_read(this + O::Projectile::drag, float); } 117 | 118 | float previoustraveledTime() { return safe_read(this + O::Projectile::previousTraveledTime, float); } 119 | void previoustraveledTime(float d) { safe_write(this + O::Projectile::previousTraveledTime, d, float); } 120 | 121 | float gravityModifier() { return safe_read(this + O::Projectile::gravityModifier, float); } 122 | void integrity(float f) { safe_write(this + O::Projectile::integrity, f, float); } 123 | float integrity() { return safe_read(this + O::Projectile::integrity, float); } 124 | float maxDistance() { return safe_read(this + O::Projectile::maxDistance, float); } 125 | vector3 currentPosition() { return safe_read(this + O::Projectile::currentPosition, vector3); } 126 | void currentPosition(vector3 d) { safe_write(this + O::Projectile::currentPosition, d, vector3); } 127 | 128 | void partialTime(float f) { safe_write(this + O::Projectile::tumbleSpeed, f, float); } 129 | float partialTime() { return safe_read(this + O::Projectile::tumbleSpeed, float); } 130 | vector3 prevSentVelocity() { return safe_read(this + O::Projectile::tumbleAxis, vector3); } 131 | void prevSentVelocity(vector3 d) { safe_write(this + O::Projectile::tumbleAxis, d, vector3); } 132 | float sentTraveledTime() { return safe_read(this + O::Projectile::closeFlybyDistance, float); } 133 | void sentTraveledTime(float d) { safe_write(this + O::Projectile::closeFlybyDistance, d, float); } 134 | float lastUpdateTime() { return safe_read(this + O::Projectile::ricochetChance, float); } 135 | void lastUpdateTime(float d) { safe_write(this + O::Projectile::ricochetChance, d, float); } 136 | vector3 prevSentPosition() { return safe_read(this + O::Projectile::swimScale, vector3); } 137 | void prevSentPosition(vector3 d) { safe_write(this + O::Projectile::swimScale, d, vector3); } 138 | bool needsLOS() { return safe_read(this + O::Projectile::createDecals, bool); } 139 | void needsLOS(bool d) { safe_write(this + O::Projectile::createDecals, d, bool); } 140 | 141 | float traveledDistance() { return safe_read(this + O::Projectile::traveledDistance, float); } 142 | void traveledDistance(float d) { safe_write(this + O::Projectile::traveledDistance, d, float); } 143 | 144 | float initialDistance() { return safe_read(this + O::Projectile::initialDistance, float); } 145 | 146 | float traveledTime() { return safe_read(this + O::Projectile::traveledTime, float); } 147 | void traveledTime(float d) { safe_write(this + O::Projectile::traveledTime, d, float); } 148 | 149 | vector3 previousPosition() { return safe_read(this + O::Projectile::previousPosition, vector3); } 150 | void previousPosition(vector3 d) { safe_write(this + O::Projectile::previousPosition, d, vector3); } 151 | 152 | void hitTest(DWORD64 d) { safe_write(this + O::Projectile::hitTest, d, DWORD64); } 153 | DWORD64 hitTest() { return safe_read(this + O::Projectile::hitTest, DWORD64); } 154 | DWORD64 damageProperties() { return safe_read(this + O::Projectile::damageProperties, DWORD64); } 155 | 156 | int projectileID() { return safe_read(this + O::Projectile::projectileID, int); } 157 | 158 | base_player* owner() { return (base_player*)safe_read(this + O::Projectile::owner, DWORD64); } 159 | DWORD64 sourceWeaponPrefab() { return safe_read(this + O::Projectile::sourceWeaponPrefab, DWORD64); } 160 | 161 | DWORD64 damageDistances() { return safe_read(this + O::Projectile::damageDistances, DWORD64); } 162 | 163 | bool invisible() { return safe_read(this + O::Projectile::invisible, bool); } 164 | 165 | float launchTime() { return safe_read(this + O::Projectile::launchTime, float); } 166 | void launchTime(float d) { safe_write(this + O::Projectile::launchTime, d, float); } 167 | 168 | bool IsAlive() { 169 | return (this->integrity() > 0.001f && this->traveledDistance() < this->maxDistance() && this->traveledTime() < 8); 170 | } 171 | 172 | struct TraceInfo { 173 | 174 | bool valid; // 0x10 175 | float distance; // 0x14 176 | DWORD64 entity; // 0x18 //BasePlayer 177 | vector3 point; // 0x20 178 | vector3 normal; // 0x2C 179 | DWORD64/*Transform*/ bone; // 0x38 180 | DWORD64 material; // 0x40 181 | unsigned int partID; // 0x48 182 | DWORD64 collider; // 0x50 183 | }; 184 | 185 | float GetHitDist() { 186 | float travel = traveledTime(); 187 | 188 | float num6 = (travel + 2 / 60 + 0.03125f) * 1.5f; 189 | float maxdist = 0.1f + num6 * 5.5f; 190 | return maxdist; 191 | } 192 | 193 | vector3 SimulateProjectile(vector3& position, vector3& velocity, float& partialTime, float travelTime, vector3 gravity, float drag) 194 | { 195 | float num = 0.03125f; 196 | vector3 origin = position; 197 | if (partialTime > 0) 198 | { 199 | float num2 = num - partialTime; 200 | if (travelTime < num2) 201 | { 202 | origin = position; 203 | position += velocity * travelTime; 204 | partialTime += travelTime; 205 | return origin; 206 | } 207 | origin = position; 208 | position += velocity * num2; 209 | velocity += gravity * num; 210 | velocity -= velocity * drag * num; 211 | travelTime -= num2; 212 | } 213 | 214 | int num3 = FloorToInt(travelTime / num); 215 | 216 | for (int i = 0; i < num3; i++) 217 | { 218 | origin = position; 219 | position += velocity * num; 220 | velocity += gravity * num; 221 | velocity -= velocity * drag * num; 222 | } 223 | partialTime = travelTime - num * (float)num3; 224 | if (partialTime > 0) 225 | { 226 | origin = position; 227 | position += velocity * partialTime; 228 | } 229 | return origin; 230 | } 231 | 232 | void UpdateHitTest(TraceInfo info) { 233 | DWORD64 ht = hitTest(); 234 | 235 | safe_write(ht + 0x66, true, bool); //DidHit 236 | safe_write(ht + 0x88, info.entity, DWORD64); //HitEntity 237 | safe_write(ht + 0xA8, info.distance, float); //HitDistance 238 | 239 | if (info.material != 0) { 240 | str material = (GetName(info.material)); 241 | safe_write(ht + 0xC0, material, str); //HitMaterial 242 | } 243 | 244 | safe_write(ht + 0xB8, info.partID, unsigned int); //HitPart 245 | safe_write(ht + 0xB0, info.bone, DWORD64); //HitTransform 246 | safe_write(ht + 0x90, info.point, vector3); //HitPoint 247 | safe_write(ht + 0x9C, info.normal, vector3); //HitNormal 248 | safe_write(ht + 0x78, info.collider, DWORD64); //collider 249 | 250 | DWORD64 go = info.collider != 0 ? get_gameObject(info.collider) : get_gameObject(info.bone); 251 | safe_write(ht + 0x70, go, DWORD64); //gameObject 252 | if (info.bone != 0) { 253 | 254 | vector3 hitpoint = InverseTransformPoint(safe_read(ht + 0xB0, transform*)/*HitTransform*/, info.point); 255 | safe_write(ht + 0x90, hitpoint, vector3); //hitPoint 256 | 257 | vector3 normalpoint = InverseTransformDirection(safe_read(ht + 0xB0, transform*)/*HitTransform*/, info.normal); 258 | safe_write(ht + 0x9C, normalpoint, vector3); //HitNormal 259 | } 260 | 261 | } 262 | 263 | vector3 Simulate(bool returnvelocity, bool sendtoserver) { 264 | vector3 pos = prevSentPosition(); vector3 prev = prevSentVelocity(); float part = partialTime(); float travel = max(traveledTime() - sentTraveledTime(), 0); 265 | 266 | vector3 gr = get_gravity(); //static Vector3 get_gravity(); 267 | 268 | 269 | vector3 origin = SimulateProjectile(pos, prev, part, travel, gr * gravityModifier(), drag()); 270 | 271 | if (sendtoserver) { 272 | prevSentPosition(pos); 273 | prevSentVelocity(prev); 274 | partialTime(part); 275 | sentTraveledTime(traveledTime()); 276 | } 277 | 278 | if (returnvelocity) return prev; 279 | 280 | return origin; 281 | } 282 | 283 | bool DoFatBulletHit(Projectile* pr, vector3 point) { 284 | float maxdist = GetHitDist(); 285 | 286 | auto target = esp::local_player->get_aimbot_target(point, maxdist); 287 | 288 | if (get_isAlive((base_projectile*)pr) && target.player && !target.teammate) { 289 | if (!unity::is_visible(target.pos, point)) { 290 | return false; 291 | } 292 | 293 | DWORD64 ht = hitTest(); 294 | safe_write(ht + 0x66, true, bool); //DidHit 295 | safe_write(ht + 0x88, (DWORD64)target.player, DWORD64); //HitEntity 296 | transform* Transform; 297 | 298 | if (!target.is_heli) { 299 | Transform = FindBone(target.player, _(L"spine4")); 300 | if (settings::weapon::hitbox_override) 301 | Transform = FindBone(target.player, _(L"head")); 302 | } 303 | //else 304 | //{ 305 | // auto weakspots = target.player->get_weakspots(); 306 | // if (weakspots) { 307 | // auto size = *reinterpret_cast(weakspots + 0x18); 308 | 309 | // bool tail_alive = false; 310 | // bool main_alive = false; 311 | // for (int i = 0; i < size; i++) { 312 | // auto weakspot = *(uintptr_t*)(weakspots + 0x20 + i * 0x8); 313 | // if (!weakspot) 314 | // continue; 315 | // auto health = *reinterpret_cast(weakspot + 0x24); 316 | // if (health > 0) { 317 | // if (i == 0) { 318 | // main_alive = true; 319 | // } 320 | // else { 321 | // tail_alive = true; 322 | // } 323 | // } 324 | // } 325 | 326 | // if (tail_alive) { 327 | // attack->hitBone = 2699525250; 328 | // attack->hitPartID = 2306822461; 329 | // attack->hitPositionLocal = { .9f, -.4f, .1f }; 330 | // attack->hitNormalLocal = { .9f, -.4f, .1f }; 331 | // } 332 | // else if (main_alive) { 333 | // attack->hitBone = 224139191; 334 | // attack->hitPartID = 2306822461; 335 | // attack->hitPositionLocal = { .9f, -.4f, .1f }; 336 | // attack->hitNormalLocal = { .9f, -.4f, .1f }; 337 | // } 338 | // } 339 | //} 340 | if (!Transform) 341 | return false; 342 | 343 | safe_write(ht + 0xB0, (uintptr_t)Transform, DWORD64); 344 | 345 | vector3 hitpoint = InverseTransformPoint(Transform, point); 346 | safe_write(ht + 0x90, hitpoint, vector3); //hitPoint 347 | safe_write(ht + 0x14, point, vector3); 348 | 349 | bool result = Do_Hit(pr, ht, point, vector3()); 350 | //Sphere(point, 0.015f, col(1, 0, 0, 1), 20, true); 351 | return true; 352 | } 353 | return false; 354 | } 355 | 356 | bool DoHit(Projectile* pr, DWORD64 ht, vector3 point, vector3 normal, TraceInfo info, bool& exit) { 357 | bool result = false; 358 | if (!IsAlive()) 359 | return result; 360 | 361 | auto material = info.material != 0 ? GetName(info.material)->str : (_(L"generic")); 362 | 363 | bool canIgnore = unity::is_visible(sentPosition(), currentPosition() + currentVelocity().Normalized() * 0.01f); 364 | if (!canIgnore) { 365 | integrity(0); 366 | return true; 367 | } 368 | 369 | float org; 370 | if (canIgnore) { 371 | vector3 attackStart = Simulate(false, true); 372 | 373 | safe_write(ht + 0x14, Ray(attackStart, vector3()), Ray); 374 | } 375 | 376 | if (canIgnore && m_wcsicmp(material, _(L"Flesh"))) { 377 | DWORD64 Tra = safe_read(ht + 0xB0, DWORD64); 378 | if (Tra) { 379 | auto st = _(L"head"); 380 | 381 | set_name(Tra, st); 382 | } 383 | 384 | result = Do_Hit(pr, ht, point, normal); 385 | sentPosition(currentPosition()); 386 | 387 | } 388 | return result; 389 | } 390 | 391 | 392 | bool DoMovement(float deltaTime, Projectile* pr) { 393 | vector3 a = currentVelocity() * deltaTime; 394 | float magnitude = a.Length(); 395 | float num2 = 1 / magnitude; 396 | vector3 vec2 = a * num2; 397 | bool flag = false; 398 | 399 | vector3 vec3 = currentPosition() + vec2 * magnitude; 400 | float num3 = traveledTime() + deltaTime; 401 | 402 | DWORD64 ht = hitTest(); 403 | if (!ht) { 404 | /*HitTest_TypeInfo*/ 405 | DWORD64 htstatic = il2cpp::init_class(_("HitTest"), _("")); 406 | 407 | DWORD64 HitTest = il2cpp::methods::object_new(htstatic); 408 | ht = HitTest; 409 | hitTest(HitTest); 410 | } 411 | Ray ray = Ray(currentPosition(), vec2); 412 | safe_write(ht + 0x14, ray, Ray); //AttackRay 413 | safe_write(ht + 0x34, magnitude, float); //MaxDistance 414 | 415 | base_player* ow = this->owner(); 416 | safe_write(ht + 0x80, (DWORD64)ow, DWORD64); //IgnoreEntity 417 | safe_write(ht + 0x2C, 0, float); //Radius 418 | safe_write(ht + 0x30, 0.15f, float); //Forgiveness FAT BULLET 419 | if (!esp::local_player || ow->get_steam_id() == esp::local_player->get_steam_id()) { 420 | safe_write(ht + 0x10, 0x2, int); //Type 421 | } 422 | else safe_write(ht + 0x10, 0x1, int); //Type ` 423 | 424 | if (sourceWeaponPrefab()) { 425 | safe_write(ht + 0x65, true, bool); //BestHit 426 | safe_write(ht + 0x68, damageProperties(), DWORD64); //DamageProperties 427 | } 428 | 429 | typedef DWORD64(__stdcall* Unknown)(DWORD64); 430 | DWORD64 st = safe_read(mem::game_assembly_base + offsets::Method$Facepunch_Pool_GetList_TraceInfo_Address, DWORD64); //Method$Facepunch.Pool.GetList() address 431 | 432 | Unknown get_list = (Unknown)(mem::game_assembly_base + offsets::Method$Facepunch_Pool_GetList_TraceInfo_MethodAddress);//Method$Facepunch.Pool.GetList() MethodAddress 433 | 434 | DWORD64 rs = get_list(st); 435 | if (!rs) 436 | return false; 437 | 438 | Trace_All(ht, rs, 1269916433 /*mask*/); 439 | 440 | ht = hitTest(); 441 | safe_write(ht + 0x34, 0, float); //AttackEnd == AttackStart 442 | 443 | 444 | int size = safe_read(rs + 0x18, int); 445 | 446 | DWORD64 lst = safe_read(rs + 0x10, DWORD64); 447 | 448 | if (DoFatBulletHit(pr, currentPosition())) { 449 | integrity(0); 450 | return false; 451 | } 452 | 453 | for (int i = 0; i < size && this->IsAlive() && !flag; i++) { 454 | TraceInfo Trace = safe_read(lst + 0x20 + (i * sizeof(TraceInfo)), TraceInfo); 455 | if (Trace.valid) { 456 | this->UpdateHitTest(Trace); 457 | 458 | vector3 vec4 = HitPointWorld(ht); //Vector3 HitPointWorld(); 459 | vector3 normal = HitNormalWorld(ht); //Vector3 HitNormalWorld(); 460 | 461 | //Line(currentPosition(), vec4, col(1, 1, 1, 1), 20, true, true); 462 | //Sphere(Trace.point, 0.05f, col(0.5, 0, 0, 1), 20, true); 463 | 464 | float magnitude2 = (vec4 - currentPosition()).Length(); 465 | float num5 = magnitude2 * num2 * deltaTime; 466 | 467 | traveledDistance(traveledDistance() + magnitude2); 468 | traveledTime(traveledTime() + num5); 469 | currentPosition(vec4); 470 | 471 | bool exit = false; 472 | if (this->DoHit(pr, ht, vec4, normal, Trace, exit)) { 473 | flag = true; 474 | } 475 | 476 | if (exit) { 477 | return true; 478 | } 479 | } 480 | } 481 | 482 | if (!flag && this->IsAlive()) { 483 | float magnitude3 = (vec3 - currentPosition()).Length(); 484 | float num6 = magnitude3 * num2 * deltaTime; 485 | traveledDistance(traveledDistance() + magnitude3); 486 | traveledTime(traveledTime() + num6); 487 | currentPosition(vec3); 488 | } 489 | 490 | return false; 491 | } 492 | 493 | void DoVelocityUpdate(float deltaTime, Projectile* pr) { 494 | if (!IsAlive()) 495 | return; 496 | 497 | vector3 gr = get_gravity(); //static Vector3 get_gravity(); 498 | 499 | vector3 tr = (gr * gravityModifier() * deltaTime); 500 | currentVelocity(currentVelocity() + tr); 501 | 502 | vector3 dr = (currentVelocity() * drag() * deltaTime); 503 | currentVelocity(currentVelocity() - dr); 504 | } 505 | 506 | void UpdateVelocity(float deltaTime, Projectile* pr, bool& rett) { 507 | if (traveledTime() != 0) { 508 | previousPosition(this->currentPosition()); 509 | previoustraveledTime(this->traveledTime()); 510 | } 511 | 512 | transform* Transform = get_transform((base_player*)pr); 513 | vector3 pos = Transform->get_bone_position(); 514 | this->currentPosition(pos); 515 | 516 | if (traveledTime() == 0) { 517 | this->sentPosition(pos); 518 | this->previousPosition(pos); 519 | partialTime(0); sentTraveledTime(0); prevSentVelocity(initialVelocity()); prevSentPosition(sentPosition()); needsLOS(false); 520 | } 521 | 522 | deltaTime *= get_timeScale(); 523 | 524 | 525 | bool ret = this->DoMovement(deltaTime, pr); 526 | if (!ret) { 527 | this->DoVelocityUpdate(deltaTime, pr); 528 | } 529 | 530 | auto Trans = get_transform((base_player*)pr); //Component | Transform get_transform(); 531 | set_position(Trans, currentPosition()); //Transform | void set_position(vector3 value); 532 | 533 | vector4 rotation = LookRotation(currentVelocity(), vector3(0, 1, 0)); 534 | 535 | set_rotation(Trans, rotation); 536 | } 537 | }; 538 | 539 | void OnProjectileUpdate(Projectile* unk) { 540 | if (!unk) 541 | return; 542 | 543 | if(!settings::weapon::magic_bullet) 544 | return Update(unk); 545 | 546 | base_player* owner = (base_player*)safe_read(unk + 0xD0, DWORD64); 547 | if (!owner) 548 | return; 549 | 550 | if (owner->is_local_player()) { 551 | bool ret = false; 552 | if (get_isAlive((base_projectile*)unk)) { 553 | for (; unk->IsAlive(); unk->UpdateVelocity(0.03125f, unk, ret)) { 554 | if (ret) { 555 | break; 556 | } 557 | 558 | if (unk->launchTime() <= 0) { 559 | break; 560 | } 561 | 562 | float time = get_time(); 563 | 564 | if (time - unk->launchTime() < unk->traveledTime() + 0.03125f) { 565 | break; 566 | } 567 | } 568 | } 569 | else { 570 | Retire(unk); 571 | } 572 | } 573 | } -------------------------------------------------------------------------------- /utils/vector.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class vector2 6 | { 7 | public: 8 | float x; 9 | float y; 10 | 11 | vector2() 12 | {} 13 | 14 | vector2(float x, float y) 15 | : x(x), y(y) 16 | {} 17 | }; 18 | struct weapon_stats_t { 19 | float initial_velocity; 20 | float gravity_modifier; 21 | float drag; 22 | float initial_distance; 23 | }; 24 | 25 | enum ammo_types : int32_t { 26 | shotgun = -1685290200, 27 | shotgun_slug = -727717969, 28 | shotgun_fire = -1036635990, 29 | shotgun_handmade = 588596902, 30 | 31 | rifle_556 = -1211166256, 32 | rifle_556_hv = 1712070256, 33 | rifle_556_fire = 605467368, 34 | rifle_556_explosive = -1321651331, 35 | 36 | pistol = 785728077, 37 | pistol_hv = -1691396643, 38 | pistol_fire = 51984655, 39 | 40 | arrow_wooden = -1234735557, 41 | arrow_hv = -1023065463, 42 | arrow_fire = 14241751, 43 | arrow_bone = 215754713, 44 | 45 | nailgun_nails = -2097376851 46 | }; 47 | 48 | enum weapon_types : int32_t { 49 | spear_stone = 1602646136, 50 | spear_wooden = 1540934679 51 | }; 52 | 53 | float my_pow(float base, float exp) 54 | { 55 | auto nth_root = [](float A, int n) { 56 | constexpr int K = 8; 57 | float x[K] = { 1 }; 58 | for (int k = 0; k < K - 1; k++) 59 | x[k + 1] = (1.0 / n) * ((n - 1) * x[k] + A / my_pow(x[k], n - 1)); 60 | return x[K - 1]; 61 | }; 62 | if (base == 0) 63 | return 0; 64 | if (exp == 0) 65 | return 1; 66 | else if (exp < 0) 67 | return 1 / my_pow(base, -exp); 68 | else if (exp > 0 && exp < 1) 69 | return nth_root(base, 1 / exp); 70 | else if ((int)exp % 2 == 0) { 71 | float half_pow = my_pow(base, exp / 2); 72 | return half_pow * half_pow; 73 | } 74 | else 75 | return base * my_pow(base, exp - 1); 76 | } 77 | 78 | class vector3 79 | { 80 | public: 81 | float x; 82 | float y; 83 | float z; 84 | 85 | vector3() 86 | {} 87 | 88 | vector3(float x, float y, float z) 89 | : x(x), y(y), z(z) 90 | {} 91 | 92 | #define M_PI_2 1.57079632679489661923 93 | #define M_PI 3.14159265358979323846 94 | #define RAD_TO_DEG 180 / 3.141592654f 95 | 96 | bool is_empty() { return x == 0 && y == 0 && z == 0; } 97 | 98 | static float my_sqrt(float number) 99 | { 100 | long i; 101 | float x2, y; 102 | const float threehalfs = 1.5F; 103 | 104 | x2 = number * 0.5F; 105 | y = number; 106 | i = *(long*)&y; // floating point bit level hacking [sic] 107 | i = 0x5f3759df - (i >> 1); // Newton's approximation 108 | y = *(float*)&i; 109 | y = y * (threehalfs - (x2 * y * y)); // 1st iteration 110 | y = y * (threehalfs - (x2 * y * y)); // 2nd iteration 111 | 112 | return 1 / y; 113 | } 114 | 115 | inline float Length() 116 | { 117 | return my_sqrt((x * x) + (y * y) + (z * z)); 118 | } 119 | 120 | static double my_atan(double x) 121 | { 122 | // Return arctangent(x) given that 5/3 < x <= 2, with the same properties as atan. 123 | auto atani5 = [](double x) { 124 | constexpr double p00 = +0x1.124A85750FB5Cp+00; 125 | constexpr double p01 = +0x1.D59AE78C11C49p-03; 126 | constexpr double p02 = -0x1.8AD3C44F10DC3p-04; 127 | constexpr double p03 = +0x1.2B090AAD5F9DCp-05; 128 | constexpr double p04 = -0x1.881EC3D15241Fp-07; 129 | constexpr double p05 = +0x1.8CB82A74E0699p-09; 130 | constexpr double p06 = -0x1.3182219E21362p-12; 131 | constexpr double p07 = -0x1.2B9AD13DB35A8p-12; 132 | constexpr double p08 = +0x1.10F884EAC0E0Ap-12; 133 | constexpr double p09 = -0x1.3045B70E93129p-13; 134 | constexpr double p10 = +0x1.00B6A460AC05Dp-14; 135 | 136 | double y = x - 0x1.d555555461337p0; 137 | 138 | return ((((((((((+p10) * y + p09) * y + p08) * y + p07) * y + p06) * y + 139 | p05) * 140 | y + 141 | p04) * 142 | y + 143 | p03) * 144 | y + 145 | p02) * 146 | y + 147 | p01) * 148 | y + 149 | p00; 150 | }; 151 | // Return arctangent(x) given that 4/3 < x <= 5/3, with the same properties as 152 | // atan. 153 | auto atani4 = [](double x) { 154 | constexpr double p00 = +0x1730BD281F69Dp-01; 155 | constexpr double p01 = +0x1.3B13B13B13B0Cp-02; 156 | constexpr double p02 = -0x1.22D719C06115Ep-03; 157 | constexpr double p03 = +0x1.C963C83985742p-05; 158 | constexpr double p04 = -0x1.135A0938EC462p-06; 159 | constexpr double p05 = +0x1.13A254D6E5B7Cp-09; 160 | constexpr double p06 = +0x1.DFAA5E77B7375p-10; 161 | constexpr double p07 = -0x14AC1342182D2p-10; 162 | constexpr double p08 = +0x1.25BAD4D85CBE1p-10; 163 | constexpr double p09 = -0x1.E4EEF429EB680p-12; 164 | constexpr double p10 = +0x1.B4E30D1BA3819p-14; 165 | constexpr double p11 = +0x1.0280537F097F3p-15; 166 | 167 | double y = x - 0x1.8000000000003p0; 168 | 169 | return (((((((((((+p11) * y + p10) * y + p09) * y + p08) * y + p07) * y + 170 | p06) * 171 | y + 172 | p05) * 173 | y + 174 | p04) * 175 | y + 176 | p03) * 177 | y + 178 | p02) * 179 | y + 180 | p01) * 181 | y + 182 | p00; 183 | }; 184 | // Return arctangent(x) given that 1 < x <= 4 / 3, with the same properties as 185 | // atan. 186 | auto atani3 = [](double x) { 187 | constexpr double p00 = +0x1.B96E5A78C5C40p-01; 188 | constexpr double p01 = +0x1.B1B1B1B1B1B3Dp-02; 189 | constexpr double p02 = -0x1.AC97826D58470p-03; 190 | constexpr double p03 = +0x1.3FD2B9F586A67p-04; 191 | constexpr double p04 = -0x1.BC317394714B7p-07; 192 | constexpr double p05 = -0x1.2B01FC60CC37Ap-07; 193 | constexpr double p06 = +0x1.73A9328786665p-07; 194 | constexpr double p07 = -0x1.C0B993A09CE31p-08; 195 | constexpr double p08 = +0x1.2FCDACDD6E5B5p-09; 196 | constexpr double p09 = +0x1.CBD49DA316282p-13; 197 | constexpr double p10 = -0x1.0120E602F6336p-10; 198 | constexpr double p11 = +0x1.A89224FF69018p-11; 199 | constexpr double p12 = -0x1.883D8959134B3p-12; 200 | 201 | double y = x - 0x1.2aaaaaaaaaa96p0; 202 | 203 | return ((((((((((((+p12) * y + p11) * y + p10) * y + p09) * y + p08) * y + 204 | p07) * 205 | y + 206 | p06) * 207 | y + 208 | p05) * 209 | y + 210 | p04) * 211 | y + 212 | p03) * 213 | y + 214 | p02) * 215 | y + 216 | p01) * 217 | y + 218 | p00; 219 | }; 220 | // Return arctangent(x) given that 3 / 4 < x <= 1, with the same properties as 221 | // atan. 222 | auto atani2 = [](double x) { 223 | constexpr double p00 = +0x1.700A7C580EA7Ep-01; 224 | constexpr double p01 = +0x1.21FB781196AC3p-01; 225 | constexpr double p02 = -0x1.1F6A8499714A2p-02; 226 | constexpr double p03 = +0x1.41B15E5E8DCD0p-04; 227 | constexpr double p04 = +0x1.59BC93F81895Ap-06; 228 | constexpr double p05 = -0x1.63B543EFFA4EFp-05; 229 | constexpr double p06 = +0x1.C90E92AC8D86Cp-06; 230 | constexpr double p07 = -0x1.91F7E2A7A338Fp-08; 231 | constexpr double p08 = -0x1.AC1645739E676p-08; 232 | constexpr double p09 = +0x1.152311B180E6Cp-07; 233 | constexpr double p10 = -0x1.265EF51B17DB7p-08; 234 | constexpr double p11 = +0x1.CA7CDE5DE9BD7p-14; 235 | 236 | double y = x - 0x1.c0000000f4213p-1; 237 | 238 | return (((((((((((+p11) * y + p10) * y + p09) * y + p08) * y + p07) * y + 239 | p06) * 240 | y + 241 | p05) * 242 | y + 243 | p04) * 244 | y + 245 | p03) * 246 | y + 247 | p02) * 248 | y + 249 | p01) * 250 | y + 251 | p00; 252 | }; 253 | // Return arctangent(x) given that 1/2 < x <= 3/4, with the same properties as 254 | // atan. 255 | auto atani1 = [](double x) { 256 | constexpr double p00 = +0x1.1E00BABDEFED0p-1; 257 | constexpr double p01 = +0x1.702E05C0B8155p-1; 258 | constexpr double p02 = -0x1.4AF2B78215A1Bp-2; 259 | constexpr double p03 = +0x1.5D0B7E9E69054p-6; 260 | constexpr double p04 = +0x1.A1247CA5D9475p-4; 261 | constexpr double p05 = -0x1.519E110F61B54p-4; 262 | constexpr double p06 = +0x1.A759263F377F2p-7; 263 | constexpr double p07 = +0x1.094966BE2B531p-5; 264 | constexpr double p08 = -0x1.09BC0AB7F914Cp-5; 265 | constexpr double p09 = +0x1F3B7C531AA4Ap-8; 266 | constexpr double p10 = +0x1.950E69DCDD967p-7; 267 | constexpr double p11 = -0x1.D88D31ABC3AE5p-7; 268 | constexpr double p12 = +0x1.10F3E20F6A2E2p-8; 269 | 270 | double y = x - 0x1.4000000000027p-1; 271 | 272 | return ((((((((((((+p12) * y + p11) * y + p10) * y + p09) * y + p08) * y + 273 | p07) * 274 | y + 275 | p06) * 276 | y + 277 | p05) * 278 | y + 279 | p04) * 280 | y + 281 | p03) * 282 | y + 283 | p02) * 284 | y + 285 | p01) * 286 | y + 287 | p00; 288 | }; 289 | // Return arctangent(x) given that 0x1p-27 < |x| <= 1/2, with the same properties 290 | // as atan. 291 | auto atani0 = [](double x) { 292 | constexpr double p03 = -0x1.555555555551Bp-2; 293 | constexpr double p05 = +0x1.99999999918D8p-3; 294 | constexpr double p07 = -0x1.2492492179CA3p-3; 295 | constexpr double p09 = +0x1.C71C7096C2725p-4; 296 | constexpr double p11 = -0x1.745CF51795B21p-4; 297 | constexpr double p13 = +0x1.3B113F18AC049p-4; 298 | constexpr double p15 = -0x1.10F31279EC05Dp-4; 299 | constexpr double p17 = +0x1.DFE7B9674AE37p-5; 300 | constexpr double p19 = -0x1.A38CF590469ECp-5; 301 | constexpr double p21 = +0x1.56CDB5D887934p-5; 302 | constexpr double p23 = -0x1.C0EB85F543412p-6; 303 | constexpr double p25 = +0x1.4A9F5C4724056p-7; 304 | 305 | // Square x. 306 | double x2 = x * x; 307 | 308 | return ((((((((((((+p25) * x2 + p23) * x2 + p21) * x2 + p19) * x2 + p17) * 309 | x2 + 310 | p15) * 311 | x2 + 312 | p13) * 313 | x2 + 314 | p11) * 315 | x2 + 316 | p09) * 317 | x2 + 318 | p07) * 319 | x2 + 320 | p05) * 321 | x2 + 322 | p03) * 323 | x2 * x + 324 | x; 325 | }; 326 | // Return arctangent(x) given that 2 < x, with the same properties as atan. 327 | auto Tail = [](double x) { 328 | { 329 | constexpr double HalfPi = 0x3.243f6a8885a308d313198a2e037ap-1; 330 | 331 | // For large x, generate inexact and return pi/2. 332 | if (0x1p53 <= x) 333 | return HalfPi + DBL_EPSILON; 334 | if (x != x) // isnan 335 | return x - x; 336 | } 337 | 338 | constexpr double p03 = -0x1.5555555554A51p-2; 339 | constexpr double p05 = +0x1.999999989EBCAp-3; 340 | constexpr double p07 = -0x1.249248E1422E3p-3; 341 | constexpr double p09 = +0x1.C71C5EDFED480p-4; 342 | constexpr double p11 = -0x1.745B7F2D72663p-4; 343 | constexpr double p13 = +0x1.3AFD7A0E6EB75p-4; 344 | constexpr double p15 = -0x1.104146B1A1AE8p-4; 345 | constexpr double p17 = +0x1.D78252FA69C1Cp-5; 346 | constexpr double p19 = -0x1.81D33E401836Dp-5; 347 | constexpr double p21 = +0x1.007733E06CEB3p-5; 348 | constexpr double p23 = -0x1.83DAFDA7BD3FDp-7; 349 | 350 | constexpr double p000 = +0x1.921FB54442D18p0; 351 | constexpr double p001 = +0x1.1A62633145C07p-54; 352 | 353 | double y = 1 / x; 354 | 355 | // Square y. 356 | double y2 = y * y; 357 | 358 | return p001 - 359 | ((((((((((((+p23) * y2 + p21) * y2 + p19) * y2 + p17) * y2 + p15) * 360 | y2 + 361 | p13) * 362 | y2 + 363 | p11) * 364 | y2 + 365 | p09) * 366 | y2 + 367 | p07) * 368 | y2 + 369 | p05) * 370 | y2 + 371 | p03) * 372 | y2 * y + 373 | y) + 374 | p000; 375 | }; 376 | 377 | if (x < 0) 378 | if (x < -1) 379 | if (x < -5 / 3.) 380 | if (x < -2) 381 | return -Tail(-x); 382 | else 383 | return -atani5(-x); 384 | else if (x < -4 / 3.) 385 | return -atani4(-x); 386 | else 387 | return -atani3(-x); 388 | else if (x < -.5) 389 | if (x < -.75) 390 | return -atani2(-x); 391 | else 392 | return -atani1(-x); 393 | else if (x < -0x1.d12ed0af1a27fp-27) 394 | return atani0(x); 395 | else if (x <= -0x1p-1022) 396 | // Generate inexact and return x. 397 | return (DBL_EPSILON + 1) * x; 398 | else if (x == 0) 399 | return x; 400 | else 401 | // Generate underflow and return x. 402 | return x * DBL_EPSILON + x; 403 | else if (x <= +1) 404 | if (x <= +.5) 405 | if (x <= +0x1.d12ed0af1a27fp-27) 406 | if (x < +0x1p-1022) 407 | if (x == 0) 408 | return x; 409 | else 410 | // Generate underflow and return x. 411 | return x * DBL_EPSILON + x; 412 | else 413 | // Generate inexact and return x. 414 | return (DBL_EPSILON + 1) * x; 415 | else 416 | return atani0(x); 417 | else if (x <= +.75) 418 | return +atani1(+x); 419 | else 420 | return +atani2(+x); 421 | else if (x <= +5 / 3.) 422 | if (x <= +4 / 3.) 423 | return +atani3(+x); 424 | else 425 | return +atani4(+x); 426 | else if (x <= +2) 427 | return +atani5(+x); 428 | else 429 | return +Tail(+x); 430 | } 431 | 432 | static float my_sin(float x) 433 | { 434 | // useful to pre-calculate 435 | double x2 = x * x; 436 | double x4 = x2 * x2; 437 | 438 | // Calculate the terms 439 | // As long as abs(x) < sqrt(6), which is 2.45, all terms will be positive. 440 | // Values outside this range should be reduced to [-pi/2, pi/2] anyway for 441 | // accuracy. Some care has to be given to the factorials. They can be 442 | // pre-calculated by the compiler, but the value for the higher ones will exceed 443 | // the storage capacity of int. so force the compiler to use unsigned long longs 444 | // (if available) or doubles. 445 | double t1 = x * (1.0 - x2 / (2 * 3)); 446 | double x5 = x * x4; 447 | double t2 = x5 * (1.0 - x2 / (6 * 7)) / (1.0 * 2 * 3 * 4 * 5); 448 | double x9 = x5 * x4; 449 | double t3 = x9 * (1.0 - x2 / (10 * 11)) / (1.0 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9); 450 | double x13 = x9 * x4; 451 | double t4 = x13 * (1.0 - x2 / (14 * 15)) / 452 | (1.0 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13); 453 | double x14 = x13 * x4; 454 | double t5 = 455 | x14 * (1.0 - x2 / (18 * 19)) / 456 | (1.0 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17); 457 | double x15 = x14 * x4; 458 | double t6 = x15 * (1.0 - x2 / (22 * 23)) / 459 | (1.0 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 460 | 16 * 17 * 18 * 19 * 20 * 21); 461 | // add some more if your accuracy requires them. 462 | // But remember that x is smaller than 2, and the factorial grows very fast 463 | // so I doubt that 2^17 / 17! will add anything. 464 | // Even t4 might already be too small to matter when compared with t1. 465 | 466 | // Sum backwards 467 | double result = t6; 468 | result += t5; 469 | result += t4; 470 | result += t3; 471 | result += t2; 472 | result += t1; 473 | 474 | return result; 475 | } 476 | 477 | float length_2d() { return my_sqrt((x * x) + (z * z)); } 478 | 479 | static float my_cos(float x) { return my_sin(x + M_PI_2); } 480 | 481 | static float my_asin(float x) { return my_atan2(x, my_sqrt(1.0 - (x * x))); } 482 | 483 | inline float calc_pitch(vector3 from, vector3 to, weapon_stats_t stats) 484 | { 485 | float dist = (to - from).length_2d(); 486 | 487 | float dt = (dist / stats.initial_velocity); 488 | 489 | // float new_vel = stats.initial_velocity - ( stats.drag * stats.initial_velocity 490 | // * stats.initial_velocity * dt ); 491 | float new_vel = 2 / ((stats.drag * dt) + 2) * stats.initial_velocity; 492 | 493 | const float y = to.y - from.y; 494 | const float v = new_vel; 495 | const float g = 9.81f * stats.gravity_modifier; 496 | const float r_to_deg = (180 / 3.14159265358979323f); 497 | 498 | if (dist == 0) 499 | return 0; 500 | 501 | const float pitch = my_atan2( 502 | (((v * v)) - my_sqrt((v * v * v * v) - (g * ((g * (dist * dist)) + 503 | (2 * y * (v * v)))))), 504 | (g * dist)); 505 | 506 | return pitch * r_to_deg; 507 | } 508 | 509 | vector3 lerp(vector3 v, float x, bool clamp = true) 510 | { 511 | auto delta = (v - *this); 512 | if (clamp) 513 | delta.clamp(); 514 | 515 | auto result = (*this + delta * x); 516 | if (clamp) 517 | result.clamp(); 518 | 519 | return result; 520 | } 521 | 522 | vector3 forward() 523 | { 524 | float sp, sy, cp, cy; 525 | 526 | constexpr auto PI = 3.14159265358979323846; 527 | sy = my_sin(y / 180 * (float)PI); 528 | cy = my_cos(y / 180 * (float)PI); 529 | 530 | sp = my_sin(x / 180 * (float)PI); 531 | cp = my_cos(x / 180 * (float)PI); 532 | 533 | return { cp * cy, -sp, cp * sy }; 534 | } 535 | 536 | template 537 | T get_remainder(T val, T min, T max) 538 | { 539 | while (val > max) 540 | val -= max * 2; 541 | while (val < min) 542 | val += max * 2; 543 | return val; 544 | } 545 | 546 | vector3 clamp() 547 | { 548 | constexpr auto yaw_limit = static_cast(180); 549 | constexpr auto pitch_limit = static_cast(90); 550 | 551 | y = get_remainder(y, -yaw_limit, yaw_limit); 552 | x = get_remainder(x, -pitch_limit, pitch_limit); 553 | 554 | /*if ( x > 180 ) 555 | x -= 360; 556 | else if ( x < -180 ) 557 | x += 360; 558 | 559 | if ( y > 180 ) 560 | y -= 360; 561 | else if ( y < -180 ) 562 | y += 360; 563 | 564 | if ( x < -89 ) 565 | x = -89; 566 | 567 | if ( x > 89 ) 568 | x = 89; 569 | 570 | while ( y < -180 ) 571 | y += 360; 572 | 573 | while ( y > 180 ) 574 | y -= 360; 575 | 576 | z = 0;*/ 577 | 578 | if (x != x) 579 | x = 0; 580 | if (y != y) 581 | y = 0; 582 | if (z != z) 583 | z = 0; 584 | 585 | return *this; 586 | } 587 | 588 | 589 | static float my_atan2(float y, float x) 590 | { 591 | // https://en.wikipedia.org/wiki/Atan2#Definition (A compact expression with four 592 | // overlapping half-planes is: ...) 593 | if (x == 0) { 594 | if (y > 0.0f) 595 | return M_PI_2; 596 | else if (y < 0.0f) 597 | return -M_PI_2; 598 | return 0; 599 | } 600 | else if (x > 0) 601 | return my_atan(y / x); 602 | else if (x < 0) 603 | return M_PI + my_atan(y / x); 604 | else if (y > 0) 605 | return M_PI_2 - my_atan(y / x); 606 | else if (y < 0) 607 | return -M_PI_2 - my_atan(y / x); 608 | return 0; 609 | } 610 | 611 | vector3 rotation() 612 | { 613 | float pitch = -my_atan2(y, my_sqrt(x * x + z * z)); 614 | float yaw = -my_atan2(-x, z); 615 | 616 | yaw *= RAD_TO_DEG; 617 | pitch *= RAD_TO_DEG; 618 | 619 | return { pitch, yaw, 0 }; 620 | } 621 | 622 | inline float Distance(const vector3& vector) 623 | { 624 | return my_sqrt( 625 | (x - vector.x) * (x - vector.x) + 626 | (y - vector.y) * (y - vector.y) + 627 | (z - vector.z) * (z - vector.z)); 628 | } 629 | 630 | float dot(const vector3& vector) 631 | { 632 | return x * vector.x + y * vector.y + z * vector.z; 633 | } 634 | 635 | float length() 636 | { 637 | return my_sqrt(dot(*this)); 638 | } 639 | 640 | #define powFFFFFFFFFFFFFFFFFFFFFF(n) (n)*(n) 641 | 642 | float get_3d_dist(const vector3& Dst) { 643 | return my_sqrt( powFFFFFFFFFFFFFFFFFFFFFF(x - Dst.x) + powFFFFFFFFFFFFFFFFFFFFFF(y - Dst.y) + powFFFFFFFFFFFFFFFFFFFFFF(z - Dst.z)); 644 | } 645 | 646 | float distance(const vector3& vector) 647 | { 648 | return my_sqrt( 649 | (x - vector.x) * (x - vector.x) + 650 | (y - vector.y) * (y - vector.y) + 651 | (z - vector.z) * (z - vector.z)); 652 | } 653 | 654 | vector3 Normalized() { 655 | float len = Length(); 656 | return vector3(x / len, y / len, z / len); 657 | } 658 | 659 | vector3 normalize() 660 | { 661 | vector3 out = *this; 662 | auto l = length(); 663 | if (l == 0) 664 | return *this; 665 | ; 666 | out.x /= l; 667 | out.y /= l; 668 | out.z /= l; 669 | return out; 670 | } 671 | 672 | float world_distance(const vector3& vector) 673 | { 674 | return float(sqrtf(powf(vector.x - x, 2.0) + powf(vector.y - y, 2.0) + powf(vector.z - z, 2.0))); 675 | } 676 | 677 | void rotate(float deg) 678 | { 679 | float theta = deg / 180.0f * 3.14159265358979323846f; 680 | float c = cos(theta); 681 | float s = sin(theta); 682 | float tx = x * c - y * s; 683 | float ty = x * s + y * c; 684 | x = tx; 685 | y = ty; 686 | } 687 | 688 | vector3& operator+=(const vector3& vector) 689 | { 690 | x += vector.x; 691 | y += vector.y; 692 | z += vector.z; 693 | 694 | return *this; 695 | } 696 | 697 | vector3& operator-=(const vector3& vector) 698 | { 699 | x -= vector.x; 700 | y -= vector.y; 701 | z -= vector.z; 702 | 703 | return *this; 704 | } 705 | 706 | vector3& operator*=(float number) 707 | { 708 | x *= number; 709 | y *= number; 710 | z *= number; 711 | 712 | return *this; 713 | } 714 | 715 | vector3& operator/=(float number) 716 | { 717 | x /= number; 718 | y /= number; 719 | z /= number; 720 | 721 | return *this; 722 | } 723 | 724 | bool operator==(const vector3& vector) const 725 | { 726 | return x == vector.x && y == vector.y && z == vector.z; 727 | } 728 | 729 | bool operator!=(const vector3& vector) const 730 | { 731 | return x != vector.x || y != vector.y || z != vector.z; 732 | } 733 | 734 | vector3 operator+(const vector3& vector) const 735 | { 736 | return vector3(x + vector.x, y + vector.y, z + vector.z); 737 | } 738 | 739 | vector3 operator-(const vector3& vector) const 740 | { 741 | return vector3(x - vector.x, y - vector.y, z - vector.z); 742 | } 743 | 744 | vector3 operator-() const 745 | { 746 | return vector3(-x, -y, -z); 747 | } 748 | 749 | vector3 operator*(float number) const 750 | { 751 | return vector3(x * number, y * number, z * number); 752 | } 753 | 754 | vector3 operator/(float number) const 755 | { 756 | return vector3(x / number, y / number, z / number); 757 | } 758 | 759 | void angle_vectors(vector3* forward, vector3* right, vector3* up) 760 | { 761 | float sp, sy, cp, cy, sr, cr; 762 | 763 | constexpr auto PI = 3.14159265358979323846; 764 | sy = my_sin(y / 180.f * (float)PI); 765 | cy = my_cos(y / 180.f * (float)PI); 766 | 767 | sp = my_sin(x / 180.f * (float)PI); 768 | cp = my_cos(x / 180.f * (float)PI); 769 | 770 | sr = 0.f; 771 | cr = 1.f; 772 | 773 | if (forward) { 774 | *forward = { cp * cy, -sp, cp * sy }; 775 | } 776 | 777 | if (right) { 778 | right->x = cp * sy; 779 | right->y = (cr * sp * sy + -sr * cy); 780 | right->z = (sr * sp * sy + cr * cy); 781 | } 782 | 783 | if (up) { 784 | up->x = (cr * sp * cy + -sr * -sy); 785 | up->y = cr * cp; 786 | up->z = (cr * sp * sy + -sr * cy); 787 | } 788 | } 789 | }; 790 | 791 | class VMatrix 792 | { 793 | public: 794 | VMatrix() 795 | : m{ { 0, 0, 0, 0 }, 796 | { 0, 0, 0, 0 }, 797 | { 0, 0, 0, 0 }, 798 | { 0, 0, 0, 0 } } 799 | {} 800 | 801 | VMatrix(const VMatrix&) = default; 802 | 803 | VMatrix transpose() { 804 | VMatrix m; 805 | 806 | for (int i = 0; i < 4; i++) 807 | for (int j = 0; j < 4; j++) 808 | m.m[i][j] = this->m[j][i]; 809 | 810 | return m; 811 | } 812 | 813 | void matrix_identity() { 814 | memset(this, 0, sizeof(VMatrix)); 815 | m[0][0] = 1.0f; 816 | m[1][1] = 1.0f; 817 | m[2][2] = 1.0f; 818 | m[3][3] = 1.0f; 819 | } 820 | 821 | bool is_empty() { 822 | if (!m[3][0] && !m[3][1] && !m[3][2] && !m[2][1] && !m[2][0] && !m[2][2]) 823 | return true; 824 | 825 | return false; 826 | } 827 | 828 | vector3 operator*(const vector3& vec) { 829 | VMatrix m; 830 | 831 | m[3][0] = vec.x; 832 | m[3][1] = vec.y; 833 | m[3][2] = vec.z; 834 | 835 | m[0][0] = 1; 836 | m[1][1] = 1; 837 | m[2][2] = 1; 838 | 839 | 840 | m[0][3] = 0.0f; 841 | m[1][3] = 0.0f; 842 | m[2][3] = 0.0f; 843 | m[3][3] = 1.0f; 844 | 845 | auto result = m * (*this); 846 | 847 | return vector3{ result[3][0], result[3][1], result[3][2] }; 848 | } 849 | 850 | VMatrix operator*(const VMatrix& _m2) { 851 | auto _m = *this; 852 | 853 | VMatrix out; 854 | out[0][0] = _m[0][0] * _m2[0][0] + _m[0][1] * _m2[1][0] + _m[0][2] * _m2[2][0] + _m[0][3] * _m2[3][0]; 855 | out[0][1] = _m[0][0] * _m2[0][1] + _m[0][1] * _m2[1][1] + _m[0][2] * _m2[2][1] + _m[0][3] * _m2[3][1]; 856 | out[0][2] = _m[0][0] * _m2[0][2] + _m[0][1] * _m2[1][2] + _m[0][2] * _m2[2][2] + _m[0][3] * _m2[3][2]; 857 | out[0][3] = _m[0][0] * _m2[0][3] + _m[0][1] * _m2[1][3] + _m[0][2] * _m2[2][3] + _m[0][3] * _m2[3][3]; 858 | out[1][0] = _m[1][0] * _m2[0][0] + _m[1][1] * _m2[1][0] + _m[1][2] * _m2[2][0] + _m[1][3] * _m2[3][0]; 859 | out[1][1] = _m[1][0] * _m2[0][1] + _m[1][1] * _m2[1][1] + _m[1][2] * _m2[2][1] + _m[1][3] * _m2[3][1]; 860 | out[1][2] = _m[1][0] * _m2[0][2] + _m[1][1] * _m2[1][2] + _m[1][2] * _m2[2][2] + _m[1][3] * _m2[3][2]; 861 | out[1][3] = _m[1][0] * _m2[0][3] + _m[1][1] * _m2[1][3] + _m[1][2] * _m2[2][3] + _m[1][3] * _m2[3][3]; 862 | out[2][0] = _m[2][0] * _m2[0][0] + _m[2][1] * _m2[1][0] + _m[2][2] * _m2[2][0] + _m[2][3] * _m2[3][0]; 863 | out[2][1] = _m[2][0] * _m2[0][1] + _m[2][1] * _m2[1][1] + _m[2][2] * _m2[2][1] + _m[2][3] * _m2[3][1]; 864 | out[2][2] = _m[2][0] * _m2[0][2] + _m[2][1] * _m2[1][2] + _m[2][2] * _m2[2][2] + _m[2][3] * _m2[3][2]; 865 | out[2][3] = _m[2][0] * _m2[0][3] + _m[2][1] * _m2[1][3] + _m[2][2] * _m2[2][3] + _m[2][3] * _m2[3][3]; 866 | out[3][0] = _m[3][0] * _m2[0][0] + _m[3][1] * _m2[1][0] + _m[3][2] * _m2[2][0] + _m[3][3] * _m2[3][0]; 867 | out[3][1] = _m[3][0] * _m2[0][1] + _m[3][1] * _m2[1][1] + _m[3][2] * _m2[2][1] + _m[3][3] * _m2[3][1]; 868 | out[3][2] = _m[3][0] * _m2[0][2] + _m[3][1] * _m2[1][2] + _m[3][2] * _m2[2][2] + _m[3][3] * _m2[3][2]; 869 | out[3][3] = _m[3][0] * _m2[0][3] + _m[3][1] * _m2[1][3] + _m[3][2] * _m2[2][3] + _m[3][3] * _m2[3][3]; 870 | 871 | return out; 872 | } 873 | 874 | float* operator[](size_t i) { return m[i]; } 875 | const float* operator[](size_t i) const { return m[i]; } 876 | 877 | union { 878 | struct { 879 | float _11, _12, _13, _14; 880 | float _21, _22, _23, _24; 881 | float _31, _32, _33, _34; 882 | float _41, _42, _43, _44; 883 | }; 884 | float m[4][4]; 885 | }; 886 | }; 887 | 888 | class vector4 889 | { 890 | public: 891 | float x; 892 | float y; 893 | float z; 894 | float w; 895 | 896 | vector4() 897 | {} 898 | 899 | vector4(float x, float y, float z, float w) 900 | : x(x), y(y), z(z), w(w) 901 | {} 902 | 903 | vector3 forward() 904 | { 905 | vector3 point = { 0, 0, 1 }; 906 | float num = x * 2; 907 | float num2 = y * 2; 908 | float num3 = z * 2; 909 | float num4 = x * num; 910 | float num5 = y * num2; 911 | float num6 = z * num3; 912 | float num7 = x * num2; 913 | float num8 = x * num3; 914 | float num9 = y * num3; 915 | float num10 = w * num; 916 | float num11 = w * num2; 917 | float num12 = w * num3; 918 | vector3 result; 919 | result.x = (1 - (num5 + num6)) * point.x + (num7 - num12) * point.y + 920 | (num8 + num11) * point.z; 921 | result.y = (num7 + num12) * point.x + (1 - (num4 + num6)) * point.y + 922 | (num9 - num10) * point.z; 923 | result.z = (num8 - num11) * point.x + (num9 + num10) * point.y + 924 | (1 - (num4 + num5)) * point.z; 925 | return result; 926 | } 927 | 928 | 929 | inline float dot(const vector4& vector) 930 | { 931 | return x * vector.x + y * vector.y + z * vector.z + w * vector.w; 932 | } 933 | 934 | inline float distance(const vector4& vector) 935 | { 936 | return sqrtf( 937 | (x - vector.x) * (x - vector.x) + 938 | (y - vector.y) * (y - vector.y) + 939 | (z - vector.z) * (z - vector.z) + 940 | (w - vector.w) * (w - vector.w)); 941 | } 942 | 943 | bool operator==(const vector4& vector) const 944 | { 945 | return x == vector.x && y == vector.y && z == vector.z && w == vector.w; 946 | } 947 | 948 | bool operator!=(const vector4& vector) const 949 | { 950 | return x != vector.x || y != vector.y || z != vector.z || w != vector.w; 951 | } 952 | 953 | vector4 operator+(const vector4& vector) const 954 | { 955 | return vector4(x + vector.x, y + vector.y, z + vector.z, w + vector.w); 956 | } 957 | 958 | vector4 operator-(const vector4& vector) const 959 | { 960 | return vector4(x - vector.x, y - vector.y, z - vector.z, w - vector.w); 961 | } 962 | 963 | vector4 operator-() const 964 | { 965 | return vector4(-x, -y, -z, -w); 966 | } 967 | 968 | vector4 operator*(float number) const 969 | { 970 | return vector4(x * number, y * number, z * number, w * number); 971 | } 972 | 973 | vector4 operator/(float number) const 974 | { 975 | return vector4(x / number, y / number, z / number, w / number); 976 | } 977 | 978 | vector4& operator+=(const vector4& vector) 979 | { 980 | x += vector.x; 981 | y += vector.y; 982 | z += vector.z; 983 | w += vector.w; 984 | return *this; 985 | } 986 | 987 | vector4& operator-=(const vector4& vector) 988 | { 989 | x -= vector.x; 990 | y -= vector.y; 991 | z -= vector.z; 992 | w -= vector.w; 993 | return *this; 994 | } 995 | 996 | vector4& operator*=(float number) 997 | { 998 | x *= number; 999 | y *= number; 1000 | z *= number; 1001 | w *= number; 1002 | return *this; 1003 | } 1004 | 1005 | vector4& operator/=(float number) 1006 | { 1007 | x /= number; 1008 | y /= number; 1009 | z /= number; 1010 | w /= number; 1011 | return *this; 1012 | } 1013 | }; 1014 | 1015 | struct matrix 1016 | { 1017 | vector4 vec0; 1018 | vector4 vec1; 1019 | vector4 vec2; 1020 | vector4 vec3; 1021 | }; 1022 | -------------------------------------------------------------------------------- /memory/lazy_importer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 Justas Masiulis 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // documentation is available at https://github.com/JustasMasiulis/lazy_importer 18 | 19 | #ifndef LAZY_IMPORTER_HPP 20 | #define LAZY_IMPORTER_HPP 21 | 22 | #define LI_FIND(name) \ 23 | reinterpret_cast( \ 24 | ::li::detail::find_nocache<::li::detail::khash(#name)>()) 25 | #define LI_MODULE(name) ::li::detail::module_handle<::li::detail::khash(name)>() 26 | 27 | 28 | 29 | // NOTE only std::forward is used from this header. 30 | // If there is a need to eliminate this dependency the function itself is very small. 31 | #include 32 | #include 33 | #include 34 | 35 | #ifndef LAZY_IMPORTER_NO_FORCEINLINE 36 | #if defined(_MSC_VER) 37 | #define LAZY_IMPORTER_FORCEINLINE __forceinline 38 | #elif defined(__GNUC__) && __GNUC__ > 3 39 | #define LAZY_IMPORTER_FORCEINLINE inline __attribute_xorstr((__always_inline__)) 40 | #else 41 | #define LAZY_IMPORTER_FORCEINLINE inline 42 | #endif 43 | #else 44 | #define LAZY_IMPORTER_FORCEINLINE inline 45 | #endif 46 | 47 | #ifdef LAZY_IMPORTER_CASE_INSENSITIVE 48 | #define LAZY_IMPORTER_TOLOWER(c) (c >= 'A' && c <= 'Z' ? (c | (1 << 5)) : c) 49 | #else 50 | #define LAZY_IMPORTER_TOLOWER(c) (c) 51 | #endif 52 | #define LI_FIND(name) \ 53 | reinterpret_cast( \ 54 | ::li::detail::find_nocache<::li::detail::khash(#name)>()) 55 | 56 | #define LI_FIND_DEF(name) \ 57 | reinterpret_cast(::li::detail::find_nocache<::li::detail::khash(#name)>()) 58 | 59 | #define LI_MODULE(name) ::li::detail::module_handle<::li::detail::khash(name)>() 60 | 61 | // returns dll base address or nullptr if it does not exist 62 | #define LI_MODULE_SAFE_(name) reinterpret_cast(::li::detail::module_handle_safe(::li::detail::hash(name))) 63 | 64 | // returns dll size or 0 if it does not exist 65 | #define LI_MODULESIZE_SAFE_(name) ::li::detail::module_size_safe(::li::detail::hash(name)) 66 | 67 | namespace li { 68 | namespace detail { 69 | 70 | template 71 | struct pair { 72 | First first; 73 | Second second; 74 | }; 75 | 76 | namespace win { 77 | 78 | struct LIST_ENTRY_T { 79 | const char* Flink; 80 | const char* Blink; 81 | }; 82 | 83 | struct UNICODE_STRING_T { 84 | unsigned short Length; 85 | unsigned short MaximumLength; 86 | wchar_t* Buffer; 87 | }; 88 | 89 | struct PEB_LDR_DATA_T { 90 | unsigned long Length; 91 | unsigned long Initialized; 92 | const char* SsHandle; 93 | LIST_ENTRY_T InLoadOrderModuleList; 94 | }; 95 | 96 | struct PEB_T { 97 | unsigned char Reserved1[2]; 98 | unsigned char BeingDebugged; 99 | unsigned char Reserved2[1]; 100 | const char* Reserved3[2]; 101 | PEB_LDR_DATA_T* Ldr; 102 | }; 103 | 104 | struct LDR_DATA_TABLE_ENTRY_T { 105 | LIST_ENTRY_T InLoadOrderLinks; 106 | LIST_ENTRY_T InMemoryOrderLinks; 107 | LIST_ENTRY_T InInitializationOrderLinks; 108 | const char* DllBase; 109 | const char* EntryPoint; 110 | union { 111 | unsigned long SizeOfImage; 112 | const char* _dummy; 113 | }; 114 | UNICODE_STRING_T FullDllName; 115 | UNICODE_STRING_T BaseDllName; 116 | 117 | LAZY_IMPORTER_FORCEINLINE const LDR_DATA_TABLE_ENTRY_T* 118 | load_order_next() const noexcept 119 | { 120 | return reinterpret_cast( 121 | InLoadOrderLinks.Flink); 122 | } 123 | }; 124 | 125 | struct IMAGE_DOS_HEADER { // DOS .EXE header 126 | unsigned short e_magic; // Magic number 127 | unsigned short e_cblp; // Bytes on last page of file 128 | unsigned short e_cp; // Pages in file 129 | unsigned short e_crlc; // Relocations 130 | unsigned short e_cparhdr; // Size of header in paragraphs 131 | unsigned short e_minalloc; // Minimum extra paragraphs needed 132 | unsigned short e_maxalloc; // Maximum extra paragraphs needed 133 | unsigned short e_ss; // Initial (relative) SS value 134 | unsigned short e_sp; // Initial SP value 135 | unsigned short e_csum; // Checksum 136 | unsigned short e_ip; // Initial IP value 137 | unsigned short e_cs; // Initial (relative) CS value 138 | unsigned short e_lfarlc; // File address of relocation table 139 | unsigned short e_ovno; // Overlay number 140 | unsigned short e_res[4]; // Reserved words 141 | unsigned short e_oemid; // OEM identifier (for e_oeminfo) 142 | unsigned short e_oeminfo; // OEM information; e_oemid specific 143 | unsigned short e_res2[10]; // Reserved words 144 | long e_lfanew; // File address of new exe header 145 | }; 146 | 147 | struct IMAGE_FILE_HEADER { 148 | unsigned short Machine; 149 | unsigned short NumberOfSections; 150 | unsigned long TimeDateStamp; 151 | unsigned long PointerToSymbolTable; 152 | unsigned long NumberOfSymbols; 153 | unsigned short SizeOfOptionalHeader; 154 | unsigned short Characteristics; 155 | }; 156 | 157 | struct IMAGE_EXPORT_DIRECTORY { 158 | unsigned long Characteristics; 159 | unsigned long TimeDateStamp; 160 | unsigned short MajorVersion; 161 | unsigned short MinorVersion; 162 | unsigned long Name; 163 | unsigned long Base; 164 | unsigned long NumberOfFunctions; 165 | unsigned long NumberOfNames; 166 | unsigned long AddressOfFunctions; // RVA from base of image 167 | unsigned long AddressOfNames; // RVA from base of image 168 | unsigned long AddressOfNameOrdinals; // RVA from base of image 169 | }; 170 | 171 | struct IMAGE_DATA_DIRECTORY { 172 | unsigned long VirtualAddress; 173 | unsigned long Size; 174 | }; 175 | 176 | struct IMAGE_OPTIONAL_HEADER64 { 177 | unsigned short Magic; 178 | unsigned char MajorLinkerVersion; 179 | unsigned char MinorLinkerVersion; 180 | unsigned long SizeOfCode; 181 | unsigned long SizeOfInitializedData; 182 | unsigned long SizeOfUninitializedData; 183 | unsigned long AddressOfEntryPoint; 184 | unsigned long BaseOfCode; 185 | unsigned long long ImageBase; 186 | unsigned long SectionAlignment; 187 | unsigned long FileAlignment; 188 | unsigned short MajorOperatingSystemVersion; 189 | unsigned short MinorOperatingSystemVersion; 190 | unsigned short MajorImageVersion; 191 | unsigned short MinorImageVersion; 192 | unsigned short MajorSubsystemVersion; 193 | unsigned short MinorSubsystemVersion; 194 | unsigned long Win32VersionValue; 195 | unsigned long SizeOfImage; 196 | unsigned long SizeOfHeaders; 197 | unsigned long CheckSum; 198 | unsigned short Subsystem; 199 | unsigned short DllCharacteristics; 200 | unsigned long long SizeOfStackReserve; 201 | unsigned long long SizeOfStackCommit; 202 | unsigned long long SizeOfHeapReserve; 203 | unsigned long long SizeOfHeapCommit; 204 | unsigned long LoaderFlags; 205 | unsigned long NumberOfRvaAndSizes; 206 | IMAGE_DATA_DIRECTORY DataDirectory[16]; 207 | }; 208 | 209 | struct IMAGE_OPTIONAL_HEADER32 { 210 | unsigned short Magic; 211 | unsigned char MajorLinkerVersion; 212 | unsigned char MinorLinkerVersion; 213 | unsigned long SizeOfCode; 214 | unsigned long SizeOfInitializedData; 215 | unsigned long SizeOfUninitializedData; 216 | unsigned long AddressOfEntryPoint; 217 | unsigned long BaseOfCode; 218 | unsigned long BaseOfData; 219 | unsigned long ImageBase; 220 | unsigned long SectionAlignment; 221 | unsigned long FileAlignment; 222 | unsigned short MajorOperatingSystemVersion; 223 | unsigned short MinorOperatingSystemVersion; 224 | unsigned short MajorImageVersion; 225 | unsigned short MinorImageVersion; 226 | unsigned short MajorSubsystemVersion; 227 | unsigned short MinorSubsystemVersion; 228 | unsigned long Win32VersionValue; 229 | unsigned long SizeOfImage; 230 | unsigned long SizeOfHeaders; 231 | unsigned long CheckSum; 232 | unsigned short Subsystem; 233 | unsigned short DllCharacteristics; 234 | unsigned long SizeOfStackReserve; 235 | unsigned long SizeOfStackCommit; 236 | unsigned long SizeOfHeapReserve; 237 | unsigned long SizeOfHeapCommit; 238 | unsigned long LoaderFlags; 239 | unsigned long NumberOfRvaAndSizes; 240 | IMAGE_DATA_DIRECTORY DataDirectory[16]; 241 | }; 242 | 243 | struct IMAGE_NT_HEADERS { 244 | unsigned long Signature; 245 | IMAGE_FILE_HEADER FileHeader; 246 | #ifdef _WIN64 247 | IMAGE_OPTIONAL_HEADER64 OptionalHeader; 248 | #else 249 | IMAGE_OPTIONAL_HEADER32 OptionalHeader; 250 | #endif 251 | }; 252 | 253 | } // namespace win 254 | 255 | // hashing stuff 256 | struct hash_t { 257 | using value_type = unsigned long; 258 | constexpr static value_type offset = 2166136261; 259 | constexpr static value_type prime = 16777619; 260 | constexpr static unsigned long long prime64 = prime; 261 | 262 | LAZY_IMPORTER_FORCEINLINE constexpr static value_type single(value_type value, 263 | char c) noexcept 264 | { 265 | return static_cast( 266 | (value ^ LAZY_IMPORTER_TOLOWER(c)) * 267 | static_cast(prime)); 268 | } 269 | }; 270 | 271 | template 272 | LAZY_IMPORTER_FORCEINLINE constexpr hash_t::value_type 273 | khash(const CharT* str, hash_t::value_type value = hash_t::offset) noexcept 274 | { 275 | return (*str ? khash(str + 1, hash_t::single(value, *str)) : value); 276 | } 277 | 278 | template 279 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash(const CharT* str) noexcept 280 | { 281 | hash_t::value_type value = hash_t::offset; 282 | 283 | for (;;) { 284 | char c = *str++; 285 | if (!c) 286 | return value; 287 | value = hash_t::single(value, c); 288 | } 289 | } 290 | 291 | LAZY_IMPORTER_FORCEINLINE hash_t::value_type hash( 292 | const win::UNICODE_STRING_T& str) noexcept 293 | { 294 | auto first = str.Buffer; 295 | const auto last = first + (str.Length / sizeof(wchar_t)); 296 | auto value = hash_t::offset; 297 | for (; first != last; ++first) 298 | value = hash_t::single(value, static_cast(*first)); 299 | 300 | return value; 301 | } 302 | 303 | LAZY_IMPORTER_FORCEINLINE pair hash_forwarded( 304 | const char* str) noexcept 305 | { 306 | pair module_and_function{ 307 | hash_t::offset, hash_t::offset 308 | }; 309 | 310 | for (; *str != '.'; ++str) 311 | module_and_function.first = hash_t::single(module_and_function.first, *str); 312 | 313 | ++str; 314 | 315 | for (; *str; ++str) 316 | module_and_function.second = hash_t::single(module_and_function.second, *str); 317 | 318 | return module_and_function; 319 | } 320 | 321 | 322 | // some helper functions 323 | LAZY_IMPORTER_FORCEINLINE const win::PEB_T* peb() noexcept 324 | { 325 | #if defined(_WIN64) 326 | return reinterpret_cast(__readgsqword(0x60)); 327 | #elif defined(_WIN32) 328 | return reinterpret_cast(__readfsdword(0x30)); 329 | #else 330 | #error Unsupported platform. Open an issue and I'll probably add support. 331 | #endif 332 | } 333 | 334 | LAZY_IMPORTER_FORCEINLINE const win::PEB_LDR_DATA_T* ldr() 335 | { 336 | return reinterpret_cast(peb()->Ldr); 337 | } 338 | 339 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_NT_HEADERS* nt_headers( 340 | const char* base) noexcept 341 | { 342 | return reinterpret_cast( 343 | base + reinterpret_cast(base)->e_lfanew); 344 | } 345 | 346 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* image_export_dir( 347 | const char* base) noexcept 348 | { 349 | return reinterpret_cast( 350 | base + nt_headers(base)->OptionalHeader.DataDirectory->VirtualAddress); 351 | } 352 | 353 | LAZY_IMPORTER_FORCEINLINE const win::LDR_DATA_TABLE_ENTRY_T* ldr_data_entry() noexcept 354 | { 355 | return reinterpret_cast( 356 | ldr()->InLoadOrderModuleList.Flink); 357 | } 358 | 359 | struct exports_directory { 360 | const char* _base; 361 | const win::IMAGE_EXPORT_DIRECTORY* _ied; 362 | unsigned long _ied_size; 363 | 364 | public: 365 | using size_type = unsigned long; 366 | 367 | LAZY_IMPORTER_FORCEINLINE 368 | exports_directory(const char* base) noexcept : _base(base) 369 | { 370 | const auto ied_data_dir = nt_headers(base)->OptionalHeader.DataDirectory[0]; 371 | _ied = reinterpret_cast( 372 | base + ied_data_dir.VirtualAddress); 373 | _ied_size = ied_data_dir.Size; 374 | } 375 | 376 | LAZY_IMPORTER_FORCEINLINE explicit operator bool() const noexcept 377 | { 378 | return reinterpret_cast(_ied) != _base; 379 | } 380 | 381 | LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept 382 | { 383 | return _ied->NumberOfNames; 384 | } 385 | 386 | LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { return _base; } 387 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* ied() const noexcept 388 | { 389 | return _ied; 390 | } 391 | 392 | LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const noexcept 393 | { 394 | return reinterpret_cast( 395 | _base + reinterpret_cast( 396 | _base + _ied->AddressOfNames)[index]); 397 | } 398 | 399 | LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) const noexcept 400 | { 401 | const auto* const rva_table = 402 | reinterpret_cast(_base + _ied->AddressOfFunctions); 403 | 404 | const auto* const ord_table = reinterpret_cast( 405 | _base + _ied->AddressOfNameOrdinals); 406 | 407 | return _base + rva_table[ord_table[index]]; 408 | } 409 | 410 | LAZY_IMPORTER_FORCEINLINE bool is_forwarded(const char* export_address) const 411 | noexcept 412 | { 413 | const auto ui_ied = reinterpret_cast(_ied); 414 | return (export_address > ui_ied && export_address < ui_ied + _ied_size); 415 | } 416 | }; 417 | 418 | struct safe_module_enumerator { 419 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T; 420 | value_type* value; 421 | value_type* const head; 422 | 423 | LAZY_IMPORTER_FORCEINLINE safe_module_enumerator() noexcept 424 | : value(ldr_data_entry()), head(value) 425 | {} 426 | 427 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = head; } 428 | 429 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept 430 | { 431 | value = value->load_order_next(); 432 | return value != head && value->DllBase; 433 | } 434 | }; 435 | 436 | struct unsafe_module_enumerator { 437 | using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T*; 438 | value_type value; 439 | 440 | LAZY_IMPORTER_FORCEINLINE unsafe_module_enumerator() noexcept 441 | : value(ldr_data_entry()) 442 | {} 443 | 444 | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = ldr_data_entry(); } 445 | 446 | LAZY_IMPORTER_FORCEINLINE bool next() noexcept 447 | { 448 | value = value->load_order_next(); 449 | return true; 450 | } 451 | }; 452 | 453 | // provides the cached functions which use Derive classes methods 454 | template 455 | class lazy_base { 456 | protected: 457 | // This function is needed because every templated function 458 | // with different args has its own static buffer 459 | LAZY_IMPORTER_FORCEINLINE static void*& _cache() noexcept 460 | { 461 | static void* value = nullptr; 462 | return value; 463 | } 464 | 465 | public: 466 | template 467 | LAZY_IMPORTER_FORCEINLINE static T safe() noexcept 468 | { 469 | return Derived::template get(); 470 | } 471 | 472 | template 473 | LAZY_IMPORTER_FORCEINLINE static T cached() noexcept 474 | { 475 | auto& cached = _cache(); 476 | if (!cached) 477 | cached = Derived::template get(); 478 | 479 | return (T)(cached); 480 | } 481 | 482 | template 483 | LAZY_IMPORTER_FORCEINLINE static T safe_cached() noexcept 484 | { 485 | return cached(); 486 | } 487 | }; 488 | 489 | template 490 | struct lazy_module : lazy_base> { 491 | template 492 | LAZY_IMPORTER_FORCEINLINE static T get() noexcept 493 | { 494 | Enum e; 495 | do { 496 | if (hash(e.value->BaseDllName) == Hash) 497 | return (T)(e.value->DllBase); 498 | } while (e.next()); 499 | return {}; 500 | } 501 | }; 502 | 503 | template 504 | struct lazy_function : lazy_base, T> { 505 | using base_type = lazy_base, T>; 506 | 507 | template 508 | LAZY_IMPORTER_FORCEINLINE decltype(auto) operator()(Args&&... args) const 509 | { 510 | #ifndef LAZY_IMPORTER_CACHE_OPERATOR_PARENS 511 | return get()(std::forward(args)...); 512 | #else 513 | return this->cached()(std::forward(args)...); 514 | #endif 515 | } 516 | 517 | template 518 | LAZY_IMPORTER_FORCEINLINE static F get() noexcept 519 | { 520 | // for backwards compatability. 521 | // Before 2.0 it was only possible to resolve forwarded exports when 522 | // this macro was enabled 523 | #ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS 524 | return forwarded(); 525 | #else 526 | Enum e; 527 | do { 528 | const exports_directory exports(e.value->DllBase); 529 | 530 | if (exports) { 531 | auto export_index = exports.size(); 532 | while (export_index--) 533 | if (hash(exports.name(export_index)) == Hash) 534 | return (F)(exports.address(export_index)); 535 | } 536 | } while (e.next()); 537 | return {}; 538 | #endif 539 | } 540 | 541 | template 542 | LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept 543 | { 544 | detail::win::UNICODE_STRING_T name; 545 | hash_t::value_type module_hash = 0; 546 | auto function_hash = Hash; 547 | 548 | Enum e; 549 | do { 550 | name = e.value->BaseDllName; 551 | name.Length -= 8; // get rid of .dll extension 552 | 553 | if (!module_hash || hash(name) == module_hash) { 554 | const exports_directory exports(e.value->DllBase); 555 | 556 | if (exports) { 557 | auto export_index = exports.size(); 558 | while (export_index--) 559 | if (hash(exports.name(export_index)) == function_hash) { 560 | const auto addr = exports.address(export_index); 561 | 562 | if (exports.is_forwarded(addr)) { 563 | auto hashes = hash_forwarded( 564 | reinterpret_cast(addr)); 565 | 566 | function_hash = hashes.second; 567 | module_hash = hashes.first; 568 | 569 | e.reset(); 570 | break; 571 | } 572 | return (F)(addr); 573 | } 574 | } 575 | } 576 | } while (e.next()); 577 | return {}; 578 | } 579 | 580 | template 581 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe() noexcept 582 | { 583 | return forwarded(); 584 | } 585 | 586 | template 587 | LAZY_IMPORTER_FORCEINLINE static F forwarded_cached() noexcept 588 | { 589 | auto& value = base_type::_cache(); 590 | if (!value) 591 | value = forwarded(); 592 | return (F)(value); 593 | } 594 | 595 | template 596 | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe_cached() noexcept 597 | { 598 | return forwarded_cached(); 599 | } 600 | 601 | template 602 | LAZY_IMPORTER_FORCEINLINE static F in(Module m) noexcept 603 | { 604 | if (IsSafe && !m) 605 | return {}; 606 | 607 | const exports_directory exports((const char*)(m)); 608 | if (IsSafe && !exports) 609 | return {}; 610 | 611 | for (unsigned long i{};; ++i) { 612 | if (IsSafe && i == exports.size()) 613 | break; 614 | 615 | if (hash(exports.name(i)) == Hash) 616 | return (F)(exports.address(i)); 617 | } 618 | return {}; 619 | } 620 | 621 | template 622 | LAZY_IMPORTER_FORCEINLINE static F in_safe(Module m) noexcept 623 | { 624 | return in(m); 625 | } 626 | 627 | template 628 | LAZY_IMPORTER_FORCEINLINE static F in_cached(Module m) noexcept 629 | { 630 | auto& value = base_type::_cache(); 631 | if (!value) 632 | value = in(m); 633 | return (F)(value); 634 | } 635 | 636 | template 637 | LAZY_IMPORTER_FORCEINLINE static F in_safe_cached(Module m) noexcept 638 | { 639 | return in_cached(m); 640 | } 641 | 642 | template 643 | LAZY_IMPORTER_FORCEINLINE static F nt() noexcept 644 | { 645 | return in(ldr_data_entry()->load_order_next()->DllBase); 646 | } 647 | 648 | template 649 | LAZY_IMPORTER_FORCEINLINE static F nt_safe() noexcept 650 | { 651 | return in_safe(ldr_data_entry()->load_order_next()->DllBase); 652 | } 653 | 654 | template 655 | LAZY_IMPORTER_FORCEINLINE static F nt_cached() noexcept 656 | { 657 | return in_cached(ldr_data_entry()->load_order_next()->DllBase); 658 | } 659 | 660 | template 661 | LAZY_IMPORTER_FORCEINLINE static F nt_safe_cached() noexcept 662 | { 663 | return in_safe_cached(ldr_data_entry()->load_order_next()->DllBase); 664 | } 665 | }; 666 | 667 | struct allow_all_modules { 668 | LAZY_IMPORTER_FORCEINLINE constexpr bool 669 | operator()(const win::LDR_DATA_TABLE_ENTRY_T*) const noexcept 670 | { 671 | return true; 672 | } 673 | }; 674 | 675 | template 676 | LAZY_IMPORTER_FORCEINLINE const char* find_nocache() noexcept 677 | { 678 | return find_nocache(Hash, allow_all_modules{}); 679 | } 680 | 681 | template 682 | LAZY_IMPORTER_FORCEINLINE const char* find_nocache(hash_t::value_type function_hash, ModuleFilter module_filter) noexcept 683 | { 684 | const auto* head = ldr_data_entry(); 685 | 686 | while (true) { 687 | if (module_filter(head)) { 688 | const exports_directory exports(head->DllBase); 689 | 690 | if (exports) 691 | for (auto i = 0u; i < exports.size(); ++i) 692 | if (hash(exports.name(i)) == function_hash) { 693 | const auto addr = exports.address(i); 694 | 695 | #ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS 696 | if (exports.is_forwarded(addr)) { 697 | auto hashes = 698 | hash_forwarded(reinterpret_cast(addr)); 699 | return find_nocache(hashes.second, 700 | modules_by_hash{ hashes.first }); 701 | } 702 | #endif 703 | return addr; 704 | } 705 | } 706 | 707 | head = head->load_order_next(); 708 | } 709 | } 710 | 711 | LAZY_IMPORTER_FORCEINLINE size_t module_size_safe(hash_t::value_type h) { 712 | const auto head = ldr_data_entry(); 713 | auto it = head; 714 | while (true) { 715 | if (hash(it->BaseDllName) == h) 716 | return it->SizeOfImage; 717 | 718 | if (it->InLoadOrderLinks.Flink == reinterpret_cast(head)) 719 | return 0; 720 | 721 | it = it->load_order_next(); 722 | } 723 | } 724 | 725 | LAZY_IMPORTER_FORCEINLINE const char* module_handle_safe(hash_t::value_type h) { 726 | const auto head = ldr_data_entry(); 727 | auto it = head; 728 | while (true) { 729 | if (hash(it->BaseDllName) == h) 730 | return it->DllBase; 731 | 732 | if (it->InLoadOrderLinks.Flink == reinterpret_cast(head)) 733 | return 0; 734 | 735 | it = it->load_order_next(); 736 | } 737 | } 738 | } 739 | } // namespace li::detail 740 | 741 | #endif // include guard -------------------------------------------------------------------------------- /hooks.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "memory/il2cpp.hpp" 3 | #include "settings.hpp" 4 | #include "offsets.h" 5 | #include 6 | #include "Keybind.h" 7 | 8 | namespace hooks { 9 | namespace orig { 10 | static auto baseplayer_client_input = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("ClientInput"), -1, _(""), _("")))); 11 | static auto BaseProjectile_OnSignal = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BaseProjectile"), _("OnSignal"), 2, _(""), _("")))); 12 | static auto playerwalkmovement_client_input = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("PlayerWalkMovement"), _("ClientInput"), -1, _(""), _("")))); 13 | static auto DoFixedUpdate = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("PlayerWalkMovement"), _("DoFixedUpdate"), -1, _(""), _("")))); 14 | static auto blocksprint = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("BlockSprint"), 1, _(""), _("")))); 15 | static auto OnNetworkMessage = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Client"), _("OnNetworkMessage"), 1, _(""), _("")))); 16 | static auto IsConnected = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Client"), _("IsConnected"), 0, _(""), _("Network")))); 17 | static auto Run = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("ConsoleSystem"), _("Run"), 3, _(""), _("")))); 18 | 19 | uintptr_t playerprojectileattack; 20 | uintptr_t serverrpc_projectileshoot; 21 | uintptr_t serverrpc_processattack; 22 | } 23 | 24 | static auto serverrpc_projecileshoot = rb::pattern::find_rel(// 25 | _("GameAssembly.dll"), _("4C 8B 0D ? ? ? ? 48 8B 75 28")); 26 | 27 | static auto serverrpc_uint = rb::pattern::find_rel( 28 | _("GameAssembly.dll"), _("74 3A 4C 8B 0D ? ? ? ? 48 8B CB")); 29 | 30 | static auto set_sprinting = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("ModelState"), _("set_sprinting"), -1, _(""), _("")))); 31 | 32 | static auto draw_get = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("DDraw"), _("Get"), 0, _(""), _("UnityEngine")))); 33 | 34 | static auto set_flying = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("ModelState"), _("set_flying"), 1, _(""), _("")))); 35 | 36 | static auto GetSpeed = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("GetSpeed"), 2, _(""), _("")))); 37 | 38 | static auto get_ducked = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("ModelState"), _("get_ducked"), 0, _(""), _("")))); 39 | 40 | static auto IsSwimming = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("IsSwimming"), 0, _(""), _("")))); 41 | 42 | static auto ServerRPC = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BaseEntity"), _("ServerRPC"), 1, _("funcName"), _(""), 1))); 43 | 44 | static auto OnLand = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("OnLand"), 1, _("fVelocity"), _(""), 1))); 45 | 46 | static auto change_code_rpc = reinterpret_cast(mem::game_assembly_base + offsets::BaseEntity$$ServerRPC_string_bool_Address); //BaseEntity$$ServerRPC Address 47 | 48 | static auto ServerRPC_int = reinterpret_cast(mem::game_assembly_base + offsets::BaseEntity$$ServerRPC_uint_); 49 | 50 | static auto DoHit = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Projectile"), _("DoHit"), 4, _(""), _("")))); 51 | 52 | void init_hooks() { 53 | orig::IsConnected = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Client"), _("IsConnected"), 0, _(""), _("Network")))); 54 | orig::OnNetworkMessage = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Client"), _("OnNetworkMessage"), 1, _(""), _("")))); 55 | orig::BaseProjectile_OnSignal = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BaseProjectile"), _("OnSignal"), 2, _(""), _("")))); 56 | orig::baseplayer_client_input = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("ClientInput"), -1, _(""), _("")))); 57 | orig::playerwalkmovement_client_input = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("PlayerWalkMovement"), _("ClientInput"), -1, _(""), _("")))); 58 | orig::DoFixedUpdate = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("PlayerWalkMovement"), _("DoFixedUpdate"), -1, _(""), _("")))); 59 | orig::blocksprint = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("BlockSprint"), 1, _(""), _("")))); 60 | 61 | serverrpc_projecileshoot = rb::pattern::find_rel( 62 | _("GameAssembly.dll"), _("4C 8B 0D ? ? ? ? 48 8B 75 28")); 63 | 64 | serverrpc_uint = rb::pattern::find_rel( 65 | _("GameAssembly.dll"), _("74 3A 4C 8B 0D ? ? ? ? 48 8B CB")); 66 | 67 | ServerRPC_int = reinterpret_cast(mem::game_assembly_base + offsets::BaseEntity$$ServerRPC_uint_); 68 | 69 | change_code_rpc = reinterpret_cast(mem::game_assembly_base + offsets::BaseEntity$$ServerRPC_string_bool_Address); 70 | 71 | set_sprinting = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("ModelState"), _("set_sprinting"), -1, _(""), _("")))); 72 | 73 | draw_get = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("DDraw"), _("Get"), 0, _(""), _("UnityEngine")))); 74 | 75 | set_flying = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("ModelState"), _("set_flying"), 1, _(""), _("")))); 76 | 77 | GetSpeed = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("GetSpeed"), 2, _(""), _("")))); 78 | 79 | get_ducked = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("ModelState"), _("get_ducked"), 0, _(""), _("")))); 80 | 81 | IsSwimming = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("IsSwimming"), 0, _(""), _("")))); 82 | 83 | ServerRPC = ServerRPC = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BaseEntity"), _("ServerRPC"), 1, _("funcName"), _(""), 1))); 84 | 85 | OnLand = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("BasePlayer"), _("OnLand"), 1, _("fVelocity"), _(""), 1))); 86 | 87 | DoHit = reinterpret_cast(*reinterpret_cast(il2cpp::method(_("Projectile"), _("DoHit"), 4, _(""), _("")))); 88 | } 89 | 90 | double CalcBulletDrop(double height, double DepthPlayerTarget, float velocity, float gravity) { 91 | double pitch = (vector3::my_atan2(height, DepthPlayerTarget)); 92 | double BulletVelocityXY = velocity * vector3::my_cos(pitch); 93 | double Time = DepthPlayerTarget / BulletVelocityXY; 94 | double TotalVerticalDrop = (0.5f * gravity * Time * Time); 95 | return TotalVerticalDrop * 10; 96 | } 97 | 98 | void Prediction(vector3 local, vector3& target, vector3 targetvel, float bulletspeed, float gravity) { 99 | float Dist = local.get_3d_dist(target); 100 | float BulletTime = Dist / bulletspeed; 101 | 102 | vector3 vel = vector3(targetvel.x, 0, targetvel.z) * 0.75f; 103 | 104 | vector3 PredictVel = vel * BulletTime; 105 | 106 | target += PredictVel; 107 | 108 | double height = target.y - local.y; 109 | vector3 dir = target - local; 110 | float DepthPlayerTarget = vector3::my_sqrt(powFFFFFFFFFFFFFFFFFFFFFF(dir.x) + powFFFFFFFFFFFFFFFFFFFFFF(dir.z)); 111 | 112 | float drop = CalcBulletDrop(height, DepthPlayerTarget, bulletspeed, gravity); 113 | 114 | target.y += drop; 115 | } 116 | 117 | #pragma optimize("", off) 118 | #pragma code_seg(".text") 119 | inline int64_t get_rbx_value() 120 | { 121 | static __declspec(allocate(".text")) char fn_stub[] = { 122 | 0x48, 123 | 0x89, 124 | 0xD8, // mov rax,rbx 125 | 0xc3 // ret 126 | }; 127 | 128 | return ((int64_t(*)())(&fn_stub))(); 129 | } 130 | #pragma code_seg(pop) 131 | #pragma optimize("", on) 132 | 133 | ////////////////////////// 134 | ///////// PSILENT //////// 135 | ////////////////////////// 136 | void hk_serverrpc_projectileshoot(int64_t rcx, int64_t rdx, int64_t r9, int64_t projectileShoot, int64_t arg5) { 137 | do { 138 | if (!esp::local_player) 139 | break; 140 | 141 | auto weapon = esp::local_player->get_active_weapon(); 142 | 143 | if (!weapon) 144 | break; 145 | 146 | auto baseprojectile = esp::local_player->get_active_weapon()->get_base_projetile(); 147 | if (!baseprojectile) 148 | break; 149 | 150 | auto wep_class_name = *(const char**)(*(uintptr_t*)(uintptr_t)baseprojectile + 0x10); 151 | if (*(int*)(wep_class_name + 4) == 'eleM' || *(int*)(wep_class_name) == 'ddaP') 152 | break; 153 | 154 | base_projectile* projectile_list = *reinterpret_cast( 155 | *reinterpret_cast((uintptr_t)baseprojectile + 0x358) + 0x10); //createdProjectiles; 156 | 157 | esp::matrix = unity::get_view_matrix(); 158 | auto camera_pos = unity::get_camera_pos(); 159 | 160 | aim_target target = esp::local_player->get_aimbot_target(camera_pos); 161 | 162 | uintptr_t shoot_list = *(uintptr_t*)(*(uintptr_t*)(projectileShoot + 0x18) + 0x10); 163 | 164 | auto size = *(int*)(*(uintptr_t*)(projectileShoot + 0x18) + 0x18); 165 | 166 | vector3 aimbot_velocity; 167 | 168 | const auto stats = baseprojectile->get_stats(weapon->get_item_definition_id()); 169 | 170 | vector3 aim_angle; 171 | vector3 rpc_position; 172 | 173 | 174 | 175 | for (int i = 0; i < size; i++) { 176 | auto projectile = *(uintptr_t*)(shoot_list + 0x20 + i * 0x8); 177 | 178 | rpc_position = *reinterpret_cast(projectile + 0x18); 179 | auto original_vel = *reinterpret_cast(projectile + 0x24); 180 | 181 | if (target.player && target.visible && !target.teammate) { 182 | Prediction(rpc_position, target.pos, target.velocity, original_vel.Length(), stats.gravity_modifier); 183 | 184 | aim_angle = /*get_aim_angle(rpc_position, target.pos, target.velocity, false, stats)*/target.pos - rpc_position; 185 | 186 | aimbot_velocity = (aim_angle).Normalized() * original_vel.Length(); 187 | 188 | *reinterpret_cast(projectile + 0x24) = aimbot_velocity; 189 | } 190 | } 191 | 192 | for (int i = 0; i < projectile_list->get_size(); i++) { 193 | auto projectile = *(base_projectile**)((uintptr_t)projectile_list + 0x20 + i * 0x8); 194 | 195 | if (!projectile) 196 | continue; 197 | if (!keybinds::psilentb || unity::GetKey(keybinds::psilentk)) { 198 | if (settings::weapon::psilent) { 199 | if (target.player && !target.teammate) { 200 | if (!settings::weapon::psilentvis || target.visible) { 201 | projectile->set_current_velocity(aimbot_velocity); 202 | } 203 | } 204 | } 205 | } 206 | 207 | 208 | if (settings::weapon::mods) { 209 | 210 | auto ItemModProjectile = projectile->get_item_mod_projectile(); 211 | 212 | ItemModProjectile->projectileSpread() = 0; 213 | ItemModProjectile->projectileVelocitySpread() = 0; 214 | } 215 | 216 | if (settings::weapon::thick_bullet) 217 | projectile->set_projectile_thickness(settings::weapon::thickness); 218 | else 219 | projectile->set_projectile_thickness(projectile->thickness); 220 | ///////////////////////////// 221 | ////////DOESNT WORK////////// 222 | ///////////////////////////// 223 | 224 | 225 | 226 | //if (!projectile->first) { 227 | // projectile->thickness = projectile->get_projectile_thickness(); 228 | // projectile->first = true; 229 | //} 230 | 231 | 232 | 233 | 234 | 235 | } 236 | } while (0); 237 | 238 | reinterpret_cast(hooks::orig::serverrpc_projectileshoot)(rcx, rdx, r9, projectileShoot, arg5); 239 | } 240 | 241 | bool is_lagging; 242 | 243 | bool flying = false, is_speeding = false; 244 | 245 | bool has_intialized_methods = false; 246 | 247 | float nextActionTime = 0, period = 1.4721; 248 | 249 | 250 | void hk_serverrpc_playerprojectileattack(int64_t rcx, int64_t rdx, int64_t r9, int64_t _ppa, int64_t arg5) { 251 | auto projectile = reinterpret_cast(get_rbx_value()); 252 | auto ppa = reinterpret_cast(_ppa); 253 | auto& attack = ppa->playerAttack->attack; 254 | 255 | const auto orig_fn = 256 | reinterpret_cast( 257 | hooks::orig::playerprojectileattack); 258 | 259 | auto camera_pos = unity::get_camera_pos(); 260 | if (camera_pos.is_empty()) 261 | return orig_fn(rcx, rdx, r9, _ppa, arg5); 262 | 263 | do { 264 | if (!esp::local_player) 265 | break; 266 | 267 | auto hit_test = projectile->get_hit_test(); 268 | if (!hit_test) 269 | break; 270 | 271 | if (!hit_test->get_gameobject()) 272 | break; 273 | 274 | auto layer = hit_test->get_gameobject()->get_layer(); 275 | auto prefab_name = hit_test->get_gameobject()->get_prefab_name(); 276 | 277 | aim_target target = esp::local_player->get_aimbot_target(camera_pos); 278 | 279 | if (!target.player || !target.network_id) 280 | break; 281 | 282 | auto& hit_entity = hit_test->get_hit_entity(); 283 | if (layer == rust::classes::layer::Player_Server) { 284 | if (hit_entity->is_teammate(esp::local_player)) { 285 | hit_test->set_ignore_entity(hit_entity); 286 | return; 287 | } 288 | } 289 | 290 | if (!settings::weapon::hitbox_override && !settings::weapon::random_hitbox) 291 | break; 292 | 293 | 294 | if (!target.is_heli && settings::weapon::hitbox_override) { 295 | attack->hitBone = 698017942; 296 | attack->hitPartID = 2173623152; 297 | attack->hitPositionLocal = { -.1f, -.1f, 0 }; 298 | attack->hitNormalLocal = { 0, -1, 0 }; 299 | } 300 | else if (!target.is_heli && settings::weapon::random_hitbox) { 301 | switch (my_rand() % 4) { 302 | case 0: // Head 303 | attack->hitBone = 698017942; 304 | attack->hitPartID = 2173623152; 305 | break; 306 | case 1: // Chest 307 | attack->hitBone = 1031402764; 308 | attack->hitPartID = 1750816991; 309 | break; 310 | case 2: // LHand 311 | attack->hitBone = 182688154; 312 | attack->hitPartID = 1750816991; 313 | break; 314 | case 3: // RHand 315 | attack->hitBone = 102231371; 316 | attack->hitPartID = 1750816991; 317 | break; 318 | } 319 | attack->hitPositionLocal = { -.1f, -.1f, 0 }; 320 | attack->hitNormalLocal = { 0, -1, 0 }; 321 | } 322 | else { 323 | auto weakspots = target.player->get_weakspots(); 324 | if (!weakspots) 325 | break; 326 | 327 | auto size = *reinterpret_cast(weakspots + 0x18); 328 | 329 | bool tail_alive = false; 330 | bool main_alive = false; 331 | for (int i = 0; i < size; i++) { 332 | auto weakspot = *(uintptr_t*)(weakspots + 0x20 + i * 0x8); 333 | if (!weakspot) 334 | continue; 335 | auto health = *reinterpret_cast(weakspot + 0x24); 336 | if (health > 0) { 337 | if (i == 0) { 338 | main_alive = true; 339 | } 340 | else { 341 | tail_alive = true; 342 | } 343 | } 344 | } 345 | 346 | if (tail_alive) { 347 | attack->hitBone = 2699525250; 348 | attack->hitPartID = 2306822461; 349 | attack->hitPositionLocal = { .9f, -.4f, .1f }; 350 | attack->hitNormalLocal = { .9f, -.4f, .1f }; 351 | } 352 | else if (main_alive) { 353 | attack->hitBone = 224139191; 354 | attack->hitPartID = 2306822461; 355 | attack->hitPositionLocal = { .9f, -.4f, .1f }; 356 | attack->hitNormalLocal = { .9f, -.4f, .1f }; 357 | } 358 | } 359 | } while (0); 360 | 361 | return orig_fn(rcx, rdx, r9, _ppa, arg5); 362 | } 363 | 364 | // 365 | //void hk_baseprojectile_OnSignal(base_projectile* baseprojectile, int signal , rust::classes::string string) { 366 | // orig::BaseProjectile_OnSignal(baseprojectile, signal, string); 367 | // 368 | // if (settings::visuals::raid_esp) { 369 | // auto reusableInstace = il2cpp::value(_("Effect"), _("reusableInstace"), false); 370 | // 371 | // auto draw_explosion = [&](const char* explosion_name) { 372 | // auto world_position = *reinterpret_cast(reusableInstace + 0x5C); 373 | // vector2 w2s_position = {}; 374 | // if (esp::out_w2s(world_position, w2s_position)) { 375 | // esp::draw_item(w2s_position, il2cpp::methods::new_string(_("Rocket Explosion")), { 255,0,0,255 }); 376 | // } 377 | // }; 378 | // 379 | // if (reusableInstace) { 380 | // auto world_position = *reinterpret_cast(reusableInstace + 0x78); 381 | // 382 | // auto esp_name = (str)(*reinterpret_cast(reusableInstace + 0x88)); 383 | // auto name = esp_name->str; 384 | // 385 | // LOG("Prefab names: %ls", name); 386 | // 387 | // if (m_wcsicmp(name, _(L"assets/prefabs/weapons/rocketlauncher/effects/rocket_explosion.prefab"))) { 388 | // draw_explosion(_("Rocket Explosion")); 389 | // } 390 | // else if (m_wcsicmp(name, _(L"assets/prefabs/tools/c4/effects/c4_explosion.prefab"))) { 391 | // draw_explosion(_("C4 Explosion")); 392 | // } 393 | // } 394 | // } 395 | //} 396 | 397 | #define ptr_assert(val) \ 398 | if(val == 0) \ 399 | return 400 | uintptr_t client_entities; 401 | 402 | void hk_dofixedupdate(playerwalkmovement* base_movement, modelstate* modelstate) { 403 | if (esp::local_player && settings::misc::always_sprint && settings::misc::Movement) { 404 | bool is_busy = get_ducked(modelstate) | IsSwimming(esp::local_player); 405 | 406 | float speed = GetSpeed(esp::local_player, 1, is_busy); 407 | 408 | vector3 vel = *reinterpret_cast(base_movement + 0x34); // private Vector3 k__BackingField; 409 | vector3 xz = vector3(vel.x, 0, vel.z).normalize() * speed; 410 | vel = vector3(xz.x, vel.y, xz.z); 411 | 412 | if (!flying) { 413 | *reinterpret_cast(base_movement + 0x34) = vel; 414 | 415 | set_sprinting(modelstate, true); 416 | } 417 | } 418 | 419 | orig::DoFixedUpdate(base_movement, modelstate); 420 | } 421 | 422 | void hk_blocksprint(base_player* player, float duration) { 423 | if (!settings::weapon::always_shoot && settings::misc::Movement) 424 | return hooks::orig::blocksprint(player, duration); 425 | 426 | return; 427 | } 428 | 429 | void draw_raid() 430 | { 431 | auto effect_network = il2cpp::init_class(_("EffectNetwork")); 432 | if (!effect_network) 433 | return; 434 | 435 | auto effect = *reinterpret_cast(effect_network + 0xB8); 436 | if (!effect) 437 | { 438 | LOG("Effect null..."); 439 | return; 440 | } 441 | 442 | effect = *reinterpret_cast(effect); 443 | if (!effect) 444 | { 445 | LOG("Effect1 null..."); 446 | return; 447 | } 448 | 449 | auto world_pos = *reinterpret_cast(effect + 0x5C); 450 | if (world_pos.is_empty()) 451 | { 452 | LOG("world_pos.is_empty()"); 453 | return; 454 | } 455 | 456 | auto pooled_str = (str)(*reinterpret_cast(effect + 0x88)); 457 | auto pooledString = pooled_str->str; 458 | 459 | uintptr_t m_szTranslated; 460 | 461 | //assets/prefabs/ammo/rifle/riflebullet_explosive.prefab 462 | 463 | LOG("pooledString: %ls", pooled_str); 464 | } 465 | 466 | void hk_OnNetworkMessage(uintptr_t client, uintptr_t packet) 467 | { 468 | draw_raid(); 469 | orig::OnNetworkMessage(client, packet); 470 | } 471 | 472 | void get_skydome() 473 | { 474 | uintptr_t m_skydome = NULL; 475 | uintptr_t m_camera = NULL; 476 | uintptr_t last_object = NULL; 477 | { 478 | auto gom = mem::read(mem::unity_player_base + 0x17C1F18); 479 | auto current_tagged_base = mem::read(gom + 0x08 ); 480 | auto current_tagged_obj = mem::read(current_tagged_base + 0x10); 481 | 482 | while (current_tagged_obj && 483 | current_tagged_obj != last_object && 484 | (!m_skydome || !m_camera)) { 485 | INT16 tag = mem::read(current_tagged_obj + 0x54); 486 | 487 | if (!m_camera) { 488 | if (tag == 5) { 489 | uintptr_t objClass = mem::read(current_tagged_obj + 0x30); 490 | 491 | uintptr_t ent = mem::read(objClass + 0x18); 492 | 493 | m_camera = mem::read(current_tagged_obj + 0x18); 494 | } 495 | } 496 | 497 | 498 | if (!m_skydome) 499 | { 500 | if (tag == 20011) { 501 | uint64_t p = mem::read(current_tagged_obj + 0x30); 502 | uint64_t p1 = mem::read(p + 0x18); 503 | uint64_t p2 = mem::read(p1 + 0x28); 504 | 505 | const auto TOD_Day = *reinterpret_cast(p2 + 0x50); 506 | const auto TOD_Night = *reinterpret_cast(p2 + 0x58); 507 | const auto TOD_Stars = *reinterpret_cast(p2 + 0x70); 508 | if (settings::misc::brightnight) { 509 | *(float*)(TOD_Night + 0x50) = 4.f; 510 | *(float*)(TOD_Night + 0x54) = 1.f; 511 | *(float*)(TOD_Day + 0x50) = 1.f; 512 | *(float*)(TOD_Day + 0x54) = 1.f; 513 | *(float*)(TOD_Stars + 0x14) = settings::misc::staramount; 514 | } 515 | 516 | 517 | m_skydome = mem::read(current_tagged_obj + 0x18); 518 | } 519 | } 520 | last_object = current_tagged_obj; 521 | current_tagged_base = mem::read(current_tagged_base + 0x8); 522 | current_tagged_obj = mem::read(current_tagged_base + 0x10); 523 | } 524 | } 525 | } 526 | 527 | vector3 m_debugcam_toggle_pos; 528 | vector3 m_debugcam_pos; 529 | 530 | void hk_playerwalkmovement_ClientInput(playerwalkmovement* player_walk_movement, uintptr_t inputstate, modelstate* model_state) { 531 | orig::playerwalkmovement_client_input(player_walk_movement, inputstate, model_state); 532 | 533 | set_sprinting(model_state, true); 534 | 535 | flying = player_walk_movement->get_flying(); 536 | 537 | if (!keybinds::silentwalkb || unity::GetKey(keybinds::silentwalkk)) { 538 | if (settings::misc::silentwalk) { 539 | set_onLadder(model_state, true); 540 | } 541 | } 542 | model_state->remove_flag(rust::classes::ModelState_Flag::Flying); 543 | } 544 | 545 | uintptr_t do_fixed_update_ptr, client_input_ptr; 546 | 547 | 548 | 549 | void hk_baseplayer_ClientInput(base_player* baseplayer, input_state* state) { 550 | if(!do_fixed_update_ptr) 551 | do_fixed_update_ptr = mem::hook_virtual_function(_("PlayerWalkMovement"), _("DoFixedUpdate"), &hk_dofixedupdate); 552 | 553 | if(!client_input_ptr) 554 | client_input_ptr = mem::hook_virtual_function(_("PlayerWalkMovement"), _("ClientInput"), &hk_playerwalkmovement_ClientInput); 555 | 556 | if (!has_intialized_methods) { 557 | auto il2cpp_codegen_initialize_method = reinterpret_cast(il2cpp::methods::intialize_method); 558 | //56229 for real rust or 56204 for cracked rust 559 | for (int i = 0; i < 560 | #ifdef cracked_rust 561 | 56204 562 | #else 563 | 56229 564 | #endif 565 | ; i++) { 566 | il2cpp_codegen_initialize_method(i); 567 | } 568 | has_intialized_methods = true; 569 | } 570 | 571 | static uintptr_t* serverrpc_projecshoot; 572 | if (!serverrpc_projecshoot) { 573 | auto method_serverrpc_projecshoot = *reinterpret_cast(hooks::serverrpc_projecileshoot); 574 | 575 | if (method_serverrpc_projecshoot) { 576 | serverrpc_projecshoot = **(uintptr_t***)(method_serverrpc_projecshoot + 0x30); 577 | 578 | hooks::orig::serverrpc_projectileshoot = *serverrpc_projecshoot; 579 | 580 | *serverrpc_projecshoot = reinterpret_cast(&hooks::hk_serverrpc_projectileshoot); 581 | } 582 | } 583 | 584 | static uintptr_t* serverrpc_playerprojectileattack; 585 | if (!serverrpc_playerprojectileattack) { 586 | auto method_serverrpc_playerprojectileattack = *reinterpret_cast(mem::game_assembly_base + offsets::Method$BaseEntity_ServerRPC_PlayerProjectileAttack___);//Method$BaseEntity_ServerRPC_PlayerProjectileAttack___ 587 | 588 | if (method_serverrpc_playerprojectileattack) { 589 | serverrpc_playerprojectileattack = **(uintptr_t***)(method_serverrpc_playerprojectileattack + 0x30); 590 | 591 | hooks::orig::playerprojectileattack = *serverrpc_playerprojectileattack; 592 | 593 | *serverrpc_playerprojectileattack = reinterpret_cast(&hooks::hk_serverrpc_playerprojectileattack); 594 | } 595 | } 596 | 597 | if (baseplayer) { 598 | get_skydome(); 599 | 600 | if (settings::misc::attack_on_mountables) { 601 | auto mountable = baseplayer->get_mountable(); 602 | if (mountable) 603 | mountable->canwielditem() = true; 604 | } 605 | 606 | bool kyslol = false; 607 | 608 | if (settings::misc::TakeFallDamage && unity::GetKey(rust::classes::KeyCode::P)) { 609 | 610 | OnLand(baseplayer, -8.0001f - 100); 611 | } 612 | 613 | 614 | 615 | if (settings::misc::admin_mode) 616 | baseplayer->set_admin_flag(rust::classes::PlayerFlags::IsAdmin); 617 | 618 | if (settings::misc::spiderman && settings::misc::Movement) { 619 | baseplayer->SpiderMan(); 620 | 621 | } 622 | 623 | if (settings::misc::playerfovtoggle) { 624 | baseplayer->fov(); 625 | 626 | } 627 | 628 | 629 | 630 | if (!keybinds::fakelagb || unity::GetKey(keybinds::fakelagk)) { 631 | if (!is_lagging && !flying && settings::misc::fake_lag && !is_speeding) { 632 | baseplayer->set_client_tick_interval(0.2f); 633 | is_lagging = true; 634 | } 635 | } 636 | else if (is_lagging && flying || is_lagging && is_speeding) { 637 | esp::local_player->set_client_tick_interval(0.03f); 638 | is_lagging = false; 639 | } 640 | else if (is_lagging && !settings::misc::fake_lag) { 641 | esp::local_player->set_client_tick_interval(0.03f); 642 | is_lagging = false; 643 | } 644 | 645 | 646 | if (auto movement = baseplayer->get_movement()) { 647 | if (settings::misc::spiderman) { 648 | movement->set_ground_angles_new(0); 649 | 650 | } 651 | 652 | } 653 | 654 | if (settings::misc::eyeoffset) { 655 | baseplayer->Giraffe(); 656 | 657 | } 658 | 659 | if (auto movement = baseplayer->get_movement()) { 660 | if (settings::misc::infinite_jump && settings::misc::Movement) { 661 | movement->set_land_time(0); 662 | movement->set_jump_time(0); 663 | movement->set_ground_time(100000); 664 | } 665 | 666 | if (settings::misc::gravity && settings::misc::Movement) 667 | movement->set_gravity_multiplier(1.75f); 668 | else 669 | movement->set_gravity_multiplier(2.35f); 670 | 671 | if (settings::weapon::always_shoot && settings::misc::Movement) { 672 | if (auto modelstate = baseplayer->get_model_state()) { 673 | modelstate->set_flag(rust::classes::ModelState_Flag::OnGround); 674 | mem::write((uint64_t)movement + 0x4C, 1); //private float k__BackingField; // 0x4C 675 | } 676 | } 677 | } 678 | 679 | auto item = baseplayer->get_active_weapon(); 680 | 681 | if (settings::misc::auto_lock) { 682 | auto closest_ent = baseplayer->resolve_closest_entity(3); 683 | 684 | auto addr = mem::read(mem::game_assembly_base + offsets::Method_BaseEntity_ServerRPC_string_bool_address); //Method$BaseEntity.ServerRPC() address 685 | 686 | if (closest_ent.first.found && addr) { 687 | if (closest_ent.second) { 688 | auto code_str = string::format(_("%d"), (int)settings::misc::code_lock_code); 689 | change_code_rpc(closest_ent.first.player, rust::classes::string(_(L"RPC_ChangeCode")), il2cpp::methods::new_string(code_str), false, addr); 690 | ServerRPC((uintptr_t)closest_ent.first.player, rust::classes::string(_(L"TryLock"))); 691 | ServerRPC((uintptr_t)closest_ent.first.player, rust::classes::string(_(L"RPC_Lock"))); 692 | } 693 | else 694 | ServerRPC((uintptr_t)closest_ent.first.player, rust::classes::string(_(L"RPC_Lock"))); 695 | } 696 | } 697 | if (!keybinds::speedhackb || unity::GetKey(keybinds::speedhackk)) { 698 | if (settings::misc::speedhack && settings::misc::Movement) { 699 | set_timeScale(settings::misc::speedhackspeed); 700 | is_speeding = true; 701 | } 702 | } 703 | 704 | 705 | 706 | else if (!keybinds::speedkeyb || unity::GetKey(rust::classes::KeyCode::Mouse0)) { 707 | if (settings::weapon::fastshoot) { 708 | set_timeScale(1.2); 709 | is_speeding = true; 710 | } 711 | } 712 | else { 713 | set_timeScale(1); 714 | is_speeding = false; 715 | } 716 | 717 | if (item) { 718 | auto baseprojectile = item->get_base_projetile(); 719 | if (baseprojectile) { 720 | auto wep_class_name = *(const char**)(*(uintptr_t*)(uintptr_t)baseprojectile + 0x10); 721 | 722 | auto attack = [&](aim_target target, bool is_tree) { 723 | auto gathering = baseprojectile->Gathering(); 724 | 725 | if (is_tree) { 726 | if (!(gathering->tree()->gatherDamage() > 1)) { 727 | return; 728 | } 729 | } 730 | else { 731 | if (!(gathering->ore()->gatherDamage() > 1)) { 732 | return; 733 | } 734 | } 735 | 736 | attack_melee(target, baseprojectile); 737 | }; 738 | 739 | if (settings::misc::silent_farm) { 740 | auto entity = baseplayer->resolve_closest_entity(3, false); 741 | if (entity.first.found && entity.first.player) { 742 | if (*(int*)(wep_class_name + 4) == 'eleM' || *(int*)(wep_class_name + 4) == 'mmah') { 743 | attack(entity.first, entity.second); 744 | } 745 | } 746 | } 747 | 748 | if (!(*(int*)(wep_class_name + 4) == 'eleM' && *(int*)(wep_class_name) == 'esaB')) { 749 | if (unity::GetKey(rust::classes::KeyCode::Mouse0) && settings::misc::instant_med) { 750 | const auto item_id = item->get_item_definition_id(); 751 | 752 | if (item_id == 1079279582 || item_id == -2072273936) { 753 | auto time = get_time(); 754 | if (baseprojectile->get_time_since_deploy() > baseprojectile->get_deploy_delay() && baseprojectile->get_next_attack_time() <= get_time()) { 755 | if (time > nextActionTime) { 756 | nextActionTime = time + period; 757 | ServerRPC((uintptr_t)baseprojectile, rust::classes::string(_(L"UseSelf"))); 758 | } 759 | } 760 | } 761 | } 762 | else if (unity::GetKey(rust::classes::KeyCode::Mouse1) && settings::misc::instant_med) { 763 | const auto item_id = item->get_item_definition_id(); 764 | 765 | if (item_id == 1079279582 || item_id == -2072273936) { 766 | esp::matrix = unity::get_view_matrix(); 767 | auto camera_pos = unity::get_camera_pos(); 768 | 769 | auto target = baseplayer->get_aimbot_target(camera_pos); 770 | 771 | if (target.player && target.distance < 5) { 772 | auto net = target.player->get_networkable(); 773 | if (net) { 774 | auto id = net->get_id(); 775 | if (id) { 776 | 777 | auto method_addr = mem::read(mem::game_assembly_base + offsets::Method$BaseEntity_ServerRPC_uint); 778 | if (method_addr) { 779 | auto time = get_time(); 780 | if (baseprojectile->get_time_since_deploy() > baseprojectile->get_deploy_delay() && baseprojectile->get_next_attack_time() <= get_time()) { 781 | if (time > nextActionTime) { 782 | nextActionTime = time + period; 783 | ServerRPC_int(baseprojectile, rust::classes::string(_(L"UseOther")), id, method_addr); 784 | } 785 | } 786 | } 787 | } 788 | } 789 | } 790 | } 791 | } 792 | 793 | //////weapon mods///// 794 | if (*(int*)(wep_class_name) == 'esaB' && *(int*)(wep_class_name + 4) == 'jorP' || *(int*)(wep_class_name) == 'nilF') { 795 | if (item->is_weapon()) { 796 | const auto item_id = item->get_item_definition_id(); 797 | 798 | switch (item_id) { 799 | case -75944661: 800 | if (settings::weapon::weapon_removals) { 801 | mem::write((uint64_t)baseprojectile + 0x360, 1.f); 802 | } 803 | break; 804 | default: 805 | if (settings::weapon::weapon_removals) { 806 | if (settings::weapon::fast_bullet && !settings::weapon::ultraBullet) 807 | 808 | if (item_id != 1318558775) 809 | baseprojectile->projectileVelocityScale() = 1.4f; 810 | else 811 | baseprojectile->projectileVelocityScale() = 1.2f; 812 | if (settings::weapon::ultraBullet) 813 | baseprojectile->projectileVelocityScale() = 10.f; 814 | if (settings::weapon::automatic) 815 | baseprojectile->is_automatic() = true; 816 | if (settings::weapon::nospread) 817 | baseprojectile->set_no_spread(); 818 | if (settings::weapon::norecoil) 819 | baseprojectile->set_recoil(0, 0, 0, 0); 820 | if (settings::weapon::legit_recoil) 821 | baseprojectile->set_recoil(1, 1, -1, 0); 822 | if (settings::weapon::nosway) 823 | baseprojectile->set_no_sway(); 824 | } 825 | break; 826 | 827 | } 828 | } 829 | } 830 | } 831 | } 832 | } 833 | 834 | if (settings::misc::instant_revive) { 835 | auto target = baseplayer->get_aimbot_target(unity::get_camera_pos()); 836 | if (!target.is_heli && target.player && target.distance <= 5 && target.player->get_health() <= 4 && target.visible) 837 | ServerRPC((uintptr_t)target.player, rust::classes::string(_(L"RPC_Assist"))); 838 | } 839 | 840 | unity::IgnoreLayerCollision(rust::classes::layer::PlayerMovement, rust::classes::layer::Water, !settings::misc::no_playercollision); 841 | unity::IgnoreLayerCollision(rust::classes::layer::PlayerMovement, rust::classes::layer::Tree, settings::misc::no_playercollision); 842 | unity::IgnoreLayerCollision(rust::classes::layer::PlayerMovement, rust::classes::layer::AI, settings::misc::no_playercollision); 843 | 844 | draw_get(); 845 | 846 | auto tick_time = baseplayer->get_last_sent_ticket_time(); 847 | if (tick_time > gui::tick_time_when_called + 10) { 848 | unity::camera = unity::get_main_camera(); 849 | gui::tick_time_when_called = tick_time; 850 | } 851 | } 852 | 853 | orig::baseplayer_client_input(baseplayer, state); 854 | 855 | auto model_state = baseplayer->get_model_state(); 856 | 857 | //model_state->set_water_level(99999); 858 | 859 | if (settings::misc::spinbot) { 860 | state->set_aim_angles(vector3(100, my_rand() % 999 + -999, 100)); 861 | } 862 | } 863 | } --------------------------------------------------------------------------------