diff --git a/src/commands/event.h b/src/commands/event.h index e960404..58460c5 100644 --- a/src/commands/event.h +++ b/src/commands/event.h @@ -5,7 +5,7 @@ class EventCommand : public ICommand { public: - std::array m_Hints = { + std::array m_Hints = { "__showfps", "__reload_world", "ply.invulnerable", @@ -16,6 +16,12 @@ class EventCommand : public ICommand "ply.pause", "ply.unpause", "ply.vehicle.burn", + "ply.jesus.enable", + "ply.jesus.disable", + "ply.bavarium.upgrade.enable", + "ply.bavarium.upgrade.disable", + "ply.lacrima.forcefield.enable", + "ply.lacrima.forcefield.disable", "debug.vehicle.incrementtint", "vocals.rico.enable", "vocals.rico.disable", diff --git a/src/commands/spawn.h b/src/commands/spawn.h index 2187431..d47ee2e 100644 --- a/src/commands/spawn.h +++ b/src/commands/spawn.h @@ -22,7 +22,7 @@ class SpawnCommand : public ICommand #pragma pack(pop) public: - inline static std::vector m_Hints = {}; + inline static std::set m_Hints = {}; virtual const char *GetCommand() override { @@ -39,7 +39,7 @@ class SpawnCommand : public ICommand add_event_hook.call(file, &model, 0xF71C2A21); if (model.entry) { - m_Hints.emplace_back((char *)(model.base + model.entry->data)); + m_Hints.insert((char *)(model.base + model.entry->data)); } return add_event_hook.call(file, buf, hash); diff --git a/src/commands/world.h b/src/commands/world.h index 9e4c517..6f76af3 100644 --- a/src/commands/world.h +++ b/src/commands/world.h @@ -8,8 +8,6 @@ class WorldCommand : public ICommand std::array m_Hints = { "time", "timescale", - //"gravity", - //"resetgravity", }; virtual const char* GetCommand() override @@ -19,8 +17,7 @@ class WorldCommand : public ICommand virtual bool Handler(const std::string& arguments) override { - //static auto World = *(void**)0x142A8D430; - static auto WorldTime = *(void**)0x142F17250; // 1 + static auto WorldTime = *(void**)0x142F17250; // time if (arguments.find("time ") != std::string::npos) { @@ -39,21 +36,6 @@ class WorldCommand : public ICommand return true; } } -#if 0 - // gravity - else if (arguments.find("gravity ") != std::string::npos) { - float gravity = -9.810f; - if (sscanf_s(arguments.c_str(), "gravity %f", &gravity) == 1) { - *(float*)((char*)World + 0x974) = std::clamp(gravity, -5000.0f, 5000.0f); - return true; - } - } - // reset gravity - else if (arguments.find("resetgravity") != std::string::npos) { - *(float*)((char*)World + 0x974) = -9.810f; - return true; - } -#endif return false; } diff --git a/src/game/device.h b/src/game/device.h index d224d3a..a41a9a0 100644 --- a/src/game/device.h +++ b/src/game/device.h @@ -8,11 +8,11 @@ namespace jc class HDevice_t { public: - char _pad[0x28]; - ID3D11Device* m_device; - char _pad2[0x170]; - int32_t m_screenWidth; - int32_t m_screenHeight; + char _pad[0x28]; + ID3D11Device* m_device; + char _pad2[0x170]; + int32_t m_screenWidth; + int32_t m_screenHeight; }; }; // namespace jc #pragma pack(pop) diff --git a/src/game/input_manager.h b/src/game/input_manager.h new file mode 100644 index 0000000..796353c --- /dev/null +++ b/src/game/input_manager.h @@ -0,0 +1,19 @@ +#pragma once + +#pragma pack(push, 1) +namespace jc::Input +{ +class CInputDeviceManager +{ + public: + static CInputDeviceManager& instance() + { + return **(CInputDeviceManager**)0x142E2B6F8; + } + + public: + char _pad[0x70]; + bool m_hasFocus; +}; +}; // namespace jc::Input +#pragma pack(pop) diff --git a/src/game/player.h b/src/game/player.h index 83805fe..50a31db 100644 --- a/src/game/player.h +++ b/src/game/player.h @@ -15,7 +15,8 @@ class CPlayerAimControl class CPlayer { public: - // NOTE(aaron): -16 bytes because we don't cast from CAvatar in CNetworkPlayer + // NOTE(aaron): everything here is out of alignment by 16 bytes because we + // don't use CAvatar in CNetworkPlayer char _pad[0x100]; CCharacter* m_character; char _pad2[0x40]; diff --git a/src/game/player_manager.h b/src/game/player_manager.h index a721495..4c974c9 100644 --- a/src/game/player_manager.h +++ b/src/game/player_manager.h @@ -8,13 +8,11 @@ namespace jc class CNetworkPlayer { public: - char _pad[0x128]; - std::shared_ptr m_player; + char _pad[0x128]; + std::shared_ptr m_player; std::shared_ptr m_character; }; -static_assert(offsetof(CNetworkPlayer, m_character) == 0x138, "borked"); - class CNetworkPlayerManager { public: diff --git a/src/game/render_engine.h b/src/game/render_engine.h deleted file mode 100644 index 1d7d9ed..0000000 --- a/src/game/render_engine.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "debug_renderer_impl.h" - -#pragma pack(push, 1) -namespace jc -{ -class CRenderEngine -{ - public: - static CRenderEngine& instance() - { - return **(CRenderEngine**)0x142A201A8; - } - - public: - char _pad[0x2BB0]; - DebugRendererImpl* m_debugRenderer; -}; -}; // namespace jc -#pragma pack(pop) diff --git a/src/graphics.h b/src/graphics.h index f80527b..605a0d1 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -29,9 +29,9 @@ class Graphics : public Singleton m_ready = false; m_state.releaseSavedState(); - if (m_context) { + if (m_context) { m_context->Release(); - } + } if (m_font) { m_font->Release(); diff --git a/src/input.cpp b/src/input.cpp index 8e07ce7..0171fe4 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -9,18 +9,24 @@ #include "game/debug_renderer.h" #include "game/graphics_engine.h" +#include "game/input_manager.h" #include "game/ui_manager.h" static const int32_t _numHintsPerPage = 10; -void Input::EnableInput(bool toggle) +void Input::FocusChanged(bool lost_focus) { - static void *input_thingy = nullptr; - if (!input_thingy) { - input_thingy = *(void **)0x142E2B6F8; - m_history.push_back(""); + m_hasFocus = !lost_focus; + + // if we are drawing input and regained focus, lock the input once again + // as the game will unlock it automatically + if (m_drawInput && !lost_focus) { + jc::Input::CInputDeviceManager::instance().m_hasFocus = false; } +} +void Input::EnableInput(bool toggle) +{ m_drawInput = toggle; m_currentHistory = 0; m_selectedHint = -1; @@ -30,7 +36,7 @@ void Input::EnableInput(bool toggle) jc::CUIManager().instance().m_active = !toggle; // freeze input - *(bool *)((char *)input_thingy + 0x70) = !toggle; + jc::Input::CInputDeviceManager::instance().m_hasFocus = !toggle; } void Input::Draw() @@ -74,7 +80,23 @@ void Input::Draw() bool Input::WndProc(uint32_t message, WPARAM wParam, LPARAM lParam) { + if (!m_hasFocus) { + return false; + } + switch (message) { + // fix ESC key still getting passed to the game when closing the input window + // this is because EnableInput will give focus back to the input manager and + // if we leave it on KEYDOWN the game will then see the ESC key as down + case WM_KEYUP: { + if (wParam == VK_ESCAPE && m_selectedHint == -1 && m_history[0].size() == 0) { + EnableInput(false); + return true; + } + + break; + } + case WM_KEYDOWN: { // tilde key down and the previous key state was up const auto vsc = MapVirtualKeyEx(static_cast(wParam), MAPVK_VK_TO_VSC, GetKeyboardLayout(0)); @@ -107,8 +129,6 @@ bool Input::WndProc(uint32_t message, WPARAM wParam, LPARAM lParam) m_cmdArguments = ""; m_currentHistory = 0; m_hints.clear(); - } else { - EnableInput(false); } } else { m_selectedHint = -1; diff --git a/src/input.h b/src/input.h index 09e95dd..c4f4e94 100644 --- a/src/input.h +++ b/src/input.h @@ -17,8 +17,8 @@ class Input : public Singleton using command_t = std::function; private: - bool m_drawInput = false; - std::vector m_history; + bool m_drawInput = false; + std::vector m_history = {""}; int32_t m_currentHistory = 0; ICommand* m_cmd = nullptr; std::string m_cmdText = ""; @@ -26,6 +26,7 @@ class Input : public Singleton std::vector m_hints; int32_t m_selectedHint = -1; int32_t m_hintPage = 0; + bool m_hasFocus = true; std::unordered_map> m_commands; std::unordered_map m_fnCommands; @@ -37,6 +38,8 @@ class Input : public Singleton Input() = default; virtual ~Input() = default; + void FocusChanged(bool lost_focus); + void RegisterCommand(std::unique_ptr cmd) { cmd->Initialize(); diff --git a/src/main.cpp b/src/main.cpp index 876b644..da9f5a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -75,6 +75,20 @@ HRESULT D3D11CreateDevice(IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE Drive HWND hwnd = *(HWND *)0x142E22A18; WndProc_orig = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc); + // focus lost + static hk::inject_call lose_focus(0x143218620); + lose_focus.inject([](HWND hwnd, bool a2) { + lose_focus.call(hwnd, a2); + Input::Get()->FocusChanged(true); + }); + + // focus gained + static hk::inject_call gain_focus(0x143218611); + gain_focus.inject([](HWND hwnd) { + gain_focus.call(); + Input::Get()->FocusChanged(false); + }); + static hk::inject_call flip(0x1432E0071); flip.inject([](jc::HDevice_t *device) { Graphics::Get()->BeginDraw(device); diff --git a/src/vector.h b/src/vector.h index 4b98526..74dde0f 100644 --- a/src/vector.h +++ b/src/vector.h @@ -11,15 +11,15 @@ struct CVector3f { struct CVector4f { float x, y, z, w; - static CVector4f FromARGB(const uint32_t hex) - { + static CVector4f FromARGB(const uint32_t hex) + { CVector4f result; result.w = ((hex >> 24) & 0xFF) / 255.0f; result.x = ((hex >> 16) & 0xFF) / 255.0f; result.y = ((hex >> 8) & 0xFF) / 255.0f; result.z = (hex & 0xFF) / 255.0f; return result; - } + } }; struct CMatrix4f { diff --git a/src/xinput9_1_0.h b/src/xinput9_1_0.h index a09d878..1712e1e 100644 --- a/src/xinput9_1_0.h +++ b/src/xinput9_1_0.h @@ -25,4 +25,4 @@ __declspec(dllexport) DWORD XInputSetState(DWORD dwUserIndex, uintptr_t pVibrati return E_FAIL; } -}; // namespace \ No newline at end of file +}; // namespace