diff --git a/SingleFile/SingleFile.vcxproj b/SingleFile/SingleFile.vcxproj
index edf10c5..45b33a1 100644
--- a/SingleFile/SingleFile.vcxproj
+++ b/SingleFile/SingleFile.vcxproj
@@ -38,13 +38,14 @@
Level3
true
- WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
stdcpplatest
Windows
true
+ minhook.lib;%(AdditionalDependencies)
diff --git a/SingleFile/main.cpp b/SingleFile/main.cpp
index 95f12ba..63ee226 100644
--- a/SingleFile/main.cpp
+++ b/SingleFile/main.cpp
@@ -1,17 +1,12 @@
-#define _CRT_SECURE_NO_WARNINGS
#include
-#include
#include
-#include
-#pragma comment(lib, "minhook")
-#define IN_RANGE(x, a, b) (x >= a && x <= b)
-#define GET_BITS(x) (IN_RANGE(x,'0','9') ? (x - '0') : ((x&(~0x20)) - 'A' + 0xA))
+#include
+#define GET_BITS(x) ((x >= '0' && x <= '9') ? (x - '0') : ((x&(~0x20)) - 'A' + 0xA))
#define GET_BYTE(x) (GET_BITS(x[0x0]) << 0x4 | GET_BITS(x[0x1]))
-PVOID client_dll = NULL; PVOID engine_dll = NULL; HMODULE pModule = NULL;
+PVOID client_dll = NULL; PVOID engine_dll = NULL;
typedef enum MH_STATUS {
MH_UNKNOWN = -1, MH_OK = 0, MH_ERROR_ALREADY_INITIALIZED, MH_ERROR_NOT_INITIALIZED, MH_ERROR_ALREADY_CREATED, MH_ERROR_NOT_CREATED, MH_ERROR_ENABLED, MH_ERROR_DISABLED, MH_ERROR_NOT_EXECUTABLE, MH_ERROR_UNSUPPORTED_FUNCTION, MH_ERROR_MEMORY_ALLOC, MH_ERROR_MEMORY_PROTECT, MH_ERROR_MODULE_NOT_FOUND, MH_ERROR_FUNCTION_NOT_FOUND
-}
-MH_STATUS; // get minhook here: https://github.com/TsudaKageyu/minhook | License for minhook (text of license has not been modified, just newlines removed) : /* MinHook - The Minimalistic API Hooking Library for x64 / x86 * Copyright(C) 2009 - 2017 Tsuda Kageyu. * All rights reserved. * *Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met : * *1. Redistributions of source code must retain the above copyright * notice, this list of conditionsand the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditionsand the following disclaimer in the * documentationand /or other materials provided with the distribution. * *THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, *PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * /
+} MH_STATUS; // get minhook here: https://github.com/TsudaKageyu/minhook | License for minhook (text of license has not been modified, just newlines removed) : /* MinHook - The Minimalistic API Hooking Library for x64 / x86 * Copyright(C) 2009 - 2017 Tsuda Kageyu. * All rights reserved. * *Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met : * *1. Redistributions of source code must retain the above copyright * notice, this list of conditionsand the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditionsand the following disclaimer in the * documentationand /or other materials provided with the distribution. * *THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, *PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * /
extern "C" {
MH_STATUS WINAPI MH_Initialize(VOID);
MH_STATUS WINAPI MH_Uninitialize(VOID);
@@ -34,7 +29,8 @@ PBYTE PatternScan(PVOID m_pModule, LPCSTR m_szSignature) {
if (!pat[0x2])
return first_match;
pat += (*(PUSHORT)pat == (USHORT)'\?\?' || *(PBYTE)pat != (BYTE)'\?') ? 0x3 : 0x2;
- } else {
+ }
+ else {
if (first_match != 0x0)
current = first_match;
pat = m_szSignature;
@@ -43,13 +39,13 @@ PBYTE PatternScan(PVOID m_pModule, LPCSTR m_szSignature) {
}
return NULL;
}
-#undef DrawText
-#undef CreateFont
template
__forceinline I v(PVOID iface, Args... args) { return (*(I(__thiscall***)(void*, Args...))(iface))[Idx](iface, args...); }
#define VIRTUAL_METHOD(returnType, name, idx, args, argsRaw) __forceinline returnType name args { return vargsRaw; }
#define OFFSET(type, name, offset) __forceinline type name(VOID) { return *(type*)(this + offset); }
#define ROFFSET(type, name, offset) __forceinline type& name(VOID) { return *(type*)(this + offset);} // not sure if there's a better way to do this but whatever
+#define PAD(amt) private: char padding_##amt[amt]; public:
+#define CLAMP(val, _min, _max) (val > _max) ? _max : (val < _min) ? _min : val
using matrix_t = FLOAT[3][4];
using matrix4x4_t = FLOAT[4][4];
BOOLEAN menu_open = TRUE;
@@ -71,6 +67,9 @@ struct sconfig {
BOOLEAN m_bDisablePostProcess;
BOOLEAN m_bRankRevealer;
BOOLEAN m_bFlashReducer;
+ BOOLEAN m_bThirdperson;
+ INT m_nThirdpersonDistance = 10;
+ BOOLEAN m_bThirdpersonOnDead;
}visuals;
struct smisc {
BOOLEAN m_bBhop;
@@ -82,16 +81,13 @@ struct sconfig {
BOOLEAN m_bSpectatorList;
BOOLEAN m_bUseSpam;
BOOLEAN m_bVoteRevealer;
+ BOOLEAN m_bClanTag;
}misc;
}config;
class vec3 {
public:
FLOAT x, y, z;
- vec3(FLOAT a = 0, FLOAT b = 0, FLOAT c = 0) {
- this->x = a;
- this->y = b;
- this->z = c;
- }
+ vec3(FLOAT a = 0, FLOAT b = 0, FLOAT c = 0) : x(a), y(b), z(c) { }
vec3 operator-=(const vec3& in) { x -= in.x; y -= in.y; z -= in.z; return *this; }
vec3 operator+=(const vec3& in) { x += in.x; y += in.y; z += in.z; return *this; }
vec3 operator/=(const vec3& in) { x /= in.x; y /= in.y; z /= in.z; return *this; }
@@ -105,13 +101,7 @@ class vec3 {
};
struct SPlayerInfo {
ULONG64 m_ullVersion;
- union {
- ULONG64 m_ullXUID;
- struct {
- DWORD m_nXUIDLow;
- DWORD m_nXUIDHigh;
- };
- };
+ ULONG64 m_ullXUID;
CHAR m_szName[128];
INT m_nUserID;
CHAR m_szGUID[33];
@@ -124,16 +114,17 @@ struct SPlayerInfo {
};
class CMatSystemSurface {
public:
- VIRTUAL_METHOD(VOID, DrawFilledRect, 16, (DWORD x, DWORD y, DWORD w, DWORD h), (this, x, y, x + w, y + h))
- VIRTUAL_METHOD(VOID, SetColor, 15, (USHORT r, USHORT g, USHORT b, USHORT a), (this, r, g, b, a))
- VIRTUAL_METHOD(VOID, SetTextColor, 25, (USHORT r, USHORT g, USHORT b, USHORT a), (this, r, g, b, a))
- VIRTUAL_METHOD(VOID, SetTextPosition, 26, (DWORD x, DWORD y), (this, x, y))
- VIRTUAL_METHOD(VOID, DrawText, 28, (LPCWSTR text, DWORD len), (this, text, len, 0))
- VIRTUAL_METHOD(DWORD, CreateFont, 71, (VOID), (this))
- VIRTUAL_METHOD(BOOLEAN, SetFontGlyphs, 72, (DWORD _font, LPCSTR name, DWORD height, DWORD weight, DWORD font_flags), (this, _font, name, height, weight, 0, 0, font_flags, 0, 0))
- VIRTUAL_METHOD(VOID, SetTextFont, 23, (DWORD _font), (this, _font))
- VIRTUAL_METHOD(VOID, DrawRectOutline, 18, (DWORD x, DWORD y, DWORD w, DWORD h), (this, x, y, x + w, y + h))
- VIRTUAL_METHOD(VOID, GetTextSize, 79, (DWORD _font, LPCWSTR text, DWORD& w, DWORD& h), (this, _font, text, std::ref(w), std::ref(h)))
+ VIRTUAL_METHOD(VOID, DrawFilledRect, 16, (DWORD x, DWORD y, DWORD w, DWORD h), (this, x, y, x + w, y + h));
+ VIRTUAL_METHOD(VOID, SetColor, 15, (USHORT r, USHORT g, USHORT b, USHORT a), (this, r, g, b, a));
+ VIRTUAL_METHOD(VOID, SetTextColor, 25, (USHORT r, USHORT g, USHORT b, USHORT a), (this, r, g, b, a));
+ VIRTUAL_METHOD(VOID, SetTextPosition, 26, (DWORD x, DWORD y), (this, x, y));
+ VIRTUAL_METHOD(VOID, DrawText, 28, (LPCWSTR text, DWORD len), (this, text, len, 0));
+ VIRTUAL_METHOD(DWORD, CreateFont, 71, (VOID), (this));
+ VIRTUAL_METHOD(BOOLEAN, SetFontGlyphs, 72, (DWORD _font, LPCSTR name, DWORD height, DWORD weight, DWORD font_flags), (this, _font, name, height, weight, 0, 0, font_flags, 0, 0));
+ VIRTUAL_METHOD(VOID, SetTextFont, 23, (DWORD _font), (this, _font));
+ VIRTUAL_METHOD(VOID, DrawRectOutline, 18, (DWORD x, DWORD y, DWORD w, DWORD h), (this, x, y, x + w, y + h));
+ VIRTUAL_METHOD(VOID, GetTextSize, 79, (DWORD _font, LPCWSTR text, DWORD& w, DWORD& h), (this, _font, text, std::ref(w), std::ref(h)));
+ VIRTUAL_METHOD(VOID, GradientRectangle, 123, (INT x, INT y, INT w, INT h, DWORD dwAlpha1, DWORD dwAlpha2, BOOLEAN bHoriz), (this, x, y, x + w, y + h, dwAlpha1, dwAlpha2, bHoriz));
};
enum EMoveType {
NONE = 0,
@@ -150,7 +141,7 @@ class CCSClientClass {
public:
PVOID CreateClassFn;
PVOID CreateEventFn;
- char* m_szNetworkedName;
+ LPSTR m_szNetworkedName;
PVOID m_pRecvTable;
CCSClientClass* m_pNextClass;
INT m_nClassID;
@@ -184,28 +175,12 @@ class CBaseEntity {
OFFSET(FLOAT, FlashDuration, 0xA420);
ROFFSET(FLOAT, FlashMaxAlpha, 0xA41C)
OFFSET(INT, Ammo, 0x3264);
- OFFSET(INT, CrosshairTarget, 0xB3E4);
+ OFFSET(INT, CrosshairTarget, 0xB3E8);
+ ROFFSET(INT, ObserverMode, 0x3378);
};
class CGlobalVarsBase {
-public:
- FLOAT m_flRealTime;
- INT m_nFrameCount;
- FLOAT m_flAbsFrameTime;
- FLOAT m_flAbsFrameStart;
+ PAD(0x10); // PAD resets access level to public
FLOAT m_flCurrentTime;
- FLOAT m_flFrameTime;
- INT m_nMaxClients;
- INT m_nTickCount;
- FLOAT m_flTickInterval;
- FLOAT m_flInteropolationAmount;
- INT m_nTicksThisFrmae;
- INT m_nNetworkProtocol;
- PVOID m_pGameSaveData;
- BOOLEAN m_bClient;
- BOOLEAN m_bRemoteClient;
-private:
- DWORD unk1;
- DWORD unk2;
};
template
T RelativeToAbsolute(DWORD m_pAddress) {
@@ -226,6 +201,7 @@ class IVEngineClient {
VIRTUAL_METHOD(VOID, ClientCmdUnrestricted, 114, (LPCSTR szCommand), (this, szCommand, FALSE));
VIRTUAL_METHOD(LPCSTR, GetVersionString, 105, (VOID), (this));
VIRTUAL_METHOD(INT, GetPlayerIndex, 9, (INT nIndex), (this, nIndex));
+ VIRTUAL_METHOD(VOID, GetViewAngles, 18, (vec3& angles), (this, std::ref(angles)));
};
class IGameEvent {
public:
@@ -251,44 +227,67 @@ class ICVar {
public:
VIRTUAL_METHOD(CConvar*, FindVar, 15, (LPCSTR name), (this, name));
};
-class CRecvProp;
-class CClientClass {
+class CRay {
+public:
+ CRay(vec3 vecSource, vec3 vecDest) { this->vecStart = vecSource; this->vecDelta = (vecDelta - vecSource); }
+ vec3 vecStart;
+ vec3 vecDelta;
+};
+struct CTraceFilter {
+ LPCVOID pSkip;
+ CTraceFilter(CBaseEntity* pEntity) { this->pSkip = pEntity; }
+};
+class CTrace {
+public:
+ vec3 vecStart;
+ vec3 vecEnd;
+ PAD(0x14);
+ FLOAT flFraction;
+ PAD(0xC);
+ LPCSTR pszSurfaceName;
+ PAD(0x0C);
+ CBaseEntity* pEntity;
+ INT nHitbox;
+};
+class IEngineTrace {
public:
- PVOID m_pCreateFunction;
- PVOID m_pCreateEventFunction;
- char* m_szNetworkName;
- CRecvProp* m_pRecvPointer;
- CClientClass* m_pNextPointer;
- int m_nClassID;
+ VIRTUAL_METHOD(VOID, TraceRay, 5, (const CRay& pRay, DWORD dwMask, const CTraceFilter& pSkip, CTrace& pTrace), (this, std::cref(pRay), dwMask, std::cref(pSkip), std::ref(pTrace)));
};
+class CRecvProp;
class IClient {
public:
- VIRTUAL_METHOD(CClientClass*, GetClientClasses, 8, (VOID), (this))
+ VIRTUAL_METHOD(CCSClientClass*, GetClientClasses, 8, (VOID), (this))
VIRTUAL_METHOD(BOOLEAN, DispatchUserMessage, 38, (INT m_nMessageType, INT m_nArgument1, INT m_nArgument2, PVOID m_pData), (this, m_nMessageType, m_nArgument1, m_nArgument2, m_pData))
};
+class CInput {
+public:
+ PAD(0xAD);
+ bool bCameraInThirdperson;
+ PAD(0x1);
+ vec3 vecCameraOffset;
+};
class IClientModeShared;
class IGameEventManager2;
class ISound;
struct sinterfaces {
- IVEngineClient* engine = nullptr;
- CMatSystemSurface* surface = nullptr;
- CBaseEntityList* entitylist = nullptr;
- IPanel* panel = nullptr;
- IClient* client = nullptr;
- IClientModeShared* client_mode = nullptr;
- IGameEventManager2* events = nullptr;
- CGlobalVarsBase* globals = nullptr;
- ICVar* cvar = nullptr;
- ISound* sound = nullptr;
+ IVEngineClient* engine = NULL;
+ CMatSystemSurface* surface = NULL;
+ CBaseEntityList* entitylist = NULL;
+ IPanel* panel = NULL;
+ IClient* client = NULL;
+ IClientModeShared* client_mode = NULL;
+ IGameEventManager2* events = NULL;
+ CGlobalVarsBase* globals = NULL;
+ ICVar* cvar = NULL;
+ ISound* sound = NULL;
+ CInput* input = NULL;
+ IEngineTrace* trace = NULL;
}interfaces;
HWND csgo_window;
WNDPROC orig_proc;
struct vec2 {
INT x, y;
- vec2(INT x = 0, INT y = 0) {
- this->x = x;
- this->y = y;
- }
+ vec2(INT x = 0, INT y = 0) : x(x), y(y) {}
};
VOID load(LPCSTR szConfigName) {
FILE* cfg = fopen(szConfigName, "r");
@@ -300,6 +299,11 @@ VOID save(LPCSTR szConfigName) {
fwrite(&config, sizeof(config), 1, cfg);
fclose(cfg);
}
+typedef struct TAGrgba {
+ INT r, g, b, a;
+ TAGrgba(INT r = 0, INT g = 0, INT b = 0, INT a = 255) : r(r), g(g), b(b), a(a) { }
+ FLOAT* AsFloat() { FLOAT p[4] = { this->r / 255.f, this->g / 255.f, this->b / 255.f, this->a / 255.f }; return p; }
+}RGBA, * PRGBA;
namespace menu {
struct sctx { BOOLEAN open; INT width; };
std::unordered_map < LPCWSTR, BOOLEAN> item_clicks = {};
@@ -308,10 +312,10 @@ namespace menu {
vec2 start_pos, size;
BOOLEAN dragging = FALSE, clicked = FALSE, item_active = FALSE, inmove = FALSE;
INT x_pos = 0, y_pos = 0, last_mouse_x = 0, last_mouse_y = 0;
- BOOLEAN in_region( INT x, INT y, INT w, INT h ) {
+ BOOLEAN in_region(INT x, INT y, INT w, INT h) {
return last_mouse_x >= x && last_mouse_y >= y && last_mouse_x <= x + w && last_mouse_y <= y + h;
}
- BOOLEAN clicked_at( LPCWSTR n, INT x, INT y, INT w, INT h ) {
+ BOOLEAN clicked_at(LPCWSTR n, INT x, INT y, INT w, INT h) {
if (item_clicks.count(n) == 0) item_clicks[n] = FALSE;
if (!in_region(x, y, w, h) && !item_clicks[n] || inmove) return FALSE;
item_active = TRUE;
@@ -343,7 +347,7 @@ namespace menu {
interfaces.surface->SetTextColor(255, 255, 255, 255);
static DWORD u, i;
interfaces.surface->GetTextSize(menu::font, name, u, i);
- interfaces.surface->SetTextPosition( start_pos.x + (size.x / 2) - (u / 2), start_pos.y + 6);
+ interfaces.surface->SetTextPosition(start_pos.x + (size.x / 2) - (u / 2), start_pos.y + 6);
interfaces.surface->DrawText(name, wcslen(name));
x_pos = start_pos.x + 10;
y_pos = start_pos.y + 25;
@@ -387,7 +391,7 @@ namespace menu {
return FALSE;
}
VOID move(INT x, INT y) {
- auto store = [x, y] () -> VOID { menu::last_mouse_x = x; menu::last_mouse_y = y; };
+ auto store = [x, y]() -> VOID { menu::last_mouse_x = x; menu::last_mouse_y = y; };
if (!clicked) {
menu::dragging = FALSE;
return store();
@@ -404,7 +408,7 @@ namespace menu {
VOID keybinder(PINT pKey) { // Pints for the low hello Dex.
INT x = x_pos + 180 - Keys[pKey].width;
INT y = y_pos - 15;
- LPCWSTR wszKeyName = pwszVirtualKeys[*pKey];
+ LPCWSTR wszKeyName = pwszVirtualKeys[*pKey];
DWORD w, xh, h = 20;
interfaces.surface->GetTextSize(menu::font, wszKeyName, w, xh);
Keys[pKey].width = w + 16;
@@ -426,17 +430,68 @@ namespace menu {
interfaces.surface->DrawFilledRect(x + 1, y + 1, Keys[pKey].width - 2, h - 2);
interfaces.surface->SetTextPosition(x + (Keys[pKey].width / 2) - 0x6, y + 3); // 0x6 = 12 / 2, 12 is the size of L"..." on the menu.
interfaces.surface->DrawText(L"...", 0x3);
- INT nState = *pKey;
for (INT i = 0; i < 256; i++) {
- USHORT nValue = GetAsyncKeyState(i) & 1;
- if (nValue && i != nState) {
+ if (GetAsyncKeyState( i ) & 1 && i != *pKey) {
*pKey = i;
Keys[pKey].open = FALSE;
}
}
}
}
-}
+ VOID slider(LPCWSTR wsz, INT nMin, INT nMax, PINT pnOut) {
+ interfaces.surface->SetTextPosition(x_pos + 2, y_pos); y_pos += 12;
+ interfaces.surface->DrawText(wsz, wcslen(wsz));
+ WCHAR pwszValue[8]; _itow(*pnOut, pwszValue, 10); DWORD w, h;
+ interfaces.surface->GetTextSize(menu::font, pwszValue, w, h);
+ interfaces.surface->SetTextPosition((x_pos + 170) - (w + 2), y_pos - 12); // meh too lazy to change offset
+ interfaces.surface->DrawText(pwszValue, wcslen(pwszValue));
+ interfaces.surface->SetColor(17, 17, 17, 255);
+ interfaces.surface->DrawRectOutline(x_pos, y_pos, 170, 15);
+ interfaces.surface->SetColor(37, 37, 37, 255);
+ interfaces.surface->DrawRectOutline(x_pos + 1, y_pos + 1, 168, 13);
+ interfaces.surface->SetColor(25, 100, 255, 255);
+ interfaces.surface->DrawFilledRect(x_pos + 2, y_pos + 2, (166 * ((FLOAT)(*pnOut) / (FLOAT)(nMax - nMin))), 11);
+ if (in_region(x_pos - 2, y_pos - 2, 172, 17) && GetAsyncKeyState(VK_LBUTTON)) // make the bbox slightly bigger if the mouse is moving quickly
+ *pnOut = CLAMP((FLOAT)((last_mouse_x - x_pos) / 170.f) * nMax, nMin, nMax);
+ y_pos += 20;
+ }
+ VOID colorpicker(INT x, PRGBA pColor) { // we'll re-use the Keys object for the opened-ness.
+ interfaces.surface->SetColor(17, 17, 17, 255);
+ interfaces.surface->DrawRectOutline(x_pos + x, y_pos, 16, 16);
+ interfaces.surface->SetColor(37, 37, 37, 255);
+ interfaces.surface->DrawRectOutline(x_pos + x + 1, y_pos + 1, 14, 14);
+ interfaces.surface->SetColor(pColor->r, pColor->g, pColor->b, pColor->a);
+ interfaces.surface->DrawFilledRect(x_pos + x + 2, y_pos + 2, 12, 12);
+ interfaces.surface->SetColor(0, 0, 0, 255);
+ interfaces.surface->GradientRectangle(x_pos + x + 2, y_pos + 2, 12, 12, 75, 25, FALSE); // give 3d look
+ if (in_region(x_pos + x, y_pos, 16, 16) && GetAsyncKeyState(VK_LBUTTON))
+ Keys[(PINT)(pColor)].open = TRUE;
+ if (!in_region(x_pos + x, y_pos, 16, 16) && GetAsyncKeyState(VK_LBUTTON) && !in_region(x_pos + x + 5, y_pos + 5, 230, 200))
+ Keys[(PINT)(pColor)].open = FALSE;
+ if (Keys[(PINT)(pColor)].open) {
+ interfaces.surface->SetColor(42, 42, 42, 255);
+ interfaces.surface->DrawFilledRect(x_pos + x + 5, y_pos + 5, 230, 200);
+ interfaces.surface->SetColor(37, 37, 37, 255);
+ interfaces.surface->DrawRectOutline(x_pos + x + 6, y_pos + 6, 228, 198);
+ interfaces.surface->SetColor(255, 255, 255, 255);
+ interfaces.surface->DrawFilledRect(x_pos + x + 7, y_pos + 7, 196, 196);
+ interfaces.surface->SetColor(1, 1, 1, 255);
+ interfaces.surface->GradientRectangle(x_pos + x + 7, y_pos + 7, 196, 196, 255, 0, FALSE);
+ interfaces.surface->SetColor(25, 100, 255, 255);
+ interfaces.surface->GradientRectangle(x_pos + x + 7, y_pos + 7, 196, 196, 0, 255, TRUE);
+ const RGBA Hues[7] = {
+ {255, 0, 0}, {255, 0, 255}, {0, 0, 255}, {0, 255, 255}, {0, 255, 0}, {255, 255, 0}, {255, 0, 0}
+ };
+ for (INT i = 0; i < 6; i++) {
+ RGBA coly = Hues[i + 1], colx = Hues[i];
+ interfaces.surface->SetColor(colx.r, colx.g, colx.b, 255);
+ interfaces.surface->DrawFilledRect(x_pos + x + 210, y_pos + 2 + (14 * i), 16, 14);
+ interfaces.surface->SetColor(coly.r, coly.g, coly.b, 255);
+ interfaces.surface->GradientRectangle(x_pos + x + 210, y_pos + 2 + (28 * i), 16, 28, 0, 255, FALSE);
+ }
+ }
+ }
+}
VOID SetupFonts() {
menu::font = interfaces.surface->CreateFont();
interfaces.surface->SetFontGlyphs(menu::font, "Verdana", 12, 600, 0);
@@ -450,7 +505,7 @@ VOID RenderMenu() {
once = TRUE;
}
menu::window(L"singlefile csgo internal");
- menu::checkbox(L"bhop", &config.misc.m_bBhop);
+ menu::checkbox(L"bhop", &config.misc.m_bBhop);
menu::checkbox(L"auto pistol", &config.aimbot.m_bAutoPistol);
menu::checkbox(L"hitsound", &config.misc.m_bHitSound);
menu::checkbox(L"box esp", &config.visuals.m_bBoxESP);
@@ -473,16 +528,20 @@ VOID RenderMenu() {
menu::checkbox(L"use spam", &config.misc.m_bUseSpam);
menu::checkbox(L"flash reducer", &config.visuals.m_bFlashReducer);
menu::checkbox(L"vote revealer", &config.misc.m_bVoteRevealer);
- if (menu::button(L"load", {menu::start_pos.x + 10, menu::start_pos.y + 220}, {195, 30}))
+ if (menu::button(L"load", { menu::start_pos.x + 10, menu::start_pos.y + 220 }, { 195, 30 }))
load("singlefile");
- if (menu::button(L"save", {menu::start_pos.x + 215, menu::start_pos.y + 220}, {195, 30}))
- save("singlefile");
+ if (menu::button(L"save", { menu::start_pos.x + 215, menu::start_pos.y + 220 }, { 195, 30 }))
+save("singlefile");
+RGBA pog(20, 100, 255);
+menu::colorpicker(170, &pog);
+static int nTest = 102;
+menu::slider(L"test slider", 0, 200, &nTest);
}
class CUserCmd {
private:
BYTE pad_0x0[0x4];
public:
- INT m_nCommandNumber;
+ INT m_nCommandNumber;
INT m_nTickCount;
vec3 m_vecAngles;
vec3 m_vecDirection;
@@ -500,6 +559,7 @@ class CUserCmd {
private:
BYTE pad_0x1[0x18];
};
+VOID(WINAPI* OverrideViewOriginal)(PVOID);
BOOLEAN(WINAPI* CreateMoveOriginal)(FLOAT, CUserCmd*);
VOID(__thiscall* PaintTraverseOriginal)(IPanel*, DWORD, BOOLEAN, BOOLEAN);
BOOLEAN(__thiscall* GameEventsOriginal)(IGameEventManager2*, IGameEvent*);
@@ -507,21 +567,13 @@ VOID(WINAPI* EmitSoundOriginal)(PVOID, INT, INT, LPCSTR, DWORD, LPCSTR, FLOAT, I
BOOLEAN(__thiscall* DispatchUserMessageOriginal)(PVOID, INT, INT, INT, PVOID);
LRESULT CALLBACK Wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- if (uMsg == WM_KEYDOWN) {
- switch (wParam) {
- case VK_INSERT:
- menu_open = !menu_open;
- break;
- }
- }
+ if (uMsg == WM_KEYDOWN && wParam == VK_INSERT)
+ menu_open ^= true;
+ menu::inmove = uMsg == WM_MOUSEMOVE;
menu::clicked = (BOOLEAN)(wParam & MK_LBUTTON);
- if (uMsg == WM_MOUSEMOVE) {
+ if (menu::inmove)
menu::move((INT)((SHORT)(LOWORD(lParam))), (INT)((SHORT)(HIWORD(lParam))));
- menu::inmove = TRUE;
- } else {
- menu::inmove = FALSE;
- }
- return CallWindowProc(orig_proc, hWnd, uMsg, wParam, lParam);
+ return CallWindowProcA(orig_proc, hWnd, uMsg, wParam, lParam);
}
enum {
IN_ATTACK = 1 << 0,
@@ -530,8 +582,8 @@ enum {
IN_SCORE = 1 << 16,
IN_COUNT = 1 << 26,
};
-namespace colors { unsigned char green[4] = {0, 255, 0, 255}; unsigned char lightgreen[4] = {10, 200, 10, 255}; unsigned char red[4] = {255, 0, 0, 255}; unsigned char lightred[4] = {200, 10, 10, 255}; };
-void(*ColoredMsg)(PUCHAR, LPCSTR, ...);
+namespace colors { unsigned char green[4] = { 0, 255, 0, 255 }; unsigned char lightgreen[4] = { 10, 200, 10, 255 }; unsigned char red[4] = { 255, 0, 0, 255 }; unsigned char lightred[4] = { 200, 10, 10, 255 }; };
+VOID(*ColoredMsg)(PUCHAR, LPCSTR, ...);
VOID voterevealer(IGameEvent* evt = NULL) {
if (!config.misc.m_bVoteRevealer || !interfaces.engine->IsInGame())
return;
@@ -568,13 +620,25 @@ VOID autopistol(CUserCmd* cmd) {
cmd->m_nButtons &= ~IN_ATTACK;
}
}
+__forceinline constexpr DWORD fnv(LPCSTR szString, DWORD nOffset = 0x811C9DC5) {
+ return (*szString == '\0') ? nOffset : fnv(&szString[1], (nOffset ^ DWORD(*szString)) * 0x01000193);
+}
+#define CT_FNV(str) (std::integral_constant::value)
VOID autoaccept(LPCSTR sound) {
- if (strstr(sound, "UIPanorama.popup_accept_match_beep")) {
+ if (fnv(sound) == CT_FNV("UIPanorama.popup_accept_match_beep")) {
static BOOLEAN(WINAPI * SetLPReady)(LPCSTR) = (decltype(SetLPReady))PatternScan(client_dll, "55 8B EC 83 E4 F8 8B 4D 08 BA ? ? ? ? E8 ? ? ? ? 85 C0 75 12");
if (config.misc.m_bAutoAccept)
SetLPReady("");
}
}
+LPCSTR szClantag = "";
+VOID clantag() {
+ static VOID(__fastcall * SetClantag)(LPCSTR, LPCSTR) = (decltype(SetClantag))PatternScan(engine_dll, "53 56 57 8B DA 8B F9 FF 15");
+ if (config.misc.m_bClanTag && !strstr(szClantag, "SingleFile"))
+ SetClantag("SingleFile", "SingleFile");
+ if (!config.misc.m_bClanTag && strstr(szClantag, "SingleFile"))
+ SetClantag("\x20", "\x20");
+}
VOID flashreducer() {
if (!config.visuals.m_bFlashReducer || !interfaces.engine->IsInGame())
return;
@@ -586,15 +650,14 @@ VOID flashreducer() {
interfaces.engine->GetScreenSize(w, h);
interfaces.surface->GetTextSize(6, L"FLASHED!", tw, th); // first 50 built-in vgui fonts: https://cdn.discordapp.com/attachments/634094496300400641/821827439042101258/unknown.png
interfaces.surface->SetTextPosition((DWORD)((w * 0.5f) - tw * 0.5f), (DWORD)(h * 0.75f));
- interfaces.surface->SetTextFont(6);
+ interfaces.surface->SetTextFont(6);
interfaces.surface->DrawText(L"FLASHED!", 0x8);
}
}
struct bbox {
INT x, y, w, h;
};
-BOOLEAN WorldToScreen(const vec3& world, vec3& screen)
-{
+BOOLEAN WorldToScreen(const vec3& world, vec3& screen) {
matrix4x4_t& view = interfaces.engine->GetViewMatrix();
screen.x = world.x * view[0][0] + world.y * view[0][1] + world.z * view[0][2] + view[0][3];
screen.y = world.x * view[1][0] + world.y * view[1][1] + world.z * view[1][2] + view[1][3];
@@ -613,30 +676,35 @@ BOOLEAN WorldToScreen(const vec3& world, vec3& screen)
return TRUE;
}
#define FL_MAX 3.40282e+038;
+#define PI 3.1415927f
+#define Radians(x) ((FLOAT)(x)*(FLOAT)(PI / 180.f))
vec3 VectorTransform(vec3 in, matrix_t matrix) {
return vec3(in.dot(matrix[0]) + matrix[0][3], in.dot(matrix[1]) + matrix[1][3], in.dot(matrix[2]) + matrix[2][3]);
}
+vec3 AngleVectors(vec3 vecAngles) {
+ vec3 vecReturn;
+ FLOAT p1, p2, p3, p4;
+ p1 = sinf(Radians(vecAngles.y));
+ p2 = cosf(Radians(vecAngles.y));
+ p3 = sinf(Radians(vecAngles.x));
+ p4 = cosf(Radians(vecAngles.x));
+ vecReturn = { p4 * p2, p4 * p1, -p3 };
+ return vecReturn;
+}
BOOLEAN getbbot(CBaseEntity* player, bbox& box) {
matrix_t& rgflTransFrame = (matrix_t&)player->GetCoordinateFrame();
const vec3 min = player->CollisonMins();
const vec3 max = player->CollisonMaxs();
vec3 vecTransScreen[8];
vec3 points[] = {
- vec3(min.x, min.y, min.z),
- vec3(min.x, max.y, min.z),
- vec3(max.x, max.y, min.z),
- vec3(max.x, min.y, min.z),
- vec3(max.x, max.y, max.z),
- vec3(min.x, max.y, max.z),
- vec3(min.x, min.y, max.z),
- vec3(max.x, min.y, max.z)
+ vec3(min.x, min.y, min.z), vec3(min.x, max.y, min.z), vec3(max.x, max.y, min.z), vec3(max.x, min.y, min.z), vec3(max.x, max.y, max.z), vec3(min.x, max.y, max.z), vec3(min.x, min.y, max.z), vec3(max.x, min.y, max.z)
};
for (INT i = 0; i <= 7; i++) {
if (!WorldToScreen(VectorTransform(points[i], rgflTransFrame), vecTransScreen[i]))
return FALSE;
}
vec3 vecBoxes[] = {
- vecTransScreen[3], vecTransScreen[5], vecTransScreen[0], vecTransScreen[4], vecTransScreen[2], vecTransScreen[1], vecTransScreen[6], vecTransScreen[7]
+ vecTransScreen[3], vecTransScreen[5], vecTransScreen[0], vecTransScreen[4], vecTransScreen[2], vecTransScreen[1], vecTransScreen[6], vecTransScreen[7]
};
FLOAT flLeft = vecTransScreen[3].x, flBottom = vecTransScreen[3].y, flRight = vecTransScreen[3].x, flTop = vecTransScreen[3].y;
for (INT i = 0; i <= 7; i++) {
@@ -655,15 +723,6 @@ BOOLEAN getbbot(CBaseEntity* player, bbox& box) {
box.h = (INT)(flBottom)-(INT)(flTop);
return TRUE;
}
-struct rgba {
- INT r, g, b, a;
- rgba(INT r = 0, INT g = 0, INT b = 0, INT a = 255) {
- this->r = r;
- this->g = g;
- this->b = b;
- this->a = a;
- }
-};
VOID players() {
if (!interfaces.engine->IsInGame())
return;
@@ -702,11 +761,11 @@ VOID players() {
}
}
if (config.visuals.m_bHealthBar) {
- rgba healthclr;
+ RGBA healthclr;
if (entity->GetHealth() > 100)
- healthclr = rgba(0, 255, 0, 255);
+ healthclr = RGBA(0, 255, 0, 255);
else
- healthclr = rgba((INT)(255 - entity->GetHealth() * 2.55f), (INT)(entity->GetHealth() * 2.55f), 0, 255);
+ healthclr = RGBA((INT)(255 - entity->GetHealth() * 2.55f), (INT)(entity->GetHealth() * 2.55f), 0, 255);
interfaces.surface->SetColor(0, 0, 0, 255);
interfaces.surface->DrawFilledRect(box.x - 10, box.y - 1, 5, box.h + 2);
interfaces.surface->SetColor(healthclr.r, healthclr.g, healthclr.b, healthclr.a);
@@ -718,7 +777,7 @@ VOID players() {
}
VOID cvars() {
CBaseEntity* localplayer = interfaces.entitylist->GetEntity(interfaces.engine->GetLocalPlayer());
- interfaces.cvar->FindVar("mat_postprocess_enable")->SetValue(config.visuals.m_bDisablePostProcess ? 0 : 1);
+ interfaces.cvar->FindVar("mat_postprocess_enable")->SetValue(config.visuals.m_bDisablePostProcess ? 0 : 1);
interfaces.cvar->FindVar("cl_crosshair_recoil")->SetValue(config.misc.m_bRecoilCrosshair ? 1 : 0); // i'm sure the ? 1 : 0 doesn't matter but this feels better. /shrug
interfaces.cvar->FindVar("weapon_debug_spread_show")->SetValue(((config.misc.m_bNoScopeCrosshair) && !localplayer->IsScoped()) ? 2 : 0);
}
@@ -728,7 +787,7 @@ VOID speclist() {
CBaseEntity* localplayer = interfaces.entitylist->GetEntity(interfaces.engine->GetLocalPlayer());
if (!localplayer)
return;
- static INT b = 0;
+ INT b = 0;
if (config.misc.m_bSpectatorList) {
for (INT i = 1; i <= interfaces.engine->GetMaxClients(); i++) {
CBaseEntity* entity = interfaces.entitylist->GetEntity(i);
@@ -750,7 +809,6 @@ VOID speclist() {
b += 12;
}
}
- b = 0;
}
VOID triggerbot(CUserCmd* cmd) {
if (!(config.aimbot.m_bTriggerbot))
@@ -773,18 +831,24 @@ VOID usespam(CUserCmd* cmd) {
cmd->m_nButtons &= ~IN_USE;
}
}
+VOID __stdcall _OverrideView(PVOID pArgument) {
+ return OverrideViewOriginal(pArgument);
+}
BOOLEAN __fastcall _DispatchUserMessage(PVOID ecx, PVOID edx, INT nMessageType, INT nArgument, INT nArgument2, PVOID pData) {
if (nMessageType == 47 && config.misc.m_bVoteRevealer) {
- ColoredMsg(colors::green, "[singlefile] Vote Passed!\n"); Beep(670, 50); }
+ ColoredMsg(colors::green, "[singlefile] Vote Passed!\n"); Beep(670, 50);
+ }
if (nMessageType == 48 && config.misc.m_bVoteRevealer) {
- ColoredMsg(colors::red, "[singlefile] Vote Failed!\n"); Beep(343, 50); }
+ ColoredMsg(colors::red, "[singlefile] Vote Failed!\n"); Beep(343, 50);
+ }
return DispatchUserMessageOriginal(interfaces.client, nMessageType, nArgument, nArgument2, pData);
}
BOOLEAN WINAPI _CreateMove(FLOAT flInputSampleTime, CUserCmd* cmd) {
BOOLEAN SetViewAngles = CreateMoveOriginal(flInputSampleTime, cmd);
- if (cmd->m_nCommandNumber % 4 == 1) {
+ if (cmd->m_nCommandNumber % 10 == 1) {
cmd->m_nButtons |= IN_COUNT; // anti-afk kick maybe make it it's own option at some point :P
cvars(); // commands that do not to run each tick (i.e don't need usercmd, just dependent on localplayer & being in game)
+ clantag();
}
if (cmd->m_nButtons & IN_SCORE && config.visuals.m_bRankRevealer)
interfaces.client->DispatchUserMessage(50, 0, 0, NULL);
@@ -798,31 +862,28 @@ VOID WINAPI _EmitSound(void* filter, int entityIndex, int channel, const char* s
autoaccept(soundEntry);
return EmitSoundOriginal(filter, entityIndex, channel, soundEntry, soundEntryHash, sample, volume, seed, soundLevel, flags, pitch, std::cref(origin), std::cref(direction), utlVecOrigins, updatePositions, soundtime, speakerentity, soundParams);
}
-DWORD fnv(LPCSTR szString, DWORD nOffset = 0x811C9DC5) {
- return (*szString == '\0') ? nOffset : fnv(&szString[1], (nOffset ^ DWORD(*szString)) * 0x01000193);
-}
BOOLEAN WINAPI _GameEvents(IGameEvent* event) {
DWORD dwEventHash = fnv(event->GetName());
- if (config.misc.m_bHitSound && dwEventHash == 0x1B30DDF0) {
+ if (config.misc.m_bHitSound && dwEventHash == CT_FNV("player_hurt")) {
SPlayerInfo player;
interfaces.engine->GetPlayerInfo(interfaces.engine->GetLocalPlayer(), &player);
if (event->GetInt("attacker") == player.m_nUserID)
interfaces.engine->ClientCmdUnrestricted("play buttons/arena_switch_press_02");
}
- if (dwEventHash == 0xFDAD5FE5 && config.misc.m_bVoteRevealer)
+ if (dwEventHash == CT_FNV("vote_cast") && config.misc.m_bVoteRevealer)
voterevealer(event);
return GameEventsOriginal(interfaces.events, event);
}
VOID WINAPI _PaintTraverse(DWORD dwPanel, BOOLEAN bForceRepaint, BOOLEAN bAllowRepaint) {
DWORD drawing = fnv(interfaces.panel->GetPanelName(dwPanel));
- if (drawing == 0xA4A548AF) { // fnv("MatSystemTopPanel") = 0xA4A548AF
+ if (drawing == CT_FNV("MatSystemTopPanel")) {
players();
speclist();
flashreducer();
if (menu_open)
RenderMenu();
}
- if (drawing == 0x8BE56F81) { // fnv("FocusOverlayPanel") = 0x8BE56F81
+ if (drawing == CT_FNV("FocusOverlayPanel")) {
interfaces.panel->SetInputMouseState(dwPanel, menu_open);
interfaces.panel->SetInputKeyboardState(dwPanel, menu_open && (config.misc.m_bGameKeyboard));
}
@@ -835,6 +896,7 @@ VOID LoadHooks() {
MH_CreateHook((*(PVOID**)(interfaces.events))[9], &_GameEvents, (PVOID*)&GameEventsOriginal);
MH_CreateHook((*(PVOID**)(interfaces.sound))[5], &_EmitSound, (PVOID*)&EmitSoundOriginal);
MH_CreateHook((*(PVOID**)(interfaces.client))[38], &_DispatchUserMessage, (PVOID*)&DispatchUserMessageOriginal);
+ MH_CreateHook((*(PVOID**)(interfaces.client_mode))[18], &_OverrideView, (PVOID*)&OverrideViewOriginal);
MH_EnableHook(NULL);
}
template
@@ -842,13 +904,13 @@ T CreateInterface(PVOID m_pModule, LPCSTR m_szInterface) {
return ((T(*)(LPCSTR, DWORD))GetProcAddress((HMODULE)m_pModule, "CreateInterface"))(m_szInterface, 0x0);
}
INT GetLineCount();
-VOID WINAPI Init (HMODULE mod) {
+VOID WINAPI Init(HMODULE mod) {
while (!GetModuleHandleA("serverbrowser.dll"))
Sleep(250);
AllocConsole();
SetConsoleTitleA("singlefile: console");
freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
- printf("singlefile v1.3: loading... (compiled with %d lines of code)\n", GetLineCount());
+ printf("singlefile v1.4 beta: loading... (compiled with %d lines of code)\n", GetLineCount());
csgo_window = FindWindowA("Valve001", NULL);
orig_proc = (WNDPROC)SetWindowLongA(csgo_window, GWLP_WNDPROC, (LONG)Wndproc);
client_dll = GetModuleHandleA("client.dll");
@@ -857,7 +919,7 @@ VOID WINAPI Init (HMODULE mod) {
PVOID vgui2_dll = GetModuleHandleA("vgui2.dll");
PVOID vstdlib_dll = GetModuleHandleA("vstdlib.dll");
interfaces.engine = CreateInterface(engine_dll, "VEngineClient014");
- if (!strstr(interfaces.engine->GetVersionString(), "1.37.8.7"))
+ if (!strstr(interfaces.engine->GetVersionString(), "1.37.8.8"))
printf("note: you are using an unknown cs:go client version (%s). if you are experiencing crashes, you may need to update offsets. each offset in the source code has it's netvar name, or you can find it on hazedumper.\n", interfaces.engine->GetVersionString());
interfaces.entitylist = CreateInterface(client_dll, "VClientEntityList003");
interfaces.surface = CreateInterface(surface_dll, "VGUI_Surface031");
@@ -866,8 +928,10 @@ VOID WINAPI Init (HMODULE mod) {
interfaces.cvar = CreateInterface(vstdlib_dll, "VEngineCvar007");
interfaces.events = CreateInterface(engine_dll, "GAMEEVENTSMANAGER002");
interfaces.sound = CreateInterface(engine_dll, "IEngineSoundClient003");
+ interfaces.trace = CreateInterface(engine_dll, "EngineTraceClient004");
interfaces.client_mode = **(IClientModeShared***)((*(DWORD**)(interfaces.client))[0xA] + 0x5);
interfaces.globals = **(CGlobalVarsBase***)((*(DWORD**)(interfaces.client))[0xB] + 0xA);
+ interfaces.input = *(CInput**)((*(DWORD**)(interfaces.client))[0x10] + 0x1);
ColoredMsg = (decltype(ColoredMsg))GetProcAddress(GetModuleHandleA("tier0.dll"), "?ConColorMsg@@YAXABVColor@@PBDZZ");
SetupFonts();
LoadHooks();
@@ -876,8 +940,9 @@ VOID WINAPI Init (HMODULE mod) {
Sleep(500);
MH_DisableHook(NULL); // NULL = all hooks
MH_RemoveHook(NULL);
+ SetWindowLongA(csgo_window, GWLP_WNDPROC, (LONG_PTR)orig_proc);
MH_Uninitialize();
- FreeConsole();
+ FreeLibraryAndExitThread(mod, 0x1);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID pReserved) {
if (dwReason == DLL_PROCESS_ATTACH)
@@ -886,4 +951,4 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID pReserved) {
}
INT GetLineCount() { // must be at bottom obviously :P
return (__LINE__ + 0x1);
-}
+}
\ No newline at end of file