mirror of
https://github.com/EricPlayZ/EGameTools.git
synced 2025-07-18 17:37:53 +08:00
fixed zoom-in issues, fixed Player Variables performance in Debug mode, cleaned up code
This commit is contained in:
@ -19,5 +19,7 @@ namespace EGSDK::Engine {
|
||||
|
||||
void SetFOV(float fov);
|
||||
void SetPosition(const Vector3* pos);
|
||||
|
||||
static bool isSetFOVCalledByEGT;
|
||||
};
|
||||
}
|
@ -68,45 +68,41 @@ namespace EGSDK::GamePH {
|
||||
void SetValues(bool value);
|
||||
};
|
||||
|
||||
class EGameSDK_API PlayerVarVector {
|
||||
class EGameSDK_API PlayerVarMap {
|
||||
public:
|
||||
PlayerVarVector() = default;
|
||||
PlayerVarVector(const PlayerVarVector&) = delete;
|
||||
PlayerVarVector& operator=(const PlayerVarVector&) = delete;
|
||||
PlayerVarMap() = default;
|
||||
PlayerVarMap(const PlayerVarMap&) = delete;
|
||||
PlayerVarMap& operator=(const PlayerVarMap&) = delete;
|
||||
|
||||
PlayerVarVector(PlayerVarVector&&) noexcept = default;
|
||||
PlayerVarVector& operator=(PlayerVarVector&&) noexcept = default;
|
||||
PlayerVarMap(PlayerVarMap&&) noexcept = default;
|
||||
PlayerVarMap& operator=(PlayerVarMap&&) noexcept = default;
|
||||
|
||||
std::unique_ptr<PlayerVariable>& emplace_back(std::unique_ptr<PlayerVariable> playerVar);
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator beginUnsafe();
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator endUnsafe();
|
||||
std::unique_ptr<PlayerVariable>& try_emplace(std::unique_ptr<PlayerVariable> playerVar);
|
||||
bool empty();
|
||||
bool none_of(const std::string& name);
|
||||
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator FindIter(const std::string& name);
|
||||
std::unique_ptr<PlayerVariable>* FindPtr(const std::string& name);
|
||||
PlayerVariable* Find(const std::string& name);
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator Erase(const std::string& name);
|
||||
bool Erase(const std::string& name);
|
||||
|
||||
template <typename Callable, typename... Args>
|
||||
void ForEach(Callable&& func, Args&&... args) {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
for (auto& playerVar : _playerVars)
|
||||
func(playerVar, std::forward<Args>(args)...);
|
||||
for (const auto& name : _order)
|
||||
func(_playerVars.at(name), std::forward<Args>(args)...);
|
||||
}
|
||||
private:
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator FindIterUnsafe(const std::string& name);
|
||||
|
||||
std::vector<std::unique_ptr<PlayerVariable>> _playerVars{};
|
||||
std::unordered_map<std::string, std::unique_ptr<PlayerVariable>> _playerVars{};
|
||||
std::vector<std::string> _order{};
|
||||
mutable std::mutex _mutex{};
|
||||
};
|
||||
|
||||
class EGameSDK_API PlayerVariables {
|
||||
public:
|
||||
static PlayerVarVector playerVars;
|
||||
static PlayerVarVector customPlayerVars;
|
||||
static PlayerVarVector defaultPlayerVars;
|
||||
static PlayerVarVector customDefaultPlayerVars;
|
||||
static PlayerVarMap playerVars;
|
||||
static PlayerVarMap customPlayerVars;
|
||||
static PlayerVarMap defaultPlayerVars;
|
||||
static PlayerVarMap customDefaultPlayerVars;
|
||||
static std::atomic<bool> gotPlayerVars;
|
||||
|
||||
static std::unordered_map<std::string, std::any> prevPlayerVarValueMap;
|
||||
|
@ -170,6 +170,10 @@ namespace EGSDK::Utils {
|
||||
for (const auto& callback : callbacks)
|
||||
callback(args...);
|
||||
}
|
||||
auto ExecuteCallbacksWithOriginal(Args... args) {
|
||||
ExecuteCallbacks(args...);
|
||||
return pOriginal(args...);
|
||||
}
|
||||
|
||||
OrigType pOriginal = nullptr;
|
||||
OrigType pTarget = nullptr;
|
||||
@ -227,6 +231,10 @@ namespace EGSDK::Utils {
|
||||
for (const auto& callback : callbacks)
|
||||
callback(args...);
|
||||
}
|
||||
auto ExecuteCallbacksWithOriginal(Args... args) {
|
||||
ExecuteCallbacks(args...);
|
||||
return pOriginal(args...);
|
||||
}
|
||||
|
||||
OrigType pOriginal = nullptr;
|
||||
private:
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <EGSDK\Utils\Memory.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
bool CBaseCamera::isSetFOVCalledByEGT = false;
|
||||
|
||||
float CBaseCamera::GetFOV() {
|
||||
return Utils::Memory::SafeCallFunction<float>("engine_x64_rwdi.dll", "?GetFOV@IBaseCamera@@QEBAMXZ", -1.0f, this);
|
||||
}
|
||||
@ -20,7 +22,9 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
|
||||
void CBaseCamera::SetFOV(float fov) {
|
||||
isSetFOVCalledByEGT = true;
|
||||
Utils::Memory::SafeCallFunctionVoid("engine_x64_rwdi.dll", "?SetFOV@IBaseCamera@@QEAAXM@Z", this, fov);
|
||||
isSetFOVCalledByEGT = false;
|
||||
}
|
||||
void CBaseCamera::SetPosition(const Vector3* pos) {
|
||||
Utils::Memory::SafeCallFunctionVoid("engine_x64_rwdi.dll", "?SetPosition@IBaseCamera@@QEAAXAEBVvec3@@@Z", this, pos);
|
||||
|
@ -90,64 +90,42 @@ namespace EGSDK::GamePH {
|
||||
this->defaultValue = value;
|
||||
}
|
||||
|
||||
std::unique_ptr<PlayerVariable>& PlayerVarVector::emplace_back(std::unique_ptr<PlayerVariable> playerVar) {
|
||||
std::unique_ptr<PlayerVariable>& PlayerVarMap::try_emplace(std::unique_ptr<PlayerVariable> playerVar) {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
_playerVars.emplace_back(std::move(playerVar));
|
||||
return _playerVars.back();
|
||||
const std::string& name = playerVar->GetName();
|
||||
auto [it, inserted] = _playerVars.try_emplace(name, std::move(playerVar));
|
||||
if (inserted)
|
||||
_order.emplace_back(name);
|
||||
return it->second;
|
||||
}
|
||||
// Unsafe function: Assumes the caller has locked _mutex
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::beginUnsafe() {
|
||||
return _playerVars.begin();
|
||||
}
|
||||
// Unsafe function: Assumes the caller has locked _mutex
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::endUnsafe() {
|
||||
return _playerVars.end();
|
||||
}
|
||||
bool PlayerVarVector::empty() {
|
||||
bool PlayerVarMap::empty() {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return _playerVars.empty();
|
||||
}
|
||||
bool PlayerVarVector::none_of(const std::string& name) {
|
||||
bool PlayerVarMap::none_of(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return std::none_of(_playerVars.begin(), _playerVars.end(), [&name](const auto& playerVar) {
|
||||
return playerVar->GetName() == name;
|
||||
});
|
||||
return _playerVars.find(name) == _playerVars.end();
|
||||
}
|
||||
|
||||
// Unsafe function: Assumes the caller has locked _mutex
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::FindIterUnsafe(const std::string& name) {
|
||||
return std::find_if(_playerVars.begin(), _playerVars.end(), [&name](const auto& playerVar) {
|
||||
return playerVar->GetName() == name;
|
||||
});
|
||||
}
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::FindIter(const std::string& name) {
|
||||
std::unique_ptr<PlayerVariable>* PlayerVarMap::FindPtr(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
return std::find_if(_playerVars.begin(), _playerVars.end(), [&name](const auto& playerVar) {
|
||||
return playerVar->GetName() == name;
|
||||
});
|
||||
auto it = _playerVars.find(name);
|
||||
return it == _playerVars.end() ? nullptr : &it->second;
|
||||
}
|
||||
std::unique_ptr<PlayerVariable>* PlayerVarVector::FindPtr(const std::string& name) {
|
||||
PlayerVariable* PlayerVarMap::Find(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
auto playerVarIt = FindIterUnsafe(name);
|
||||
return playerVarIt == _playerVars.end() ? nullptr : &*playerVarIt;
|
||||
auto it = _playerVars.find(name);
|
||||
return it == _playerVars.end() ? nullptr : it->second.get();
|
||||
}
|
||||
PlayerVariable* PlayerVarVector::Find(const std::string& name) {
|
||||
bool PlayerVarMap::Erase(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
auto playerVarIt = FindIterUnsafe(name);
|
||||
return playerVarIt == _playerVars.end() ? nullptr : playerVarIt->get();
|
||||
}
|
||||
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::Erase(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
auto playerVarIt = FindIterUnsafe(name);
|
||||
if (playerVarIt != _playerVars.end())
|
||||
return _playerVars.erase(playerVarIt);
|
||||
return _playerVars.end();
|
||||
return _playerVars.erase(name) > 0;
|
||||
}
|
||||
|
||||
PlayerVarVector PlayerVariables::playerVars{};
|
||||
PlayerVarVector PlayerVariables::customPlayerVars{};
|
||||
PlayerVarVector PlayerVariables::defaultPlayerVars{};
|
||||
PlayerVarVector PlayerVariables::customDefaultPlayerVars{};
|
||||
PlayerVarMap PlayerVariables::playerVars{};
|
||||
PlayerVarMap PlayerVariables::customPlayerVars{};
|
||||
PlayerVarMap PlayerVariables::defaultPlayerVars{};
|
||||
PlayerVarMap PlayerVariables::customDefaultPlayerVars{};
|
||||
std::atomic<bool> PlayerVariables::gotPlayerVars = false;
|
||||
static bool sortedPlayerVars = false;
|
||||
|
||||
@ -155,24 +133,24 @@ namespace EGSDK::GamePH {
|
||||
std::unordered_map<std::string, bool> PlayerVariables::prevBoolValueMap{};
|
||||
|
||||
template <typename T>
|
||||
static void updateDefaultVar(PlayerVarVector& defaultVars, const std::string& name, T value, T defaultValue) {
|
||||
static void updateDefaultVar(PlayerVarMap& defaultVars, const std::string& name, T value, T defaultValue) {
|
||||
static_assert(std::is_same_v<T, std::string> || std::is_same_v<T, float> || std::is_same_v<T, bool>, "Invalid type: value must be string, float or bool");
|
||||
|
||||
auto playerVar = defaultVars.Find(name);
|
||||
if (!playerVar) {
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
auto stringPlayerVar = std::make_unique<StringPlayerVariable>(name);
|
||||
defaultVars.emplace_back(std::move(stringPlayerVar));
|
||||
defaultVars.try_emplace(std::move(stringPlayerVar));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, float>) {
|
||||
auto floatPlayerVar = std::make_unique<FloatPlayerVariable>(name);
|
||||
floatPlayerVar->SetValues(value);
|
||||
defaultVars.emplace_back(std::move(floatPlayerVar));
|
||||
defaultVars.try_emplace(std::move(floatPlayerVar));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, bool>) {
|
||||
auto boolPlayerVar = std::make_unique<BoolPlayerVariable>(name);
|
||||
boolPlayerVar->SetValues(value);
|
||||
defaultVars.emplace_back(std::move(boolPlayerVar));
|
||||
defaultVars.try_emplace(std::move(boolPlayerVar));
|
||||
}
|
||||
} else {
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
@ -381,16 +359,16 @@ namespace EGSDK::GamePH {
|
||||
PlayerVarType playerVarType = getPlayerVarType(funcAddress, startOfFunc);
|
||||
switch (playerVarType) {
|
||||
case PlayerVarType::String:
|
||||
playerVars.emplace_back(std::make_unique<StringPlayerVariable>(playerVarName));
|
||||
playerVars.try_emplace(std::make_unique<StringPlayerVariable>(playerVarName));
|
||||
break;
|
||||
case PlayerVarType::Float:
|
||||
playerVars.emplace_back(std::make_unique<FloatPlayerVariable>(playerVarName));
|
||||
playerVars.try_emplace(std::make_unique<FloatPlayerVariable>(playerVarName));
|
||||
break;
|
||||
case PlayerVarType::Bool:
|
||||
playerVars.emplace_back(std::make_unique<BoolPlayerVariable>(playerVarName));
|
||||
playerVars.try_emplace(std::make_unique<BoolPlayerVariable>(playerVarName));
|
||||
break;
|
||||
default:
|
||||
//playerVars.emplace_back(std::make_unique<PlayerVariable>(playerVarName));
|
||||
//playerVars.try_emplace(std::make_unique<PlayerVariable>(playerVarName));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -494,9 +472,9 @@ namespace EGSDK::GamePH {
|
||||
if (playerVar->GetType() != PlayerVarType::Float)
|
||||
return;
|
||||
if (!customPlayerVar)
|
||||
customPlayerVar = customPlayerVars.emplace_back(std::make_unique<FloatPlayerVariable>(name)).get();
|
||||
customPlayerVar = customPlayerVars.try_emplace(std::make_unique<FloatPlayerVariable>(name)).get();
|
||||
if (!defPlayerVar) {
|
||||
defPlayerVar = defaultPlayerVars.emplace_back(std::make_unique<FloatPlayerVariable>(name)).get();
|
||||
defPlayerVar = defaultPlayerVars.try_emplace(std::make_unique<FloatPlayerVariable>(name)).get();
|
||||
reinterpret_cast<FloatPlayerVariable*>(defPlayerVar)->SetValues(reinterpret_cast<FloatPlayerVariable*>(playerVar)->value);
|
||||
}
|
||||
|
||||
@ -506,9 +484,9 @@ namespace EGSDK::GamePH {
|
||||
if (playerVar->GetType() != PlayerVarType::Bool)
|
||||
return;
|
||||
if (!customPlayerVar)
|
||||
customPlayerVar = customPlayerVars.emplace_back(std::make_unique<BoolPlayerVariable>(name)).get();
|
||||
customPlayerVar = customPlayerVars.try_emplace(std::make_unique<BoolPlayerVariable>(name)).get();
|
||||
if (!defPlayerVar) {
|
||||
defPlayerVar = defaultPlayerVars.emplace_back(std::make_unique<BoolPlayerVariable>(name)).get();
|
||||
defPlayerVar = defaultPlayerVars.try_emplace(std::make_unique<BoolPlayerVariable>(name)).get();
|
||||
reinterpret_cast<BoolPlayerVariable*>(defPlayerVar)->SetValues(reinterpret_cast<BoolPlayerVariable*>(playerVar)->value);
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
<ClInclude Include="include\EGT\Config\Config.h" />
|
||||
<ClInclude Include="include\EGT\Core\Core.h" />
|
||||
<ClInclude Include="include\EGT\Engine\Engine_Hooks.h" />
|
||||
<ClInclude Include="include\EGT\GamePH\GamePH_Hooks.h" />
|
||||
<ClInclude Include="include\EGT\ImGui_impl\D3D11_impl.h" />
|
||||
<ClInclude Include="include\EGT\ImGui_impl\D3D12_impl.h" />
|
||||
<ClInclude Include="include\EGT\ImGui_impl\DeferredActions.h" />
|
||||
|
@ -67,6 +67,9 @@
|
||||
<Filter Include="src\Utils">
|
||||
<UniqueIdentifier>{7170f228-254a-4cb7-8784-59baf69789d8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="include\GamePH">
|
||||
<UniqueIdentifier>{f334e27a-fb9d-4bf0-b3fa-692a6a8dfb39}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="deps\ImGui\imgui_hotkey.cpp">
|
||||
@ -230,5 +233,8 @@
|
||||
<ClInclude Include="deps\ImGui\imguiex_animation.h">
|
||||
<Filter>deps\ImGui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\EGT\GamePH\GamePH_Hooks.h">
|
||||
<Filter>include\GamePH</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -42,7 +42,8 @@ namespace ImGui {
|
||||
value = newValue;
|
||||
}
|
||||
void Option::SetBothValues(bool newValue) {
|
||||
previousValue = newValue; value = newValue;
|
||||
previousValue = newValue;
|
||||
value = newValue;
|
||||
}
|
||||
void Option::SetValue(bool newValue) {
|
||||
value = newValue;
|
||||
|
@ -5,6 +5,10 @@ namespace ImGui {
|
||||
static ImGuiStyle defImGuiStyle{};
|
||||
static size_t tabIndex = 1;
|
||||
|
||||
static void FormatString(char* buffer, size_t bufferSize, const char* fmt, va_list args) {
|
||||
vsnprintf(buffer, bufferSize, fmt, args);
|
||||
}
|
||||
|
||||
void StyleScaleAllSizes(ImGuiStyle* style, const float scale_factor, ImGuiStyle* defStyle) {
|
||||
if (!defStyle)
|
||||
defStyle = &defImGuiStyle;
|
||||
@ -221,20 +225,74 @@ namespace ImGui {
|
||||
SeparatorText(label);
|
||||
PopStyleColor();
|
||||
}
|
||||
void DisplaySimplePopupMessage(const char* popupTitle, const char* fmt, ...) {
|
||||
if (ImGui::BeginPopupModal(popupTitle, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char buffer[512];
|
||||
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
static void DisplaySimplePopupMessageBase(const char* popupTitle, const char* fmt, ...) {
|
||||
char buffer[512];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
FormatString(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (ImGui::BeginPopupModal(popupTitle, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::Text("%s", buffer);
|
||||
if (ImGui::Button("OK", ImVec2(120.0f, 0.0f)))
|
||||
ImGui::CloseCurrentPopup();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
static void DisplaySimplePopupMessageBase(float itemWidth, float scale, const char* popupTitle, const char* fmt, ...) {
|
||||
char buffer[512];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
FormatString(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (ImGui::BeginPopupModal(popupTitle, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::SetNextItemWidth(itemWidth * scale);
|
||||
ImGui::TextCentered("%s", buffer);
|
||||
ImGui::SetNextItemWidth(itemWidth * scale);
|
||||
if (ImGui::Button("OK", ImVec2(itemWidth, 0.0f) * scale))
|
||||
ImGui::CloseCurrentPopup();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
void DisplaySimplePopupMessage(const char* popupTitle, const char* fmt, ...) {
|
||||
char buffer[512];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
FormatString(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
DisplaySimplePopupMessageBase(popupTitle, fmt, buffer);
|
||||
}
|
||||
void DisplaySimplePopupMessageCentered(const char* popupTitle, const char* fmt, ...) {
|
||||
char buffer[512];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
FormatString(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), 0, ImVec2(0.5f, 0.5f));
|
||||
DisplaySimplePopupMessageBase(popupTitle, fmt, buffer);
|
||||
}
|
||||
void DisplaySimplePopupMessage(float itemWidth, float scale, const char* popupTitle, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char buffer[512];
|
||||
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
DisplaySimplePopupMessageBase(itemWidth, scale, popupTitle, fmt, buffer);
|
||||
}
|
||||
void DisplaySimplePopupMessageCentered(float itemWidth, float scale, const char* popupTitle, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char buffer[512];
|
||||
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), 0, ImVec2(0.5f, 0.5f));
|
||||
DisplaySimplePopupMessageBase(itemWidth, scale, popupTitle, fmt, buffer);
|
||||
}
|
||||
void Spacing(const ImVec2 size, const bool customPosOffset) {
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
|
@ -19,5 +19,8 @@ namespace ImGui {
|
||||
extern bool ButtonCentered(const char* label, const ImVec2 size = ImVec2(0.0f, 0.0f));
|
||||
extern void SeparatorTextColored(const char* text, const ImU32 col);
|
||||
extern void DisplaySimplePopupMessage(const char* popupTitle, const char* fmt, ...);
|
||||
extern void DisplaySimplePopupMessageCentered(const char* popupTitle, const char* fmt, ...);
|
||||
extern void DisplaySimplePopupMessage(float itemWidth, float scale, const char* popupTitle, const char* fmt, ...);
|
||||
extern void DisplaySimplePopupMessageCentered(float itemWidth, float scale, const char* popupTitle, const char* fmt, ...);
|
||||
extern void Spacing(const ImVec2 size, const bool customPosOffset = false);
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <atomic>
|
||||
#include <semaphore>
|
||||
#include <EGSDK\Utils\Values.h>
|
||||
|
||||
namespace EGT {
|
||||
@ -8,6 +10,17 @@ namespace EGT {
|
||||
constexpr unsigned long GAME_VER_COMPAT = 12001;
|
||||
|
||||
namespace Core {
|
||||
extern void OpenIOBuffer();
|
||||
extern void CloseIOBuffer();
|
||||
extern void EnableConsole();
|
||||
extern void DisableConsole();
|
||||
|
||||
extern std::atomic<bool> exiting;
|
||||
extern std::counting_semaphore<4> maxHookThreads;
|
||||
|
||||
extern void InitLogger();
|
||||
|
||||
extern DWORD64 WINAPI MainThread(HMODULE hModule);
|
||||
extern void Cleanup();
|
||||
}
|
||||
}
|
@ -2,11 +2,17 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <EGSDK\Vector3.h>
|
||||
#include <EGSDK\Utils\Hook.h>
|
||||
|
||||
namespace EGT::Engine {
|
||||
namespace Hooks {
|
||||
extern bool switchedFreeCamByGamePause;
|
||||
extern EGSDK::Vector3 freeCamPosBeforeGamePause;
|
||||
extern int mountDataPaksRanWith8Count;
|
||||
|
||||
extern EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, DWORD, DWORD), DWORD64, DWORD, DWORD> FsOpenHook;
|
||||
extern EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, UINT, UINT, DWORD64*, DWORD64(*)(DWORD64, DWORD, DWORD64, char*, int), INT16, DWORD64, UINT), DWORD64, UINT, UINT, DWORD64*, DWORD64(*)(DWORD64, DWORD, DWORD64, char*, int), INT16, DWORD64, UINT> MountDataPaksHook;
|
||||
extern EGSDK::Utils::Hook::MHook<void*, bool(*)(void*), void*> FsCheckZipCrcHook;
|
||||
extern EGSDK::Utils::Hook::MHook<void*, void* (*)(void*), void*> AuthenticateDataAddNewFileHook;
|
||||
}
|
||||
}
|
8
EGameTools/include/EGT/GamePH/GamePH_Hooks.h
Normal file
8
EGameTools/include/EGT/GamePH/GamePH_Hooks.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include <EGSDK\Utils\Hook.h>
|
||||
|
||||
namespace EGT::GamePH {
|
||||
namespace Hooks {
|
||||
extern EGSDK::Utils::Hook::ByteHook<void*> SaveGameCRCBoolCheckHook;
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ namespace EGT::Menu {
|
||||
namespace Camera {
|
||||
extern EGSDK::Vector3 cameraOffset;
|
||||
extern float firstPersonFOV;
|
||||
extern float originalFirstPersonFOVAfterZoomIn;
|
||||
extern ImGui::KeyBindOption firstPersonZoomIn;
|
||||
|
||||
extern ImGui::Option photoMode;
|
||||
|
@ -213,7 +213,7 @@ namespace EGT::Config {
|
||||
SPDLOG_INFO("{} does not exist (will create now); using default config values", configFileName);
|
||||
LoadAndWriteDefaultConfig();
|
||||
}
|
||||
static void ReadConfig(const bool configUpdate = false) {
|
||||
static void ReadConfig(bool configUpdate = false) {
|
||||
try {
|
||||
reader = inih::INIReader(configFileName);
|
||||
|
||||
@ -233,7 +233,7 @@ namespace EGT::Config {
|
||||
break;
|
||||
#ifdef _DEBUG
|
||||
if (entry.key == "DisableLowLevelMouseHook") {
|
||||
option->SetBothValues(reader.Get(entry.section.data(), entry.key.data(), true));
|
||||
option->SetBothValues(true);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -55,7 +55,6 @@ namespace EGT::Core {
|
||||
std::atomic<bool> exiting = false;
|
||||
static std::vector<std::thread> threads{};
|
||||
static HANDLE keepAliveEvent{};
|
||||
|
||||
std::counting_semaphore<4> maxHookThreads(4);
|
||||
|
||||
static bool LoopHookRenderer() {
|
||||
@ -301,6 +300,7 @@ namespace EGT::Core {
|
||||
threads.emplace_back(Config::ConfigLoop);
|
||||
|
||||
if (Menu::Debug::enableDebuggingConsole.GetValue()) {
|
||||
OpenIOBuffer();
|
||||
EnableConsole();
|
||||
AddConsoleSink();
|
||||
}
|
||||
@ -373,6 +373,13 @@ namespace EGT::Core {
|
||||
MH_Uninitialize();
|
||||
SPDLOG_INFO("Unhooked everything");
|
||||
|
||||
SPDLOG_INFO("Disabling console");
|
||||
if (Menu::Debug::enableDebuggingConsole.GetValue()) {
|
||||
DisableConsole();
|
||||
CloseIOBuffer();
|
||||
}
|
||||
SPDLOG_INFO("Console disabled");
|
||||
|
||||
SetEvent(keepAliveEvent);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include <filesystem>
|
||||
#include <EGSDK\Utils\Hook.h>
|
||||
#include <EGSDK\Utils\Time.h>
|
||||
#include <EGSDK\GamePH\LevelDI.h>
|
||||
#include <EGSDK\Engine\CBaseCamera.h>
|
||||
#include <EGSDK\Engine\Engine_Misc.h>
|
||||
#include <EGSDK\Offsets.h>
|
||||
#include <EGT\Engine\Engine_Hooks.h>
|
||||
#include <EGT\Menu\Camera.h>
|
||||
#include <EGT\Menu\Misc.h>
|
||||
|
||||
@ -14,44 +14,40 @@ namespace EGT::Engine {
|
||||
bool switchedFreeCamByGamePause = false;
|
||||
EGSDK::Vector3 freeCamPosBeforeGamePause{};
|
||||
|
||||
static void detourMoveCameraFromForwardUpPos(void*, float* a3, float* a4, EGSDK::Vector3* pos);
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(void*, float*, float*, EGSDK::Vector3*)> MoveCameraFromForwardUpPosHook{ "MoveCameraFromForwardUpPos", &EGSDK::Offsets::Get_MoveCameraFromForwardUpPos, &detourMoveCameraFromForwardUpPos };
|
||||
|
||||
static void detourMoveCameraFromForwardUpPos(void* pCBaseCamera, float* a3, float* a4, EGSDK::Vector3* pos) {
|
||||
EGSDK::GamePH::LevelDI* iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(void*, float*, float*, EGSDK::Vector3*), void*, float*, float*, EGSDK::Vector3*> MoveCameraFromForwardUpPosHook{ "MoveCameraFromForwardUpPos", &EGSDK::Offsets::Get_MoveCameraFromForwardUpPos, [](void* pCBaseCamera, float* a3, float* a4, EGSDK::Vector3* pos) -> void {
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
if (!iLevel || !iLevel->IsLoaded() || iLevel->IsTimerFrozen())
|
||||
return MoveCameraFromForwardUpPosHook.pOriginal(pCBaseCamera, a3, a4, pos);
|
||||
return MoveCameraFromForwardUpPosHook.ExecuteCallbacksWithOriginal(pCBaseCamera, a3, a4, pos);
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
if (Menu::Camera::freeCam.GetValue() && switchedFreeCamByGamePause) {
|
||||
switchedFreeCamByGamePause = false;
|
||||
*pos = freeCamPosBeforeGamePause;
|
||||
return MoveCameraFromForwardUpPosHook.pOriginal(pCBaseCamera, a3, a4, pos);
|
||||
return MoveCameraFromForwardUpPosHook.ExecuteCallbacksWithOriginal(pCBaseCamera, a3, a4, pos);
|
||||
}
|
||||
if ((!Menu::Camera::thirdPersonCamera.GetValue() && Menu::Camera::cameraOffset.isDefault()) || Menu::Camera::photoMode.GetValue() || Menu::Camera::freeCam.GetValue())
|
||||
return MoveCameraFromForwardUpPosHook.pOriginal(pCBaseCamera, a3, a4, pos);
|
||||
return MoveCameraFromForwardUpPosHook.ExecuteCallbacksWithOriginal(pCBaseCamera, a3, a4, pos);
|
||||
|
||||
EGSDK::Engine::CBaseCamera* viewCam = static_cast<EGSDK::Engine::CBaseCamera*>(iLevel->GetViewCamera());
|
||||
auto viewCam = static_cast<EGSDK::Engine::CBaseCamera*>(iLevel->GetViewCamera());
|
||||
if (!viewCam)
|
||||
return MoveCameraFromForwardUpPosHook.pOriginal(pCBaseCamera, a3, a4, pos);
|
||||
return MoveCameraFromForwardUpPosHook.ExecuteCallbacksWithOriginal(pCBaseCamera, a3, a4, pos);
|
||||
|
||||
EGSDK::Vector3 forwardVec{};
|
||||
EGSDK::Vector3 forwardVec, upVec, leftVec = {};
|
||||
viewCam->GetForwardVector(&forwardVec);
|
||||
const EGSDK::Vector3 normForwardVec = forwardVec.normalize();
|
||||
EGSDK::Vector3 upVec{};
|
||||
viewCam->GetUpVector(&upVec);
|
||||
const EGSDK::Vector3 normUpVec = upVec.normalize();
|
||||
EGSDK::Vector3 leftVec{};
|
||||
viewCam->GetLeftVector(&leftVec);
|
||||
const EGSDK::Vector3 normLeftVec = leftVec.normalize();
|
||||
|
||||
const auto normForwardVec = forwardVec.normalize();
|
||||
const auto normUpVec = upVec.normalize();
|
||||
const auto normLeftVec = leftVec.normalize();
|
||||
|
||||
EGSDK::Vector3 newCamPos = *pos;
|
||||
|
||||
if (!Menu::Camera::cameraOffset.isDefault() && !Menu::Camera::thirdPersonCamera.GetValue()) {
|
||||
newCamPos -= normLeftVec * Menu::Camera::cameraOffset.X;
|
||||
newCamPos.Y += Menu::Camera::cameraOffset.Y;
|
||||
newCamPos -= normForwardVec * -Menu::Camera::cameraOffset.Z;
|
||||
newCamPos -= normForwardVec * Menu::Camera::cameraOffset.Z;
|
||||
} else if (Menu::Camera::thirdPersonCamera.GetValue()) {
|
||||
newCamPos -= normForwardVec * -Menu::Camera::thirdPersonDistanceBehindPlayer;
|
||||
newCamPos.Y += Menu::Camera::thirdPersonHeightAbovePlayer - 1.5f;
|
||||
@ -59,96 +55,95 @@ namespace EGT::Engine {
|
||||
}
|
||||
|
||||
*pos = newCamPos;
|
||||
|
||||
MoveCameraFromForwardUpPosHook.pOriginal(pCBaseCamera, a3, a4, pos);
|
||||
}
|
||||
MoveCameraFromForwardUpPosHook.ExecuteCallbacksWithOriginal(pCBaseCamera, a3, a4, pos);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region SetFOV
|
||||
|
||||
static void* GetSetFOV() {
|
||||
return EGSDK::Utils::Memory::GetProcAddr("engine_x64_rwdi.dll", "?SetFOV@IBaseCamera@@QEAAXM@Z");
|
||||
}
|
||||
EGSDK::Utils::Hook::MHook<void*, void(*)(void*, float), float> SetFOVHook{ "SetFOV", &GetSetFOV, [](void* pCBaseCamera, float fov) -> void {
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(void*, float), void*, float> SetFOVHook{ "SetFOV", &GetSetFOV, [](void* pCBaseCamera, float fov) -> void {
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
if (!iLevel || !iLevel->IsLoaded())
|
||||
return SetFOVHook.ExecuteCallbacksWithOriginal(pCBaseCamera, fov);
|
||||
if (Menu::Camera::thirdPersonCamera.GetValue())
|
||||
fov = static_cast<float>(Menu::Camera::thirdPersonFOV);
|
||||
else if (!Menu::Camera::firstPersonZoomIn.IsKeyDown())
|
||||
Menu::Camera::originalFirstPersonFOVAfterZoomIn = fov;
|
||||
|
||||
SetFOVHook.ExecuteCallbacks(fov);
|
||||
return SetFOVHook.pOriginal(pCBaseCamera, fov);
|
||||
return SetFOVHook.ExecuteCallbacksWithOriginal(pCBaseCamera, fov);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region fs::open
|
||||
static const std::string userModFilesFullPath = "\\\\?\\" + std::filesystem::absolute("..\\..\\..\\source\\data\\EGameTools\\UserModFiles").string();
|
||||
|
||||
static std::vector<std::string> cachedUserModDirs{};
|
||||
static EGSDK::Utils::Time::Timer timeSinceCache{ 0 };
|
||||
static void CacheUserModDirs() {
|
||||
static EGSDK::Utils::Time::Timer cacheUpdateTimer{ 0 };
|
||||
|
||||
static void RecacheUserModDirectories() {
|
||||
SPDLOG_INFO("Recaching user mod directories");
|
||||
|
||||
if (!cachedUserModDirs.empty())
|
||||
cachedUserModDirs.clear();
|
||||
|
||||
cachedUserModDirs.push_back(userModFilesFullPath);
|
||||
|
||||
try {
|
||||
const auto rdi = std::filesystem::recursive_directory_iterator(userModFilesFullPath);
|
||||
for (auto entry = std::filesystem::begin(rdi); entry != std::filesystem::end(rdi); ++entry) {
|
||||
if (!entry->is_directory())
|
||||
continue;
|
||||
cachedUserModDirs.clear();
|
||||
cachedUserModDirs.push_back(userModFilesFullPath);
|
||||
|
||||
cachedUserModDirs.push_back(entry->path().string());
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(userModFilesFullPath)) {
|
||||
if (entry.is_directory())
|
||||
cachedUserModDirs.push_back(entry.path().string());
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
SPDLOG_ERROR("Exception thrown while caching user mod directories: {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
static std::optional<std::string> FindValidModFilePath(const std::string& fileName) {
|
||||
for (const auto& dir : cachedUserModDirs) {
|
||||
std::string potentialPath = dir + "\\" + fileName;
|
||||
if (std::filesystem::exists(potentialPath)) {
|
||||
SPDLOG_INFO("Found user mod file: {}", potentialPath);
|
||||
return potentialPath.substr(userModFilesFullPath.size() + 1); // Strip base path
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static void* GetFsOpen() {
|
||||
return EGSDK::Utils::Memory::GetProcAddr("filesystem_x64_rwdi.dll", "?open@fs@@YAPEAUSFsFile@@V?$string_const@D@ttl@@W4TYPE@EFSMode@@W45FFSOpenFlags@@@Z");
|
||||
}
|
||||
static DWORD64 detourFsOpen(DWORD64 file, DWORD a2, DWORD a3);
|
||||
EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, DWORD, DWORD)> FsOpenHook{ "fs::open", &GetFsOpen, &detourFsOpen };
|
||||
|
||||
static DWORD64 detourFsOpen(DWORD64 file, DWORD a2, DWORD a3) {
|
||||
EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, DWORD, DWORD), DWORD64, DWORD, DWORD> FsOpenHook{ "fs::open", &GetFsOpen, [](DWORD64 file, DWORD a2, DWORD a3) -> DWORD64 {
|
||||
const DWORD64 firstByte = (file >> 56) & 0xFF; // get first byte of addr
|
||||
|
||||
const char* filePath = reinterpret_cast<const char*>(file & 0x1FFFFFFFFFFFFFFF); // remove first byte of addr in case it exists
|
||||
const std::string fileName = std::filesystem::path(filePath).filename().string();
|
||||
if (fileName.empty() || fileName.contains("EGameTools") || fileName.ends_with(".model"))
|
||||
return FsOpenHook.pOriginal(file, a2, a3);
|
||||
return FsOpenHook.ExecuteCallbacksWithOriginal(file, a2, a3);
|
||||
|
||||
if (timeSinceCache.DidTimePass()) {
|
||||
CacheUserModDirs();
|
||||
timeSinceCache = EGSDK::Utils::Time::Timer(5000);
|
||||
if (cacheUpdateTimer.DidTimePass()) {
|
||||
RecacheUserModDirectories();
|
||||
cacheUpdateTimer = EGSDK::Utils::Time::Timer(5000);
|
||||
}
|
||||
|
||||
std::string finalPath{};
|
||||
try {
|
||||
for (const auto& entry : cachedUserModDirs) {
|
||||
finalPath = entry + "\\" + fileName;
|
||||
if (!std::filesystem::exists(finalPath))
|
||||
continue;
|
||||
|
||||
finalPath.erase(0, userModFilesFullPath.size() + 1); // erase entire path until mod folder
|
||||
const char* filePath2 = finalPath.c_str();
|
||||
SPDLOG_INFO("Loading user mod file \"{}\"", finalPath.c_str());
|
||||
if (auto modFilePath = FindValidModFilePath(fileName)) {
|
||||
const char* modFileCStr = modFilePath->c_str();
|
||||
SPDLOG_INFO("Loading user mod file: {}", modFilePath->c_str());
|
||||
|
||||
DWORD64 finalAddr = reinterpret_cast<DWORD64>(filePath2);
|
||||
DWORD64 modFileAddr = reinterpret_cast<DWORD64>(modFileCStr);
|
||||
if (firstByte != 0x0)
|
||||
finalAddr |= (firstByte << 56);
|
||||
modFileAddr |= (firstByte << 56);
|
||||
|
||||
const DWORD64 result = FsOpenHook.pOriginal(finalAddr, a2, a3);
|
||||
DWORD64 result = FsOpenHook.ExecuteCallbacksWithOriginal(modFileAddr, a2, a3);
|
||||
if (!result) {
|
||||
SPDLOG_ERROR("fs::open returned 0! Something went wrong with loading user mod file \"{}\"!\nPlease make sure the path to the file is no longer than 260 characters!", finalPath.c_str());
|
||||
return FsOpenHook.pOriginal(file, a2, a3);
|
||||
return FsOpenHook.ExecuteCallbacksWithOriginal(file, a2, a3);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
SPDLOG_ERROR("Exception thrown while loading user mod file \"{}\": {}", finalPath.c_str(), e.what());
|
||||
}
|
||||
return FsOpenHook.pOriginal(file, a2, a3);
|
||||
}
|
||||
return FsOpenHook.ExecuteCallbacksWithOriginal(file, a2, a3);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
// Thank you @12brendon34 on Discord for help with finding the function responsible for .PAK loading!
|
||||
@ -163,96 +158,96 @@ namespace EGT::Engine {
|
||||
};
|
||||
|
||||
static DWORD64 mount(mount_path* path, USHORT flags, void** a3) {
|
||||
DWORD64(*pMount)(mount_path*, USHORT, void**) = (decltype(pMount))EGSDK::Utils::Memory::GetProcAddr("filesystem_x64_rwdi.dll", "?mount@fs@@YA_NAEBUmount_path@1@GPEAPEAVCFsMount@@@Z");
|
||||
if (!pMount)
|
||||
return 0;
|
||||
return EGSDK::Utils::Memory::SafeCallFunction<DWORD64>("filesystem_x64_rwdi.dll", "?mount@fs@@YA_NAEBUmount_path@1@GPEAPEAVCFsMount@@@Z", 0, path, flags, a3);
|
||||
}
|
||||
}
|
||||
|
||||
return pMount(path, flags, a3);
|
||||
static bool MountUserPakFile(const std::string& fullPakPath, const std::string& gamePath) {
|
||||
try {
|
||||
std::string pakPath = fullPakPath;
|
||||
pakPath.erase(0, gamePath.size() + 1);
|
||||
|
||||
fs::mount_path path{};
|
||||
path.gamePath = gamePath.c_str();
|
||||
path.pakPath = pakPath.c_str();
|
||||
path.fullPakPath = fullPakPath.c_str();
|
||||
|
||||
SPDLOG_INFO("Attempting to load user PAK mod file: \"{}\"", pakPath);
|
||||
|
||||
// Attempt to mount the PAK file
|
||||
if (!fs::mount(&path, 1, nullptr)) {
|
||||
SPDLOG_ERROR("Failed to mount user PAK mod file \"{}\". Ensure the file is valid and the path is no longer than 260 characters.", pakPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
SPDLOG_INFO("Successfully loaded user PAK mod file: \"{}\"", pakPath);
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
SPDLOG_ERROR("Error mounting user PAK mod file \"{}\": {}", fullPakPath, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
static void IterateAndMountUserPakFiles(const std::string& userModFilesPath, const std::string& gamePath) {
|
||||
try {
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(userModFilesPath)) {
|
||||
if (entry.is_directory())
|
||||
continue;
|
||||
|
||||
const std::string fullPakPath = entry.path().string();
|
||||
if (EGSDK::Utils::Values::str_ends_with_ci(fullPakPath, ".pak"))
|
||||
MountUserPakFile(fullPakPath, gamePath);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
SPDLOG_ERROR("Exception during PAK file iteration: {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
static void* GetCResourceLoadingRuntimeCreate() {
|
||||
return EGSDK::Utils::Memory::GetProcAddr("engine_x64_rwdi.dll", "?Create@CResourceLoadingRuntime@@SAPEAV1@_N@Z");
|
||||
}
|
||||
static void* detourCResourceLoadingRuntimeCreate(bool noTexStreaming);
|
||||
EGSDK::Utils::Hook::MHook<void*, void*(*)(bool)> CResourceLoadingRuntimeCreateHook{ "CResourceLoadingRuntimeCreate", &GetCResourceLoadingRuntimeCreate, &detourCResourceLoadingRuntimeCreate };
|
||||
|
||||
static void* detourCResourceLoadingRuntimeCreate(bool noTexStreaming) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, void* (*)(bool), bool> CResourceLoadingRuntimeCreateHook{ "CResourceLoadingRuntimeCreate", &GetCResourceLoadingRuntimeCreate, [](bool noTexStreaming) -> void* {
|
||||
std::string gamePath = userModFilesFullPath;
|
||||
EGSDK::Utils::Values::str_replace(gamePath, "\\ph\\source\\data\\EGameTools\\UserModFiles", "");
|
||||
|
||||
fs::mount_path pathPtr = fs::mount_path();
|
||||
pathPtr.gamePath = gamePath.c_str();
|
||||
SPDLOG_INFO("Mounting user PAK mod files from: {}", userModFilesFullPath);
|
||||
IterateAndMountUserPakFiles(userModFilesFullPath, gamePath);
|
||||
|
||||
try {
|
||||
const auto rdi = std::filesystem::recursive_directory_iterator(userModFilesFullPath);
|
||||
for (auto entry = std::filesystem::begin(rdi); entry != std::filesystem::end(rdi); ++entry) {
|
||||
if (entry->is_directory())
|
||||
continue;
|
||||
std::string fullPakPath = entry->path().string();
|
||||
if (!EGSDK::Utils::Values::str_ends_with_ci(fullPakPath, ".pak"))
|
||||
continue;
|
||||
|
||||
std::string pakPath = fullPakPath;
|
||||
pakPath.erase(0, gamePath.size() + 1);
|
||||
|
||||
pathPtr.pakPath = pakPath.c_str();
|
||||
pathPtr.fullPakPath = fullPakPath.c_str();
|
||||
|
||||
SPDLOG_INFO("Loading user PAK mod file \"{}\"", pakPath.c_str());
|
||||
if (!fs::mount(&pathPtr, 1, nullptr))
|
||||
SPDLOG_ERROR("fs::mount returned 0! Something went wrong with loading user PAK mod file \"{}\"!\nPlease make sure the path to the file is no longer than 260 characters, and make sure the file is valid!", pakPath.c_str());
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
SPDLOG_ERROR("Exception thrown while iterating over user mod directories for PAK loading: {}", e.what());
|
||||
}
|
||||
|
||||
return CResourceLoadingRuntimeCreateHook.pOriginal(noTexStreaming);
|
||||
}
|
||||
return CResourceLoadingRuntimeCreateHook.ExecuteCallbacksWithOriginal(noTexStreaming);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region MountDataPaks
|
||||
int mountDataPaksRanWith8Count = 0;
|
||||
|
||||
static DWORD64 detourMountDataPaks(DWORD64 a1, UINT a2, UINT a3, DWORD64* a4, DWORD64(*a5)(DWORD64, DWORD, DWORD64, char*, int), INT16 a6, DWORD64 a7, UINT a8);
|
||||
EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, UINT, UINT, DWORD64*, DWORD64(*)(DWORD64, DWORD, DWORD64, char*, int), INT16, DWORD64, UINT)> MountDataPaksHook{ "MountDataPaks", &EGSDK::Offsets::Get_MountDataPaks, &detourMountDataPaks };
|
||||
|
||||
static DWORD64 detourMountDataPaks(DWORD64 a1, UINT a2, UINT a3, DWORD64* a4, DWORD64(*a5)(DWORD64, DWORD, DWORD64, char*, int), INT16 a6, DWORD64 a7, UINT a8) {
|
||||
EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, UINT, UINT, DWORD64*, DWORD64(*)(DWORD64, DWORD, DWORD64, char*, int), INT16, DWORD64, UINT), DWORD64, UINT, UINT, DWORD64*, DWORD64(*)(DWORD64, DWORD, DWORD64, char*, int), INT16, DWORD64, UINT> MountDataPaksHook{ "MountDataPaks", &EGSDK::Offsets::Get_MountDataPaks, [](DWORD64 a1, UINT a2, UINT a3, DWORD64* a4, DWORD64(*a5)(DWORD64, DWORD, DWORD64, char*, int), INT16 a6, DWORD64 a7, UINT a8) -> DWORD64 {
|
||||
if (Menu::Misc::increaseDataPAKsLimit.GetValue()) {
|
||||
if (a8 == 8)
|
||||
mountDataPaksRanWith8Count++;
|
||||
|
||||
a8 = 200;
|
||||
}
|
||||
return MountDataPaksHook.pOriginal(a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
}
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region FsCheckZipCrc
|
||||
static void* GetFsCheckZipCrc() {
|
||||
return EGSDK::Utils::Memory::GetProcAddr("filesystem_x64_rwdi.dll", "?check_zip_crc@izipped_buffer_file@fs@@QEAA_NXZ");
|
||||
}
|
||||
static bool detourFsCheckZipCrc(void* instance);
|
||||
EGSDK::Utils::Hook::MHook<void*, bool(*)(void*)> FsCheckZipCrcHook{ "FsCheckZipCrc", &GetFsCheckZipCrc, &detourFsCheckZipCrc };
|
||||
|
||||
static bool detourFsCheckZipCrc(void* instance) {
|
||||
return Menu::Misc::disableSavegameCRCCheck.GetValue() ? true : FsCheckZipCrcHook.pOriginal(instance);
|
||||
}
|
||||
EGSDK::Utils::Hook::MHook<void*, bool(*)(void*), void*> FsCheckZipCrcHook{ "FsCheckZipCrc", &GetFsCheckZipCrc, [](void* instance) -> bool {
|
||||
return Menu::Misc::disableSavegameCRCCheck.GetValue() ? true : FsCheckZipCrcHook.ExecuteCallbacksWithOriginal(instance);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region AuthenticateDataAddNewFile
|
||||
static void* GetAuthenticateDataAddNewFile() {
|
||||
return EGSDK::Utils::Memory::GetProcAddr("engine_x64_rwdi.dll", "?AddNewFile@Results@AuthenticateData@@QEAAAEAVFile@12@XZ");
|
||||
}
|
||||
static void* detourAuthenticateDataAddNewFile(void* instance);
|
||||
EGSDK::Utils::Hook::MHook<void*, void*(*)(void*)> AuthenticateDataAddNewFileHook{ "AuthenticateDataAddNewFile", &GetAuthenticateDataAddNewFile, &detourAuthenticateDataAddNewFile };
|
||||
|
||||
static void* detourAuthenticateDataAddNewFile(void* instance) {
|
||||
void* result = AuthenticateDataAddNewFileHook.pOriginal(instance);
|
||||
EGSDK::Utils::Hook::MHook<void*, void* (*)(void*), void*> AuthenticateDataAddNewFileHook{ "AuthenticateDataAddNewFile", &GetAuthenticateDataAddNewFile, [](void* instance) -> void* {
|
||||
void* result = AuthenticateDataAddNewFileHook.ExecuteCallbacksWithOriginal(instance);
|
||||
if (Menu::Misc::disableDataPAKsCRCCheck.GetValue())
|
||||
EGSDK::Engine::AuthenticateDataResultsClear(instance);
|
||||
return result;
|
||||
}
|
||||
} };
|
||||
#pragma endregion
|
||||
}
|
||||
}
|
@ -16,175 +16,144 @@
|
||||
namespace EGT::GamePH {
|
||||
namespace Hooks {
|
||||
#pragma region LifeSetHealth
|
||||
static void detourLifeSetHealth(float* pLifeHealth, float health);
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(float*, float)> LifeSetHealthHook{ "LifeSetHealth", &EGSDK::Offsets::Get_LifeSetHealth, &detourLifeSetHealth };
|
||||
|
||||
static void detourLifeSetHealth(float* pLifeHealth, float health) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(float*, float), float*, float> LifeSetHealthHook{ "LifeSetHealth", &EGSDK::Offsets::Get_LifeSetHealth, [](float* pLifeHealth, float health) -> void {
|
||||
if (!Menu::Player::godMode.GetValue() && !Menu::Camera::freeCam.GetValue())
|
||||
return LifeSetHealthHook.pOriginal(pLifeHealth, health);
|
||||
return LifeSetHealthHook.ExecuteCallbacksWithOriginal(pLifeHealth, health);
|
||||
|
||||
EGSDK::GamePH::PlayerHealthModule* playerHealthModule = EGSDK::GamePH::PlayerHealthModule::Get();
|
||||
auto playerHealthModule = EGSDK::GamePH::PlayerHealthModule::Get();
|
||||
if (!playerHealthModule)
|
||||
return LifeSetHealthHook.pOriginal(pLifeHealth, health);
|
||||
EGSDK::GamePH::LevelDI* iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
return LifeSetHealthHook.ExecuteCallbacksWithOriginal(pLifeHealth, health);
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
if (!iLevel || !iLevel->IsLoaded())
|
||||
return LifeSetHealthHook.pOriginal(pLifeHealth, health);
|
||||
return LifeSetHealthHook.ExecuteCallbacksWithOriginal(pLifeHealth, health);
|
||||
|
||||
if (std::abs(reinterpret_cast<LONG64>(playerHealthModule) - reinterpret_cast<LONG64>(pLifeHealth)) < 0x100 && playerHealthModule->health > 0.0f)
|
||||
constexpr size_t addressThreshold = 0x100;
|
||||
if (std::abs(reinterpret_cast<LONG64>(playerHealthModule) - reinterpret_cast<LONG64>(pLifeHealth)) < addressThreshold && playerHealthModule->health > 0.0f)
|
||||
return;
|
||||
|
||||
LifeSetHealthHook.pOriginal(pLifeHealth, health);
|
||||
}
|
||||
LifeSetHealthHook.ExecuteCallbacksWithOriginal(pLifeHealth, health);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region PlayerHealthModuleKillPlayer
|
||||
static DWORD64 detourPlayerHealthModuleKillPlayer(void* playerHealthModule);
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(void*)> PlayerHealthModuleKillPlayerHook{ "PlayerHealthModuleKillPlayer", &EGSDK::Offsets::Get_PlayerHealthModuleKillPlayer, &detourPlayerHealthModuleKillPlayer };
|
||||
|
||||
static DWORD64 detourPlayerHealthModuleKillPlayer(void* playerHealthModule) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(void*), void*> PlayerHealthModuleKillPlayerHook{ "PlayerHealthModuleKillPlayer", &EGSDK::Offsets::Get_PlayerHealthModuleKillPlayer, [](void* playerHealthModule) -> DWORD64 {
|
||||
if (!Menu::Player::godMode.GetValue() && !Menu::Camera::freeCam.GetValue())
|
||||
return PlayerHealthModuleKillPlayerHook.pOriginal(playerHealthModule);
|
||||
return PlayerHealthModuleKillPlayerHook.ExecuteCallbacksWithOriginal(playerHealthModule);
|
||||
|
||||
EGSDK::GamePH::PlayerHealthModule* pPlayerHealthModule = EGSDK::GamePH::PlayerHealthModule::Get();
|
||||
auto pPlayerHealthModule = EGSDK::GamePH::PlayerHealthModule::Get();
|
||||
if (!pPlayerHealthModule)
|
||||
return PlayerHealthModuleKillPlayerHook.pOriginal(playerHealthModule);
|
||||
return PlayerHealthModuleKillPlayerHook.ExecuteCallbacksWithOriginal(playerHealthModule);
|
||||
if (pPlayerHealthModule == playerHealthModule)
|
||||
return 0;
|
||||
|
||||
return PlayerHealthModuleKillPlayerHook.pOriginal(playerHealthModule);
|
||||
}
|
||||
return PlayerHealthModuleKillPlayerHook.ExecuteCallbacksWithOriginal(playerHealthModule);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IsNotOutOfMapBounds
|
||||
static bool detourIsNotOutOfMapBounds(void* pInstance, DWORD64 a2);
|
||||
static EGSDK::Utils::Hook::MHook<void*, bool(*)(void*, DWORD64)> IsNotOutOfMapBoundsHook{ "IsNotOutOfMapBounds", &EGSDK::Offsets::Get_IsNotOutOfMapBounds, &detourIsNotOutOfMapBounds };
|
||||
|
||||
static bool detourIsNotOutOfMapBounds(void* pInstance, DWORD64 a2) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, bool(*)(void*, DWORD64), void*, DWORD64> IsNotOutOfMapBoundsHook{ "IsNotOutOfMapBounds", &EGSDK::Offsets::Get_IsNotOutOfMapBounds, [](void* pInstance, DWORD64 a2) -> bool {
|
||||
if (Menu::Player::disableOutOfBoundsTimer.GetValue())
|
||||
return true;
|
||||
|
||||
return IsNotOutOfMapBoundsHook.pOriginal(pInstance, a2);
|
||||
}
|
||||
return IsNotOutOfMapBoundsHook.ExecuteCallbacksWithOriginal(pInstance, a2);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IsNotOutOfMissionBounds
|
||||
static bool detourIsNotOutOfMissionBounds(void* pInstance, DWORD64 a2);
|
||||
static EGSDK::Utils::Hook::MHook<void*, bool(*)(void*, DWORD64)> IsNotOutOfMissionBoundsHook{ "IsNotOutOfMissionBounds", &EGSDK::Offsets::Get_IsNotOutOfMissionBounds, &detourIsNotOutOfMissionBounds };
|
||||
|
||||
static bool detourIsNotOutOfMissionBounds(void* pInstance, DWORD64 a2) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, bool(*)(void*, DWORD64), void*, DWORD64> IsNotOutOfMissionBoundsHook{ "IsNotOutOfMissionBounds", &EGSDK::Offsets::Get_IsNotOutOfMissionBounds, [](void* pInstance, DWORD64 a2) -> bool {
|
||||
if (Menu::Player::disableOutOfBoundsTimer.GetValue())
|
||||
return true;
|
||||
|
||||
return IsNotOutOfMissionBoundsHook.pOriginal(pInstance, a2);
|
||||
}
|
||||
return IsNotOutOfMissionBoundsHook.ExecuteCallbacksWithOriginal(pInstance, a2);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ShowUIManager
|
||||
static void detourShowUIManager(void* pLevelDI, bool enabled);
|
||||
static void* GetShowUIManager() {
|
||||
return EGSDK::Utils::Memory::GetProcAddr("engine_x64_rwdi.dll", "?ShowUIManager@ILevel@@QEAAX_N@Z");
|
||||
}
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(void*, bool)> ShowUIManagerHook{ "ShowUIManager", &GetShowUIManager, &detourShowUIManager };
|
||||
|
||||
static void detourShowUIManager(void* pLevelDI, bool enabled) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(void*, bool), void*, bool> ShowUIManagerHook{ "ShowUIManager", &GetShowUIManager, [](void* pLevelDI, bool enabled) -> void {
|
||||
if (Menu::Misc::disableHUD.GetValue())
|
||||
enabled = false;
|
||||
|
||||
ShowUIManagerHook.pOriginal(pLevelDI, enabled);
|
||||
}
|
||||
ShowUIManagerHook.ExecuteCallbacksWithOriginal(pLevelDI, enabled);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region TogglePhotoMode
|
||||
static void detourTogglePhotoMode1(void* guiPhotoModeData, bool enabled);
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(void*, bool)> TogglePhotoMode1Hook{ "TogglePhotoMode1", &EGSDK::Offsets::Get_TogglePhotoMode1, &detourTogglePhotoMode1 };
|
||||
|
||||
static void detourTogglePhotoMode1(void* guiPhotoModeData, bool enabled) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(void*, bool), void*, bool> TogglePhotoMode1Hook{ "TogglePhotoMode1", &EGSDK::Offsets::Get_TogglePhotoMode1, [](void* guiPhotoModeData, bool enabled) -> void {
|
||||
Menu::Camera::photoMode.Set(enabled);
|
||||
|
||||
if (!Menu::Camera::freeCam.GetValue())
|
||||
return TogglePhotoMode1Hook.pOriginal(guiPhotoModeData, enabled);
|
||||
EGSDK::GamePH::LevelDI* iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
return TogglePhotoMode1Hook.ExecuteCallbacksWithOriginal(guiPhotoModeData, enabled);
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
if (!iLevel || iLevel->IsTimerFrozen())
|
||||
return TogglePhotoMode1Hook.pOriginal(guiPhotoModeData, enabled);
|
||||
EGSDK::GamePH::GameDI_PH* pGameDI_PH = EGSDK::GamePH::GameDI_PH::Get();
|
||||
return TogglePhotoMode1Hook.ExecuteCallbacksWithOriginal(guiPhotoModeData, enabled);
|
||||
auto pGameDI_PH = EGSDK::GamePH::GameDI_PH::Get();
|
||||
if (!pGameDI_PH)
|
||||
return TogglePhotoMode1Hook.pOriginal(guiPhotoModeData, enabled);
|
||||
EGSDK::GamePH::FreeCamera* pFreeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
return TogglePhotoMode1Hook.ExecuteCallbacksWithOriginal(guiPhotoModeData, enabled);
|
||||
auto pFreeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
if (!pFreeCam)
|
||||
return TogglePhotoMode1Hook.pOriginal(guiPhotoModeData, enabled);
|
||||
return TogglePhotoMode1Hook.ExecuteCallbacksWithOriginal(guiPhotoModeData, enabled);
|
||||
|
||||
if (enabled) {
|
||||
pGameDI_PH->TogglePhotoMode();
|
||||
pFreeCam->AllowCameraMovement(0);
|
||||
}
|
||||
|
||||
TogglePhotoMode1Hook.pOriginal(guiPhotoModeData, enabled);
|
||||
}
|
||||
TogglePhotoMode1Hook.ExecuteCallbacksWithOriginal(guiPhotoModeData, enabled);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ShowTPPModelFunc3
|
||||
ImGui::Option wannaUseTPPModel{};
|
||||
static bool prevUseTPPModel;
|
||||
static void detourShowTPPModelFunc3(DWORD64 tppFunc2Addr, bool showTPPModel);
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(DWORD64, bool)> ShowTPPModelFunc3Hook{ "ShowTPPModelFunc3", &EGSDK::Offsets::Get_ShowTPPModelFunc3, &detourShowTPPModelFunc3 };
|
||||
|
||||
static void detourShowTPPModelFunc3(DWORD64 tppFunc2Addr, bool showTPPModel) {
|
||||
EGSDK::GamePH::PlayerDI_PH* pPlayerDI_PH = EGSDK::GamePH::PlayerDI_PH::Get();
|
||||
if (!pPlayerDI_PH) {
|
||||
ShowTPPModelFunc3Hook.pOriginal(tppFunc2Addr, showTPPModel);
|
||||
return;
|
||||
}
|
||||
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(DWORD64, bool), DWORD64, bool> ShowTPPModelFunc3Hook{ "ShowTPPModelFunc3", &EGSDK::Offsets::Get_ShowTPPModelFunc3, [](DWORD64 tppFunc2Addr, bool showTPPModel) -> void {
|
||||
auto pPlayerDI_PH = EGSDK::GamePH::PlayerDI_PH::Get();
|
||||
if (!pPlayerDI_PH)
|
||||
return ShowTPPModelFunc3Hook.ExecuteCallbacksWithOriginal(tppFunc2Addr, showTPPModel);
|
||||
|
||||
if (!showTPPModel && prevUseTPPModel) {
|
||||
pPlayerDI_PH->enableTPPModel2 = true;
|
||||
pPlayerDI_PH->enableTPPModel1 = true;
|
||||
}
|
||||
ShowTPPModelFunc3Hook.pOriginal(tppFunc2Addr, showTPPModel);
|
||||
ShowTPPModelFunc3Hook.ExecuteCallbacksWithOriginal(tppFunc2Addr, showTPPModel);
|
||||
if (showTPPModel && prevUseTPPModel) {
|
||||
pPlayerDI_PH->enableTPPModel2 = false;
|
||||
pPlayerDI_PH->enableTPPModel1 = false;
|
||||
} else
|
||||
prevUseTPPModel = showTPPModel;
|
||||
}
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region CalculateFreeCamCollision
|
||||
static DWORD64 detourCalculateFreeCamCollision(void* pFreeCamera, float* finalPos);
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(void*, float*)> CalculateFreeCamCollisionHook{ "CalculateFreeCamCollision", &EGSDK::Offsets::Get_CalculateFreeCamCollision, &detourCalculateFreeCamCollision };
|
||||
|
||||
static DWORD64 detourCalculateFreeCamCollision(void* pFreeCamera, float* finalPos) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(void*, float*), void*, float*> CalculateFreeCamCollisionHook{ "CalculateFreeCamCollision", &EGSDK::Offsets::Get_CalculateFreeCamCollision, [](void* pFreeCamera, float* finalPos) -> DWORD64 {
|
||||
if (Menu::Camera::disablePhotoModeLimits.GetValue() || Menu::Camera::freeCam.GetValue())
|
||||
return 0;
|
||||
|
||||
return CalculateFreeCamCollisionHook.pOriginal(pFreeCamera, finalPos);
|
||||
}
|
||||
return CalculateFreeCamCollisionHook.ExecuteCallbacksWithOriginal(pFreeCamera, finalPos);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region PlaySoundEvent
|
||||
static DWORD64 detourPlaySoundEvent(void* pCoAudioEventControl, DWORD64 name, DWORD64 a3);
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(void*, DWORD64, DWORD64)> PlaySoundEventHook{ "PlaySoundEvent", &EGSDK::Offsets::Get_PlaySoundEvent, &detourPlaySoundEvent };
|
||||
|
||||
static DWORD64 detourPlaySoundEvent(void* pCoAudioEventControl, DWORD64 name, DWORD64 a3) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(void*, DWORD64, DWORD64), void*, DWORD64, DWORD64> PlaySoundEventHook{ "PlaySoundEvent", &EGSDK::Offsets::Get_PlaySoundEvent, [](void* pCoAudioEventControl, DWORD64 name, DWORD64 a3) -> DWORD64 {
|
||||
const char* soundName = reinterpret_cast<const char*>(name & 0x1FFFFFFFFFFFFFFF); // remove first byte of addr in case it exists
|
||||
if (Menu::World::freezeTime.GetValue() && soundName &&
|
||||
(!strcmp(soundName, "set_gp_infection_start") || !strcmp(soundName, "set_gp_infection_immune"))) {
|
||||
if (Menu::World::freezeTime.GetValue() && soundName && (!strcmp(soundName, "set_gp_infection_start") || !strcmp(soundName, "set_gp_infection_immune")))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PlaySoundEventHook.pOriginal(pCoAudioEventControl, name, a3);
|
||||
}
|
||||
return PlaySoundEventHook.ExecuteCallbacksWithOriginal(pCoAudioEventControl, name, a3);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region CalculateFallHeight
|
||||
static DWORD64 detourCalculateFallHeight(void* pInstance, float height);
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(void*, float)> CalculateFallHeightHook{ "CalculateFallHeight", &EGSDK::Offsets::Get_CalculateFallHeight, &detourCalculateFallHeight };
|
||||
static bool prevFreeCamValue = Menu::Camera::freeCam.GetPrevValue();
|
||||
|
||||
static DWORD64 detourCalculateFallHeight(void* pInstance, float height) {
|
||||
static bool prevFreeCam = Menu::Camera::freeCam.GetPrevValue();
|
||||
prevFreeCam = Menu::Camera::freeCam.GetPrevValue();
|
||||
if (!Menu::Camera::freeCam.GetValue() && prevFreeCam) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(void*, float), void*, float> CalculateFallHeightHook{ "CalculateFallHeight", &EGSDK::Offsets::Get_CalculateFallHeight, [](void* pInstance, float height) -> DWORD64 {
|
||||
prevFreeCamValue = Menu::Camera::freeCam.GetPrevValue();
|
||||
if (!Menu::Camera::freeCam.GetValue() && prevFreeCamValue) {
|
||||
Menu::Camera::freeCam.SetPrevValue(false);
|
||||
prevFreeCam = false;
|
||||
prevFreeCamValue = false;
|
||||
return 0;
|
||||
}
|
||||
if (Menu::Teleport::waypointIsSet && !*Menu::Teleport::waypointIsSet && Menu::Teleport::justTeleportedToWaypoint) {
|
||||
@ -195,28 +164,22 @@ namespace EGT::GamePH {
|
||||
if (Menu::Player::godMode.GetValue())
|
||||
return 0;
|
||||
|
||||
return CalculateFallHeightHook.pOriginal(pInstance, height);
|
||||
}
|
||||
return CalculateFallHeightHook.ExecuteCallbacksWithOriginal(pInstance, height);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region CanUseGrappleHook
|
||||
static bool detourCanUseGrappleHook(void* pInstance, bool a2);
|
||||
static EGSDK::Utils::Hook::MHook<void*, bool(*)(void*, bool)> CanUseGrappleHookHook{ "CanUseGrappleHook", &EGSDK::Offsets::Get_CanUseGrappleHook, &detourCanUseGrappleHook };
|
||||
|
||||
static bool detourCanUseGrappleHook(void* pInstance, bool a2) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, bool(*)(void*, bool), void*, bool> CanUseGrappleHookHook{ "CanUseGrappleHook", &EGSDK::Offsets::Get_CanUseGrappleHook, [](void* pInstance, bool a2) -> bool {
|
||||
if (Menu::Player::allowGrappleHookInSafezone.GetValue())
|
||||
return true;
|
||||
|
||||
return CanUseGrappleHookHook.pOriginal(pInstance, a2);
|
||||
}
|
||||
return CanUseGrappleHookHook.ExecuteCallbacksWithOriginal(pInstance, a2);
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ReadPlayerJumpParams
|
||||
static DWORD64 detourReadPlayerJumpParams(DWORD64 a1, DWORD64 a2, DWORD64 a3, char a4, DWORD64* a5);
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, DWORD64, DWORD64, char, DWORD64*)> ReadPlayerJumpParamsHook{ "ReadPlayerJumpParams", &EGSDK::Offsets::Get_ReadPlayerJumpParams, &detourReadPlayerJumpParams };
|
||||
|
||||
static DWORD64 detourReadPlayerJumpParams(DWORD64 a1, DWORD64 a2, DWORD64 a3, char a4, DWORD64* a5) {
|
||||
DWORD64 result = ReadPlayerJumpParamsHook.pOriginal(a1, a2, a3, a4, a5);
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, DWORD64, DWORD64, char, DWORD64*), DWORD64, DWORD64, DWORD64, char, DWORD64*> ReadPlayerJumpParamsHook{ "ReadPlayerJumpParams", &EGSDK::Offsets::Get_ReadPlayerJumpParams, [](DWORD64 a1, DWORD64 a2, DWORD64 a3, char a4, DWORD64* a5) -> DWORD64 {
|
||||
DWORD64 result = ReadPlayerJumpParamsHook.ExecuteCallbacksWithOriginal(a1, a2, a3, a4, a5);
|
||||
|
||||
if (Menu::Player::disableAirControl.GetValue())
|
||||
*reinterpret_cast<bool*>(a1 + EGSDK::Offsets::Get_allowVelocityMod_offset()) = false;
|
||||
@ -224,71 +187,33 @@ namespace EGT::GamePH {
|
||||
*reinterpret_cast<bool*>(a1 + EGSDK::Offsets::Get_disableHeadCorrection_offset()) = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region HandleInventoryItemsAmount
|
||||
static void detourHandleInventoryItemsAmount(int* pInventoryItem_0x10, UINT amount);
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(int*, UINT)> HandleInventoryItemsAmountHook{ "HandleInventoryItemsAmount", &EGSDK::Offsets::Get_HandleInventoryItemsAmount, &detourHandleInventoryItemsAmount };
|
||||
|
||||
static void detourHandleInventoryItemsAmount(int* pInventoryItem_0x10, UINT amount) {
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(int*, UINT), int*, UINT> HandleInventoryItemsAmountHook{ "HandleInventoryItemsAmount", &EGSDK::Offsets::Get_HandleInventoryItemsAmount, [](int* pInventoryItem_0x10, UINT amount) -> void {
|
||||
int previousValue = *pInventoryItem_0x10;
|
||||
HandleInventoryItemsAmountHook.pOriginal(pInventoryItem_0x10, amount);
|
||||
HandleInventoryItemsAmountHook.ExecuteCallbacksWithOriginal(pInventoryItem_0x10, amount);
|
||||
if (!EGSDK::GamePH::LevelDI::Get() || !EGSDK::GamePH::LevelDI::Get()->IsLoaded())
|
||||
return;
|
||||
|
||||
if (*pInventoryItem_0x10 < previousValue && *pInventoryItem_0x10 == amount && Menu::Player::unlimitedItems.GetValue())
|
||||
*pInventoryItem_0x10 = previousValue;
|
||||
}
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region SetNewWaypointLocation
|
||||
static DWORD64 detourSetNewWaypointLocation(DWORD64 pLogicalPlayer, int a2, EGSDK::Vector3* newWaypointLoc);
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, int, EGSDK::Vector3*)> SetNewWaypointLocationHook{ "SetNewWaypointLocation", &EGSDK::Offsets::Get_SetNewWaypointLocation, &detourSetNewWaypointLocation };
|
||||
|
||||
static DWORD64 detourSetNewWaypointLocation(DWORD64 pLogicalPlayer, int a2, EGSDK::Vector3* newWaypointLoc) {
|
||||
DWORD64 result = SetNewWaypointLocationHook.pOriginal(pLogicalPlayer, a2, newWaypointLoc);
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, int, EGSDK::Vector3*), DWORD64, int, EGSDK::Vector3*> SetNewWaypointLocationHook{ "SetNewWaypointLocation", &EGSDK::Offsets::Get_SetNewWaypointLocation, [](DWORD64 pLogicalPlayer, int a2, EGSDK::Vector3* newWaypointLoc) -> DWORD64 {
|
||||
DWORD64 result = SetNewWaypointLocationHook.ExecuteCallbacksWithOriginal(pLogicalPlayer, a2, newWaypointLoc);
|
||||
Menu::Teleport::waypointCoords = *newWaypointLoc;
|
||||
if (EGSDK::Offsets::Get_SetNewWaypointLocationWaypointIsSetBoolInstr()) {
|
||||
const DWORD offset = *EGSDK::Offsets::Get_SetNewWaypointLocationWaypointIsSetBoolInstr();
|
||||
Menu::Teleport::waypointIsSet = reinterpret_cast<bool*>(pLogicalPlayer + offset);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
/*#pragma region HandleHeadBob
|
||||
static bool isHandleHeadBobRunning = false;
|
||||
|
||||
static void detourHandleHeadBob(DWORD64 a1, DWORD64 a2, DWORD64 a3, DWORD64 a4);
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(DWORD64, DWORD64, DWORD64, DWORD64)> HandleHeadBobHook{ "HandleHeadBob", &EGSDK::OffsetsGet_HandleHeadBob, &detourHandleHeadBob };
|
||||
|
||||
static void detourHandleHeadBob(DWORD64 a1, DWORD64 a2, DWORD64 a3, DWORD64 a4) {
|
||||
isHandleHeadBobRunning = true;
|
||||
HandleHeadBobHook.pOriginal(a1, a2, a3, a4);
|
||||
isHandleHeadBobRunning = false;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region SomeFloatCalcFunc
|
||||
static DWORD64 detourSomeFloatCalcFunc(float* a1, float* a2, float a3, DWORD64 a4, DWORD64 a5, DWORD64 a6);
|
||||
static EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(float*, float*, float, DWORD64, DWORD64, DWORD64)> SomeFloatCalcFuncHook{ "SomeFloatCalcFunc", &EGSDK::OffsetsGet_SomeFloatCalcFunc, &detourSomeFloatCalcFunc };
|
||||
|
||||
static DWORD64 detourSomeFloatCalcFunc(float* a1, float* a2, float a3, DWORD64 a4, DWORD64 a5, DWORD64 a6) {
|
||||
if (isHandleHeadBobRunning) {
|
||||
static int i = 1;
|
||||
if (*a1 < 0.002f && i >= 2 && i <= 3) {
|
||||
*a1 *= 2.0f;
|
||||
a3 *= 2.0f;
|
||||
}
|
||||
i++;
|
||||
if (i > 3)
|
||||
i = 1;
|
||||
}
|
||||
return SomeFloatCalcFuncHook.pOriginal(a1, a2, a3, a4, a5, a6);
|
||||
}
|
||||
#pragma endregion*/
|
||||
|
||||
#pragma region ByteHooks
|
||||
static unsigned char SaveGameCRCBoolCheckBytes[3] = { 0xB3, 0x01, 0x90 }; // mov bl, 01
|
||||
EGSDK::Utils::Hook::ByteHook<void*> SaveGameCRCBoolCheckHook{ "SaveGameCRCBoolCheck", &EGSDK::Offsets::Get_SaveGameCRCBoolCheck, SaveGameCRCBoolCheckBytes, sizeof(SaveGameCRCBoolCheckBytes) }; // and bl, dil
|
||||
|
@ -52,8 +52,7 @@ namespace EGT::ImGui_impl {
|
||||
return renderTarget;
|
||||
}
|
||||
|
||||
HRESULT(__stdcall* oPresent)(IDXGISwapChain*, UINT, UINT);
|
||||
HRESULT __stdcall hkPresent11(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags) {
|
||||
static void RenderImGui_DX11(IDXGISwapChain* pSwapChain) {
|
||||
static bool init = false;
|
||||
|
||||
if (!init) {
|
||||
@ -78,34 +77,34 @@ namespace EGT::ImGui_impl {
|
||||
init = true;
|
||||
}
|
||||
|
||||
for (int retries = 0;; retries++) {
|
||||
try {
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
Menu::FirstTimeRunning();
|
||||
if (Menu::menuToggle.GetValue())
|
||||
Menu::Render();
|
||||
Menu::FirstTimeRunning();
|
||||
if (Menu::menuToggle.GetValue())
|
||||
Menu::Render();
|
||||
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
|
||||
DeferredActions::Process();
|
||||
DeferredActions::Process();
|
||||
|
||||
if (d3d11RenderTargetView)
|
||||
d3d11DeviceContext->OMSetRenderTargets(1, &d3d11RenderTargetView, nullptr);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
if (d3d11RenderTargetView)
|
||||
d3d11DeviceContext->OMSetRenderTargets(1, &d3d11RenderTargetView, nullptr);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
return oPresent(pSwapChain, SyncInterval, Flags);
|
||||
} catch (const std::exception& e) {
|
||||
SPDLOG_ERROR("Exception thrown rendering ImGui in DX11: {}", e.what());
|
||||
if (retries >= 6) {
|
||||
SPDLOG_ERROR("Retried rendering ImGui in DX11 6 times, game will exit now.");
|
||||
IM_ASSERT(retries < 6 && "Retried rendering ImGui in DX11 6 times, game will exit now.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT(__stdcall* oPresent)(IDXGISwapChain*, UINT, UINT);
|
||||
HRESULT __stdcall hkPresent11(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags) {
|
||||
__try {
|
||||
RenderImGui_DX11(pSwapChain);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
SPDLOG_ERROR("Exception thrown rendering ImGui in DX11");
|
||||
}
|
||||
|
||||
return oPresent(pSwapChain, SyncInterval, Flags);
|
||||
}
|
||||
|
||||
HRESULT(__stdcall* oResizeBuffers)(IDXGISwapChain*, UINT, UINT, UINT, DXGI_FORMAT, UINT);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <spdlog\spdlog.h>
|
||||
#include <ImGui\backends\imgui_impl_dx12.h>
|
||||
#include <ImGui\backends\imgui_impl_win32.h>
|
||||
#include <EGSDK\Utils\Memory.h>
|
||||
#include <EGT\ImGui_impl\Win32_impl.h>
|
||||
#include <EGT\ImGui_impl\DeferredActions.h>
|
||||
#include <EGT\Menu\Menu.h>
|
||||
@ -111,73 +112,69 @@ namespace EGT::ImGui_impl {
|
||||
init = true;
|
||||
}
|
||||
|
||||
for (int retries = 0;; retries++) {
|
||||
try {
|
||||
if (!frameContext[0].main_render_target_resource)
|
||||
CreateRenderTarget(pSwapChain);
|
||||
if (!d3d12CommandQueue || !frameContext[0].main_render_target_resource)
|
||||
return;
|
||||
if (!frameContext[0].main_render_target_resource)
|
||||
CreateRenderTarget(pSwapChain);
|
||||
if (!d3d12CommandQueue || !frameContext[0].main_render_target_resource)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX12_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
ImGui_ImplDX12_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
Menu::FirstTimeRunning();
|
||||
if (Menu::menuToggle.GetValue())
|
||||
Menu::Render();
|
||||
Menu::FirstTimeRunning();
|
||||
if (Menu::menuToggle.GetValue())
|
||||
Menu::Render();
|
||||
|
||||
ImGui::Render();
|
||||
ImGui::Render();
|
||||
|
||||
DeferredActions::Process();
|
||||
DeferredActions::Process();
|
||||
|
||||
UINT backBufferIdx = pSwapChain->GetCurrentBackBufferIndex();
|
||||
ID3D12CommandAllocator* commandAllocator = frameContext[backBufferIdx].commandAllocator;
|
||||
commandAllocator->Reset();
|
||||
UINT backBufferIdx = pSwapChain->GetCurrentBackBufferIndex();
|
||||
ID3D12CommandAllocator* commandAllocator = frameContext[backBufferIdx].commandAllocator;
|
||||
commandAllocator->Reset();
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier{};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = frameContext[backBufferIdx].main_render_target_resource;
|
||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
d3d12CommandList->Reset(commandAllocator, NULL);
|
||||
d3d12CommandList->ResourceBarrier(1, &barrier);
|
||||
D3D12_RESOURCE_BARRIER barrier{};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = frameContext[backBufferIdx].main_render_target_resource;
|
||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
d3d12CommandList->Reset(commandAllocator, NULL);
|
||||
d3d12CommandList->ResourceBarrier(1, &barrier);
|
||||
|
||||
d3d12CommandList->OMSetRenderTargets(1, &frameContext[backBufferIdx].main_render_target_descriptor, FALSE, NULL);
|
||||
d3d12CommandList->SetDescriptorHeaps(1, &d3d12DescriptorHeapImGuiRender);
|
||||
d3d12CommandList->OMSetRenderTargets(1, &frameContext[backBufferIdx].main_render_target_descriptor, FALSE, NULL);
|
||||
d3d12CommandList->SetDescriptorHeaps(1, &d3d12DescriptorHeapImGuiRender);
|
||||
|
||||
ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), d3d12CommandList);
|
||||
ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), d3d12CommandList);
|
||||
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||
|
||||
d3d12CommandList->ResourceBarrier(1, &barrier);
|
||||
d3d12CommandList->Close();
|
||||
d3d12CommandList->ResourceBarrier(1, &barrier);
|
||||
d3d12CommandList->Close();
|
||||
|
||||
d3d12CommandQueue->ExecuteCommandLists(1, reinterpret_cast<ID3D12CommandList* const*>(&d3d12CommandList));
|
||||
|
||||
break;
|
||||
} catch (const std::exception& e) {
|
||||
SPDLOG_ERROR("Exception thrown rendering ImGui in DX12: {}", e.what());
|
||||
if (retries >= 6) {
|
||||
SPDLOG_ERROR("Retried rendering ImGui in DX12 6 times, game will exit now.");
|
||||
IM_ASSERT(retries < 6 && "Retried rendering ImGui in DX12 6 times, game will exit now.");
|
||||
}
|
||||
}
|
||||
}
|
||||
d3d12CommandQueue->ExecuteCommandLists(1, reinterpret_cast<ID3D12CommandList* const*>(&d3d12CommandList));
|
||||
}
|
||||
|
||||
HRESULT(__stdcall* oPresent)(IDXGISwapChain3*, UINT, UINT);
|
||||
HRESULT __stdcall hkPresent12(IDXGISwapChain3* pSwapChain, UINT SyncInterval, UINT Flags) {
|
||||
RenderImGui_DX12(pSwapChain);
|
||||
__try {
|
||||
RenderImGui_DX12(pSwapChain);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
SPDLOG_ERROR("Exception thrown rendering ImGui in DX12");
|
||||
}
|
||||
|
||||
return oPresent(pSwapChain, SyncInterval, Flags);
|
||||
}
|
||||
|
||||
HRESULT(__stdcall* oPresent1)(IDXGISwapChain3*, UINT, UINT, const DXGI_PRESENT_PARAMETERS* pPresentParameters);
|
||||
HRESULT __stdcall hkPresent112(IDXGISwapChain3* pSwapChain, UINT SyncInterval, UINT PresentFlags, const DXGI_PRESENT_PARAMETERS* pPresentParameters) {
|
||||
RenderImGui_DX12(pSwapChain);
|
||||
__try {
|
||||
RenderImGui_DX12(pSwapChain);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
SPDLOG_ERROR("Exception thrown rendering ImGui in DX12");
|
||||
}
|
||||
|
||||
return oPresent1(pSwapChain, SyncInterval, PresentFlags, pPresentParameters);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace EGT::Menu {
|
||||
|
||||
EGSDK::Vector3 cameraOffset{};
|
||||
float firstPersonFOV = baseFOV;
|
||||
float originalFirstPersonFOVAfterZoomIn = firstPersonFOV;
|
||||
ImGui::KeyBindOption firstPersonZoomIn{ 'Q' , false };
|
||||
static bool isZoomingIn = false;
|
||||
|
||||
@ -35,8 +36,8 @@ namespace EGT::Menu {
|
||||
ImGui::KeyBindOption tpUseTPPModel{ VK_F2 };
|
||||
float thirdPersonFOV = baseFOV;
|
||||
float thirdPersonDistanceBehindPlayer = 2.0f;
|
||||
float thirdPersonHeightAbovePlayer = 1.35f;
|
||||
float thirdPersonHorizontalDistanceFromPlayer = 0.0f;
|
||||
float thirdPersonHeightAbovePlayer = 1.3f;
|
||||
float thirdPersonHorizontalDistanceFromPlayer = -0.6f;
|
||||
|
||||
float lensDistortion = 20.0f;
|
||||
static float altLensDistortion = lensDistortion;
|
||||
@ -48,89 +49,77 @@ namespace EGT::Menu {
|
||||
static void UpdateFirstPersonFOV() {
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
auto viewCam = iLevel ? reinterpret_cast<EGSDK::Engine::CBaseCamera*>(iLevel->GetViewCamera()) : nullptr;
|
||||
{
|
||||
static float previousFirstPersonFOV = firstPersonFOV;
|
||||
|
||||
static float previousFirstPersonFOV = firstPersonFOV;
|
||||
static bool hasChangedZoomLevel = false;
|
||||
static int zoomLevel = 0;
|
||||
|
||||
if (iLevel && viewCam) {
|
||||
if (goProMode.GetValue()) {
|
||||
if (goProMode.HasChangedTo(true)) {
|
||||
previousFirstPersonFOV = firstPersonFOV;
|
||||
goProMode.SetPrevValue(true);
|
||||
}
|
||||
|
||||
if (iLevel && viewCam)
|
||||
viewCam->SetFOV(110.0f);
|
||||
viewCam->SetFOV(110.0f);
|
||||
firstPersonFOV = 110;
|
||||
return;
|
||||
} else if (goProMode.HasChangedTo(false)) {
|
||||
firstPersonFOV = previousFirstPersonFOV;
|
||||
goProMode.SetPrevValue(false);
|
||||
|
||||
if (iLevel && viewCam)
|
||||
viewCam->SetFOV(firstPersonFOV);
|
||||
viewCam->SetFOV(firstPersonFOV);
|
||||
}
|
||||
}
|
||||
|
||||
static float originalFirstPersonFOV = firstPersonFOV;
|
||||
static float previousFirstPersonFOV = firstPersonFOV;
|
||||
static bool scrolledDown = false;
|
||||
static bool hasChangedZoomLevel = false;
|
||||
static int zoomLevel = 0;
|
||||
if (iLevel && viewCam && !thirdPersonCamera.GetValue() && !freeCam.GetValue()) {
|
||||
if (firstPersonZoomIn.IsKeyDown()) {
|
||||
if (firstPersonZoomIn.IsKeyPressed()) {
|
||||
hasChangedZoomLevel = true;
|
||||
if (!isZoomingIn) {
|
||||
originalFirstPersonFOV = firstPersonFOV;
|
||||
previousFirstPersonFOV = originalFirstPersonFOV;
|
||||
originalFirstPersonFOVAfterZoomIn = firstPersonFOV;
|
||||
previousFirstPersonFOV = originalFirstPersonFOVAfterZoomIn;
|
||||
} else
|
||||
previousFirstPersonFOV = firstPersonFOV;
|
||||
}
|
||||
|
||||
isZoomingIn = true;
|
||||
float newFOV = previousFirstPersonFOV;
|
||||
switch (zoomLevel) {
|
||||
case 0:
|
||||
newFOV = std::max(originalFirstPersonFOV - 25.0f, 42.0f);
|
||||
break;
|
||||
case 1:
|
||||
newFOV = std::max(originalFirstPersonFOV - 45.0f, 25.0f);
|
||||
break;
|
||||
case 2:
|
||||
newFOV = std::max(originalFirstPersonFOV - 65.0f, 15.0f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
firstPersonFOV = ImGui::AnimateLerp("zoomInFOVLerp", previousFirstPersonFOV, newFOV, 0.3f, hasChangedZoomLevel, &ImGui::AnimEaseOutSine);
|
||||
|
||||
float targetFOV = previousFirstPersonFOV;
|
||||
if (zoomLevel == 0)
|
||||
targetFOV = std::max(originalFirstPersonFOVAfterZoomIn - 25.0f, 42.0f);
|
||||
else if (zoomLevel == 1)
|
||||
targetFOV = std::max(originalFirstPersonFOVAfterZoomIn - 45.0f, 25.0f);
|
||||
else if (zoomLevel == 2)
|
||||
targetFOV = std::max(originalFirstPersonFOVAfterZoomIn - 65.0f, 15.0f);
|
||||
|
||||
firstPersonFOV = ImGui::AnimateLerp("zoomInFOVLerp", previousFirstPersonFOV, targetFOV, 0.3f, hasChangedZoomLevel, &ImGui::AnimEaseOutSine);
|
||||
viewCam->SetFOV(firstPersonFOV);
|
||||
hasChangedZoomLevel = false;
|
||||
|
||||
if (ImGui::KeyBindOption::scrolledMouseWheelUp) {
|
||||
ImGui::KeyBindOption::scrolledMouseWheelUp = false;
|
||||
if (zoomLevel < 2) {
|
||||
scrolledDown = false;
|
||||
hasChangedZoomLevel = true;
|
||||
previousFirstPersonFOV = firstPersonFOV;
|
||||
zoomLevel++;
|
||||
previousFirstPersonFOV = firstPersonFOV;
|
||||
hasChangedZoomLevel = true;
|
||||
}
|
||||
} else if (ImGui::KeyBindOption::scrolledMouseWheelDown) {
|
||||
ImGui::KeyBindOption::scrolledMouseWheelDown = false;
|
||||
if (zoomLevel > 0) {
|
||||
scrolledDown = true;
|
||||
hasChangedZoomLevel = true;
|
||||
previousFirstPersonFOV = firstPersonFOV;
|
||||
zoomLevel--;
|
||||
previousFirstPersonFOV = firstPersonFOV;
|
||||
hasChangedZoomLevel = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
zoomLevel = 0;
|
||||
scrolledDown = false;
|
||||
if (firstPersonZoomIn.IsKeyReleased()) {
|
||||
hasChangedZoomLevel = true;
|
||||
previousFirstPersonFOV = firstPersonFOV;
|
||||
}
|
||||
if (!EGSDK::Utils::Values::are_samef(firstPersonFOV, originalFirstPersonFOV) && isZoomingIn) {
|
||||
firstPersonFOV = ImGui::AnimateLerp("zoomInFOVLerp", previousFirstPersonFOV, originalFirstPersonFOV, 0.25f, hasChangedZoomLevel, &ImGui::AnimEaseOutSine);
|
||||
|
||||
if (!EGSDK::Utils::Values::are_samef(firstPersonFOV, originalFirstPersonFOVAfterZoomIn) && isZoomingIn) {
|
||||
firstPersonFOV = ImGui::AnimateLerp("zoomInFOVLerp", previousFirstPersonFOV, originalFirstPersonFOVAfterZoomIn, 0.25f, hasChangedZoomLevel, &ImGui::AnimEaseOutSine);
|
||||
viewCam->SetFOV(firstPersonFOV);
|
||||
hasChangedZoomLevel = false;
|
||||
} else
|
||||
@ -254,7 +243,7 @@ namespace EGT::Menu {
|
||||
static void UpdateDisabledOptions() {
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
freeCam.SetChangesAreDisabled(!iLevel || !iLevel->IsLoaded() || photoMode.GetValue() || isZoomingIn);
|
||||
thirdPersonCamera.SetChangesAreDisabled(freeCam.GetValue() || photoMode.GetValue() || isZoomingIn);
|
||||
thirdPersonCamera.SetChangesAreDisabled(!iLevel || !iLevel->IsLoaded() || freeCam.GetValue() || photoMode.GetValue() || isZoomingIn);
|
||||
tpUseTPPModel.SetChangesAreDisabled(freeCam.GetValue() || photoMode.GetValue());
|
||||
}
|
||||
static void HandleToggles() {
|
||||
@ -290,6 +279,7 @@ namespace EGT::Menu {
|
||||
ImGui::SetNextItemWidth(400.0f * Menu::scale);
|
||||
ImGui::SliderFloat3("Camera Offset (XYZ)", reinterpret_cast<float*>(&cameraOffset), -0.5f, 0.5f, "%.2fm");
|
||||
ImGui::EndDisabled();
|
||||
ImGui::CheckboxHotkey("Zoom In", &firstPersonZoomIn, "Allows zooming in with the specified hotkey and changing zoom level with the mouse wheel");
|
||||
|
||||
ImGui::SeparatorText("Third Person Camera");
|
||||
ImGui::BeginDisabled(thirdPersonCamera.GetChangesAreDisabled());
|
||||
@ -332,7 +322,6 @@ namespace EGT::Menu {
|
||||
ImGui::CheckboxHotkey("Disable Photo Mode Limits", &disablePhotoModeLimits, "Disables the invisible box while in Photo Mode");
|
||||
ImGui::SameLine();
|
||||
ImGui::CheckboxHotkey("Disable Head Correction", &disableHeadCorrection, "Disables centering of the player's hands to the center of the camera");
|
||||
ImGui::CheckboxHotkey("Zoom In", &firstPersonZoomIn);
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(IM_COL32(200, 0, 0, 255)), "* GoPro Mode is best used with Head Bob Reduction set to 0 and Player FOV\nCorrection set to 0 in game options");
|
||||
|
@ -144,16 +144,14 @@ namespace EGT::Menu {
|
||||
ImGui::Spacing(ImVec2(0.0f, 5.0f));
|
||||
|
||||
ImGui::BeginDisabled(!timePassedFromWelcomeScreen.DidTimePass());
|
||||
{
|
||||
const std::string btnText = "Let me play!" + (!timePassedFromWelcomeScreen.DidTimePass() ? (" (" + std::to_string(10 - (timePassedFromWelcomeScreen.GetTimePassed() / 1000)) + ")") : "");
|
||||
if (ImGui::ButtonCentered(btnText.c_str(), ImVec2(0.0f, 30.0f) * scale)) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
firstTimeRunning.Set(false);
|
||||
if (hasSeenChangelog.GetValue())
|
||||
menuToggle.SetChangesAreDisabled(false);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
const std::string btnText = "Let me play!" + (!timePassedFromWelcomeScreen.DidTimePass() ? (" (" + std::to_string(10 - (timePassedFromWelcomeScreen.GetTimePassed() / 1000)) + ")") : "");
|
||||
if (ImGui::ButtonCentered(btnText.c_str(), ImVec2(0.0f, 30.0f) * scale)) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
firstTimeRunning.Set(false);
|
||||
if (hasSeenChangelog.GetValue())
|
||||
menuToggle.SetChangesAreDisabled(false);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,6 @@ namespace EGT::Menu {
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,7 @@
|
||||
#include <EGSDK\GamePH\GameDI_PH.h>
|
||||
#include <EGSDK\GamePH\LevelDI.h>
|
||||
#include <EGT\Menu\Misc.h>
|
||||
|
||||
namespace EGT::GamePH::Hooks {
|
||||
extern EGSDK::Utils::Hook::ByteHook<void*> SaveGameCRCBoolCheckHook;
|
||||
}
|
||||
#include <EGT\GamePH\GamePH_Hooks.h>
|
||||
|
||||
namespace EGT::Menu {
|
||||
namespace Misc {
|
||||
@ -18,7 +15,7 @@ namespace EGT::Menu {
|
||||
ImGui::Option increaseDataPAKsLimit{ false };
|
||||
|
||||
static void UpdateDisabledOptions() {
|
||||
EGSDK::GamePH::LevelDI* iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
disableHUD.SetChangesAreDisabled(!iLevel || !iLevel->IsLoaded());
|
||||
}
|
||||
|
||||
@ -26,14 +23,13 @@ namespace EGT::Menu {
|
||||
void Tab::Update() {
|
||||
UpdateDisabledOptions();
|
||||
|
||||
EGSDK::GamePH::LevelDI* iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
if (!iLevel)
|
||||
return;
|
||||
|
||||
if (!iLevel->IsLoaded() && disableHUD.GetValue()) {
|
||||
disableHUD.SetBothValues(false);
|
||||
iLevel->ShowUIManager(true);
|
||||
|
||||
return;
|
||||
}
|
||||
if (disableHUD.HasChanged()) {
|
||||
@ -41,19 +37,19 @@ namespace EGT::Menu {
|
||||
iLevel->ShowUIManager(!disableHUD.GetValue());
|
||||
}
|
||||
|
||||
EGSDK::GamePH::GameDI_PH* gameDI_PH = EGSDK::GamePH::GameDI_PH::Get();
|
||||
if (!gameDI_PH)
|
||||
return;
|
||||
gameDI_PH->blockPauseGameOnPlayerAfk = disableGamePauseWhileAFK.GetValue();
|
||||
auto gameDI_PH = EGSDK::GamePH::GameDI_PH::Get();
|
||||
if (gameDI_PH)
|
||||
gameDI_PH->blockPauseGameOnPlayerAfk = disableGamePauseWhileAFK.GetValue();
|
||||
}
|
||||
void Tab::Render() {
|
||||
ImGui::SeparatorText("Misc##Misc");
|
||||
ImGui::CheckboxHotkey("Disable Game Pause While AFK", &disableGamePauseWhileAFK, "Prevents the game from pausing while you're afk");
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(disableHUD.GetChangesAreDisabled()); {
|
||||
ImGui::CheckboxHotkey("Disable HUD", &disableHUD, "Disables the entire HUD, including any sort of menus like the pause menu");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(disableHUD.GetChangesAreDisabled());
|
||||
ImGui::CheckboxHotkey("Disable HUD", &disableHUD, "Disables the entire HUD, including any sort of menus like the pause menu");
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SeparatorText("Game Checks##Misc");
|
||||
if (ImGui::Checkbox("Disable Savegame CRC Check *", &disableSavegameCRCCheck, "Stops the game from falsely saying your savegame is corrupt whenever you modify it outside of the game using a save editor"))
|
||||
disableSavegameCRCCheck.GetValue() ? EGT::GamePH::Hooks::SaveGameCRCBoolCheckHook.Enable() : EGT::GamePH::Hooks::SaveGameCRCBoolCheckHook.Disable();
|
||||
|
@ -56,23 +56,18 @@ namespace EGT::Menu {
|
||||
while (std::getline(coordStream, coordItem, ',')) {
|
||||
try {
|
||||
coordValues.push_back(std::stof(coordItem));
|
||||
} catch (const std::invalid_argument& e) {
|
||||
UNREFERENCED_PARAMETER(e);
|
||||
SPDLOG_ERROR("ParseTeleportLocations: Invalid coordinate value: {}, for location: {}", coordItem, tpLocName);
|
||||
} catch (...) {
|
||||
SPDLOG_ERROR("Invalid coordinate value: {}, for location: {}", coordItem, tpLocName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EGSDK::Vector3 tpLocPos{};
|
||||
if (coordValues.size() == 3) {
|
||||
tpLocPos.X = coordValues[0];
|
||||
tpLocPos.Y = coordValues[1];
|
||||
tpLocPos.Z = coordValues[2];
|
||||
teleportLocations.push_back({ tpLocName, tpLocPos });
|
||||
} else
|
||||
SPDLOG_ERROR("ParseTeleportLocations: Invalid number of coordinates ({}) for location: {}", coordValues.size(), tpLocName);
|
||||
if (coordValues.size() == 3)
|
||||
teleportLocations.push_back({ tpLocName, { coordValues[0], coordValues[1], coordValues[2] } });
|
||||
else
|
||||
SPDLOG_ERROR("Invalid number of coordinates ({}) for location: {}", coordValues.size(), tpLocName);
|
||||
} else
|
||||
SPDLOG_ERROR("ParseTeleportLocations: Invalid format for TP location: {}", item);
|
||||
SPDLOG_ERROR("Invalid format for TP location: {}", item);
|
||||
}
|
||||
|
||||
SPDLOG_INFO("Successfully parsed teleport locations:");
|
||||
@ -89,7 +84,6 @@ namespace EGT::Menu {
|
||||
|
||||
for (size_t i = 0; i < teleportLocations.size(); ++i) {
|
||||
const TeleportLocation& loc = teleportLocations[i];
|
||||
|
||||
ss << loc.name << ":" << loc.pos.X << "," << loc.pos.Y << "," << loc.pos.Z;
|
||||
if (i < teleportLocations.size() - 1)
|
||||
ss << ";";
|
||||
@ -97,9 +91,16 @@ namespace EGT::Menu {
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
static std::string GetFormattedPosition(const EGSDK::Vector3* position) {
|
||||
if (!position || position->isDefault())
|
||||
return "X: 0.00, Y: 0.00, Z: 0.00";
|
||||
static std::string formattedStr{};
|
||||
formattedStr = std::format("X: {:.2f}, Y: {:.2f}, Z: {:.2f}", position->X, position->Y, position->Z);
|
||||
return formattedStr;
|
||||
}
|
||||
|
||||
static bool isTeleportationDisabled() {
|
||||
EGSDK::GamePH::LevelDI* iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
if (!iLevel || !iLevel->IsLoaded())
|
||||
return true;
|
||||
if (!Camera::freeCam.GetValue() && !EGSDK::Engine::CBulletPhysicsCharacter::Get())
|
||||
@ -115,42 +116,28 @@ namespace EGT::Menu {
|
||||
return;
|
||||
|
||||
if (Camera::freeCam.GetValue()) {
|
||||
EGSDK::GamePH::FreeCamera* freeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
if (!freeCam)
|
||||
return;
|
||||
|
||||
EGSDK::Vector3 camPos{};
|
||||
freeCam->GetPosition(&camPos);
|
||||
if (camPos.isDefault())
|
||||
return;
|
||||
|
||||
teleportCoords = camPos;
|
||||
auto freeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
if (freeCam)
|
||||
freeCam->GetPosition(&teleportCoords);
|
||||
} else {
|
||||
EGSDK::Engine::CBulletPhysicsCharacter* playerCharacter = EGSDK::Engine::CBulletPhysicsCharacter::Get();
|
||||
if (!playerCharacter)
|
||||
return;
|
||||
|
||||
teleportCoords = playerCharacter->playerPos;
|
||||
auto playerCharacter = EGSDK::Engine::CBulletPhysicsCharacter::Get();
|
||||
if (playerCharacter)
|
||||
teleportCoords = playerCharacter->playerPos;
|
||||
}
|
||||
}
|
||||
static bool TeleportPlayerTo(const EGSDK::Vector3& pos) {
|
||||
if (isTeleportationDisabled())
|
||||
return false;
|
||||
|
||||
if (pos.isDefault())
|
||||
if (isTeleportationDisabled() || pos.isDefault())
|
||||
return false;
|
||||
|
||||
if (Camera::freeCam.GetValue()) {
|
||||
EGSDK::GamePH::FreeCamera* freeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
auto freeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
if (!freeCam)
|
||||
return false;
|
||||
|
||||
freeCam->SetPosition(&pos);
|
||||
} else {
|
||||
EGSDK::Engine::CBulletPhysicsCharacter* playerCharacter = EGSDK::Engine::CBulletPhysicsCharacter::Get();
|
||||
auto playerCharacter = EGSDK::Engine::CBulletPhysicsCharacter::Get();
|
||||
if (!playerCharacter)
|
||||
return false;
|
||||
|
||||
if (Player::freezePlayer.GetValue())
|
||||
playerCharacter->posBeforeFreeze = pos;
|
||||
playerCharacter->MoveCharacter(pos);
|
||||
@ -162,29 +149,20 @@ namespace EGT::Menu {
|
||||
static void UpdateTeleportPos() {
|
||||
if (isTeleportationDisabled()) {
|
||||
if (!teleportCoords.isDefault())
|
||||
teleportCoords = EGSDK::Vector3();
|
||||
teleportCoords = {};
|
||||
return;
|
||||
}
|
||||
if (!teleportCoords.isDefault())
|
||||
return;
|
||||
|
||||
if (Camera::freeCam.GetValue()) {
|
||||
EGSDK::GamePH::FreeCamera* freeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
if (!freeCam)
|
||||
return;
|
||||
|
||||
EGSDK::Vector3 camPos{};
|
||||
freeCam->GetPosition(&camPos);
|
||||
if (camPos.isDefault())
|
||||
return;
|
||||
|
||||
teleportCoords = camPos;
|
||||
auto freeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
if (freeCam)
|
||||
freeCam->GetPosition(&teleportCoords);
|
||||
} else {
|
||||
EGSDK::Engine::CBulletPhysicsCharacter* playerCharacter = EGSDK::Engine::CBulletPhysicsCharacter::Get();
|
||||
if (!playerCharacter)
|
||||
return;
|
||||
|
||||
teleportCoords = playerCharacter->playerPos;
|
||||
auto playerCharacter = EGSDK::Engine::CBulletPhysicsCharacter::Get();
|
||||
if (playerCharacter)
|
||||
teleportCoords = playerCharacter->playerPos;
|
||||
}
|
||||
}
|
||||
static void HotkeysUpdate() {
|
||||
@ -288,26 +266,8 @@ namespace EGT::Menu {
|
||||
if (tpSaveResult)
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), 0, ImVec2(0.5f, 0.5f));
|
||||
if (ImGui::BeginPopupModal("Location already exists", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::PushItemWidth(500.0f * Menu::scale);
|
||||
ImGui::TextCentered("The location you have entered already exists. Either the name of the location, or the position of the location is already inside the list. If you want to change it then please remove it and add it again.", false);
|
||||
if (ImGui::Button("OK", ImVec2(500.0f, 0.0f) * Menu::scale)) {
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), 0, ImVec2(0.5f, 0.5f));
|
||||
if (ImGui::BeginPopupModal("Couldn't add location", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::PushItemWidth(500.0f * Menu::scale);
|
||||
ImGui::TextCentered("Something went wrong trying to add a location. Either the player class or camera class are not found, or you're in a place in the game where the character or camera isn't properly loaded. If this happens, even though you know it should work fine, please contact @EricPlayZ on NexusMods, GitHub or Discord.");
|
||||
if (ImGui::Button("OK", ImVec2(500.0f, 0.0f) * Menu::scale)) {
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::DisplaySimplePopupMessageCentered(500.0f, Menu::scale, "Location already exists", "The location you have entered already exists. Either the name of the location, or the position of the location is already inside the list. If you want to change it then please remove it and add it again.", false);
|
||||
ImGui::DisplaySimplePopupMessageCentered(500.0f, Menu::scale, "Couldn't add location", "Something went wrong trying to add a location. Either the player class or camera class are not found, or you're in a place in the game where the character or camera isn't properly loaded. If this happens, even though you know it should work fine, please contact @EricPlayZ on NexusMods, GitHub or Discord.");
|
||||
}
|
||||
|
||||
Tab Tab::instance{};
|
||||
@ -317,86 +277,57 @@ namespace EGT::Menu {
|
||||
}
|
||||
void Tab::Render() {
|
||||
ImGui::SeparatorText("Saved Locations##Teleport");
|
||||
ImGui::PushItemWidth(672.0f * Menu::scale);
|
||||
ImGui::SetNextItemWidth(672.0f * Menu::scale);
|
||||
ImGui::ListBox("##SavedTPLocationsListBox", &selectedTPLocation, savedTeleportLocationNamesPtrs.data(), static_cast<int>(savedTeleportLocationNamesPtrs.size()), 5);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::BeginDisabled(isTeleportationDisabled() || selectedTPLocation < 0 || selectedTPLocation >= savedTeleportLocations.size()); {
|
||||
if (ImGui::ButtonHotkey("Teleport to Selected Location", &teleportToSelectedLocation, "Teleports player to selected location from the saved locations list"))
|
||||
TeleportPlayerTo(savedTeleportLocations[selectedTPLocation].pos);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::BeginDisabled(isTeleportationDisabled() || selectedTPLocation < 0 || selectedTPLocation >= savedTeleportLocations.size());
|
||||
if (ImGui::ButtonHotkey("Teleport to Selected Location", &teleportToSelectedLocation, "Teleports player to selected location from the saved locations list"))
|
||||
TeleportPlayerTo(savedTeleportLocations[selectedTPLocation].pos);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(selectedTPLocation < 0 || selectedTPLocation >= savedTeleportLocations.size()); {
|
||||
if (ImGui::Button("Remove Selected Location")) {
|
||||
savedTeleportLocations.erase(savedTeleportLocations.begin() + selectedTPLocation);
|
||||
UpdateTeleportLocationVisualNames();
|
||||
selectedTPLocation = -1;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::BeginDisabled(selectedTPLocation < 0 || selectedTPLocation >= savedTeleportLocations.size());
|
||||
if (ImGui::Button("Remove Selected Location")) {
|
||||
savedTeleportLocations.erase(savedTeleportLocations.begin() + selectedTPLocation);
|
||||
UpdateTeleportLocationVisualNames();
|
||||
selectedTPLocation = -1;
|
||||
}
|
||||
ImGui::BeginDisabled(isTeleportationDisabled()); {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save Current Location"))
|
||||
ImGui::OpenPopup("Give the location a name");
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::BeginDisabled(isTeleportationDisabled());
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save Current Location"))
|
||||
ImGui::OpenPopup("Give the location a name");
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SeparatorText("Custom##Teleport");
|
||||
ImGui::BeginDisabled(isTeleportationDisabled()); {
|
||||
static std::string playerPos = "Player Position = X: 0.00, Y: 0.00, Z: 0.00";
|
||||
EGSDK::Engine::CBulletPhysicsCharacter* playerCharacter = EGSDK::Engine::CBulletPhysicsCharacter::Get();
|
||||
if (!playerCharacter)
|
||||
playerPos = "Player Position -- X: 0.00, Y: 0.00, Z: 0.00";
|
||||
else {
|
||||
playerPos = "Player Position -- X: " + std::format("{:.2f}", playerCharacter->playerPos.data.X) + ", Y: " + std::format("{:.2f}", playerCharacter->playerPos.data.Y) + ", Z: " + std::format("{:.2f}", playerCharacter->playerPos.data.Z);
|
||||
}
|
||||
ImGui::BeginDisabled(isTeleportationDisabled());
|
||||
auto playerCharacter = EGSDK::Engine::CBulletPhysicsCharacter::Get();
|
||||
auto freeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
|
||||
static std::string cameraPos = "Free Camera Position -- X: 0.00, Y: 0.00, Z: 0.00";
|
||||
EGSDK::GamePH::FreeCamera* freeCam = EGSDK::GamePH::FreeCamera::Get();
|
||||
if (!Camera::freeCam.GetValue() || !freeCam)
|
||||
cameraPos = "Free Camera Position -- X: 0.00, Y: 0.00, Z: 0.00";
|
||||
else {
|
||||
EGSDK::Vector3 camPos{};
|
||||
freeCam->GetPosition(&camPos);
|
||||
if (camPos.isDefault())
|
||||
cameraPos = "Free Camera Position -- X: 0.00, Y: 0.00, Z: 0.00";
|
||||
else
|
||||
cameraPos = "Free Camera Position -- X: " + std::format("{:.2f}", camPos.X) + ", Y: " + std::format("{:.2f}", camPos.Y) + ", Z: " + std::format("{:.2f}", camPos.Z);
|
||||
}
|
||||
EGSDK::Vector3 camPos{};
|
||||
ImGui::Text("Player Position: %s", GetFormattedPosition(playerCharacter ? &playerCharacter->playerPos.data : nullptr).data());
|
||||
ImGui::Text("Free Camera Position: %s", GetFormattedPosition(freeCam && Camera::freeCam.GetValue() ? freeCam->GetPosition(&camPos) : nullptr).data());
|
||||
ImGui::Text("Waypoint Position: %s", GetFormattedPosition(waypointIsSet && *waypointIsSet && !waypointCoords.isDefault() ? &waypointCoords : nullptr).data());
|
||||
|
||||
static std::string waypointPos = "Waypoint Position = X: 0.00, Y: 0.00, Z: 0.00";
|
||||
if (!waypointIsSet || !*waypointIsSet || waypointCoords.isDefault())
|
||||
waypointPos = "Waypoint Position -- X: 0.00, Y: 0.00, Z: 0.00";
|
||||
else {
|
||||
waypointPos = "Waypoint Position -- X: " + std::format("{:.2f}", waypointCoords.X) + ", Y: " + std::format("{:.2f}", waypointCoords.Y) + ", Z: " + std::format("{:.2f}", waypointCoords.Z);
|
||||
}
|
||||
ImGui::SetNextItemWidth(500.0f * Menu::scale);
|
||||
ImGui::InputFloat3("Teleport Coords (XYZ)", reinterpret_cast<float*>(&teleportCoords), "%.2fm");
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Text(playerPos.data());
|
||||
ImGui::Text(cameraPos.data());
|
||||
ImGui::Text(waypointPos.data());
|
||||
ImGui::BeginDisabled(isTeleportationDisabled() || !waypointIsSet || !*waypointIsSet);
|
||||
if (ImGui::ButtonHotkey("Teleport to Waypoint", &teleportToWaypoint, "Teleports player to waypoint.\nWARNING: If the waypoint is selected to track an object/item on the map, Teleport to Waypoint will not work, if so just set the waypoint nearby instead.\nWARNING: Your player height won't change when teleporting, so make sure you catch yourself if you fall under the map because of the teleportation"))
|
||||
justTeleportedToWaypoint = TeleportPlayerTo(waypointCoords);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SetNextItemWidth(500.0f * Menu::scale);
|
||||
ImGui::InputFloat3("Teleport Coords (XYZ)", reinterpret_cast<float*>(&teleportCoords), "%.2fm");
|
||||
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::BeginDisabled(isTeleportationDisabled() || !waypointIsSet || !*waypointIsSet); {
|
||||
if (ImGui::ButtonHotkey("Teleport to Waypoint", &teleportToWaypoint, "Teleports player to waypoint.\nWARNING: If the waypoint is selected to track an object/item on the map, Teleport to Waypoint will not work, if so just set the waypoint nearby instead.\nWARNING: Your player height won't change when teleporting, so make sure you catch yourself if you fall under the map because of the teleportation"))
|
||||
justTeleportedToWaypoint = TeleportPlayerTo(waypointCoords);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(isTeleportationDisabled()); {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::ButtonHotkey("Teleport to Coords", &teleportToCoords, "Teleports player to the coords specified in the input boxes above"))
|
||||
TeleportPlayerTo(teleportCoords);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Get Player Coords"))
|
||||
SyncTPCoordsToPlayer();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::BeginDisabled(isTeleportationDisabled());
|
||||
ImGui::SameLine();
|
||||
if (ImGui::ButtonHotkey("Teleport to Coords", &teleportToCoords, "Teleports player to the coords specified in the input boxes above"))
|
||||
TeleportPlayerTo(teleportCoords);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Get Player Coords"))
|
||||
SyncTPCoordsToPlayer();
|
||||
ImGui::EndDisabled();
|
||||
|
||||
HandleDialogs();
|
||||
}
|
||||
|
@ -1,36 +1,14 @@
|
||||
#include <Windows.h>
|
||||
#include <semaphore>
|
||||
#include <EGSDK\Utils\Hook.h>
|
||||
|
||||
namespace EGT::Core {
|
||||
extern void OpenIOBuffer();
|
||||
extern void CloseIOBuffer();
|
||||
extern void EnableConsole();
|
||||
extern void DisableConsole();
|
||||
|
||||
extern std::counting_semaphore<4> maxHookThreads;
|
||||
|
||||
extern void InitLogger();
|
||||
|
||||
extern DWORD64 WINAPI MainThread(HMODULE hModule);
|
||||
extern void Cleanup();
|
||||
}
|
||||
|
||||
namespace EGT::Engine {
|
||||
namespace Hooks {
|
||||
extern EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, UINT, UINT, DWORD64*, DWORD64(*)(DWORD64, DWORD, DWORD64, char*, int), INT16, DWORD64, UINT)> MountDataPaksHook;
|
||||
extern EGSDK::Utils::Hook::MHook<void*, void*(*)(void*)> AuthenticateDataAddNewFileHook;
|
||||
extern EGSDK::Utils::Hook::MHook<void*, bool(*)(void*)> FsCheckZipCrcHook;
|
||||
extern EGSDK::Utils::Hook::MHook<void*, DWORD64(*)(DWORD64, DWORD, DWORD)> FsOpenHook;
|
||||
}
|
||||
}
|
||||
#include <EGT\Core\Core.h>
|
||||
#include <EGT\Engine\Engine_Hooks.h>
|
||||
|
||||
static HANDLE mainThreadHandle{};
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE moduleHandle, DWORD64 reasonForCall, void* lpReserved) {
|
||||
switch (reasonForCall) {
|
||||
case DLL_PROCESS_ATTACH: {
|
||||
EGT::Core::OpenIOBuffer();
|
||||
EGT::Core::InitLogger();
|
||||
|
||||
MH_Initialize();
|
||||
@ -56,8 +34,6 @@ BOOL APIENTRY DllMain(HMODULE moduleHandle, DWORD64 reasonForCall, void* lpReser
|
||||
case DLL_PROCESS_DETACH: {
|
||||
SPDLOG_INFO("DLL_PROCESS_DETACH");
|
||||
EGT::Core::Cleanup();
|
||||
EGT::Core::DisableConsole();
|
||||
EGT::Core::CloseIOBuffer();
|
||||
|
||||
if (mainThreadHandle) {
|
||||
SPDLOG_INFO("Closing main thread handle");
|
||||
|
Reference in New Issue
Block a user