Compare commits
1 Commits
main
...
bone_posit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d7d974d88 |
24
Makefile
24
Makefile
@@ -1,15 +1,11 @@
|
|||||||
|
|
||||||
# Need to use g++ because the sdk headers use classes
|
# Need to use g++ because the sdk headers use classes
|
||||||
CC=g++
|
CC=g++
|
||||||
INCLUDES=-Isrc/include/sdk/common -Isrc/include/sdk/public -Isrc/include/sdk/pm_shared -Isrc/include/sdk/engine -Isrc/include
|
INCLUDES=-Isrc/include/sdk/common -Isrc/include/sdk/public -Isrc/include/sdk/pm_shared -Isrc/include/sdk/engine
|
||||||
CFLAGS=-Wall -Wextra -Wno-write-strings -m32 -fPIC -fpermissive $(INCLUDES)
|
CFLAGS=-Wall -Wextra -Wno-write-strings -m32 -fPIC $(INCLUDES)
|
||||||
LDFLAGS=-lm -lGL
|
LDFLAGS=-lm
|
||||||
|
|
||||||
IMGUI_DIR=src/include/imgui
|
OBJS=obj/main.c.o obj/globals.c.o obj/cvars.c.o obj/hooks.c.o obj/detour.c.o obj/util.c.o obj/features/movement.c.o obj/features/esp.c.o obj/features/chams.c.o obj/features/aim.c.o obj/features/misc.c.o
|
||||||
IMGUI_INCLUDES=-I$(IMGUI_DIR)
|
|
||||||
IMGUI_SRCS=$(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp
|
|
||||||
IMGUI_OBJS=$(patsubst %.cpp,%.o,$(IMGUI_SRCS))
|
|
||||||
|
|
||||||
OBJS=obj/main.c.o obj/globals.c.o obj/settings.c.o obj/hooks.c.o obj/detour.c.o obj/util.c.o obj/features/movement.c.o obj/features/anti_aim.c.o obj/features/fov.c.o obj/features/namechanger.c.o obj/features/esp.c.o obj/features/chams.c.o obj/features/aim.c.o obj/features/misc.c.o obj/features/thirdperson.c.o obj/features/no_recoil.c.o obj/game_detection.c.o obj/menu.c.o $(IMGUI_OBJS)
|
|
||||||
BIN=libhlcheat.so
|
BIN=libhlcheat.so
|
||||||
|
|
||||||
.PHONY: clean all inject
|
.PHONY: clean all inject
|
||||||
@@ -32,12 +28,6 @@ inject: $(BIN)
|
|||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
$(CC) $(CFLAGS) -shared -o $@ $(OBJS) $(LDFLAGS)
|
$(CC) $(CFLAGS) -shared -o $@ $(OBJS) $(LDFLAGS)
|
||||||
|
|
||||||
obj/%.c.o: src/%.c
|
$(OBJS): obj/%.c.o : src/%.c
|
||||||
@mkdir -p $(@D)
|
@mkdir -p obj/features/
|
||||||
$(CC) $(CFLAGS) -c -o $@ $< $(LDFLAGS)
|
|
||||||
|
|
||||||
$(IMGUI_DIR)/backends/%.o: $(IMGUI_DIR)/backends/%.cpp
|
|
||||||
$(CC) $(CFLAGS) $(IMGUI_INCLUDES) -c -o $@ $< $(LDFLAGS)
|
|
||||||
|
|
||||||
%.o: %.cpp
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $< $(LDFLAGS)
|
$(CC) $(CFLAGS) -c -o $@ $< $(LDFLAGS)
|
||||||
|
|||||||
73
README.org
73
README.org
@@ -1,24 +1,14 @@
|
|||||||
#+title: Half-Life cheat (Original author: [[https://github.com/8dcc/][8dcc]])
|
#+title: Half-Life cheat
|
||||||
#+options: toc:nil
|
#+options: toc:nil
|
||||||
#+startup: showeverything
|
#+startup: showeverything
|
||||||
#+author: Wizzard
|
#+author: 8dcc
|
||||||
|
|
||||||
*Linux cheat for goldsrc games.*
|
*Linux cheat for Half-Life 1 (and goldsrc).*
|
||||||
|
|
||||||
#+TOC: headlines 2
|
#+TOC: headlines 2
|
||||||
|
|
||||||
* WARNING
|
|
||||||
TO USE THIS YOU MUST BE RUNNING THE LEGACY BETA
|
|
||||||
|
|
||||||
* Description
|
* Description
|
||||||
Simple linux cheat for most goldsrc games, made in C.
|
Simple linux cheat for Half-Life 1 (and most /goldsrc/ games) made in C.
|
||||||
|
|
||||||
Supported games:
|
|
||||||
- [[https://store.steampowered.com/app/70/HalfLife/][Half-Life 1]]
|
|
||||||
- [[https://store.steampowered.com/app/10/CounterStrike/][Counter-Strike 1.6]]
|
|
||||||
- [[https://store.steampowered.com/app/20/Team_Fortress_Classic/][Team Fortress Classic]]
|
|
||||||
- [[https://store.steampowered.com/app/30/Day_of_Defeat/][Day of Defeat]]
|
|
||||||
- [[https://store.steampowered.com/app/40/Deathmatch_Classic/][Deathmatch Classic]]
|
|
||||||
|
|
||||||
This project was heavily inspired by [[https://github.com/UnkwUsr/hlhax][UnkwUsr/hlhax]], and would not have been
|
This project was heavily inspired by [[https://github.com/UnkwUsr/hlhax][UnkwUsr/hlhax]], and would not have been
|
||||||
possible without his help. Make sure to check out his repo too.
|
possible without his help. Make sure to check out his repo too.
|
||||||
@@ -27,39 +17,15 @@ Also make sure to check out [[https://github.com/deboogerxyz/ahc][deboogerxyz/ah
|
|||||||
|
|
||||||
* Features
|
* Features
|
||||||
|
|
||||||
| Feature | Description |
|
| Feature | Command | Values (0..n) |
|
||||||
|-------------|-----------------------------------|
|
|------------+---------------+------------------------|
|
||||||
| Bhop | Automatically jump when landing |
|
| Bhop | =cv_bhop= | off/on |
|
||||||
| Autostrafe | Automatic strafing movement |
|
| Autostrafe | =cv_autostrafe= | off/rage/legit |
|
||||||
| Aimbot | Aim assistance with FOV control |
|
| Aimbot | =cv_aimbot= | off/fov* |
|
||||||
| Autoshoot | Automatically shoot at enemies |
|
| ESP | =cv_esp= | off/3d-box/name/all |
|
||||||
| ESP | See enemies through walls |
|
| Chams | =cv_chams= | off/players/hands/all* |
|
||||||
| Chams | Colored player models |
|
| Crosshair | =cv_crosshair= | off/length |
|
||||||
| Crosshair | Custom crosshair |
|
|
||||||
| Tracers | Show bullet paths |
|
|
||||||
| Namechanger | Automatically change player name |
|
|
||||||
| ThirdPerson | Third-person camera view |
|
|
||||||
|
|
||||||
#+begin_quote
|
|
||||||
*Note:* All features can now be controlled via the ImGui menu (press INSERT to open).
|
|
||||||
#+end_quote
|
|
||||||
|
|
||||||
* GUI Menu
|
|
||||||
|
|
||||||
The cheat includes a full graphical user interface that can be opened by pressing the *INSERT* key. The menu includes several tabs:
|
|
||||||
|
|
||||||
- *Aimbot:* Configure aimbot settings including FOV, smoothing, and autoshoot
|
|
||||||
- *Visuals:* ESP, chams, crosshair and other visual enhancements
|
|
||||||
- *Misc:* Various utilities including name changer
|
|
||||||
- *Movement:* Bunny hop and auto-strafe settings
|
|
||||||
- *ThirdPerson:* Configure third-person camera view and key binding
|
|
||||||
- *Config:* Save and load configurations, set default settings
|
|
||||||
|
|
||||||
Key features of the menu:
|
|
||||||
- Press INSERT to toggle the menu on/off
|
|
||||||
- Settings are automatically saved to =~/.config/dz-goldsrccheat/=
|
|
||||||
- Default settings can be saved and will automatically load on startup
|
|
||||||
- Bind custom keys for features like third-person toggle
|
|
||||||
|
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
*Note:* Aimbot FOV goes from 0 (off) to 180 (all enemies)
|
*Note:* Aimbot FOV goes from 0 (off) to 180 (all enemies)
|
||||||
@@ -67,19 +33,14 @@ Key features of the menu:
|
|||||||
|
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
*Note:* Chams color can be changed from the =h_glColor4f()= function inside
|
*Note:* Chams color can be changed from the =h_glColor4f()= function inside
|
||||||
[[https://git.deadzone.lol/Wizzard/goldsrc-cheat/src/branch/main/src/hooks.c][src/hooks.c]]. Since this cheat is not hard to compile, I rather have less
|
[[https://github.com/8dcc/hl-cheat/blob/main/src/hooks.c][src/hooks.c]]. Since this cheat is not hard to compile, I rather have less
|
||||||
console variables than more customization at runtime.
|
console variables than more customization at runtime.
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
#+begin_quote
|
|
||||||
*Note:* Bullet tracer color, width and time can be changed at the bottom of the
|
|
||||||
=bullet_tracers()= function inside [[https://git.deadzone.lol/Wizzard/goldsrc-cheat/src/branch/main/src/features/misc.c][src/features/misc.c]]. See previous chams note.
|
|
||||||
#+end_quote
|
|
||||||
|
|
||||||
* Building
|
* Building
|
||||||
#+begin_src console
|
#+begin_src console
|
||||||
$ git clone --recurse-submodules https://git.deadzone.lol/Wizzard/goldsrc-cheat
|
$ git clone --recurse-submodules https://github.com/8dcc/hl-cheat
|
||||||
$ cd goldsource-cheat
|
$ cd hl-cheat
|
||||||
$ make
|
$ make
|
||||||
...
|
...
|
||||||
#+end_src
|
#+end_src
|
||||||
@@ -88,7 +49,7 @@ Note that you will need to clone with =--recurse-submodules= for the sdk. If you
|
|||||||
have already cloned it, you can just:
|
have already cloned it, you can just:
|
||||||
|
|
||||||
#+begin_src console
|
#+begin_src console
|
||||||
$ cd goldsource-cheat
|
$ cd hl-cheat
|
||||||
$ git submodule update --init --recursive
|
$ git submodule update --init --recursive
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
@@ -101,5 +62,5 @@ $ ./injector.sh
|
|||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
goldsource-cheat loaded!
|
hl-cheat loaded!
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|||||||
BIN
default.cfg
BIN
default.cfg
Binary file not shown.
217
inject-debug.sh
217
inject-debug.sh
@@ -1,217 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
pid=$(pidof "hl_linux")
|
|
||||||
libpath=$(realpath "libhlcheat.so")
|
|
||||||
|
|
||||||
if [ "$pid" == "" ]; then
|
|
||||||
echo "inject-debug.sh: process not running."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
show_help() {
|
|
||||||
echo "Usage: $0 [OPTIONS]"
|
|
||||||
echo "Options:"
|
|
||||||
echo " --help Show this help message"
|
|
||||||
echo " --unload Debug the unload process interactively"
|
|
||||||
echo " --inject Debug the injection process interactively"
|
|
||||||
echo ""
|
|
||||||
echo "Common GDB commands to use during debugging:"
|
|
||||||
echo " bt Show backtrace"
|
|
||||||
echo " info locals Show local variables"
|
|
||||||
echo " n Step over (next line)"
|
|
||||||
echo " s Step into function"
|
|
||||||
echo " c Continue execution"
|
|
||||||
echo " p expression Print value of expression"
|
|
||||||
echo " finish Run until current function returns"
|
|
||||||
echo ""
|
|
||||||
echo "Without options, the script will inject the cheat normally."
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
UNLOAD_MODE=0
|
|
||||||
INJECT_MODE=0
|
|
||||||
|
|
||||||
for arg in "$@"; do
|
|
||||||
case $arg in
|
|
||||||
--help)
|
|
||||||
show_help
|
|
||||||
;;
|
|
||||||
--unload)
|
|
||||||
UNLOAD_MODE=1
|
|
||||||
;;
|
|
||||||
--inject)
|
|
||||||
INJECT_MODE=1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
cat > /tmp/gdbinit-goldsrc << EOF
|
|
||||||
set confirm off
|
|
||||||
set pagination off
|
|
||||||
set print pretty on
|
|
||||||
|
|
||||||
define hook-stop
|
|
||||||
echo \nBREAKPOINT HIT\n
|
|
||||||
bt
|
|
||||||
echo \nLOCAL VARIABLES:\n
|
|
||||||
info locals
|
|
||||||
echo \nSTACK FRAME:\n
|
|
||||||
info frame
|
|
||||||
echo \nCommands: n (next), s (step), c (continue), bt (backtrace), finish (run until function returns)\n
|
|
||||||
end
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
if [ $UNLOAD_MODE -eq 1 ]; then
|
|
||||||
echo "Starting interactive unload debugging session..."
|
|
||||||
|
|
||||||
cat >> /tmp/gdbinit-goldsrc << EOF
|
|
||||||
# Set up functions to help with dlopen/dlclose
|
|
||||||
set \$dlopen = (void* (*)(char*, int))dlopen
|
|
||||||
set \$dlclose = (int (*)(void*))dlclose
|
|
||||||
set \$dlerror = (char* (*)(void))dlerror
|
|
||||||
|
|
||||||
# Set breakpoints on critical functions
|
|
||||||
break self_unload
|
|
||||||
break unload
|
|
||||||
break safe_unload_with_debug
|
|
||||||
break UNINJECT_CommandHandler
|
|
||||||
break hooks_restore
|
|
||||||
break globals_restore
|
|
||||||
break GL_UNHOOK
|
|
||||||
|
|
||||||
# Command to manually invoke the unload from GDB
|
|
||||||
define uninject
|
|
||||||
set \$self = \$dlopen("$libpath", 6)
|
|
||||||
p \$self
|
|
||||||
call \$dlclose(\$self)
|
|
||||||
call \$dlclose(\$self)
|
|
||||||
call \$dlerror()
|
|
||||||
end
|
|
||||||
|
|
||||||
define call_uninject_cmd
|
|
||||||
call UNINJECT_CommandHandler()
|
|
||||||
end
|
|
||||||
|
|
||||||
echo \nType 'call_uninject_cmd' to execute the uninject command\n
|
|
||||||
echo Type 'uninject' to manually trigger the unload process\n
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
|
||||||
|
|
||||||
echo "Interactive unload debugging session ended."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $INJECT_MODE -eq 1 ]; then
|
|
||||||
echo "Starting interactive injection debugging session..."
|
|
||||||
|
|
||||||
cat >> /tmp/gdbinit-goldsrc << EOF
|
|
||||||
# Set up functions to help with dlopen/dlclose
|
|
||||||
set \$dlopen = (void* (*)(char*, int))dlopen
|
|
||||||
set \$dlclose = (int (*)(void*))dlclose
|
|
||||||
set \$dlerror = (char* (*)(void))dlerror
|
|
||||||
|
|
||||||
# Set breakpoints on critical functions
|
|
||||||
break load
|
|
||||||
break globals_init
|
|
||||||
break cvars_init
|
|
||||||
break hooks_init
|
|
||||||
|
|
||||||
# Command to manually inject the library
|
|
||||||
define inject
|
|
||||||
call \$dlopen("$libpath", 2)
|
|
||||||
call \$dlerror()
|
|
||||||
end
|
|
||||||
|
|
||||||
echo \nType 'inject' to load the library\n
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
|
||||||
|
|
||||||
echo "Interactive injection debugging session ended."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Injecting cheat..."
|
|
||||||
|
|
||||||
if grep -q "$libpath" "/proc/$pid/maps"; then
|
|
||||||
echo -e "goldsource-cheat already loaded. Reloading...\n"
|
|
||||||
|
|
||||||
cat > /tmp/gdbinit-goldsrc << EOF
|
|
||||||
set confirm off
|
|
||||||
set pagination off
|
|
||||||
set print pretty on
|
|
||||||
set \$dlopen = (void* (*)(char*, int))dlopen
|
|
||||||
set \$dlclose = (int (*)(void*))dlclose
|
|
||||||
set \$dlerror = (char* (*)(void))dlerror
|
|
||||||
|
|
||||||
# Reload library
|
|
||||||
define reload_lib
|
|
||||||
set \$self = \$dlopen("$libpath", 6)
|
|
||||||
call \$dlclose(\$self)
|
|
||||||
call \$dlclose(\$self)
|
|
||||||
call \$dlopen("$libpath", 2)
|
|
||||||
call \$dlerror()
|
|
||||||
echo "\nReload complete. Library has been reloaded.\n"
|
|
||||||
echo "You can now debug interactively.\n"
|
|
||||||
echo "Type 'continue' or 'c' to let the game run normally.\n"
|
|
||||||
echo "Type 'call_uninject_cmd' to trigger the uninject command.\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Command to manually trigger uninject
|
|
||||||
define call_uninject_cmd
|
|
||||||
call UNINJECT_CommandHandler()
|
|
||||||
end
|
|
||||||
|
|
||||||
# Execute reload automatically
|
|
||||||
reload_lib
|
|
||||||
|
|
||||||
# Break on uninject command
|
|
||||||
break UNINJECT_CommandHandler
|
|
||||||
break safe_unload_with_debug
|
|
||||||
break self_unload
|
|
||||||
|
|
||||||
echo "\nType 'help' for GDB commands or 'continue' to let the game run.\n"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
|
||||||
else
|
|
||||||
cat > /tmp/gdbinit-goldsrc << EOF
|
|
||||||
set confirm off
|
|
||||||
set pagination off
|
|
||||||
set print pretty on
|
|
||||||
set \$dlopen = (void* (*)(char*, int))dlopen
|
|
||||||
set \$dlclose = (int (*)(void*))dlclose
|
|
||||||
set \$dlerror = (char* (*)(void))dlerror
|
|
||||||
|
|
||||||
# Initial library load
|
|
||||||
define load_lib
|
|
||||||
call \$dlopen("$libpath", 2)
|
|
||||||
call \$dlerror()
|
|
||||||
echo "\nInjection complete. Library has been loaded.\n"
|
|
||||||
echo "You can now debug interactively.\n"
|
|
||||||
echo "Type 'continue' or 'c' to let the game run normally.\n"
|
|
||||||
echo "Type 'call_uninject_cmd' to trigger the uninject command.\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Command to manually trigger uninject
|
|
||||||
define call_uninject_cmd
|
|
||||||
call UNINJECT_CommandHandler()
|
|
||||||
end
|
|
||||||
|
|
||||||
# Execute load automatically
|
|
||||||
load_lib
|
|
||||||
|
|
||||||
# Break on uninject command
|
|
||||||
break UNINJECT_CommandHandler
|
|
||||||
break safe_unload_with_debug
|
|
||||||
break self_unload
|
|
||||||
|
|
||||||
echo "\nType 'help' for GDB commands or 'continue' to let the game run.\n"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\nDebug session ended."
|
|
||||||
@@ -30,7 +30,7 @@ if [ "$1" == "unload" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if grep -q "$libpath" "/proc/$pid/maps"; then
|
if grep -q "$libpath" "/proc/$pid/maps"; then
|
||||||
echo -e "goldsource-cheat already loaded. Reloading...\n";
|
echo -e "hl-cheat already loaded. Reloading...\n";
|
||||||
|
|
||||||
# 0x2 -> RTLD_NOW
|
# 0x2 -> RTLD_NOW
|
||||||
# 0x6 -> RTLD_LAZY | RTLD_NOLOAD
|
# 0x6 -> RTLD_LAZY | RTLD_NOLOAD
|
||||||
|
|||||||
24
src/cvars.c
Normal file
24
src/cvars.c
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
#include "include/cvars.h"
|
||||||
|
#include "include/sdk.h"
|
||||||
|
#include "include/globals.h"
|
||||||
|
|
||||||
|
DECL_CVAR(bhop);
|
||||||
|
DECL_CVAR(autostrafe);
|
||||||
|
DECL_CVAR(aimbot);
|
||||||
|
DECL_CVAR(esp);
|
||||||
|
DECL_CVAR(chams);
|
||||||
|
DECL_CVAR(crosshair);
|
||||||
|
DECL_CVAR(clmove);
|
||||||
|
|
||||||
|
bool cvars_init(void) {
|
||||||
|
REGISTER_CVAR(bhop, 1);
|
||||||
|
REGISTER_CVAR(autostrafe, 0);
|
||||||
|
REGISTER_CVAR(aimbot, 0);
|
||||||
|
REGISTER_CVAR(esp, 3);
|
||||||
|
REGISTER_CVAR(chams, 1);
|
||||||
|
REGISTER_CVAR(crosshair, 0);
|
||||||
|
REGISTER_CVAR(clmove, 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
101
src/detour.c
101
src/detour.c
@@ -11,7 +11,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h> /* getpagesize */
|
#include <unistd.h> /* getpagesize */
|
||||||
#include <sys/mman.h> /* mprotect */
|
#include <sys/mman.h> /* mprotect */
|
||||||
#include <stdio.h> /* printf */
|
|
||||||
|
|
||||||
#include "include/detour.h"
|
#include "include/detour.h"
|
||||||
|
|
||||||
@@ -20,11 +19,6 @@
|
|||||||
#define PAGE_ALIGN(x) ((x + PAGE_SIZE - 1) & PAGE_MASK)
|
#define PAGE_ALIGN(x) ((x + PAGE_SIZE - 1) & PAGE_MASK)
|
||||||
#define PAGE_ALIGN_DOWN(x) (PAGE_ALIGN(x) - PAGE_SIZE)
|
#define PAGE_ALIGN_DOWN(x) (PAGE_ALIGN(x) - PAGE_SIZE)
|
||||||
|
|
||||||
/* Store detour data for functions we've hooked */
|
|
||||||
#define MAX_HOOKS 32
|
|
||||||
static detour_data_t g_hooks[MAX_HOOKS];
|
|
||||||
static int g_hook_count = 0;
|
|
||||||
|
|
||||||
static bool protect_addr(void* ptr, int new_flags) {
|
static bool protect_addr(void* ptr, int new_flags) {
|
||||||
void* p = (void*)PAGE_ALIGN_DOWN((detour_ptr_t)ptr);
|
void* p = (void*)PAGE_ALIGN_DOWN((detour_ptr_t)ptr);
|
||||||
int pgsz = getpagesize();
|
int pgsz = getpagesize();
|
||||||
@@ -55,9 +49,6 @@ static uint8_t def_jmp_bytes[] = { 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void detour_init(detour_data_t* data, void* orig, void* hook) {
|
void detour_init(detour_data_t* data, void* orig, void* hook) {
|
||||||
if (!orig || !hook)
|
|
||||||
return;
|
|
||||||
|
|
||||||
data->detoured = false;
|
data->detoured = false;
|
||||||
data->orig = orig;
|
data->orig = orig;
|
||||||
data->hook = hook;
|
data->hook = hook;
|
||||||
@@ -117,95 +108,3 @@ bool detour_del(detour_data_t* d) {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get existing hook data for an original function pointer */
|
|
||||||
static detour_data_t* find_hook_data(void* orig) {
|
|
||||||
for (int i = 0; i < g_hook_count; i++) {
|
|
||||||
if (g_hooks[i].orig == orig) {
|
|
||||||
return &g_hooks[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wrapper functions for backward compatibility with code using
|
|
||||||
* DetourFunction and DetourRemove naming convention */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wrapper for detour_add that saves and returns the original
|
|
||||||
* function pointer as required by the DetourFunction interface
|
|
||||||
*/
|
|
||||||
void* DetourFunction(void* orig, void* hook) {
|
|
||||||
if (!orig || !hook) {
|
|
||||||
printf("DetourFunction error: NULL pointer provided\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if we already have a hook for this function */
|
|
||||||
detour_data_t* existing = find_hook_data(orig);
|
|
||||||
if (existing) {
|
|
||||||
/* If the function was already hooked but with a different hook,
|
|
||||||
restore the original first */
|
|
||||||
if (existing->hook != hook) {
|
|
||||||
printf("DetourFunction: Function at %p already hooked, updating\n", orig);
|
|
||||||
detour_del(existing);
|
|
||||||
existing->hook = hook;
|
|
||||||
/* Recreate the jump instruction with new hook */
|
|
||||||
memcpy(existing->jmp_bytes, &def_jmp_bytes, sizeof(def_jmp_bytes));
|
|
||||||
memcpy(&existing->jmp_bytes[JMP_BYTES_PTR], &hook, sizeof(detour_ptr_t));
|
|
||||||
if (!detour_add(existing)) {
|
|
||||||
printf("DetourFunction error: Failed to update hook for %p\n", orig);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return existing->orig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No existing hook, create a new one if we have space */
|
|
||||||
if (g_hook_count >= MAX_HOOKS) {
|
|
||||||
printf("DetourFunction error: Max hooks (%d) reached\n", MAX_HOOKS);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
detour_data_t* data = &g_hooks[g_hook_count++];
|
|
||||||
memset(data, 0, sizeof(detour_data_t)); // Clear memory before use
|
|
||||||
detour_init(data, orig, hook);
|
|
||||||
if (detour_add(data))
|
|
||||||
return data->orig;
|
|
||||||
|
|
||||||
/* If detour failed, decrement the counter */
|
|
||||||
printf("DetourFunction error: Failed to add hook for %p\n", orig);
|
|
||||||
g_hook_count--;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wrapper for detour_del that takes the original and hook
|
|
||||||
* function pointers directly
|
|
||||||
*/
|
|
||||||
bool DetourRemove(void* orig, void* hook) {
|
|
||||||
if (!orig) {
|
|
||||||
printf("DetourRemove error: NULL original function pointer\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the hook in our array */
|
|
||||||
detour_data_t* data = find_hook_data(orig);
|
|
||||||
if (!data) {
|
|
||||||
printf("DetourRemove error: Hook for function %p not found\n", orig);
|
|
||||||
return false; /* Not found */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If hook is specified, make sure it matches */
|
|
||||||
if (hook && data->hook != hook) {
|
|
||||||
printf("DetourRemove error: Hook function mismatch for %p\n", orig);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the hook */
|
|
||||||
bool result = detour_del(data);
|
|
||||||
if (!result) {
|
|
||||||
printf("DetourRemove error: Failed to remove hook for %p\n", orig);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,417 +1,74 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "../include/sdk.h"
|
|
||||||
#include "../include/util.h"
|
|
||||||
#include "../include/entityutil.h"
|
|
||||||
#include "../include/mathutil.h"
|
|
||||||
#include "../include/menu.h"
|
|
||||||
#include "../include/settings.h"
|
|
||||||
#include "features.h"
|
#include "features.h"
|
||||||
|
#include "../include/sdk.h"
|
||||||
|
#include "../include/cvars.h"
|
||||||
|
#include "../include/util.h"
|
||||||
|
|
||||||
#define HITBOX_HEAD 0
|
/* Game units to add to the entity origin to get the head */
|
||||||
#define HITBOX_CHEST 1
|
#define HEAD_OFFSET 0.8f
|
||||||
#define HITBOX_STOMACH 2
|
|
||||||
#define HITBOX_PELVIS 3
|
|
||||||
#define HITBOX_LEFTARM 4
|
|
||||||
#define HITBOX_RIGHTARM 5
|
|
||||||
#define HITBOX_LEFTLEG 6
|
|
||||||
#define HITBOX_RIGHTLEG 7
|
|
||||||
#define HITBOX_NEAREST 4
|
|
||||||
#define MAX_HITBOXES 7
|
|
||||||
|
|
||||||
#define AIM_PUNCH_MULT 2.0f
|
static vec3_t get_closest_delta(vec3_t viewangles) {
|
||||||
|
vec3_t view_height;
|
||||||
|
i_engine->pEventAPI->EV_LocalPlayerViewheight(view_height);
|
||||||
|
vec3_t local_eyes = vec_add(localplayer->origin, view_height);
|
||||||
|
/* TODO: Compensate aim punch */
|
||||||
|
|
||||||
#define SMOOTHING_FACTOR 3.0f
|
/* These 2 vars are used to store the best target across iterations.
|
||||||
|
* NOTE: The default value of best_fov will be the aimbot fov */
|
||||||
|
float best_fov = cv_aimbot->value;
|
||||||
|
vec3_t best_delta = { 0, 0, 0 };
|
||||||
|
|
||||||
#define PITCH 0
|
|
||||||
#define YAW 1
|
|
||||||
#define ROLL 2
|
|
||||||
|
|
||||||
#define PRIORITY_NONE 0
|
|
||||||
#define PRIORITY_LOW 1
|
|
||||||
#define PRIORITY_MEDIUM 2
|
|
||||||
#define PRIORITY_HIGH 3
|
|
||||||
|
|
||||||
// Weapon IDs
|
|
||||||
#define WEAPON_GLOCK 17
|
|
||||||
#define WEAPON_DEAGLE 26
|
|
||||||
#define WEAPON_AK47 28
|
|
||||||
#define WEAPON_M4A1 22
|
|
||||||
#define WEAPON_AWP 33
|
|
||||||
|
|
||||||
extern const char* hitbox_options[];
|
|
||||||
extern int current_hitbox;
|
|
||||||
|
|
||||||
const char* hitbox_names[] = {
|
|
||||||
"Head",
|
|
||||||
"Chest",
|
|
||||||
"Stomach",
|
|
||||||
"Pelvis",
|
|
||||||
"Nearest Point"
|
|
||||||
};
|
|
||||||
|
|
||||||
int current_hitbox = HITBOX_HEAD;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
vec3_t mins;
|
|
||||||
vec3_t maxs;
|
|
||||||
vec3_t origin;
|
|
||||||
float radius;
|
|
||||||
} hitbox_t;
|
|
||||||
|
|
||||||
bool get_hitbox(cl_entity_t* ent, int hitbox_id, hitbox_t* out_hitbox) {
|
|
||||||
if (!ent || !out_hitbox) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
out_hitbox->radius = 5.0f;
|
|
||||||
|
|
||||||
bool is_ak47 = (g_currentWeaponID == WEAPON_AK47);
|
|
||||||
|
|
||||||
studiohdr_t* studio = NULL;
|
|
||||||
if (ent->model) {
|
|
||||||
studio = (studiohdr_t*)i_enginestudio->Mod_Extradata(ent->model);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (hitbox_id) {
|
|
||||||
case 0: {
|
|
||||||
vec3_t view_offset;
|
|
||||||
view_offset.x = 0.0f;
|
|
||||||
view_offset.y = 0.0f;
|
|
||||||
|
|
||||||
if (is_ak47) {
|
|
||||||
view_offset.z = 26.0f;
|
|
||||||
} else {
|
|
||||||
view_offset.z = 27.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
out_hitbox->origin = vec_add(ent->origin, view_offset);
|
|
||||||
out_hitbox->radius = 7.0f;
|
|
||||||
|
|
||||||
vec3_t head_offset;
|
|
||||||
head_offset.x = 0.0f;
|
|
||||||
head_offset.y = 0.0f;
|
|
||||||
head_offset.z = 0.0f;
|
|
||||||
|
|
||||||
if (is_ak47) {
|
|
||||||
head_offset.z = -1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
out_hitbox->origin = vec_add(out_hitbox->origin, head_offset);
|
|
||||||
|
|
||||||
static int debug_counter = 0;
|
|
||||||
if (debug_counter++ % 500 == 0) {
|
|
||||||
i_engine->Con_Printf("Head hitbox: Origin(%.1f,%.1f,%.1f) Radius(%.1f) WeaponID: %d\n",
|
|
||||||
out_hitbox->origin.x, out_hitbox->origin.y, out_hitbox->origin.z,
|
|
||||||
out_hitbox->radius, g_currentWeaponID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 1: {
|
|
||||||
vec3_t chest_offset;
|
|
||||||
chest_offset.x = 0.0f;
|
|
||||||
chest_offset.y = 0.0f;
|
|
||||||
chest_offset.z = 18.0f;
|
|
||||||
|
|
||||||
out_hitbox->origin = vec_add(ent->origin, chest_offset);
|
|
||||||
out_hitbox->radius = 10.0f;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 2: {
|
|
||||||
vec3_t stomach_offset;
|
|
||||||
stomach_offset.x = 0.0f;
|
|
||||||
stomach_offset.y = 0.0f;
|
|
||||||
stomach_offset.z = 12.0f;
|
|
||||||
|
|
||||||
out_hitbox->origin = vec_add(ent->origin, stomach_offset);
|
|
||||||
out_hitbox->radius = 9.0f;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 3: {
|
|
||||||
vec3_t pelvis_offset;
|
|
||||||
pelvis_offset.x = 0.0f;
|
|
||||||
pelvis_offset.y = 0.0f;
|
|
||||||
pelvis_offset.z = 6.0f;
|
|
||||||
|
|
||||||
out_hitbox->origin = vec_add(ent->origin, pelvis_offset);
|
|
||||||
out_hitbox->radius = 8.0f;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if (is_ak47) {
|
|
||||||
vec3_t fallback_offset;
|
|
||||||
fallback_offset.x = 0.0f;
|
|
||||||
fallback_offset.y = 0.0f;
|
|
||||||
fallback_offset.z = 20.0f;
|
|
||||||
|
|
||||||
out_hitbox->origin = vec_add(ent->origin, fallback_offset);
|
|
||||||
} else {
|
|
||||||
vec3_t fallback_offset;
|
|
||||||
fallback_offset.x = 0.0f;
|
|
||||||
fallback_offset.y = 0.0f;
|
|
||||||
fallback_offset.z = 25.0f;
|
|
||||||
|
|
||||||
out_hitbox->origin = vec_add(ent->origin, fallback_offset);
|
|
||||||
}
|
|
||||||
out_hitbox->radius = 8.0f;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_hitbox_visible(vec3_t eye_pos, hitbox_t* hitbox) {
|
|
||||||
if (!hitbox)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
pmtrace_t* trace = i_engine->PM_TraceLine(eye_pos, hitbox->origin, PM_TRACELINE_PHYSENTSONLY, 2, -1);
|
|
||||||
|
|
||||||
static int trace_debug = 0;
|
|
||||||
if (trace_debug++ % 500 == 0) {
|
|
||||||
printf("Trace: fraction=%.3f, ent=%d\n", trace->fraction, trace->ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trace->fraction < 0.9f) {
|
|
||||||
if (trace->ent <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int ent_idx = i_pmove->physents[trace->ent].info;
|
|
||||||
cl_entity_t* hit_entity = get_player(ent_idx);
|
|
||||||
|
|
||||||
if (hit_entity) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
cl_entity_t* entity;
|
|
||||||
float fov;
|
|
||||||
vec3_t aim_point;
|
|
||||||
bool is_visible;
|
|
||||||
int priority;
|
|
||||||
float distance;
|
|
||||||
} target_t;
|
|
||||||
|
|
||||||
int get_target_priority(cl_entity_t* ent) {
|
|
||||||
if (!ent)
|
|
||||||
return PRIORITY_NONE;
|
|
||||||
|
|
||||||
return PRIORITY_MEDIUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
static target_t get_best_target(vec3_t viewangles, vec3_t eye_pos) {
|
|
||||||
target_t best_target = {NULL, 0.0f, {0, 0, 0}, false, PRIORITY_NONE, 9999.0f};
|
|
||||||
float best_score = 0.0f;
|
|
||||||
float max_fov = g_settings.aimbot_fov;
|
|
||||||
|
|
||||||
for (int i = 1; i <= i_engine->GetMaxClients(); i++) {
|
for (int i = 1; i <= i_engine->GetMaxClients(); i++) {
|
||||||
cl_entity_t* ent = get_player(i);
|
cl_entity_t* ent = get_player(i);
|
||||||
|
|
||||||
if (!ent || !is_alive(ent))
|
if (!is_alive(ent) || is_friend(ent))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!g_settings.aimbot_team_attack && is_friend(ent))
|
/* TODO: Get bones origin instead of calculating from ent origin */
|
||||||
continue;
|
const vec3_t head_pos = vec_add(ent->origin, vec3(0, 0, HEAD_OFFSET));
|
||||||
|
const vec3_t enemy_angle = vec_to_ang(vec_sub(head_pos, local_eyes));
|
||||||
hitbox_t target_hitbox;
|
|
||||||
bool hitbox_found = false;
|
const vec3_t delta = vec_sub(enemy_angle, viewangles);
|
||||||
|
vec_norm(delta);
|
||||||
if (current_hitbox == HITBOX_NEAREST) {
|
|
||||||
const int hitbox_priority[] = {HITBOX_HEAD, HITBOX_CHEST, HITBOX_STOMACH, HITBOX_PELVIS};
|
float fov = hypotf(delta.x, delta.y);
|
||||||
|
if (fov > 360.0f) {
|
||||||
for (int h = 0; h < 4; h++) {
|
fov = remainderf(fov, 360.0f);
|
||||||
if (get_hitbox(ent, hitbox_priority[h], &target_hitbox)) {
|
if (fov > 180.0f)
|
||||||
if (is_hitbox_visible(eye_pos, &target_hitbox)) {
|
fov = 360.0f - fov;
|
||||||
hitbox_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hitbox_found = get_hitbox(ent, current_hitbox, &target_hitbox);
|
|
||||||
if (hitbox_found) {
|
|
||||||
hitbox_found = is_hitbox_visible(eye_pos, &target_hitbox);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hitbox_found)
|
if (fov < best_fov) {
|
||||||
continue;
|
best_fov = fov;
|
||||||
|
vec_copy(best_delta, delta);
|
||||||
vec3_t to_target = vec_sub(target_hitbox.origin, eye_pos);
|
|
||||||
vec3_t aim_angles = vec_to_ang(to_target);
|
|
||||||
|
|
||||||
vec3_t angle_delta = vec_sub(aim_angles, viewangles);
|
|
||||||
vec_norm(&angle_delta);
|
|
||||||
ang_clamp(&angle_delta);
|
|
||||||
|
|
||||||
float fov_distance = sqrtf(angle_delta.x * angle_delta.x + angle_delta.y * angle_delta.y);
|
|
||||||
|
|
||||||
if (fov_distance > max_fov)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float distance = sqrtf(to_target.x * to_target.x + to_target.y * to_target.y + to_target.z * to_target.z);
|
|
||||||
|
|
||||||
float fov_score = 1.0f - (fov_distance / max_fov);
|
|
||||||
|
|
||||||
int priority = get_target_priority(ent);
|
|
||||||
float priority_score = priority / (float)PRIORITY_HIGH;
|
|
||||||
|
|
||||||
float distance_score = 1.0f - fmin(1.0f, distance / 3000.0f);
|
|
||||||
|
|
||||||
float final_score = (fov_score * 0.6f) + (priority_score * 0.3f) + (distance_score * 0.1f);
|
|
||||||
|
|
||||||
if (final_score > best_score) {
|
|
||||||
best_score = final_score;
|
|
||||||
best_target.entity = ent;
|
|
||||||
best_target.fov = fov_distance;
|
|
||||||
vec_copy(best_target.aim_point, target_hitbox.origin);
|
|
||||||
best_target.is_visible = true;
|
|
||||||
best_target.priority = priority;
|
|
||||||
best_target.distance = distance;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return best_target;
|
return best_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RECOIL_DETECTION_MULT 1.0f
|
|
||||||
#define RECOIL_DECAY_RATE 0.5f
|
|
||||||
|
|
||||||
static vec3_t s_last_viewangles = {0, 0, 0};
|
|
||||||
static vec3_t s_punch_angles = {0, 0, 0};
|
|
||||||
static int s_firing_frames = 0;
|
|
||||||
|
|
||||||
void aimbot(usercmd_t* cmd) {
|
void aimbot(usercmd_t* cmd) {
|
||||||
if (!g_settings.aimbot_enabled)
|
if (!CVAR_ON(aimbot) || !(cmd->buttons & IN_ATTACK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!is_alive(localplayer))
|
/* Calculate delta with the engine viewangles, not with the cmd ones */
|
||||||
return;
|
|
||||||
|
|
||||||
if (g_settings.aimbot_require_key && !(cmd->buttons & IN_ATTACK))
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool can_fire = g_flCurrentTime >= g_flNextPrimaryAttack;
|
|
||||||
|
|
||||||
vec3_t eye_pos;
|
|
||||||
vec_copy(eye_pos, localplayer->origin);
|
|
||||||
eye_pos.z += 28.0f;
|
|
||||||
|
|
||||||
vec3_t viewangles;
|
|
||||||
i_engine->GetViewAngles(viewangles);
|
|
||||||
|
|
||||||
static int shot_count = 0;
|
|
||||||
static float last_shot_time = 0.0f;
|
|
||||||
|
|
||||||
if (cmd->buttons & IN_ATTACK) {
|
|
||||||
if (g_flCurrentTime - last_shot_time > 0.08f) {
|
|
||||||
shot_count++;
|
|
||||||
last_shot_time = g_flCurrentTime;
|
|
||||||
|
|
||||||
if (shot_count % 5 == 0) {
|
|
||||||
i_engine->Con_Printf("Shot counter: %d shots in spray\n", shot_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (g_flCurrentTime - last_shot_time > 0.25f) {
|
|
||||||
if (shot_count > 3) {
|
|
||||||
i_engine->Con_Printf("Reset shot counter from %d\n", shot_count);
|
|
||||||
}
|
|
||||||
shot_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd->buttons & IN_ATTACK) {
|
|
||||||
if (g_currentWeaponID == WEAPON_AK47) {
|
|
||||||
viewangles.x -= g_punchAngles[0] * 1.2f;
|
|
||||||
viewangles.y -= g_punchAngles[1] * 0.8f;
|
|
||||||
|
|
||||||
if (shot_count >= 3) {
|
|
||||||
float extra_comp = CLAMP((shot_count - 2) * 0.3f, 0.0f, 3.0f);
|
|
||||||
viewangles.x -= extra_comp;
|
|
||||||
|
|
||||||
if (shot_count % 5 == 0) {
|
|
||||||
i_engine->Con_Printf("AK-47 Extra comp: %.1f degrees down\n", extra_comp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
viewangles.x -= g_punchAngles[0] * 0.6f;
|
|
||||||
viewangles.y -= g_punchAngles[1] * 0.4f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
target_t best_target = get_best_target(viewangles, eye_pos);
|
|
||||||
|
|
||||||
if (!best_target.entity) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t aim_direction = vec_sub(best_target.aim_point, eye_pos);
|
|
||||||
vec3_t aim_angles = vec_to_ang(aim_direction);
|
|
||||||
|
|
||||||
if (g_currentWeaponID == WEAPON_AK47) {
|
|
||||||
if (shot_count > 0) {
|
|
||||||
float ak_compensation = CLAMP(shot_count * 0.25f, 0.0f, 6.0f);
|
|
||||||
|
|
||||||
aim_angles.x -= ak_compensation;
|
|
||||||
|
|
||||||
if (shot_count % 5 == 0) {
|
|
||||||
i_engine->Con_Printf("AK-47 aim adjust: Shot %d, Aiming %.1f lower\n",
|
|
||||||
shot_count, ak_compensation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t engine_viewangles;
|
vec3_t engine_viewangles;
|
||||||
i_engine->GetViewAngles(engine_viewangles);
|
i_engine->GetViewAngles(engine_viewangles);
|
||||||
|
|
||||||
if (g_settings.aimbot_smoothing_enabled && !g_settings.aimbot_silent) {
|
/* TODO: Add setting for lowest health */
|
||||||
vec3_t delta;
|
vec3_t best_delta = get_closest_delta(engine_viewangles);
|
||||||
delta.x = aim_angles.x - engine_viewangles.x;
|
if (!vec_is_zero(best_delta)) {
|
||||||
delta.y = aim_angles.y - engine_viewangles.y;
|
/* NOTE: We can divide the best delta here to add smoothing */
|
||||||
delta.z = 0.0f;
|
|
||||||
|
engine_viewangles.x += best_delta.x;
|
||||||
if (delta.y > 180.0f) delta.y -= 360.0f;
|
engine_viewangles.y += best_delta.y;
|
||||||
if (delta.y < -180.0f) delta.y += 360.0f;
|
engine_viewangles.z += best_delta.z;
|
||||||
|
|
||||||
float smooth_factor = g_settings.aimbot_smooth;
|
|
||||||
|
|
||||||
if (g_currentWeaponID == WEAPON_AK47 && shot_count > 1) {
|
|
||||||
smooth_factor *= 0.7f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (best_target.fov < g_settings.aimbot_fov * 0.5f) {
|
|
||||||
smooth_factor *= 0.6f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (smooth_factor < 1.0f) smooth_factor = 1.0f;
|
|
||||||
|
|
||||||
vec3_t smooth_angles;
|
|
||||||
smooth_angles.x = engine_viewangles.x + delta.x / smooth_factor;
|
|
||||||
smooth_angles.y = engine_viewangles.y + delta.y / smooth_factor;
|
|
||||||
smooth_angles.z = 0.0f;
|
|
||||||
|
|
||||||
ang_clamp(&smooth_angles);
|
|
||||||
|
|
||||||
engine_viewangles = smooth_angles;
|
|
||||||
|
|
||||||
i_engine->SetViewAngles(engine_viewangles);
|
|
||||||
}
|
|
||||||
else if (g_settings.aimbot_silent) {
|
|
||||||
vec_copy(cmd->viewangles, aim_angles);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
engine_viewangles = aim_angles;
|
|
||||||
i_engine->SetViewAngles(engine_viewangles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_settings.aimbot_autoshoot && best_target.is_visible && can_fire) {
|
vec_copy(cmd->viewangles, engine_viewangles);
|
||||||
cmd->buttons |= IN_ATTACK;
|
|
||||||
}
|
/* NOTE: Uncomment to disable silent aim */
|
||||||
}
|
/* i_engine->SetViewAngles(engine_viewangles); */
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,323 +0,0 @@
|
|||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/keysym.h>
|
|
||||||
|
|
||||||
#include "features.h"
|
|
||||||
#include "../include/sdk.h"
|
|
||||||
#include "../include/settings.h"
|
|
||||||
#include "../include/util.h"
|
|
||||||
#include "../include/globals.h"
|
|
||||||
|
|
||||||
#define AA_PITCH_NONE 0
|
|
||||||
#define AA_PITCH_DOWN 1
|
|
||||||
#define AA_PITCH_UP 2
|
|
||||||
#define AA_PITCH_ZERO 3
|
|
||||||
#define AA_PITCH_JITTER 4
|
|
||||||
#define AA_PITCH_CUSTOM 5
|
|
||||||
|
|
||||||
#define AA_YAW_NONE 0
|
|
||||||
#define AA_YAW_BACKWARD 1
|
|
||||||
#define AA_YAW_SPIN 2
|
|
||||||
#define AA_YAW_JITTER 3
|
|
||||||
#define AA_YAW_SIDEWAYS 4
|
|
||||||
#define AA_YAW_CUSTOM 5
|
|
||||||
|
|
||||||
static float spin_angle = 0.0f;
|
|
||||||
static float last_update_time = 0.0f;
|
|
||||||
static float jitter_next_update = 0.0f;
|
|
||||||
|
|
||||||
float random_float(float min, float max) {
|
|
||||||
return (max - min) * ((float)rand() / (float)RAND_MAX) + min;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSpacebarPressed() {
|
|
||||||
Display* display = XOpenDisplay(NULL);
|
|
||||||
if (!display) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char keys_return[32];
|
|
||||||
XQueryKeymap(display, keys_return);
|
|
||||||
KeyCode kc = XKeysymToKeycode(display, XK_space);
|
|
||||||
bool pressed = (keys_return[kc >> 3] & (1 << (kc & 7))) != 0;
|
|
||||||
|
|
||||||
XCloseDisplay(display);
|
|
||||||
return pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_key_pressed(int key_code) {
|
|
||||||
if (key_code <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Display* display = XOpenDisplay(NULL);
|
|
||||||
if (!display) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char keys_return[32];
|
|
||||||
XQueryKeymap(display, keys_return);
|
|
||||||
|
|
||||||
KeyCode kc;
|
|
||||||
if (key_code >= 'A' && key_code <= 'Z') {
|
|
||||||
kc = XKeysymToKeycode(display, XK_a + (key_code - 'A'));
|
|
||||||
} else if (key_code >= 'a' && key_code <= 'z') {
|
|
||||||
kc = XKeysymToKeycode(display, XK_a + (key_code - 'a'));
|
|
||||||
} else {
|
|
||||||
switch (key_code) {
|
|
||||||
case K_SPACE: kc = XKeysymToKeycode(display, XK_space); break;
|
|
||||||
case K_CTRL: kc = XKeysymToKeycode(display, XK_Control_L); break;
|
|
||||||
case K_SHIFT: kc = XKeysymToKeycode(display, XK_Shift_L); break;
|
|
||||||
case K_ALT: kc = XKeysymToKeycode(display, XK_Alt_L); break;
|
|
||||||
case K_TAB: kc = XKeysymToKeycode(display, XK_Tab); break;
|
|
||||||
default: kc = XKeysymToKeycode(display, key_code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pressed = (keys_return[kc >> 3] & (1 << (kc & 7))) != 0;
|
|
||||||
XCloseDisplay(display);
|
|
||||||
return pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply_pitch_anti_aim(vec3_t* view_angles, int pitch_mode, float custom_pitch) {
|
|
||||||
switch (pitch_mode) {
|
|
||||||
case AA_PITCH_DOWN:
|
|
||||||
view_angles->x = 89.0f;
|
|
||||||
break;
|
|
||||||
case AA_PITCH_UP:
|
|
||||||
view_angles->x = -89.0f;
|
|
||||||
break;
|
|
||||||
case AA_PITCH_ZERO:
|
|
||||||
view_angles->x = 0.0f;
|
|
||||||
break;
|
|
||||||
case AA_PITCH_JITTER: {
|
|
||||||
static bool flip_pitch = false;
|
|
||||||
if (flip_pitch) {
|
|
||||||
view_angles->x = 89.0f;
|
|
||||||
} else {
|
|
||||||
view_angles->x = -89.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_flCurrentTime > jitter_next_update) {
|
|
||||||
flip_pitch = !flip_pitch;
|
|
||||||
jitter_next_update = g_flCurrentTime + random_float(0.1f, 0.3f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AA_PITCH_CUSTOM:
|
|
||||||
view_angles->x = CLAMP(custom_pitch, -89.0f, 89.0f);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply_yaw_anti_aim(vec3_t* view_angles, int yaw_mode, float custom_yaw, float speed, float jitter_range) {
|
|
||||||
float time_now;
|
|
||||||
float time_delta;
|
|
||||||
static bool is_left = true;
|
|
||||||
|
|
||||||
switch (yaw_mode) {
|
|
||||||
case AA_YAW_BACKWARD:
|
|
||||||
view_angles->y += 180.0f;
|
|
||||||
break;
|
|
||||||
case AA_YAW_SPIN:
|
|
||||||
time_now = g_flCurrentTime;
|
|
||||||
time_delta = time_now - last_update_time;
|
|
||||||
|
|
||||||
spin_angle += time_delta * speed;
|
|
||||||
|
|
||||||
if (spin_angle > 360.0f) {
|
|
||||||
spin_angle -= 360.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
view_angles->y = spin_angle;
|
|
||||||
|
|
||||||
last_update_time = time_now;
|
|
||||||
break;
|
|
||||||
case AA_YAW_JITTER:
|
|
||||||
if (g_flCurrentTime > jitter_next_update) {
|
|
||||||
view_angles->y += random_float(-jitter_range, jitter_range);
|
|
||||||
jitter_next_update = g_flCurrentTime + random_float(0.1f, 0.3f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AA_YAW_SIDEWAYS:
|
|
||||||
if (g_flCurrentTime > jitter_next_update) {
|
|
||||||
is_left = !is_left;
|
|
||||||
jitter_next_update = g_flCurrentTime + random_float(0.5f, 1.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_left) {
|
|
||||||
view_angles->y += 90.0f;
|
|
||||||
} else {
|
|
||||||
view_angles->y -= 90.0f;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AA_YAW_CUSTOM:
|
|
||||||
view_angles->y = custom_yaw;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply_lby_breaker(vec3_t* view_angles, bool enable_breaker) {
|
|
||||||
if (!enable_breaker)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static bool lby_update = false;
|
|
||||||
static float next_lby_update = 0.0f;
|
|
||||||
|
|
||||||
if (g_flCurrentTime > next_lby_update) {
|
|
||||||
lby_update = !lby_update;
|
|
||||||
next_lby_update = g_flCurrentTime + 1.1f;
|
|
||||||
|
|
||||||
if (lby_update) {
|
|
||||||
view_angles->y += 120.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply_fake_duck(usercmd_t* cmd, bool enable_duck) {
|
|
||||||
if (!enable_duck)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static int duck_state = 0;
|
|
||||||
static float next_duck_time = 0.0f;
|
|
||||||
|
|
||||||
if (g_flCurrentTime > next_duck_time) {
|
|
||||||
duck_state = (duck_state + 1) % 4;
|
|
||||||
next_duck_time = g_flCurrentTime + 0.05f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (duck_state < 2) {
|
|
||||||
cmd->buttons |= IN_DUCK;
|
|
||||||
} else {
|
|
||||||
cmd->buttons &= ~IN_DUCK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void anti_aim(usercmd_t* cmd) {
|
|
||||||
if (!g_settings.antiaim_enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_alive(localplayer)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cmd->buttons & IN_ATTACK) && !g_settings.antiaim_on_attack) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd->buttons & IN_USE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t view_angles;
|
|
||||||
i_engine->GetViewAngles(view_angles);
|
|
||||||
|
|
||||||
if (g_settings.antiaim_pitch_enabled) {
|
|
||||||
if (g_settings.antiaim_pitch_mode == 0) {
|
|
||||||
view_angles.x = g_settings.antiaim_pitch;
|
|
||||||
|
|
||||||
view_angles.x = CLAMP(view_angles.x, -89.0f, 89.0f);
|
|
||||||
} else {
|
|
||||||
apply_pitch_anti_aim(&view_angles, g_settings.antiaim_pitch_mode, g_settings.antiaim_custom_pitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static float last_debug_time = 0.0f;
|
|
||||||
if (g_flCurrentTime > last_debug_time + 5.0f) {
|
|
||||||
i_engine->Con_Printf("Anti-Aim: Applied pitch angle %.1f (mode %d)\n",
|
|
||||||
view_angles.x, g_settings.antiaim_pitch_mode);
|
|
||||||
last_debug_time = g_flCurrentTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.antiaim_yaw_enabled) {
|
|
||||||
if (g_settings.antiaim_yaw_mode == 0) {
|
|
||||||
if (g_settings.antiaim_legit) {
|
|
||||||
float legit_yaw_max = 35.0f;
|
|
||||||
view_angles.y += CLAMP(g_settings.antiaim_yaw, -legit_yaw_max, legit_yaw_max);
|
|
||||||
} else {
|
|
||||||
view_angles.y += g_settings.antiaim_yaw;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
apply_yaw_anti_aim(&view_angles, g_settings.antiaim_yaw_mode, g_settings.antiaim_custom_yaw,
|
|
||||||
g_settings.antiaim_spin_speed, g_settings.antiaim_jitter_range);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (view_angles.y > 180.0f) view_angles.y -= 360.0f;
|
|
||||||
if (view_angles.y < -180.0f) view_angles.y += 360.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
apply_lby_breaker(&view_angles, g_settings.antiaim_lby_breaker);
|
|
||||||
|
|
||||||
if (g_settings.antiaim_desync) {
|
|
||||||
static bool switch_side = false;
|
|
||||||
static float next_switch = 0.0f;
|
|
||||||
|
|
||||||
if (g_flCurrentTime > next_switch) {
|
|
||||||
switch_side = !switch_side;
|
|
||||||
next_switch = g_flCurrentTime + random_float(0.4f, 0.8f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_settings.antiaim_view) {
|
|
||||||
vec3_t real_angles;
|
|
||||||
i_engine->GetViewAngles(real_angles);
|
|
||||||
|
|
||||||
vec3_t server_angles;
|
|
||||||
vec_copy(server_angles, real_angles);
|
|
||||||
server_angles.y += (switch_side ? 58.0f : -58.0f);
|
|
||||||
|
|
||||||
if (server_angles.y > 180.0f) server_angles.y -= 360.0f;
|
|
||||||
if (server_angles.y < -180.0f) server_angles.y += 360.0f;
|
|
||||||
|
|
||||||
vec_copy(cmd->viewangles, server_angles);
|
|
||||||
i_engine->SetViewAngles(real_angles);
|
|
||||||
|
|
||||||
static float last_desync_log = 0.0f;
|
|
||||||
if (g_flCurrentTime > last_desync_log + 3.0f) {
|
|
||||||
i_engine->Con_Printf("Desync active: Server %.1f, Client %.1f (invisible to user)\n",
|
|
||||||
server_angles.y, real_angles.y);
|
|
||||||
last_desync_log = g_flCurrentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float desync_amount = switch_side ? 58.0f : -58.0f;
|
|
||||||
view_angles.y += desync_amount;
|
|
||||||
|
|
||||||
if (view_angles.y > 180.0f) view_angles.y -= 360.0f;
|
|
||||||
if (view_angles.y < -180.0f) view_angles.y += 360.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool should_fake_duck = false;
|
|
||||||
|
|
||||||
if (g_settings.antiaim_fakeduck_key > 0) {
|
|
||||||
should_fake_duck = g_settings.antiaim_fakeduck && is_key_pressed(g_settings.antiaim_fakeduck_key);
|
|
||||||
} else {
|
|
||||||
should_fake_duck = g_settings.antiaim_fakeduck;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (should_fake_duck) {
|
|
||||||
apply_fake_duck(cmd, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.antiaim_view) {
|
|
||||||
i_engine->SetViewAngles(view_angles);
|
|
||||||
} else {
|
|
||||||
vec_copy(cmd->viewangles, view_angles);
|
|
||||||
}
|
|
||||||
|
|
||||||
static float last_log_time = 0.0f;
|
|
||||||
if (g_flCurrentTime > last_log_time + 5.0f) {
|
|
||||||
i_engine->Con_Printf("Anti-Aim active: Pitch=%.1f, Yaw=%.1f, Mode=%d/%d\n",
|
|
||||||
view_angles.x, view_angles.y,
|
|
||||||
g_settings.antiaim_pitch_mode, g_settings.antiaim_yaw_mode);
|
|
||||||
last_log_time = g_flCurrentTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
#include "features.h"
|
#include "features.h"
|
||||||
#include "../include/globals.h"
|
#include "../include/globals.h"
|
||||||
#include "../include/settings.h"
|
#include "../include/cvars.h"
|
||||||
#include "../include/util.h"
|
#include "../include/util.h"
|
||||||
|
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
@@ -14,7 +15,7 @@ enum chams_settings {
|
|||||||
visible_flags visible_mode;
|
visible_flags visible_mode;
|
||||||
|
|
||||||
bool chams(void* this_ptr) {
|
bool chams(void* this_ptr) {
|
||||||
const int setting = g_settings.chams ? PLAYER_CHAMS : DISABLED;
|
const int setting = cv_chams->value == 5.0f ? 7 : cv_chams->value;
|
||||||
if (setting == DISABLED)
|
if (setting == DISABLED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -38,9 +39,6 @@ bool chams(void* this_ptr) {
|
|||||||
|
|
||||||
const bool friendly = is_friend(ent);
|
const bool friendly = is_friend(ent);
|
||||||
|
|
||||||
if (friendly && !g_settings.esp_friendly)
|
|
||||||
return false; // Do not render chams for friendlies
|
|
||||||
|
|
||||||
/* If we got here it means we are rendering a valid player */
|
/* If we got here it means we are rendering a valid player */
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "features.h"
|
#include "features.h"
|
||||||
#include "../include/globals.h"
|
#include "../include/globals.h"
|
||||||
#include "../include/settings.h"
|
#include "../include/cvars.h"
|
||||||
#include "../include/util.h"
|
#include "../include/util.h"
|
||||||
#include "../include/game_detection.h"
|
|
||||||
|
|
||||||
// ESP enums moved to settings.h as esp_mode_t
|
/* For cv_esp */
|
||||||
|
enum esp_values {
|
||||||
|
ESP_OFF = 0,
|
||||||
|
ESP_BOX = 1,
|
||||||
|
ESP_NAME = 2,
|
||||||
|
/* ESP_ALL should be 3 but we can just OR box and name */
|
||||||
|
};
|
||||||
|
|
||||||
bool gl_draw3dbox(vec3_t o, int bh, int bw, int lw) {
|
bool gl_draw3dbox(vec3_t o, int bh, int bw, int lw) {
|
||||||
/*
|
/*
|
||||||
@@ -92,36 +98,38 @@ static bool gl_draw2dbox(vec3_t o, int bh) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void esp(void) {
|
void esp(void) {
|
||||||
const int setting = g_settings.esp_mode;
|
const int setting = (int)cv_esp->value;
|
||||||
if (setting == ESP_OFF)
|
if (setting == ESP_OFF)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Iterate all clients */
|
||||||
for (int i = 1; i <= i_engine->GetMaxClients(); i++) {
|
for (int i = 1; i <= i_engine->GetMaxClients(); i++) {
|
||||||
cl_entity_t* ent = get_player(i);
|
cl_entity_t* ent = get_player(i);
|
||||||
|
|
||||||
if (!valid_player(ent) || !is_alive(ent) || vec_is_zero(ent->origin))
|
if (!valid_player(ent) || !is_alive(ent) || vec_is_zero(ent->origin))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (is_friend(ent) && !g_settings.esp_friendly)
|
const int bh = (ent->curstate.usehull == 1) ? 44 : 70;
|
||||||
continue;
|
/* const int bw = 25; */
|
||||||
|
|
||||||
int bh = 70;
|
|
||||||
if (IsDayOfDefeat()) {
|
|
||||||
bh = 76;
|
|
||||||
} else if (ent->curstate.usehull == 1) {
|
|
||||||
bh = 44;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* If ESP_BOX is enabled, draw it. If it returns false, continue */
|
||||||
if (setting & ESP_BOX && !gl_draw2dbox(ent->origin, bh))
|
if (setting & ESP_BOX && !gl_draw2dbox(ent->origin, bh))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* Rest of the loop is for name esp, if var is not enabled, continue */
|
||||||
if (!(setting & ESP_NAME))
|
if (!(setting & ESP_NAME))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vec3_t name_pos = vec3(ent->origin.x, ent->origin.y, ent->origin.z + bh + 5);
|
/* Draw name on top of the player. */
|
||||||
vec2_t s_name_pos;
|
vec3_t top = vec3(ent->origin.x, ent->origin.y, ent->origin.z + bh);
|
||||||
if (world_to_screen(name_pos, s_name_pos)) {
|
vec2_t s_top;
|
||||||
engine_draw_text(s_name_pos[0] - 5, s_name_pos[1] - 2, get_name(ent->index), (rgb_t){ 255, 255, 255 });
|
|
||||||
}
|
if (!world_to_screen(top, s_top))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* TODO: Instead of -5px, center the player name to the player origin.
|
||||||
|
* I don't know how to get the text size before rendering. */
|
||||||
|
engine_draw_text(s_top[0] - 5, s_top[1] - 2, get_name(ent->index),
|
||||||
|
(rgb_t){ 255, 255, 255 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
#ifndef FEATURES_H_
|
#ifndef FEATURES_H_
|
||||||
#define FEATURES_H_
|
#define FEATURES_H_
|
||||||
|
|
||||||
@@ -10,13 +11,8 @@ enum visible_flags {
|
|||||||
FRIEND_VISIBLE = 3,
|
FRIEND_VISIBLE = 3,
|
||||||
FRIEND_NOT_VISIBLE = 4,
|
FRIEND_NOT_VISIBLE = 4,
|
||||||
HANDS = 5,
|
HANDS = 5,
|
||||||
SCOPE = 6,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* src/features/movement.c */
|
/* src/features/movement.c */
|
||||||
@@ -33,29 +29,7 @@ bool chams(void* this_ptr);
|
|||||||
/* src/features/aim.c */
|
/* src/features/aim.c */
|
||||||
void aimbot(usercmd_t* cmd);
|
void aimbot(usercmd_t* cmd);
|
||||||
|
|
||||||
/* src/features/no_recoil.c */
|
|
||||||
void no_recoil(usercmd_t* cmd);
|
|
||||||
|
|
||||||
/* src/features/misc.c */
|
/* src/features/misc.c */
|
||||||
void custom_crosshair(void);
|
void custom_crosshair(void);
|
||||||
void bullet_tracers(usercmd_t* cmd);
|
|
||||||
|
|
||||||
/* src/features/namechanger.c */
|
#endif /* FEATURES_H_ */
|
||||||
void check_namechanger_mode_and_execute(usercmd_t* cmd);
|
|
||||||
|
|
||||||
/* src/features/anti_aim.c */
|
|
||||||
void anti_aim(usercmd_t* cmd);
|
|
||||||
|
|
||||||
/* src/features/fov.c */
|
|
||||||
void fov_adjust(usercmd_t* cmd);
|
|
||||||
|
|
||||||
/* src/features/thirdperson.c */
|
|
||||||
void thirdperson_init(void);
|
|
||||||
void thirdperson_update(void);
|
|
||||||
bool thirdperson_key_event(int keynum, int down);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FEATURES_H_ */
|
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "../include/globals.h"
|
|
||||||
#include "../include/sdk.h"
|
|
||||||
#include "../include/util.h"
|
|
||||||
#include "../include/settings.h"
|
|
||||||
#include "features.h"
|
|
||||||
|
|
||||||
extern float* scr_fov_value;
|
|
||||||
|
|
||||||
void fov_adjust(usercmd_t* cmd) {
|
|
||||||
if (!scr_fov_value) {
|
|
||||||
printf("FOV ERROR: Check globals.c missing scr_fov_value.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.fov > 0) {
|
|
||||||
*scr_fov_value = g_settings.fov;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
#include "features.h"
|
#include "features.h"
|
||||||
#include "../include/sdk.h"
|
#include "../include/sdk.h"
|
||||||
#include "../include/globals.h"
|
#include "../include/globals.h"
|
||||||
|
#include "../include/cvars.h"
|
||||||
#include "../include/util.h"
|
#include "../include/util.h"
|
||||||
#include "../include/game_detection.h"
|
|
||||||
#include "../include/settings.h"
|
|
||||||
|
|
||||||
void custom_crosshair(void) {
|
void custom_crosshair(void) {
|
||||||
if (!g_settings.custom_crosshair)
|
if (!CVAR_ON(crosshair))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Get window size, and then the center. */
|
/* Get window size, and then the center. */
|
||||||
@@ -14,7 +14,7 @@ void custom_crosshair(void) {
|
|||||||
int my = game_info->m_height / 2;
|
int my = game_info->m_height / 2;
|
||||||
|
|
||||||
/* The real length is sqrt(2 * (len^2)) */
|
/* The real length is sqrt(2 * (len^2)) */
|
||||||
const int len = 5;
|
const int len = cv_crosshair->value;
|
||||||
const int gap = 1;
|
const int gap = 1;
|
||||||
const float w = 1;
|
const float w = 1;
|
||||||
const rgb_t col = { 255, 255, 255 };
|
const rgb_t col = { 255, 255, 255 };
|
||||||
@@ -29,53 +29,3 @@ void custom_crosshair(void) {
|
|||||||
gl_drawline(mx - gap, my + gap, mx - gap - len, my + gap + len, w, col);
|
gl_drawline(mx - gap, my + gap, mx - gap - len, my + gap + len, w, col);
|
||||||
gl_drawline(mx + gap, my + gap, mx + gap + len, my + gap + len, w, col);
|
gl_drawline(mx + gap, my + gap, mx + gap + len, my + gap + len, w, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
weapon_data_t g_currentWeapon;
|
|
||||||
static double lastTracerTime = 0;
|
|
||||||
|
|
||||||
static bool attackReleased = true;
|
|
||||||
|
|
||||||
void bullet_tracers(usercmd_t* cmd) {
|
|
||||||
if (!g_settings.tracers || !is_alive(localplayer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (IsCS16()) {
|
|
||||||
if (cmd->buttons & IN_ATTACK) {
|
|
||||||
if (!attackReleased) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
attackReleased = false;
|
|
||||||
} else {
|
|
||||||
attackReleased = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!can_shoot()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!(cmd->buttons & IN_ATTACK) || !can_shoot()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get player eye pos, start of tracer */
|
|
||||||
vec3_t view_height;
|
|
||||||
i_engine->pEventAPI->EV_LocalPlayerViewheight(view_height);
|
|
||||||
vec3_t local_eyes = vec_add(localplayer->origin, view_height);
|
|
||||||
|
|
||||||
/* Get forward vector from viewangles */
|
|
||||||
vec3_t fwd;
|
|
||||||
i_engine->pfnAngleVectors(cmd->viewangles, fwd, NULL, NULL);
|
|
||||||
|
|
||||||
const int tracer_len = 3000;
|
|
||||||
vec3_t end;
|
|
||||||
end.x = local_eyes.x + fwd.x * tracer_len;
|
|
||||||
end.y = local_eyes.y + fwd.y * tracer_len;
|
|
||||||
end.z = local_eyes.z + fwd.z * tracer_len;
|
|
||||||
|
|
||||||
/* NOTE: Change tracer settings here */
|
|
||||||
const float w = 0.8;
|
|
||||||
const float time = 2;
|
|
||||||
draw_tracer(local_eyes, end, (rgb_t){ 66, 165, 245 }, 1, w, time);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "features.h"
|
#include "features.h"
|
||||||
#include "../include/sdk.h"
|
#include "../include/sdk.h"
|
||||||
#include "../include/globals.h"
|
#include "../include/globals.h"
|
||||||
#include "../include/settings.h"
|
#include "../include/cvars.h"
|
||||||
#include "../include/util.h"
|
#include "../include/util.h"
|
||||||
|
|
||||||
static void autostrafe_legit(usercmd_t* cmd) {
|
static void autostrafe_legit(usercmd_t* cmd) {
|
||||||
@@ -23,8 +24,6 @@ static void autostrafe_legit(usercmd_t* cmd) {
|
|||||||
* https://github.com/deboogerxyz/ahc/blob/0492646e28dd7234a8cd431d37b152dc18a21b04/ahc.c#L201
|
* https://github.com/deboogerxyz/ahc/blob/0492646e28dd7234a8cd431d37b152dc18a21b04/ahc.c#L201
|
||||||
* https://github.com/NullHooks/NullHooks/blob/535351569ca599cadd21a286d88098b6dc057a46/src/core/features/movement/bhop.cpp#L73
|
* https://github.com/NullHooks/NullHooks/blob/535351569ca599cadd21a286d88098b6dc057a46/src/core/features/movement/bhop.cpp#L73
|
||||||
*/
|
*/
|
||||||
static const float DEG2RAD_CACHED = M_PI / 180.0f;
|
|
||||||
|
|
||||||
static void autostrafe_rage(usercmd_t* cmd) {
|
static void autostrafe_rage(usercmd_t* cmd) {
|
||||||
if (i_pmove->movetype != MOVETYPE_WALK)
|
if (i_pmove->movetype != MOVETYPE_WALK)
|
||||||
return;
|
return;
|
||||||
@@ -32,7 +31,7 @@ static void autostrafe_rage(usercmd_t* cmd) {
|
|||||||
/* TODO: Get at runtime */
|
/* TODO: Get at runtime */
|
||||||
const float sv_airaccelerate = 10.0f;
|
const float sv_airaccelerate = 10.0f;
|
||||||
const float sv_maxspeed = 320.0f;
|
const float sv_maxspeed = 320.0f;
|
||||||
const float cl_forwardspeed = 425.0f;
|
const float cl_forwardspeed = 400.0f;
|
||||||
const float cl_sidespeed = 400.0f;
|
const float cl_sidespeed = 400.0f;
|
||||||
|
|
||||||
float speed = vec_len2d(i_pmove->velocity);
|
float speed = vec_len2d(i_pmove->velocity);
|
||||||
@@ -49,22 +48,24 @@ static void autostrafe_rage(usercmd_t* cmd) {
|
|||||||
|
|
||||||
float best_delta = acosf(term);
|
float best_delta = acosf(term);
|
||||||
|
|
||||||
|
/* Use engine viewangles in case we do something nasty with cmd's angles */
|
||||||
vec3_t viewangles;
|
vec3_t viewangles;
|
||||||
i_engine->GetViewAngles(viewangles);
|
i_engine->GetViewAngles(viewangles);
|
||||||
|
|
||||||
float yaw = viewangles.y * DEG2RAD_CACHED;
|
/* Get our desired angles and delta */
|
||||||
float vel_dir = atan2f(i_pmove->velocity.y, i_pmove->velocity.x) - yaw;
|
float yaw = DEG2RAD(viewangles.y);
|
||||||
|
float vel_dir = atan2f(i_pmove->velocity.y, i_pmove->velocity.x) - yaw;
|
||||||
float target_ang = atan2f(-cmd->sidemove, cmd->forwardmove);
|
float target_ang = atan2f(-cmd->sidemove, cmd->forwardmove);
|
||||||
float delta = angle_delta_rad(vel_dir, target_ang);
|
float delta = angle_delta_rad(vel_dir, target_ang);
|
||||||
|
|
||||||
float movedir = delta < 0 ? vel_dir + best_delta : vel_dir - best_delta;
|
float movedir = delta < 0 ? vel_dir + best_delta : vel_dir - best_delta;
|
||||||
|
|
||||||
cmd->forwardmove = cosf(movedir) * cl_forwardspeed;
|
cmd->forwardmove = cosf(movedir) * cl_forwardspeed;
|
||||||
cmd->sidemove = -sinf(movedir) * cl_sidespeed;
|
cmd->sidemove = -sinf(movedir) * cl_sidespeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bhop(usercmd_t* cmd) {
|
void bhop(usercmd_t* cmd) {
|
||||||
if (!g_settings.bhop || i_pmove->movetype != MOVETYPE_WALK)
|
if (!CVAR_ON(bhop) || i_pmove->movetype != MOVETYPE_WALK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static bool was_in_air = false;
|
static bool was_in_air = false;
|
||||||
@@ -80,8 +81,18 @@ void bhop(usercmd_t* cmd) {
|
|||||||
was_in_air = (i_pmove->flags & FL_ONGROUND) == 0;
|
was_in_air = (i_pmove->flags & FL_ONGROUND) == 0;
|
||||||
|
|
||||||
/* Autostrafe if enabled. Check if we are in the air and holding space. */
|
/* Autostrafe if enabled. Check if we are in the air and holding space. */
|
||||||
if (is_jumping && g_settings.autostrafe) {
|
if (is_jumping) {
|
||||||
autostrafe_rage(cmd);
|
switch ((int)cv_autostrafe->value) {
|
||||||
|
case 1:
|
||||||
|
autostrafe_rage(cmd);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
autostrafe_legit(cmd);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,15 +101,18 @@ void bhop(usercmd_t* cmd) {
|
|||||||
* https://github.com/deboogerxyz/ahc/blob/0492646e28dd7234a8cd431d37b152dc18a21b04/ahc.c#L377
|
* https://github.com/deboogerxyz/ahc/blob/0492646e28dd7234a8cd431d37b152dc18a21b04/ahc.c#L377
|
||||||
*/
|
*/
|
||||||
void correct_movement(usercmd_t* cmd, vec3_t old_angles) {
|
void correct_movement(usercmd_t* cmd, vec3_t old_angles) {
|
||||||
float delta_y = fmodf(cmd->viewangles.y - old_angles.y + 540.0f, 360.0f) - 180.0f; // Normalized delta in [-180, 180)
|
float old_y = old_angles.y + (old_angles.y < 0 ? 360 : 0);
|
||||||
|
float new_y = cmd->viewangles.y + (cmd->viewangles.y < 0 ? 360 : 0);
|
||||||
float delta_rad = delta_y * DEG2RAD_CACHED;
|
float delta = (new_y < old_y) ? fabsf(new_y - old_y)
|
||||||
float delta_cos = cosf(delta_rad);
|
: 360 - fabsf(new_y - old_y);
|
||||||
float delta_sin = sinf(delta_rad);
|
|
||||||
|
delta = 360 - delta;
|
||||||
|
|
||||||
float forward = cmd->forwardmove;
|
float forward = cmd->forwardmove;
|
||||||
float side = cmd->sidemove;
|
float side = cmd->sidemove;
|
||||||
|
|
||||||
cmd->forwardmove = delta_cos * forward - delta_sin * side;
|
cmd->forwardmove =
|
||||||
cmd->sidemove = delta_sin * forward + delta_cos * side;
|
cos(DEG2RAD(delta)) * forward + cos(DEG2RAD(delta + 90)) * side;
|
||||||
}
|
cmd->sidemove =
|
||||||
|
sin(DEG2RAD(delta)) * forward + sin(DEG2RAD(delta + 90)) * side;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <cstring>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <vector>
|
|
||||||
#include "features.h"
|
|
||||||
#include "../include/globals.h"
|
|
||||||
#include "../include/settings.h"
|
|
||||||
#include "../include/util.h"
|
|
||||||
#include "../include/game_detection.h"
|
|
||||||
|
|
||||||
static int change_counter = 0;
|
|
||||||
#define NAME_CHANGE_INTERVAL 10
|
|
||||||
|
|
||||||
static int last_name_idx = -1;
|
|
||||||
|
|
||||||
void change_name(const char* new_name) {
|
|
||||||
if (!new_name) return;
|
|
||||||
|
|
||||||
char command[256];
|
|
||||||
snprintf(command, sizeof(command), "name \"%s\u0315 \"", new_name);
|
|
||||||
i_engine->pfnClientCmd(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<char*> get_valid_names(bool (*filter)(cl_entity_t*)) {
|
|
||||||
int max_players = 32;
|
|
||||||
std::vector<char*> valid_names;
|
|
||||||
|
|
||||||
for (int i = 0; i < max_players; i++) {
|
|
||||||
cl_entity_t* ent = get_player(i);
|
|
||||||
if (!ent) continue;
|
|
||||||
|
|
||||||
if (!filter || filter(ent)) {
|
|
||||||
valid_names.push_back(get_name(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return valid_names;
|
|
||||||
}
|
|
||||||
|
|
||||||
void change_name_from_list(std::vector<char*>& names) {
|
|
||||||
if (names.empty()) return;
|
|
||||||
|
|
||||||
last_name_idx = (last_name_idx + 1) % names.size();
|
|
||||||
|
|
||||||
char* name = names[last_name_idx];
|
|
||||||
if (name) {
|
|
||||||
change_name(name);
|
|
||||||
printf("Changing name to: %s\n", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void change_name_teammates() {
|
|
||||||
auto names = get_valid_names(is_friend);
|
|
||||||
std::random_shuffle(names.begin(), names.end());
|
|
||||||
change_name_from_list(names);
|
|
||||||
}
|
|
||||||
|
|
||||||
void change_name_enemies() {
|
|
||||||
auto names = get_valid_names([](cl_entity_t* ent) -> bool {
|
|
||||||
return !is_friend(ent);
|
|
||||||
});
|
|
||||||
std::random_shuffle(names.begin(), names.end());
|
|
||||||
change_name_from_list(names);
|
|
||||||
}
|
|
||||||
|
|
||||||
void change_name_all_players() {
|
|
||||||
auto names = get_valid_names(nullptr);
|
|
||||||
std::random_shuffle(names.begin(), names.end());
|
|
||||||
change_name_from_list(names);
|
|
||||||
}
|
|
||||||
|
|
||||||
void change_name_based_on_mode(usercmd_t* cmd) {
|
|
||||||
if (!g_settings.namechanger) return;
|
|
||||||
|
|
||||||
if (++change_counter < g_settings.namechanger_speed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
change_counter = 0;
|
|
||||||
|
|
||||||
int mode = 3;
|
|
||||||
|
|
||||||
if (g_settings.namechanger) {
|
|
||||||
mode = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case 1:
|
|
||||||
change_name_teammates();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
change_name_enemies();
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
change_name_all_players();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_namechanger_mode_and_execute(usercmd_t* cmd) {
|
|
||||||
if (!g_settings.namechanger) return;
|
|
||||||
|
|
||||||
change_name_based_on_mode(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
#include "../include/sdk.h"
|
|
||||||
#include "../include/settings.h"
|
|
||||||
#include "../include/util.h"
|
|
||||||
#include "../include/globals.h"
|
|
||||||
#include "../features/features.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
static time_t last_log_time = 0;
|
|
||||||
static vec3_t last_punch = {0, 0, 0};
|
|
||||||
static vec3_t previous_viewangles = {0, 0, 0};
|
|
||||||
|
|
||||||
#define WEAPON_GLOCK 17
|
|
||||||
#define WEAPON_DEAGLE 26
|
|
||||||
#define WEAPON_AK47 28
|
|
||||||
#define WEAPON_M4A1 22
|
|
||||||
#define WEAPON_AWP 33
|
|
||||||
|
|
||||||
#define AK47_RECOIL_VERT_MULT 2.8f
|
|
||||||
#define AK47_RECOIL_HORIZ_MULT 0.9f
|
|
||||||
#define DEFAULT_RECOIL_VERT_MULT 2.0f
|
|
||||||
#define DEFAULT_RECOIL_HORIZ_MULT 0.6f
|
|
||||||
|
|
||||||
static float ak47_pattern[] = {
|
|
||||||
0.0f,
|
|
||||||
2.2f,
|
|
||||||
3.0f,
|
|
||||||
3.5f,
|
|
||||||
3.9f,
|
|
||||||
4.0f,
|
|
||||||
3.8f,
|
|
||||||
3.5f,
|
|
||||||
3.2f,
|
|
||||||
2.9f,
|
|
||||||
2.7f,
|
|
||||||
2.5f,
|
|
||||||
2.2f,
|
|
||||||
2.0f,
|
|
||||||
1.9f,
|
|
||||||
1.7f,
|
|
||||||
1.6f,
|
|
||||||
1.5f,
|
|
||||||
1.4f,
|
|
||||||
1.3f,
|
|
||||||
1.2f,
|
|
||||||
1.1f,
|
|
||||||
1.0f,
|
|
||||||
0.9f,
|
|
||||||
0.8f,
|
|
||||||
0.8f,
|
|
||||||
0.7f,
|
|
||||||
0.7f,
|
|
||||||
0.6f,
|
|
||||||
0.6f
|
|
||||||
};
|
|
||||||
|
|
||||||
static int bullet_count = 0;
|
|
||||||
static float last_shot_time = 0.0f;
|
|
||||||
static int current_weapon_id = -1;
|
|
||||||
|
|
||||||
void no_recoil(usercmd_t* cmd) {
|
|
||||||
if (!is_alive(localplayer) || (!g_settings.aimbot_norecoil && !g_settings.aimbot_recoil_comp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(cmd->buttons & IN_ATTACK)) {
|
|
||||||
if (g_flCurrentTime - last_shot_time > 0.2f) {
|
|
||||||
if (bullet_count > 0) {
|
|
||||||
i_engine->Con_Printf("Recoil: Reset spray pattern from %d bullets\n", bullet_count);
|
|
||||||
bullet_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t current_viewangles;
|
|
||||||
i_engine->GetViewAngles(current_viewangles);
|
|
||||||
|
|
||||||
bool is_ak47 = false;
|
|
||||||
bool is_high_recoil_weapon = false;
|
|
||||||
|
|
||||||
if (g_currentWeaponID == WEAPON_AK47) {
|
|
||||||
is_ak47 = true;
|
|
||||||
is_high_recoil_weapon = true;
|
|
||||||
}
|
|
||||||
else if (g_currentWeaponID == WEAPON_M4A1) {
|
|
||||||
is_high_recoil_weapon = true;
|
|
||||||
}
|
|
||||||
else if (g_flNextPrimaryAttack - g_flNextAttack < 0.15f) {
|
|
||||||
is_high_recoil_weapon = true;
|
|
||||||
if (g_flNextPrimaryAttack - g_flNextAttack < 0.11f) {
|
|
||||||
is_ak47 = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
last_shot_time = g_flCurrentTime;
|
|
||||||
|
|
||||||
static float last_attack_time = 0.0f;
|
|
||||||
bool is_new_shot = g_flCurrentTime - last_attack_time > 0.05f;
|
|
||||||
|
|
||||||
if (is_new_shot) {
|
|
||||||
bullet_count++;
|
|
||||||
last_attack_time = g_flCurrentTime;
|
|
||||||
|
|
||||||
if (bullet_count > 1 && (bullet_count % 3 == 0 || bullet_count <= 5)) {
|
|
||||||
i_engine->Con_Printf("Recoil comp: Shot #%d, Weapon: %s\n",
|
|
||||||
bullet_count, is_ak47 ? "AK-47" : (is_high_recoil_weapon ? "High Recoil" : "Standard"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t punch_angles;
|
|
||||||
vec_copy(punch_angles, g_punchAngles);
|
|
||||||
|
|
||||||
float vert_mult = 0.0f;
|
|
||||||
float horiz_mult = 0.0f;
|
|
||||||
float pattern_compensation = 0.0f;
|
|
||||||
|
|
||||||
if (g_settings.aimbot_norecoil) {
|
|
||||||
if (is_ak47) {
|
|
||||||
vert_mult = AK47_RECOIL_VERT_MULT;
|
|
||||||
horiz_mult = AK47_RECOIL_HORIZ_MULT;
|
|
||||||
|
|
||||||
if (bullet_count > 0 && bullet_count <= 30) {
|
|
||||||
pattern_compensation = ak47_pattern[bullet_count-1] * 0.6f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (is_high_recoil_weapon) {
|
|
||||||
vert_mult = 2.2f;
|
|
||||||
horiz_mult = 0.8f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vert_mult = 1.9f;
|
|
||||||
horiz_mult = 0.7f;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd->viewangles[0] -= (punch_angles[0] * vert_mult);
|
|
||||||
cmd->viewangles[1] -= (punch_angles[1] * horiz_mult);
|
|
||||||
|
|
||||||
if (pattern_compensation > 0) {
|
|
||||||
cmd->viewangles[0] -= pattern_compensation;
|
|
||||||
|
|
||||||
if (is_ak47 && bullet_count <= 5) {
|
|
||||||
i_engine->Con_Printf("AK-47 pattern comp: Shot #%d, Compensation: %.2f degrees\n",
|
|
||||||
bullet_count, pattern_compensation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (g_settings.aimbot_recoil_comp) {
|
|
||||||
if (is_ak47) {
|
|
||||||
vert_mult = 2.0f;
|
|
||||||
horiz_mult = 0.7f;
|
|
||||||
|
|
||||||
if (bullet_count > 0 && bullet_count <= 30) {
|
|
||||||
pattern_compensation = ak47_pattern[bullet_count-1] * 0.35f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (is_high_recoil_weapon) {
|
|
||||||
vert_mult = 1.7f;
|
|
||||||
horiz_mult = 0.6f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vert_mult = 1.3f;
|
|
||||||
horiz_mult = 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd->viewangles[0] -= (punch_angles[0] * vert_mult);
|
|
||||||
cmd->viewangles[1] -= (punch_angles[1] * horiz_mult);
|
|
||||||
|
|
||||||
if (pattern_compensation > 0) {
|
|
||||||
cmd->viewangles[0] -= pattern_compensation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t current_time = time(NULL);
|
|
||||||
if (current_time - last_log_time >= 2) {
|
|
||||||
if (bullet_count > 0) {
|
|
||||||
i_engine->Con_Printf("Recoil control - Weapon: %s, Bullet: %d, VMult: %.1f, HMult: %.1f, Pattern: %.1f\n",
|
|
||||||
is_ak47 ? "AK-47" : (is_high_recoil_weapon ? "High Recoil" : "Standard"),
|
|
||||||
bullet_count, vert_mult, horiz_mult, pattern_compensation);
|
|
||||||
}
|
|
||||||
|
|
||||||
last_log_time = current_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
ang_clamp(&cmd->viewangles);
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#ifndef NO_RECOIL_H
|
|
||||||
#define NO_RECOIL_H
|
|
||||||
|
|
||||||
#include "../include/sdk.h"
|
|
||||||
|
|
||||||
void no_recoil(usercmd_t* cmd);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
#include "../include/sdk.h"
|
|
||||||
#include "../include/settings.h"
|
|
||||||
#include "../include/globals.h"
|
|
||||||
#include "../include/util.h"
|
|
||||||
#include "thirdperson.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define TP_MIN_DIST 30.0f
|
|
||||||
#define TP_MAX_DIST 800.0f
|
|
||||||
#define TP_DEFAULT_DIST 150.0f
|
|
||||||
|
|
||||||
#define YAW 1
|
|
||||||
#define PITCH 0
|
|
||||||
#define ROLL 2
|
|
||||||
|
|
||||||
static bool s_initialized = false;
|
|
||||||
static bool s_thirdperson_enabled = false;
|
|
||||||
static vec3_t s_camera_origin = {0, 0, 0};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void thirdperson_init(void) {
|
|
||||||
s_initialized = true;
|
|
||||||
s_thirdperson_enabled = false;
|
|
||||||
i_engine->Con_Printf("Third-person system initialized\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void thirdperson_toggle(void) {
|
|
||||||
g_settings.thirdperson = !g_settings.thirdperson;
|
|
||||||
s_thirdperson_enabled = g_settings.thirdperson;
|
|
||||||
|
|
||||||
if (s_thirdperson_enabled) {
|
|
||||||
i_engine->Con_Printf("Third-person view enabled (distance: %.1f)\n", g_settings.thirdperson_dist);
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Third-person view disabled\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool thirdperson_key_event(int keynum, int down) {
|
|
||||||
i_engine->Con_Printf("Thirdperson key event: keynum=%d, down=%d, configured=%d\n",
|
|
||||||
keynum, down, g_settings.thirdperson_key);
|
|
||||||
|
|
||||||
if (!down) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool should_toggle = false;
|
|
||||||
|
|
||||||
if (keynum == 'C' || keynum == 'c' || keynum == 67 || keynum == 99) {
|
|
||||||
i_engine->Con_Printf("C key detected (keynum=%d)\n", keynum);
|
|
||||||
if (g_settings.thirdperson_key == 'C' || g_settings.thirdperson_key == 'c' ||
|
|
||||||
g_settings.thirdperson_key == 67 || g_settings.thirdperson_key == 99) {
|
|
||||||
should_toggle = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (keynum == g_settings.thirdperson_key) {
|
|
||||||
i_engine->Con_Printf("Configured key detected (keynum=%d)\n", keynum);
|
|
||||||
should_toggle = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (should_toggle) {
|
|
||||||
thirdperson_toggle();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void thirdperson_modify_view(ref_params_t* pparams) {
|
|
||||||
if (!g_settings.thirdperson) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float distance = g_settings.thirdperson_dist;
|
|
||||||
|
|
||||||
vec3_t forward, right, up;
|
|
||||||
|
|
||||||
i_engine->pfnAngleVectors(pparams->viewangles, forward, right, up);
|
|
||||||
|
|
||||||
vec3_t camera_offset;
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
camera_offset[i] = -forward[i] * distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t newOrigin;
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
newOrigin[i] = pparams->vieworg[i] + camera_offset[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
vec_copy(s_camera_origin, newOrigin);
|
|
||||||
|
|
||||||
pmtrace_t trace;
|
|
||||||
i_engine->pEventAPI->EV_SetTraceHull(2);
|
|
||||||
i_engine->pEventAPI->EV_PlayerTrace(pparams->vieworg, newOrigin, PM_NORMAL, -1, &trace);
|
|
||||||
|
|
||||||
if (trace.fraction < 1.0) {
|
|
||||||
vec3_t dir;
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
dir[i] = newOrigin[i] - pparams->vieworg[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
float len = sqrtf(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);
|
|
||||||
if (len > 0) {
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
dir[i] /= len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t collisionPoint;
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
collisionPoint[i] = pparams->vieworg[i] + (trace.fraction * distance - 5.0f) * forward[i];
|
|
||||||
}
|
|
||||||
vec_copy(newOrigin, collisionPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec_copy(pparams->vieworg, newOrigin);
|
|
||||||
|
|
||||||
static int debug_count = 0;
|
|
||||||
if (++debug_count % 300 == 0) {
|
|
||||||
i_engine->Con_Printf("Camera position: [%.1f, %.1f, %.1f], distance=%.1f\n",
|
|
||||||
newOrigin[0], newOrigin[1], newOrigin[2], distance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void thirdperson_update(void) {
|
|
||||||
s_thirdperson_enabled = g_settings.thirdperson;
|
|
||||||
}
|
|
||||||
|
|
||||||
int thirdperson_is_active(void) {
|
|
||||||
return g_settings.thirdperson ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#ifndef THIRDPERSON_H_
|
|
||||||
#define THIRDPERSON_H_
|
|
||||||
|
|
||||||
#include "../include/sdk.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void thirdperson_init(void);
|
|
||||||
|
|
||||||
int thirdperson_is_active(void);
|
|
||||||
|
|
||||||
void thirdperson_get_offset(float* offset);
|
|
||||||
|
|
||||||
void thirdperson_update(void);
|
|
||||||
|
|
||||||
void thirdperson_toggle(void);
|
|
||||||
|
|
||||||
bool thirdperson_key_event(int keynum, int down);
|
|
||||||
|
|
||||||
void thirdperson_modify_view(ref_params_t* pparams);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
#include "include/game_detection.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
static GameType current_game = GAME_UNKNOWN;
|
|
||||||
|
|
||||||
GameType get_current_game(void) {
|
|
||||||
if (current_game != GAME_UNKNOWN) {
|
|
||||||
return current_game;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *fp = fopen("/proc/self/cmdline", "r");
|
|
||||||
if (fp) {
|
|
||||||
char buf[1024];
|
|
||||||
size_t size = fread(buf, sizeof(char), sizeof(buf) - 1, fp);
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
if (size > 0) {
|
|
||||||
buf[size] = '\0';
|
|
||||||
|
|
||||||
char *gameTypeToken = NULL;
|
|
||||||
char *steamToken = NULL;
|
|
||||||
|
|
||||||
int tokensFound = 0;
|
|
||||||
|
|
||||||
for (char *token = buf; token < buf + size; token += strlen(token) + 1) {
|
|
||||||
tokensFound++;
|
|
||||||
|
|
||||||
if (strcmp(token, "-game") == 0) {
|
|
||||||
gameTypeToken = token + strlen(token) + 1;
|
|
||||||
} else if (strcmp(token, "-steam") == 0) {
|
|
||||||
steamToken = token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gameTypeToken) {
|
|
||||||
if (strcmp(gameTypeToken, "cstrike") == 0) {
|
|
||||||
current_game = GAME_CS16;
|
|
||||||
} else if (strcmp(gameTypeToken, "dod") == 0) {
|
|
||||||
current_game = GAME_DAY_OF_DEFEAT;
|
|
||||||
} else if (strcmp(gameTypeToken, "dmc") == 0) {
|
|
||||||
current_game = GAME_DMC;
|
|
||||||
} else if (strcmp(gameTypeToken, "tfc") == 0) {
|
|
||||||
current_game = GAME_TFC;
|
|
||||||
} else if (strcmp(gameTypeToken, "SpaceLife") == 0) {
|
|
||||||
current_game = GAME_SL;
|
|
||||||
}
|
|
||||||
} else if (steamToken && tokensFound == 2) {
|
|
||||||
// If only `-steam` is found and no `-game`, with only two tokens, assume it's Half-Life 1
|
|
||||||
current_game = GAME_HALFLIFE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return current_game;
|
|
||||||
}
|
|
||||||
|
|
||||||
int IsCS16(void) {
|
|
||||||
return get_current_game() == GAME_CS16;
|
|
||||||
}
|
|
||||||
|
|
||||||
int IsHalfLife(void) {
|
|
||||||
return get_current_game() == GAME_HALFLIFE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int IsDayOfDefeat(void) {
|
|
||||||
return get_current_game() == GAME_DAY_OF_DEFEAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
int IsTFC(void) {
|
|
||||||
return get_current_game() == GAME_TFC;
|
|
||||||
}
|
|
||||||
|
|
||||||
int IsDeathmatchClassic(void) {
|
|
||||||
return get_current_game() == GAME_DMC;
|
|
||||||
}
|
|
||||||
|
|
||||||
int IsSpaceLife(void) {
|
|
||||||
return get_current_game() == GAME_SL;
|
|
||||||
}
|
|
||||||
@@ -1,21 +1,17 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h> /* PROT_* */
|
||||||
|
|
||||||
#include "include/globals.h"
|
#include "include/globals.h"
|
||||||
#include "include/sdk.h"
|
#include "include/sdk.h"
|
||||||
#include "include/util.h"
|
#include "include/util.h"
|
||||||
|
|
||||||
game_id this_game_id = HL;
|
enum game_id this_game_id = HL;
|
||||||
vec3_t g_punchAngles = { 0, 0, 0 };
|
|
||||||
|
|
||||||
float g_flNextAttack = 0.f, g_flNextPrimaryAttack = 0.f;
|
|
||||||
int g_iClip = 0;
|
|
||||||
int g_currentWeaponID = -1;
|
|
||||||
|
|
||||||
double g_flCurrentTime = 0.0;
|
|
||||||
|
|
||||||
|
/* Bone origins of each player, updated in studiorendermodel */
|
||||||
|
vec3_t g_bones[64][128];
|
||||||
|
|
||||||
void* hw;
|
void* hw;
|
||||||
void** h_client;
|
void** h_client;
|
||||||
@@ -25,29 +21,36 @@ DECL_INTF(playermove_t, pmove);
|
|||||||
DECL_INTF(engine_studio_api_t, enginestudio);
|
DECL_INTF(engine_studio_api_t, enginestudio);
|
||||||
DECL_INTF(StudioModelRenderer_t, studiomodelrenderer);
|
DECL_INTF(StudioModelRenderer_t, studiomodelrenderer);
|
||||||
|
|
||||||
|
/* Game struct with some useful info */
|
||||||
game_t* game_info;
|
game_t* game_info;
|
||||||
|
|
||||||
|
/* Array of extra_player_info's for each player */
|
||||||
void* player_extra_info;
|
void* player_extra_info;
|
||||||
|
|
||||||
|
/* Updated in CL_CreateMove hook */
|
||||||
cl_entity_t* localplayer = NULL;
|
cl_entity_t* localplayer = NULL;
|
||||||
|
|
||||||
float* scr_fov_value = NULL;
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool globals_init(void) {
|
bool globals_init(void) {
|
||||||
|
/*
|
||||||
|
* Get handler for hw.so
|
||||||
|
* RTLD_LAZY: If the symbol is never referenced, then it is never resolved.
|
||||||
|
* RTLD_NOLOAD: Don't load the shared object.
|
||||||
|
*/
|
||||||
hw = dlopen("hw.so", RTLD_LAZY | RTLD_NOLOAD);
|
hw = dlopen("hw.so", RTLD_LAZY | RTLD_NOLOAD);
|
||||||
if (!hw) {
|
if (!hw) {
|
||||||
printf("goldsource-cheat: globals_init: can't open hw.so\n");
|
printf("hl-cheat: globals_init: can't open hw.so\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
h_client = (void**)dlsym(hw, "hClientDLL");
|
h_client = (void**)dlsym(hw, "hClientDLL");
|
||||||
if (!h_client) {
|
if (!h_client) {
|
||||||
printf("goldsource-cheat: globals_init: can't find hClientDLL\n");
|
printf("hl-cheat: globals_init: can't find hClientDLL\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get symbol addresses using dlsym and the handler we just opened */
|
||||||
i_engine = (cl_enginefunc_t*)dlsym(hw, "cl_enginefuncs");
|
i_engine = (cl_enginefunc_t*)dlsym(hw, "cl_enginefuncs");
|
||||||
i_client = (cl_clientfunc_t*)dlsym(hw, "cl_funcs");
|
i_client = (cl_clientfunc_t*)dlsym(hw, "cl_funcs");
|
||||||
i_pmove = *(playermove_t**)dlsym(hw, "pmove");
|
i_pmove = *(playermove_t**)dlsym(hw, "pmove");
|
||||||
@@ -60,16 +63,14 @@ bool globals_init(void) {
|
|||||||
|
|
||||||
game_info = *(game_t**)dlsym(hw, "game");
|
game_info = *(game_t**)dlsym(hw, "game");
|
||||||
|
|
||||||
scr_fov_value = (float*)dlsym(hw, "scr_fov_value");
|
|
||||||
|
|
||||||
if (!i_engine || !i_client || !i_pmove || !i_enginestudio ||
|
if (!i_engine || !i_client || !i_pmove || !i_enginestudio ||
|
||||||
!i_studiomodelrenderer || !game_info) {
|
!i_studiomodelrenderer || !game_info) {
|
||||||
printf("goldsource-cheat: globals_init: couldn't load some symbols\n");
|
printf("hl-cheat: globals_init: couldn't load some symbols\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!protect_addr(i_studiomodelrenderer, PROT_READ | PROT_WRITE)) {
|
if (!protect_addr(i_studiomodelrenderer, PROT_READ | PROT_WRITE)) {
|
||||||
printf("goldsource-cheat: globals_init: couldn't unprotect address of SMR\n");
|
printf("hl-cheat: globals_init: couldn't unprotect address of SMR\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
483
src/hooks.c
483
src/hooks.c
@@ -1,284 +1,79 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "include/settings.h"
|
|
||||||
#include "include/hooks.h"
|
#include "include/hooks.h"
|
||||||
#include "include/util.h"
|
|
||||||
#include "include/sdk.h"
|
#include "include/sdk.h"
|
||||||
|
#include "include/globals.h"
|
||||||
|
#include "include/util.h"
|
||||||
|
#include "include/cvars.h"
|
||||||
#include "include/detour.h" /* 8dcc/detour-lib */
|
#include "include/detour.h" /* 8dcc/detour-lib */
|
||||||
#include "include/main.h" /* For self_unload() */
|
|
||||||
#include "include/menu.h" /* ImGui menu */
|
|
||||||
#include "features/features.h" /* bhop(), esp(), etc. */
|
#include "features/features.h" /* bhop(), esp(), etc. */
|
||||||
#include "include/entityutil.h"
|
|
||||||
#include "include/game_detection.h"
|
|
||||||
#include "features/thirdperson.h"
|
|
||||||
|
|
||||||
#define IMGUI_IMPLEMENTATION
|
|
||||||
#include "include/imgui/imgui.h"
|
|
||||||
#include "include/imgui/backends/imgui_impl_opengl2.h"
|
|
||||||
|
|
||||||
#include "include/sdk/public/keydefs.h"
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <GL/gl.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
extern void* DetourFunction(void* orig, void* hook);
|
|
||||||
extern bool DetourRemove(void* orig, void* hook);
|
|
||||||
|
|
||||||
typedef unsigned char BYTE;
|
|
||||||
|
|
||||||
/* Forward declarations of hook functions */
|
|
||||||
void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
|
||||||
void h_CL_Move(void);
|
|
||||||
int h_CL_IsThirdPerson(void);
|
|
||||||
void h_CL_CameraOffset(float* ofs);
|
|
||||||
|
|
||||||
/* Normal VMT hooks */
|
/* Normal VMT hooks */
|
||||||
DECL_HOOK(CL_CreateMove);
|
DECL_HOOK(CL_CreateMove);
|
||||||
DECL_HOOK(HUD_Redraw);
|
DECL_HOOK(HUD_Redraw);
|
||||||
DECL_HOOK(StudioRenderModel);
|
DECL_HOOK(StudioRenderModel);
|
||||||
DECL_HOOK(CalcRefdef);
|
|
||||||
DECL_HOOK(HUD_PostRunCmd);
|
|
||||||
key_event_func_t ho_HUD_Key_Event = NULL; // Manually declare the hook
|
|
||||||
|
|
||||||
// Manual declarations for third-person hooks
|
/* OpenGL hooks */
|
||||||
int (*ho_CL_IsThirdPerson)(void) = NULL;
|
DECL_HOOK(glColor4f);
|
||||||
void (*ho_CL_CameraOffset)(float* ofs) = NULL;
|
|
||||||
|
|
||||||
/* OpenGL hooks - use function pointer as we get actual addresses from game */
|
|
||||||
void (*real_glColor4f)(GLfloat, GLfloat, GLfloat, GLfloat) = NULL;
|
|
||||||
|
|
||||||
/* Detour hooks */
|
/* Detour hooks */
|
||||||
static detour_data_t detour_data_clmove;
|
static detour_data_t detour_data_clmove;
|
||||||
|
DECL_DETOUR_TYPE(void, clmove_type);
|
||||||
/* Flag to delay uninject until next frame */
|
DECL_HOOK(CL_Move);
|
||||||
static bool g_should_uninject = false;
|
|
||||||
|
|
||||||
/* Mouse position tracking independent from the game engine */
|
|
||||||
static int g_menu_mouse_x = 0;
|
|
||||||
static int g_menu_mouse_y = 0;
|
|
||||||
static bool g_mouse_down[5] = {false, false, false, false, false}; // Tracking mouse buttons
|
|
||||||
|
|
||||||
/* Store last known camera angles for locking */
|
|
||||||
static vec3_t s_locked_view_angles = {0, 0, 0};
|
|
||||||
static bool s_lock_initialized = false;
|
|
||||||
|
|
||||||
/* Forward declarations */
|
|
||||||
static void force_view_angles(void);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool hooks_init(void) {
|
bool hooks_init(void) {
|
||||||
/* Initialize ImGui menu before hooking any rendering functions */
|
|
||||||
if (!menu_init()) {
|
|
||||||
i_engine->Con_Printf("Failed to initialize ImGui menu\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize third-person camera system */
|
|
||||||
thirdperson_init();
|
|
||||||
|
|
||||||
/* VMT hooking */
|
/* VMT hooking */
|
||||||
HOOK(i_client, CL_CreateMove);
|
HOOK(i_client, CL_CreateMove);
|
||||||
HOOK(i_client, HUD_Redraw);
|
HOOK(i_client, HUD_Redraw);
|
||||||
HOOK(i_studiomodelrenderer, StudioRenderModel);
|
HOOK(i_studiomodelrenderer, StudioRenderModel);
|
||||||
HOOK(i_client, CalcRefdef);
|
|
||||||
HOOK(i_client, HUD_PostRunCmd);
|
|
||||||
|
|
||||||
ho_CL_IsThirdPerson = i_client->CL_IsThirdPerson;
|
|
||||||
i_client->CL_IsThirdPerson = h_CL_IsThirdPerson;
|
|
||||||
i_engine->Con_Printf("CL_IsThirdPerson hook installed at %p -> %p\n",
|
|
||||||
ho_CL_IsThirdPerson, h_CL_IsThirdPerson);
|
|
||||||
|
|
||||||
ho_CL_CameraOffset = i_client->CL_CameraOffset;
|
|
||||||
i_client->CL_CameraOffset = h_CL_CameraOffset;
|
|
||||||
i_engine->Con_Printf("CL_CameraOffset hook installed at %p -> %p\n",
|
|
||||||
ho_CL_CameraOffset, h_CL_CameraOffset);
|
|
||||||
|
|
||||||
ho_HUD_Key_Event = (key_event_func_t)i_client->HUD_Key_Event;
|
|
||||||
i_client->HUD_Key_Event = (key_event_func_t)h_HUD_Key_Event;
|
|
||||||
|
|
||||||
real_glColor4f = (void (*)(GLfloat, GLfloat, GLfloat, GLfloat))glColor4f;
|
/* OpenGL hooks */
|
||||||
if (real_glColor4f) {
|
GL_HOOK(glColor4f);
|
||||||
void* result = DetourFunction((void*)real_glColor4f, (void*)h_glColor4f);
|
|
||||||
if (!result) {
|
/* Detour hooks */
|
||||||
i_engine->Con_Printf("Failed to hook glColor4f\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void* clmove_ptr = dlsym(hw, "CL_Move");
|
void* clmove_ptr = dlsym(hw, "CL_Move");
|
||||||
if (!clmove_ptr) {
|
if (!clmove_ptr)
|
||||||
i_engine->Con_Printf("Failed to find CL_Move\n");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize detour_data_clmove struct for detour, and add the hook */
|
/* Initialize detour_data_clmove struct for detour, and add the hook */
|
||||||
detour_init(&detour_data_clmove, clmove_ptr, (void*)h_CL_Move);
|
detour_init(&detour_data_clmove, clmove_ptr, (void*)h_CL_Move);
|
||||||
if (!detour_add(&detour_data_clmove)) {
|
detour_add(&detour_data_clmove);
|
||||||
i_engine->Con_Printf("Failed to hook CL_Move\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize debug info */
|
|
||||||
if (g_settings.thirdperson) {
|
|
||||||
i_engine->Con_Printf("Third-person mode initialized with distance %.1f\n",
|
|
||||||
g_settings.thirdperson_dist);
|
|
||||||
}
|
|
||||||
|
|
||||||
i_engine->Con_Printf("All hooks initialized successfully\n");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hooks_restore(void) {
|
void hooks_restore(void) {
|
||||||
/* First shut down ImGui to prevent any rendering after hooks are removed */
|
detour_del(&detour_data_clmove);
|
||||||
menu_shutdown();
|
|
||||||
|
|
||||||
/* Remove CL_Move detour */
|
|
||||||
if (detour_data_clmove.detoured) {
|
|
||||||
detour_del(&detour_data_clmove);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove OpenGL hooks */
|
|
||||||
if (real_glColor4f) {
|
|
||||||
DetourRemove((void*)real_glColor4f, (void*)h_glColor4f);
|
|
||||||
real_glColor4f = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore VMT hooks */
|
|
||||||
if (i_client) {
|
|
||||||
i_client->CL_CreateMove = ho_CL_CreateMove;
|
|
||||||
i_client->HUD_Redraw = ho_HUD_Redraw;
|
|
||||||
i_client->CalcRefdef = ho_CalcRefdef;
|
|
||||||
i_client->HUD_PostRunCmd = ho_HUD_PostRunCmd;
|
|
||||||
i_client->CL_IsThirdPerson = ho_CL_IsThirdPerson;
|
|
||||||
i_client->CL_CameraOffset = ho_CL_CameraOffset;
|
|
||||||
|
|
||||||
if (ho_HUD_Key_Event) {
|
|
||||||
i_client->HUD_Key_Event = ho_HUD_Key_Event;
|
|
||||||
ho_HUD_Key_Event = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i_studiomodelrenderer) {
|
|
||||||
i_studiomodelrenderer->StudioRenderModel = ho_StudioRenderModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
i_engine->Con_Printf("All hooks restored\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void hooks_schedule_uninject(void) {
|
|
||||||
g_should_uninject = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void h_CL_CreateMove(float frametime, usercmd_t* cmd, int active) {
|
void h_CL_CreateMove(float frametime, usercmd_t* cmd, int active) {
|
||||||
/* Check if we should uninject before doing anything else */
|
|
||||||
if (g_should_uninject) {
|
|
||||||
g_should_uninject = false;
|
|
||||||
self_unload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
localplayer = i_engine->GetLocalPlayer();
|
|
||||||
|
|
||||||
ORIGINAL(CL_CreateMove, frametime, cmd, active);
|
ORIGINAL(CL_CreateMove, frametime, cmd, active);
|
||||||
|
|
||||||
vec3_t old_angles = cmd->viewangles;
|
vec3_t old_angles = cmd->viewangles;
|
||||||
|
|
||||||
float origForward = cmd->forwardmove;
|
|
||||||
float origSide = cmd->sidemove;
|
|
||||||
float origUp = cmd->upmove;
|
|
||||||
int origButtons = cmd->buttons;
|
|
||||||
|
|
||||||
fov_adjust(cmd);
|
/* Declared in globals.c */
|
||||||
|
localplayer = i_engine->GetLocalPlayer();
|
||||||
|
|
||||||
if (g_menu_open && !g_settings.menu_allow_movement) {
|
bhop(cmd);
|
||||||
cmd->forwardmove = 0.0f;
|
aimbot(cmd);
|
||||||
cmd->sidemove = 0.0f;
|
|
||||||
cmd->upmove = 0.0f;
|
|
||||||
cmd->buttons = 0;
|
|
||||||
|
|
||||||
if (s_lock_initialized) {
|
|
||||||
vec_copy(cmd->viewangles, s_locked_view_angles);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
if (g_menu_open && g_settings.menu_allow_movement) {
|
|
||||||
cmd->forwardmove = origForward;
|
|
||||||
cmd->sidemove = origSide;
|
|
||||||
cmd->upmove = origUp;
|
|
||||||
cmd->buttons = origButtons;
|
|
||||||
}
|
|
||||||
|
|
||||||
bhop(cmd);
|
|
||||||
no_recoil(cmd); // Apply recoil control before aimbot
|
|
||||||
aimbot(cmd);
|
|
||||||
bullet_tracers(cmd);
|
|
||||||
anti_aim(cmd);
|
|
||||||
check_namechanger_mode_and_execute(cmd);
|
|
||||||
|
|
||||||
if (g_menu_open && s_lock_initialized) {
|
|
||||||
vec_copy(cmd->viewangles, s_locked_view_angles);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always maintain view angle control and clamp angles
|
|
||||||
correct_movement(cmd, old_angles);
|
correct_movement(cmd, old_angles);
|
||||||
ang_clamp(&cmd->viewangles);
|
vec_clamp(cmd->viewangles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
rgb_t rainbow_color(float time) {
|
|
||||||
const float frequency = 0.1f;
|
|
||||||
|
|
||||||
unsigned char r = (sin(frequency * time + 0) * 127.5f + 127.5f);
|
|
||||||
unsigned char g = (sin(frequency * time + 2.0f) * 127.5f + 127.5f);
|
|
||||||
unsigned char b = (sin(frequency * time + 4.0f) * 127.5f + 127.5f);
|
|
||||||
|
|
||||||
return (rgb_t){ r, g, b };
|
|
||||||
}
|
|
||||||
|
|
||||||
int h_HUD_Redraw(float time, int intermission) {
|
int h_HUD_Redraw(float time, int intermission) {
|
||||||
force_view_angles();
|
|
||||||
|
|
||||||
int ret = ORIGINAL(HUD_Redraw, time, intermission);
|
int ret = ORIGINAL(HUD_Redraw, time, intermission);
|
||||||
|
|
||||||
if (g_settings.watermark) {
|
/* Watermark */
|
||||||
rgb_t color = g_settings.watermark_rainbow ? rainbow_color(time) : (rgb_t){ 0, 255, 255 };
|
engine_draw_text(5, 5, "8dcc/hl-cheat", (rgb_t){ 255, 255, 255 });
|
||||||
engine_draw_text(5, 5, "https://git.deadzone.lol/Wizzard/goldsrc-cheat", color);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp();
|
esp();
|
||||||
|
|
||||||
custom_crosshair();
|
custom_crosshair();
|
||||||
|
|
||||||
if (g_menu_open && g_imgui_context) {
|
|
||||||
SCREENINFO scr_inf;
|
|
||||||
scr_inf.iSize = sizeof(SCREENINFO);
|
|
||||||
i_engine->pfnGetScreenInfo(&scr_inf);
|
|
||||||
|
|
||||||
int mouse_x, mouse_y;
|
|
||||||
i_engine->GetMousePosition(&mouse_x, &mouse_y);
|
|
||||||
|
|
||||||
ImGui::SetCurrentContext(g_imgui_context);
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
io.MouseDown[0] = g_mouse_down[0];
|
|
||||||
io.MouseDown[1] = g_mouse_down[1];
|
|
||||||
|
|
||||||
if (mouse_x >= 0 && mouse_x < scr_inf.iWidth &&
|
|
||||||
mouse_y >= 0 && mouse_y < scr_inf.iHeight) {
|
|
||||||
io.MousePos.x = (float)mouse_x;
|
|
||||||
io.MousePos.y = (float)mouse_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menu_render();
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -286,54 +81,20 @@ int h_HUD_Redraw(float time, int intermission) {
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void h_StudioRenderModel(void* this_ptr) {
|
void h_StudioRenderModel(void* this_ptr) {
|
||||||
|
/* Update bones array */
|
||||||
|
cl_entity_t* ent = i_enginestudio->GetCurrentEntity();
|
||||||
|
bone_matrix* mat = (bone_matrix*)i_enginestudio->StudioGetBoneTransform();
|
||||||
|
for (int i = 0; i < 128; i++) {
|
||||||
|
const vec3_t bone_orig = matrix_3x4_origin((*mat)[i]);
|
||||||
|
vec_copy(g_bones[ent->index][i], bone_orig);
|
||||||
|
}
|
||||||
|
|
||||||
if (!chams(this_ptr))
|
if (!chams(this_ptr))
|
||||||
ORIGINAL(StudioRenderModel, this_ptr);
|
ORIGINAL(StudioRenderModel, this_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void h_CalcRefdef(ref_params_t* params) {
|
|
||||||
/* Store punch angles for CreateMove */
|
|
||||||
vec_copy(g_punchAngles, params->punchangle);
|
|
||||||
|
|
||||||
/* Call original CalcRefdef */
|
|
||||||
ORIGINAL(CalcRefdef, params);
|
|
||||||
|
|
||||||
/* Apply third-person camera with direct view modification */
|
|
||||||
if (g_settings.thirdperson) {
|
|
||||||
thirdperson_modify_view(params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void h_HUD_PostRunCmd(struct local_state_s* from, struct local_state_s* to,
|
|
||||||
struct usercmd_s* cmd, int runfuncs, double time,
|
|
||||||
unsigned int random_seed) {
|
|
||||||
ORIGINAL(HUD_PostRunCmd, from, to, cmd, runfuncs, time, random_seed);
|
|
||||||
|
|
||||||
g_flCurrentTime = time;
|
|
||||||
|
|
||||||
/* Store attack information to check if we can shoot */
|
|
||||||
if (runfuncs) {
|
|
||||||
g_flNextAttack = to->client.m_flNextAttack;
|
|
||||||
g_flNextPrimaryAttack =
|
|
||||||
to->weapondata[to->client.m_iId].m_flNextPrimaryAttack;
|
|
||||||
g_iClip = to->weapondata[to->client.m_iId].m_iClip;
|
|
||||||
|
|
||||||
// Track current weapon ID
|
|
||||||
int weaponId = to->client.m_iId;
|
|
||||||
|
|
||||||
// Update global weapon ID if it changed
|
|
||||||
if (g_currentWeaponID != weaponId) {
|
|
||||||
g_currentWeaponID = weaponId;
|
|
||||||
i_engine->Con_Printf("Weapon changed: ID=%d\n", g_currentWeaponID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
||||||
/* This visible_mode variable is changed inside the chams() function, which
|
/* This visible_mode variable is changed inside the chams() function, which
|
||||||
* is called from the StudioRenderModel hook.
|
* is called from the StudioRenderModel hook.
|
||||||
@@ -373,186 +134,16 @@ void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This part is executed regardless of the visible_mode.
|
ORIGINAL(glColor4f, r, g, b, a);
|
||||||
* NOTE: Not calling original breaks chams. */
|
|
||||||
if (real_glColor4f)
|
|
||||||
real_glColor4f(r, g, b, a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
void h_CL_Move() {
|
||||||
* Simple passthrough to thirdperson module
|
if (cv_clmove->value != 0) {
|
||||||
*/
|
for (int i = 0; i < (int)cv_clmove->value; i++)
|
||||||
int h_CL_IsThirdPerson(void) {
|
CALL_ORIGINAL(detour_data_clmove, clmove_type);
|
||||||
// We still need this to tell the engine we're in third person view
|
}
|
||||||
return thirdperson_is_active();
|
|
||||||
}
|
CALL_ORIGINAL(detour_data_clmove, clmove_type);
|
||||||
|
|
||||||
/*
|
|
||||||
* This isn't used anymore - our direct camera control in CalcRefdef handles everything
|
|
||||||
*/
|
|
||||||
void h_CL_CameraOffset(float* ofs) {
|
|
||||||
// Not used by our new implementation
|
|
||||||
ofs[0] = ofs[1] = ofs[2] = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to handle CL_Move
|
|
||||||
void h_CL_Move(void)
|
|
||||||
{
|
|
||||||
// Get original function address safely
|
|
||||||
void (*original_func)(void) = NULL;
|
|
||||||
if (detour_data_clmove.detoured) {
|
|
||||||
detour_del(&detour_data_clmove);
|
|
||||||
original_func = (void (*)(void))detour_data_clmove.orig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call original function if we have it
|
|
||||||
if (original_func) {
|
|
||||||
original_func();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update third-person camera every frame
|
|
||||||
thirdperson_update();
|
|
||||||
|
|
||||||
// Restore the detour
|
|
||||||
if (detour_data_clmove.orig) {
|
|
||||||
detour_add(&detour_data_clmove);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int h_HUD_Key_Event(int down, int keynum, const char* pszCurrentBinding) {
|
|
||||||
if (keynum == 'C' || keynum == 'c' || keynum == 67 || keynum == 99 ||
|
|
||||||
keynum == g_settings.thirdperson_key || keynum == K_INS) {
|
|
||||||
i_engine->Con_Printf("Key event: down=%d, keynum=%d, binding=%s\n",
|
|
||||||
down, keynum, pszCurrentBinding ? pszCurrentBinding : "none");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_menu_open) {
|
|
||||||
if (keynum == K_BACKSPACE || keynum == K_DEL ||
|
|
||||||
keynum == K_LEFTARROW || keynum == K_RIGHTARROW ||
|
|
||||||
keynum == K_UPARROW || keynum == K_DOWNARROW ||
|
|
||||||
keynum == K_HOME || keynum == K_END ||
|
|
||||||
keynum == K_ENTER || keynum == K_TAB ||
|
|
||||||
keynum == K_CTRL || keynum == K_SHIFT || keynum == K_ALT) {
|
|
||||||
|
|
||||||
menu_key_event(keynum, down);
|
|
||||||
return 0;
|
|
||||||
} else if (down && keynum >= 32 && keynum <= 126) {
|
|
||||||
menu_char_event(keynum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern bool g_waiting_for_key_bind;
|
|
||||||
if (g_waiting_for_key_bind && down) {
|
|
||||||
menu_key_event(keynum, down);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thirdperson_key_event(keynum, down)) {
|
|
||||||
i_engine->Con_Printf("Thirdperson key event handled successfully\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (down && (keynum == K_INS || (pszCurrentBinding && strcmp(pszCurrentBinding, "dz_menu") == 0))) {
|
|
||||||
i_engine->Con_Printf("Menu toggle key detected!\n");
|
|
||||||
menu_key_event(keynum, down);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_menu_open) {
|
|
||||||
if (keynum == K_MOUSE1 || keynum == K_MOUSE2) {
|
|
||||||
if (keynum == K_MOUSE1)
|
|
||||||
g_mouse_down[0] = down ? true : false;
|
|
||||||
else if (keynum == K_MOUSE2)
|
|
||||||
g_mouse_down[1] = down ? true : false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keynum == K_ESCAPE && down) {
|
|
||||||
if (ho_HUD_Key_Event)
|
|
||||||
return ho_HUD_Key_Event(down, keynum, pszCurrentBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.menu_allow_movement) {
|
|
||||||
if (pszCurrentBinding && (
|
|
||||||
strstr(pszCurrentBinding, "+forward") ||
|
|
||||||
strstr(pszCurrentBinding, "+back") ||
|
|
||||||
strstr(pszCurrentBinding, "+moveleft") ||
|
|
||||||
strstr(pszCurrentBinding, "+moveright") ||
|
|
||||||
strstr(pszCurrentBinding, "+jump") ||
|
|
||||||
strstr(pszCurrentBinding, "+duck") ||
|
|
||||||
strstr(pszCurrentBinding, "+speed"))) {
|
|
||||||
|
|
||||||
i_engine->Con_Printf("Passing movement key to game: %s\n", pszCurrentBinding);
|
|
||||||
if (ho_HUD_Key_Event)
|
|
||||||
return ho_HUD_Key_Event(down, keynum, pszCurrentBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keynum == 'W' || keynum == 'A' || keynum == 'S' || keynum == 'D' ||
|
|
||||||
keynum == ' ' ||
|
|
||||||
keynum == K_CTRL ||
|
|
||||||
keynum == K_SHIFT) {
|
|
||||||
|
|
||||||
i_engine->Con_Printf("Passing direct movement key to game: %d\n", keynum);
|
|
||||||
if (ho_HUD_Key_Event)
|
|
||||||
return ho_HUD_Key_Event(down, keynum, pszCurrentBinding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ho_HUD_Key_Event) {
|
|
||||||
return ho_HUD_Key_Event(down, keynum, pszCurrentBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void force_view_angles(void) {
|
|
||||||
static bool s_was_menu_open = false;
|
|
||||||
|
|
||||||
float current_time = i_engine->GetClientTime();
|
|
||||||
static float s_menu_close_time = 0.0f;
|
|
||||||
static bool s_is_restoring = false;
|
|
||||||
|
|
||||||
if (g_menu_open != s_was_menu_open) {
|
|
||||||
if (g_menu_open) {
|
|
||||||
i_engine->GetViewAngles(s_locked_view_angles);
|
|
||||||
s_lock_initialized = true;
|
|
||||||
i_engine->Con_Printf("Stored view angles: %.1f %.1f %.1f\n",
|
|
||||||
s_locked_view_angles[0], s_locked_view_angles[1], s_locked_view_angles[2]);
|
|
||||||
s_is_restoring = false;
|
|
||||||
} else {
|
|
||||||
s_menu_close_time = current_time;
|
|
||||||
s_is_restoring = true;
|
|
||||||
|
|
||||||
// Immediately restore angles
|
|
||||||
if (s_lock_initialized) {
|
|
||||||
i_engine->SetViewAngles(s_locked_view_angles);
|
|
||||||
i_engine->Con_Printf("Restored view angles: %.1f %.1f %.1f\n",
|
|
||||||
s_locked_view_angles[0], s_locked_view_angles[1], s_locked_view_angles[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s_was_menu_open = g_menu_open;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_menu_open && s_lock_initialized) {
|
|
||||||
i_engine->SetViewAngles(s_locked_view_angles);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_menu_open && s_is_restoring) {
|
|
||||||
if (current_time - s_menu_close_time < 0.2f) {
|
|
||||||
i_engine->SetViewAngles(s_locked_view_angles);
|
|
||||||
} else {
|
|
||||||
s_is_restoring = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
45
src/include/cvars.h
Normal file
45
src/include/cvars.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
#ifndef CVARS_H_
|
||||||
|
#define CVARS_H_
|
||||||
|
|
||||||
|
#include "sdk.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
#define CVAR_PREFIX "cv_"
|
||||||
|
#define CVAR_HACK_ID 0x4000 /* (1<<14) One that is not in use by the game */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DECL_CVAR: Declares cvar variable in source file.
|
||||||
|
* DECL_CVAR_EXTERN: Same but for headers.
|
||||||
|
* REGISTER_CVAR: Create the cvar, return cvar_t*
|
||||||
|
* CVAR_ON: Returns true if the cvar is non-zero
|
||||||
|
*
|
||||||
|
* prefix | meaning
|
||||||
|
* -------+-------------------------------
|
||||||
|
* cv_* | cvar variable
|
||||||
|
*/
|
||||||
|
#define DECL_CVAR(name) cvar_t* cv_##name = NULL;
|
||||||
|
|
||||||
|
#define DECL_CVAR_EXTERN(name) extern cvar_t* cv_##name;
|
||||||
|
|
||||||
|
#define REGISTER_CVAR(name, value) \
|
||||||
|
cv_##name = \
|
||||||
|
i_engine->pfnRegisterVariable(CVAR_PREFIX #name, #value, CVAR_HACK_ID);
|
||||||
|
|
||||||
|
#define CVAR_ON(name) (cv_##name->value != 0.0f)
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DECL_CVAR_EXTERN(bhop);
|
||||||
|
DECL_CVAR_EXTERN(autostrafe);
|
||||||
|
DECL_CVAR_EXTERN(aimbot);
|
||||||
|
DECL_CVAR_EXTERN(esp);
|
||||||
|
DECL_CVAR_EXTERN(chams);
|
||||||
|
DECL_CVAR_EXTERN(crosshair);
|
||||||
|
DECL_CVAR_EXTERN(clmove);
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool cvars_init(void);
|
||||||
|
|
||||||
|
#endif /* CVARS_H_ */
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
#ifndef ENTITY_H_
|
|
||||||
#define ENTITY_H_ 1
|
|
||||||
|
|
||||||
#include "sdk.h"
|
|
||||||
|
|
||||||
cl_entity_t* get_player(int ent_idx);
|
|
||||||
bool is_alive(cl_entity_t* ent);
|
|
||||||
bool valid_player(cl_entity_t* ent);
|
|
||||||
bool is_friend(cl_entity_t* ent);
|
|
||||||
bool can_shoot(void);
|
|
||||||
char* get_name(int ent_idx);
|
|
||||||
|
|
||||||
#endif /* ENTITY_H_ */
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#ifndef _GAME_DETECT_H_
|
|
||||||
#define _GAME_DETECT_H_
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GAME_UNKNOWN = 0,
|
|
||||||
GAME_HALFLIFE,
|
|
||||||
GAME_CS16,
|
|
||||||
GAME_TFC,
|
|
||||||
GAME_DAY_OF_DEFEAT,
|
|
||||||
GAME_DMC,
|
|
||||||
GAME_SL
|
|
||||||
} GameType;
|
|
||||||
|
|
||||||
GameType get_current_game(void);
|
|
||||||
int IsCS16(void);
|
|
||||||
int IsHalfLife(void);
|
|
||||||
int IsDayOfDefeat(void);
|
|
||||||
int IsTFC(void);
|
|
||||||
int IsDeathmatchClassic(void);
|
|
||||||
int IsSpaceLife(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
#ifndef GLOBALS_H_
|
#ifndef GLOBALS_H_
|
||||||
#define GLOBALS_H_
|
#define GLOBALS_H_
|
||||||
|
|
||||||
@@ -8,7 +9,6 @@ enum game_id {
|
|||||||
CS = 1, /* Counter-Strike 1.6 */
|
CS = 1, /* Counter-Strike 1.6 */
|
||||||
TF = 2, /* Team Fortress Classic */
|
TF = 2, /* Team Fortress Classic */
|
||||||
DOD = 3, /* Day of Defeat */
|
DOD = 3, /* Day of Defeat */
|
||||||
SL = 4, /* Space Life: Finleys Revenge */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@@ -34,12 +34,7 @@ enum game_id {
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
extern game_id this_game_id;
|
extern game_id this_game_id;
|
||||||
extern vec3_t g_punchAngles;
|
extern vec3_t g_bones[64][128];
|
||||||
extern float g_flNextAttack, g_flNextPrimaryAttack;
|
|
||||||
extern float* scr_fov_value;
|
|
||||||
extern int g_iClip;
|
|
||||||
extern int g_currentWeaponID;
|
|
||||||
extern double g_flCurrentTime;
|
|
||||||
|
|
||||||
extern void* hw;
|
extern void* hw;
|
||||||
extern void** h_client; /* hClientDLL hander */
|
extern void** h_client; /* hClientDLL hander */
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
#ifndef HOOKS_H_
|
#ifndef HOOKS_H_
|
||||||
#define HOOKS_H_
|
#define HOOKS_H_
|
||||||
|
|
||||||
@@ -7,12 +8,6 @@
|
|||||||
|
|
||||||
#include <dlfcn.h> /* dlsym */
|
#include <dlfcn.h> /* dlsym */
|
||||||
#include <GL/gl.h> /* GLFloat */
|
#include <GL/gl.h> /* GLFloat */
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef void (*hook_func_t)(void);
|
|
||||||
|
|
||||||
typedef int (*key_event_func_t)(int down, int keynum, const char* pszCurrentBinding);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table of prefixes:
|
* Table of prefixes:
|
||||||
* prefix | meaning
|
* prefix | meaning
|
||||||
@@ -56,15 +51,18 @@ typedef int (*key_event_func_t)(int down, int keynum, const char* pszCurrentBind
|
|||||||
* GL_HOOK: Hooks a OpenGL function. Example:
|
* GL_HOOK: Hooks a OpenGL function. Example:
|
||||||
*
|
*
|
||||||
* GL_HOOK(glColor4f);
|
* GL_HOOK(glColor4f);
|
||||||
|
* void** hp_glColor4f = (void**)dlsym(hw, "qglColor4f"); // Ptr
|
||||||
|
* ho_glColor4f = (glColor4f_t)(*hp_glColor4f); // Original from ptr
|
||||||
|
* *hp_glColor4f = (void*)h_glColor4f; // Set ptr to our func
|
||||||
|
|
||||||
|
* Note: ho_glColor4f and h_glColor4f sould be declared with DECL_HOOK_EXTERN
|
||||||
*
|
*
|
||||||
* Will store the original function in o_glColor4f and set the function to
|
|
||||||
* h_glColor4f (which must be defined)
|
|
||||||
*
|
*
|
||||||
* GL_UNHOOK: Restores a OpenGL hook created by GL_HOOK. Example:
|
* GL_UNHOOK: Restores a OpenGL hook created by GL_HOOK. Example:
|
||||||
*
|
*
|
||||||
* GL_UNHOOK(glColor4f);
|
* GL_UNHOOK(glColor4f);
|
||||||
*
|
* void** hp_glColor4f = (void**)dlsym(hw, "qglColor4f"); // Ptr
|
||||||
* Will restore the original function from o_glColor4f to the original pointer.
|
* *hp_glColor4f = (void*)ho_glColor4f; // Set to original
|
||||||
*/
|
*/
|
||||||
#define DECL_HOOK_EXTERN(type, name, ...) \
|
#define DECL_HOOK_EXTERN(type, name, ...) \
|
||||||
typedef type (*name##_t)(__VA_ARGS__); \
|
typedef type (*name##_t)(__VA_ARGS__); \
|
||||||
@@ -79,47 +77,29 @@ typedef int (*key_event_func_t)(int down, int keynum, const char* pszCurrentBind
|
|||||||
|
|
||||||
#define ORIGINAL(name, ...) ho_##name(__VA_ARGS__);
|
#define ORIGINAL(name, ...) ho_##name(__VA_ARGS__);
|
||||||
|
|
||||||
#define GL_HOOK(ret_type, name, ...) \
|
#define GL_HOOK(name) \
|
||||||
typedef ret_type (*name##_t)(__VA_ARGS__); \
|
void** hp_##name = (void**)dlsym(hw, "q" #name); \
|
||||||
name##_t h_##name; \
|
ho_##name = (name##_t)(*hp_##name); \
|
||||||
name##_t o_##name;
|
*hp_##name = (void*)h_##name;
|
||||||
|
|
||||||
#define GL_UNHOOK(name) \
|
#define GL_UNHOOK(name) \
|
||||||
o_##name = h_##name;
|
void** hp_##name = (void**)dlsym(hw, "q" #name); \
|
||||||
|
*hp_##name = (void*)ho_##name;
|
||||||
/* For GL hooking */
|
|
||||||
typedef void (*glColor4f_t)(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
|
||||||
typedef void* (*wglSwapBuffers_t)(void*);
|
|
||||||
|
|
||||||
/* OpenGL hooks */
|
|
||||||
extern void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
|
||||||
extern void* o_glColor4f;
|
|
||||||
|
|
||||||
extern wglSwapBuffers_t o_wglSwapBuffers;
|
|
||||||
|
|
||||||
/* HUD_Key_Event hook */
|
|
||||||
extern int h_HUD_Key_Event(int down, int keynum, const char* pszCurrentBinding);
|
|
||||||
extern key_event_func_t ho_HUD_Key_Event;
|
|
||||||
|
|
||||||
/* VMT hooks */
|
|
||||||
DECL_HOOK_EXTERN(void, CL_CreateMove, float, usercmd_t*, int);
|
|
||||||
DECL_HOOK_EXTERN(int, HUD_Redraw, float, int);
|
|
||||||
DECL_HOOK_EXTERN(void, StudioRenderModel, void*);
|
|
||||||
DECL_HOOK_EXTERN(void, CalcRefdef, ref_params_t*);
|
|
||||||
DECL_HOOK_EXTERN(void, HUD_PostRunCmd, struct local_state_s*,
|
|
||||||
struct local_state_s*, struct usercmd_s*, int, double,
|
|
||||||
unsigned int);
|
|
||||||
|
|
||||||
/* Detour hooks */
|
|
||||||
DECL_HOOK_EXTERN(void, CL_Move);
|
|
||||||
|
|
||||||
/* Detour for CL_Move */
|
|
||||||
#define ORIGINAL_DETOUR(type) ((type)detour_get_original(&detour_data_clmove))()
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool hooks_init(void);
|
bool hooks_init(void);
|
||||||
void hooks_restore(void);
|
void hooks_restore(void);
|
||||||
void hooks_schedule_uninject(void);
|
|
||||||
|
/* VMT hooks */
|
||||||
|
DECL_HOOK_EXTERN(void, CL_CreateMove, float, usercmd_t*, int);
|
||||||
|
DECL_HOOK_EXTERN(int, HUD_Redraw, float, int);
|
||||||
|
DECL_HOOK_EXTERN(void, StudioRenderModel, void*);
|
||||||
|
|
||||||
|
/* OpenGL hooks */
|
||||||
|
DECL_HOOK_EXTERN(void, glColor4f, GLfloat, GLfloat, GLfloat, GLfloat);
|
||||||
|
|
||||||
|
/* Detour hooks */
|
||||||
|
DECL_HOOK_EXTERN(void, CL_Move);
|
||||||
|
|
||||||
#endif /* HOOKS_H_ */
|
#endif /* HOOKS_H_ */
|
||||||
|
|||||||
@@ -1,321 +0,0 @@
|
|||||||
// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline)
|
|
||||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
|
||||||
|
|
||||||
// Implemented features:
|
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
|
||||||
// Missing features or Issues:
|
|
||||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
|
||||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
|
||||||
// Learn about Dear ImGui:
|
|
||||||
// - FAQ https://dearimgui.com/faq
|
|
||||||
// - Getting Started https://dearimgui.com/getting-started
|
|
||||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
|
||||||
// - Introduction, links and more at the top of imgui.cpp
|
|
||||||
|
|
||||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
|
||||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
|
||||||
// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read.
|
|
||||||
// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more
|
|
||||||
// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might
|
|
||||||
// confuse your GPU driver.
|
|
||||||
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
|
|
||||||
|
|
||||||
// CHANGELOG
|
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
|
||||||
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
|
||||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748)
|
|
||||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
|
||||||
// 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
|
||||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
|
||||||
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
|
||||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
|
|
||||||
// 2020-01-23: OpenGL: Backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications.
|
|
||||||
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
|
||||||
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
|
|
||||||
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
|
||||||
// 2018-08-03: OpenGL: Disabling/restoring GL_LIGHTING and GL_COLOR_MATERIAL to increase compatibility with legacy OpenGL applications.
|
|
||||||
// 2018-06-08: Misc: Extracted imgui_impl_opengl2.cpp/.h away from the old combined GLFW/SDL+OpenGL2 examples.
|
|
||||||
// 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
|
||||||
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplOpenGL2_RenderDrawData() in the .h file so you can call it yourself.
|
|
||||||
// 2017-09-01: OpenGL: Save and restore current polygon mode.
|
|
||||||
// 2016-09-10: OpenGL: Uploading font texture as RGBA32 to increase compatibility with users shaders (not ideal).
|
|
||||||
// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
|
|
||||||
|
|
||||||
#include "imgui.h"
|
|
||||||
#ifndef IMGUI_DISABLE
|
|
||||||
#include "imgui_impl_opengl2.h"
|
|
||||||
#include <stdint.h> // intptr_t
|
|
||||||
|
|
||||||
// Clang/GCC warnings with -Weverything
|
|
||||||
#if defined(__clang__)
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used
|
|
||||||
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Include OpenGL header (without an OpenGL loader) requires a bit of fiddling
|
|
||||||
#if defined(_WIN32) && !defined(APIENTRY)
|
|
||||||
#define APIENTRY __stdcall // It is customary to use APIENTRY for OpenGL function pointer declarations on all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
|
|
||||||
#endif
|
|
||||||
#if defined(_WIN32) && !defined(WINGDIAPI)
|
|
||||||
#define WINGDIAPI __declspec(dllimport) // Some Windows OpenGL headers need this
|
|
||||||
#endif
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#define GL_SILENCE_DEPRECATION
|
|
||||||
#include <OpenGL/gl.h>
|
|
||||||
#else
|
|
||||||
#include <GL/gl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// [Debugging]
|
|
||||||
//#define IMGUI_IMPL_OPENGL_DEBUG
|
|
||||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
|
||||||
#include <stdio.h>
|
|
||||||
#define GL_CALL(_CALL) do { _CALL; GLenum gl_err = glGetError(); if (gl_err != 0) fprintf(stderr, "GL error 0x%x returned from '%s'.\n", gl_err, #_CALL); } while (0) // Call with error check
|
|
||||||
#else
|
|
||||||
#define GL_CALL(_CALL) _CALL // Call without error check
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// OpenGL data
|
|
||||||
struct ImGui_ImplOpenGL2_Data
|
|
||||||
{
|
|
||||||
GLuint FontTexture;
|
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
|
||||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
|
||||||
static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
|
|
||||||
{
|
|
||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions
|
|
||||||
bool ImGui_ImplOpenGL2_Init()
|
|
||||||
{
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
IMGUI_CHECKVERSION();
|
|
||||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
|
||||||
|
|
||||||
// Setup backend capabilities flags
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)();
|
|
||||||
io.BackendRendererUserData = (void*)bd;
|
|
||||||
io.BackendRendererName = "imgui_impl_opengl2";
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_Shutdown()
|
|
||||||
{
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
|
||||||
io.BackendRendererName = nullptr;
|
|
||||||
io.BackendRendererUserData = nullptr;
|
|
||||||
IM_DELETE(bd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_NewFrame()
|
|
||||||
{
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL2_Init()?");
|
|
||||||
|
|
||||||
if (!bd->FontTexture)
|
|
||||||
ImGui_ImplOpenGL2_CreateDeviceObjects();
|
|
||||||
if (!bd->FontTexture)
|
|
||||||
ImGui_ImplOpenGL2_CreateFontsTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
|
|
||||||
{
|
|
||||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
//glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // In order to composite our output buffer we need to preserve alpha
|
|
||||||
glDisable(GL_CULL_FACE);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
glDisable(GL_STENCIL_TEST);
|
|
||||||
glDisable(GL_LIGHTING);
|
|
||||||
glDisable(GL_COLOR_MATERIAL);
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
||||||
glShadeModel(GL_SMOOTH);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
|
|
||||||
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
|
||||||
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
|
|
||||||
// (DO NOT MODIFY THIS FILE! Add the code in your calling function)
|
|
||||||
// GLint last_program;
|
|
||||||
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
|
||||||
// glUseProgram(0);
|
|
||||||
// ImGui_ImplOpenGL2_RenderDrawData(...);
|
|
||||||
// glUseProgram(last_program)
|
|
||||||
// There are potentially many more states you could need to clear/setup that we can't access from default headers.
|
|
||||||
// e.g. glBindBuffer(GL_ARRAY_BUFFER, 0), glDisable(GL_TEXTURE_CUBE_MAP).
|
|
||||||
|
|
||||||
// Setup viewport, orthographic projection matrix
|
|
||||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
|
||||||
GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glPushMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glPushMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenGL2 Render function.
|
|
||||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
|
||||||
// This is in order to be able to run within an OpenGL engine that doesn't do so.
|
|
||||||
void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|
||||||
{
|
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
|
||||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
|
||||||
if (fb_width == 0 || fb_height == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Backup GL state
|
|
||||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
||||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
|
||||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
|
||||||
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
|
||||||
GLint last_shade_model; glGetIntegerv(GL_SHADE_MODEL, &last_shade_model);
|
|
||||||
GLint last_tex_env_mode; glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_tex_env_mode);
|
|
||||||
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
|
|
||||||
|
|
||||||
// Setup desired GL state
|
|
||||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
|
||||||
|
|
||||||
// Will project scissor/clipping rectangles into framebuffer space
|
|
||||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
|
||||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
|
||||||
|
|
||||||
// Render command lists
|
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
|
||||||
{
|
|
||||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
|
||||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
|
||||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
|
||||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv)));
|
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col)));
|
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
|
||||||
{
|
|
||||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
|
||||||
if (pcmd->UserCallback)
|
|
||||||
{
|
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
|
||||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
|
||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
|
||||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
|
||||||
else
|
|
||||||
pcmd->UserCallback(draw_list, pcmd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
|
||||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
|
||||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
|
||||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
|
||||||
glScissor((int)clip_min.x, (int)((float)fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y));
|
|
||||||
|
|
||||||
// Bind texture, Draw
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
|
||||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore modified GL state
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glPopMatrix();
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glPopMatrix();
|
|
||||||
glPopAttrib();
|
|
||||||
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
|
|
||||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
|
||||||
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
|
||||||
glShadeModel(last_shade_model);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImGui_ImplOpenGL2_CreateFontsTexture()
|
|
||||||
{
|
|
||||||
// Build texture atlas
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
GLint last_texture;
|
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
||||||
glGenTextures(1, &bd->FontTexture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, bd->FontTexture);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
|
||||||
|
|
||||||
// Restore state
|
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_DestroyFontsTexture()
|
|
||||||
{
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
if (bd->FontTexture)
|
|
||||||
{
|
|
||||||
glDeleteTextures(1, &bd->FontTexture);
|
|
||||||
io.Fonts->SetTexID(0);
|
|
||||||
bd->FontTexture = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImGui_ImplOpenGL2_CreateDeviceObjects()
|
|
||||||
{
|
|
||||||
return ImGui_ImplOpenGL2_CreateFontsTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_DestroyDeviceObjects()
|
|
||||||
{
|
|
||||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline)
|
|
||||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
|
||||||
|
|
||||||
// Implemented features:
|
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
|
||||||
// Missing features or Issues:
|
|
||||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
|
||||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
|
||||||
// Learn about Dear ImGui:
|
|
||||||
// - FAQ https://dearimgui.com/faq
|
|
||||||
// - Getting Started https://dearimgui.com/getting-started
|
|
||||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
|
||||||
// - Introduction, links and more at the top of imgui.cpp
|
|
||||||
|
|
||||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
|
||||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
|
||||||
// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read.
|
|
||||||
// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more
|
|
||||||
// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might
|
|
||||||
// confuse your GPU driver.
|
|
||||||
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "../imgui.h" // IMGUI_IMPL_API
|
|
||||||
#ifndef IMGUI_DISABLE
|
|
||||||
|
|
||||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data);
|
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
//-----------------------------------------------------------------------------
|
|
||||||
// DEAR IMGUI COMPILE-TIME OPTIONS
|
|
||||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
|
||||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
|
||||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
|
||||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
|
||||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
|
||||||
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
//---- Define assertion handler. Defaults to calling assert().
|
|
||||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
|
||||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
|
||||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
|
||||||
|
|
||||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
|
||||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
|
||||||
// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
|
||||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
|
||||||
//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export
|
|
||||||
//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import
|
|
||||||
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
|
|
||||||
|
|
||||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
|
||||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
|
||||||
|
|
||||||
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
|
||||||
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
|
||||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
|
||||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
|
|
||||||
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
|
|
||||||
|
|
||||||
//---- Don't implement some functions to reduce linkage requirements.
|
|
||||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
|
||||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
|
||||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
|
||||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
|
||||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
|
||||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
|
|
||||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
|
||||||
|
|
||||||
//---- Enable Test Engine / Automation features.
|
|
||||||
//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details.
|
|
||||||
|
|
||||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
|
||||||
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
|
||||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
|
||||||
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
|
||||||
|
|
||||||
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
|
|
||||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
|
||||||
|
|
||||||
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate.
|
|
||||||
//#define IMGUI_USE_LEGACY_CRC32_ADLER
|
|
||||||
|
|
||||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
|
||||||
//#define IMGUI_USE_WCHAR32
|
|
||||||
|
|
||||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
|
||||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
|
||||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
|
||||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
|
||||||
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
|
||||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
|
||||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
|
||||||
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
|
|
||||||
|
|
||||||
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
|
||||||
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
|
||||||
//#define IMGUI_USE_STB_SPRINTF
|
|
||||||
|
|
||||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
|
||||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
|
||||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
|
||||||
//#define IMGUI_ENABLE_FREETYPE
|
|
||||||
|
|
||||||
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
|
|
||||||
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
|
||||||
// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions.
|
|
||||||
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
|
|
||||||
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
|
||||||
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
|
||||||
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
|
||||||
|
|
||||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
|
||||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
|
||||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
|
||||||
|
|
||||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
|
||||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
|
||||||
/*
|
|
||||||
#define IM_VEC2_CLASS_EXTRA \
|
|
||||||
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
|
||||||
operator MyVec2() const { return MyVec2(x,y); }
|
|
||||||
|
|
||||||
#define IM_VEC4_CLASS_EXTRA \
|
|
||||||
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
|
||||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
|
||||||
*/
|
|
||||||
//---- ...Or use Dear ImGui's own very basic math operators.
|
|
||||||
//#define IMGUI_DEFINE_MATH_OPERATORS
|
|
||||||
|
|
||||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
|
||||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
|
||||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
|
||||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
|
||||||
//#define ImDrawIdx unsigned int
|
|
||||||
|
|
||||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
|
||||||
//struct ImDrawList;
|
|
||||||
//struct ImDrawCmd;
|
|
||||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
|
||||||
//#define ImDrawCallback MyImDrawCallback
|
|
||||||
|
|
||||||
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
|
|
||||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
|
||||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
|
||||||
//#define IM_DEBUG_BREAK __debugbreak()
|
|
||||||
|
|
||||||
//---- Debug Tools: Enable slower asserts
|
|
||||||
//#define IMGUI_DEBUG_PARANOID
|
|
||||||
|
|
||||||
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
|
||||||
/*
|
|
||||||
namespace ImGui
|
|
||||||
{
|
|
||||||
void MyFunction(const char* name, MyMatrix44* mtx);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,627 +0,0 @@
|
|||||||
// [DEAR IMGUI]
|
|
||||||
// This is a slightly modified version of stb_rect_pack.h 1.01.
|
|
||||||
// Grep for [DEAR IMGUI] to find the changes.
|
|
||||||
//
|
|
||||||
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
|
|
||||||
// Sean Barrett 2014
|
|
||||||
//
|
|
||||||
// Useful for e.g. packing rectangular textures into an atlas.
|
|
||||||
// Does not do rotation.
|
|
||||||
//
|
|
||||||
// Before #including,
|
|
||||||
//
|
|
||||||
// #define STB_RECT_PACK_IMPLEMENTATION
|
|
||||||
//
|
|
||||||
// in the file that you want to have the implementation.
|
|
||||||
//
|
|
||||||
// Not necessarily the awesomest packing method, but better than
|
|
||||||
// the totally naive one in stb_truetype (which is primarily what
|
|
||||||
// this is meant to replace).
|
|
||||||
//
|
|
||||||
// Has only had a few tests run, may have issues.
|
|
||||||
//
|
|
||||||
// More docs to come.
|
|
||||||
//
|
|
||||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
|
||||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
|
||||||
//
|
|
||||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
|
||||||
//
|
|
||||||
// Please note: better rectangle packers are welcome! Please
|
|
||||||
// implement them to the same API, but with a different init
|
|
||||||
// function.
|
|
||||||
//
|
|
||||||
// Credits
|
|
||||||
//
|
|
||||||
// Library
|
|
||||||
// Sean Barrett
|
|
||||||
// Minor features
|
|
||||||
// Martins Mozeiko
|
|
||||||
// github:IntellectualKitty
|
|
||||||
//
|
|
||||||
// Bugfixes / warning fixes
|
|
||||||
// Jeremy Jaussaud
|
|
||||||
// Fabian Giesen
|
|
||||||
//
|
|
||||||
// Version history:
|
|
||||||
//
|
|
||||||
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
|
|
||||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
|
||||||
// 0.99 (2019-02-07) warning fixes
|
|
||||||
// 0.11 (2017-03-03) return packing success/fail result
|
|
||||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
|
||||||
// 0.09 (2016-08-27) fix compiler warnings
|
|
||||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
|
||||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
|
||||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
|
||||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
|
||||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
|
||||||
// 0.01: initial release
|
|
||||||
//
|
|
||||||
// LICENSE
|
|
||||||
//
|
|
||||||
// See end of file for license information.
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// INCLUDE SECTION
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
|
||||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
|
||||||
|
|
||||||
#define STB_RECT_PACK_VERSION 1
|
|
||||||
|
|
||||||
#ifdef STBRP_STATIC
|
|
||||||
#define STBRP_DEF static
|
|
||||||
#else
|
|
||||||
#define STBRP_DEF extern
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct stbrp_context stbrp_context;
|
|
||||||
typedef struct stbrp_node stbrp_node;
|
|
||||||
typedef struct stbrp_rect stbrp_rect;
|
|
||||||
|
|
||||||
typedef int stbrp_coord;
|
|
||||||
|
|
||||||
#define STBRP__MAXVAL 0x7fffffff
|
|
||||||
// Mostly for internal use, but this is the maximum supported coordinate value.
|
|
||||||
|
|
||||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
|
||||||
// Assign packed locations to rectangles. The rectangles are of type
|
|
||||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
|
||||||
// are 'num_rects' many of them.
|
|
||||||
//
|
|
||||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
|
||||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
|
||||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
|
||||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
|
||||||
// have the 'was_packed' flag set to 0.
|
|
||||||
//
|
|
||||||
// You should not try to access the 'rects' array from another thread
|
|
||||||
// while this function is running, as the function temporarily reorders
|
|
||||||
// the array while it executes.
|
|
||||||
//
|
|
||||||
// To pack into another rectangle, you need to call stbrp_init_target
|
|
||||||
// again. To continue packing into the same rectangle, you can call
|
|
||||||
// this function again. Calling this multiple times with multiple rect
|
|
||||||
// arrays will probably produce worse packing results than calling it
|
|
||||||
// a single time with the full rectangle array, but the option is
|
|
||||||
// available.
|
|
||||||
//
|
|
||||||
// The function returns 1 if all of the rectangles were successfully
|
|
||||||
// packed and 0 otherwise.
|
|
||||||
|
|
||||||
struct stbrp_rect
|
|
||||||
{
|
|
||||||
// reserved for your use:
|
|
||||||
int id;
|
|
||||||
|
|
||||||
// input:
|
|
||||||
stbrp_coord w, h;
|
|
||||||
|
|
||||||
// output:
|
|
||||||
stbrp_coord x, y;
|
|
||||||
int was_packed; // non-zero if valid packing
|
|
||||||
|
|
||||||
}; // 16 bytes, nominally
|
|
||||||
|
|
||||||
|
|
||||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
|
||||||
// Initialize a rectangle packer to:
|
|
||||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
|
||||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
|
||||||
//
|
|
||||||
// You must call this function every time you start packing into a new target.
|
|
||||||
//
|
|
||||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
|
||||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
|
||||||
// the call (or calls) finish.
|
|
||||||
//
|
|
||||||
// Note: to guarantee best results, either:
|
|
||||||
// 1. make sure 'num_nodes' >= 'width'
|
|
||||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
|
||||||
//
|
|
||||||
// If you don't do either of the above things, widths will be quantized to multiples
|
|
||||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
|
||||||
//
|
|
||||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
|
||||||
// may run out of temporary storage and be unable to pack some rectangles.
|
|
||||||
|
|
||||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
|
||||||
// Optionally call this function after init but before doing any packing to
|
|
||||||
// change the handling of the out-of-temp-memory scenario, described above.
|
|
||||||
// If you call init again, this will be reset to the default (false).
|
|
||||||
|
|
||||||
|
|
||||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
|
||||||
// Optionally select which packing heuristic the library should use. Different
|
|
||||||
// heuristics will produce better/worse results for different data sets.
|
|
||||||
// If you call init again, this will be reset to the default.
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
STBRP_HEURISTIC_Skyline_default=0,
|
|
||||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
|
||||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// the details of the following structures don't matter to you, but they must
|
|
||||||
// be visible so you can handle the memory allocations for them
|
|
||||||
|
|
||||||
struct stbrp_node
|
|
||||||
{
|
|
||||||
stbrp_coord x,y;
|
|
||||||
stbrp_node *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct stbrp_context
|
|
||||||
{
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int align;
|
|
||||||
int init_mode;
|
|
||||||
int heuristic;
|
|
||||||
int num_nodes;
|
|
||||||
stbrp_node *active_head;
|
|
||||||
stbrp_node *free_head;
|
|
||||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// IMPLEMENTATION SECTION
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
|
||||||
#ifndef STBRP_SORT
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define STBRP_SORT qsort
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef STBRP_ASSERT
|
|
||||||
#include <assert.h>
|
|
||||||
#define STBRP_ASSERT assert
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#define STBRP__NOTUSED(v) (void)(v)
|
|
||||||
#define STBRP__CDECL __cdecl
|
|
||||||
#else
|
|
||||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
|
||||||
#define STBRP__CDECL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
STBRP__INIT_skyline = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
|
||||||
{
|
|
||||||
switch (context->init_mode) {
|
|
||||||
case STBRP__INIT_skyline:
|
|
||||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
|
||||||
context->heuristic = heuristic;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
STBRP_ASSERT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
|
||||||
{
|
|
||||||
if (allow_out_of_mem)
|
|
||||||
// if it's ok to run out of memory, then don't bother aligning them;
|
|
||||||
// this gives better packing, but may fail due to OOM (even though
|
|
||||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
|
||||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
|
||||||
context->align = 1;
|
|
||||||
else {
|
|
||||||
// if it's not ok to run out of memory, then quantize the widths
|
|
||||||
// so that num_nodes is always enough nodes.
|
|
||||||
//
|
|
||||||
// I.e. num_nodes * align >= width
|
|
||||||
// align >= width / num_nodes
|
|
||||||
// align = ceil(width/num_nodes)
|
|
||||||
|
|
||||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i < num_nodes-1; ++i)
|
|
||||||
nodes[i].next = &nodes[i+1];
|
|
||||||
nodes[i].next = NULL;
|
|
||||||
context->init_mode = STBRP__INIT_skyline;
|
|
||||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
|
||||||
context->free_head = &nodes[0];
|
|
||||||
context->active_head = &context->extra[0];
|
|
||||||
context->width = width;
|
|
||||||
context->height = height;
|
|
||||||
context->num_nodes = num_nodes;
|
|
||||||
stbrp_setup_allow_out_of_mem(context, 0);
|
|
||||||
|
|
||||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
|
||||||
context->extra[0].x = 0;
|
|
||||||
context->extra[0].y = 0;
|
|
||||||
context->extra[0].next = &context->extra[1];
|
|
||||||
context->extra[1].x = (stbrp_coord) width;
|
|
||||||
context->extra[1].y = (1<<30);
|
|
||||||
context->extra[1].next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find minimum y position if it starts at x1
|
|
||||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
|
||||||
{
|
|
||||||
stbrp_node *node = first;
|
|
||||||
int x1 = x0 + width;
|
|
||||||
int min_y, visited_width, waste_area;
|
|
||||||
|
|
||||||
STBRP__NOTUSED(c);
|
|
||||||
|
|
||||||
STBRP_ASSERT(first->x <= x0);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// skip in case we're past the node
|
|
||||||
while (node->next->x <= x0)
|
|
||||||
++node;
|
|
||||||
#else
|
|
||||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STBRP_ASSERT(node->x <= x0);
|
|
||||||
|
|
||||||
min_y = 0;
|
|
||||||
waste_area = 0;
|
|
||||||
visited_width = 0;
|
|
||||||
while (node->x < x1) {
|
|
||||||
if (node->y > min_y) {
|
|
||||||
// raise min_y higher.
|
|
||||||
// we've accounted for all waste up to min_y,
|
|
||||||
// but we'll now add more waste for everything we've visted
|
|
||||||
waste_area += visited_width * (node->y - min_y);
|
|
||||||
min_y = node->y;
|
|
||||||
// the first time through, visited_width might be reduced
|
|
||||||
if (node->x < x0)
|
|
||||||
visited_width += node->next->x - x0;
|
|
||||||
else
|
|
||||||
visited_width += node->next->x - node->x;
|
|
||||||
} else {
|
|
||||||
// add waste area
|
|
||||||
int under_width = node->next->x - node->x;
|
|
||||||
if (under_width + visited_width > width)
|
|
||||||
under_width = width - visited_width;
|
|
||||||
waste_area += under_width * (min_y - node->y);
|
|
||||||
visited_width += under_width;
|
|
||||||
}
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pwaste = waste_area;
|
|
||||||
return min_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int x,y;
|
|
||||||
stbrp_node **prev_link;
|
|
||||||
} stbrp__findresult;
|
|
||||||
|
|
||||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
|
||||||
{
|
|
||||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
|
||||||
stbrp__findresult fr;
|
|
||||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
|
||||||
|
|
||||||
// align to multiple of c->align
|
|
||||||
width = (width + c->align - 1);
|
|
||||||
width -= width % c->align;
|
|
||||||
STBRP_ASSERT(width % c->align == 0);
|
|
||||||
|
|
||||||
// if it can't possibly fit, bail immediately
|
|
||||||
if (width > c->width || height > c->height) {
|
|
||||||
fr.prev_link = NULL;
|
|
||||||
fr.x = fr.y = 0;
|
|
||||||
return fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
node = c->active_head;
|
|
||||||
prev = &c->active_head;
|
|
||||||
while (node->x + width <= c->width) {
|
|
||||||
int y,waste;
|
|
||||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
|
||||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
|
||||||
// bottom left
|
|
||||||
if (y < best_y) {
|
|
||||||
best_y = y;
|
|
||||||
best = prev;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// best-fit
|
|
||||||
if (y + height <= c->height) {
|
|
||||||
// can only use it if it first vertically
|
|
||||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
|
||||||
best_y = y;
|
|
||||||
best_waste = waste;
|
|
||||||
best = prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prev = &node->next;
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
|
||||||
|
|
||||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
|
||||||
//
|
|
||||||
// e.g, if fitting
|
|
||||||
//
|
|
||||||
// ____________________
|
|
||||||
// |____________________|
|
|
||||||
//
|
|
||||||
// into
|
|
||||||
//
|
|
||||||
// | |
|
|
||||||
// | ____________|
|
|
||||||
// |____________|
|
|
||||||
//
|
|
||||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
|
||||||
//
|
|
||||||
// This makes BF take about 2x the time
|
|
||||||
|
|
||||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
|
||||||
tail = c->active_head;
|
|
||||||
node = c->active_head;
|
|
||||||
prev = &c->active_head;
|
|
||||||
// find first node that's admissible
|
|
||||||
while (tail->x < width)
|
|
||||||
tail = tail->next;
|
|
||||||
while (tail) {
|
|
||||||
int xpos = tail->x - width;
|
|
||||||
int y,waste;
|
|
||||||
STBRP_ASSERT(xpos >= 0);
|
|
||||||
// find the left position that matches this
|
|
||||||
while (node->next->x <= xpos) {
|
|
||||||
prev = &node->next;
|
|
||||||
node = node->next;
|
|
||||||
}
|
|
||||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
|
||||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
|
||||||
if (y + height <= c->height) {
|
|
||||||
if (y <= best_y) {
|
|
||||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
|
||||||
best_x = xpos;
|
|
||||||
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
|
|
||||||
best_y = y;
|
|
||||||
best_waste = waste;
|
|
||||||
best = prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tail = tail->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fr.prev_link = best;
|
|
||||||
fr.x = best_x;
|
|
||||||
fr.y = best_y;
|
|
||||||
return fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
|
||||||
{
|
|
||||||
// find best position according to heuristic
|
|
||||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
|
||||||
stbrp_node *node, *cur;
|
|
||||||
|
|
||||||
// bail if:
|
|
||||||
// 1. it failed
|
|
||||||
// 2. the best node doesn't fit (we don't always check this)
|
|
||||||
// 3. we're out of memory
|
|
||||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
|
||||||
res.prev_link = NULL;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// on success, create new node
|
|
||||||
node = context->free_head;
|
|
||||||
node->x = (stbrp_coord) res.x;
|
|
||||||
node->y = (stbrp_coord) (res.y + height);
|
|
||||||
|
|
||||||
context->free_head = node->next;
|
|
||||||
|
|
||||||
// insert the new node into the right starting point, and
|
|
||||||
// let 'cur' point to the remaining nodes needing to be
|
|
||||||
// stiched back in
|
|
||||||
|
|
||||||
cur = *res.prev_link;
|
|
||||||
if (cur->x < res.x) {
|
|
||||||
// preserve the existing one, so start testing with the next one
|
|
||||||
stbrp_node *next = cur->next;
|
|
||||||
cur->next = node;
|
|
||||||
cur = next;
|
|
||||||
} else {
|
|
||||||
*res.prev_link = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
// from here, traverse cur and free the nodes, until we get to one
|
|
||||||
// that shouldn't be freed
|
|
||||||
while (cur->next && cur->next->x <= res.x + width) {
|
|
||||||
stbrp_node *next = cur->next;
|
|
||||||
// move the current node to the free list
|
|
||||||
cur->next = context->free_head;
|
|
||||||
context->free_head = cur;
|
|
||||||
cur = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stitch the list back in
|
|
||||||
node->next = cur;
|
|
||||||
|
|
||||||
if (cur->x < res.x + width)
|
|
||||||
cur->x = (stbrp_coord) (res.x + width);
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
cur = context->active_head;
|
|
||||||
while (cur->x < context->width) {
|
|
||||||
STBRP_ASSERT(cur->x < cur->next->x);
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
|
||||||
STBRP_ASSERT(cur->next == NULL);
|
|
||||||
|
|
||||||
{
|
|
||||||
int count=0;
|
|
||||||
cur = context->active_head;
|
|
||||||
while (cur) {
|
|
||||||
cur = cur->next;
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
cur = context->free_head;
|
|
||||||
while (cur) {
|
|
||||||
cur = cur->next;
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
STBRP_ASSERT(count == context->num_nodes+2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
|
||||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
|
||||||
if (p->h > q->h)
|
|
||||||
return -1;
|
|
||||||
if (p->h < q->h)
|
|
||||||
return 1;
|
|
||||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
|
||||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
|
||||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
|
||||||
}
|
|
||||||
|
|
||||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
|
||||||
{
|
|
||||||
int i, all_rects_packed = 1;
|
|
||||||
|
|
||||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
|
||||||
for (i=0; i < num_rects; ++i) {
|
|
||||||
rects[i].was_packed = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort according to heuristic
|
|
||||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
|
||||||
|
|
||||||
for (i=0; i < num_rects; ++i) {
|
|
||||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
|
||||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
|
||||||
} else {
|
|
||||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
|
||||||
if (fr.prev_link) {
|
|
||||||
rects[i].x = (stbrp_coord) fr.x;
|
|
||||||
rects[i].y = (stbrp_coord) fr.y;
|
|
||||||
} else {
|
|
||||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// unsort
|
|
||||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
|
||||||
|
|
||||||
// set was_packed flags and all_rects_packed status
|
|
||||||
for (i=0; i < num_rects; ++i) {
|
|
||||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
|
||||||
if (!rects[i].was_packed)
|
|
||||||
all_rects_packed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the all_rects_packed status
|
|
||||||
return all_rects_packed;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
This software is available under 2 licenses -- choose whichever you prefer.
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
ALTERNATIVE A - MIT License
|
|
||||||
Copyright (c) 2017 Sean Barrett
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
|
||||||
This is free and unencumbered software released into the public domain.
|
|
||||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
|
||||||
software, either in source code form or as a compiled binary, for any purpose,
|
|
||||||
commercial or non-commercial, and by any means.
|
|
||||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
|
||||||
software dedicate any and all copyright interest in the software to the public
|
|
||||||
domain. We make this dedication for the benefit of the public at large and to
|
|
||||||
the detriment of our heirs and successors. We intend this dedication to be an
|
|
||||||
overt act of relinquishment in perpetuity of all present and future rights to
|
|
||||||
this software under copyright law.
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,8 @@
|
|||||||
|
|
||||||
#ifndef MAIN_H_
|
#ifndef MAIN_H_
|
||||||
#define MAIN_H_
|
#define MAIN_H_
|
||||||
|
|
||||||
void load(void);
|
void load(void);
|
||||||
void unload(void);
|
|
||||||
void self_unload(void);
|
void self_unload(void);
|
||||||
void UNINJECT_CommandHandler(void);
|
|
||||||
void safe_unload_with_debug(void);
|
|
||||||
|
|
||||||
#endif /* MAIN_H_ */
|
#endif /* MAIN_H_ */
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
#ifndef MATHUTIL_H_
|
|
||||||
#define MATHUTIL_H_ 1
|
|
||||||
|
|
||||||
#include "sdk.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
/* Vector 2 for 2d points */
|
|
||||||
typedef float vec2_t[2];
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define DEG2RAD(n) ((n)*M_PI / 180.0f)
|
|
||||||
#define RAD2DEG(n) ((n)*180.0f / M_PI)
|
|
||||||
|
|
||||||
/* Use indexes so it works for float[] as well as vec3_t */
|
|
||||||
#define vec_copy(dst, src) \
|
|
||||||
do { \
|
|
||||||
dst[0] = src[0]; \
|
|
||||||
dst[1] = src[1]; \
|
|
||||||
dst[2] = src[2]; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
vec3_t vec3(float x, float y, float z);
|
|
||||||
vec3_t vec_add(vec3_t a, vec3_t b);
|
|
||||||
vec3_t vec_sub(vec3_t a, vec3_t b);
|
|
||||||
bool vec_is_zero(vec3_t v);
|
|
||||||
float vec_len2d(vec3_t v);
|
|
||||||
void ang_clamp(vec3_t* v);
|
|
||||||
void vec_norm(vec3_t* v);
|
|
||||||
float angle_delta_rad(float a, float b);
|
|
||||||
vec3_t vec_to_ang(vec3_t v);
|
|
||||||
vec3_t matrix_3x4_origin(matrix_3x4 m);
|
|
||||||
bool world_to_screen(vec3_t vec, vec2_t screen);
|
|
||||||
|
|
||||||
#endif /* MATHUTIL_H_ */
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "imgui/imgui.h"
|
|
||||||
#include "imgui/backends/imgui_impl_opengl2.h"
|
|
||||||
#include "sdk.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool menu_init(void);
|
|
||||||
void menu_shutdown(void);
|
|
||||||
void menu_render(void);
|
|
||||||
void menu_key_event(int keynum, int down);
|
|
||||||
void menu_char_event(int ascii);
|
|
||||||
|
|
||||||
extern bool g_menu_open;
|
|
||||||
extern bool g_imgui_initialized;
|
|
||||||
extern ImGuiContext* g_imgui_context;
|
|
||||||
extern bool g_waiting_for_key_bind;
|
|
||||||
extern const char* g_current_key_binding_action;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -35,38 +35,6 @@
|
|||||||
/* engine_studio_api_t */
|
/* engine_studio_api_t */
|
||||||
#include "sdk/common/r_studioint.h"
|
#include "sdk/common/r_studioint.h"
|
||||||
|
|
||||||
#define K_TAB 9
|
|
||||||
#define K_ENTER 13
|
|
||||||
#define K_ESCAPE 27
|
|
||||||
#define K_SPACE 32
|
|
||||||
#define K_BACKSPACE 127
|
|
||||||
#define K_UPARROW 128
|
|
||||||
#define K_DOWNARROW 129
|
|
||||||
#define K_LEFTARROW 130
|
|
||||||
#define K_RIGHTARROW 131
|
|
||||||
#define K_ALT 132
|
|
||||||
#define K_CTRL 133
|
|
||||||
#define K_SHIFT 134
|
|
||||||
#define K_F1 135
|
|
||||||
#define K_F2 136
|
|
||||||
#define K_F3 137
|
|
||||||
#define K_F4 138
|
|
||||||
#define K_F5 139
|
|
||||||
#define K_F6 140
|
|
||||||
#define K_F7 141
|
|
||||||
#define K_F8 142
|
|
||||||
#define K_F9 143
|
|
||||||
#define K_F10 144
|
|
||||||
#define K_F11 145
|
|
||||||
#define K_F12 146
|
|
||||||
#define K_INS 147
|
|
||||||
#define K_DEL 148
|
|
||||||
#define K_PGDN 149
|
|
||||||
#define K_PGUP 150
|
|
||||||
#define K_HOME 151
|
|
||||||
#define K_END 152
|
|
||||||
#define K_PAUSE 255
|
|
||||||
|
|
||||||
typedef float matrix_3x4[3][4];
|
typedef float matrix_3x4[3][4];
|
||||||
typedef matrix_3x4 bone_matrix[128];
|
typedef matrix_3x4 bone_matrix[128];
|
||||||
|
|
||||||
@@ -94,7 +62,7 @@ typedef struct cl_clientfuncs_s {
|
|||||||
void (*CL_CameraOffset)(float* ofs);
|
void (*CL_CameraOffset)(float* ofs);
|
||||||
struct kbutton_s* (*KB_Find)(const char* name);
|
struct kbutton_s* (*KB_Find)(const char* name);
|
||||||
void (*CAM_Think)(void);
|
void (*CAM_Think)(void);
|
||||||
void (*CalcRefdef)(struct ref_params_s* pparams);
|
void (*V_CalcRefdef)(struct ref_params_s* pparams);
|
||||||
int (*HUD_AddEntity)(int type, struct cl_entity_s* ent,
|
int (*HUD_AddEntity)(int type, struct cl_entity_s* ent,
|
||||||
const char* modelname);
|
const char* modelname);
|
||||||
|
|
||||||
|
|||||||
@@ -1,157 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
ESP_OFF = 0,
|
|
||||||
ESP_BOX = 1,
|
|
||||||
ESP_NAME = 2,
|
|
||||||
ESP_ALL = 3
|
|
||||||
} esp_mode_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
esp_mode_t esp_mode;
|
|
||||||
bool esp_friendly;
|
|
||||||
float fov;
|
|
||||||
bool chams;
|
|
||||||
bool tracers;
|
|
||||||
bool custom_crosshair;
|
|
||||||
bool watermark;
|
|
||||||
bool watermark_rainbow;
|
|
||||||
|
|
||||||
bool aimbot_enabled;
|
|
||||||
float aimbot_fov;
|
|
||||||
float aimbot_smooth;
|
|
||||||
bool aimbot_smoothing_enabled;
|
|
||||||
bool aimbot_silent;
|
|
||||||
bool aimbot_autoshoot;
|
|
||||||
bool aimbot_require_key;
|
|
||||||
bool aimbot_norecoil;
|
|
||||||
bool aimbot_recoil_comp;
|
|
||||||
bool aimbot_friendly_fire;
|
|
||||||
bool aimbot_team_attack;
|
|
||||||
int aimbot_hitbox;
|
|
||||||
|
|
||||||
bool bhop;
|
|
||||||
bool autostrafe;
|
|
||||||
bool antiaim;
|
|
||||||
bool antiaim_view;
|
|
||||||
bool fakeduck;
|
|
||||||
bool clmove;
|
|
||||||
|
|
||||||
int aa_pitch_mode;
|
|
||||||
int aa_yaw_mode;
|
|
||||||
float aa_custom_pitch;
|
|
||||||
float aa_custom_yaw;
|
|
||||||
float aa_spin_speed;
|
|
||||||
float aa_jitter_range;
|
|
||||||
bool aa_lby_breaker;
|
|
||||||
bool aa_desync;
|
|
||||||
bool aa_on_attack;
|
|
||||||
bool aa_first_person;
|
|
||||||
bool fake_duck;
|
|
||||||
|
|
||||||
bool antiaim_enabled;
|
|
||||||
bool antiaim_pitch_enabled;
|
|
||||||
bool antiaim_yaw_enabled;
|
|
||||||
float antiaim_pitch;
|
|
||||||
float antiaim_yaw;
|
|
||||||
bool antiaim_fakeduck;
|
|
||||||
int antiaim_fakeduck_key;
|
|
||||||
bool antiaim_desync;
|
|
||||||
bool antiaim_legit;
|
|
||||||
|
|
||||||
int antiaim_pitch_mode;
|
|
||||||
int antiaim_yaw_mode;
|
|
||||||
float antiaim_custom_pitch;
|
|
||||||
float antiaim_custom_yaw;
|
|
||||||
float antiaim_spin_speed;
|
|
||||||
float antiaim_jitter_range;
|
|
||||||
bool antiaim_lby_breaker;
|
|
||||||
bool antiaim_on_attack;
|
|
||||||
|
|
||||||
bool namechanger;
|
|
||||||
float namechanger_speed;
|
|
||||||
bool menu_allow_movement;
|
|
||||||
|
|
||||||
bool thirdperson;
|
|
||||||
int thirdperson_key;
|
|
||||||
float thirdperson_dist;
|
|
||||||
|
|
||||||
bool blinker;
|
|
||||||
} cheat_settings_t;
|
|
||||||
|
|
||||||
extern cheat_settings_t g_settings;
|
|
||||||
|
|
||||||
void settings_init(void);
|
|
||||||
void settings_reset(void);
|
|
||||||
bool settings_save_to_file(const char* filename);
|
|
||||||
bool settings_load_from_file(const char* filename);
|
|
||||||
bool settings_set_as_default(void);
|
|
||||||
bool settings_create_root_default(void);
|
|
||||||
const char* get_config_dir(void);
|
|
||||||
|
|
||||||
inline void init_default_settings(void) {
|
|
||||||
memset(&g_settings, 0, sizeof(g_settings));
|
|
||||||
|
|
||||||
g_settings.aimbot_fov = 5.0f;
|
|
||||||
g_settings.aimbot_smooth = 10.0f;
|
|
||||||
g_settings.aimbot_smoothing_enabled = true;
|
|
||||||
g_settings.aimbot_hitbox = 0;
|
|
||||||
|
|
||||||
g_settings.esp_mode = ESP_OFF;
|
|
||||||
g_settings.fov = 90.0f;
|
|
||||||
|
|
||||||
g_settings.namechanger_speed = 5.0f;
|
|
||||||
|
|
||||||
g_settings.thirdperson = false;
|
|
||||||
g_settings.thirdperson_dist = 300.0f;
|
|
||||||
g_settings.thirdperson_key = 'C';
|
|
||||||
|
|
||||||
// Initialize anti-aim defaults
|
|
||||||
g_settings.aa_pitch_mode = 0; // None
|
|
||||||
g_settings.aa_yaw_mode = 0; // None
|
|
||||||
g_settings.aa_custom_pitch = 0.0f;
|
|
||||||
g_settings.aa_custom_yaw = 0.0f;
|
|
||||||
g_settings.aa_spin_speed = 360.0f; // One rotation per second
|
|
||||||
g_settings.aa_jitter_range = 45.0f; // ±45 degrees jitter
|
|
||||||
g_settings.aa_lby_breaker = false;
|
|
||||||
g_settings.aa_desync = false;
|
|
||||||
g_settings.aa_on_attack = false;
|
|
||||||
g_settings.aa_first_person = false;
|
|
||||||
g_settings.fake_duck = false;
|
|
||||||
|
|
||||||
// Initialize new anti-aim settings
|
|
||||||
g_settings.antiaim_enabled = false;
|
|
||||||
g_settings.antiaim_pitch_enabled = false;
|
|
||||||
g_settings.antiaim_yaw_enabled = false;
|
|
||||||
g_settings.antiaim_pitch = 89.0f; // Default to look down
|
|
||||||
g_settings.antiaim_yaw = 180.0f; // Default to backward
|
|
||||||
g_settings.antiaim_fakeduck = false;
|
|
||||||
g_settings.antiaim_fakeduck_key = 0; // No key binding
|
|
||||||
g_settings.antiaim_desync = false;
|
|
||||||
g_settings.antiaim_legit = false;
|
|
||||||
g_settings.antiaim_view = false; // Don't show anti-aim in first person by default
|
|
||||||
|
|
||||||
// Initialize advanced anti-aim settings
|
|
||||||
g_settings.antiaim_pitch_mode = 1; // Down (89°)
|
|
||||||
g_settings.antiaim_yaw_mode = 1; // Backward (180°)
|
|
||||||
g_settings.antiaim_custom_pitch = 0.0f;
|
|
||||||
g_settings.antiaim_custom_yaw = 0.0f;
|
|
||||||
g_settings.antiaim_spin_speed = 360.0f; // One rotation per second
|
|
||||||
g_settings.antiaim_jitter_range = 45.0f; // ±45 degrees jitter
|
|
||||||
g_settings.antiaim_lby_breaker = false;
|
|
||||||
g_settings.antiaim_on_attack = false;
|
|
||||||
|
|
||||||
g_settings.menu_allow_movement = true;
|
|
||||||
g_settings.blinker = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -14,28 +14,18 @@ typedef struct {
|
|||||||
uint8_t r, g, b;
|
uint8_t r, g, b;
|
||||||
} rgb_t;
|
} rgb_t;
|
||||||
|
|
||||||
#define ERR(...) \
|
|
||||||
do { \
|
|
||||||
fprintf(stderr, "hl-cheat: %s: ", __func__); \
|
|
||||||
fprintf(stderr, __VA_ARGS__); \
|
|
||||||
fputc('\n', stderr); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DEG2RAD(n) ((n)*M_PI / 180.0f)
|
#define DEG2RAD(n) ((n)*M_PI / 180.0f)
|
||||||
#define RAD2DEG(n) ((n)*180.0f / M_PI)
|
#define RAD2DEG(n) ((n)*180.0f / M_PI)
|
||||||
|
#define CLAMP(val, min, max) \
|
||||||
#define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
|
(((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val)))
|
||||||
|
|
||||||
#define gl_drawline_points(p0, p1, w, col) \
|
#define gl_drawline_points(p0, p1, w, col) \
|
||||||
gl_drawline(p0[0], p0[1], p1[0], p1[1], w, col);
|
gl_drawline(p0[0], p0[1], p1[0], p1[1], w, col);
|
||||||
|
|
||||||
/* Use indexes so it works for float[] as well as vec3_t */
|
|
||||||
#define vec_copy(dst, src) \
|
#define vec_copy(dst, src) \
|
||||||
do { \
|
dst.x = src.x; \
|
||||||
dst[0] = src[0]; \
|
dst.y = src.y; \
|
||||||
dst[1] = src[1]; \
|
dst.z = src.z;
|
||||||
dst[2] = src[2]; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -43,7 +33,6 @@ cl_entity_t* get_player(int ent_idx);
|
|||||||
bool is_alive(cl_entity_t* ent);
|
bool is_alive(cl_entity_t* ent);
|
||||||
bool valid_player(cl_entity_t* ent);
|
bool valid_player(cl_entity_t* ent);
|
||||||
bool is_friend(cl_entity_t* ent);
|
bool is_friend(cl_entity_t* ent);
|
||||||
bool can_shoot(void);
|
|
||||||
char* get_name(int ent_idx);
|
char* get_name(int ent_idx);
|
||||||
game_id get_cur_game(void);
|
game_id get_cur_game(void);
|
||||||
vec3_t vec3(float x, float y, float z);
|
vec3_t vec3(float x, float y, float z);
|
||||||
@@ -51,16 +40,15 @@ vec3_t vec_add(vec3_t a, vec3_t b);
|
|||||||
vec3_t vec_sub(vec3_t a, vec3_t b);
|
vec3_t vec_sub(vec3_t a, vec3_t b);
|
||||||
bool vec_is_zero(vec3_t v);
|
bool vec_is_zero(vec3_t v);
|
||||||
float vec_len2d(vec3_t v);
|
float vec_len2d(vec3_t v);
|
||||||
void ang_clamp(vec3_t* v);
|
void vec_clamp(vec3_t v);
|
||||||
void vec_norm(vec3_t* v);
|
void vec_norm(vec3_t v);
|
||||||
float angle_delta_rad(float a, float b);
|
float angle_delta_rad(float a, float b);
|
||||||
vec3_t vec_to_ang(vec3_t v);
|
vec3_t vec_to_ang(vec3_t v);
|
||||||
vec3_t matrix_3x4_origin(matrix_3x4 m);
|
vec3_t matrix_3x4_origin(matrix_3x4 m);
|
||||||
bool world_to_screen(vec3_t vec, vec2_t screen);
|
bool world_to_screen(vec3_t vec, vec2_t screen);
|
||||||
void engine_draw_text(int x, int y, char* s, rgb_t c);
|
void engine_draw_text(int x, int y, char* s, rgb_t c);
|
||||||
void draw_tracer(vec3_t start, vec3_t end, rgb_t c, float a, float w, float t);
|
|
||||||
void gl_drawbox(int x, int y, int w, int h, rgb_t c);
|
void gl_drawbox(int x, int y, int w, int h, rgb_t c);
|
||||||
void gl_drawline(int x0, int y0, int x1, int y1, float w, rgb_t col);
|
void gl_drawline(int x0, int y0, int x1, int y1, float w, rgb_t col);
|
||||||
bool protect_addr(void* ptr, int new_flags);
|
bool protect_addr(void* ptr, int new_flags);
|
||||||
|
|
||||||
#endif /* UTIL_H_ */
|
#endif /* UTIL_H_ */
|
||||||
|
|||||||
198
src/main.c
198
src/main.c
@@ -1,205 +1,73 @@
|
|||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "include/main.h"
|
#include "include/main.h"
|
||||||
#include "include/sdk.h"
|
#include "include/sdk.h"
|
||||||
#include "include/globals.h"
|
#include "include/globals.h"
|
||||||
#include "include/settings.h"
|
#include "include/cvars.h"
|
||||||
#include "include/hooks.h"
|
#include "include/hooks.h"
|
||||||
#include "include/util.h"
|
#include "include/util.h"
|
||||||
#include "include/game_detection.h"
|
|
||||||
|
|
||||||
static bool loaded = false;
|
static bool loaded = false;
|
||||||
|
|
||||||
void debug_log(const char* message) {
|
__attribute__((constructor)) /* Entry point when injected */
|
||||||
FILE* logfile = fopen("/tmp/cheat-unload-debug.log", "a");
|
|
||||||
if (logfile) {
|
|
||||||
time_t now = time(NULL);
|
|
||||||
char timestamp[64];
|
|
||||||
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", localtime(&now));
|
|
||||||
fprintf(logfile, "[%s] %s\n", timestamp, message);
|
|
||||||
fclose(logfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void safe_unload_with_debug(void) {
|
|
||||||
debug_log("Starting safe unload with debug logging");
|
|
||||||
|
|
||||||
char buf[256];
|
|
||||||
snprintf(buf, sizeof(buf), "Function addresses - self_unload: %p, unload: %p, hooks_restore: %p",
|
|
||||||
(void*)self_unload, (void*)unload, (void*)hooks_restore);
|
|
||||||
debug_log(buf);
|
|
||||||
|
|
||||||
debug_log("Resetting all settings to default values");
|
|
||||||
i_engine->pfnClientCmd("echo \"Step 0: Resetting all settings...\"");
|
|
||||||
settings_reset();
|
|
||||||
|
|
||||||
i_engine->pfnClientCmd("echo \"Step 1: Unhooking functions...\"");
|
|
||||||
debug_log("Unhooking all functions");
|
|
||||||
|
|
||||||
debug_log("Restoring OpenGL hooks");
|
|
||||||
|
|
||||||
debug_log("Restoring VMT hooks");
|
|
||||||
hooks_restore();
|
|
||||||
|
|
||||||
debug_log("Restoring globals");
|
|
||||||
globals_restore();
|
|
||||||
|
|
||||||
debug_log("Removing custom commands");
|
|
||||||
i_engine->pfnClientCmd("echo \"Step 2: Removing custom commands...\"");
|
|
||||||
|
|
||||||
debug_log("Waiting for hooks to settle");
|
|
||||||
i_engine->pfnClientCmd("echo \"Step 3: Waiting for hooks to settle...\"");
|
|
||||||
usleep(250000);
|
|
||||||
|
|
||||||
debug_log("Beginning library unload sequence");
|
|
||||||
i_engine->pfnClientCmd("echo \"Step 4: Unloading library...\"");
|
|
||||||
|
|
||||||
void* self = dlopen("libhlcheat.so", RTLD_LAZY | RTLD_NOLOAD);
|
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "dlopen result: %p", self);
|
|
||||||
debug_log(buf);
|
|
||||||
|
|
||||||
if (self) {
|
|
||||||
/* Close the call we just made to dlopen() */
|
|
||||||
debug_log("Closing first dlopen reference");
|
|
||||||
int result = dlclose(self);
|
|
||||||
snprintf(buf, sizeof(buf), "First dlclose result: %d", result);
|
|
||||||
debug_log(buf);
|
|
||||||
|
|
||||||
/* Close the call our injector made */
|
|
||||||
debug_log("Closing second dlopen reference");
|
|
||||||
result = dlclose(self);
|
|
||||||
snprintf(buf, sizeof(buf), "Second dlclose result: %d", result);
|
|
||||||
debug_log(buf);
|
|
||||||
} else {
|
|
||||||
debug_log("ERROR: Failed to get handle to library");
|
|
||||||
const char* error = dlerror();
|
|
||||||
if (error) {
|
|
||||||
debug_log(error);
|
|
||||||
i_engine->pfnClientCmd("echo \"ERROR: Failed to get handle to library\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_log("Safe unload completed");
|
|
||||||
i_engine->pfnClientCmd("echo \"Unload procedure completed\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
void UNINJECT_CommandHandler(void) {
|
|
||||||
i_engine->pfnClientCmd("echo \"Uninjecting goldsource-cheat with debug logging...\"");
|
|
||||||
|
|
||||||
safe_unload_with_debug();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MENU_CommandHandler(void) {
|
|
||||||
extern bool g_menu_open;
|
|
||||||
g_menu_open = !g_menu_open;
|
|
||||||
i_engine->Con_Printf("Menu toggled to %s\n", g_menu_open ? "open" : "closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((constructor))
|
|
||||||
void load(void) {
|
void load(void) {
|
||||||
printf("goldsource-cheat injected!\n");
|
printf("hl-cheat injected!\n");
|
||||||
|
|
||||||
|
/* Initialize globals/interfaces */
|
||||||
if (!globals_init()) {
|
if (!globals_init()) {
|
||||||
fprintf(stderr, "goldsource-cheat: load: error loading globals, aborting\n");
|
fprintf(stderr, "hl-cheat: load: error loading globals, aborting\n");
|
||||||
self_unload();
|
self_unload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings_init();
|
/* Create cvars for settings */
|
||||||
|
if (!cvars_init()) {
|
||||||
|
fprintf(stderr, "hl-cheat: load: error creating cvars, aborting\n");
|
||||||
|
self_unload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hook functions */
|
||||||
if (!hooks_init()) {
|
if (!hooks_init()) {
|
||||||
fprintf(stderr, "goldsource-cheat: load: error hooking functions, aborting\n");
|
fprintf(stderr, "hl-cheat: load: error hooking functions, aborting\n");
|
||||||
self_unload();
|
self_unload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
i_engine->pfnAddCommand("dz_uninject", UNINJECT_CommandHandler);
|
/* Get game version after injecting */
|
||||||
i_engine->pfnAddCommand("dz_menu", MENU_CommandHandler);
|
this_game_id = get_cur_game();
|
||||||
|
|
||||||
i_engine->pfnClientCmd("bind INS dz_menu");
|
|
||||||
i_engine->Con_Printf("Bound INSERT key to menu toggle\n");
|
|
||||||
|
|
||||||
if (IsCS16()) {
|
i_engine->pfnClientCmd("echo \"hl-cheat loaded successfully!\"");
|
||||||
i_engine->pfnClientCmd("play weapons/knife_deploy1.wav");
|
|
||||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
|
||||||
}
|
|
||||||
else if (IsDayOfDefeat()) {
|
|
||||||
i_engine->pfnClientCmd("play weapons/kar_cock.wav");
|
|
||||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
|
||||||
}
|
|
||||||
else if (IsTFC()) {
|
|
||||||
i_engine->pfnClientCmd("play misc/party2.wav");
|
|
||||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
|
||||||
}
|
|
||||||
else if (IsDeathmatchClassic()) {
|
|
||||||
i_engine->pfnClientCmd("play items/r_item1.wav");
|
|
||||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i_engine->pfnClientCmd("play weapons/cbar_hit1.wav");
|
|
||||||
i_engine->pfnClientCmd("speak \"Cheat successfully loaded\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
i_engine->pfnClientCmd("echo \"goldsource-cheat loaded successfully!\"");
|
|
||||||
i_engine->pfnClientCmd("echo \"Deadzone rulez!\"");
|
|
||||||
i_engine->pfnClientCmd("echo \"https://git.deadzone.lol/Wizzard/goldsrc-cheat\"");
|
|
||||||
|
|
||||||
GameType game = get_current_game();
|
|
||||||
switch(game) {
|
|
||||||
case GAME_HALFLIFE:
|
|
||||||
i_engine->pfnClientCmd("echo \"Detected Game: Half-Life 1\"");
|
|
||||||
break;
|
|
||||||
case GAME_CS16:
|
|
||||||
i_engine->pfnClientCmd("echo \"Detected Game: Counter-Strike 1.6\"");
|
|
||||||
break;
|
|
||||||
case GAME_DAY_OF_DEFEAT:
|
|
||||||
i_engine->pfnClientCmd("echo \"Detected Game: Day of Defeat\"");
|
|
||||||
break;
|
|
||||||
case GAME_TFC:
|
|
||||||
i_engine->pfnClientCmd("echo \"Detected Game: Team Fortress Classic\"");
|
|
||||||
break;
|
|
||||||
case GAME_DMC:
|
|
||||||
i_engine->pfnClientCmd("echo \"Detected Game: Deathmatch Classic\"");
|
|
||||||
break;
|
|
||||||
case GAME_SL:
|
|
||||||
i_engine->pfnClientCmd("echo \"Detected Game: Space Life: Finley's Revenge\"");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
i_engine->pfnClientCmd("echo \"Detected Game: Unknown Game\"");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
loaded = true;
|
loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((destructor))
|
__attribute__((destructor)) /* Entry point when unloaded */
|
||||||
void unload(void) {
|
void unload() {
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
settings_reset();
|
/* TODO: Remove our cvars */
|
||||||
|
|
||||||
globals_restore();
|
globals_restore();
|
||||||
hooks_restore();
|
hooks_restore();
|
||||||
|
|
||||||
|
GL_UNHOOK(glColor4f); /* Manually restore OpenGL hooks here */
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("goldsource-cheat unloaded.\n\n");
|
printf("hl-cheat unloaded.\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void self_unload(void) {
|
void self_unload(void) {
|
||||||
|
/*
|
||||||
|
* RTLD_LAZY: If the symbol is never referenced, then it is never resolved.
|
||||||
|
* RTLD_NOLOAD: Don't load the shared object.
|
||||||
|
*/
|
||||||
void* self = dlopen("libhlcheat.so", RTLD_LAZY | RTLD_NOLOAD);
|
void* self = dlopen("libhlcheat.so", RTLD_LAZY | RTLD_NOLOAD);
|
||||||
|
|
||||||
if (self) {
|
/* Close the call we just made to dlopen() */
|
||||||
dlclose(self);
|
dlclose(self);
|
||||||
dlclose(self);
|
|
||||||
}
|
/* Close the call our injector made */
|
||||||
|
dlclose(self);
|
||||||
}
|
}
|
||||||
|
|||||||
968
src/menu.c
968
src/menu.c
@@ -1,968 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#define IMGUI_IMPLEMENTATION
|
|
||||||
#include "include/menu.h"
|
|
||||||
#include "include/sdk.h"
|
|
||||||
#include "include/globals.h"
|
|
||||||
#include "include/settings.h"
|
|
||||||
#include "include/hooks.h"
|
|
||||||
#include "include/util.h"
|
|
||||||
#include <GL/gl.h>
|
|
||||||
|
|
||||||
#include "include/sdk/public/keydefs.h"
|
|
||||||
|
|
||||||
extern const char* hitbox_names[];
|
|
||||||
extern int current_hitbox;
|
|
||||||
|
|
||||||
bool g_menu_open = false;
|
|
||||||
|
|
||||||
ImGuiContext* g_imgui_context = NULL;
|
|
||||||
bool g_imgui_initialized = false;
|
|
||||||
|
|
||||||
bool g_waiting_for_key_bind = false;
|
|
||||||
const char* g_current_key_binding_action = NULL;
|
|
||||||
|
|
||||||
static bool s_need_refresh_configs = true;
|
|
||||||
static char s_config_files[32][64] = {0};
|
|
||||||
static int s_config_file_count = 0;
|
|
||||||
|
|
||||||
static void render_fallback_menu(void);
|
|
||||||
|
|
||||||
static bool check_gl_state(void) {
|
|
||||||
GLenum error = glGetError();
|
|
||||||
if (error != GL_NO_ERROR) {
|
|
||||||
const char* err_str = "Unknown";
|
|
||||||
switch (error) {
|
|
||||||
case GL_INVALID_ENUM: err_str = "GL_INVALID_ENUM"; break;
|
|
||||||
case GL_INVALID_VALUE: err_str = "GL_INVALID_VALUE"; break;
|
|
||||||
case GL_INVALID_OPERATION: err_str = "GL_INVALID_OPERATION"; break;
|
|
||||||
case GL_STACK_OVERFLOW: err_str = "GL_STACK_OVERFLOW"; break;
|
|
||||||
case GL_STACK_UNDERFLOW: err_str = "GL_STACK_UNDERFLOW"; break;
|
|
||||||
case GL_OUT_OF_MEMORY: err_str = "GL_OUT_OF_MEMORY"; break;
|
|
||||||
}
|
|
||||||
printf("OpenGL error: %s (0x%x)\n", err_str, error);
|
|
||||||
i_engine->Con_Printf("OpenGL error: %s (0x%x)\n", err_str, error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" bool menu_init(void) {
|
|
||||||
printf("Initializing ImGui menu...\n");
|
|
||||||
i_engine->Con_Printf("Initializing ImGui menu...\n");
|
|
||||||
|
|
||||||
if (g_imgui_context) {
|
|
||||||
printf("ImGui context already exists, shutting down first\n");
|
|
||||||
menu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check_gl_state()) {
|
|
||||||
printf("OpenGL not ready for ImGui initialization\n");
|
|
||||||
i_engine->Con_Printf("Warning: OpenGL state not clean, continuing anyway\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
g_imgui_context = ImGui::CreateContext();
|
|
||||||
if (!g_imgui_context) {
|
|
||||||
printf("Failed to create ImGui context\n");
|
|
||||||
i_engine->Con_Printf("Error: Failed to create ImGui context\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("ImGui context created successfully\n");
|
|
||||||
i_engine->Con_Printf("ImGui context created successfully\n");
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
|
||||||
|
|
||||||
io.MouseDrawCursor = false;
|
|
||||||
|
|
||||||
SCREENINFO scr_inf;
|
|
||||||
scr_inf.iSize = sizeof(SCREENINFO);
|
|
||||||
i_engine->pfnGetScreenInfo(&scr_inf);
|
|
||||||
|
|
||||||
if (scr_inf.iWidth <= 0 || scr_inf.iHeight <= 0) {
|
|
||||||
scr_inf.iWidth = 800;
|
|
||||||
scr_inf.iHeight = 600;
|
|
||||||
i_engine->Con_Printf("Using default screen dimensions: %dx%d\n",
|
|
||||||
scr_inf.iWidth, scr_inf.iHeight);
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Screen dimensions: %dx%d\n",
|
|
||||||
scr_inf.iWidth, scr_inf.iHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
io.DisplaySize = ImVec2((float)scr_inf.iWidth, (float)scr_inf.iHeight);
|
|
||||||
|
|
||||||
bool init_result = ImGui_ImplOpenGL2_Init();
|
|
||||||
if (!init_result) {
|
|
||||||
printf("Failed to initialize ImGui OpenGL2 backend\n");
|
|
||||||
i_engine->Con_Printf("Error: Failed to initialize ImGui OpenGL2 backend\n");
|
|
||||||
ImGui::DestroyContext(g_imgui_context);
|
|
||||||
g_imgui_context = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("ImGui OpenGL2 backend initialized successfully\n");
|
|
||||||
i_engine->Con_Printf("ImGui OpenGL2 backend initialized successfully\n");
|
|
||||||
|
|
||||||
ImGui::StyleColorsDark();
|
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
|
||||||
style.WindowRounding = 5.0f;
|
|
||||||
style.FrameRounding = 3.0f;
|
|
||||||
style.ItemSpacing = ImVec2(8, 4);
|
|
||||||
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.1f, 0.1f, 0.1f, 0.9f);
|
|
||||||
style.Colors[ImGuiCol_TitleBg] = ImVec4(0.15f, 0.15f, 0.15f, 1.0f);
|
|
||||||
style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.15f, 0.15f, 0.15f, 1.0f);
|
|
||||||
style.Colors[ImGuiCol_Button] = ImVec4(0.2f, 0.2f, 0.2f, 1.0f);
|
|
||||||
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.3f, 0.3f, 0.3f, 1.0f);
|
|
||||||
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.4f, 0.4f, 0.4f, 1.0f);
|
|
||||||
|
|
||||||
g_menu_open = false;
|
|
||||||
g_imgui_initialized = true;
|
|
||||||
|
|
||||||
i_client->IN_ActivateMouse();
|
|
||||||
|
|
||||||
i_engine->Con_Printf("ImGui menu initialized successfully\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void menu_shutdown(void) {
|
|
||||||
if (g_imgui_initialized) {
|
|
||||||
i_engine->Con_Printf("Shutting down ImGui...\n");
|
|
||||||
|
|
||||||
if (g_imgui_context) {
|
|
||||||
ImGui_ImplOpenGL2_Shutdown();
|
|
||||||
ImGui::DestroyContext(g_imgui_context);
|
|
||||||
g_imgui_context = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_imgui_initialized = false;
|
|
||||||
i_engine->Con_Printf("ImGui shutdown complete\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
g_menu_open = false;
|
|
||||||
|
|
||||||
i_client->IN_ActivateMouse();
|
|
||||||
|
|
||||||
i_engine->pfnClientCmd("bind mouse1 +attack; bind mouse2 +attack2");
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void menu_render(void) {
|
|
||||||
if (!g_menu_open)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (g_imgui_initialized && g_imgui_context) {
|
|
||||||
ImGui::SetCurrentContext(g_imgui_context);
|
|
||||||
|
|
||||||
SCREENINFO scr_inf;
|
|
||||||
scr_inf.iSize = sizeof(SCREENINFO);
|
|
||||||
i_engine->pfnGetScreenInfo(&scr_inf);
|
|
||||||
|
|
||||||
if (scr_inf.iWidth <= 0 || scr_inf.iHeight <= 0) {
|
|
||||||
i_engine->Con_Printf("Warning: Invalid screen dimensions, using defaults\n");
|
|
||||||
scr_inf.iWidth = 800;
|
|
||||||
scr_inf.iHeight = 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.DisplaySize = ImVec2((float)scr_inf.iWidth, (float)scr_inf.iHeight);
|
|
||||||
io.DeltaTime = 1.0f / 60.0f;
|
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_NewFrame();
|
|
||||||
ImGui::NewFrame();
|
|
||||||
|
|
||||||
ImGui::SetNextWindowPos(ImVec2(scr_inf.iWidth * 0.5f, scr_inf.iHeight * 0.5f),
|
|
||||||
ImGuiCond_Once, ImVec2(0.5f, 0.5f));
|
|
||||||
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Once);
|
|
||||||
|
|
||||||
if (ImGui::Begin("GoldSource Cheat", &g_menu_open,
|
|
||||||
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize)) {
|
|
||||||
|
|
||||||
if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None)) {
|
|
||||||
|
|
||||||
if (ImGui::BeginTabItem("Aimbot")) {
|
|
||||||
// Main aimbot settings section
|
|
||||||
ImGui::Text("Aimbot Settings");
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
if (ImGui::Checkbox("Enable Aimbot", &g_settings.aimbot_enabled)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.aimbot_enabled) {
|
|
||||||
// Target selection section
|
|
||||||
ImGui::Text("Target Selection:");
|
|
||||||
|
|
||||||
if (ImGui::SliderFloat("FOV", &g_settings.aimbot_fov, 0.1f, 180.0f, "%.1f")) {
|
|
||||||
// Ensure value stays within limits
|
|
||||||
g_settings.aimbot_fov = CLAMP(g_settings.aimbot_fov, 0.1f, 180.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Field of view for target selection.\nSmaller values = more precise targeting");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* hitbox_items[] = { "Head", "Chest", "Stomach", "Pelvis", "Nearest" };
|
|
||||||
if (ImGui::Combo("Hitbox", &g_settings.aimbot_hitbox, hitbox_items, 5)) {
|
|
||||||
current_hitbox = g_settings.aimbot_hitbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Shoot Teammates", &g_settings.aimbot_team_attack);
|
|
||||||
|
|
||||||
// Aiming behavior section
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Aiming Behavior:");
|
|
||||||
|
|
||||||
ImGui::Checkbox("Enable Smoothing", &g_settings.aimbot_smoothing_enabled);
|
|
||||||
|
|
||||||
if (g_settings.aimbot_smoothing_enabled) {
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Makes aim movement look more natural");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::SliderFloat("Smoothing", &g_settings.aimbot_smooth, 1.0f, 100.0f, "%.1f")) {
|
|
||||||
// Ensure value stays within limits
|
|
||||||
g_settings.aimbot_smooth = CLAMP(g_settings.aimbot_smooth, 1.0f, 100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Text("Lower = Faster | Higher = Smoother");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Silent Aim", &g_settings.aimbot_silent);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Aim is only visible server-side, not in your view");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recoil control section
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Recoil Control:");
|
|
||||||
|
|
||||||
ImGui::Checkbox("No Recoil", &g_settings.aimbot_norecoil);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Completely removes recoil effect");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Recoil Compensation", &g_settings.aimbot_recoil_comp);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Dynamic recoil correction for weapons like AK-47\nAdjusts aim based on spray pattern");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto shoot section
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Auto Functions:");
|
|
||||||
|
|
||||||
ImGui::Checkbox("Auto Shoot", &g_settings.aimbot_autoshoot);
|
|
||||||
|
|
||||||
if (g_settings.aimbot_autoshoot) {
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Auto Shoot automatically fires when aim is on target");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Indent(20);
|
|
||||||
ImGui::Checkbox("Require Fire Button", &g_settings.aimbot_require_key);
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("When enabled, auto-shoot will only fire if you're also pressing the fire button");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
ImGui::Unindent(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Weapon info section
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Current Weapon: %s (ID: %d)",
|
|
||||||
g_currentWeaponID == 7 ? "AK-47" :
|
|
||||||
g_currentWeaponID == 16 ? "M4A1" :
|
|
||||||
g_currentWeaponID == 1 ? "Desert Eagle" : "Unknown",
|
|
||||||
g_currentWeaponID);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginTabItem("Visuals")) {
|
|
||||||
const char* esp_modes[] = {"Off", "2D Box", "Name", "All"};
|
|
||||||
int esp_mode = (int)g_settings.esp_mode;
|
|
||||||
if (ImGui::Combo("ESP", &esp_mode, esp_modes, 4)) {
|
|
||||||
g_settings.esp_mode = (esp_mode_t)esp_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("ESP Friendly", &g_settings.esp_friendly);
|
|
||||||
|
|
||||||
if (ImGui::SliderFloat("FOV Changer", &g_settings.fov, 70.0f, 140.0f, "%.1f")) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Chams", &g_settings.chams);
|
|
||||||
|
|
||||||
ImGui::Checkbox("Custom Crosshair", &g_settings.custom_crosshair);
|
|
||||||
|
|
||||||
ImGui::Checkbox("Bullet Tracers", &g_settings.tracers);
|
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginTabItem("Movement")) {
|
|
||||||
ImGui::Checkbox("Bunny Hop", &g_settings.bhop);
|
|
||||||
|
|
||||||
ImGui::Checkbox("Auto Strafe", &g_settings.autostrafe);
|
|
||||||
|
|
||||||
ImGui::Checkbox("Anti-Aim", &g_settings.antiaim);
|
|
||||||
|
|
||||||
if (g_settings.antiaim) {
|
|
||||||
ImGui::Checkbox("Anti-Aim View", &g_settings.antiaim_view);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Fake Duck", &g_settings.fakeduck);
|
|
||||||
|
|
||||||
ImGui::Checkbox("CL_Move", &g_settings.clmove);
|
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginTabItem("Anti-Aim")) {
|
|
||||||
ImGui::Text("Anti-Aim Settings");
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
if (ImGui::Checkbox("Enable Anti-Aim", &g_settings.antiaim_enabled)) {
|
|
||||||
if (g_settings.antiaim_enabled) {
|
|
||||||
i_engine->Con_Printf("Anti-Aim enabled\n");
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Anti-Aim disabled\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Master switch for all anti-aim features");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.antiaim_enabled) {
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Pitch Control:");
|
|
||||||
|
|
||||||
if (ImGui::Checkbox("Enable Pitch Anti-Aim", &g_settings.antiaim_pitch_enabled)) {
|
|
||||||
if (g_settings.antiaim_pitch_enabled) {
|
|
||||||
i_engine->Con_Printf("Pitch Anti-Aim enabled\n");
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Pitch Anti-Aim disabled\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.antiaim_pitch_enabled) {
|
|
||||||
const char* pitch_items[] = {"Fixed", "Down (89°)", "Up (-89°)", "Zero (0°)", "Jitter", "Custom"};
|
|
||||||
if (ImGui::Combo("Pitch Mode", &g_settings.antiaim_pitch_mode, pitch_items, 6)) {
|
|
||||||
// Reset custom pitch if mode changed
|
|
||||||
if (g_settings.antiaim_pitch_mode != 5) { // Not custom
|
|
||||||
g_settings.antiaim_custom_pitch = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show settings based on mode
|
|
||||||
if (g_settings.antiaim_pitch_mode == 0) { // Fixed
|
|
||||||
ImGui::SliderFloat("Pitch Angle", &g_settings.antiaim_pitch, -89.0f, 89.0f, "%.1f°");
|
|
||||||
}
|
|
||||||
else if (g_settings.antiaim_pitch_mode == 5) { // Custom
|
|
||||||
ImGui::SliderFloat("Custom Pitch", &g_settings.antiaim_custom_pitch, -89.0f, 89.0f, "%.1f°");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Yaw Control:");
|
|
||||||
|
|
||||||
if (ImGui::Checkbox("Enable Yaw Anti-Aim", &g_settings.antiaim_yaw_enabled)) {
|
|
||||||
if (g_settings.antiaim_yaw_enabled) {
|
|
||||||
i_engine->Con_Printf("Yaw Anti-Aim enabled\n");
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Yaw Anti-Aim disabled\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.antiaim_yaw_enabled) {
|
|
||||||
const char* yaw_items[] = {"Fixed", "Backward (180°)", "Spin", "Jitter", "Sideways", "Custom"};
|
|
||||||
if (ImGui::Combo("Yaw Mode", &g_settings.antiaim_yaw_mode, yaw_items, 6)) {
|
|
||||||
// Reset custom yaw if mode changed
|
|
||||||
if (g_settings.antiaim_yaw_mode != 5) { // Not custom
|
|
||||||
g_settings.antiaim_custom_yaw = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show settings based on mode
|
|
||||||
if (g_settings.antiaim_yaw_mode == 0) { // Fixed
|
|
||||||
ImGui::SliderFloat("Yaw Angle", &g_settings.antiaim_yaw, -180.0f, 180.0f, "%.1f°");
|
|
||||||
}
|
|
||||||
else if (g_settings.antiaim_yaw_mode == 2) { // Spin
|
|
||||||
ImGui::SliderFloat("Spin Speed", &g_settings.antiaim_spin_speed, 10.0f, 1000.0f, "%.1f°/s");
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Controls how fast the spin rotates (degrees per second)");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (g_settings.antiaim_yaw_mode == 3) { // Jitter
|
|
||||||
ImGui::SliderFloat("Jitter Range", &g_settings.antiaim_jitter_range, 5.0f, 180.0f, "%.1f°");
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Controls the maximum angle of random jitter (±degrees)");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (g_settings.antiaim_yaw_mode == 5) { // Custom
|
|
||||||
ImGui::SliderFloat("Custom Yaw", &g_settings.antiaim_custom_yaw, -180.0f, 180.0f, "%.1f°");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Additional Options:");
|
|
||||||
|
|
||||||
ImGui::Checkbox("Anti-Aim When Shooting", &g_settings.antiaim_on_attack);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Continue anti-aim even when attacking (may affect accuracy)");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("LBY Breaker", &g_settings.antiaim_lby_breaker);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Breaks lower body yaw for more effective anti-aim");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Desync", &g_settings.antiaim_desync);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Creates a desync between client and server angles.\nMakes you harder to hit but may cause visual glitches.");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Legit Anti-Aim", &g_settings.antiaim_legit);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Less obvious anti-aim that's harder to detect visually.\nLess effective than rage anti-aim but less noticeable.");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Show in First Person", &g_settings.antiaim_view);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("When enabled, you'll see your anti-aim from first person.\nWhen disabled, only others see your anti-aim.");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Fake Duck", &g_settings.antiaim_fakeduck);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Rapidly switches between duck and stand positions.\nMakes you harder to hit while appearing ducked to others.");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.antiaim_fakeduck) {
|
|
||||||
const char* key_name = "None";
|
|
||||||
if (g_settings.antiaim_fakeduck_key > 0) {
|
|
||||||
// Convert key code to name
|
|
||||||
switch(g_settings.antiaim_fakeduck_key) {
|
|
||||||
case 'F': key_name = "F"; break;
|
|
||||||
case 'V': key_name = "V"; break;
|
|
||||||
case 'T': key_name = "T"; break;
|
|
||||||
case 'P': key_name = "P"; break;
|
|
||||||
case 'C': key_name = "C"; break;
|
|
||||||
case K_F1: key_name = "F1"; break;
|
|
||||||
case K_F2: key_name = "F2"; break;
|
|
||||||
case K_F3: key_name = "F3"; break;
|
|
||||||
case K_F4: key_name = "F4"; break;
|
|
||||||
case K_F5: key_name = "F5"; break;
|
|
||||||
case K_TAB: key_name = "Tab"; break;
|
|
||||||
case K_SPACE: key_name = "Space"; break;
|
|
||||||
case K_CTRL: key_name = "Ctrl"; break;
|
|
||||||
case K_SHIFT: key_name = "Shift"; break;
|
|
||||||
case K_ALT: key_name = "Alt"; break;
|
|
||||||
case K_MOUSE1: key_name = "Mouse1"; break;
|
|
||||||
case K_MOUSE2: key_name = "Mouse2"; break;
|
|
||||||
case K_MOUSE3: key_name = "Mouse3"; break;
|
|
||||||
default: {
|
|
||||||
if (g_settings.antiaim_fakeduck_key >= 32 && g_settings.antiaim_fakeduck_key <= 126) {
|
|
||||||
static char chr[2] = {0};
|
|
||||||
chr[0] = (char)g_settings.antiaim_fakeduck_key;
|
|
||||||
key_name = chr;
|
|
||||||
} else {
|
|
||||||
static char code[32] = {0};
|
|
||||||
snprintf(code, sizeof(code), "Key %d", g_settings.antiaim_fakeduck_key);
|
|
||||||
key_name = code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Text("Fake Duck Key: %s", key_name);
|
|
||||||
|
|
||||||
if (g_waiting_for_key_bind && g_current_key_binding_action && strcmp(g_current_key_binding_action, "fakeduck") == 0) {
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.1f, 0.1f, 1.0f));
|
|
||||||
ImGui::Button("Press any key...", ImVec2(150, 25));
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
} else {
|
|
||||||
if (ImGui::Button("Bind Fake Duck Key", ImVec2(150, 25))) {
|
|
||||||
g_waiting_for_key_bind = true;
|
|
||||||
g_current_key_binding_action = "fakeduck";
|
|
||||||
i_engine->Con_Printf("Press any key to bind for fake duck\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
if (ImGui::Button("Clear##FakeDuckKey", ImVec2(80, 25))) {
|
|
||||||
g_settings.antiaim_fakeduck_key = 0;
|
|
||||||
i_engine->Con_Printf("Fake duck key binding cleared\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginTabItem("Misc")) {
|
|
||||||
ImGui::Checkbox("Name Changer", &g_settings.namechanger);
|
|
||||||
|
|
||||||
if (g_settings.namechanger) {
|
|
||||||
ImGui::SliderFloat("Name Change Speed", &g_settings.namechanger_speed, 1.0f, 50.0f, "%.1f");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Checkbox("Watermark", &g_settings.watermark);
|
|
||||||
|
|
||||||
if (g_settings.watermark) {
|
|
||||||
ImGui::Checkbox("Rainbow Watermark", &g_settings.watermark_rainbow);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
ImGui::Text("Menu Settings:");
|
|
||||||
ImGui::Checkbox("Allow Movement (WASD) With Menu Open", &g_settings.menu_allow_movement);
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
if (ImGui::Button("Reset Settings", ImVec2(150, 30))) {
|
|
||||||
settings_reset();
|
|
||||||
i_engine->pfnClientCmd("echo \"All settings have been reset to defaults.\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.1f, 1.0f), "?");
|
|
||||||
if (ImGui::IsItemHovered()) {
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
ImGui::Text("Reset all settings to default values");
|
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
if (ImGui::Button("Uninject Cheat", ImVec2(150, 30))) {
|
|
||||||
i_engine->pfnClientCmd("dz_uninject");
|
|
||||||
g_menu_open = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginTabItem("View")) {
|
|
||||||
ImGui::Text("Camera Settings:");
|
|
||||||
|
|
||||||
bool thirdperson_changed = ImGui::Checkbox("Third-Person View", &g_settings.thirdperson);
|
|
||||||
|
|
||||||
if (g_settings.thirdperson) {
|
|
||||||
ImGui::BeginGroup();
|
|
||||||
if (ImGui::Button("100")) {
|
|
||||||
g_settings.thirdperson_dist = 100.0f;
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("270")) {
|
|
||||||
g_settings.thirdperson_dist = 270.0f;
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("500")) {
|
|
||||||
g_settings.thirdperson_dist = 500.0f;
|
|
||||||
}
|
|
||||||
ImGui::EndGroup();
|
|
||||||
|
|
||||||
ImGui::SliderFloat("Camera Distance", &g_settings.thirdperson_dist, 30.0f, 800.0f, "%.1f");
|
|
||||||
|
|
||||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Camera distance updates in real-time");
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Keybind for Third-Person Toggle:");
|
|
||||||
|
|
||||||
const char* key_name = "None";
|
|
||||||
if (g_settings.thirdperson_key > 0) {
|
|
||||||
switch(g_settings.thirdperson_key) {
|
|
||||||
case 'F': key_name = "F"; break;
|
|
||||||
case 'V': key_name = "V"; break;
|
|
||||||
case 'T': key_name = "T"; break;
|
|
||||||
case 'P': key_name = "P"; break;
|
|
||||||
case 'C': key_name = "C"; break;
|
|
||||||
case K_F1: key_name = "F1"; break;
|
|
||||||
case K_F2: key_name = "F2"; break;
|
|
||||||
case K_F3: key_name = "F3"; break;
|
|
||||||
case K_F4: key_name = "F4"; break;
|
|
||||||
case K_F5: key_name = "F5"; break;
|
|
||||||
case K_TAB: key_name = "Tab"; break;
|
|
||||||
case K_SPACE: key_name = "Space"; break;
|
|
||||||
case K_CTRL: key_name = "Ctrl"; break;
|
|
||||||
case K_SHIFT: key_name = "Shift"; break;
|
|
||||||
case K_ALT: key_name = "Alt"; break;
|
|
||||||
case K_MOUSE1: key_name = "Mouse1"; break;
|
|
||||||
case K_MOUSE2: key_name = "Mouse2"; break;
|
|
||||||
case K_MOUSE3: key_name = "Mouse3"; break;
|
|
||||||
default: {
|
|
||||||
if (g_settings.thirdperson_key >= 32 && g_settings.thirdperson_key <= 126) {
|
|
||||||
static char chr[2] = {0};
|
|
||||||
chr[0] = (char)g_settings.thirdperson_key;
|
|
||||||
key_name = chr;
|
|
||||||
} else {
|
|
||||||
static char code[32] = {0};
|
|
||||||
snprintf(code, sizeof(code), "Key %d", g_settings.thirdperson_key);
|
|
||||||
key_name = code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Text("Current Key: %s", key_name);
|
|
||||||
|
|
||||||
if (g_waiting_for_key_bind) {
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.1f, 0.1f, 1.0f));
|
|
||||||
ImGui::Button("Press any key...", ImVec2(150, 25));
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
} else {
|
|
||||||
if (ImGui::Button("Bind new key", ImVec2(150, 25))) {
|
|
||||||
g_waiting_for_key_bind = true;
|
|
||||||
g_current_key_binding_action = "thirdperson";
|
|
||||||
i_engine->Con_Printf("Press any key to bind for third-person toggle\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::Button("Clear", ImVec2(80, 25))) {
|
|
||||||
g_settings.thirdperson_key = 0;
|
|
||||||
i_engine->Con_Printf("Third-person key binding cleared\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Text("Note: Default binding is C key");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginTabItem("Config")) {
|
|
||||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Configuration System");
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
static char config_name[64] = "default";
|
|
||||||
ImGui::Text("Config Name:");
|
|
||||||
ImGui::PushItemWidth(200);
|
|
||||||
ImGui::InputText("##ConfigName", config_name, sizeof(config_name));
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
|
|
||||||
if (ImGui::Button("Save Config", ImVec2(120, 30))) {
|
|
||||||
if (settings_save_to_file(config_name)) {
|
|
||||||
ImGui::OpenPopup("ConfigSaved");
|
|
||||||
s_need_refresh_configs = true;
|
|
||||||
} else {
|
|
||||||
ImGui::OpenPopup("ConfigError");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
if (ImGui::Button("Load Config", ImVec2(120, 30))) {
|
|
||||||
if (settings_load_from_file(config_name)) {
|
|
||||||
ImGui::OpenPopup("ConfigLoaded");
|
|
||||||
} else {
|
|
||||||
ImGui::OpenPopup("ConfigError");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
if (ImGui::Button("Reset to Default", ImVec2(120, 30))) {
|
|
||||||
ImGui::OpenPopup("ConfirmReset");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
if (ImGui::Button("Set as Default", ImVec2(120, 30))) {
|
|
||||||
if (settings_set_as_default()) {
|
|
||||||
ImGui::OpenPopup("DefaultSaved");
|
|
||||||
} else {
|
|
||||||
ImGui::OpenPopup("ConfigError");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
if (ImGui::Button("Delete Config", ImVec2(120, 30))) {
|
|
||||||
ImGui::OpenPopup("ConfirmDelete");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
ImGui::Text("Available Configs:");
|
|
||||||
|
|
||||||
if (s_need_refresh_configs) {
|
|
||||||
memset(s_config_files, 0, sizeof(s_config_files));
|
|
||||||
s_config_file_count = 0;
|
|
||||||
|
|
||||||
const char* config_dir = get_config_dir();
|
|
||||||
if (config_dir) {
|
|
||||||
DIR* dir = opendir(config_dir);
|
|
||||||
if (dir) {
|
|
||||||
struct dirent* entry;
|
|
||||||
while ((entry = readdir(dir)) != NULL && s_config_file_count < 32) {
|
|
||||||
size_t len = strlen(entry->d_name);
|
|
||||||
if (len > 4 && strcmp(entry->d_name + len - 4, ".cfg") == 0) {
|
|
||||||
strncpy(s_config_files[s_config_file_count], entry->d_name, len - 4);
|
|
||||||
s_config_files[s_config_file_count][len - 4] = '\0';
|
|
||||||
s_config_file_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s_need_refresh_configs = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::Button("Refresh List", ImVec2(120, 25))) {
|
|
||||||
s_need_refresh_configs = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::BeginChild("ConfigList", ImVec2(0, 150), true);
|
|
||||||
for (int i = 0; i < s_config_file_count; i++) {
|
|
||||||
if (ImGui::Selectable(s_config_files[i], false)) {
|
|
||||||
strncpy(config_name, s_config_files[i], sizeof(config_name) - 1);
|
|
||||||
config_name[sizeof(config_name) - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndChild();
|
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndTabBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Render();
|
|
||||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
|
||||||
} else {
|
|
||||||
render_fallback_menu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void render_fallback_menu(void) {
|
|
||||||
SCREENINFO scr_inf;
|
|
||||||
scr_inf.iSize = sizeof(SCREENINFO);
|
|
||||||
i_engine->pfnGetScreenInfo(&scr_inf);
|
|
||||||
|
|
||||||
int x1 = scr_inf.iWidth / 4;
|
|
||||||
int y1 = scr_inf.iHeight / 4;
|
|
||||||
int x2 = scr_inf.iWidth * 3 / 4;
|
|
||||||
int y2 = scr_inf.iHeight * 3 / 4;
|
|
||||||
|
|
||||||
i_engine->pfnFillRGBA(x1, y1, x2-x1, y2-y1, 0, 0, 0, 230);
|
|
||||||
|
|
||||||
i_engine->pfnFillRGBA(x1, y1, x2-x1, 2, 255, 0, 0, 255);
|
|
||||||
i_engine->pfnFillRGBA(x1, y2-2, x2-x1, 2, 255, 0, 0, 255);
|
|
||||||
i_engine->pfnFillRGBA(x1, y1, 2, y2-y1, 255, 0, 0, 255);
|
|
||||||
i_engine->pfnFillRGBA(x2-2, y1, 2, y2-y1, 255, 0, 0, 255);
|
|
||||||
|
|
||||||
i_engine->pfnDrawSetTextColor(1.0f, 1.0f, 0.0f);
|
|
||||||
i_engine->pfnDrawConsoleString(x1+10, y1+10, "===== GoldSource Cheat Menu (Fallback) =====");
|
|
||||||
|
|
||||||
i_engine->pfnDrawSetTextColor(0.0f, 1.0f, 1.0f);
|
|
||||||
|
|
||||||
int y = y1 + 40;
|
|
||||||
i_engine->pfnDrawConsoleString(x1+20, y, "-- Aimbot Settings --");
|
|
||||||
y += 20;
|
|
||||||
|
|
||||||
char buffer[128];
|
|
||||||
|
|
||||||
bool aimbot_enabled = g_settings.aimbot_enabled;
|
|
||||||
snprintf(buffer, sizeof(buffer), "- Aimbot: %s", aimbot_enabled ? "ON" : "OFF");
|
|
||||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
|
||||||
y += 15;
|
|
||||||
|
|
||||||
if (aimbot_enabled) {
|
|
||||||
snprintf(buffer, sizeof(buffer), "- FOV: %.1f", g_settings.aimbot_fov);
|
|
||||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
|
||||||
y += 15;
|
|
||||||
|
|
||||||
if (g_settings.aimbot_smoothing_enabled) {
|
|
||||||
snprintf(buffer, sizeof(buffer), "- Smoothing: %.1f", g_settings.aimbot_smooth);
|
|
||||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
|
||||||
y += 15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
y += 10;
|
|
||||||
i_engine->pfnDrawSetTextColor(0.0f, 1.0f, 1.0f);
|
|
||||||
i_engine->pfnDrawConsoleString(x1+20, y, "-- Visual Settings --");
|
|
||||||
y += 20;
|
|
||||||
|
|
||||||
int esp_mode = (int)g_settings.esp_mode;
|
|
||||||
snprintf(buffer, sizeof(buffer), "- ESP: %s", esp_mode > 0 ? "ON" : "OFF");
|
|
||||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
|
||||||
y += 15;
|
|
||||||
|
|
||||||
bool chams_enabled = g_settings.chams;
|
|
||||||
snprintf(buffer, sizeof(buffer), "- Chams: %s", chams_enabled ? "ON" : "OFF");
|
|
||||||
i_engine->pfnDrawConsoleString(x1+30, y, buffer);
|
|
||||||
y += 30;
|
|
||||||
|
|
||||||
i_engine->pfnDrawSetTextColor(1.0f, 1.0f, 0.0f);
|
|
||||||
i_engine->pfnDrawConsoleString(x1+20, y, "Press INSERT to close menu");
|
|
||||||
y += 20;
|
|
||||||
i_engine->pfnDrawConsoleString(x1+20, y, "Use console to change settings");
|
|
||||||
|
|
||||||
i_engine->pfnDrawSetTextColor(0.7f, 0.7f, 0.7f);
|
|
||||||
i_engine->pfnDrawConsoleString(5, scr_inf.iHeight - 20, "Type 'dz_menu' in console to toggle menu");
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void menu_key_event(int keynum, int down) {
|
|
||||||
i_engine->Con_Printf("menu_key_event called: keynum=%d, down=%d, waiting_for_key=%d\n",
|
|
||||||
keynum, down, g_waiting_for_key_bind);
|
|
||||||
|
|
||||||
if (g_menu_open && g_imgui_initialized && g_imgui_context) {
|
|
||||||
ImGui::SetCurrentContext(g_imgui_context);
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
switch (keynum) {
|
|
||||||
case K_TAB: io.AddKeyEvent(ImGuiKey_Tab, down); break;
|
|
||||||
case K_LEFTARROW: io.AddKeyEvent(ImGuiKey_LeftArrow, down); break;
|
|
||||||
case K_RIGHTARROW: io.AddKeyEvent(ImGuiKey_RightArrow, down); break;
|
|
||||||
case K_UPARROW: io.AddKeyEvent(ImGuiKey_UpArrow, down); break;
|
|
||||||
case K_DOWNARROW: io.AddKeyEvent(ImGuiKey_DownArrow, down); break;
|
|
||||||
case K_BACKSPACE: io.AddKeyEvent(ImGuiKey_Backspace, down); break;
|
|
||||||
case K_DEL: io.AddKeyEvent(ImGuiKey_Delete, down); break;
|
|
||||||
case K_ENTER: io.AddKeyEvent(ImGuiKey_Enter, down); break;
|
|
||||||
case K_HOME: io.AddKeyEvent(ImGuiKey_Home, down); break;
|
|
||||||
case K_END: io.AddKeyEvent(ImGuiKey_End, down); break;
|
|
||||||
case K_ESCAPE: io.AddKeyEvent(ImGuiKey_Escape, down); break;
|
|
||||||
case K_CTRL: io.AddKeyEvent(ImGuiKey_LeftCtrl, down); break;
|
|
||||||
case K_SHIFT: io.AddKeyEvent(ImGuiKey_LeftShift, down); break;
|
|
||||||
case K_ALT: io.AddKeyEvent(ImGuiKey_LeftAlt, down); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_waiting_for_key_bind && down && keynum != K_ESCAPE) {
|
|
||||||
i_engine->Con_Printf("Processing key bind: keynum=%d, action=%s\n",
|
|
||||||
keynum, g_current_key_binding_action ? g_current_key_binding_action : "none");
|
|
||||||
|
|
||||||
if (keynum != K_MWHEELDOWN && keynum != K_MWHEELUP && keynum != K_INS) {
|
|
||||||
if (g_current_key_binding_action && strcmp(g_current_key_binding_action, "thirdperson") == 0) {
|
|
||||||
g_settings.thirdperson_key = keynum;
|
|
||||||
i_engine->Con_Printf("Third-person key bound to keycode: %d\n", keynum);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_waiting_for_key_bind = false;
|
|
||||||
g_current_key_binding_action = NULL;
|
|
||||||
i_engine->Con_Printf("Key binding completed!\n");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Ignored wheel/INS key: %d\n", keynum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_waiting_for_key_bind && down && keynum == K_ESCAPE) {
|
|
||||||
g_waiting_for_key_bind = false;
|
|
||||||
g_current_key_binding_action = NULL;
|
|
||||||
i_engine->Con_Printf("Key binding canceled\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keynum == K_INS && down) {
|
|
||||||
g_menu_open = !g_menu_open;
|
|
||||||
i_engine->Con_Printf("Menu %s\n", g_menu_open ? "opened" : "closed");
|
|
||||||
|
|
||||||
if (g_imgui_initialized && g_imgui_context) {
|
|
||||||
ImGui::SetCurrentContext(g_imgui_context);
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.MouseDrawCursor = g_menu_open;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_menu_open) {
|
|
||||||
i_client->IN_DeactivateMouse();
|
|
||||||
i_client->IN_ClearStates();
|
|
||||||
|
|
||||||
i_engine->pfnClientCmd("unbind mouse1; unbind mouse2");
|
|
||||||
i_engine->Con_Printf("Mouse deactivated for game, using ImGui cursor\n");
|
|
||||||
} else {
|
|
||||||
i_client->IN_ActivateMouse();
|
|
||||||
|
|
||||||
i_engine->pfnClientCmd("bind mouse1 +attack; bind mouse2 +attack2");
|
|
||||||
i_engine->Con_Printf("Mouse reactivated for game\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void menu_char_event(int ascii) {
|
|
||||||
if (!g_menu_open || !g_imgui_initialized || !g_imgui_context)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImGui::SetCurrentContext(g_imgui_context);
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.AddInputCharacter((unsigned int)ascii);
|
|
||||||
}
|
|
||||||
354
src/settings.c
354
src/settings.c
@@ -1,354 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "include/settings.h"
|
|
||||||
#include "include/globals.h"
|
|
||||||
#include "include/game_detection.h"
|
|
||||||
|
|
||||||
|
|
||||||
cheat_settings_t g_settings;
|
|
||||||
|
|
||||||
static bool copy_file(const char* src_path, const char* dst_path) {
|
|
||||||
FILE* src = fopen(src_path, "rb");
|
|
||||||
if (!src) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* dst = fopen(dst_path, "wb");
|
|
||||||
if (!dst) {
|
|
||||||
fclose(src);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buffer[4096];
|
|
||||||
size_t bytes;
|
|
||||||
|
|
||||||
while ((bytes = fread(buffer, 1, sizeof(buffer), src)) > 0) {
|
|
||||||
if (fwrite(buffer, 1, bytes, dst) != bytes) {
|
|
||||||
fclose(src);
|
|
||||||
fclose(dst);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(src);
|
|
||||||
fclose(dst);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool create_root_default_config(void) {
|
|
||||||
cheat_settings_t preset;
|
|
||||||
memset(&preset, 0, sizeof(preset));
|
|
||||||
|
|
||||||
preset.esp_mode = ESP_BOX;
|
|
||||||
preset.chams = true;
|
|
||||||
preset.aimbot_enabled = true;
|
|
||||||
preset.aimbot_fov = 5.0f;
|
|
||||||
preset.aimbot_smoothing_enabled = true;
|
|
||||||
preset.bhop = true;
|
|
||||||
preset.autostrafe = true;
|
|
||||||
preset.thirdperson = false;
|
|
||||||
preset.thirdperson_key = 'C';
|
|
||||||
preset.thirdperson_dist = 150.0f;
|
|
||||||
preset.watermark = true;
|
|
||||||
preset.watermark_rainbow = true;
|
|
||||||
preset.fov = 90.0f;
|
|
||||||
preset.menu_allow_movement = true;
|
|
||||||
|
|
||||||
FILE* file = fopen("../default.cfg", "wb");
|
|
||||||
if (!file) {
|
|
||||||
i_engine->Con_Printf("Error: Could not create root default.cfg\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t written = fwrite(&preset, sizeof(preset), 1, file);
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
if (written != 1) {
|
|
||||||
i_engine->Con_Printf("Error: Failed to write to root default.cfg\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
i_engine->Con_Printf("Successfully created ../default.cfg with preset settings\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void settings_init(void) {
|
|
||||||
init_default_settings();
|
|
||||||
|
|
||||||
char cwd[1024] = {0};
|
|
||||||
if (getcwd(cwd, sizeof(cwd)) != NULL) {
|
|
||||||
i_engine->Con_Printf("Current working directory: %s\n", cwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* config_dir = get_config_dir();
|
|
||||||
if (!config_dir) {
|
|
||||||
i_engine->Con_Printf("Error: Could not get config directory, using defaults\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char config_path[1024];
|
|
||||||
snprintf(config_path, sizeof(config_path), "%s/default.cfg", config_dir);
|
|
||||||
i_engine->Con_Printf("Config path: %s\n", config_path);
|
|
||||||
|
|
||||||
if (access(config_path, F_OK) == 0) {
|
|
||||||
i_engine->Con_Printf("Found config, loading from: %s\n", config_path);
|
|
||||||
|
|
||||||
if (settings_load_from_file("default")) {
|
|
||||||
i_engine->Con_Printf("Successfully loaded config\n");
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Error loading config, using defaults\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (access("../default.cfg", F_OK) == 0) {
|
|
||||||
i_engine->Con_Printf("Found config in project dir, copying to user config...\n");
|
|
||||||
|
|
||||||
if (copy_file("../default.cfg", config_path)) {
|
|
||||||
i_engine->Con_Printf("Successfully copied project config to user directory\n");
|
|
||||||
|
|
||||||
if (settings_load_from_file("default")) {
|
|
||||||
i_engine->Con_Printf("Successfully loaded copied config\n");
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Error loading copied config, using defaults\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Error copying project config, using defaults\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
i_engine->Con_Printf("No config found anywhere, creating default config with current settings\n");
|
|
||||||
|
|
||||||
if (settings_save_to_file("default")) {
|
|
||||||
i_engine->Con_Printf("Created new default config\n");
|
|
||||||
} else {
|
|
||||||
i_engine->Con_Printf("Error creating default config\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_settings.thirdperson_key == 0) {
|
|
||||||
g_settings.thirdperson_key = 'C';
|
|
||||||
}
|
|
||||||
|
|
||||||
i_engine->Con_Printf("Settings initialized. Third-person key: %d\n", g_settings.thirdperson_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void settings_reset(void) {
|
|
||||||
|
|
||||||
g_settings.esp_mode = ESP_OFF;
|
|
||||||
g_settings.esp_friendly = false;
|
|
||||||
g_settings.chams = false;
|
|
||||||
g_settings.tracers = false;
|
|
||||||
g_settings.custom_crosshair = false;
|
|
||||||
g_settings.watermark = false;
|
|
||||||
g_settings.watermark_rainbow = false;
|
|
||||||
|
|
||||||
g_settings.aimbot_enabled = false;
|
|
||||||
g_settings.aimbot_autoshoot = false;
|
|
||||||
g_settings.aimbot_silent = false;
|
|
||||||
g_settings.aimbot_norecoil = false;
|
|
||||||
g_settings.aimbot_recoil_comp = false;
|
|
||||||
g_settings.aimbot_friendly_fire = false;
|
|
||||||
g_settings.aimbot_team_attack = false;
|
|
||||||
g_settings.aimbot_require_key = false;
|
|
||||||
g_settings.aimbot_smoothing_enabled = true;
|
|
||||||
|
|
||||||
g_settings.bhop = false;
|
|
||||||
g_settings.autostrafe = false;
|
|
||||||
g_settings.antiaim = false;
|
|
||||||
g_settings.antiaim_view = false;
|
|
||||||
g_settings.fakeduck = false;
|
|
||||||
g_settings.clmove = false;
|
|
||||||
|
|
||||||
// Reset anti-aim settings
|
|
||||||
g_settings.antiaim_enabled = false;
|
|
||||||
g_settings.antiaim_pitch_enabled = false;
|
|
||||||
g_settings.antiaim_yaw_enabled = false;
|
|
||||||
g_settings.antiaim_pitch = 89.0f;
|
|
||||||
g_settings.antiaim_yaw = 180.0f;
|
|
||||||
g_settings.antiaim_fakeduck = false;
|
|
||||||
g_settings.antiaim_fakeduck_key = 0;
|
|
||||||
g_settings.antiaim_desync = false;
|
|
||||||
g_settings.antiaim_legit = false;
|
|
||||||
|
|
||||||
// Reset advanced anti-aim settings
|
|
||||||
g_settings.antiaim_pitch_mode = 1; // Down (89°)
|
|
||||||
g_settings.antiaim_yaw_mode = 1; // Backward (180°)
|
|
||||||
g_settings.antiaim_custom_pitch = 0.0f;
|
|
||||||
g_settings.antiaim_custom_yaw = 0.0f;
|
|
||||||
g_settings.antiaim_spin_speed = 360.0f; // One rotation per second
|
|
||||||
g_settings.antiaim_jitter_range = 45.0f; // ±45 degrees jitter
|
|
||||||
g_settings.antiaim_lby_breaker = false;
|
|
||||||
g_settings.antiaim_on_attack = false;
|
|
||||||
|
|
||||||
g_settings.namechanger = false;
|
|
||||||
|
|
||||||
g_settings.fov = 90.0f;
|
|
||||||
|
|
||||||
g_settings.thirdperson = false;
|
|
||||||
g_settings.thirdperson_key = 0;
|
|
||||||
g_settings.thirdperson_dist = 150.0f;
|
|
||||||
|
|
||||||
i_engine->pfnClientCmd("echo \"All cheat settings have been reset to default values\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* get_config_dir(void) {
|
|
||||||
static char config_dir[512] = {0};
|
|
||||||
|
|
||||||
if (config_dir[0] == '\0') {
|
|
||||||
const char* home = getenv("HOME");
|
|
||||||
if (!home) {
|
|
||||||
i_engine->Con_Printf("Error: Could not get HOME directory\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(config_dir, sizeof(config_dir), "%s/.config/dz-goldsrccheat", home);
|
|
||||||
|
|
||||||
struct stat st = {0};
|
|
||||||
if (stat(config_dir, &st) == -1) {
|
|
||||||
if (mkdir(config_dir, 0755) == -1) {
|
|
||||||
i_engine->Con_Printf("Error: Could not create config directory %s\n", config_dir);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
i_engine->Con_Printf("Created config directory: %s\n", config_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return config_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool settings_save_to_file(const char* filename) {
|
|
||||||
const char* config_dir = get_config_dir();
|
|
||||||
if (!config_dir) {
|
|
||||||
i_engine->Con_Printf("Error: Could not get config directory\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char filepath[1024];
|
|
||||||
snprintf(filepath, sizeof(filepath), "%s/%s.cfg", config_dir, filename);
|
|
||||||
|
|
||||||
FILE* file = fopen(filepath, "wb");
|
|
||||||
if (!file) {
|
|
||||||
i_engine->Con_Printf("Error: Could not open file for writing: %s\n", filepath);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simple direct binary write of the settings
|
|
||||||
size_t written = fwrite(&g_settings, sizeof(g_settings), 1, file);
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
if (written != 1) {
|
|
||||||
i_engine->Con_Printf("Error: Failed to write settings to file: %s\n", filepath);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
i_engine->Con_Printf("Settings saved to %s\n", filepath);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool settings_load_from_file(const char* filename) {
|
|
||||||
const char* config_dir = get_config_dir();
|
|
||||||
if (!config_dir) {
|
|
||||||
i_engine->Con_Printf("Error: Could not get config directory\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char filepath[1024];
|
|
||||||
snprintf(filepath, sizeof(filepath), "%s/%s.cfg", config_dir, filename);
|
|
||||||
|
|
||||||
if (access(filepath, F_OK) != 0) {
|
|
||||||
i_engine->Con_Printf("Error: Config file does not exist: %s\n", filepath);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* file = fopen(filepath, "rb");
|
|
||||||
if (!file) {
|
|
||||||
i_engine->Con_Printf("Error: Could not open file for reading: %s\n", filepath);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get file size for debugging
|
|
||||||
fseek(file, 0, SEEK_END);
|
|
||||||
long file_size = ftell(file);
|
|
||||||
fseek(file, 0, SEEK_SET);
|
|
||||||
|
|
||||||
i_engine->Con_Printf("Loading config from %s, file size: %ld bytes, struct size: %zu bytes\n",
|
|
||||||
filepath, file_size, sizeof(cheat_settings_t));
|
|
||||||
|
|
||||||
// Simple direct binary read of the settings
|
|
||||||
size_t read = fread(&g_settings, sizeof(g_settings), 1, file);
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
if (read != 1) {
|
|
||||||
i_engine->Con_Printf("Error: Failed to read settings from file: %s\n", filepath);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
i_engine->Con_Printf("Settings loaded. Aimbot=%d, ESP=%d, Bhop=%d, ThirdPerson=%d, TPDist=%.1f\n",
|
|
||||||
g_settings.aimbot_enabled, g_settings.esp_mode, g_settings.bhop,
|
|
||||||
g_settings.thirdperson, g_settings.thirdperson_dist);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool settings_set_as_default(void) {
|
|
||||||
return settings_save_to_file("default");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool settings_create_root_default(void) {
|
|
||||||
return create_root_default_config();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a simple function to copy config from ~/gitprojects/goldsource-cheat/default.cfg to ~/.config/dz-goldsrccheat/default.cfg
|
|
||||||
bool copy_project_config_to_user(void) {
|
|
||||||
const char* config_dir = get_config_dir();
|
|
||||||
if (!config_dir) {
|
|
||||||
i_engine->Con_Printf("Error: Could not get config directory\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char dst_path[1024];
|
|
||||||
snprintf(dst_path, sizeof(dst_path), "%s/default.cfg", config_dir);
|
|
||||||
|
|
||||||
// Check if source exists
|
|
||||||
if (access("../default.cfg", F_OK) != 0) {
|
|
||||||
i_engine->Con_Printf("Error: Source config ../default.cfg does not exist\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!copy_file("../default.cfg", dst_path)) {
|
|
||||||
i_engine->Con_Printf("Error: Failed to copy ../default.cfg to %s\n", dst_path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
i_engine->Con_Printf("Successfully copied project config to user directory\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a simple function to copy config from ~/.config/dz-goldsrccheat/default.cfg to ~/gitprojects/goldsource-cheat/default.cfg
|
|
||||||
bool copy_user_config_to_project(void) {
|
|
||||||
const char* config_dir = get_config_dir();
|
|
||||||
if (!config_dir) {
|
|
||||||
i_engine->Con_Printf("Error: Could not get config directory\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char src_path[1024];
|
|
||||||
snprintf(src_path, sizeof(src_path), "%s/default.cfg", config_dir);
|
|
||||||
|
|
||||||
// Check if source exists
|
|
||||||
if (access(src_path, F_OK) != 0) {
|
|
||||||
i_engine->Con_Printf("Error: Source config %s does not exist\n", src_path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!copy_file(src_path, "../default.cfg")) {
|
|
||||||
i_engine->Con_Printf("Error: Failed to copy %s to ../default.cfg\n", src_path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
i_engine->Con_Printf("Successfully copied user config to project directory\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
96
src/util.c
96
src/util.c
@@ -9,7 +9,6 @@
|
|||||||
#include "include/util.h"
|
#include "include/util.h"
|
||||||
#include "include/sdk.h"
|
#include "include/sdk.h"
|
||||||
#include "include/globals.h"
|
#include "include/globals.h"
|
||||||
#include "include/game_detection.h"
|
|
||||||
|
|
||||||
cl_entity_t* get_player(int ent_idx) {
|
cl_entity_t* get_player(int ent_idx) {
|
||||||
if (ent_idx < 0 || ent_idx > 32)
|
if (ent_idx < 0 || ent_idx > 32)
|
||||||
@@ -36,33 +35,34 @@ bool is_friend(cl_entity_t* ent) {
|
|||||||
if (!ent)
|
if (!ent)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
GameType game = get_current_game();
|
/* Check the current game because this method only works for some games */
|
||||||
|
switch (this_game_id) {
|
||||||
switch (game) {
|
case TF: {
|
||||||
case GAME_TFC: {
|
|
||||||
extra_player_info_t* info = (extra_player_info_t*)player_extra_info;
|
extra_player_info_t* info = (extra_player_info_t*)player_extra_info;
|
||||||
return info[ent->index].teamnumber == info[localplayer->index].teamnumber;
|
|
||||||
|
return info[ent->index].teamnumber ==
|
||||||
|
info[localplayer->index].teamnumber;
|
||||||
}
|
}
|
||||||
case GAME_CS16: {
|
case CS: {
|
||||||
extra_player_info_cs_t* info = (extra_player_info_cs_t*)player_extra_info;
|
extra_player_info_cs_t* info =
|
||||||
return info[ent->index].teamnumber == info[localplayer->index].teamnumber;
|
(extra_player_info_cs_t*)player_extra_info;
|
||||||
|
|
||||||
|
return info[ent->index].teamnumber ==
|
||||||
|
info[localplayer->index].teamnumber;
|
||||||
}
|
}
|
||||||
case GAME_DAY_OF_DEFEAT: {
|
case DOD: {
|
||||||
extra_player_info_dod_t* info = (extra_player_info_dod_t*)player_extra_info;
|
extra_player_info_dod_t* info =
|
||||||
return info[ent->index].teamnumber == info[localplayer->index].teamnumber;
|
(extra_player_info_dod_t*)player_extra_info;
|
||||||
|
|
||||||
|
return info[ent->index].teamnumber ==
|
||||||
|
info[localplayer->index].teamnumber;
|
||||||
}
|
}
|
||||||
case GAME_HALFLIFE:
|
case HL:
|
||||||
case GAME_DMC:
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_shoot(void) {
|
|
||||||
return g_iClip > 0 && g_flNextAttack <= 0.0f &&
|
|
||||||
g_flNextPrimaryAttack <= 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* get_name(int ent_idx) {
|
char* get_name(int ent_idx) {
|
||||||
hud_player_info_t info;
|
hud_player_info_t info;
|
||||||
i_engine->pfnGetPlayerInfo(ent_idx, &info);
|
i_engine->pfnGetPlayerInfo(ent_idx, &info);
|
||||||
@@ -70,6 +70,26 @@ char* get_name(int ent_idx) {
|
|||||||
return info.name;
|
return info.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
game_id get_cur_game(void) {
|
||||||
|
typedef void (*COM_ParseDirectoryFromCmd_t)(const char*, char*, int,
|
||||||
|
const char*);
|
||||||
|
COM_ParseDirectoryFromCmd_t COM_ParseDirectoryFromCmd =
|
||||||
|
(COM_ParseDirectoryFromCmd_t)dlsym(hw, "COM_ParseDirectoryFromCmd");
|
||||||
|
|
||||||
|
char game[FILENAME_MAX];
|
||||||
|
COM_ParseDirectoryFromCmd("-game", game, sizeof(game), "valve");
|
||||||
|
|
||||||
|
/* Get the current game we are playing */
|
||||||
|
if (game[0] == 'c' && game[1] == 's') /* cstrike */
|
||||||
|
return CS;
|
||||||
|
else if (*game == 'd') /* dod */
|
||||||
|
return DOD;
|
||||||
|
else if (*game == 't') /* tfc */
|
||||||
|
return TF;
|
||||||
|
else
|
||||||
|
return HL;
|
||||||
|
}
|
||||||
|
|
||||||
vec3_t vec3(float x, float y, float z) {
|
vec3_t vec3(float x, float y, float z) {
|
||||||
vec3_t ret;
|
vec3_t ret;
|
||||||
|
|
||||||
@@ -108,16 +128,16 @@ float vec_len2d(vec3_t v) {
|
|||||||
return sqrtf(v.x * v.x + v.y * v.y);
|
return sqrtf(v.x * v.x + v.y * v.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ang_clamp(vec3_t* v) {
|
void vec_clamp(vec3_t v) {
|
||||||
v->x = CLAMP(v->x, -89.0f, 89.0f);
|
v.x = CLAMP(v.x, -89.0f, 89.0f);
|
||||||
v->y = CLAMP(remainderf(v->y, 360.0f), -180.0f, 180.0f);
|
v.y = CLAMP(remainderf(v.y, 360.0f), -180.0f, 180.0f); /* v.y % 360 */
|
||||||
v->z = CLAMP(v->z, -50.0f, 50.0f);
|
v.z = CLAMP(v.z, -50.0f, 50.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vec_norm(vec3_t* v) {
|
void vec_norm(vec3_t v) {
|
||||||
v->x = isfinite(v->x) ? remainderf(v->x, 360.f) : 0.f;
|
v.x = isfinite(v.x) ? remainder(v.x, 360) : 0;
|
||||||
v->y = isfinite(v->y) ? remainderf(v->y, 360.f) : 0.f;
|
v.y = isfinite(v.y) ? remainder(v.y, 360) : 0;
|
||||||
v->z = 0.0f;
|
v.z = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float angle_delta_rad(float a, float b) {
|
float angle_delta_rad(float a, float b) {
|
||||||
@@ -163,15 +183,10 @@ bool world_to_screen(vec3_t vec, vec2_t screen) {
|
|||||||
scr_inf.iSize = sizeof(SCREENINFO);
|
scr_inf.iSize = sizeof(SCREENINFO);
|
||||||
i_engine->pfnGetScreenInfo(&scr_inf);
|
i_engine->pfnGetScreenInfo(&scr_inf);
|
||||||
|
|
||||||
|
/* If within bounds, transform to screen scale */
|
||||||
if (screen[0] < 1 && screen[1] < 1 && screen[0] > -1 && screen[1] > -1) {
|
if (screen[0] < 1 && screen[1] < 1 && screen[0] > -1 && screen[1] > -1) {
|
||||||
if (IsDayOfDefeat()) {
|
|
||||||
printf("Before transformation: %f, %f, Depth: %f\n", screen[0], screen[1], screen[2]);
|
|
||||||
screen[0] = ((screen[0] + 1) * 0.5) * scr_inf.iWidth;
|
|
||||||
screen[1] = ((1 - screen[1]) * 0.5) * scr_inf.iHeight;
|
|
||||||
} else {
|
|
||||||
screen[0] = screen[0] * (scr_inf.iWidth / 2) + (scr_inf.iWidth / 2);
|
screen[0] = screen[0] * (scr_inf.iWidth / 2) + (scr_inf.iWidth / 2);
|
||||||
screen[1] = -screen[1] * (scr_inf.iHeight / 2) + (scr_inf.iHeight / 2);
|
screen[1] = -screen[1] * (scr_inf.iHeight / 2) + (scr_inf.iHeight / 2);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -189,19 +204,6 @@ void engine_draw_text(int x, int y, char* s, rgb_t c) {
|
|||||||
i_engine->pfnDrawConsoleString(x, y, s);
|
i_engine->pfnDrawConsoleString(x, y, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_tracer(vec3_t start, vec3_t end, rgb_t c, float a, float w,
|
|
||||||
float time) {
|
|
||||||
static const char* MDL_STR = "sprites/laserbeam.spr";
|
|
||||||
static int beam_idx = i_engine->pEventAPI->EV_FindModelIndex(MDL_STR);
|
|
||||||
|
|
||||||
float r = c.r / 255.f;
|
|
||||||
float g = c.g / 255.f;
|
|
||||||
float b = c.b / 255.f;
|
|
||||||
|
|
||||||
i_engine->pEfxAPI->R_BeamPoints(start, end, beam_idx, time, w, 0, a, 0, 0,
|
|
||||||
0, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gl_drawbox(int x, int y, int w, int h, rgb_t c) {
|
void gl_drawbox(int x, int y, int w, int h, rgb_t c) {
|
||||||
/* Line width */
|
/* Line width */
|
||||||
const int lw = 1;
|
const int lw = 1;
|
||||||
@@ -251,7 +253,7 @@ bool protect_addr(void* ptr, int new_flags) {
|
|||||||
int pgsz = getpagesize();
|
int pgsz = getpagesize();
|
||||||
|
|
||||||
if (mprotect(p, pgsz, new_flags) == -1) {
|
if (mprotect(p, pgsz, new_flags) == -1) {
|
||||||
printf("goldsource-cheat: error protecting %p\n", ptr);
|
printf("hl-cheat: error protecting %p\n", ptr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user