diff --git a/GolemHelper.sln b/GolemHelper.sln new file mode 100644 index 0000000..c9f89d5 --- /dev/null +++ b/GolemHelper.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35527.113 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GolemHelper", "GolemHelper\GolemHelper.vcxproj", "{46CF5BA6-DB8A-4B64-8AE0-5970961AB00F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {46CF5BA6-DB8A-4B64-8AE0-5970961AB00F}.Debug|x64.ActiveCfg = Debug|x64 + {46CF5BA6-DB8A-4B64-8AE0-5970961AB00F}.Debug|x64.Build.0 = Debug|x64 + {46CF5BA6-DB8A-4B64-8AE0-5970961AB00F}.Debug|x86.ActiveCfg = Debug|Win32 + {46CF5BA6-DB8A-4B64-8AE0-5970961AB00F}.Debug|x86.Build.0 = Debug|Win32 + {46CF5BA6-DB8A-4B64-8AE0-5970961AB00F}.Release|x64.ActiveCfg = Release|x64 + {46CF5BA6-DB8A-4B64-8AE0-5970961AB00F}.Release|x64.Build.0 = Release|x64 + {46CF5BA6-DB8A-4B64-8AE0-5970961AB00F}.Release|x86.ActiveCfg = Release|Win32 + {46CF5BA6-DB8A-4B64-8AE0-5970961AB00F}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/GolemHelper/Definitions/Nexus.h b/GolemHelper/Definitions/Nexus.h new file mode 100644 index 0000000..e3a27bf --- /dev/null +++ b/GolemHelper/Definitions/Nexus.h @@ -0,0 +1,795 @@ +#ifndef NEXUS_H +#define NEXUS_H + +#include + +#ifndef __cplusplus +#include +#endif + +#define NEXUS_API_VERSION 6 + +typedef enum ERenderType +{ + ERenderType_PreRender, + ERenderType_Render, + ERenderType_PostRender, + ERenderType_OptionsRender +} ERenderType; + +///---------------------------------------------------------------------------------------------------- +/// GUI_RENDER: +/// Render callback signature. +///---------------------------------------------------------------------------------------------------- +typedef void (*GUI_RENDER) (void); +typedef void (*GUI_ADDRENDER) (ERenderType aRenderType, GUI_RENDER aRenderCallback); +typedef void (*GUI_REMRENDER) (GUI_RENDER aRenderCallback); +typedef void (*GUI_REGISTERCLOSEONESCAPE)(const char* aWindowName, bool* aIsVisible); +typedef void (*GUI_DEREGISTERCLOSEONESCAPE)(const char* aWindowName); + +typedef void (*UPDATER_REQUESTUPDATE)(signed int aSignature, const char* aUpdateURL); + +typedef const char* (*PATHS_GETGAMEDIR)(void); +typedef const char* (*PATHS_GETADDONDIR)(const char* aName); +typedef const char* (*PATHS_GETCOMMONDIR)(void); + +typedef enum EMHStatus +{ + MH_UNKNOWN = -1, + MH_OK = 0, + MH_ERROR_ALREADY_INITIALIZED, + MH_ERROR_NOT_INITIALIZED, + MH_ERROR_ALREADY_CREATED, + MH_ERROR_NOT_CREATED, + MH_ERROR_ENABLED, + MH_ERROR_DISABLED, + MH_ERROR_NOT_EXECUTABLE, + MH_ERROR_UNSUPPORTED_FUNCTION, + MH_ERROR_MEMORY_ALLOC, + MH_ERROR_MEMORY_PROTECT, + MH_ERROR_MODULE_NOT_FOUND, + MH_ERROR_FUNCTION_NOT_FOUND +} EMHStatus; + +typedef EMHStatus(__stdcall* MINHOOK_CREATE)(LPVOID pTarget, LPVOID pDetour, LPVOID* ppOriginal); +typedef EMHStatus(__stdcall* MINHOOK_REMOVE)(LPVOID pTarget); +typedef EMHStatus(__stdcall* MINHOOK_ENABLE)(LPVOID pTarget); +typedef EMHStatus(__stdcall* MINHOOK_DISABLE)(LPVOID pTarget); + +typedef enum ELogLevel +{ + ELogLevel_OFF = 0, + ELogLevel_CRITICAL = 1, + ELogLevel_WARNING = 2, + ELogLevel_INFO = 3, + ELogLevel_DEBUG = 4, + ELogLevel_TRACE = 5, + ELogLevel_ALL +} ELogLevel; + +typedef void (*LOGGER_LOG2)(ELogLevel aLogLevel, const char* aChannel, const char* aStr); + +typedef void (*ALERTS_NOTIFY)(const char* aMessage); + +///---------------------------------------------------------------------------------------------------- +/// EVENT_CONSUME: +/// Event consume callback signature. +/// aEventArgs is payload and should be known to consumer. +///---------------------------------------------------------------------------------------------------- +typedef void (*EVENT_CONSUME)(void* aEventArgs); +typedef void (*EVENTS_RAISE)(const char* aIdentifier, void* aEventData); +typedef void (*EVENTS_RAISENOTIFICATION)(const char* aIdentifier); +typedef void (*EVENTS_RAISE_TARGETED)(signed int aSignature, const char* aIdentifier, void* aEventData); +typedef void (*EVENTS_RAISENOTIFICATION_TARGETED)(signed int aSignature, const char* aIdentifier); +typedef void (*EVENTS_SUBSCRIBE)(const char* aIdentifier, EVENT_CONSUME aConsumeEventCallback); + +///---------------------------------------------------------------------------------------------------- +/// WNDPROC_CALLBACK: +/// Slightly different WndProc signature. +/// Return 0 if your addon handled it and you don't want it to be passed to the game. +///---------------------------------------------------------------------------------------------------- +typedef UINT(*WNDPROC_CALLBACK)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +typedef void (*WNDPROC_ADDREM)(WNDPROC_CALLBACK aWndProcCallback); +typedef LRESULT(*WNDPROC_SENDTOGAME)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +typedef struct Keybind +{ + unsigned short Key; + bool Alt; + bool Ctrl; + bool Shift; +} Keybind; + +///---------------------------------------------------------------------------------------------------- +/// KEYBINDS_PROCESS: +/// KeybindHandler callback signature. +/// aIsRelease will be true if the keybind is released. +///---------------------------------------------------------------------------------------------------- +typedef void (*KEYBINDS_PROCESS)(const char* aIdentifier, bool aIsRelease); +typedef void (*KEYBINDS_INVOKE)(const char* aIdentifier, bool aIsRelease); +typedef void (*KEYBINDS_REGISTERWITHSTRING)(const char* aIdentifier, KEYBINDS_PROCESS aKeybindHandler, const char* aKeybind); +typedef void (*KEYBINDS_REGISTERWITHSTRUCT)(const char* aIdentifier, KEYBINDS_PROCESS aKeybindHandler, Keybind aKeybind); +typedef void (*KEYBINDS_DEREGISTER)(const char* aIdentifier); + +typedef enum EGameBinds +{ + // Movement + EGameBinds_MoveForward = 0, + EGameBinds_MoveBackward = 1, + EGameBinds_MoveLeft = 2, + EGameBinds_MoveRight = 3, + EGameBinds_MoveTurnLeft = 4, + EGameBinds_MoveTurnRight = 5, + EGameBinds_MoveDodge = 6, + EGameBinds_MoveAutoRun = 7, + EGameBinds_MoveWalk = 8, + EGameBinds_MoveJump = 9, + EGameBinds_MoveSwimUp = 10, + EGameBinds_MoveSwimDown = 11, + EGameBinds_MoveAboutFace = 12, + + // Skills + EGameBinds_SkillWeaponSwap = 17, + EGameBinds_SkillWeapon1 = 18, + EGameBinds_SkillWeapon2 = 19, + EGameBinds_SkillWeapon3 = 20, + EGameBinds_SkillWeapon4 = 21, + EGameBinds_SkillWeapon5 = 22, + EGameBinds_SkillHeal = 23, + EGameBinds_SkillUtility1 = 24, + EGameBinds_SkillUtility2 = 25, + EGameBinds_SkillUtility3 = 26, + EGameBinds_SkillElite = 27, + EGameBinds_SkillProfession1 = 28, + EGameBinds_SkillProfession2 = 29, + EGameBinds_SkillProfession3 = 30, + EGameBinds_SkillProfession4 = 31, + EGameBinds_SkillProfession5 = 79, + EGameBinds_SkillProfession6 = 201, + EGameBinds_SkillProfession7 = 202, + EGameBinds_SkillSpecialAction = 82, + + // Targeting + EGameBinds_TargetAlert = 131, + EGameBinds_TargetCall = 32, + EGameBinds_TargetTake = 33, + EGameBinds_TargetCallLocal = 199, + EGameBinds_TargetTakeLocal = 200, + EGameBinds_TargetEnemyNearest = 34, + EGameBinds_TargetEnemyNext = 35, + EGameBinds_TargetEnemyPrev = 36, + EGameBinds_TargetAllyNearest = 37, + EGameBinds_TargetAllyNext = 38, + EGameBinds_TargetAllyPrev = 39, + EGameBinds_TargetLock = 40, + EGameBinds_TargetSnapGroundTarget = 80, + EGameBinds_TargetSnapGroundTargetToggle = 115, + EGameBinds_TargetAutoTargetingDisable = 116, + EGameBinds_TargetAutoTargetingToggle = 117, + EGameBinds_TargetAllyTargetingMode = 197, + EGameBinds_TargetAllyTargetingModeToggle = 198, + + // UI Binds + EGameBinds_UiCommerce = 41, // TradingPost + EGameBinds_UiContacts = 42, + EGameBinds_UiGuild = 43, + EGameBinds_UiHero = 44, + EGameBinds_UiInventory = 45, + EGameBinds_UiKennel = 46, // Pets + EGameBinds_UiLogout = 47, + EGameBinds_UiMail = 71, + EGameBinds_UiOptions = 48, + EGameBinds_UiParty = 49, + EGameBinds_UiPvp = 73, + EGameBinds_UiPvpBuild = 75, + EGameBinds_UiScoreboard = 50, + EGameBinds_UiSeasonalObjectivesShop = 209, // Wizard's Vault + EGameBinds_UiInformation = 51, + EGameBinds_UiChatToggle = 70, + EGameBinds_UiChatCommand = 52, + EGameBinds_UiChatFocus = 53, + EGameBinds_UiChatReply = 54, + EGameBinds_UiToggle = 55, + EGameBinds_UiSquadBroadcastChatToggle = 85, + EGameBinds_UiSquadBroadcastChatCommand = 83, + EGameBinds_UiSquadBroadcastChatFocus = 84, + + // Camera + EGameBinds_CameraFree = 13, + EGameBinds_CameraZoomIn = 14, + EGameBinds_CameraZoomOut = 15, + EGameBinds_CameraReverse = 16, + EGameBinds_CameraActionMode = 78, + EGameBinds_CameraActionModeDisable = 114, + + // Screenshots + EGameBinds_ScreenshotNormal = 56, + EGameBinds_ScreenshotStereoscopic = 57, + + // Map + EGameBinds_MapToggle = 59, + EGameBinds_MapFocusPlayer = 60, + EGameBinds_MapFloorDown = 61, + EGameBinds_MapFloorUp = 62, + EGameBinds_MapZoomIn = 63, + EGameBinds_MapZoomOut = 64, + + // Mounts + EGameBinds_SpumoniToggle = 152, + EGameBinds_SpumoniMovement = 130, + EGameBinds_SpumoniSecondaryMovement = 153, + EGameBinds_SpumoniMAM01 = 155, // Raptor + EGameBinds_SpumoniMAM02 = 156, // Springer + EGameBinds_SpumoniMAM03 = 157, // Skimmer + EGameBinds_SpumoniMAM04 = 158, // Jackal + EGameBinds_SpumoniMAM05 = 159, // Griffon + EGameBinds_SpumoniMAM06 = 161, // RollerBeetle + EGameBinds_SpumoniMAM07 = 169, // Warclaw + EGameBinds_SpumoniMAM08 = 170, // Skyscale + EGameBinds_SpumoniMAM09 = 203, // SiegeTurtle + + // Spectator Binds + EGameBinds_SpectatorNearestFixed = 102, + EGameBinds_SpectatorNearestPlayer = 103, + EGameBinds_SpectatorPlayerRed1 = 104, + EGameBinds_SpectatorPlayerRed2 = 105, + EGameBinds_SpectatorPlayerRed3 = 106, + EGameBinds_SpectatorPlayerRed4 = 107, + EGameBinds_SpectatorPlayerRed5 = 108, + EGameBinds_SpectatorPlayerBlue1 = 109, + EGameBinds_SpectatorPlayerBlue2 = 110, + EGameBinds_SpectatorPlayerBlue3 = 111, + EGameBinds_SpectatorPlayerBlue4 = 112, + EGameBinds_SpectatorPlayerBlue5 = 113, + EGameBinds_SpectatorFreeCamera = 120, + EGameBinds_SpectatorFreeCameraMode = 127, + EGameBinds_SpectatorFreeMoveForward = 121, + EGameBinds_SpectatorFreeMoveBackward = 122, + EGameBinds_SpectatorFreeMoveLeft = 123, + EGameBinds_SpectatorFreeMoveRight = 124, + EGameBinds_SpectatorFreeMoveUp = 125, + EGameBinds_SpectatorFreeMoveDown = 126, + + // Squad Markers + EGameBinds_SquadMarkerPlaceWorld1 = 86, // Arrow + EGameBinds_SquadMarkerPlaceWorld2 = 87, // Circle + EGameBinds_SquadMarkerPlaceWorld3 = 88, // Heart + EGameBinds_SquadMarkerPlaceWorld4 = 89, // Square + EGameBinds_SquadMarkerPlaceWorld5 = 90, // Star + EGameBinds_SquadMarkerPlaceWorld6 = 91, // Swirl + EGameBinds_SquadMarkerPlaceWorld7 = 92, // Triangle + EGameBinds_SquadMarkerPlaceWorld8 = 93, // Cross + EGameBinds_SquadMarkerClearAllWorld = 119, + EGameBinds_SquadMarkerSetAgent1 = 94, // Arrow + EGameBinds_SquadMarkerSetAgent2 = 95, // Circle + EGameBinds_SquadMarkerSetAgent3 = 96, // Heart + EGameBinds_SquadMarkerSetAgent4 = 97, // Square + EGameBinds_SquadMarkerSetAgent5 = 98, // Star + EGameBinds_SquadMarkerSetAgent6 = 99, // Swirl + EGameBinds_SquadMarkerSetAgent7 = 100, // Triangle + EGameBinds_SquadMarkerSetAgent8 = 101, // Cross + EGameBinds_SquadMarkerClearAllAgent = 118, + + // Mastery Skills + EGameBinds_MasteryAccess = 196, + EGameBinds_MasteryAccess01 = 204, // Fishing + EGameBinds_MasteryAccess02 = 205, // Skiff + EGameBinds_MasteryAccess03 = 206, // Jade Bot Waypoint + EGameBinds_MasteryAccess04 = 207, // Rift Scan + EGameBinds_MasteryAccess05 = 208, // Skyscale + EGameBinds_MasteryAccess06 = 211, // Homestead Doorway + + // Miscellaneous Binds + EGameBinds_MiscAoELoot = 74, + EGameBinds_MiscInteract = 65, + EGameBinds_MiscShowEnemies = 66, + EGameBinds_MiscShowAllies = 67, + EGameBinds_MiscCombatStance = 68, // Stow/Draw + EGameBinds_MiscToggleLanguage = 69, + EGameBinds_MiscTogglePetCombat = 76, + EGameBinds_MiscToggleFullScreen = 160, + EGameBinds_MiscToggleDecorationMode = 210, // DecorateMode + + // Toys/Novelties + EGameBinds_ToyUseDefault = 162, + EGameBinds_ToyUseSlot1 = 163, // Chair + EGameBinds_ToyUseSlot2 = 164, // Instrument + EGameBinds_ToyUseSlot3 = 165, // Held Item + EGameBinds_ToyUseSlot4 = 166, // Toy + EGameBinds_ToyUseSlot5 = 167, // Tonic + //ToyUseSlot6 unused + + // Build Templates + EGameBinds_Loadout1 = 171, + EGameBinds_Loadout2 = 172, + EGameBinds_Loadout3 = 173, + EGameBinds_Loadout4 = 174, + EGameBinds_Loadout5 = 175, + EGameBinds_Loadout6 = 176, + EGameBinds_Loadout7 = 177, + EGameBinds_Loadout8 = 178, + + // Equipment Templates + EGameBinds_GearLoadout1 = 182, + EGameBinds_GearLoadout2 = 183, + EGameBinds_GearLoadout3 = 184, + EGameBinds_GearLoadout4 = 185, + EGameBinds_GearLoadout5 = 186, + EGameBinds_GearLoadout6 = 187, + EGameBinds_GearLoadout7 = 188, + EGameBinds_GearLoadout8 = 189 +} EGameBinds; + +typedef void (*GAMEBINDS_PRESSASYNC)(EGameBinds aGameBind); +typedef void (*GAMEBINDS_RELEASEASYNC)(EGameBinds aGameBind); +typedef void (*GAMEBINDS_INVOKEASYNC)(EGameBinds aGameBind, int aDuration); +typedef void (*GAMEBINDS_PRESS)(EGameBinds aGameBind); +typedef void (*GAMEBINDS_RELEASE)(EGameBinds aGameBind); +typedef bool (*GAMEBINDS_ISBOUND)(EGameBinds aGameBind); + +typedef void* (*DATALINK_GETRESOURCE)(const char* aIdentifier); +typedef void* (*DATALINK_SHARERESOURCE)(const char* aIdentifier, size_t aResourceSize); + +typedef struct Texture +{ + unsigned Width; + unsigned Height; + void* Resource; // ID3D11ShaderResourceView* +} Texture; + +///---------------------------------------------------------------------------------------------------- +/// TEXTURES_RECEIVECALLBACK: +/// TextureReceiver callback signature. +///---------------------------------------------------------------------------------------------------- +typedef void (*TEXTURES_RECEIVECALLBACK)(const char* aIdentifier, Texture* aTexture); +typedef Texture* (*TEXTURES_GET)(const char* aIdentifier); +typedef Texture* (*TEXTURES_GETORCREATEFROMFILE)(const char* aIdentifier, const char* aFilename); +typedef Texture* (*TEXTURES_GETORCREATEFROMRESOURCE)(const char* aIdentifier, unsigned aResourceID, HMODULE aModule); +typedef Texture* (*TEXTURES_GETORCREATEFROMURL)(const char* aIdentifier, const char* aRemote, const char* aEndpoint); +typedef Texture* (*TEXTURES_GETORCREATEFROMMEMORY)(const char* aIdentifier, void* aData, size_t aSize); +typedef void (*TEXTURES_LOADFROMFILE)(const char* aIdentifier, const char* aFilename, TEXTURES_RECEIVECALLBACK aCallback); +typedef void (*TEXTURES_LOADFROMRESOURCE)(const char* aIdentifier, unsigned aResourceID, HMODULE aModule, TEXTURES_RECEIVECALLBACK aCallback); +typedef void (*TEXTURES_LOADFROMURL)(const char* aIdentifier, const char* aRemote, const char* aEndpoint, TEXTURES_RECEIVECALLBACK aCallback); +typedef void (*TEXTURES_LOADFROMMEMORY)(const char* aIdentifier, void* aData, size_t aSize, TEXTURES_RECEIVECALLBACK aCallback); + +typedef void (*QUICKACCESS_ADDSHORTCUT) (const char* aIdentifier, const char* aTextureIdentifier, const char* aTextureHoverIdentifier, const char* aKeybindIdentifier, const char* aTooltipText); +typedef void (*QUICKACCESS_ADDSIMPLE) (const char* aIdentifier, GUI_RENDER aShortcutRenderCallback); +typedef void (*QUICKACCESS_ADDSIMPLE2) (const char* aIdentifier, const char* aTargetShortcutIdentifier, GUI_RENDER aShortcutRenderCallback); +typedef void (*QUICKACCESS_GENERIC) (const char* aIdentifier); + +typedef const char* (*LOCALIZATION_TRANSLATE)(const char* aIdentifier); +typedef const char* (*LOCALIZATION_TRANSLATETO)(const char* aIdentifier, const char* aLanguageIdentifier); +typedef void (*LOCALIZATION_SET)(const char* aIdentifier, const char* aLanguageIdentifier, const char* aString); + +///---------------------------------------------------------------------------------------------------- +/// FONTS_RECEIVECALLBACK: +/// FontReceiver callback signature. +/// aFont = ImFont* +///---------------------------------------------------------------------------------------------------- +typedef void (*FONTS_RECEIVECALLBACK)(const char* aIdentifier, void* aFont); +///---------------------------------------------------------------------------------------------------- +/// FONTS_GETRELEASE: +/// Signature to get and release fonts. +///---------------------------------------------------------------------------------------------------- +typedef void (*FONTS_GETRELEASE)(const char* aIdentifier, FONTS_RECEIVECALLBACK aCallback); +typedef void (*FONTS_ADDFROMFILE)(const char* aIdentifier, float aFontSize, const char* aFilename, FONTS_RECEIVECALLBACK aCallback, void* aConfig); +typedef void (*FONTS_ADDFROMRESOURCE)(const char* aIdentifier, float aFontSize, unsigned aResourceID, HMODULE aModule, FONTS_RECEIVECALLBACK aCallback, void* aConfig); +typedef void (*FONTS_ADDFROMMEMORY)(const char* aIdentifier, float aFontSize, void* aData, size_t aSize, FONTS_RECEIVECALLBACK aCallback, void* aConfig); +typedef void (*FONTS_RESIZE)(const char* aIdentifier, float aFontSize); + +typedef struct NexusLinkData +{ + unsigned Width; + unsigned Height; + float Scaling; + + bool IsMoving; + bool IsCameraMoving; + bool IsGameplay; + + void* Font; // ImFont* + void* FontBig; // ImFont* + void* FontUI; // ImFont* +} NexusLinkData; + +typedef struct AddonAPI +{ + /* Renderer */ + void* SwapChain; + void* ImguiContext; + void* ImguiMalloc; + void* ImguiFree; + + struct RendererVT + { + ///---------------------------------------------------------------------------------------------------- + /// Register: + /// Registers a render callback, ERenderType is either Pre, Present, Post or Options, + /// callback should be of void func(). + ///---------------------------------------------------------------------------------------------------- + GUI_ADDRENDER Register; + ///---------------------------------------------------------------------------------------------------- + /// Deregister: + /// Removes the registered render callback that is passed. + ///---------------------------------------------------------------------------------------------------- + GUI_REMRENDER Deregister; + }; + RendererVT Renderer; + + ///---------------------------------------------------------------------------------------------------- + /// RequestUpdate: + /// Downloads the addon available at remote without checking its version. + /// The addon already did that. + /// I hope. + ///---------------------------------------------------------------------------------------------------- + UPDATER_REQUESTUPDATE RequestUpdate; + + /* Logging */ + LOGGER_LOG2 Log; + + /* User Interface */ + struct UIVT + { + ///---------------------------------------------------------------------------------------------------- + /// SendAlert: + /// Sends a text alert to the user visible for a short amount of time. + ///---------------------------------------------------------------------------------------------------- + ALERTS_NOTIFY SendAlert; + ///---------------------------------------------------------------------------------------------------- + /// RegisterCloseOnEscape: + /// Registers a window name to get its bool toggled when escape is pressed. + ///---------------------------------------------------------------------------------------------------- + GUI_REGISTERCLOSEONESCAPE RegisterCloseOnEscape; + ///---------------------------------------------------------------------------------------------------- + /// DeregisterCloseOnEscape: + /// Deregisters a window name to listen to on escape. + ///---------------------------------------------------------------------------------------------------- + GUI_DEREGISTERCLOSEONESCAPE DeregisterCloseOnEscape; + }; + UIVT UI; + + /* Paths */ + struct PathsVT + { + PATHS_GETGAMEDIR GetGameDirectory; + PATHS_GETADDONDIR GetAddonDirectory; + PATHS_GETCOMMONDIR GetCommonDirectory; + }; + PathsVT Paths; + + /* Minhook */ + struct MinHookVT + { + MINHOOK_CREATE Create; + MINHOOK_REMOVE Remove; + MINHOOK_ENABLE Enable; + MINHOOK_DISABLE Disable; + }; + MinHookVT MinHook; + + struct EventsVT + { + ///---------------------------------------------------------------------------------------------------- + /// Raise: + /// Raises an event to all subscribing addons. + /// aEventData is a pointer to the data you want to share or nullptr. + /// Addons are responsible for knowing how to interpret this data. + ///---------------------------------------------------------------------------------------------------- + EVENTS_RAISE Raise; + ///---------------------------------------------------------------------------------------------------- + /// RaiseNotification: + /// Raises an event without a payload. + /// Synonymous with RaiseEvent("EV_FOO", nullptr); + ///---------------------------------------------------------------------------------------------------- + EVENTS_RAISENOTIFICATION RaiseNotification; + ///---------------------------------------------------------------------------------------------------- + /// RaiseTargeted: + /// Raises an event targeted at a specific subscriber. + ///---------------------------------------------------------------------------------------------------- + EVENTS_RAISE_TARGETED RaiseTargeted; + ///---------------------------------------------------------------------------------------------------- + /// RaiseNotificationTargeted: + /// Raises a notification (event without payload) targeted at a specific subscriber. + ///---------------------------------------------------------------------------------------------------- + EVENTS_RAISENOTIFICATION_TARGETED RaiseNotificationTargeted; + ///---------------------------------------------------------------------------------------------------- + /// Subscribe: + /// Registers an event callback. + ///---------------------------------------------------------------------------------------------------- + EVENTS_SUBSCRIBE Subscribe; + ///---------------------------------------------------------------------------------------------------- + /// Unsubscribe: + /// Deregisters an event callback. + ///---------------------------------------------------------------------------------------------------- + EVENTS_SUBSCRIBE Unsubscribe; + }; + EventsVT Events; + + /* WndProc */ + struct WndProcVT + { + ///---------------------------------------------------------------------------------------------------- + /// Register: + /// Registers/Deregisters a WndProc callback. + ///---------------------------------------------------------------------------------------------------- + WNDPROC_ADDREM Register; + ///---------------------------------------------------------------------------------------------------- + /// Deregister: + /// Registers/Deregisters a WndProc callback. + ///---------------------------------------------------------------------------------------------------- + WNDPROC_ADDREM Deregister; + ///---------------------------------------------------------------------------------------------------- + /// SendToGameOnly: + /// Sends a WndProc to the game only and bypasses all other hooks. + ///---------------------------------------------------------------------------------------------------- + WNDPROC_SENDTOGAME SendToGameOnly; + }; + WndProcVT WndProc; + + /* InputBinds */ + struct InputBindsVT + { + ///---------------------------------------------------------------------------------------------------- + /// Invoke: + /// Trigger a keybind programmatically. + ///---------------------------------------------------------------------------------------------------- + KEYBINDS_INVOKE Invoke; + ///---------------------------------------------------------------------------------------------------- + /// RegisterWithString: + /// Registers a KeybindHandler callback for a given named keybind. + /// aKeybind is the default if not yet defined. Use as "ALT+CTRL+SHIFT+Q", "ALT+SHIFT+T", etc. + ///---------------------------------------------------------------------------------------------------- + KEYBINDS_REGISTERWITHSTRING RegisterWithString; + ///---------------------------------------------------------------------------------------------------- + /// RegisterWithStruct: + /// Same as KEYBINDS_REGISTERWITHSTRING except you pass a Nexus Keybind struct as a default bind. + ///---------------------------------------------------------------------------------------------------- + KEYBINDS_REGISTERWITHSTRUCT RegisterWithStruct; + ///---------------------------------------------------------------------------------------------------- + /// Deregister: + /// Deregisters a KeybindHandler callback. + ///---------------------------------------------------------------------------------------------------- + KEYBINDS_DEREGISTER Deregister; + }; + InputBindsVT InputBinds; + + /* GameBinds */ + struct GameBindsVT + { + ///---------------------------------------------------------------------------------------------------- + /// Deregister: + /// Presses the keys of a given bind + ///---------------------------------------------------------------------------------------------------- + GAMEBINDS_PRESSASYNC PressAsync; + ///---------------------------------------------------------------------------------------------------- + /// ReleaseAsync: + /// Releases the keypresses of a given bind. + ///---------------------------------------------------------------------------------------------------- + GAMEBINDS_RELEASEASYNC ReleaseAsync; + ///---------------------------------------------------------------------------------------------------- + /// InvokeAsync: + /// Sends the keys of a given bind and then releases them after a given duration. + ///---------------------------------------------------------------------------------------------------- + GAMEBINDS_INVOKEASYNC InvokeAsync; + ///---------------------------------------------------------------------------------------------------- + /// Press: + /// Presses the keys of a given bind + ///---------------------------------------------------------------------------------------------------- + GAMEBINDS_PRESS Press; + ///---------------------------------------------------------------------------------------------------- + /// Release: + /// Releases the keypresses of a given bind. + ///---------------------------------------------------------------------------------------------------- + GAMEBINDS_RELEASE Release; + ///---------------------------------------------------------------------------------------------------- + /// IsBound: + /// Returns if a given game bind is set. + ///---------------------------------------------------------------------------------------------------- + GAMEBINDS_ISBOUND IsBound; + }; + GameBindsVT GameBinds; + + /* DataLink */ + struct DataLinkVT + { + ///---------------------------------------------------------------------------------------------------- + /// Get: + /// Returns a pointer to the requested resource or nullptr if not existing. + ///---------------------------------------------------------------------------------------------------- + DATALINK_GETRESOURCE Get; + ///---------------------------------------------------------------------------------------------------- + /// Share: + /// Allocates a shared resource of given size and returns a pointer to it for writing. + ///---------------------------------------------------------------------------------------------------- + DATALINK_SHARERESOURCE Share; + }; + DataLinkVT DataLink; + + /* Textures */ + struct TexturesVT + { + ///---------------------------------------------------------------------------------------------------- + /// Get: + /// Returns a Texture* or nullptr if it doesn't exist. + ///---------------------------------------------------------------------------------------------------- + TEXTURES_GET Get; + ///---------------------------------------------------------------------------------------------------- + /// GetOrCreateFromFile: + /// Returns a Texture* or if it doesn't exist yet creates it from file. + ///---------------------------------------------------------------------------------------------------- + TEXTURES_GETORCREATEFROMFILE GetOrCreateFromFile; + ///---------------------------------------------------------------------------------------------------- + /// GetOrCreateFromResource: + /// Returns a Texture* or if it doesn't exist yet creates it from resource. + ///---------------------------------------------------------------------------------------------------- + TEXTURES_GETORCREATEFROMRESOURCE GetOrCreateFromResource; + ///---------------------------------------------------------------------------------------------------- + /// GetOrCreateFromURL: + /// Returns a Texture* or if it doesn't exist yet creates it from URL. + ///---------------------------------------------------------------------------------------------------- + TEXTURES_GETORCREATEFROMURL GetOrCreateFromURL; + ///---------------------------------------------------------------------------------------------------- + /// GetOrCreateFromMemory: + /// Returns a Texture* or if it doesn't exist yet creates it from memory. + ///---------------------------------------------------------------------------------------------------- + TEXTURES_GETORCREATEFROMMEMORY GetOrCreateFromMemory; + ///---------------------------------------------------------------------------------------------------- + /// LoadFromFile: + /// Creates a texture from file and passes it to the TextureReceiver callback when finished. + ///---------------------------------------------------------------------------------------------------- + TEXTURES_LOADFROMFILE LoadFromFile; + ///---------------------------------------------------------------------------------------------------- + /// LoadFromResource: + /// Creates a texture from resource and passes it to the TextureReceiver callback when finished. + ///---------------------------------------------------------------------------------------------------- + TEXTURES_LOADFROMRESOURCE LoadFromResource; + ///---------------------------------------------------------------------------------------------------- + /// LoadFromURL: + /// Creates a texture from URL and passes it to the TextureReceiver callback when finished. + ///---------------------------------------------------------------------------------------------------- + TEXTURES_LOADFROMURL LoadFromURL; + ///---------------------------------------------------------------------------------------------------- + /// LoadFromMemory: + /// Creates a texture from memory and passes it to the TextureReceiver callback when finished. + ///---------------------------------------------------------------------------------------------------- + TEXTURES_LOADFROMMEMORY LoadFromMemory; + }; + TexturesVT Textures; + + /* Shortcuts */ + struct QuickAccessVT + { + ///---------------------------------------------------------------------------------------------------- + /// Add: + /// Adds a shortcut icon to the QuickAccess with given texture identifiers. + /// When clicked aKeybindIdentifier will be invoked. + ///---------------------------------------------------------------------------------------------------- + QUICKACCESS_ADDSHORTCUT Add; + ///---------------------------------------------------------------------------------------------------- + /// Remove: + /// Removes a shortcut with the given identifier from Quick Access. + ///---------------------------------------------------------------------------------------------------- + QUICKACCESS_GENERIC Remove; + ///---------------------------------------------------------------------------------------------------- + /// Notify: + /// Sends a notification icon to the given shortcut. + ///---------------------------------------------------------------------------------------------------- + QUICKACCESS_GENERIC Notify; + ///---------------------------------------------------------------------------------------------------- + /// AddContextMenu: + /// Appends ImGui callback when right-clicking a shortcut icon. + ///---------------------------------------------------------------------------------------------------- + QUICKACCESS_ADDSIMPLE2 AddContextMenu; + ///---------------------------------------------------------------------------------------------------- + /// RemoveContextMenu: + /// Removes a simple shortcut / context item with the given identifier from Quick Access. + ///---------------------------------------------------------------------------------------------------- + QUICKACCESS_GENERIC RemoveContextMenu; + }; + QuickAccessVT QuickAccess; + + /* Localization */ + struct LocalizationVT + { + ///---------------------------------------------------------------------------------------------------- + /// Translate: + /// Translates aIdentifier into current active language or returns aIdentifier if not available. + ///---------------------------------------------------------------------------------------------------- + LOCALIZATION_TRANSLATE Translate; + ///---------------------------------------------------------------------------------------------------- + /// TranslateTo: + /// Same as Translate except you can pass which language you want to translate to. + ///---------------------------------------------------------------------------------------------------- + LOCALIZATION_TRANSLATETO TranslateTo; + ///---------------------------------------------------------------------------------------------------- + /// Set: + /// Set a translated string at runtime. + ///---------------------------------------------------------------------------------------------------- + LOCALIZATION_SET Set; + }; + LocalizationVT Localization; + + /* Fonts */ + struct FontsVT + { + ///---------------------------------------------------------------------------------------------------- + /// Get: + /// Requests a font to be sent to the given callback/receiver. + ///---------------------------------------------------------------------------------------------------- + FONTS_GETRELEASE Get; + ///---------------------------------------------------------------------------------------------------- + /// Release: + /// Releases a callback/receiver from a specific font. + ///---------------------------------------------------------------------------------------------------- + FONTS_GETRELEASE Release; + ///---------------------------------------------------------------------------------------------------- + /// AddFromFile: + /// Adds a font from disk and sends updates to the callback. + ///---------------------------------------------------------------------------------------------------- + FONTS_ADDFROMFILE AddFromFile; + ///---------------------------------------------------------------------------------------------------- + /// AddFromResource: + /// Adds a font from an embedded resource and sends updates to the callback. + ///---------------------------------------------------------------------------------------------------- + FONTS_ADDFROMRESOURCE AddFromResource; + ///---------------------------------------------------------------------------------------------------- + /// AddFromMemory: + /// Adds a font from memory and sends updates to the callback. + ///---------------------------------------------------------------------------------------------------- + FONTS_ADDFROMMEMORY AddFromMemory; + ///---------------------------------------------------------------------------------------------------- + /// Resize: + /// Resizes a font and sends updates to the callback. + ///---------------------------------------------------------------------------------------------------- + FONTS_RESIZE Resize; + }; + FontsVT Fonts; +} AddonAPI; + +typedef void (*ADDON_LOAD) (AddonAPI* aAPI); +typedef void (*ADDON_UNLOAD) (void); + +typedef struct AddonVersion +{ + signed short Major; + signed short Minor; + signed short Build; + signed short Revision; +} AddonVersion; + +typedef enum EAddonFlags +{ + EAddonFlags_None = 0, + EAddonFlags_IsVolatile = 1, /* is hooking functions or doing anything else that's volatile and game build dependant */ + EAddonFlags_DisableHotloading = 2, /* prevents unloading at runtime, aka. will require a restart if updated, etc. */ + EAddonFlags_OnlyLoadDuringGameLaunchSequence = 4 /* prevents loading the addon later than the initial character select */ +} EAddonFlags; + +typedef enum EUpdateProvider +{ + EUpdateProvider_None = 0, /* Does not support auto updating */ + EUpdateProvider_Raidcore = 1, /* Provider is Raidcore (via API) */ + EUpdateProvider_GitHub = 2, /* Provider is GitHub Releases */ + EUpdateProvider_Direct = 3, /* Provider is direct file link */ + EUpdateProvider_Self = 4 /* Provider is self check, addon has to request manually and version will not be verified */ +} EUpdateProvider; + +typedef struct AddonDefinition +{ + /* required */ + signed int Signature; /* Raidcore Addon ID, set to random unqiue negative integer if not on Raidcore */ + signed int APIVersion; /* Determines which AddonAPI struct revision the Loader will pass, use the NEXUS_API_VERSION define from Nexus.h */ + const char* Name; /* Name of the addon as shown in the library */ + AddonVersion Version; + const char* Author; /* Author of the addon */ + const char* Description; /* Short description */ + ADDON_LOAD Load; /* Pointer to Load Function of the addon */ + ADDON_UNLOAD Unload; /* Pointer to Unload Function of the addon. Not required if EAddonFlags::DisableHotloading is set. */ + EAddonFlags Flags; /* Information about the addon */ + + /* update fallback */ + EUpdateProvider Provider; /* What platform is the the addon hosted on */ + const char* UpdateLink; /* Link to the update resource */ +} AddonDefinition; + +#endif diff --git a/GolemHelper/GolemHelper.vcxproj b/GolemHelper/GolemHelper.vcxproj new file mode 100644 index 0000000..5de826e --- /dev/null +++ b/GolemHelper/GolemHelper.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {46cf5ba6-db8a-4b64-8ae0-5970961ab00f} + GolemHelper + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;GOLEMHELPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;GOLEMHELPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;GOLEMHELPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + + + Windows + true + false + + + + + Level3 + true + true + true + NDEBUG;GOLEMHELPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + + + Windows + true + true + true + false + + + + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/GolemHelper/GolemHelper.vcxproj.filters b/GolemHelper/GolemHelper.vcxproj.filters new file mode 100644 index 0000000..b53373b --- /dev/null +++ b/GolemHelper/GolemHelper.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {076f83a5-9043-4392-bb42-102eb54d65fb} + + + + + File di intestazione + + + File di intestazione + + + Definitions + + + + + File di origine + + + File di origine + + + \ No newline at end of file diff --git a/GolemHelper/GolemHelper.vcxproj.user b/GolemHelper/GolemHelper.vcxproj.user new file mode 100644 index 0000000..0f14913 --- /dev/null +++ b/GolemHelper/GolemHelper.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/GolemHelper/dllmain.cpp b/GolemHelper/dllmain.cpp new file mode 100644 index 0000000..7200917 --- /dev/null +++ b/GolemHelper/dllmain.cpp @@ -0,0 +1,412 @@ +#include "pch.h" +#include "Definitions/Nexus.h" +#include +#include +#include + +AddonAPI* g_api = nullptr; + +struct { + bool enabled = false; + bool boonsEnabled = true; + bool golemEnabled = true; + bool isQuickDps = false; + bool isAlacDps = false; + bool isChronomancer = false; + bool debugMode = false; + int debugCounter = 0; +} g_state; + +struct MenuCoordinates { + int golemStepX[25] = { + 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, + 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, + 830, 830, 830, 830, 830 + }; + int golemStepY[25] = { + 260, 260, 306, 257, 257, 306, 257, 306, 352, 400, + 454, 508, 352, 257, 306, 454, 400, 306, 352, 400, + 454, 400, 454, 454, 548 + }; + + int boonStepX[20] = { + 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, + 830, 830, 830, 830, 830, 830, 830, 830, 830, 830 + }; + int boonStepY[20] = { + 262, 354, 262, 262, 400, 305, 354, 305, 262, 305, + 450, 500, 354, 262, 305, 354, 400, 450, 262, 550 + }; +} g_coords; + +void GetScaledCoordinates(int baseX, int baseY, int* scaledX, int* scaledY) { + g_api->Log(ELogLevel_INFO, "GolemHelper", "GetScaledCoordinates CHIAMATA"); + + NexusLinkData* nexusData = (NexusLinkData*)g_api->DataLink.Get("DL_NEXUS_LINK"); + + if (nexusData && nexusData->Width > 0 && nexusData->Height > 0) { + float uiScale = nexusData->Scaling; + float dpiScale = (float)nexusData->Width / 1920.0f; + + char valuesBuffer[200]; + sprintf_s(valuesBuffer, "GetScaled INPUT: uiScale=%.3f, base=%d,%d", uiScale, baseX, baseY); + g_api->Log(ELogLevel_INFO, "GolemHelper", valuesBuffer); + + int scaledForResolutionX = (int)(baseX * dpiScale); + int scaledForResolutionY = baseY; + + int finalX = scaledForResolutionX; + int finalY = scaledForResolutionY; + + if (uiScale >= 0.89f && uiScale <= 0.91f) { + finalX = scaledForResolutionX - (int)(scaledForResolutionX * 0.029f); + finalY = scaledForResolutionY - (int)(scaledForResolutionY * 0.103f); + g_api->Log(ELogLevel_INFO, "GolemHelper", "APPLIED SMALL OFFSET"); + } + else if (uiScale >= 1.09f && uiScale <= 1.15f) { + finalX = scaledForResolutionX - (int)(scaledForResolutionX * 0.053f); + finalY = scaledForResolutionY + (int)(scaledForResolutionY * 0.095f); + g_api->Log(ELogLevel_INFO, "GolemHelper", "APPLIED LARGE OFFSET"); + } + else if (uiScale >= 1.21f && uiScale <= 1.25f) { + finalX = scaledForResolutionX - (int)(scaledForResolutionX * 0.097f); + finalY = scaledForResolutionY + (int)(scaledForResolutionY * 0.206f); + g_api->Log(ELogLevel_INFO, "GolemHelper", "APPLIED LARGER OFFSET"); + } + else { + char buffer[100]; + sprintf_s(buffer, "NO OFFSET - uiScale %.3f", uiScale); + g_api->Log(ELogLevel_INFO, "GolemHelper", buffer); + } + + *scaledX = finalX; + *scaledY = finalY; + + char resultBuffer[200]; + sprintf_s(resultBuffer, "GetScaled RESULT: %d,%d -> %d,%d", scaledForResolutionX, scaledForResolutionY, finalX, finalY); + g_api->Log(ELogLevel_INFO, "GolemHelper", resultBuffer); + } + else { + g_api->Log(ELogLevel_WARNING, "GolemHelper", "GetScaledCoordinates - Nexus data not available"); + + int screenWidth = GetSystemMetrics(SM_CXSCREEN); + float dpiScale = (float)screenWidth / 1920.0f; + + *scaledX = (int)(baseX * dpiScale); + *scaledY = baseY; + } +} + +void DebugMousePosition() { + if (!g_api) return; + + POINT mousePos; + GetCursorPos(&mousePos); + + NexusLinkData* nexusData = (NexusLinkData*)g_api->DataLink.Get("DL_NEXUS_LINK"); + + if (nexusData && nexusData->Width > 0 && nexusData->Height > 0) { + float uiScale = nexusData->Scaling; + float dpiScale = (float)nexusData->Width / 1920.0f; + float finalScaleX = uiScale * dpiScale; + + int baseX = (int)(mousePos.x / finalScaleX); + int baseY = mousePos.y; + + g_state.debugCounter++; + + char buffer[450]; + sprintf_s(buffer, "=== DEBUG #%d === Resolution: %dx%d | Mouse: %d,%d | Base coords: %d,%d | Interface Size: %.2f | DPI Scale: %.3f | Final ScaleX: %.3f", + g_state.debugCounter, nexusData->Width, nexusData->Height, + mousePos.x, mousePos.y, baseX, baseY, uiScale, dpiScale, finalScaleX); + g_api->Log(ELogLevel_INFO, "GolemHelper", buffer); + } + else { + g_api->Log(ELogLevel_WARNING, "GolemHelper", "Cannot debug - Nexus data not available"); + } + + if (g_state.debugCounter == 1) { + g_api->UI.SendAlert("Debug active - Interface Size + DPI scaling"); + } +} + +void ClickAtScaled(int baseX, int baseY, int delay = 25) { + HWND gameWindow = GetForegroundWindow(); + if (!gameWindow) return; + + int scaledX, scaledY; + GetScaledCoordinates(baseX, baseY, &scaledX, &scaledY); + + LPARAM lParam = MAKELPARAM(scaledX, scaledY); + SendMessage(gameWindow, WM_LBUTTONDOWN, MK_LBUTTON, lParam); + Sleep(10); + SendMessage(gameWindow, WM_LBUTTONUP, 0, lParam); + Sleep(delay); +} + +bool ShouldSkipBoonStep(int stepIndex) { + if (g_state.isQuickDps && stepIndex == 14) { + return true; + } + + if (g_state.isAlacDps && (stepIndex == 13 || stepIndex == 18)) { + return true; + } + + return false; +} + +bool ShouldSkipGolemStep(int stepIndex) { + if (g_state.isChronomancer && stepIndex == 17) { + return true; + } + + return false; +} + +void ApplyAllBoons() { + if (!g_api || !g_state.boonsEnabled || !g_state.enabled) return; + + NexusLinkData* nexusData = (NexusLinkData*)g_api->DataLink.Get("DL_NEXUS_LINK"); + if (nexusData && nexusData->Width > 0 && nexusData->Height > 0) { + float uiScale = nexusData->Scaling; + float dpiScale = (float)nexusData->Width / 1920.0f; + float finalScaleX = dpiScale; + + char scalingBuffer[300]; + sprintf_s(scalingBuffer, "Current scaling - Resolution: %dx%d | Interface Size: %.3f | DPI Scale: %.3f | Final ScaleX: %.3f", + nexusData->Width, nexusData->Height, uiScale, dpiScale, finalScaleX); + g_api->Log(ELogLevel_INFO, "GolemHelper", scalingBuffer); + + if (uiScale >= 0.89f && uiScale <= 0.91f) { + g_api->Log(ELogLevel_INFO, "GolemHelper", "Applying SMALL interface offset"); + } + else if (uiScale >= 1.09f && uiScale <= 1.15f) { + g_api->Log(ELogLevel_INFO, "GolemHelper", "Applying LARGE interface offset"); + } + else if (uiScale >= 1.21f && uiScale <= 1.25f) { + g_api->Log(ELogLevel_INFO, "GolemHelper", "Applying LARGER interface offset"); + } + else { + char noOffsetBuffer[150]; + sprintf_s(noOffsetBuffer, "NO OFFSET applied - uiScale %.3f doesn't match any range", uiScale); + g_api->Log(ELogLevel_INFO, "GolemHelper", noOffsetBuffer); + } + } + + const char* mode = g_state.isQuickDps ? "Quick DPS" : + g_state.isAlacDps ? "Alac DPS" : "Normal"; + + char startBuffer[200]; + sprintf_s(startBuffer, "Starting boon sequence (20 steps) - Mode: %s", mode); + g_api->Log(ELogLevel_INFO, "GolemHelper", startBuffer); + + try { + g_api->GameBinds.InvokeAsync(EGameBinds_MiscInteract, 50); + Sleep(390); + + for (int i = 0; i < 20; i++) { + if (g_coords.boonStepX[i] == 0 && g_coords.boonStepY[i] == 0) { + char skipBuffer[100]; + sprintf_s(skipBuffer, "Skipping boon step %d (coordinates 0,0)", i + 1); + g_api->Log(ELogLevel_INFO, "GolemHelper", skipBuffer); + continue; + } + + if (ShouldSkipBoonStep(i)) { + char skipBuffer[150]; + sprintf_s(skipBuffer, "Skipping boon step %d (%s mode) - coordinates: %d,%d", + i + 1, mode, g_coords.boonStepX[i], g_coords.boonStepY[i]); + g_api->Log(ELogLevel_INFO, "GolemHelper", skipBuffer); + continue; + } + + char stepBuffer[200]; + sprintf_s(stepBuffer, "Executing boon step %d at base coordinates: %d,%d", + i + 1, g_coords.boonStepX[i], g_coords.boonStepY[i]); + g_api->Log(ELogLevel_INFO, "GolemHelper", stepBuffer); + + int scaledX, scaledY; + GetScaledCoordinates(g_coords.boonStepX[i], g_coords.boonStepY[i], &scaledX, &scaledY); + char scaledBuffer[200]; + sprintf_s(scaledBuffer, "-> FINAL SCALED COORDINATES: %d,%d", scaledX, scaledY); + g_api->Log(ELogLevel_INFO, "GolemHelper", scaledBuffer); + + int delay = (i == 19) ? 50 : 290; + ClickAtScaled(g_coords.boonStepX[i], g_coords.boonStepY[i], delay); + } + } + catch (...) { + g_api->Log(ELogLevel_WARNING, "GolemHelper", "Exception during boon sequence"); + } + + g_api->Log(ELogLevel_INFO, "GolemHelper", "Boon sequence completed!"); +} + +void ApplyGolemSettings() { + if (!g_api || !g_state.golemEnabled || !g_state.enabled) return; + + NexusLinkData* nexusData = (NexusLinkData*)g_api->DataLink.Get("DL_NEXUS_LINK"); + if (nexusData && nexusData->Width > 0 && nexusData->Height > 0) { + float uiScale = nexusData->Scaling; + float dpiScale = (float)nexusData->Width / 1920.0f; + float finalScaleX = dpiScale; + + char scalingBuffer[300]; + sprintf_s(scalingBuffer, "Current scaling - Resolution: %dx%d | Interface Size: %.3f | DPI Scale: %.3f | Final ScaleX: %.3f", + nexusData->Width, nexusData->Height, uiScale, dpiScale, finalScaleX); + g_api->Log(ELogLevel_INFO, "GolemHelper", scalingBuffer); + } + + const char* mode = g_state.isChronomancer ? "Chronomancer" : "Normal"; + char startBuffer[200]; + sprintf_s(startBuffer, "Starting golem settings sequence (25 steps) - Mode: %s", mode); + g_api->Log(ELogLevel_INFO, "GolemHelper", startBuffer); + + try { + g_api->GameBinds.InvokeAsync(EGameBinds_MiscInteract, 50); + Sleep(390); + + for (int i = 0; i < 25; i++) { + if (g_coords.golemStepX[i] == 0 && g_coords.golemStepY[i] == 0) { + char skipBuffer[100]; + sprintf_s(skipBuffer, "Skipping golem step %d (coordinates 0,0)", i + 1); + g_api->Log(ELogLevel_INFO, "GolemHelper", skipBuffer); + continue; + } + + if (ShouldSkipGolemStep(i)) { + char skipBuffer[150]; + sprintf_s(skipBuffer, "Skipping golem step %d (%s mode) - coordinates: %d,%d", + i + 1, mode, g_coords.golemStepX[i], g_coords.golemStepY[i]); + g_api->Log(ELogLevel_INFO, "GolemHelper", skipBuffer); + continue; + } + + char stepBuffer[150]; + sprintf_s(stepBuffer, "Executing golem step %d at base coordinates: %d,%d", + i + 1, g_coords.golemStepX[i], g_coords.golemStepY[i]); + g_api->Log(ELogLevel_INFO, "GolemHelper", stepBuffer); + + int delay = (i == 24) ? 50 : 290; + ClickAtScaled(g_coords.golemStepX[i], g_coords.golemStepY[i], delay); + } + } + catch (...) { + g_api->Log(ELogLevel_WARNING, "GolemHelper", "Exception during golem settings sequence"); + } + + g_api->Log(ELogLevel_INFO, "GolemHelper", "Golem settings sequence completed (25 steps)!"); +} + +void HandleBoonKeybind(const char* id, bool release) { + if (!release && g_state.enabled) ApplyAllBoons(); +} + +void HandleGolemKeybind(const char* id, bool release) { + if (!release && g_state.enabled) ApplyGolemSettings(); +} + +void HandleToggleKeybind(const char* id, bool release) { + if (!release) { + g_state.enabled = !g_state.enabled; + g_api->UI.SendAlert(g_state.enabled ? "GolemHelper enabled" : "GolemHelper disabled"); + } +} + +void HandleDebugKeybind(const char* id, bool release) { + if (!release) DebugMousePosition(); +} + +void HandleQuickDpsKeybind(const char* id, bool release) { + if (!release) { + g_state.isQuickDps = !g_state.isQuickDps; + if (g_state.isQuickDps) { + g_state.isAlacDps = false; + } + g_api->UI.SendAlert(g_state.isQuickDps ? "Quick DPS mode enabled" : "Quick DPS mode disabled"); + g_api->Log(ELogLevel_INFO, "GolemHelper", g_state.isQuickDps ? "Quick DPS enabled" : "Quick DPS disabled"); + } +} + +void HandleAlacDpsKeybind(const char* id, bool release) { + if (!release) { + g_state.isAlacDps = !g_state.isAlacDps; + if (g_state.isAlacDps) { + g_state.isQuickDps = false; + } + g_api->UI.SendAlert(g_state.isAlacDps ? "Alac DPS mode enabled" : "Alac DPS mode disabled"); + g_api->Log(ELogLevel_INFO, "GolemHelper", g_state.isAlacDps ? "Alac DPS enabled" : "Alac DPS disabled"); + } +} + +void HandleChronomancerKeybind(const char* id, bool release) { + if (!release) { + g_state.isChronomancer = !g_state.isChronomancer; + g_api->UI.SendAlert(g_state.isChronomancer ? "Chronomancer mode enabled" : "Chronomancer mode disabled"); + g_api->Log(ELogLevel_INFO, "GolemHelper", g_state.isChronomancer ? "Chronomancer enabled" : "Chronomancer disabled"); + } +} + +void Load(AddonAPI* api) { + g_api = api; + g_state.enabled = true; + + Keybind kb_empty = { 0, false, false, false }; + g_api->InputBinds.RegisterWithStruct("GolemHelper.ApplyBoons", HandleBoonKeybind, kb_empty); + g_api->InputBinds.RegisterWithStruct("GolemHelper.ApplyGolem", HandleGolemKeybind, kb_empty); + g_api->InputBinds.RegisterWithStruct("GolemHelper.QuickDPS", HandleQuickDpsKeybind, kb_empty); + g_api->InputBinds.RegisterWithStruct("GolemHelper.AlacDPS", HandleAlacDpsKeybind, kb_empty); + g_api->InputBinds.RegisterWithStruct("GolemHelper.Chronomancer", HandleChronomancerKeybind, kb_empty); + g_api->InputBinds.RegisterWithStruct("GolemHelper.Toggle", HandleToggleKeybind, kb_empty); + g_api->InputBinds.RegisterWithStruct("GolemHelper.DebugMouse", HandleDebugKeybind, kb_empty); + + g_api->Log(ELogLevel_INFO, "GolemHelper", "=== GolemHelper v1.0.0-beta.1 Loaded with Array System + DPS Modes + Chronomancer ==="); + g_api->Log(ELogLevel_INFO, "GolemHelper", "Available keybinds:"); + g_api->Log(ELogLevel_INFO, "GolemHelper", "Available keybinds:"); + g_api->Log(ELogLevel_INFO, "GolemHelper", "- ApplyBoons: Apply boons with current DPS mode"); + g_api->Log(ELogLevel_INFO, "GolemHelper", "- ApplyGolem: Apply golem settings"); + g_api->Log(ELogLevel_INFO, "GolemHelper", "- QuickDPS: Toggle Quick DPS mode (skip quickness)"); + g_api->Log(ELogLevel_INFO, "GolemHelper", "- AlacDPS: Toggle Alac DPS mode (skip alacrity)"); + g_api->Log(ELogLevel_INFO, "GolemHelper", "- Chronomancer: Toggle Chronomancer mode (skip slow on golem)"); + g_api->Log(ELogLevel_INFO, "GolemHelper", "- Toggle: Enable/disable addon"); + g_api->Log(ELogLevel_INFO, "GolemHelper", "- DebugMouse: Show mouse position (for coordinate mapping)"); + + const char* boonMode = g_state.isQuickDps ? "Quick DPS" : + g_state.isAlacDps ? "Alac DPS" : "Normal"; + const char* golemMode = g_state.isChronomancer ? "Chronomancer" : "Normal"; + + char modeBuffer[150]; + sprintf_s(modeBuffer, "Current Modes - Boons: %s | Golem: %s | Base coordinates: 1080p", boonMode, golemMode); + g_api->Log(ELogLevel_INFO, "GolemHelper", modeBuffer); +} + +void Unload() { + g_api->InputBinds.Deregister("GolemHelper.ApplyBoons"); + g_api->InputBinds.Deregister("GolemHelper.ApplyGolem"); + g_api->InputBinds.Deregister("GolemHelper.QuickDPS"); + g_api->InputBinds.Deregister("GolemHelper.AlacDPS"); + g_api->InputBinds.Deregister("GolemHelper.Chronomancer"); + g_api->InputBinds.Deregister("GolemHelper.Toggle"); + g_api->InputBinds.Deregister("GolemHelper.DebugMouse"); + g_api = nullptr; + g_state.enabled = false; +} + +extern "C" __declspec(dllexport) AddonDefinition* GetAddonDef() { + static AddonDefinition def; + def.Signature = -424248; + def.APIVersion = NEXUS_API_VERSION; + def.Name = "GolemHelper"; + def.Version = { 1, 0, 0, 1 }; + def.Author = "Azrub"; + def.Description = "Boon & golem automation with DPS modes, Chronomancer mode and auto-scaling [BETA]"; + def.Load = Load; + def.Unload = Unload; + def.Flags = EAddonFlags_None; + def.Provider = EUpdateProvider_GitHub; + def.UpdateLink = "https://github.com/Azrub/GolemHelper"; + return &def; +} + +BOOL APIENTRY DllMain(HMODULE, DWORD, LPVOID) { return TRUE; } \ No newline at end of file diff --git a/GolemHelper/framework.h b/GolemHelper/framework.h new file mode 100644 index 0000000..41481c5 --- /dev/null +++ b/GolemHelper/framework.h @@ -0,0 +1,5 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Escludere gli elementi usati raramente dalle intestazioni di Windows +// File di intestazione di Windows +#include diff --git a/GolemHelper/pch.cpp b/GolemHelper/pch.cpp new file mode 100644 index 0000000..fb69ea2 --- /dev/null +++ b/GolemHelper/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: file di origine corrispondente all'intestazione precompilata + +#include "pch.h" + +// Quando si usano intestazioni precompilate, questo file è necessario per la riuscita della compilazione. diff --git a/GolemHelper/pch.h b/GolemHelper/pch.h new file mode 100644 index 0000000..e0a5bed --- /dev/null +++ b/GolemHelper/pch.h @@ -0,0 +1,13 @@ +// pch.h: questo è un file di intestazione precompilata. +// I file elencati di seguito vengono compilati una sola volta, in modo da migliorare le prestazioni per le compilazioni successive. +// Questa impostazione influisce anche sulle prestazioni di IntelliSense, incluso il completamento codice e molte altre funzionalità di esplorazione del codice. +// I file elencati qui vengono però TUTTI ricompilati se uno di essi viene aggiornato da una compilazione all'altra. +// Non aggiungere qui file soggetti a frequenti aggiornamenti; in caso contrario si perderanno i vantaggi offerti in termini di prestazioni. + +#ifndef PCH_H +#define PCH_H + +// aggiungere qui le intestazioni da precompilare +#include "framework.h" + +#endif //PCH_H