From fa1877879347eb05f7073acbcef6a72f99048160 Mon Sep 17 00:00:00 2001 From: al-eax Date: Sun, 5 Apr 2020 16:27:03 +0200 Subject: [PATCH] initial commit --- .gitignore | 45 +++++ CMakeLists.txt | 24 +++ README.md | 60 +++++++ build.sh | 3 + build_debug_inject.sh | 3 + build_run_inject.sh | 3 + gdb_wow .sh | 2 + inject_debug_via_ldpreload.sh | 2 + inject_via_ldpreload.sh | 2 + src/Controller.h | 89 +++++++++ src/DebugConsole.h | 60 +++++++ src/Esp.h | 155 ++++++++++++++++ src/Hooks.h | 137 ++++++++++++++ src/ImGuiOglFrame.h | 329 ++++++++++++++++++++++++++++++++++ src/MainMenu.h | 69 +++++++ src/Offsets.h_OLD | 74 ++++++++ src/PathRecorder.h | 55 ++++++ src/PathWalker.h | 60 +++++++ src/Radar.h | 108 +++++++++++ src/Utils.h | 181 +++++++++++++++++++ src/WindowUtils.h | 149 +++++++++++++++ src/imgui_impl_opengl2.cpp | 244 +++++++++++++++++++++++++ src/imgui_impl_opengl2.h | 30 ++++ src/main.cpp | 9 + src/wow/Offsets.h | 110 ++++++++++++ src/wow/WOWCamera.h | 69 +++++++ src/wow/WOWClient.h | 38 ++++ src/wow/WOWFunctions.h | 142 +++++++++++++++ src/wow/WOWObject.h | 42 +++++ src/wow/WOWObjectManager.h | 107 +++++++++++ src/wow/WOWPlayer.h | 10 ++ src/wow/WOWUnit.h | 37 ++++ 32 files changed, 2448 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100755 build.sh create mode 100755 build_debug_inject.sh create mode 100755 build_run_inject.sh create mode 100755 gdb_wow .sh create mode 100755 inject_debug_via_ldpreload.sh create mode 100755 inject_via_ldpreload.sh create mode 100644 src/Controller.h create mode 100644 src/DebugConsole.h create mode 100644 src/Esp.h create mode 100644 src/Hooks.h create mode 100644 src/ImGuiOglFrame.h create mode 100644 src/MainMenu.h create mode 100644 src/Offsets.h_OLD create mode 100644 src/PathRecorder.h create mode 100644 src/PathWalker.h create mode 100644 src/Radar.h create mode 100644 src/Utils.h create mode 100644 src/WindowUtils.h create mode 100644 src/imgui_impl_opengl2.cpp create mode 100644 src/imgui_impl_opengl2.h create mode 100644 src/main.cpp create mode 100644 src/wow/Offsets.h create mode 100644 src/wow/WOWCamera.h create mode 100644 src/wow/WOWClient.h create mode 100644 src/wow/WOWFunctions.h create mode 100644 src/wow/WOWObject.h create mode 100644 src/wow/WOWObjectManager.h create mode 100644 src/wow/WOWPlayer.h create mode 100644 src/wow/WOWUnit.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73c077c --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# Created by https://www.gitignore.io/api/c++ +# Edit at https://www.gitignore.io/?templates=c++ + +### C++ ### +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# End of https://www.gitignore.io/api/c++ + +# additional stuff + +build/* + +### other stuff ### +*.ini diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..49f545f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.0) + +project(ezwow) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_FLAGS "-O2 -fPIC -fpermissive -m32 -L/usr/lib/x86_64-linux-gnu") + +set(CMAKE_CXX_FLAGS_LIST "${CMAKE_CXX_FLAGS_LIST} -m32") +set(CMAKE_EXE_LINK_FLAGS_LIST "${CMAKE_EXE_LINK_FLAGS_LIST} -m32") +set(CMAKE_SHARED_LINK_FLAGS_LIST "${CMAKE_SHARED_LINK_FLAGS_LIST} '-m32'") + +set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS OFF) +set(CMAKE_SYSTEM_LIBRARY_PATH /lib32 /usr/lib32 /usr/lib/i386-linux-gnu /usr/local/lib32) +set(CMAKE_IGNORE_PATH /lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib64 /usr/local/lib) +set(CMAKE_ASM_FLAGS "--32") + +add_library(ezwow SHARED + src/main.cpp + src/third_party/imgui/imgui_draw.cpp + src/third_party/imgui/imgui.cpp + src/third_party/imgui/imgui_widgets.cpp + src/imgui_impl_opengl2.cpp +) + diff --git a/README.md b/README.md new file mode 100644 index 0000000..5d18342 --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# EzWow + + +special thanks to ownedcore.com community! + + +## set up + +```sh +# install wine +sudo apt-get install wine +# stuff to build +sudo apt-get install g++ git cmake g++-multilib +sudo apt-get install build-essential libgl1-mesa-dev + +# window handling & input related stuff +sudo apt-get install libxmu-dev +sudo apt-get install libxtst-dev +``` + +## clone & build + +```sh +# clone repo with dependencies and build +git clone --recursive git@github.com:al-eax/ezwow.git +cd ezwow +# make all sh files executable +find . "*.sh" -execdir chmod u+x {} + +# build libezwow.so +./build.sh +``` + +## configure + +```sh +# replace the path to your Wow.exe in these files +editor inject_via_ldpreload.sh +editor inject_debug_via_ldpreload.sh +``` + +## build, run & inject + +```sh +# build libezwow.so +./build.sh + +# build libezwow.so, start Wow.exe via wine and inject libezwow.so +./inject_via_ldpreload.sh + +# attach gdb to Wow +./gdb_wow.sh + +# start Wow via winedbg and inject libezwow.so +./inject_debug_via_ldpreload +``` + +## third party + +* subhook +* imgui diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..32e277b --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#mkdir build +cmake -B./build/ -H. || exit 1 +cmake --build ./build/ || exit 1 \ No newline at end of file diff --git a/build_debug_inject.sh b/build_debug_inject.sh new file mode 100755 index 0000000..0dd787a --- /dev/null +++ b/build_debug_inject.sh @@ -0,0 +1,3 @@ +#!/bin/bash +bash build.sh || exit 1 +bash inject_debug_via_ldpreload.sh diff --git a/build_run_inject.sh b/build_run_inject.sh new file mode 100755 index 0000000..7ac3468 --- /dev/null +++ b/build_run_inject.sh @@ -0,0 +1,3 @@ +#!/bin/bash +bash build.sh || exit 1 +bash inject_via_ldpreload.sh diff --git a/gdb_wow .sh b/gdb_wow .sh new file mode 100755 index 0000000..e6e1a3a --- /dev/null +++ b/gdb_wow .sh @@ -0,0 +1,2 @@ +#!/bin/bash +sudo gdb --pid=$(pgrep Wow.exe) diff --git a/inject_debug_via_ldpreload.sh b/inject_debug_via_ldpreload.sh new file mode 100755 index 0000000..1e9c269 --- /dev/null +++ b/inject_debug_via_ldpreload.sh @@ -0,0 +1,2 @@ +#!/bin/bash +LD_PRELOAD=build/libezwow.so winedbg "/media/alex/SSD/Games/TBC-2.4.3.8606-Repack/Wow.exe" "-console " \ No newline at end of file diff --git a/inject_via_ldpreload.sh b/inject_via_ldpreload.sh new file mode 100755 index 0000000..bf78210 --- /dev/null +++ b/inject_via_ldpreload.sh @@ -0,0 +1,2 @@ +#!/bin/bash +LD_PRELOAD=build/libezwow.so wine "/media/alex/SSD/Games/TBC-2.4.3.8606-Repack/Wow.exe" "-console" \ No newline at end of file diff --git a/src/Controller.h b/src/Controller.h new file mode 100644 index 0000000..016f651 --- /dev/null +++ b/src/Controller.h @@ -0,0 +1,89 @@ +// +// Created by alex on 27.06.19. +// + +#ifndef WOWCPP_CONTROLLER_H +#define WOWCPP_CONTROLLER_H + +#include + +#include "MainMenu.h" +#include "Hooks.h" +#include "Radar.h" +#include "wow/WOWClient.h" +#include "wow/WOWFunctions.h" +#include "wow/WOWCamera.h" +#include "wow/Offsets.h" +#include "PathRecorder.h" +#include "PathWalker.h" +#include "DebugConsole.h" +#include "Esp.h" + +class Controller +{ + static inline MainMenu menu; + inline static pthread_t thread; + inline static bool hooks_installed = false; + inline static bool is_ingame = false; + static inline Esp esp; + +public: + /** + * This function gets NO CALLS from the game MAIN THREAD! + * This function gets called once per frame, when wines directx server calls glXSwapBuffers. + * Its perfect for ui rendering and rinning other visual systems. + */ + static void GlxSwapBufferCallback() + { + try + { + menu.Render(); + } + catch (const std::exception &e) + { + std::cerr << e.what() << '\n'; + } + } + + /** + * This function gets called in the function at GET_CAM_OFFSET_FUNC. + * This function gets multiple calls per frame. + */ + static void InGameLoopCallback() + { + is_ingame = WOWClient().IsInGame(); + // menu.in_game = is_ingame; + static bool walk = false; + + if (menu.btn_login) + { + menu.btn_login = false; + WOWFunctions::Login("foo", "bar"); + Logs.push_back("logged in"); + } + + if(menu.btn_dbg1){ + menu.btn_dbg1 = false; + menu.in_game = is_ingame; + } + } + + /** + * This function gets called in a created thread in Controller::Run method. + */ + static void ThreadLoopCallback() + { + if (!hooks_installed) + { + InitHook(InGameLoopCallback, GlxSwapBufferCallback, []() { }); + hooks_installed = true; + } + } + + static void Run() + { + pthread_create(&thread, NULL, [](void *) -> void * { while(1) Controller::ThreadLoopCallback(); }, NULL); + } +}; + +#endif //WOWCPP_CONTROLLER_H diff --git a/src/DebugConsole.h b/src/DebugConsole.h new file mode 100644 index 0000000..e6f60dc --- /dev/null +++ b/src/DebugConsole.h @@ -0,0 +1,60 @@ + +#ifndef __DBGCONSOLE_H__ +#define __DBGCONSOLE_H__ + +#include +#include +#include +#include +#include +#include + +#include "ImGuiOglFrame.h" +#include "imgui_impl_opengl2.h" + +static std::vector Logs; +static std::map Commands; + +class DebugConsole +{ + +private: + + void ExecuteCmd(std::string cmd) + { + Logs.push_back(">" + cmd); + if(Commands.count(cmd) == 1) + Commands[cmd](); + } + +public: + + void Draw() + { + ImGui::Begin("Debugconsole", NULL, ImVec2(350, 200), 0.6f, ImGuiWindowFlags_NoSavedSettings); + + static char txtb_command[200]; + + ImGui::InputText("", txtb_command, 200); + ImGui::SameLine(); + if (ImGui::Button("execute")) + { + ExecuteCmd(std::string(txtb_command)); + txtb_command[0] = '\0'; + } + + ImGui::BeginChild("Scrolling"); + for (int i = Logs.size() - 1; i >= 0; i--) + ImGui::Text(Logs[i].c_str()); + + ImGui::EndChild(); + + ImGui::End(); + + if(Logs.size() > 200) + Logs.erase(Logs.begin(), Logs.begin() + 100); + } +}; + +#endif + diff --git a/src/Esp.h b/src/Esp.h new file mode 100644 index 0000000..adbb2d4 --- /dev/null +++ b/src/Esp.h @@ -0,0 +1,155 @@ + + +#ifndef __ESP_H__ +#define __ESP_H__ + +#include "wow/WOWObjectManager.h" +#include "Utils.h" +#include "wow/WOWCamera.h" +#include "ImGuiOglFrame.h" +#include "wow/WOWClient.h" + +class Esp +{ +private: + /* data */ + Vector2f WorldToScreen(Vector3f cam_position, Vector3f view_direction, Vector3f world_point, Vector2f screen_size, Vector2f near_far) + { + + //create the other view vectors + if (view_direction.len() == 0) + return Vector2f{-1, -1}; + + Vector3f foreward = view_direction.norm(); + + if (foreward.len() == 0) + return Vector2f{-1, -1}; + + Vector3f left = foreward.cross({0, 0, 100}).norm(); //calc the left vector + + if (left.len() == 0) + return Vector2f{-1, -1}; + + Vector3f up = foreward.cross(left).norm(); //calc the up vector + + if (up.len() == 0) + return Vector2f{-1, -1}; + + printf("foreward %s left %s up %s\n", foreward.str().c_str(), left.str().c_str(), up.str().c_str()); + + auto rel_world_pos = world_point.sub(cam_position); + + // check if rel_world_pos is in ront of us: + // we project the enemy on our view_direction vector. Dot gives us the factor f; so f * view_direction = projected point + if (rel_world_pos.dot(foreward) < 0) + { + //return Vector2f{-1, -1}; + printf("- invisible\n"); + } + else + { + printf("+ visible %f\n", rel_world_pos.dot(foreward)); + } + + Vector2f transforms_rel_world_pos{ + left.mult(rel_world_pos.dot(left)).y / (rel_world_pos.dot(foreward) - near_far.x ), + -up.mult(rel_world_pos.dot(up)).z / (rel_world_pos.dot(foreward) - near_far.x )}; + + // corecction + if(transforms_rel_world_pos.x == 1 || transforms_rel_world_pos.y == 1) + return {-1,-1}; + + + + printf("before transforms_rel_world_pos %s \n", transforms_rel_world_pos.str().c_str()); + + + // if (transforms_rel_world_pos.x > 0) + // transforms_rel_world_pos.x = transforms_rel_world_pos.x / 0.67; + // else + // transforms_rel_world_pos.x = transforms_rel_world_pos.x / 0.29; + + printf("transforms_rel_world_pos normed %s \n", transforms_rel_world_pos.str().c_str()); + + + transforms_rel_world_pos.x = screen_size.x * 0.5 + screen_size.x * 0.5 * transforms_rel_world_pos.x; + transforms_rel_world_pos.y = screen_size.y * 0.5 + screen_size.y * 0.5 * transforms_rel_world_pos.y; + + + + float dist_x_mid = std::abs(transforms_rel_world_pos.x - screen_size.x * 0.5); + //transforms_rel_world_pos.x += dist_x_mid * corecction.x; + + printf("after transforms_rel_world_pos %s \n", transforms_rel_world_pos.str().c_str()); + return transforms_rel_world_pos; + } + Vector2f fov{1, 1}; + +void ObjectToWindowShort(float WindowOut[3]) +{ + float mvx[16], px[16]; + int vp[4]; + + glGetFloatv(GL_MODELVIEW_MATRIX, mvx); + glGetFloatv(GL_PROJECTION_MATRIX, px); + glGetIntegerv(GL_VIEWPORT, vp); + + float x2 = px[0]*mvx[12]+px[4]*mvx[13]+px[8]*mvx[14]+px[12]; + float y2 = px[1]*mvx[12]+px[5]*mvx[13]+px[9]*mvx[14]+px[13]; + float z2 = px[2]*mvx[12]+px[6]*mvx[13]+px[10]*mvx[14]+px[14]; + float w2 = px[3]*mvx[12]+px[7]*mvx[13]+px[11]*mvx[14]+px[15]; + + WindowOut[0] = (float) vp[0] + vp[2] * 0.5f * (x2/w2 + 1.0f); + WindowOut[1] = (float) vp[1] + vp[3] * 0.5f * (y2/w2 + 1.0f); + WindowOut[2] = (float) 0.5f * (z2/w2 + 1.0f); + WindowOut[1] = (float) (vp[3] - WindowOut[1]); +} + +public: + void Draw() + { + Vector2f size = WOWClient().GetVideoResolution(); + + ImGuiWindowFlags window_flags = 0; + window_flags |= ImGuiWindowFlags_NoTitleBar; + window_flags |= ImGuiWindowFlags_NoResize; + window_flags |= ImGuiWindowFlags_NoMove; + window_flags |= ImGuiWindowFlags_NoSavedSettings; + //window_flags |= ImGuiWindowFlags_NoMouseInputs; + ImGui::SetNextWindowPos(ImVec2(0, 0)); + ImGui::Begin("ESPP", NULL, ImVec2(size.x, size.y), 0.0f, window_flags); + + auto cam_pos = WOWCamera().Position(); + auto view_direction = WOWCamera().ViewDirection(); + auto units = WOWObjectManager().GetUnitList(); + auto u = units[0]; + + auto screen_pos = WorldToScreen(cam_pos, view_direction, u.GetLocation(), size, WOWCamera().zPlane()); + float foo[3] = {u.GetLocation().x,u.GetLocation().y,u.GetLocation().z}; + + ObjectToWindowShort(foo); + if (screen_pos.x != -1 && screen_pos.y != -1) + { + ImDrawList *draw_list = ImGui::GetWindowDrawList(); + //printf("+ isible\n"); + draw_list->AddCircleFilled(ImVec2(screen_pos.x, screen_pos.y), 4, ImColor(200, 200, 150)); + + draw_list->AddCircleFilled(ImVec2(foo[0],foo[1]), 4, ImColor(100, 200, 150)); + + } + else + { + //printf("- invisible\n"); + } + + ImGui::End(); + ImGui::Begin("ESP menu", NULL); + ImGui::LabelText(u.GetName().c_str(), ""); + ImGui::SliderFloat("fovx", &fov.x, -500.0f, 500.0f); + ImGui::SliderFloat("fovy", &fov.y, -500.0f, 500.0f); + + ImGui::End(); + } +}; + +#endif \ No newline at end of file diff --git a/src/Hooks.h b/src/Hooks.h new file mode 100644 index 0000000..2fd65f1 --- /dev/null +++ b/src/Hooks.h @@ -0,0 +1,137 @@ +// +// Created by alex on 14.06.19. +// + +#ifndef WOWCPP_HOOKS_H +#define WOWCPP_HOOKS_H + +#include +#include +//#include +#include +#include +//#include + +#include "third_party/subhook/subhook.c" +#include "WindowUtils.h" +#include "wow/WOWFunctions.h" +#include "DebugConsole.h" + +using CallbackFunction = void (*)(void); +template +/** + * @brief A simple wrapper for subhook c functions. + * Make sure you called Install() before accessing Trampolin or Original. + */ +class Hook +{ +private: + subhook_t hook; + +public: + CallbackFunction UserCallBack; + T Trampolin = nullptr; + T Original = nullptr; + T Callback = nullptr; + + template + void Install(U func_too_hook, V callback) + { + Install((void *)func_too_hook, (void *)callback); + } + + void Install(T func_too_hook, T callback) + { + Install((void *)func_too_hook, (void *)callback); + } + + void Install(void *func_too_hook, void *callback) + { + hook = subhook_new((void *)func_too_hook, (void *)callback, (subhook_flags_t)0); + subhook_install(hook); + Callback = (T)callback; + Trampolin = (T)subhook_get_trampoline(hook); + Original = (T)hook->src; + } + + void Disable() + { + subhook_remove(hook); + } + + void Enable() + { + Install(hook->src, hook->dst); + } +}; + +Hook Hook_glXSwapBuffers; +Hook<> Hook_MainLoop; +Hook Hook_Interact; +Hook Hook_W2S; +Hook Hook_glDepthRange; + +void MainLoopCallBack() +{ + Hook_MainLoop.UserCallBack(); + Hook_MainLoop.Trampolin(); +} + +void FrameCallBack(Display *di, GLXDrawable dr) +{ + Hook_glXSwapBuffers.Disable(); + Hook_glXSwapBuffers.UserCallBack(); + glXSwapBuffers(di, dr); + Hook_glXSwapBuffers.Enable(); +} + +void __fastcall InteractCallback(int param_1) +{ + Logs.push_back("Interact called"); +} + +void __thiscall W2SCallback(int *thiz, float *param, float *param2) +{ + //printf("W2SCallback %x %f %f\n",thiz, param[0],param[1]); + printf("W2SCallback %x %f %f | %f %f\n",thiz, param[0],param[1], param2[0],param2[1]); + + Hook_W2S.Trampolin(thiz,param,param2); + +} + +void glDepthRangeCallback(GLclampd near, GLclampd far){ + printf("glDepthRangeCallback\n"); + Hook_glDepthRange.Disable(); + if(far == 1){ + Hook_glDepthRange.UserCallBack(); + } + glDepthRange(near,far); + Hook_glDepthRange.Enable(); +} + +void InitHook(CallbackFunction _MainLoopCallBack, CallbackFunction _FrameCallBack, CallbackFunction _GLdepthRangeCallBack) +{ + + while (dlsym(RTLD_NEXT, "glXGetProcAddressARB") == 0) + { + } + Hook_glXSwapBuffers.UserCallBack = _FrameCallBack; + Hook_glXSwapBuffers.Install(glXGetProcAddressARB((GLubyte *)"glXSwapBuffers"), FrameCallBack); + + while(glXGetProcAddressARB((GLubyte *)"glDepthRange") == 0) + { + } + Hook_glDepthRange.UserCallBack = _GLdepthRangeCallBack; + Hook_glDepthRange.Install(glXGetProcAddressARB((GLubyte *)"glDepthRange"), glDepthRangeCallback); + + Hook_MainLoop.UserCallBack = _MainLoopCallBack; + Hook_MainLoop.Install(MAINLOOP_FUNC, MainLoopCallBack); + + //Hook_Interact.Install(0x00600960, InteractCallback); + + //Hook_W2S.Install(0x00534010, W2SCallback); + + +} + +#endif //WOWCPP_HOOKS_H diff --git a/src/ImGuiOglFrame.h b/src/ImGuiOglFrame.h new file mode 100644 index 0000000..b88a944 --- /dev/null +++ b/src/ImGuiOglFrame.h @@ -0,0 +1,329 @@ +// +// Created by alex on 25.06.19. +// + +#ifndef IMGUIOGLFRAME_H +#define IMGUIOGLFRAME_H + +#include +#include +#include +#include // dlopen/RTLD_LAZY +#include // M_PI + +#include "wow/WOWObjectManager.h" +#include "wow/WOWCamera.h" + +#include "WindowUtils.h" + +#include "third_party/imgui/imgui.h" +#include "imgui_impl_opengl2.h" + +class ImGuiOglFrame +{ + +private: + static inline GLXContext my_context; + static inline GLXContext game_context; + static inline Display *display; + static inline GLXDrawable current_drawable; + + static void CreateOwnContext() + { + int screen = -1; + glXQueryContext(display, game_context, GLX_SCREEN, &screen); + int attribs[] = {GLX_FBCONFIG_ID, -1, None}; + int dummy; + glXQueryContext(display, game_context, GLX_FBCONFIG_ID, &attribs[1]); + GLXFBConfig *fb = glXChooseFBConfig(display, screen, attribs, &dummy); + XVisualInfo *vis = glXGetVisualFromFBConfig(display, *fb); + my_context = glXCreateContext(display, vis, 0, True); + } + + /** + * @see https://www.ownedcore.com/forums/world-of-warcraft/world-of-warcraft-bots-programs/wow-memory-editing/302991-opengl-howto-about-drawing-3d-geometry-ig-perfectly-zbuffer-no-ui-overlay.html#post1933915 + */ + static bool SwitchOglContext() + { + auto window = GetWindowByName("World of Warcraft"); + if (window == -1) + return false; + + if (display == nullptr) + display = glXGetCurrentDisplay(); + game_context = glXGetCurrentContext(); + current_drawable = glXGetCurrentDrawable(); + if (my_context == 0) + CreateOwnContext(); + + glXMakeCurrent(display, current_drawable, my_context); + glEnable(GL_DEPTH_TEST); + + uint32_t w, h; + GetWindowSize(window, w, h); + glXQueryDrawable(display, current_drawable, GLX_WIDTH, &w); + glXQueryDrawable(display, current_drawable, GLX_HEIGHT, &h); + glViewport(0, 0, w, h); + + return true; + } + + static void UnSwitchGlContext() + { + glXMakeCurrent(display, current_drawable, game_context); + } + + /** + * @see https://www.gamedev.net/forums/topic/421529-manual-alternative-to-glulookat-/ + * @see https://www.gamedev.net/forums/topic/421529-manual-alternative-to-glulookat-/ + * @param pos + * @param dir + * @param up + */ + /* + static void LookAt(const CVector3& pos, const CVector3& dir, const CVector3& up) + { + CVector3 dirN; + CVector3 upN; + CVector3 rightN; + + dirN = dir; + dirN.Normalize(); + + upN = up; + upN.Normalize(); + + rightN = dirN.Cross(upN); + rightN.Normalize(); + + upN = rightN.Cross(dirN); + upN.Normalize(); + + float mat[16]; + mat[ 0] = rightN.x; + mat[ 1] = upN.x; + mat[ 2] = -dirN.x; + mat[ 3] = 0.0; + + mat[ 4] = rightN.y; + mat[ 5] = upN.y; + mat[ 6] = -dirN.y; + mat[ 7] = 0.0; + + mat[ 8] = rightN.z; + mat[ 9] = upN.z; + mat[10] = -dirN.z; + mat[11] = 0.0; + + mat[12] = -(rightN.Dot(pos)); + mat[13] = -(upN.Dot(pos)); + mat[14] = (dirN.Dot(pos)); + mat[15] = 1.0; + + glMultMatrixf(&mat[0]); + } +*/ + + void SetupGl3D() + { + // dlopen("glut.so", RTLD_LAZY); + float view_mat[9]; + WOWCamera cam; + cam.ViewMatrix(view_mat); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + printf("fov %f , Ratio %f near %f far %f\n", cam.Fov(), cam.Ratio(), cam.zNear(), cam.zFar()); + auto _gluPerspective = (void (*)(GLdouble, GLdouble, GLdouble, GLdouble))glXGetProcAddressARB((GLubyte *)"gluPerspective"); + + _gluPerspective(cam.Fov() * 180.0f / M_PI, cam.Ratio(), cam.zNear(), cam.zFar()); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glScalef(2.0f, 2.0f, 1.0f); + auto f = cam.ViewDirection(); + float forward[3] = { + f.x, + f.y, + f.z}; + float fPos[3] = { + cam.Position().x, + cam.Position().y, + cam.Position().z}; + printf("POS %f %f %f\n", fPos[0], fPos[1], fPos[2]); + + auto _gluLookAt = (void (*)(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble))glXGetProcAddressARB((GLubyte *)"gluLookAt"); + _gluLookAt(fPos[0], fPos[1], fPos[2], + fPos[0] + forward[0], fPos[1] + forward[1], fPos[2] + forward[2], + 0, 0, 1); + } + +protected: + /** + * @brief Override this function to draw your imgui 2d stuff + */ + virtual void Draw(){}; + + /** + * @brief Checks wether a key was pressed or not and sets this information to the imgui io object. + * + * @param key the key to heck + */ + static void CheckKeyInput(int key) + { + auto &io = ImGui::GetIO(); + static std::map KeyWasPressed; + + io.KeysDown[io.KeyMap[ImGuiKey_Backspace]] = (key == XK_BackSpace || key == XK_KP_Delete); + + if (GetKeyState(key)) + { + KeyWasPressed[key]++; + } + else if (KeyWasPressed[key] > 0) + { + KeyWasPressed[key] = 0; + if (key >= XK_A && key <= XK_Z) + io.AddInputCharacter((unsigned int)key); + if (key == XK_space || key == XK_KP_Space) + { + io.AddInputCharacter(' '); + } + } + } + + /** + * @brief updates imguis io object for mouse position, clicks and pressed keys. + * + */ + static void UpdateIO() + { + auto window = GetWindowByName("World of Warcraft"); + + if (window == -1) + return; + + auto &io = ImGui::GetIO(); + + int x, y; + unsigned int w, h; + + GetRelativeMousePosition(window, x, y); + GetWindowSize(window, w, h); + GetMouseBtnStatus(io.MouseDown[0], io.MouseDown[1], io.MouseDown[2]); + + io.MousePos = ImVec2(x, y); + io.DisplaySize = ImVec2(w, h); + + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableSetMousePos | ImGuiBackendFlags_HasSetMousePos; + + //check keys a..z + for (int key = XK_A; key <= XK_Z; key++) + CheckKeyInput(key); + //check space key + CheckKeyInput(XK_space); + } + + void tetrahedron(float zbuffer /* 0.94f : 0.1f */, float x, float y, float z) + { + glDepthRange(0.0f, 1); + + glPushMatrix(); + glTranslatef(x, y, z); + glScalef(3.0f, 3.0f, 3.0f); + glBegin(GL_TRIANGLE_FAN); + glColor3ub(255, 0, 255); + glVertex3f(0.0f, 0.0f, 10.0f); + + glColor3ub(255, 0, 0); + glVertex3f(10.0f, 0.0f, 0.0f); + + glColor3ub(0, 255, 0); + glVertex3f(cos(2 * M_PI / 3), sin(2 * M_PI / 3), 0); + + glColor3ub(0, 0, 255); + glVertex3f(cos(-2 * M_PI / 3), sin(-2 * M_PI / 3), 0); + + glColor3ub(255, 0, 0); + glVertex3f(10.0f, 0.0f, 0.0f); + glEnd(); + glPopMatrix(); + } + + void ObjectToWindowShort(float WindowOut[3]) + { + float mvx[16], px[16]; + int vp[4]; + + glGetFloatv(GL_MODELVIEW_MATRIX, mvx); + glGetFloatv(GL_PROJECTION_MATRIX, px); + glGetIntegerv(GL_VIEWPORT, vp); + + float x2 = px[0] * mvx[12] + px[4] * mvx[13] + px[8] * mvx[14] + px[12]; + float y2 = px[1] * mvx[12] + px[5] * mvx[13] + px[9] * mvx[14] + px[13]; + float z2 = px[2] * mvx[12] + px[6] * mvx[13] + px[10] * mvx[14] + px[14]; + float w2 = px[3] * mvx[12] + px[7] * mvx[13] + px[11] * mvx[14] + px[15]; + + WindowOut[0] = (float)vp[0] + vp[2] * 0.5f * (x2 / w2 + 1.0f); + WindowOut[1] = (float)vp[1] + vp[3] * 0.5f * (y2 / w2 + 1.0f); + WindowOut[2] = (float)0.5f * (z2 / w2 + 1.0f); + WindowOut[1] = (float)(vp[3] - WindowOut[1]); + } + +public: + bool in_game = false; + void Render() + { + if (!SwitchOglContext()) + return; + + static bool _init = true; + + if (_init) + { + _init = false; + ImGui::CreateContext(); + ImGui_ImplOpenGL2_Init(); + } + + UpdateIO(); + ImGui_ImplOpenGL2_NewFrame(); + + ImGui::NewFrame(); + + Draw(); + + ImGui::Render(); + ImGui::EndFrame(); + ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); + + if (in_game) + { + printf("ingame\n"); + auto u = WOWObjectManager().GetUnitList()[0]; + float foo[3] = {u.GetLocation().x, u.GetLocation().y, u.GetLocation().z}; + auto pos = u.GetLocation(); + + SetupGl3D(); + // auto pos = WOWObjectManager().GetUnitList()[0].GetLocation(); + // auto pos2 = WOWObjectManager().GetLocalPlayer().GetLocation(); + // glPushMatrix(); + // glTranslatef(0.1,.1,0.1); + // //glScalef(3.0f, 3.0f, 3.0f); + // glBegin(GL_LINES); + // glVertex3f(0.4, 0.4, 0.4); + // //glVertex3f(pos.x, pos.y, pos.z); + // glVertex3f(0.3, 0.3, 0.3); + // glEnd(); + // glPopMatrix(); + // + //for (float f = -10.00; f < 100; f += 0.01) + tetrahedron(0, pos.x, pos.y, pos.z); + } + + UnSwitchGlContext(); + } +}; + +#endif //IMGUIOGLFRAME_H diff --git a/src/MainMenu.h b/src/MainMenu.h new file mode 100644 index 0000000..f94bd53 --- /dev/null +++ b/src/MainMenu.h @@ -0,0 +1,69 @@ +// +// Created by alex on 28.06.19. +// + +#ifndef WOWCPP_MAINMENU_H +#define WOWCPP_MAINMENU_H + +#include "ImGuiOglFrame.h" +#include "Radar.h" +#include "wow/WOWClient.h" +#include "DebugConsole.h" +#include "Esp.h" + +class MainMenu : public ImGuiOglFrame +{ +public: + // ui controls: + bool chbx_draw_esp = false; + bool chbx_draw_radar = false; + bool btn_login = false; + bool chbx_draw_console = false; + bool chbx_esp = false; + bool btn_dbg1, btn_dbg2, btn_dbg3,btn_dbg4; + + char txtbx_1[200]; + Radar radar; + DebugConsole console; + Esp esp; + +protected: + virtual void Draw() override + { + ImGui::Begin("EzWoW", NULL, ImVec2(200, 200), -1 ); //, ImGuiWindowFlags_NoSavedSettings); + ImGui::Checkbox("Radar", &chbx_draw_radar); + ImGui::Checkbox("Debugconsole", &chbx_draw_console); + ImGui::Checkbox("Esp", &chbx_esp); + + btn_login |= ImGui::Button("login"); + + ImGui::InputText("foooo", txtbx_1, 200); + ImGui::LabelText("current Status", "%s", WOWClient().GetCurrentStatus().c_str()); + + btn_dbg1 |= ImGui::Button("dbg1"); + btn_dbg2 |= ImGui::Button("dbg2"); + btn_dbg3 |= ImGui::Button("dbg3"); + btn_dbg4 |= ImGui::Button("dbg4"); + + ImGui::End(); + + if (chbx_draw_radar) + { + radar.Draw(); + } + + if(chbx_draw_console){ + console.Draw(); + } + + if(chbx_esp){ + esp.Draw(); + } + } + + void Draw3d() + { + } +}; + +#endif //WOWCPP_MAINMENU_H diff --git a/src/Offsets.h_OLD b/src/Offsets.h_OLD new file mode 100644 index 0000000..dadb6b1 --- /dev/null +++ b/src/Offsets.h_OLD @@ -0,0 +1,74 @@ +// +// Created by alex on 14.06.19. +// +/* + * see https://github.com/ARNFRIED/TrampolineDetours + * + */ + +#ifndef WOWCPP_OFFSETS_H +#define WOWCPP_OFFSETS_H + +#include + +//WOW Objectmanager offset list: + +uint32_t WOW_OBJECT_TABLE_PTR = 0x00D43318; +uint32_t OBJ_TABLE_OBJMGR_OFFSET = 0x2218; +uint32_t OBJMGR_LP_GUID_OFFSET = 0xC0; +uint32_t OBJMGR_FIRST_OBJ = 0xAC; + +//WOWObject offset list: +uint32_t WOWOBJ_DESCRIPTOR_OFFSET = 0x8; +uint32_t WOWOBJ_TYPE_OFFSET = 0x14; +uint32_t WOWOBJ_GUID_OFFSET = 0x30; +uint32_t WOWOBJ_NEXT_OBJ_OFFSET = 0x3C; +uint32_t WOWOBJ_LOCATION_OFFSET = 0xBF0; + + +enum WOWObjectType : uint32_t { + Object = 0, + Item = 1, + Container = 2, + Unit = 3, + Player = 4, + GameObject = 5, + DynamicObject = 6, + Corpse = 7, + AiGroup = 8, + AreaTrigger = 9, + ListEnd = 205, +}; + +//WOWUnit offset list: + +uint32_t WOWUNIT_NAME_OFFSET_1 = 0xdb8; +uint32_t WOWUNIT_NAME_OFFSET_2 = 0x40; +uint32_t WOWUNIT_HP_OFFSET = 0x70; +uint32_t WOWUNIT_LEVEL_OFFSET = 0x88; + +// Camera + +uint32_t CAM_OFFSET = 0x732c; +uint32_t CAM_ADDRESS = 0x00c6eccc; + +// Other offsets + +uint32_t VIDEO_RESOLUTION_WIDTH_ADDR = 0x00D6938C; +uint32_t VIDEO_RESOLUTION_HEIGHT_ADDR = 0x00D6938C + 0x4; + +uint32_t WINDOW_WIDTH_OFFSET = 0x00E17FB8; +uint32_t WINDOW_HEIGHT_OFFSET = 0x00E17FB8 + 0x4; + +uint32_t TARGET_GUID_FUNC = 0x004a46a0; +uint32_t LUA_TO_STRING_FUNX = 0x00706C80; + +uint32_t SCREEN_STATUS_TEXT_PTR = 0x00C07CD0; +uint32_t LOGIN_FUNC_PTR = 0x0046E560; //__cdecl (char* user,char*pass) + +uint32_t GET_CAM_OFFSET_FUNC = 0x004ab5b0; +uint32_t MAINLOOP_FUNC2 = 0x00428770; //0x000000000042b42b +uint32_t MAINLOOP_FUNC = 0x00428810; + + +#endif //WOWCPP_OFFSETS_H diff --git a/src/PathRecorder.h b/src/PathRecorder.h new file mode 100644 index 0000000..c22ceb6 --- /dev/null +++ b/src/PathRecorder.h @@ -0,0 +1,55 @@ + +#ifndef __PATHRECORDER_H__ +#define __PATHRECORDER_H__ + +#include +#include + +#include "Utils.h" +#include "wow/WOWObjectManager.h" + +class PathRecorder +{ +private: + std::vector path; + bool is_recording = false; + +public: + int distance = 5; + + void Start() + { + path.clear(); + is_recording = true; + } + + void Schedule() + { + if (!is_recording) + return; + auto curr_pos = WOWObjectManager().GetLocalPlayer().GetLocation(); + + if (path.size() > 0) + { + auto last_pos = path[path.size() -1]; + if (last_pos.dist(curr_pos) > distance) + { + path.push_back(curr_pos); + printf("added new waypoint (%f|%f|%f)\n", curr_pos.x, curr_pos.y, curr_pos.z); + } + } + else + { + path.push_back(curr_pos); + printf("added initial waypoint (%f|%f|%f)\n", curr_pos.x, curr_pos.y, curr_pos.z); + } + } + + auto Stop() + { + is_recording = false; + return path; + } +}; + +#endif \ No newline at end of file diff --git a/src/PathWalker.h b/src/PathWalker.h new file mode 100644 index 0000000..609bc6e --- /dev/null +++ b/src/PathWalker.h @@ -0,0 +1,60 @@ + +#ifndef __PATHWALKER_H__ +#define __PATHWALKER_H__ + +#include "Utils.h" + +#include "wow/WOWObjectManager.h" +#include "wow/WOWFunctions.h" + +#include + +class PathWalker +{ +private: + std::vector path; + bool enabled = false; + +public: + void Start(std::vector _path) + { + path = _path; + enabled = true; + } + + void Resume(){ + enabled = true; + } + + void Schedule() + { + if (!enabled) + return; + + auto current_pos = WOWObjectManager().GetLocalPlayer().GetLocation(); + + if (path.size() == 0){ + enabled = false; + WOWFunctions::ClickToMove(ClickToMoveType::Idle,0,current_pos,false); + return; + } + + auto path_point = path[0]; + + if(current_pos.dist(path_point) > 2 ){ + WOWFunctions::ClickToMove(ClickToMoveType::Move,0,path_point,true); + }else if( current_pos.dist(path_point) <= 2){ + path.erase(path.begin()); + } + } + + void Stop() + { + enabled = false; + auto current_pos = WOWObjectManager().GetLocalPlayer().GetLocation(); + WOWFunctions::ClickToMove(ClickToMoveType::Idle,0,current_pos,false); + } + +}; + +#endif \ No newline at end of file diff --git a/src/Radar.h b/src/Radar.h new file mode 100644 index 0000000..e67e4d7 --- /dev/null +++ b/src/Radar.h @@ -0,0 +1,108 @@ +// +// Created by alex on 28.06.19. +// + +#ifndef WOWCPP_RADAR_H +#define WOWCPP_RADAR_H + +#include + +#include "ImGuiOglFrame.h" +#include "wow/WOWObjectManager.h" +#include "wow/WOWCamera.h" +#include "DebugConsole.h" + +class Radar +{ +private: + + Vector2f WorldToRadar(Vector3f world_pos, Vector2f camera_pos,Vector2f radar_pos , Vector2f radar_size, float camera_yaw){ + + } + + void DrawUnits() + { + std::string text_filter(txtb_textfilter); + ImDrawList *draw_list = ImGui::GetWindowDrawList(); + ImVec2 winpos = ImGui::GetWindowPos(); + ImVec2 winsize = ImGui::GetWindowSize(); + + float scale_x = winsize.x / 200; + float scale_y = winsize.y / 200; + + auto Mgr = WOWObjectManager(); + if(Mgr.GetLocalPlayer().BaseAddress == 0) return; + auto my_loc = Mgr.GetLocalPlayer().GetLocation(); + int arrow_size = 10; + float arrow_strech = 0.5; + + draw_list->AddTriangleFilled(ImVec2(winpos.x + winsize.x / 2 - arrow_size * arrow_strech, winpos.y + winsize.y / 2 ), + ImVec2(winpos.x + winsize.x / 2 + arrow_size * arrow_strech, winpos.y + winsize.y / 2 ), + ImVec2(winpos.x + winsize.x / 2, winpos.y + winsize.y / 2 - arrow_size), + ImColor(255, 0, 0, 255) + ); + + for (auto &unit : Mgr.GetUnitList()) + { + if (unit.GetHealth() == 0) + continue; + + if (text_filter != "" && str_toupper(unit.GetName()).find(text_filter) == std::string::npos) + continue; + + Vector3f rel_pos = unit.GetLocation().sub(my_loc); + rel_pos = rel_pos.mult(sldr_zoom); + + Vector2f rel2d{rel_pos.x, rel_pos.y}; + + + //printf("yaw %f\n",yaw); + try + { + + float yaw = WOWObjectManager().GetLocalPlayer().GerRotation(); + + rel2d = rel2d.rot(-yaw + deg2rad(90)); + rel2d.y *= -1; + } + catch(const std::exception& e) + { + std::cerr << e.what() << '\n'; + printf("%s\n",e.what()); + continue; + } + + + + Vector2f pos2d{ + (winpos.x + winsize.x / 2 + rel2d.x * scale_x), + (winpos.y + winsize.y / 2 + rel2d.y * scale_y)}; + + draw_list->AddCircleFilled(ImVec2(pos2d.x, pos2d.y), 2, ImColor(255, 100, 255, 255)); + if(chxb_draw_names) + draw_list->AddText(ImVec2(pos2d.x, pos2d.y), ImColor(255, 100, 255, 255), unit.GetName().c_str()); + } + } + +public: + float sldr_zoom = 0.5; + char txtb_textfilter[200]; + bool chxb_draw_names; + + void Draw() + { + ImGui::Begin("Radar", NULL, ImVec2(200, 200), 0.2f); + ImGui::InputText("Filter", txtb_textfilter, 200); + ImGui::SameLine(); + if(ImGui::Button("clear")) txtb_textfilter[0] = '\0'; + ImGui::SliderFloat("scale", &sldr_zoom, 0.01f, 2.0f); + ImGui::SameLine(); + ImGui::Checkbox("draw names",&chxb_draw_names); + + DrawUnits(); + + ImGui::End(); + } +}; + +#endif //WOWCPP_RADAR_H diff --git a/src/Utils.h b/src/Utils.h new file mode 100644 index 0000000..be38e4d --- /dev/null +++ b/src/Utils.h @@ -0,0 +1,181 @@ +// +// Created by alex on 14.06.19. +// + +#ifndef WOWCPP_UTILS_H +#define WOWCPP_UTILS_H + +#include +#include +#include +#include + +#define __stdcall __attribute__((stdcall)) +#define __fastcall __attribute__((fastcall)) +#define __thiscall __attribute__((thiscall)) +#define __cdecl __attribute__((__cdecl__)) + +float rad2deg(float rad) +{ + return rad * 180.0f / M_PI; +} +float deg2rad(float deg) +{ + return deg * M_PI / 180.0f; +} + +struct Vector3f +{ + float x, y, z; + + Vector3f sub(Vector3f v) + { + return Vector3f{x - v.x, y - v.y, z - v.z}; + } + + Vector3f add(Vector3f v) + { + return Vector3f{x + v.x, y + v.y, z + v.z}; + } + Vector3f mult(float s) + { + return Vector3f{x * s, y * s, z * s}; + } + float len() + { + using namespace std; + return (float)sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2)); + } + + float dist(Vector3f v) + { + return sub(v).len(); + } + + Vector3f norm() + { + return mult(1.0f / len()); + } + + /** + * @brief Project this vector to v + * + * @param v + * @return float + */ + float dot(Vector3f v) + { + return x * v.x + y * v.y + z * v.z; + } + + float angle(Vector3f v) + { + return std::acos((dot(v)) / (len() * v.len())); + } + std::string str() + { + return "(" + std::to_string(x) + "|" + std::to_string(y) + "|" + std::to_string(z) + ")"; + } + + Vector3f cross(Vector3f b) + { + auto a = *this; + return { + a.y * b.z - a.z * b.y , + a.z * b.x - a.x * b.z, + a.x * b.y - a.y * b.x + + }; + } +}; + +struct Vector2f +{ + float x, y; + + Vector2f sub(Vector2f v) + { + return Vector2f{x - v.x, y - v.y}; + } + + Vector2f add(Vector2f v) + { + return Vector2f{x + v.x, y + v.y}; + } + Vector2f mult(float s) + { + return Vector2f{x * s, y * s}; + } + float len() + { + using namespace std; + return (float)sqrt(pow(x, 2) + pow(y, 2)); + } + + float dist(Vector2f v) + { + return sub(v).len(); + } + + float dot(Vector2f v) + { + return x * v.x + y * v.y; + } + + float angle(Vector2f v) + { + return std::atan(dot(v) / (len() + v.len())); + } + + Vector2f rot(float a) + { + using namespace std; + return Vector2f{ + cos(a) * x - sin(a) * y, + sin(a) * x + cos(a) * y}; + } + + std::string str() + { + return "(" + std::to_string(x) + "|" + std::to_string(y) + ")"; + } +}; + + +std::string str_toupper(std::string data) +{ + //https://stackoverflow.com/a/313990/4520565 + std::transform(data.begin(), data.end(), data.begin(), + [](unsigned char c) { return std::toupper(c); }); + return data; +} + +template +T Read(uint address) +{ + return *reinterpret_cast(address); +} + +template +void Write(uint address, T value) +{ + *reinterpret_cast(address) = value; +} + +template +T Read(uint address, std::vector offsets) +{ + for (auto offset : offsets) + address = Read(address + offset); + return Read(address); +} + +template +Cont filter(const Cont &container, Pred predicate) +{ + Cont result; + std::copy_if(container.begin(), container.end(), std::back_inserter(result), predicate); + return result; +} + +#endif \ No newline at end of file diff --git a/src/WindowUtils.h b/src/WindowUtils.h new file mode 100644 index 0000000..7db1161 --- /dev/null +++ b/src/WindowUtils.h @@ -0,0 +1,149 @@ +// +// Created by alex on 24.06.19. +// +// ref https://gist.github.com/kui/2622504 + +#ifndef WOWCPP_WINDOWUTILS_H +#define WOWCPP_WINDOWUTILS_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +Window GetFocusWindow(){ + static Display* d = XOpenDisplay(NULL); + int revert_to; + Window w; + XGetInputFocus(d, &w, &revert_to); + return w; +} + +std::string GetWindowName(Window window){ + static Display* d = XOpenDisplay(NULL); + static int screen = DefaultScreen(d); + static Window root_win = RootWindow(d, screen); + + XTextProperty prop; + if(root_win == window) + return ""; + if(XGetWMName(d, window, &prop)) { + int count = 0, result; + char **list = NULL; + result = XmbTextPropertyToTextList(d, &prop, &list, &count); // see man + if(result == Success){ + return std::string(list[0]); + } + } + return ""; +} + +void GetRelativeMousePosition(Window window, int& x, int& y){ + static Display* d = XOpenDisplay(NULL); + static int screen = DefaultScreen(d); + + static Window root_win = RootWindow(d, screen); + + int root_x,root_y; + unsigned int mask; + if(window == root_win) + return; + Window w1, w2; + XQueryPointer(d, window,&w1, &w2, &root_x, &root_y,&x, &y, &mask); +} + +void GetWindowSize(Window win,unsigned int& width, unsigned int& height){ + static Display* d = XOpenDisplay(NULL); + static int screen = DefaultScreen(d); + int loc_x, loc_y; + //static Window root_win = RootWindow(d, screen); + Window win_return; + unsigned int border_width_return; + unsigned int depth_return; + XGetGeometry(d,win,&win_return,&loc_x,&loc_y, &width,&height, &border_width_return, &depth_return); +} + +struct ButtonMask{ + bool MouseLeftDown; + bool MouseRightDown; + bool MouseRightLeftDOwn; +}; + + +std::vector GetWindowList() { + //https://stackoverflow.com/a/30233345/4520565 + static Display *disp = XOpenDisplay(NULL); + std::vector windows; + Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type; + int form; + unsigned long remain; + unsigned char *list; + unsigned long len; + if (XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, 33, + &type, &form, &len, &remain, &list) == Success) { // XA_WINDOW + for (int i = 0; i < len; i++) + windows.push_back(reinterpret_cast(list)[i]); + } + return windows; +} + +Window GetWindowByName(const std::string& name){ + for(auto w : GetWindowList() ) + if(GetWindowName(w) == name) + return w; + return -1; +} + +/** + * @see https://stackoverflow.com/a/52801588/4520565 + * @param ks + * @return + */ +bool GetKeyState(KeySym ks) { + static Display *dpy = XOpenDisplay(NULL); + char keys_return[32]; + XQueryKeymap(dpy, keys_return); + KeyCode kc2 = XKeysymToKeycode(dpy, ks); + bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7))); + + return isPressed; +} + + + +void GetMouseBtnStatus(bool& btn1, bool& btn2, bool& btn3){ + static Display *display = XOpenDisplay(NULL); + static int screen = DefaultScreen(display); + static Window root_win = RootWindow(display, screen); + + Window root_return, child_return; + int root_x_return, root_y_return; + int win_x_return, win_y_return; + unsigned int mask_return; + + XQueryPointer( + display, + root_win, + &root_return, + &child_return, + &root_x_return, + &root_y_return, + &win_x_return, + &win_y_return, + &mask_return + ); + + btn1 = (mask_return & Button1Mask); + btn2 = (mask_return & Button2Mask); + btn3 = (mask_return & Button3Mask); +} + + +#endif //WOWCPP_WINDOWUTILS_H diff --git a/src/imgui_impl_opengl2.cpp b/src/imgui_impl_opengl2.cpp new file mode 100644 index 0000000..2360578 --- /dev/null +++ b/src/imgui_impl_opengl2.cpp @@ -0,0 +1,244 @@ +// dear imgui: Renderer for OpenGL2 (legacy OpenGL, fixed pipeline) +// This needs to be used along with a Platform Binding (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 in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +// **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) +// 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_ImplGlfwGL2_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 "third_party/imgui/imgui.h" +#include "imgui_impl_opengl2.h" +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#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 +#else +#include +#endif + +// OpenGL Data +static GLuint g_FontTexture = 0; + +// Functions +bool ImGui_ImplOpenGL2_Init() +{ + // Setup back-end capabilities flags + ImGuiIO& io = ImGui::GetIO(); + io.BackendRendererName = "imgui_impl_opengl2"; + return true; +} + +void ImGui_ImplOpenGL2_Shutdown() +{ + ImGui_ImplOpenGL2_DestroyDeviceObjects(); +} + +void ImGui_ImplOpenGL2_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplOpenGL2_CreateDeviceObjects(); +} + +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); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_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); + glEnable(GL_TEXTURE_2D); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + // 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 current shader using the 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) + + // 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. + 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. +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) +// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any 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); + 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* cmd_list = draw_data->CmdLists[n]; + const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; + const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_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(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec4 clip_rect; + clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; + clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; + clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; + clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; + + if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) + { + // Apply scissor/clipping rectangle + glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); + + // Bind texture, Draw + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + } + idx_buffer += pcmd->ElemCount; + } + } + + // 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]); +} + +bool ImGui_ImplOpenGL2_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (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 + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + 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->TexID = (ImTextureID)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplOpenGL2_DestroyFontsTexture() +{ + if (g_FontTexture) + { + ImGuiIO& io = ImGui::GetIO(); + glDeleteTextures(1, &g_FontTexture); + io.Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplOpenGL2_CreateDeviceObjects() +{ + return ImGui_ImplOpenGL2_CreateFontsTexture(); +} + +void ImGui_ImplOpenGL2_DestroyDeviceObjects() +{ + ImGui_ImplOpenGL2_DestroyFontsTexture(); +} diff --git a/src/imgui_impl_opengl2.h b/src/imgui_impl_opengl2.h new file mode 100644 index 0000000..2e3271d --- /dev/null +++ b/src/imgui_impl_opengl2.h @@ -0,0 +1,30 @@ +// dear imgui: Renderer for OpenGL2 (legacy OpenGL, fixed pipeline) +// This needs to be used along with a Platform Binding (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 in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +// **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 + +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(); diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..e654fbf --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,9 @@ +#include "Controller.h" + + +__attribute__((constructor)) +static void init(void) +{ + Controller::Run(); + printf("controller started\n"); +} diff --git a/src/wow/Offsets.h b/src/wow/Offsets.h new file mode 100644 index 0000000..988c70d --- /dev/null +++ b/src/wow/Offsets.h @@ -0,0 +1,110 @@ +// +// Created by alex on 14.06.19. +// +/* + * see https://github.com/ARNFRIED/TrampolineDetours + * + */ + +#ifndef WOWCPP_OFFSETS_H +#define WOWCPP_OFFSETS_H + +#include +#include + +// LocalPlayer PlayerBase +uint32_t PLAYER_BASE = 0x00E29D28; + +//WOW Objectmanager offset list: + +uint32_t OBJ_TABLE = 0x00D43318; +uint32_t OBJ_TABLE_CLIENTCONN_OFFSET = 0x0; +uint32_t OBJ_TABLE_OBJMGR_OFFSET = 0x2218; +uint32_t OBJMGR_LP_GUID_OFFSET = 0xC0; +uint32_t OBJMGR_FIRST_OBJ = 0xAC; + +//WOWObject offset list: + +uint32_t WOWOBJ_NEXT_OBJ_OFFSET = 0x3C; +uint32_t WOWOBJ_GUID_OFFSET = 0x30; +uint32_t WOWOBJ_LOCATION_OFFSET = 0xBF0; +uint32_t WOWOBJ_TYPE_OFFSET = 0x14; +uint32_t WOWOBJ_DESCRIPTOR_OFFSET = 0x8; +uint32_t WOWOBJ_ROTATION = 0xBFC; + +enum WOWObjectType : uint32_t +{ + Object = 0, + Item = 1, + Container = 2, + Unit = 3, + Player = 4, + GameObject = 5, + DynamicObject = 6, + Corpse = 7, + AiGroup = 8, + AreaTrigger = 9, + ListEnd = 205, +}; + +enum ClickToMoveType +{ + FaceTarget = 0x1, + Face = 0x2, + Stop_ThrowsException = 0x3, + Move = 0x4, + NpcInteract = 0x5, + Loot = 0x6, + ObjInteract = 0x7, + FaceOther = 0x8, + Skin = 0x9, + AttackPosition = 0xA, + AttackGuid = 0xB, + ConstantFace = 0xC, + _None = 0xD, + Attack = 0x10, + Idle = 0x13, +}; + +//WOWUnit offset list: + +uint32_t WOWUNIT_NAME_OFFSET_1 = 0xdb8; +uint32_t WOWUNIT_NAME_OFFSET_2 = 0x40; +uint32_t WOWUNIT_HP_OFFSET = 0x70; +uint32_t WOWUNIT_LEVEL_OFFSET = 0x88; + +// Camera + +uint32_t CAMSTRUCT_OFFSET = 0x732c; +uint32_t CAM_ADDRESS = 0x00c6eccc; +uint32_t CAM_SOME_GUID_OFFSET = 0x88; //size 8 bytes + +// Other offsets + +uint32_t VIDEO_RESOLUTION_WIDTH_ADDR = 0x00D6938C; +uint32_t VIDEO_RESOLUTION_HEIGHT_ADDR = 0x00D6938C + 0x4; + +uint32_t WINDOW_WIDTH_OFFSET = 0x00E17FB8; +uint32_t WINDOW_HEIGHT_OFFSET = 0x00E17FB8 + 0x4; + +uint32_t TARGET_GUID_FUNC = 0x004a46a0; +uint32_t LUA_TO_STRING_FUNX = 0x00706C80; + +uint32_t CLIENT_STATUS_TEXT_PTR = 0x00C07CD0; +uint32_t LOGIN_FUNC_PTR = 0x0046E560; //__cdecl (char* user,char*pass) + +uint32_t GET_CAM_OFFSET_FUNC = 0x004ab5b0; +uint32_t MAINLOOP_FUNC2 = 0x00428770; //0x000000000042b42b +uint32_t MAINLOOP_FUNC = 0x00428810; + +// FUNCTIONs + +uint32_t TARGETUNIT_FUNC_ADDR = 0x004a6690; +uint32_t CASTSPELLBYID = 0x006fc520; +uint32_t CASTSPELL_BY_NAME = 0x004c42e0; + + +uint32_t MOUSE_OVER_UNIT_GUID_ADDR = 0x00DDEC78; + +uint32_t TARGET_OBJECT_FUNC = 0x00600960; +#endif //WOWCPP_OFFSETS_H diff --git a/src/wow/WOWCamera.h b/src/wow/WOWCamera.h new file mode 100644 index 0000000..b06b23f --- /dev/null +++ b/src/wow/WOWCamera.h @@ -0,0 +1,69 @@ +#ifndef __WOW_CAMERA_H__ +#define __WOW_CAMERA_H__ + +#include "../Utils.h" +#include + +struct WOWCamera{ + uint32_t BaseAddress; + + WOWCamera(){ + BaseAddress = Read(Read(CAM_ADDRESS) + CAMSTRUCT_OFFSET); + } + + Vector3f Position(){ + Vector3f pos; + pos = Read(BaseAddress + 0x8); + return pos; + } + + Vector3f ViewDirection(){ + Vector3f pos; + pos = Read(BaseAddress + 0x8 + 3 * sizeof(float)); + return pos; + } + + void ViewMatrix(float *mat3x3){ + memcpy((void*)mat3x3,(void*)(BaseAddress + 0x14), 9 * sizeof(float)); + } + + + + float zNear(){ + return Read(BaseAddress + 0x40 -8); + } + + float zFar(){ + return Read(BaseAddress + 0x40 - 4); + } + + Vector2f zPlane() + { + return Vector2f{ zNear(), zFar() }; + } + + + float Fov(){ + return Read(BaseAddress + 0x40); + } + + float Ratio(){ + return Read(BaseAddress + 0x44); + } + + Vector2f FovRatio(){ + return Vector2f{ Fov(), Ratio() }; + } + + void Print(){ + auto pos = Position(); + auto angle = ViewDirection(); + float M[9]; + ViewMatrix(M); + printf("\n", + BaseAddress, pos.x, pos.y, pos.z, angle.x, angle.y, angle.z, + M[0],M[1],M[2],M[3],M[4],M[5],M[6],M[7],M[8] ); + } +}; + +#endif \ No newline at end of file diff --git a/src/wow/WOWClient.h b/src/wow/WOWClient.h new file mode 100644 index 0000000..3f7207c --- /dev/null +++ b/src/wow/WOWClient.h @@ -0,0 +1,38 @@ +#ifndef __WOWCLIENT_H__ +#define __WOWCLIENT_H__ + +#include "Offsets.h" +#include "../Utils.h" + +#include "WOWCamera.h" +#include "WOWObjectManager.h" +#include "WOWFunctions.h" + +struct WOWClient{ + + Vector2f GetVideoResolution(){ + return Vector2f{ + 1.0f * Read(VIDEO_RESOLUTION_WIDTH_ADDR), + 1.0f * Read(VIDEO_RESOLUTION_HEIGHT_ADDR) + }; + } + + Vector2f GetWindowSize(){ + auto size = Vector2f{ + 1.0f * Read(WINDOW_WIDTH_OFFSET), + 1.0f * Read(WINDOW_HEIGHT_OFFSET) + }; + return size; + } + + auto GetCurrentStatus(){ + if(IsInGame()) return std::string("in_game"); + return std::string( (char*)CLIENT_STATUS_TEXT_PTR); + } + + bool IsInGame(){ + return WOWFunctions::GetLocalPlayerPtr() != 0; + } + +}; +#endif \ No newline at end of file diff --git a/src/wow/WOWFunctions.h b/src/wow/WOWFunctions.h new file mode 100644 index 0000000..63a637b --- /dev/null +++ b/src/wow/WOWFunctions.h @@ -0,0 +1,142 @@ + + +#ifndef __WOWFUNCTIONS_H__ +#define __WOWFUNCTIONS_H__ + +#include + +#include "Offsets.h" +#include "../Utils.h" + +class WOWFunctions +{ + +public: + static void TargetUnit(uint64_t guid) + { + auto func = (decltype(TargetUnit) *)TARGETUNIT_FUNC_ADDR; + func(guid); + } + + static void CastSpell(uint64_t spell_id, uint64_t guid) + { + auto func = (void (*)(uint64_t, uint64_t))CASTSPELLBYID; + func(spell_id, guid); + } + + static void CastSpellByName(std::string spell) + { + DoLuaString("CastSpellByName(\"" + spell + "\")"); + } + + static void Login(std::string user, std::string pass) + { + ((void(__cdecl *)(const char *, const char *))0x0046E560)(user.c_str(), pass.c_str()); + } + + static void DoLuaString(std::string command) + { + asm( + "push $0;" //0 + "push %0;" //combat.lua arg0 | push eax + "push %1;" //text arg1 | push ebx + "call %2;" //call arg2 | call ecx + "add $0xC, %%esp;" + : + : "eax"(command.c_str()), "ebx"(command.c_str()), "ecx"(LUA_TO_STRING_FUNX) + :); + } + + static void SendChatMessage(std::string msg) + { + DoLuaString("DEFAULT_CHAT_FRAME:AddMessage(\"" + msg + "\");"); + } + + static void PrintLog(std::string text) + { + // DoLuaString("DEFAULT_CHAT_FRAME:AddMessage('" + text + "', 0.0, 1.0, 0.0);"); + } + + static void PrintCTMFlags() + { + + auto actionType = *(uint32_t *)0xD689BC; + auto timestamp = *(uint32_t *)0xD689B8; + auto Precision = *(float *)0xD689B4; //float, mapped from a named signature, but i cant tell if it actually does anything. + auto pX = *(float *)0xD68A18; //float + auto pY = *(float *)0xD68A1C; //float + auto pZ = *(float *)0xD68A20; //float + auto cX = *(float *)0xD68A18 + 4; //float + auto cY = *(float *)0xD68A1C + 4; //float + auto cZ = *(float *)0xD68A20 + 4; //float + auto ctm_target_guid = *(uint64_t *)0xD689C0; //ulong, interact guid, + + auto unknown1 = *(uint32_t *)0x00d68a14; //always 40100000 + auto unknown2 = *(uint32_t *)0x00d689cc; // always 0 + auto unknown3 = *(uint32_t *)0x00d689d0; // always 0 + + auto ptr = GetLocalPlayerPtr(); + //lbl1 = 3f000000 + // LBL2 = 0 + // + /* + + auto ctm_current_location_y = Read(0x00d68a0c); + auto ctm_current_location_z = Read(0x00d68a10); + auto lbl_ctm_precision = Read(0x00d68a10); + auto ctm_facing = Read(0x00d689a4); //set 415f66f3 while walking | set 40490fdb while standing + auto ctm_flag_alway3f000000 = Read(0x00d689ac); //is now 0x16d30008 + auto ctm_flag_always0 = Read(0x00d68998); + auto ctm_timestamp = Read(0x00d689b8); + printf("3f* %x zero %x face %x clocz %f clocy %f stmp %i type %x prcn %f xyz (%f|%f|%f) cxyz (%f|%f|%f) un1 %i un2 %x un3 %x\n", ctm_flag_alway3f000000, ctm_flag_always0, + ctm_facing, ctm_current_location_z, ctm_current_location_y, ctm_timestamp, actionType, Precision, + pX, pY, pZ, cX, cY, cZ, + unknown1, unknown2, unknown3); + */ + } + + + static void ClickToMove(ClickToMoveType type, uint64_t guid, Vector3f pos, bool walk = true) + { + static bool _walk = true; + if (walk) + { + Write(0x00d689a4, 0x415f66f3); + // _walk = false; + } + else + { + //Write(0x00d689a4, 0x40490fdb); + } + + auto actionType = (uint32_t *)0xD689BC; + auto timestamp = (uint32_t *)0xD689B8; + auto Precision = (float *)0xD689B4; //float, mapped from a named signature, but i cant tell if it actually does anything. + auto positionX = (float *)0xD68A18; //float + auto positionY = (float *)0xD68A1C; //float + auto positionZ = (float *)0xD68A20; //float + auto ClickX = (float *)0xD68A18 + 4; //float + auto ClickY = (float *)0xD68A1C + 4; //float + auto ClickZ = (float *)0xD68A20 + 4; //float + auto ctm_target_guid = (uint64_t *)0xD689C0; //ulong, interact guid, + + *positionX = pos.x; + *positionY = pos.y; + *positionZ = pos.z; + + //*timestamp++; + *actionType = (uint32_t)type; + *Precision = 0.0; + if (guid != 0) + { + *ctm_target_guid = guid; + } + } + + static uint32_t GetLocalPlayerPtr() + { + return ((uint32_t __cdecl(*)())0x00402F40)(); + } +}; + +#endif \ No newline at end of file diff --git a/src/wow/WOWObject.h b/src/wow/WOWObject.h new file mode 100644 index 0000000..8e13b48 --- /dev/null +++ b/src/wow/WOWObject.h @@ -0,0 +1,42 @@ +#ifndef WOWOBJECT_H +#define WOWOBJECT_H + +#include + +#include "Offsets.h" +#include "../Utils.h" + +struct WOWObject{ + uint32_t BaseAddress; + + auto GetNextObjectPtr() const{ + return Read(BaseAddress + WOWOBJ_NEXT_OBJ_OFFSET); + } + + auto GetGuid() const{ + return Read(BaseAddress + WOWOBJ_GUID_OFFSET); + } + + auto GetLocation() const{ + return Read(BaseAddress + WOWOBJ_LOCATION_OFFSET); + } + + auto GetType() const{ + return Read(BaseAddress + WOWOBJ_TYPE_OFFSET); + } + + auto GetDescriptor() { + return Read(BaseAddress + WOWOBJ_DESCRIPTOR_OFFSET); + } + + void Print(){ + printf("\n",BaseAddress,GetType(),GetGuid()); + } + + auto GerRotation() const{ + return Read(BaseAddress + WOWOBJ_ROTATION); + } +}; + + +#endif \ No newline at end of file diff --git a/src/wow/WOWObjectManager.h b/src/wow/WOWObjectManager.h new file mode 100644 index 0000000..5f45aa2 --- /dev/null +++ b/src/wow/WOWObjectManager.h @@ -0,0 +1,107 @@ +// +// Created by alex on 14.06.19. +// + +#ifndef WOWCPP_OBJECTMANAGER_H +#define WOWCPP_OBJECTMANAGER_H + +#include +#include + +#include "Offsets.h" +#include "WOWObject.h" +#include "WOWPlayer.h" +#include "WOWUnit.h" +#include "../Utils.h" + +struct WOWObjectManager +{ + + uint32_t BaseAddress; + + WOWObjectManager() + { + BaseAddress = Read((Read(OBJ_TABLE) + OBJ_TABLE_OBJMGR_OFFSET)); + } + + auto GetLocalPlayerGUID() const + { + return Read(BaseAddress + OBJMGR_LP_GUID_OFFSET); + } + + auto GetFirstObject() const + { + return WOWObject{Read(BaseAddress + OBJMGR_FIRST_OBJ)}; + } + + auto GetObjectList() const + { + std::vector list; + WOWObject currentObj = GetFirstObject(); + + while (currentObj.BaseAddress != 0 && (currentObj.BaseAddress & 1) == 0) + { + list.push_back(currentObj); + currentObj = WOWObject{currentObj.GetNextObjectPtr()}; + + } + return list; + } + + auto GetObjectList(WOWObjectType type) const + { + return filter(GetObjectList(), [type](WOWObject a) { return a.GetType() == type; }); + } + + auto GetUnitList() const + { + std::vector units; + for (auto &unit : GetObjectList(WOWObjectType::Unit)) + units.push_back((WOWUnit &)(unit)); + return units; + } + + auto GetPlayerList() const + { + std::vector units; + for (auto &unit : GetObjectList(WOWObjectType::Player)) + units.push_back((WOWPlayer &)(unit)); + return units; + } + + auto GetLocalPlayer() const + { + auto local_guid = GetLocalPlayerGUID(); + printf("local_guid %x\n",local_guid); + auto items = filter(GetObjectList(), [local_guid](WOWObject a) { return a.GetGuid() == local_guid; }); + + return (WOWPlayer&)items[0]; + } + + auto GetDynamicObjectList() const + { + std::vector objs; + for (auto &obj : GetObjectList(WOWObjectType::DynamicObject)) + objs.push_back((WOWObject &)(obj)); + return objs; + } + + auto GetGameObjectList() const + { + std::vector objs; + for (auto &obj : GetObjectList(WOWObjectType::GameObject)) + objs.push_back((WOWObject &)(obj)); + return objs; + } + + bool GetObjectByGuid(uint64_t guid, WOWObject& obj){ + auto objs = filter(GetObjectList(), [guid](auto obj) -> bool{return obj.GetGuid() == guid;}); + if(objs.size() > 0){ + obj = objs[0]; + return true; + } + return false; + } +}; + +#endif //WOWCPP_OBJECTMANAGER_H diff --git a/src/wow/WOWPlayer.h b/src/wow/WOWPlayer.h new file mode 100644 index 0000000..5927ab5 --- /dev/null +++ b/src/wow/WOWPlayer.h @@ -0,0 +1,10 @@ +#ifndef __WOWPLAYER_H__ +#define __WOWPLAYER_H__ + +#include "WOWObject.h" + +struct WOWPlayer : public WOWObject { + +}; + +#endif \ No newline at end of file diff --git a/src/wow/WOWUnit.h b/src/wow/WOWUnit.h new file mode 100644 index 0000000..c5b9451 --- /dev/null +++ b/src/wow/WOWUnit.h @@ -0,0 +1,37 @@ +#ifndef __WOWUNIT_H__ +#define __WOWUNIT_H__ + +#include "WOWObject.h" + +struct WOWUnit : public WOWObject{ + + auto GetName(){ + auto name_ptr = Read(BaseAddress + WOWUNIT_NAME_OFFSET_1); + if(name_ptr == 0) return std::string("?"); + auto c_name = Read(name_ptr + WOWUNIT_NAME_OFFSET_2); + return std::string(c_name); + } + + auto GetNamePtr(){ + auto name_ptr = Read(BaseAddress + WOWUNIT_NAME_OFFSET_1); + if(name_ptr == 0) return "?"; + auto c_name = Read(name_ptr + WOWUNIT_NAME_OFFSET_2); + return c_name; + } + + auto GetHealth(){ + return Read(GetDescriptor() + WOWUNIT_HP_OFFSET); + } + + auto GetLevel(){ + return Read(GetDescriptor() + WOWUNIT_LEVEL_OFFSET); + } + + void Print() { + printf("\n",BaseAddress,GetType(),GetGuid(), GetName().c_str()); + } +}; + + + +#endif \ No newline at end of file