diff options
Diffstat (limited to 'src/hl2h.cpp')
| -rw-r--r-- | src/hl2h.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/hl2h.cpp b/src/hl2h.cpp index f95f6ed..ebb9b14 100644 --- a/src/hl2h.cpp +++ b/src/hl2h.cpp | |||
| @@ -123,6 +123,42 @@ float getfov(const QAngle &my_view, const QAngle &aim_ang) { | |||
| 123 | 123 | ||
| 124 | static int g_modified_logged = 0; | 124 | static int g_modified_logged = 0; |
| 125 | 125 | ||
| 126 | // VEngineCvar004 / ICvar vtable: IAppSystem has 5 slots, then | ||
| 127 | // AllocateDLLIdentifier, RegisterConCommand, UnregisterConCommand, | ||
| 128 | // UnregisterConCommands, GetCommandLineValue, FindCommandBase, | ||
| 129 | // FindCommandBase const, FindVar -> slot 12. | ||
| 130 | // ConCommandBase has two dtor slots, then IsCommand, IsFlagSet, AddFlags, | ||
| 131 | // GetName, GetHelpText, IsRegistered, GetDLLIdentifier; ConVar then adds | ||
| 132 | // SetValue(const char*), SetValue(float), SetValue(int) -> slot 11. | ||
| 133 | bool cvar_set_int(const char *name, int value) { | ||
| 134 | if (!name) | ||
| 135 | return false; | ||
| 136 | if (g_iface.cvar) { | ||
| 137 | using FindVarFn = void *(*)(void *, const char *); | ||
| 138 | void *var = vfunc<FindVarFn>(g_iface.cvar, 12)(g_iface.cvar, name); | ||
| 139 | if (var) { | ||
| 140 | using GetNameFn = const char *(*)(void *); | ||
| 141 | const char *got = vfunc<GetNameFn>(var, 5)(var); | ||
| 142 | if (got && strcmp(got, name) == 0) { | ||
| 143 | using SetIntFn = void (*)(void *, int); | ||
| 144 | vfunc<SetIntFn>(var, 11)(var, value); | ||
| 145 | return true; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | } | ||
| 149 | // Fallback for an engine that does not expose VEngineCvar004: ClientCmd | ||
| 150 | // slot 7. Cheat-protected cvars may still be rejected. | ||
| 151 | if (g_iface.engine) { | ||
| 152 | char cmd[96]; | ||
| 153 | snprintf(cmd, sizeof(cmd), "%s %d", name, value); | ||
| 154 | using CmdFn = void (*)(void *, const char *); | ||
| 155 | vfunc<CmdFn>(g_iface.engine, 7)(g_iface.engine, cmd); | ||
| 156 | logd("cvar: fallback command '%s'", cmd); | ||
| 157 | return true; | ||
| 158 | } | ||
| 159 | return false; | ||
| 160 | } | ||
| 161 | |||
| 126 | void note_modified(const CUserCmd *cmd, int flags, const float *vel) { | 162 | void note_modified(const CUserCmd *cmd, int flags, const float *vel) { |
| 127 | // recompute usercmd CRC after modification | 163 | // recompute usercmd CRC after modification |
| 128 | fix_verified_crc(cmd->command_number, usercmd_checksum(cmd)); | 164 | fix_verified_crc(cmd->command_number, usercmd_checksum(cmd)); |
| @@ -563,6 +599,7 @@ static void do_move(int seq, float frametime) { | |||
| 563 | bones_clear(); | 599 | bones_clear(); |
| 564 | aimbot_reset_lock(); | 600 | aimbot_reset_lock(); |
| 565 | silentaim_reset_lock(); | 601 | silentaim_reset_lock(); |
| 602 | fullbright_invalidate(); | ||
| 566 | } | 603 | } |
| 567 | 604 | ||
| 568 | if (feature_active(FEAT_SPREAD)) { | 605 | if (feature_active(FEAT_SPREAD)) { |
| @@ -908,10 +945,36 @@ static void *setup_thread(void *) { | |||
| 908 | g_iface.engineserver = ef("VEngineServer021", nullptr); | 945 | g_iface.engineserver = ef("VEngineServer021", nullptr); |
| 909 | g_iface.debugoverlay = ef("VDebugOverlay003", nullptr); | 946 | g_iface.debugoverlay = ef("VDebugOverlay003", nullptr); |
| 910 | g_iface.enginetrace = ef("EngineTraceClient003", nullptr); | 947 | g_iface.enginetrace = ef("EngineTraceClient003", nullptr); |
| 948 | static const char *cvar_names[] = {"VEngineCvar004", "VEngineCvar007", | ||
| 949 | "VEngineCvar003", "IVEngineCvar004", | ||
| 950 | nullptr}; | ||
| 951 | for (int i = 0; cvar_names[i] && !g_iface.cvar; i++) { | ||
| 952 | g_iface.cvar = ef(cvar_names[i], nullptr); | ||
| 953 | if (!g_iface.cvar) | ||
| 954 | g_iface.cvar = cf(cvar_names[i], nullptr); | ||
| 955 | } | ||
| 956 | if (!g_iface.cvar) { | ||
| 957 | size_t slash = g_engine.path.find_last_of('/'); | ||
| 958 | if (slash != std::string::npos) { | ||
| 959 | std::string path = | ||
| 960 | g_engine.path.substr(0, slash + 1) + "libvstdlib.so"; | ||
| 961 | void *h = dlopen(path.c_str(), RTLD_NOLOAD | RTLD_LAZY | RTLD_GLOBAL); | ||
| 962 | if (!h) | ||
| 963 | h = dlopen(path.c_str(), RTLD_LAZY | RTLD_GLOBAL); | ||
| 964 | if (h) { | ||
| 965 | auto vf = (CreateInterfaceFn)dlsym(h, "CreateInterface"); | ||
| 966 | if (vf) { | ||
| 967 | for (int i = 0; cvar_names[i] && !g_iface.cvar; i++) | ||
| 968 | g_iface.cvar = vf(cvar_names[i], nullptr); | ||
| 969 | } | ||
| 970 | } | ||
| 971 | } | ||
| 972 | } | ||
| 911 | logf("modelinfo: %p (VModelInfoClient006)", g_iface.modelinfo); | 973 | logf("modelinfo: %p (VModelInfoClient006)", g_iface.modelinfo); |
| 912 | logf("engineserver: %p (VEngineServer021), debugoverlay: %p, " | 974 | logf("engineserver: %p (VEngineServer021), debugoverlay: %p, " |
| 913 | "enginetrace: %p (EngineTraceClient003)", | 975 | "enginetrace: %p (EngineTraceClient003)", |
| 914 | g_iface.engineserver, g_iface.debugoverlay, g_iface.enginetrace); | 976 | g_iface.engineserver, g_iface.debugoverlay, g_iface.enginetrace); |
| 977 | logf("cvar: %p (VEngineCvar004)", g_iface.cvar); | ||
| 915 | 978 | ||
| 916 | resolve_netvars(); | 979 | resolve_netvars(); |
| 917 | if (!g_net.ok()) | 980 | if (!g_net.ok()) |
