commit 37001f09829cde330398d91f357915a7e6bc90d1 Author: Azrub Date: Wed Apr 15 01:43:52 2026 +0200 Initial commit - migrate to Forgejo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0a9dfcb --- /dev/null +++ b/.gitignore @@ -0,0 +1,122 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Linker files +*.ilk + +# Debugger Files +*.pdb + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Debug information files +*.dwo + +# Visual Studio specific files +.vs/ +*.suo +*.user +*.userosscache +*.sln.docstates +*.vsidx +*.vspscc +*.vssscc +.builds/ +*.pidb +*.svclog +*.scc + +# Visual Studio additional files +*.vcxproj.user +*.sdf +*.opensdf +*.db +*.opendb +*.idb +*.exp + +# Build folders +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# MSBuild +*.log +*.wrn +*.err +*.unsuccessfulbuild +*.lastbuildstate +*.command.* +*.read.* +*.write.* +link-* + +# Backup files +*.bak +*~ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Temporary files +*.tmp +*.temp + +# IDE files +*.swp +*.swo + +# Package files (vcpkg, NuGet) +packages/ +vcpkg_installed/ + +# Visual Studio Code +.vscode/ + +# JetBrains IDEs +.idea/ + +# Resource compiled files +*.aps \ No newline at end of file diff --git a/CursorAnchor.sln b/CursorAnchor.sln new file mode 100644 index 0000000..574fd72 --- /dev/null +++ b/CursorAnchor.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}") = "CursorAnchor", "CursorAnchor\CursorAnchor.vcxproj", "{2C08EE0E-E20C-41E0-8A97-EC2D1FA6FAAE}" +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 + {2C08EE0E-E20C-41E0-8A97-EC2D1FA6FAAE}.Debug|x64.ActiveCfg = Debug|x64 + {2C08EE0E-E20C-41E0-8A97-EC2D1FA6FAAE}.Debug|x64.Build.0 = Debug|x64 + {2C08EE0E-E20C-41E0-8A97-EC2D1FA6FAAE}.Debug|x86.ActiveCfg = Debug|Win32 + {2C08EE0E-E20C-41E0-8A97-EC2D1FA6FAAE}.Debug|x86.Build.0 = Debug|Win32 + {2C08EE0E-E20C-41E0-8A97-EC2D1FA6FAAE}.Release|x64.ActiveCfg = Release|x64 + {2C08EE0E-E20C-41E0-8A97-EC2D1FA6FAAE}.Release|x64.Build.0 = Release|x64 + {2C08EE0E-E20C-41E0-8A97-EC2D1FA6FAAE}.Release|x86.ActiveCfg = Release|Win32 + {2C08EE0E-E20C-41E0-8A97-EC2D1FA6FAAE}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/CursorAnchor/CursorAnchor.vcxproj b/CursorAnchor/CursorAnchor.vcxproj new file mode 100644 index 0000000..a883886 --- /dev/null +++ b/CursorAnchor/CursorAnchor.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {2c08ee0e-e20c-41e0-8a97-ec2d1fa6faae} + CursorAnchor + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;CURSORANCHOR_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;CURSORANCHOR_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;CURSORANCHOR_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + + + + + Windows + true + false + + + + + Level3 + true + true + true + NDEBUG;CURSORANCHOR_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + + + Windows + true + true + true + false + + + + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/CursorAnchor/CursorAnchor.vcxproj.filters b/CursorAnchor/CursorAnchor.vcxproj.filters new file mode 100644 index 0000000..6ba099b --- /dev/null +++ b/CursorAnchor/CursorAnchor.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {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 + + + {02127372-2d70-4bd6-8971-ec8977e0ee4b} + + + {b77417b3-3719-455a-b7bf-410b1bef7579} + + + + + File di intestazione + + + File di intestazione + + + Dependencies\nexus + + + + + File di origine + + + File di origine + + + \ No newline at end of file diff --git a/CursorAnchor/Dependencies/nexus/Nexus.h b/CursorAnchor/Dependencies/nexus/Nexus.h new file mode 100644 index 0000000..3f88a19 --- /dev/null +++ b/CursorAnchor/Dependencies/nexus/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/CursorAnchor/dllmain.cpp b/CursorAnchor/dllmain.cpp new file mode 100644 index 0000000..a18e369 --- /dev/null +++ b/CursorAnchor/dllmain.cpp @@ -0,0 +1,95 @@ +#include "pch.h" +#include "Dependencies/nexus/Nexus.h" +#include + +AddonAPI* g_api = nullptr; + +struct { + bool enabled = false; +} g_state; + +void HandleKeybind(const char* identifier, bool isRelease) { + if (!isRelease && g_state.enabled) { + POINT currentPos; + GetCursorPos(¤tPos); + + int screenWidth = GetSystemMetrics(SM_CXSCREEN); + int screenHeight = GetSystemMetrics(SM_CYSCREEN); + int centerX = screenWidth / 2; + int centerY = screenHeight / 2; + + if (currentPos.x != centerX || currentPos.y != centerY) { + BlockInput(TRUE); + SetCursorPos(centerX, centerY); + Sleep(1); + BlockInput(FALSE); + } + + if (g_api) { + g_api->GameBinds.InvokeAsync(EGameBinds_CameraActionMode, 50); + } + } +} + +void Load(AddonAPI* api) { + g_api = api; + g_state.enabled = true; + + if (g_api) { + g_api->Log(ELogLevel_INFO, "CursorAnchor", "Loading addon..."); + + Keybind kb; + kb.Key = 0; + kb.Alt = false; + kb.Ctrl = false; + kb.Shift = false; + + g_api->InputBinds.RegisterWithStruct("CursorAnchor.Center", HandleKeybind, kb); + + g_api->Log(ELogLevel_INFO, "CursorAnchor", "Addon loaded successfully"); + } +} + +void Unload() { + if (g_api) { + g_api->InputBinds.Deregister("CursorAnchor.Center"); + g_api->Log(ELogLevel_INFO, "CursorAnchor", "Addon unloaded successfully"); + g_api = nullptr; + } + g_state.enabled = false; +} + +extern "C" __declspec(dllexport) AddonDefinition* GetAddonDef() { + static AddonDefinition def; + def.Signature = -424242; + def.APIVersion = NEXUS_API_VERSION; + def.Name = "CursorAnchor"; + def.Version.Major = 1; + def.Version.Minor = 0; + def.Version.Build = 0; + def.Version.Revision = 0; + def.Author = "Azrub"; + def.Description = "Centers cursor when toggling action camera"; + def.Load = Load; + def.Unload = Unload; + def.Flags = EAddonFlags_None; + def.Provider = EUpdateProvider_Direct; + def.UpdateLink = "https://git.azrub.dev/azrub/CursorAnchor/releases/download/latest/CursorAnchor.dll"; + return &def; +} + +BOOL APIENTRY DllMain(HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved +) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} \ No newline at end of file diff --git a/CursorAnchor/framework.h b/CursorAnchor/framework.h new file mode 100644 index 0000000..3cd7ac8 --- /dev/null +++ b/CursorAnchor/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/CursorAnchor/pch.cpp b/CursorAnchor/pch.cpp new file mode 100644 index 0000000..69046d3 --- /dev/null +++ b/CursorAnchor/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/CursorAnchor/pch.h b/CursorAnchor/pch.h new file mode 100644 index 0000000..aa5d1c5 --- /dev/null +++ b/CursorAnchor/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 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e8fa171 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Azrub + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..02f379e --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# CursorAnchor + +A Guild Wars 2 addon for [Nexus](https://github.com/RaidcoreGG/Nexus) that automatically centers your cursor when toggling between target and action camera modes. + +## Description + +CursorAnchor solves a common annoyance in Guild Wars 2: when switching between camera modes, the game remembers your cursor position, which can be problematic if you moved your cursor far away or to a second monitor. This addon ensures your cursor is always centered when toggling camera modes. + +Particularly useful for players who: +- Primarily use action camera but occasionally need target camera for specific skills +- Use multiple monitors +- Want to avoid losing track of their cursor position + +## Installation + +1. Install [Nexus Addon Loader](https://github.com/RaidcoreGG/Nexus) +2. Download `CursorAnchor.dll` from the [latest release](https://github.com/Azrub/CursorAnchor/releases) +3. Place the DLL in your `Guild Wars 2/addons` folder +4. Start the game +5. Keep or change your existing action camera toggle keybind in your game settings +6. In Nexus keybinds, set up the same action camera toggle key that you use in-game +7. Configure a different key for this addon (what you are actually going to use to change camera) + + +## Building from Source + +### Requirements +- Visual Studio 2022 +- Windows SDK +- C++17 or later + +### Steps +1. Clone the repository +2. Open the solution in Visual Studio +3. Build the solution in Release mode +4. The compiled DLL will be in `x64/Release/CursorAnchor.dll` + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. + +## Acknowledgments + +- Thanks to the Nexus team for providing the addon framework. +- Originally created as an AutoHotkey script by me for personal use, this addon has been rewritten in C++ to leverage Nexus addon loader's capabilities for better performance and smoother integration with Guild Wars 2.