├── .editorconfig
├── .github
└── workflows
│ ├── delete_old_workflow.yml
│ ├── pull_requests.yml
│ └── release.yml
├── .gitignore
├── .pre-commit-config.yaml
├── AutoHotKeyTrigger
├── AutoHotKeyTrigger.csproj
├── AutoHotKeyTriggerCore.cs
├── AutoHotKeyTriggerSettings.cs
├── FlaskNameToBuff.json
├── JsonDataHelper.cs
├── ProfileManager
│ ├── Component
│ │ ├── IComponent.cs
│ │ └── Wait.cs
│ ├── Conditions
│ │ ├── AilmentCondition.cs
│ │ ├── AnimationCondition.cs
│ │ ├── DynamicCondition
│ │ │ ├── BuffDictionary.cs
│ │ │ ├── DynamicCondition.cs
│ │ │ ├── DynamicConditionState.cs
│ │ │ ├── FlaskInfo.cs
│ │ │ ├── FlasksInfo.cs
│ │ │ ├── Interface
│ │ │ │ ├── IBuffDictionary.cs
│ │ │ │ ├── IDynamicConditionState.cs
│ │ │ │ ├── IFlaskInfo.cs
│ │ │ │ ├── IFlasksInfo.cs
│ │ │ │ ├── IStatusEffect.cs
│ │ │ │ ├── IVital.cs
│ │ │ │ ├── IVitalsInfo.cs
│ │ │ │ └── MonsterRarity.cs
│ │ │ ├── NearbyMonsterInfo.cs
│ │ │ ├── StatusEffect.cs
│ │ │ ├── Vital.cs
│ │ │ └── VitalsInfo.cs
│ │ ├── FlaskChargesCondition.cs
│ │ ├── FlaskEffectCondition.cs
│ │ ├── ICondition.cs
│ │ ├── StatusEffectCondition.cs
│ │ └── VitalsCondition.cs
│ ├── Enums
│ │ ├── ConditionType.cs
│ │ ├── OperatorType.cs
│ │ ├── StatusEffectCheckType.cs
│ │ └── VitalType.cs
│ ├── Profile.cs
│ ├── Rule.cs
│ └── VirtualKeys.cs
└── StatusEffectGroup.json
├── GameHelper
├── Cache
│ └── DisappearingEntity.cs
├── Core.cs
├── CoroutineEvents
│ ├── GameHelperEvents.cs
│ ├── HybridEvents.cs
│ └── RemoteEvents.cs
├── GameHelper.csproj
├── GameOverlay.cs
├── GameProcess.cs
├── Plugin
│ ├── IPCore.cs
│ ├── IPSettings.cs
│ ├── PCore.cs
│ ├── PManager.cs
│ ├── PluginAssemblyLoadContext.cs
│ └── PluginMetadata.cs
├── Program.cs
├── RemoteEnums
│ ├── Animation.cs
│ ├── EntityType.cs
│ ├── GameStateTypes.cs
│ ├── InventoryName.cs
│ └── Rarity.cs
├── RemoteObjects
│ ├── AreaChangeCounter.cs
│ ├── Components
│ │ ├── Actor.cs
│ │ ├── Base.cs
│ │ ├── Buffs.cs
│ │ ├── Charges.cs
│ │ ├── Chest.cs
│ │ ├── DiesAfterTime.cs
│ │ ├── Life.cs
│ │ ├── MinimapIcon.cs
│ │ ├── NPC.cs
│ │ ├── ObjectMagicProperties.cs
│ │ ├── Player.cs
│ │ ├── Positioned.cs
│ │ ├── Render.cs
│ │ ├── Shrine.cs
│ │ └── TriggerableBlockage.cs
│ ├── FilesStructures
│ │ └── WorldAreaDat.cs
│ ├── GameStates.cs
│ ├── GameWindowCull.cs
│ ├── GameWindowScale.cs
│ ├── LoadedFiles.cs
│ ├── RemoteObjectBase.cs
│ ├── States
│ │ ├── AreaLoadingState.cs
│ │ ├── InGameState.cs
│ │ └── InGameStateObjects
│ │ │ ├── AreaInstance.cs
│ │ │ ├── Entity.cs
│ │ │ ├── ImportantUiElements.cs
│ │ │ ├── Inventory.cs
│ │ │ ├── Item.cs
│ │ │ ├── ServerData.cs
│ │ │ └── WorldData.cs
│ ├── TerrainHeightHelper.cs
│ └── UiElement
│ │ ├── LargeMapUiElement.cs
│ │ ├── MapUiElement.cs
│ │ └── UiElementBase.cs
├── Settings
│ ├── SettingsWindow.cs
│ └── State.cs
├── Ui
│ ├── DataVisualization.cs
│ ├── GameUiExplorer.cs
│ ├── OverlayKiller.cs
│ └── PerformanceStats.cs
├── Utils
│ ├── ImGuiHelper.cs
│ ├── JsonHelper.cs
│ ├── MathHelper.cs
│ ├── MiscHelper.cs
│ ├── PatternFinder.cs
│ ├── RemoteObjectPropertyDetail.cs
│ └── SafeMemoryHandle.cs
└── app.manifest
├── GameOffsets
├── GameOffsets.csproj
├── GameProcessName.cs
├── Natives
│ ├── StdBucket.cs
│ ├── StdList.cs
│ ├── StdMap.cs
│ ├── StdTuple2D.cs
│ ├── StdTuple3D.cs
│ ├── StdVector.cs
│ ├── StdWString.cs
│ └── Util.cs
├── Objects
│ ├── AreaChangeOffset.cs
│ ├── Components
│ │ ├── Actor.cs
│ │ ├── Base.cs
│ │ ├── Buffs.cs
│ │ ├── Charges.cs
│ │ ├── Chest.cs
│ │ ├── ComponentHeader.cs
│ │ ├── Life.cs
│ │ ├── ObjectMagicProperties.cs
│ │ ├── Player.cs
│ │ ├── Positioned.cs
│ │ ├── Render.cs
│ │ ├── Shrine.cs
│ │ └── TriggerableBlockage.cs
│ ├── FilesStructures
│ │ ├── BaseItemTypesDatOffsets.cs
│ │ └── WorldAreaDatOffsets.cs
│ ├── GameStateOffsets.cs
│ ├── LoadedFilesOffset.cs
│ ├── States
│ │ ├── AreaLoadingStateOffset.cs
│ │ ├── InGameState
│ │ │ ├── AreaInstanceOffsets.cs
│ │ │ ├── EntityOffsets.cs
│ │ │ ├── ImportantUiElementsOffsets.cs
│ │ │ ├── InventoryOffset.cs
│ │ │ ├── ServerDataOffset.cs
│ │ │ └── WorldDataOffset.cs
│ │ └── InGameStateOffset.cs
│ └── UiElement
│ │ ├── MapUiElement.cs
│ │ └── UiElementBaseOffset.cs
├── Pattern.cs
└── StaticOffsetsPatterns.cs
├── GameOverlay.sln
├── GameOverlay.sln.DotSettings
├── HealthBars
├── Controller
│ └── SpriteController.cs
├── HealthBars.cs
├── HealthBars.csproj
├── HealthBarsSettings.cs
├── Sprite.cs
├── SpriteAtlas.cs
├── SpritesheetMetadata.cs
├── View
│ ├── Entities
│ │ ├── CommonFriendly.cs
│ │ ├── CurrentPlayer.cs
│ │ ├── Default.cs
│ │ ├── Enemy.cs
│ │ ├── EntityParams.cs
│ │ ├── Friendly.cs
│ │ ├── IEntity.cs
│ │ └── Invalid.cs
│ └── EntityFactory.cs
├── sprites
│ ├── ES.png
│ ├── EmptyHP.png
│ ├── EmptyMana.png
│ ├── EnemyHP.png
│ ├── HP.png
│ ├── Mana.png
│ ├── MonsterBar.png
│ └── PlayerBars.png
├── spritesheet.json
└── spritesheet.png
├── Launcher
├── AutoUpdate.cs
├── GameHelperFinder.cs
├── GameHelperTransformer.cs
├── Launcher.csproj
├── LocationValidator.cs
├── MiscHelper.cs
├── Program.cs
├── Properties
│ └── launchSettings.json
├── TemporaryFileManager.cs
└── app.manifest
├── NuGet.config
├── PreloadAlert
├── PreloadAlert.cs
├── PreloadAlert.csproj
└── PreloadSettings.cs
├── README.md
├── Radar
├── Helper.cs
├── IconPicker.cs
├── MapEdgeDetector.cs
├── Radar.cs
├── Radar.csproj
├── RadarSettings.cs
└── icons.png
└── SamplePluginTemplate
└── Changeme
├── Changeme.csproj
├── ChangemeCore.cs
└── ChangemeSettings.cs
/.github/workflows/delete_old_workflow.yml:
--------------------------------------------------------------------------------
1 | name: DeleteGithubActions
2 | on:
3 | delete:
4 | schedule:
5 | - cron: '0 0 * * *'
6 | workflow_dispatch:
7 | inputs:
8 | workflowName:
9 | description: 'Name of workflow to delete from'
10 | required: true
11 | default: 'DeleteGithubActions'
12 |
13 | jobs:
14 | del_runs:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Delete workflow runs on manual trigger
18 | if: github.event_name=='workflow_dispatch'
19 | uses: mwigginsdev/delete-oldest-workflow-runs@main
20 | with:
21 | token: ${{ github.token }}
22 | repository: ${{ github.repository }}
23 | keep_minimum_runs: '1'
24 | workflow_name: ${{ github.event.inputs.workflowName }}
25 |
26 | - name: Delete workflow runs on manual trigger
27 | if: github.event_name=='schedule'
28 | uses: mwigginsdev/delete-oldest-workflow-runs@main
29 | with:
30 | token: ${{ github.token }}
31 | repository: ${{ github.repository }}
32 | keep_minimum_runs: '1'
33 | workflow_name: 'Release'
34 |
35 | - name: Delete workflow runs on manual trigger
36 | if: github.event_name=='delete'
37 | uses: mwigginsdev/delete-oldest-workflow-runs@main
38 | with:
39 | token: ${{ github.token }}
40 | repository: ${{ github.repository }}
41 | keep_minimum_runs: '5'
42 | workflow_name: 'PullRequest'
43 |
--------------------------------------------------------------------------------
/.github/workflows/pull_requests.yml:
--------------------------------------------------------------------------------
1 | name: PullRequest
2 |
3 | on:
4 | pull_request:
5 | branches: [master]
6 |
7 | jobs:
8 | build:
9 | runs-on: ${{ matrix.os }}
10 | strategy:
11 | matrix:
12 | os: [windows-latest]
13 | steps:
14 | - uses: actions/checkout@master
15 | - uses: goit/setup-resharper@v2.0.0
16 | with:
17 | version: '2021.2'
18 |
19 | - name: Setup .NET
20 | uses: actions/setup-dotnet@v1
21 | with:
22 | dotnet-version: 5.0.x
23 |
24 | - name: Restore dependencies
25 | run: dotnet restore
26 |
27 | - name: Resharper Linter
28 | run: InspectCode GameOverlay.sln --build --profile=GameOverlay.sln.DotSettings --output=resharper.html --format=Html
29 |
30 | - name: Upload the Build Artifact
31 | uses: actions/upload-artifact@v2
32 | with:
33 | path: resharper.html
34 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | branches: [master, r/*]
6 | workflow_dispatch:
7 |
8 | jobs:
9 | build:
10 | runs-on: ${{ matrix.os }}
11 | env:
12 | GH_RELEASE_VERSION: ${{ needs.upversion.outputs.new_version }}
13 | needs: [upversion]
14 | strategy:
15 | matrix:
16 | os: [windows-latest]
17 | steps:
18 | - uses: actions/checkout@v2
19 |
20 | - name: Setup .NET
21 | uses: actions/setup-dotnet@v1
22 | with:
23 | dotnet-version: 5.0.x
24 |
25 | - name: Restore dependencies
26 | run: dotnet restore
27 |
28 | - name: Build
29 | run: |
30 | dotnet build --configuration Release --no-restore
31 | echo ${{ env.GH_RELEASE_VERSION }} > GameHelper/bin/Release/net5.0/VERSION.txt
32 |
33 | - name: Create Zip For Release
34 | uses: papeloto/action-zip@v1
35 | with:
36 | files: GameHelper/bin/Release/net5.0/
37 | dest: release.zip
38 |
39 | - name: Create Release
40 | uses: softprops/action-gh-release@v1
41 | with:
42 | tag_name: ${{ env.GH_RELEASE_VERSION }}
43 | name: GameHelper-standard-${{ env.GH_RELEASE_VERSION }}
44 | files: release.zip
45 | draft: false
46 | prerelease: false
47 |
48 | upversion:
49 | runs-on: [ubuntu-latest]
50 | outputs:
51 | new_version: ${{ steps.bump-semver.outputs.new_version }}
52 | steps:
53 | - uses: actions/checkout@v2
54 | - uses: actions-ecosystem/action-get-latest-tag@v1
55 | id: get-latest-tag
56 | with:
57 | semver_only: true
58 | - uses: actions-ecosystem/action-bump-semver@v1
59 | id: bump-semver
60 | with:
61 | current_version: ${{ steps.get-latest-tag.outputs.tag }}
62 | level: minor
63 | - uses: actions-ecosystem/action-push-tag@v1
64 | with:
65 | tag: ${{ steps.bump-semver.outputs.new_version }}
66 | message: "${{ steps.bump-semver.outputs.new_version }}: PR #${{ github.event.pull_request.number }} ${{ github.event.pull_request.title }}"
67 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/pre-commit/pre-commit-hooks
3 | rev: v3.3.0
4 | hooks:
5 | - id: check-yaml
6 | - id: trailing-whitespace
7 | - id: no-commit-to-branch
8 | args: ['--branch', 'master']
9 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/AutoHotKeyTrigger.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | Library
6 | true
7 | true
8 | x64
9 |
10 |
11 |
12 |
13 | runtime
14 |
15 |
16 |
17 |
18 |
19 |
20 | false
21 | runtime
22 | false
23 |
24 |
25 |
26 |
27 |
28 | PreserveNewest
29 |
30 |
31 | PreserveNewest
32 |
33 |
34 |
35 |
36 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/AutoHotKeyTriggerSettings.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using GameHelper.Plugin;
10 | using ProfileManager;
11 | using ProfileManager.Conditions;
12 | using AutoHotKeyTrigger.ProfileManager.Enums;
13 |
14 | ///
15 | /// plugin settings class.
16 | ///
17 | public sealed class AutoHotKeyTriggerSettings : IPSettings
18 | {
19 |
20 | ///
21 | /// Gets a value indicating whether to enable or disable the auto-quit feature.
22 | ///
23 | public bool EnableAutoQuit = false;
24 |
25 | ///
26 | /// Condition on which user want to auto-quit.
27 | ///
28 | public readonly VitalsCondition AutoQuitCondition =
29 | new(OperatorType.LESS_THAN, VitalType.LIFE_PERCENT, 30);
30 |
31 | ///
32 | /// Gets a key which allows the user to manually quit the game Connection.
33 | ///
34 | public ConsoleKey AutoQuitKey = ConsoleKey.F11;
35 |
36 | ///
37 | /// Gets all the profiles containing rules on when to perform the action.
38 | ///
39 | public readonly Dictionary Profiles = new();
40 |
41 | ///
42 | /// Gets the currently selected profile.
43 | ///
44 | public string CurrentProfile = string.Empty;
45 |
46 | ///
47 | /// Gets a value indicating weather the debug mode is enabled or not.
48 | ///
49 | public bool DebugMode = false;
50 |
51 | ///
52 | /// Gets a value indicating weather this plugin should work in hideout or not.
53 | ///
54 | public bool ShouldRunInHideout = true;
55 |
56 | ///
57 | /// Gets a value indicating weather user wants to dump the player
58 | /// status effect or not.
59 | ///
60 | public ConsoleKey DumpStatusEffectOnMe = ConsoleKey.F10;
61 | }
62 | }
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/JsonDataHelper.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger
6 | {
7 | using System.Collections.Generic;
8 |
9 | ///
10 | /// A helper class that reads JSON data and provides useful functions.
11 | ///
12 | public static class JsonDataHelper
13 | {
14 | ///
15 | /// Gets or sets the flask buff name by looking at flask base name.
16 | ///
17 | public static Dictionary> FlaskNameToBuffGroups { get; set; } =
18 | new();
19 |
20 | ///
21 | /// Gets or sets the status effects in a group and the group name.
22 | ///
23 | public static Dictionary> StatusEffectGroups { get; set; } =
24 | new();
25 | }
26 | }
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Component/IComponent.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Component
6 | {
7 | ///
8 | /// A partial condition that can't be used on it's own and
9 | /// adds more logic to a .
10 | ///
11 | public interface IComponent
12 | {
13 | ///
14 | /// Executes the component
15 | ///
16 | /// returns true or false based on the component states
17 | public bool execute(bool isConditionValid);
18 |
19 | ///
20 | /// Display the component via ImGui widgets.
21 | ///
22 | /// should display the component in expanded form or non expanded form.
23 | public void Display(bool expand);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Component/Wait.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 |
6 | namespace AutoHotKeyTrigger.ProfileManager.Component
7 | {
8 | using ImGuiNET;
9 | using Newtonsoft.Json;
10 | using System.Diagnostics;
11 | using System.Numerics;
12 |
13 | ///
14 | /// Adds wait to the condition.
15 | ///
16 | public class Wait : IComponent
17 | {
18 | [JsonProperty] private float duration;
19 | private Stopwatch sw;
20 |
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | /// duration in seconds to wait for.
25 | public Wait(float duation)
26 | {
27 | this.duration = duation;
28 | this.sw = new();
29 | }
30 |
31 | ///
32 | public void Display(bool expand)
33 | {
34 | if (expand)
35 | {
36 | ImGui.Text("Condition WAITS for");
37 | ImGui.SameLine();
38 | ImGui.DragFloat("(seconds)##WAITCOMPONENT", ref this.duration, 0.05f, 0.0f, 5f);
39 | }
40 | else
41 | {
42 | ImGui.SameLine();
43 | ImGui.Text("for");
44 | ImGui.SameLine();
45 | ImGui.TextColored(new Vector4(255, 255, 0, 255), $"{this.duration}");
46 | ImGui.SameLine();
47 | ImGui.Text("seconds.");
48 | }
49 | }
50 |
51 | ///
52 | public bool execute(bool isConditionValid)
53 | {
54 | if (isConditionValid)
55 | {
56 | if (!this.sw.IsRunning)
57 | {
58 | this.sw.Start();
59 | }
60 |
61 | if (this.sw.ElapsedMilliseconds >= (this.duration * 1000f))
62 | {
63 | return true;
64 | }
65 | }
66 | else
67 | {
68 | this.sw.Reset();
69 | }
70 |
71 | return false;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/BuffDictionary.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition
6 | {
7 | using System.Collections.Generic;
8 | using GameOffsets.Objects.Components;
9 | using Interface;
10 |
11 | ///
12 | /// Describes a set of buffs applied to the player
13 | ///
14 | public class BuffDictionary : IBuffDictionary
15 | {
16 | private readonly IReadOnlyDictionary source;
17 |
18 | ///
19 | /// Creates a new instance
20 | ///
21 | /// Source data for the buffs
22 | public BuffDictionary(IReadOnlyDictionary source)
23 | {
24 | this.source = source;
25 | }
26 |
27 | ///
28 | /// Returns a buff description
29 | ///
30 | /// The buff id
31 | public IStatusEffect this[string id]
32 | {
33 | get
34 | {
35 | if (this.source.TryGetValue(id, out var value))
36 | {
37 | return new StatusEffect(true, value.TimeLeft, value.TotalTime, value.Charges, value.Effectiveness);
38 | }
39 |
40 | return new StatusEffect(false, 0, 0, 0, 0);
41 | }
42 | }
43 |
44 | ///
45 | /// Checks whether the buff is present
46 | ///
47 | /// The buff id
48 | public bool Has(string id)
49 | {
50 | return this.source.ContainsKey(id);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/FlaskInfo.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition
6 | {
7 | using System;
8 | using System.Linq;
9 | using GameHelper.RemoteObjects.Components;
10 | using GameHelper.RemoteObjects.States;
11 | using GameHelper.RemoteObjects.States.InGameStateObjects;
12 | using Interface;
13 |
14 | ///
15 | /// The structure describing a flask state
16 | ///
17 | /// Whether the flask effect is active now
18 | /// Current charge amount of a flask
19 | public record FlaskInfo(bool Active, int Charges) : IFlaskInfo
20 | {
21 | ///
22 | /// Create a new instance from the state and flask data
23 | ///
24 | /// State to build the structure from
25 | /// The flask entity
26 | ///
27 | ///
28 | public static FlaskInfo From(InGameState state, Item flaskItem)
29 | {
30 | if (flaskItem.Address == IntPtr.Zero)
31 | {
32 | return new FlaskInfo(false, 0);
33 | }
34 |
35 | var active = false;
36 | if (flaskItem.TryGetComponent(out var @base))
37 | {
38 | if (!JsonDataHelper.FlaskNameToBuffGroups.TryGetValue(@base.ItemBaseName, out var buffNames))
39 | {
40 | throw new Exception($"New (IsValid={flaskItem.IsValid}) flask base found " +
41 | $"{@base.ItemBaseName}. Please let the developer know.");
42 | }
43 |
44 | if (state.CurrentAreaInstance.Player.TryGetComponent(out var playerBuffs))
45 | {
46 | active = buffNames.Any(playerBuffs.StatusEffects.ContainsKey);
47 | }
48 | }
49 |
50 | var charges = flaskItem.TryGetComponent(out var chargesComponent) ? chargesComponent.Current : 0;
51 | return new FlaskInfo(active, charges);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/FlasksInfo.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Linq;
10 | using GameHelper.RemoteObjects.States;
11 | using Interface;
12 |
13 | ///
14 | /// Information about a set of flasks
15 | ///
16 | public class FlasksInfo : IFlasksInfo
17 | {
18 | private const int FlaskCount = 5;
19 |
20 | ///
21 | /// Provides access to the flask array
22 | ///
23 | /// The flask index (0-based)
24 | public IFlaskInfo this[int i]
25 | {
26 | get
27 | {
28 | if (i < 0 || i >= FlaskCount)
29 | {
30 | throw new Exception($"Flask index is 0-based and must be in the range of 0-{FlaskCount - 1}");
31 | }
32 |
33 | return this.flasks[i];
34 | }
35 | }
36 |
37 | ///
38 | /// The flask in the first slot;
39 | ///
40 | public IFlaskInfo Flask1 => this[0];
41 |
42 | ///
43 | /// The flask in the second slot;
44 | ///
45 | public IFlaskInfo Flask2 => this[1];
46 |
47 | ///
48 | /// The flask in the third slot;
49 | ///
50 | public IFlaskInfo Flask3 => this[2];
51 |
52 | ///
53 | /// The flask in the fourth slot;
54 | ///
55 | public IFlaskInfo Flask4 => this[3];
56 |
57 | ///
58 | /// The flask in the fifth slot;
59 | ///
60 | public IFlaskInfo Flask5 => this[4];
61 |
62 | private readonly IReadOnlyList flasks;
63 |
64 | ///
65 | /// Creates a new instance
66 | ///
67 | /// State to build the structure from
68 | public FlasksInfo(InGameState state)
69 | {
70 | this.flasks = Enumerable.Range(0, FlaskCount)
71 | .Select(i => state.CurrentAreaInstance.ServerDataObject.FlaskInventory[0, i])
72 | .Select(f => FlaskInfo.From(state, f))
73 | .ToList();
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/Interface/IBuffDictionary.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition.Interface
6 | {
7 | ///
8 | /// Describes a set of buffs applied to the player
9 | ///
10 | public interface IBuffDictionary
11 | {
12 | ///
13 | /// Returns a buff description
14 | ///
15 | /// The buff id
16 | IStatusEffect this[string id] { get; }
17 |
18 | ///
19 | /// Checks whether the buff is present
20 | ///
21 | bool Has(string id);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/Interface/IDynamicConditionState.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition.Interface
6 | {
7 | using System.Collections.Generic;
8 | using GameHelper.RemoteEnums;
9 |
10 | ///
11 | /// The structure that can be queried using DynamicCondition
12 | ///
13 | public interface IDynamicConditionState
14 | {
15 | ///
16 | /// The ailment list
17 | ///
18 | IReadOnlyCollection Ailments { get; }
19 |
20 | ///
21 | /// The current animation
22 | ///
23 | Animation Animation { get; }
24 |
25 | ///
26 | /// The buff list
27 | ///
28 | IBuffDictionary Buffs { get; }
29 |
30 | ///
31 | /// The flask information
32 | ///
33 | IFlasksInfo Flasks { get; }
34 |
35 | ///
36 | /// The vitals information
37 | ///
38 | IVitalsInfo Vitals { get; }
39 |
40 | ///
41 | /// Number of friendly nearby monsters
42 | ///
43 | int FriendlyMonsterCount { get; }
44 |
45 | ///
46 | /// Calculates the number of nearby monsters given a rarity selector
47 | ///
48 | /// The rarity selector for monster search
49 | ///
50 | int MonsterCount(MonsterRarity rarity);
51 |
52 | ///
53 | /// Detect a keypress event
54 | ///
55 | bool IsKeyPressedForAction(int vk);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/Interface/IFlaskInfo.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition.Interface
6 | {
7 | ///
8 | /// The structure describing a flask state
9 | ///
10 | public interface IFlaskInfo
11 | {
12 | ///
13 | /// Whether the flask effect is active now
14 | ///
15 | bool Active { get; init; }
16 |
17 | ///
18 | /// Current charge amount of a flask
19 | ///
20 | int Charges { get; init; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/Interface/IFlasksInfo.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition.Interface
6 | {
7 | ///
8 | /// Information about a set of flasks
9 | ///
10 | public interface IFlasksInfo
11 | {
12 | ///
13 | /// Provides access to the flask array
14 | ///
15 | /// The flask index (0-based)
16 | IFlaskInfo this[int i] { get; }
17 |
18 | ///
19 | /// The flask in the first slot;
20 | ///
21 | IFlaskInfo Flask1 { get; }
22 |
23 | ///
24 | /// The flask in the second slot;
25 | ///
26 | IFlaskInfo Flask2 { get; }
27 |
28 | ///
29 | /// The flask in the third slot;
30 | ///
31 | IFlaskInfo Flask3 { get; }
32 |
33 | ///
34 | /// The flask in the fourth slot;
35 | ///
36 | IFlaskInfo Flask4 { get; }
37 |
38 | ///
39 | /// The flask in the fifth slot;
40 | ///
41 | IFlaskInfo Flask5 { get; }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/Interface/IStatusEffect.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition.Interface
6 | {
7 | ///
8 | /// Information about a status effect
9 | ///
10 | public interface IStatusEffect
11 | {
12 | ///
13 | /// Amount of stacks of the effect
14 | ///
15 | int Charges { get; init; }
16 |
17 | ///
18 | /// Whether it exists on the player currently
19 | ///
20 | bool Exists { get; init; }
21 |
22 | ///
23 | /// Time left in percent from total time
24 | ///
25 | double PercentTimeLeft { get; }
26 |
27 | ///
28 | /// Time left in seconds
29 | ///
30 | double TimeLeft { get; init; }
31 |
32 | ///
33 | /// Total time the effect will last
34 | ///
35 | double TotalTime { get; init; }
36 |
37 | ///
38 | /// Effectiveness of the status effect like elusive
39 | /// Value might change from effect to effect and might not be between 0 - 100.
40 | ///
41 | int Effectiveness { get; init; }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/Interface/IVital.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition.Interface
6 | {
7 | ///
8 | /// Information about a vital
9 | ///
10 | public interface IVital
11 | {
12 | ///
13 | /// Current value
14 | ///
15 | double Current { get; }
16 |
17 | ///
18 | /// Maximum value
19 | ///
20 | double Max { get; }
21 |
22 | ///
23 | /// Value in percent from the max
24 | ///
25 | double Percent { get; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/Interface/IVitalsInfo.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition.Interface
6 | {
7 | ///
8 | /// Information about player vitals
9 | ///
10 | public interface IVitalsInfo
11 | {
12 | ///
13 | /// Energy shield information
14 | ///
15 | IVital ES { get; }
16 |
17 | ///
18 | /// Health information
19 | ///
20 | IVital HP { get; }
21 |
22 | ///
23 | /// Mana information
24 | ///
25 | IVital Mana { get; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/Interface/MonsterRarity.cs:
--------------------------------------------------------------------------------
1 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition.Interface
2 | {
3 | using System;
4 |
5 | ///
6 | /// different rarity of monster available in the game.
7 | ///
8 | [Flags]
9 | public enum MonsterRarity
10 | {
11 | ///
12 | /// Monsters with red icons (i.e. white monsters).
13 | ///
14 | Normal = 1 << 0,
15 |
16 | ///
17 | /// Monsters with blue icons (i.e. blue monsters).
18 | ///
19 | Magic = 1 << 1,
20 |
21 | ///
22 | /// Monsters with yellow icons (i.e. yellow monsters).
23 | ///
24 | Rare = 1 << 2,
25 |
26 | ///
27 | /// Monsters with big red icon (i.e. golden monsters).
28 | ///
29 | Unique = 1 << 3,
30 |
31 | ///
32 | /// All rarity of monsters.
33 | ///
34 | Any = Normal | Magic | Rare | Unique,
35 |
36 | ///
37 | /// Rare or above.
38 | ///
39 | AtLeastRare = Rare | Unique
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/StatusEffect.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition
6 | {
7 | using Interface;
8 |
9 | ///
10 | /// Information about a status effect
11 | ///
12 | /// Whether it exists on the player currently
13 | /// Time left in seconds
14 | /// Total time the effect will last
15 | /// Amount of stacks of the effect
16 | /// Effectiveness of effects like elusive.
17 | public record StatusEffect(bool Exists, double TimeLeft, double TotalTime, int Charges, int Effectiveness) : IStatusEffect
18 | {
19 | ///
20 | /// Time left in percent from total time
21 | ///
22 | public double PercentTimeLeft =>
23 | this.Exists
24 | ? double.IsPositiveInfinity(this.TimeLeft)
25 | ? 100
26 | : 100 * this.TimeLeft / this.TotalTime
27 | : 0;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/Vital.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition
6 | {
7 | using GameOffsets.Objects.Components;
8 | using Interface;
9 |
10 | ///
11 | /// Information about a vital
12 | ///
13 | /// Current value
14 | /// Maximum value
15 | public record Vital(double Current, double Max) : IVital
16 | {
17 | ///
18 | /// Value in percent from the max
19 | ///
20 | public double Percent => this.Current / this.Max * 100;
21 |
22 | ///
23 | /// Creates a new instance
24 | ///
25 | /// Source data for the structure
26 | ///
27 | public static Vital From(VitalStruct vital)
28 | {
29 | return new Vital(vital.Current, vital.Unreserved);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/DynamicCondition/VitalsInfo.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Conditions.DynamicCondition
6 | {
7 | using GameHelper.RemoteObjects.Components;
8 | using Interface;
9 |
10 | ///
11 | /// Information about player vitals
12 | ///
13 | public class VitalsInfo : IVitalsInfo
14 | {
15 | ///
16 | /// Health information
17 | ///
18 | public IVital HP { get; }
19 |
20 | ///
21 | /// Energy shield information
22 | ///
23 | public IVital ES { get; }
24 |
25 | ///
26 | /// Mana information
27 | ///
28 | public IVital Mana { get; }
29 |
30 | ///
31 | /// Creates a new instance
32 | ///
33 | /// Source data for the structure
34 | public VitalsInfo(Life lifeComponent)
35 | {
36 | this.HP = Vital.From(lifeComponent.Health);
37 | this.ES = Vital.From(lifeComponent.EnergyShield);
38 | this.Mana = Vital.From(lifeComponent.Mana);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Conditions/ICondition.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 |
6 | namespace AutoHotKeyTrigger.ProfileManager.Conditions
7 | {
8 | using AutoHotKeyTrigger.ProfileManager.Component;
9 |
10 | ///
11 | /// Interface for the conditions on which actions can trigger.
12 | ///
13 | public interface ICondition
14 | {
15 | ///
16 | /// Evaluates the condition.
17 | ///
18 | /// true if the condition is successful, otherwise false.
19 | public bool Evaluate();
20 |
21 | ///
22 | /// Displays the condition to the user via ImGui.
23 | ///
24 | /// whether to expand the condition or not
25 | public void Display(bool expand);
26 |
27 | ///
28 | /// Adds the component to the condition.
29 | ///
30 | /// component object to add.
31 | void Add(IComponent component);
32 | }
33 | }
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Enums/ConditionType.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Enums
6 | {
7 | using Newtonsoft.Json;
8 | using Newtonsoft.Json.Converters;
9 |
10 | ///
11 | /// Conditions supported by this plugin.
12 | ///
13 | [JsonConverter(typeof(StringEnumConverter))]
14 | public enum ConditionType
15 | {
16 | ///
17 | /// Condition based on player Vitals.
18 | ///
19 | VITALS,
20 |
21 | ///
22 | /// Condition based on what player is doing.
23 | ///
24 | ANIMATION,
25 |
26 | ///
27 | /// Condition based on player Buffs/Debuffs.
28 | ///
29 | STATUS_EFFECT,
30 |
31 | ///
32 | /// Condition based on flask mod active on player or not.
33 | ///
34 | FLASK_EFFECT,
35 |
36 | ///
37 | /// Condition based on number of charges flask has.
38 | ///
39 | FLASK_CHARGES,
40 |
41 | ///
42 | /// Condition based on Ailment on the player.
43 | ///
44 | AILMENT,
45 |
46 | ///
47 | /// Condition base on user code
48 | ///
49 | DYNAMIC
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Enums/OperatorType.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Enums
6 | {
7 | using Newtonsoft.Json;
8 | using Newtonsoft.Json.Converters;
9 |
10 | ///
11 | /// Different type of operators available to use on the Conditions.
12 | ///
13 | [JsonConverter(typeof(StringEnumConverter))]
14 | public enum OperatorType
15 | {
16 | ///
17 | /// Equal To Operator.
18 | ///
19 | EQUAL_TO,
20 |
21 | ///
22 | /// Not Equal To Operator.
23 | ///
24 | NOT_EQUAL_TO,
25 |
26 | ///
27 | /// Greater Than Operator.
28 | ///
29 | BIGGER_THAN,
30 |
31 | ///
32 | /// Less Than Operator.
33 | ///
34 | LESS_THAN,
35 |
36 | ///
37 | /// List/Dict Contains Operator.
38 | ///
39 | CONTAINS,
40 |
41 | ///
42 | /// List/Dict doesn't Contain Operator.
43 | ///
44 | NOT_CONTAINS
45 | }
46 | }
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Enums/StatusEffectCheckType.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Enums
6 | {
7 | using Newtonsoft.Json;
8 | using Newtonsoft.Json.Converters;
9 |
10 | ///
11 | /// Check type for the condition
12 | ///
13 | [JsonConverter(typeof(StringEnumConverter))]
14 | public enum StatusEffectCheckType
15 | {
16 | ///
17 | /// Check remaining buff duration
18 | ///
19 | DURATION,
20 |
21 | ///
22 | /// Check remaning buff duration in percent
23 | ///
24 | DURATION_PERCENT,
25 |
26 | ///
27 | /// Check buff charges
28 | ///
29 | CHARGES
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/ProfileManager/Enums/VitalType.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace AutoHotKeyTrigger.ProfileManager.Enums
6 | {
7 | using Newtonsoft.Json;
8 | using Newtonsoft.Json.Converters;
9 |
10 | ///
11 | /// Different type of player Vitals.
12 | ///
13 | [JsonConverter(typeof(StringEnumConverter))]
14 | public enum VitalType
15 | {
16 | ///
17 | /// Condition based on player Mana.
18 | ///
19 | MANA,
20 |
21 | ///
22 | /// Condition based on player Mana.
23 | ///
24 | MANA_PERCENT,
25 |
26 | ///
27 | /// Condition based on player Life.
28 | ///
29 | LIFE,
30 |
31 | ///
32 | /// Condition based on player Life.
33 | ///
34 | LIFE_PERCENT,
35 |
36 | ///
37 | /// Condition based on player Energy Shield.
38 | ///
39 | ENERGYSHIELD,
40 |
41 | ///
42 | /// Condition based on player Energy Shield.
43 | ///
44 | ENERGYSHIELD_PERCENT
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/AutoHotKeyTrigger/StatusEffectGroup.json:
--------------------------------------------------------------------------------
1 | {
2 | "Bleeding Or Corruption": [
3 | "bleeding",
4 | "puncture",
5 | "puncture_moving",
6 | "physical_damage_and_bleed",
7 | "corrupted_blood",
8 | "corrupted_blood_rain"
9 | ],
10 | "Bleeding": [
11 | "bleeding",
12 | "puncture",
13 | "puncture_moving",
14 | "physical_damage_and_bleed"
15 | ],
16 | "Corruption": [
17 | "corrupted_blood",
18 | "corrupted_blood_rain"
19 | ],
20 | "Frozen Or Chilled": [
21 | "frozen",
22 | "cold_damage_and_freeze",
23 | "chilled",
24 | "ground_ice_chill",
25 | "chilling_bond_in_beam",
26 | "yugul_pool_chilled"
27 | ],
28 | "Frozen": [
29 | "frozen",
30 | "cold_damage_and_freeze"
31 | ],
32 | "Chilled": [
33 | "chilled",
34 | "ground_ice_chill",
35 | "chilling_bond_in_beam",
36 | "yugul_pool_chilled"
37 | ],
38 | "Poisoned": [
39 | "poison",
40 | "viper_strike_orb",
41 | "ground_desecration",
42 | "caustic_cloud",
43 | "chaos_bond_in_beam"
44 | ],
45 | "Burning": [
46 | "ground_fire_burn",
47 | "ignited",
48 | "searing_bond_in_beam",
49 | "fire_damage_and_ignite",
50 | "righteous_fire_aura",
51 | "demon_righteous_fire_aura"
52 | ],
53 | "Shocked": [
54 | "shocked",
55 | "ground_lightning_shock",
56 | "seawitch_lightning_beam",
57 | "lightning_damage_and_shock"
58 | ],
59 | "Cursed": [
60 | "curse_temporal_chains",
61 | "curse_elemental_weakness",
62 | "curse_cold_weakness",
63 | "curse_lightning_weakness",
64 | "curse_chaos_weakness",
65 | "curse_fire_weakness",
66 | "curse_newpunishment",
67 | "curse_enfeeble",
68 | "curse_vulnerability",
69 | "curse_warlords_mark",
70 | "curse_assassins_mark"
71 | ]
72 | }
73 |
--------------------------------------------------------------------------------
/GameHelper/CoroutineEvents/GameHelperEvents.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.CoroutineEvents
6 | {
7 | using Coroutine;
8 |
9 | ///
10 | /// Co-Routine events specific to the GameHelper.
11 | ///
12 | public static class GameHelperEvents
13 | {
14 | ///
15 | /// Gets the event raised when the game has changed its size, position or both.
16 | ///
17 | public static readonly Event OnMoved = new();
18 |
19 | ///
20 | /// Gets the event raised when the game Foreground property has changed.
21 | ///
22 | public static readonly Event OnForegroundChanged = new();
23 |
24 | ///
25 | /// Gets the event raised just before the GameProcess has closed the game.
26 | ///
27 | public static readonly Event OnClose = new();
28 |
29 | ///
30 | /// To Update data every frame before rendering.
31 | ///
32 | internal static readonly Event PerFrameDataUpdate = new();
33 |
34 | ///
35 | /// To submit ImGui code for generating the UI.
36 | ///
37 | internal static readonly Event OnRender = new();
38 |
39 | ///
40 | /// Gets the event raised when GameProcess has opened a new game.
41 | ///
42 | internal static readonly Event OnOpened = new();
43 |
44 | ///
45 | /// Gets the Game Helper closing event. The event is called whenever
46 | /// all the settings have to be saved.
47 | ///
48 | internal static readonly Event TimeToSaveAllSettings = new();
49 | }
50 | }
--------------------------------------------------------------------------------
/GameHelper/CoroutineEvents/HybridEvents.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.CoroutineEvents
6 | {
7 | using Coroutine;
8 |
9 | ///
10 | /// Events specific to the Game and the GameHelper state.
11 | ///
12 | public static class HybridEvents
13 | {
14 | ///
15 | /// Gets the event that is triggered after all the preloads
16 | /// of the current area/zone are updated.
17 | ///
18 | public static readonly Event PreloadsUpdated = new();
19 | }
20 | }
--------------------------------------------------------------------------------
/GameHelper/CoroutineEvents/RemoteEvents.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.CoroutineEvents
6 | {
7 | using Coroutine;
8 |
9 | ///
10 | /// Co-Routine events specific to the game.
11 | ///
12 | public static class RemoteEvents
13 | {
14 | ///
15 | /// Gets the event that is triggered 50ms after the area change detection.
16 | /// Area change is detected by checking if the time spend on the
17 | /// loading screen (given to us by the game) is greater than the
18 | /// last recorded time and IsLoading bool is set to false.
19 | /// NOTE: when this is triggered the preloads might not be up to date.
20 | ///
21 | public static readonly Event AreaChanged = new();
22 |
23 | ///
24 | /// Gets the Current State Changed event.
25 | ///
26 | internal static readonly Event StateChanged = new();
27 | }
28 | }
--------------------------------------------------------------------------------
/GameHelper/GameHelper.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | GameHelper.Program
6 | app.manifest
7 | zaafar
8 | An overlay to help play the game.
9 | true
10 |
11 |
12 |
13 | Exe
14 | false
15 | ;NU1605
16 | 1701;1702; 1591
17 | x64
18 |
19 |
20 |
21 | WinExe
22 | x64
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/GameHelper/Plugin/IPCore.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.Plugin
6 | {
7 | ///
8 | /// Interface for creating plugins.
9 | ///
10 | internal interface IPCore
11 | {
12 | ///
13 | /// Called at the init of the plugin to set
14 | /// it's directory information.
15 | ///
16 | /// plugin dll directory.
17 | public void SetPluginDllLocation(string dllLocation);
18 |
19 | ///
20 | /// Called when the plugin is enabled by the user or when GameOverlay
21 | /// starts and plugin is already enabled.
22 | ///
23 | /// value indicating whether game is open or not.
24 | public void OnEnable(bool isGameOpened);
25 |
26 | ///
27 | /// Called when the plugin is disabled by the user.
28 | ///
29 | public void OnDisable();
30 |
31 | ///
32 | /// Called to draw the plugin settings on the GameHelper Settings window.
33 | /// Should use ImGui objects to draw the settings.
34 | ///
35 | public void DrawSettings();
36 |
37 | ///
38 | /// Draws the plugin UI. This function isn't called when the plugin is disabled.
39 | ///
40 | public void DrawUI();
41 |
42 | ///
43 | /// Called when it's time to save all the settings
44 | /// related to the plugin on the file.
45 | /// NOTE: Load settings function isn't provided as
46 | /// it's expected the plugin will load the settings
47 | /// in OnEnable function.
48 | ///
49 | public void SaveSettings();
50 | }
51 | }
--------------------------------------------------------------------------------
/GameHelper/Plugin/IPSettings.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.Plugin
6 | {
7 | ///
8 | /// Interface for loading/saving plugin settings.
9 | ///
10 | public interface IPSettings { }
11 | }
--------------------------------------------------------------------------------
/GameHelper/Plugin/PCore.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.Plugin
6 | {
7 | ///
8 | /// Interface for creating plugins.
9 | ///
10 | /// plugin's setting class name.
11 | public abstract class PCore : IPCore
12 | where TSettings : IPSettings, new()
13 | {
14 | ///
15 | /// Gets or sets the plugin root directory folder.
16 | ///
17 | public string DllDirectory;
18 |
19 | ///
20 | /// Gets or sets the plugin settings.
21 | ///
22 | public TSettings Settings = new();
23 |
24 | ///
25 | public abstract void OnDisable();
26 |
27 | ///
28 | public abstract void OnEnable(bool isGameOpened);
29 |
30 | ///
31 | public abstract void DrawSettings();
32 |
33 | ///
34 | public abstract void DrawUI();
35 |
36 | ///
37 | public abstract void SaveSettings();
38 |
39 | ///
40 | public void SetPluginDllLocation(string dllLocation)
41 | {
42 | this.DllDirectory = dllLocation;
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/GameHelper/Plugin/PluginAssemblyLoadContext.cs:
--------------------------------------------------------------------------------
1 | namespace GameHelper.Plugin
2 | {
3 | using System.Reflection;
4 | using System.Runtime.Loader;
5 |
6 | internal class PluginAssemblyLoadContext : AssemblyLoadContext
7 | {
8 | private readonly AssemblyDependencyResolver resolver;
9 |
10 | public PluginAssemblyLoadContext(string assemblyLocation)
11 | {
12 | this.resolver = new AssemblyDependencyResolver(assemblyLocation);
13 | }
14 |
15 | protected override Assembly Load(AssemblyName assemblyName)
16 | {
17 | var path = this.resolver.ResolveAssemblyToPath(assemblyName);
18 | if (path != null)
19 | {
20 | return this.LoadFromAssemblyPath(path);
21 | }
22 |
23 | return null;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/GameHelper/Plugin/PluginMetadata.cs:
--------------------------------------------------------------------------------
1 | namespace GameHelper.Plugin
2 | {
3 | ///
4 | /// Container for plugin metadata.
5 | ///
6 | internal class PluginMetadata
7 | {
8 | ///
9 | /// Gets or sets a value indicating whether the plugin is enabled or not.
10 | ///
11 | public bool Enable { get; set; } = true;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/GameHelper/Program.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper
6 | {
7 | using System;
8 | using System.IO;
9 | using System.Threading.Tasks;
10 | using Utils;
11 |
12 | ///
13 | /// Class executed when the application starts.
14 | ///
15 | internal class Program
16 | {
17 | ///
18 | /// function executed when the application starts.
19 | ///
20 | private static async Task Main()
21 | {
22 | AppDomain.CurrentDomain.UnhandledException += (sender, exceptionArgs) =>
23 | {
24 | var errorText = "Program exited with message:\n " + exceptionArgs.ExceptionObject;
25 | File.AppendAllText("Error.log", $"{DateTime.Now:g} {errorText}\r\n{new string('-', 30)}\r\n");
26 | Environment.Exit(1);
27 | };
28 |
29 | using (Core.Overlay = new GameOverlay(MiscHelper.GenerateRandomString()))
30 | {
31 | await Core.Overlay.Run();
32 | }
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteEnums/GameStateTypes.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteEnums
6 | {
7 | ///
8 | /// Gets all known states of the game.
9 | ///
10 | public enum GameStateTypes
11 | {
12 | ///
13 | /// When user is on the Area Loading Screen.
14 | ///
15 | AreaLoadingState,
16 |
17 | ///
18 | /// Game State.
19 | ///
20 | ChangePasswordState,
21 |
22 | ///
23 | /// When user is viewing the credit screen window (accessable from login screen)
24 | ///
25 | CreditsState,
26 |
27 | ///
28 | /// When user has opened the escape menu.
29 | ///
30 | EscapeState,
31 |
32 | ///
33 | /// When User is in Town/Hideout/Area/Zone etc.
34 | ///
35 | InGameState,
36 |
37 | ///
38 | /// The user is watching the GGG animation that comes before the login screen.
39 | ///
40 | PreGameState,
41 |
42 | ///
43 | /// When user is on the Login screen.
44 | ///
45 | LoginState,
46 |
47 | ///
48 | /// When user is transitioning from to .
49 | ///
50 | WaitingState,
51 |
52 | ///
53 | /// When user is on the create new character screen.
54 | ///
55 | CreateCharacterState,
56 |
57 | ///
58 | /// When user is on the select character screen.
59 | ///
60 | SelectCharacterState,
61 |
62 | ///
63 | /// When user is on the delete character screen.
64 | ///
65 | DeleteCharacterState,
66 |
67 | ///
68 | /// When user is transitioning from to .
69 | ///
70 | LoadingState,
71 |
72 | ///
73 | /// This is a special State, changing to this state will not trigger State Change Event.
74 | /// This is just for displaying purposes. It means Game isn't stared.
75 | ///
76 | GameNotLoaded
77 | }
78 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteEnums/InventoryName.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteEnums
6 | {
7 | ///
8 | /// Read Inventories.dat file for inventory name and index mapping.
9 | /// Remember, in the game, inventory index starts from 0x01.
10 | /// In the Inventories.dat file, inventory index starts from 0x00.
11 | ///
12 | public enum InventoryName
13 | {
14 | #pragma warning disable CS1591, SA1602
15 | NoInvSelected,
16 | MainInventory1,
17 | BodyArmour1,
18 | Weapon1,
19 | Offhand1,
20 | Helm1,
21 | Amulet1,
22 | Ring1,
23 | Ring2,
24 | Gloves1,
25 | Boots1,
26 | Belt1,
27 | Flask1,
28 | Cursor1,
29 | Map1,
30 | Weapon2,
31 | Offhand2,
32 | StrMasterCrafting,
33 | StrDexMasterCrafting,
34 | DexMasterCrafting,
35 | DexIntMasterCrafting,
36 | IntMasterCrafting,
37 | StrIntMasterCrafting,
38 | PVPMasterCrafting,
39 | PassiveJewels1,
40 | AnimatedArmour1,
41 | GuildTag1,
42 | StashInventoryId,
43 | DivinationCardTrade,
44 | Darkshrine,
45 | TalismanTrade,
46 | Leaguestone1,
47 | BestiaryCrafting,
48 | IncursionSacrifice,
49 | BetrayalUnveiling,
50 | ItemSynthesisInput,
51 | ItemSynthesisOutput,
52 | BlightCraftingInput,
53 | BlightCraftingItem,
54 | MetamorphosisGenomeInput,
55 | AtlasUpgrades1,
56 | AtlasUpgradesStorage,
57 | ExpeditionMapMission,
58 | ExpeditionDeal1,
59 | HarvestCraftingItem,
60 | HeistContractMission,
61 | HeistNpcEquipment1,
62 | HeistNpcEquipment2,
63 | HeistNpcEquipment3,
64 | HeistNpcEquipment4,
65 | HeistNpcEquipment5,
66 | HeistNpcEquipment6,
67 | HeistNpcEquipment7,
68 | HeistNpcEquipment8,
69 | HeistNpcEquipment9,
70 | Trinket1,
71 | HeistBlueprintMission,
72 | HeistStorage1,
73 | RitualSavedRewards1,
74 | DONOTUSE1,
75 | DONOTUSE2,
76 | DONOTUSE3,
77 | DONOTUSE4,
78 | RESERVED1,
79 | RESERVED2,
80 | RESERVED3,
81 | RESERVED4,
82 | UltimatumCraftingItem,
83 | RESERVED5,
84 | RESERVED6,
85 | ExpeditionStorage1,
86 | HellscapeModificationInventory1,
87 | LabyrinthCraftingInput,
88 | SentinelDroneInventory1,
89 | SentinelStorage1,
90 | LakeTabletInventory1,
91 | MemoryLineMaps
92 | #pragma warning restore CS1591, SA1602
93 | }
94 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteEnums/Rarity.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteEnums
6 | {
7 | ///
8 | /// Read Rarity.dat file for Rarity to integer mapping.
9 | ///
10 | public enum Rarity
11 | {
12 | ///
13 | /// Normal Item/Monster.
14 | ///
15 | Normal,
16 |
17 | ///
18 | /// Magic Item/Monster.
19 | ///
20 | Magic,
21 |
22 | ///
23 | /// Rare Item/Monster.
24 | ///
25 | Rare,
26 |
27 | ///
28 | /// Unique Item/Monster.
29 | ///
30 | Unique
31 | }
32 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/AreaChangeCounter.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using Coroutine;
10 | using CoroutineEvents;
11 | using GameOffsets.Objects;
12 | using ImGuiNET;
13 |
14 | ///
15 | /// Points to the AreaChangeCounter object and read/cache it's value
16 | /// on every area change.
17 | ///
18 | public class AreaChangeCounter : RemoteObjectBase
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// address of the remote memory object.
24 | internal AreaChangeCounter(IntPtr address)
25 | : base(address)
26 | {
27 | CoroutineHandler.Start(this.OnAreaChange(), priority: int.MaxValue);
28 | }
29 |
30 | ///
31 | /// Gets the cached value of the AreaChangeCounter.
32 | ///
33 | public int Value { get; private set; } = int.MaxValue;
34 |
35 | ///
36 | /// Converts the class data to ImGui.
37 | ///
38 | internal override void ToImGui()
39 | {
40 | base.ToImGui();
41 | ImGui.Text($"Area Change Counter: {this.Value}");
42 | }
43 |
44 | ///
45 | protected override void CleanUpData()
46 | {
47 | this.Value = int.MaxValue;
48 | }
49 |
50 | ///
51 | protected override void UpdateData(bool hasAddressChanged)
52 | {
53 | var reader = Core.Process.Handle;
54 | this.Value = reader.ReadMemory(this.Address).counter;
55 | }
56 |
57 | private IEnumerator OnAreaChange()
58 | {
59 | while (true)
60 | {
61 | yield return new Wait(RemoteEvents.AreaChanged);
62 | if (this.Address != IntPtr.Zero)
63 | {
64 | this.UpdateData(false);
65 | }
66 | }
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/Actor.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Objects.Components;
9 | using ImGuiNET;
10 | using RemoteEnums;
11 |
12 | ///
13 | /// The component in the entity.
14 | ///
15 | public class Actor : RemoteObjectBase
16 | {
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// address of the component.
21 | public Actor(IntPtr address)
22 | : base(address, true) { }
23 |
24 | ///
25 | /// Gets a value indicating what the player is doing.
26 | ///
27 | public Animation Animation { get; private set; } = Animation.Idle;
28 |
29 | ///
30 | /// Converts the class data to ImGui.
31 | ///
32 | internal override void ToImGui()
33 | {
34 | base.ToImGui();
35 | ImGui.Text($"AnimationId: {(int)this.Animation}, Animation: {this.Animation}");
36 | }
37 |
38 | ///
39 | protected override void CleanUpData()
40 | {
41 | throw new Exception("Component Address should never be Zero.");
42 | }
43 |
44 | ///
45 | protected override void UpdateData(bool hasAddressChanged)
46 | {
47 | var reader = Core.Process.Handle;
48 | var data = reader.ReadMemory(this.Address);
49 | this.Animation = (Animation)data.AnimationId;
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/Base.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using System.Collections.Concurrent;
9 | using System.Collections.Generic;
10 | using Coroutine;
11 | using GameOffsets.Objects.Components;
12 | using GameOffsets.Objects.FilesStructures;
13 | using ImGuiNET;
14 |
15 | ///
16 | /// The component in the entity.
17 | ///
18 | public class Base : RemoteObjectBase
19 | {
20 | ///
21 | /// Cache the BaseItemType.Dat data to save few reads per frame.
22 | ///
23 | private static readonly ConcurrentDictionary BaseItemTypeDatCache = new();
24 |
25 | ///
26 | /// Initializes a new instance of the class.
27 | ///
28 | /// address of the component.
29 | public Base(IntPtr address)
30 | : base(address, true) { }
31 |
32 | static Base()
33 | {
34 | CoroutineHandler.Start(OnGameClose());
35 | }
36 |
37 | ///
38 | /// Gets the items base name.
39 | ///
40 | public string ItemBaseName { get; private set; } = string.Empty;
41 |
42 | ///
43 | internal override void ToImGui()
44 | {
45 | base.ToImGui();
46 | ImGui.Text($"Base Name: {this.ItemBaseName}");
47 | }
48 |
49 | ///
50 | protected override void CleanUpData()
51 | {
52 | throw new Exception("Component Address should never be Zero.");
53 | }
54 |
55 | ///
56 | protected override void UpdateData(bool hasAddressChanged)
57 | {
58 | var reader = Core.Process.Handle;
59 | var data = reader.ReadMemory(this.Address);
60 | if (BaseItemTypeDatCache.TryGetValue(data.BaseInternalPtr, out var itemName))
61 | {
62 | this.ItemBaseName = itemName;
63 | }
64 | else
65 | {
66 | var baseItemTypeDatRow = reader.ReadMemory(data.BaseInternalPtr);
67 | var name = reader.ReadStdWString(baseItemTypeDatRow.BaseNamePtr);
68 | if (!string.IsNullOrEmpty(name))
69 | {
70 | BaseItemTypeDatCache[data.BaseInternalPtr] = name;
71 | this.ItemBaseName = name;
72 | }
73 | }
74 | }
75 |
76 | private static IEnumerable OnGameClose()
77 | {
78 | while (true)
79 | {
80 | yield return new(CoroutineEvents.GameHelperEvents.OnClose);
81 | BaseItemTypeDatCache.Clear();
82 | }
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/Charges.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Objects.Components;
9 | using ImGuiNET;
10 |
11 | ///
12 | /// The component in the entity.
13 | ///
14 | public class Charges : RemoteObjectBase
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | /// address of the component.
20 | public Charges(IntPtr address)
21 | : base(address, true) { }
22 |
23 | ///
24 | /// Gets a value indicating number of charges the flask has.
25 | ///
26 | public int Current { get; private set; }
27 |
28 | ///
29 | /// Converts the class data to ImGui.
30 | ///
31 | internal override void ToImGui()
32 | {
33 | base.ToImGui();
34 | ImGui.Text($"Current Charges: {this.Current}");
35 | }
36 |
37 | ///
38 | protected override void CleanUpData()
39 | {
40 | throw new Exception("Component Address should never be Zero.");
41 | }
42 |
43 | ///
44 | protected override void UpdateData(bool hasAddressChanged)
45 | {
46 | var reader = Core.Process.Handle;
47 | var data = reader.ReadMemory(this.Address);
48 | this.Current = data.current;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/Chest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Objects.Components;
9 | using ImGuiNET;
10 |
11 | ///
12 | /// The component in the entity.
13 | ///
14 | public class Chest : RemoteObjectBase
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | /// address of the component.
20 | public Chest(IntPtr address)
21 | : base(address, true) { }
22 |
23 | ///
24 | /// Gets a value indicating whether chest is opened or not.
25 | ///
26 | public bool IsOpened { get; private set; }
27 |
28 | ///
29 | /// Gets a value indicating whether chest is a strongbox or not.
30 | ///
31 | public bool IsStrongbox { get; private set; }
32 |
33 | ///
34 | /// Gets a value indicating whether chest label is visible or not
35 | /// NOTE: Breach chests, Legion chests, Normal Chests labels are visible.
36 | ///
37 | public bool IsLabelVisible { get; private set; }
38 |
39 | ///
40 | /// Converts the class data to ImGui.
41 | ///
42 | internal override void ToImGui()
43 | {
44 | base.ToImGui();
45 | ImGui.Text($"IsOpened: {this.IsOpened}");
46 | ImGui.Text($"IsStrongbox: {this.IsStrongbox}");
47 | ImGui.Text($"IsLabelVisible: {this.IsLabelVisible}");
48 | }
49 |
50 | ///
51 | protected override void CleanUpData()
52 | {
53 | throw new Exception("Component Address should never be Zero.");
54 | }
55 |
56 | ///
57 | protected override void UpdateData(bool hasAddressChanged)
58 | {
59 | var reader = Core.Process.Handle;
60 | var data = reader.ReadMemory(this.Address);
61 | this.IsOpened = data.IsOpened;
62 | if (hasAddressChanged)
63 | {
64 | var dataInternal = reader.ReadMemory(data.ChestsDataPtr);
65 | this.IsStrongbox = dataInternal.StrongboxDatPtr != IntPtr.Zero;
66 | this.IsLabelVisible = dataInternal.IsLabelVisible;
67 | }
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/DiesAfterTime.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 |
9 | ///
10 | /// The component in the entity.
11 | ///
12 | public class DiesAfterTime : RemoteObjectBase
13 | {
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | /// address of the component.
18 | public DiesAfterTime(IntPtr address)
19 | : base(address, true) { }
20 |
21 | ///
22 | protected override void CleanUpData()
23 | {
24 | throw new Exception("Component Address should never be Zero.");
25 | }
26 |
27 | ///
28 | protected override void UpdateData(bool hasAddressChanged) { }
29 | }
30 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/Life.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Objects.Components;
9 | using ImGuiNET;
10 | using Utils;
11 |
12 | ///
13 | /// The component in the entity.
14 | ///
15 | public class Life : RemoteObjectBase
16 | {
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// address of the component.
21 | public Life(IntPtr address)
22 | : base(address, true) { }
23 |
24 | ///
25 | /// Gets a value indicating whether the entity is alive or not.
26 | ///
27 | public bool IsAlive { get; private set; } = true;
28 |
29 | ///
30 | /// Gets the health related information of the entity.
31 | ///
32 | public VitalStruct Health { get; private set; }
33 |
34 | ///
35 | /// Gets the energyshield related information of the entity.
36 | ///
37 | public VitalStruct EnergyShield { get; private set; }
38 |
39 | ///
40 | /// Gets the mana related information of the entity.
41 | ///
42 | public VitalStruct Mana { get; private set; }
43 |
44 | ///
45 | /// Converts the class data to ImGui.
46 | ///
47 | internal override void ToImGui()
48 | {
49 | base.ToImGui();
50 |
51 | if (ImGui.TreeNode("Health"))
52 | {
53 | this.VitalToImGui(this.Health);
54 | ImGui.TreePop();
55 | }
56 |
57 | if (ImGui.TreeNode("Energy Shield"))
58 | {
59 | this.VitalToImGui(this.EnergyShield);
60 | ImGui.TreePop();
61 | }
62 |
63 | if (ImGui.TreeNode("Mana"))
64 | {
65 | this.VitalToImGui(this.Mana);
66 | ImGui.TreePop();
67 | }
68 | }
69 |
70 | ///
71 | protected override void CleanUpData()
72 | {
73 | throw new Exception("Component Address should never be Zero.");
74 | }
75 |
76 | ///
77 | protected override void UpdateData(bool hasAddressChanged)
78 | {
79 | var reader = Core.Process.Handle;
80 | var data = reader.ReadMemory(this.Address);
81 | this.Health = data.Health;
82 | this.EnergyShield = data.EnergyShield;
83 | this.Mana = data.Mana;
84 | this.IsAlive = data.Health.Current > 0;
85 | }
86 |
87 | private void VitalToImGui(VitalStruct data)
88 | {
89 | ImGuiHelper.IntPtrToImGui("PtrToSelf", data.PtrToLifeComponent);
90 | ImGui.Text($"Regeneration: {data.Regeneration}");
91 | ImGui.Text($"Total: {data.Total}");
92 | ImGui.Text($"ReservedFlat: {data.ReservedFlat}");
93 | ImGui.Text($"Current: {data.Current}");
94 | ImGui.Text($"Reserved(%%): {data.ReservedPercent}");
95 | ImGui.Text($"Current(%%): {data.CurrentInPercent()}");
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/MinimapIcon.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 |
9 | ///
10 | /// The component in the entity.
11 | ///
12 | public class MinimapIcon : RemoteObjectBase
13 | {
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | /// address of the component.
18 | public MinimapIcon(IntPtr address)
19 | : base(address, true) { }
20 |
21 | ///
22 | protected override void CleanUpData()
23 | {
24 | throw new Exception("Component Address should never be Zero.");
25 | }
26 |
27 | ///
28 | protected override void UpdateData(bool hasAddressChanged) { }
29 | }
30 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/NPC.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 |
9 | ///
10 | /// The component in the entity.
11 | ///
12 | public class NPC : RemoteObjectBase
13 | {
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | /// address of the component.
18 | public NPC(IntPtr address)
19 | : base(address, true) { }
20 |
21 | ///
22 | protected override void CleanUpData()
23 | {
24 | throw new Exception("Component Address should never be Zero.");
25 | }
26 |
27 | ///
28 | protected override void UpdateData(bool hasAddressChanged) { }
29 | }
30 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/ObjectMagicProperties.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Objects.Components;
9 | using ImGuiNET;
10 | using RemoteEnums;
11 |
12 | ///
13 | /// ObjectMagicProperties component of the entity.
14 | ///
15 | public class ObjectMagicProperties : RemoteObjectBase
16 | {
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// address of the component.
21 | public ObjectMagicProperties(IntPtr address)
22 | : base(address, true) { }
23 |
24 | ///
25 | /// Gets a value indicating entity rarity information.
26 | ///
27 | public Rarity Rarity { get; private set; } = Rarity.Normal;
28 |
29 | ///
30 | /// Converts the class data to ImGui.
31 | ///
32 | internal override void ToImGui()
33 | {
34 | base.ToImGui();
35 | ImGui.Text($"Rarity: {this.Rarity}");
36 | }
37 |
38 | ///
39 | protected override void CleanUpData()
40 | {
41 | throw new Exception("Component Address should never be Zero.");
42 | }
43 |
44 | ///
45 | protected override void UpdateData(bool hasAddressChanged)
46 | {
47 | if (hasAddressChanged)
48 | {
49 | var reader = Core.Process.Handle;
50 | var data = reader.ReadMemory(this.Address);
51 | this.Rarity = (Rarity)data.Rarity;
52 | }
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/Player.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Objects.Components;
9 | using ImGuiNET;
10 |
11 | ///
12 | /// The component in the entity.
13 | ///
14 | public class Player : RemoteObjectBase
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | /// address of the component.
20 | public Player(IntPtr address)
21 | : base(address, true) { }
22 |
23 | ///
24 | /// Gets the name of the player.
25 | ///
26 | public string Name { get; private set; }
27 |
28 | ///
29 | /// Converts the class data to ImGui.
30 | ///
31 | internal override void ToImGui()
32 | {
33 | base.ToImGui();
34 | ImGui.Text($"Player Name: {this.Name}");
35 | }
36 |
37 | ///
38 | protected override void CleanUpData()
39 | {
40 | throw new Exception("Component Address should never be Zero.");
41 | }
42 |
43 | ///
44 | protected override void UpdateData(bool hasAddressChanged)
45 | {
46 | if (!hasAddressChanged)
47 | {
48 | return;
49 | }
50 |
51 | var reader = Core.Process.Handle;
52 | var data = reader.ReadMemory(this.Address);
53 | this.Name = reader.ReadStdWString(data.Name);
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/Positioned.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Objects.Components;
9 | using GameOffsets.Objects.States.InGameState;
10 | using ImGuiNET;
11 |
12 | ///
13 | /// The component in the entity.
14 | ///
15 | public class Positioned : RemoteObjectBase
16 | {
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// address of the component.
21 | public Positioned(IntPtr address)
22 | : base(address, true) { }
23 |
24 | ///
25 | /// Gets the flags related to the entity from the positioned component.
26 | /// NOTE: This flag contains the information if the entity is friendly or not.
27 | ///
28 | public byte Flags { get; private set; }
29 |
30 | ///
31 | /// Gets a value indicating whether the entity is friendly or not.
32 | ///
33 | public bool IsFriendly { get; private set; }
34 |
35 | ///
36 | /// Converts the class data to ImGui.
37 | ///
38 | internal override void ToImGui()
39 | {
40 | base.ToImGui();
41 | ImGui.Text($"Flags: {this.Flags:X}");
42 | ImGui.Text($"IsFriendly: {this.IsFriendly}");
43 | }
44 |
45 | ///
46 | protected override void UpdateData(bool hasAddressChanged)
47 | {
48 | var reader = Core.Process.Handle;
49 | var data = reader.ReadMemory(this.Address);
50 | this.Flags = data.Reaction;
51 | this.IsFriendly = EntityHelper.IsFriendly(data.Reaction);
52 | }
53 |
54 | ///
55 | protected override void CleanUpData()
56 | {
57 | throw new Exception("Component Address should never be Zero.");
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/Render.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Natives;
9 | using GameOffsets.Objects.Components;
10 | using GameOffsets.Objects.States.InGameState;
11 | using ImGuiNET;
12 |
13 | ///
14 | /// The component in the entity.
15 | ///
16 | public class Render : RemoteObjectBase
17 | {
18 | private static readonly float WorldToGridRatio =
19 | TileStructure.TileToWorldConversion / TileStructure.TileToGridConversion;
20 |
21 | private StdTuple3D gridPos2D;
22 |
23 | ///
24 | /// Initializes a new instance of the class.
25 | ///
26 | /// address of the component.
27 | public Render(IntPtr address)
28 | : base(address, true) { }
29 |
30 | ///
31 | /// Gets the position where entity is located on the grid (map).
32 | ///
33 | public StdTuple3D GridPosition
34 | {
35 | get => this.gridPos2D;
36 | private set => this.gridPos2D = value;
37 | }
38 |
39 | ///
40 | /// Gets the position where entity is located on the grid (map).
41 | ///
42 | public StdTuple3D ModelBounds { get; private set; }
43 |
44 | ///
45 | /// Gets the postion where entity is rendered in the game world.
46 | /// NOTE: Z-Axis is pointing to the (visible/invisible) healthbar.
47 | ///
48 | public StdTuple3D WorldPosition { get; private set; }
49 |
50 | ///
51 | /// Gets the terrain height on which the Entity is standing.
52 | ///
53 | public float TerrainHeight { get; private set; }
54 |
55 | ///
56 | /// Converts the class data to ImGui.
57 | ///
58 | internal override void ToImGui()
59 | {
60 | base.ToImGui();
61 | ImGui.Text($"Grid Position: {this.gridPos2D}");
62 | ImGui.Text($"World Position: {this.WorldPosition}");
63 | ImGui.Text($"Terrain Height (Z-Axis): {this.TerrainHeight}");
64 | ImGui.Text($"Model Bounds: {this.ModelBounds}");
65 | }
66 |
67 | ///
68 | protected override void CleanUpData()
69 | {
70 | throw new Exception("Component Address should never be Zero.");
71 | }
72 |
73 | ///
74 | protected override void UpdateData(bool hasAddressChanged)
75 | {
76 | var reader = Core.Process.Handle;
77 | var data = reader.ReadMemory(this.Address);
78 | this.WorldPosition = data.CurrentWorldPosition;
79 | this.ModelBounds = data.CharactorModelBounds;
80 | this.TerrainHeight = (float)Math.Round(data.TerrainHeight, 4);
81 | this.gridPos2D.X = data.CurrentWorldPosition.X / WorldToGridRatio;
82 | this.gridPos2D.Y = data.CurrentWorldPosition.Y / WorldToGridRatio;
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/Shrine.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Objects.Components;
9 | using ImGuiNET;
10 |
11 | ///
12 | /// The component in the entity.
13 | ///
14 | public class Shrine : RemoteObjectBase
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | /// address of the component.
20 | public Shrine(IntPtr address)
21 | : base(address, true) { }
22 |
23 | ///
24 | /// Gets a value indicating whether chest is opened or not.
25 | ///
26 | public bool IsUsed { get; private set; }
27 |
28 | ///
29 | /// Converts the class data to ImGui.
30 | ///
31 | internal override void ToImGui()
32 | {
33 | base.ToImGui();
34 | ImGui.Text($"Is Shrine Used: {this.IsUsed}");
35 | }
36 |
37 | ///
38 | protected override void CleanUpData()
39 | {
40 | throw new Exception("Component Address should never be Zero.");
41 | }
42 |
43 | ///
44 | protected override void UpdateData(bool hasAddressChanged)
45 | {
46 | var reader = Core.Process.Handle;
47 | var data = reader.ReadMemory(this.Address);
48 | this.IsUsed = data.IsUsed;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/Components/TriggerableBlockage.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.Components
6 | {
7 | using System;
8 | using GameOffsets.Objects.Components;
9 | using ImGuiNET;
10 |
11 | ///
12 | /// The component in the entity.
13 | ///
14 | public class TriggerableBlockage : RemoteObjectBase
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | /// address of the component.
20 | public TriggerableBlockage(IntPtr address)
21 | : base(address, true) { }
22 |
23 | ///
24 | /// Gets a value indicating whether TriggerableBlockage is closed or not.
25 | ///
26 | public bool IsBlocked { get; private set; }
27 |
28 | ///
29 | /// Converts the class data to ImGui.
30 | ///
31 | internal override void ToImGui()
32 | {
33 | base.ToImGui();
34 | ImGui.Text($"Is Blocked: {this.IsBlocked}");
35 | }
36 |
37 | ///
38 | protected override void CleanUpData()
39 | {
40 | throw new Exception("Component Address should never be Zero.");
41 | }
42 |
43 | ///
44 | protected override void UpdateData(bool hasAddressChanged)
45 | {
46 | var reader = Core.Process.Handle;
47 | var data = reader.ReadMemory(this.Address);
48 | this.IsBlocked = data.IsBlocked;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/GameWindowCull.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using Coroutine;
10 | using CoroutineEvents;
11 | using ImGuiNET;
12 |
13 | ///
14 | /// Reads the Game Window Cull (black bar on each side) values from the game.
15 | /// Only reads when game window moves/resize.
16 | ///
17 | public class GameWindowCull : RemoteObjectBase
18 | {
19 | ///
20 | /// Initializes a new instance of the class.
21 | ///
22 | /// address of the remote memory object.
23 | internal GameWindowCull(IntPtr address)
24 | : base(address)
25 | {
26 | CoroutineHandler.Start(this.OnGameMove(), priority: int.MaxValue);
27 | CoroutineHandler.Start(this.OnGameForegroundChange(), priority: int.MaxValue);
28 | }
29 |
30 | ///
31 | /// Gets the current game window scale values.
32 | ///
33 | public int Value { get; private set; }
34 |
35 | ///
36 | /// Converts the class data to ImGui.
37 | ///
38 | internal override void ToImGui()
39 | {
40 | base.ToImGui();
41 | ImGui.Text($"Game Window Cull Size: {this.Value}");
42 | }
43 |
44 | ///
45 | protected override void CleanUpData()
46 | {
47 | this.Value = 0;
48 | }
49 |
50 | ///
51 | protected override void UpdateData(bool hasAddressChanged)
52 | {
53 | var reader = Core.Process.Handle;
54 | this.Value = reader.ReadMemory(this.Address);
55 | }
56 |
57 | private IEnumerator OnGameMove()
58 | {
59 | while (true)
60 | {
61 | yield return new Wait(GameHelperEvents.OnMoved);
62 |
63 | // No need to check for IntPtr.zero
64 | // because game will only move when it exists. :D
65 | this.UpdateData(false);
66 | }
67 | }
68 |
69 | private IEnumerator OnGameForegroundChange()
70 | {
71 | while (true)
72 | {
73 | yield return new Wait(GameHelperEvents.OnForegroundChanged);
74 |
75 | // No need to check for IntPtr.zero
76 | // because game will only move when it exists. :D
77 | this.UpdateData(false);
78 | }
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/States/AreaLoadingState.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.States
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using Coroutine;
10 | using CoroutineEvents;
11 | using GameOffsets.Objects.States;
12 | using ImGuiNET;
13 |
14 | ///
15 | /// Reads AreaLoadingState Game Object.
16 | ///
17 | public sealed class AreaLoadingState : RemoteObjectBase
18 | {
19 | private AreaLoadingStateOffset lastCache;
20 |
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | /// address of the remote memory object.
25 | internal AreaLoadingState(IntPtr address)
26 | : base(address)
27 | {
28 | CoroutineHandler.Start(this.OnPerFrame(), priority: int.MaxValue - 1);
29 | }
30 |
31 | ///
32 | /// Gets the game current Area Name.
33 | ///
34 | public string CurrentAreaName { get; private set; } = string.Empty;
35 |
36 | ///
37 | /// Gets a value indicating whether the game is in loading screen or not.
38 | ///
39 | internal bool IsLoading { get; private set; }
40 |
41 | ///
42 | /// Converts the class data to ImGui.
43 | ///
44 | internal override void ToImGui()
45 | {
46 | base.ToImGui();
47 | ImGui.Text($"Current Area Name: {this.CurrentAreaName}");
48 | ImGui.Text($"Is Loading Screen: {this.IsLoading}");
49 | ImGui.Text($"Total Loading Time(ms): {this.lastCache.TotalLoadingScreenTimeMs}");
50 | }
51 |
52 | ///
53 | protected override void CleanUpData()
54 | {
55 | this.lastCache = default;
56 | this.CurrentAreaName = string.Empty;
57 | }
58 |
59 | ///
60 | protected override void UpdateData(bool hasAddressChanged)
61 | {
62 | var reader = Core.Process.Handle;
63 | var data = reader.ReadMemory(this.Address);
64 | this.IsLoading = data.IsLoading == 0x01;
65 | var hasAreaChanged = false;
66 | if (data.CurrentAreaName.Buffer != IntPtr.Zero &&
67 | !this.IsLoading &&
68 | data.TotalLoadingScreenTimeMs > this.lastCache.TotalLoadingScreenTimeMs)
69 | {
70 | var areaName = reader.ReadStdWString(data.CurrentAreaName);
71 | this.CurrentAreaName = areaName;
72 | this.lastCache = data;
73 | hasAreaChanged = true;
74 | }
75 |
76 | if (hasAreaChanged)
77 | {
78 | CoroutineHandler.InvokeLater(new Wait(0.1d), () => { CoroutineHandler.RaiseEvent(RemoteEvents.AreaChanged); });
79 | }
80 | }
81 |
82 | private IEnumerator OnPerFrame()
83 | {
84 | while (true)
85 | {
86 | yield return new Wait(GameHelperEvents.PerFrameDataUpdate);
87 | if (this.Address != IntPtr.Zero)
88 | {
89 | this.UpdateData(false);
90 | }
91 | }
92 | }
93 | }
94 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/States/InGameState.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.States
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using Coroutine;
10 | using CoroutineEvents;
11 | using GameOffsets.Objects.States;
12 | using InGameStateObjects;
13 | using UiElement;
14 |
15 | ///
16 | /// Reads InGameState Game Object.
17 | ///
18 | public class InGameState : RemoteObjectBase
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// address of the remote memory object.
24 | internal InGameState(IntPtr address)
25 | : base(address)
26 | {
27 | Core.CoroutinesRegistrar.Add(CoroutineHandler.Start(
28 | this.OnPerFrame(), "[InGameState] Update Game State", int.MaxValue - 2));
29 | }
30 |
31 | ///
32 | /// Gets the data related to the currently loaded world area.
33 | ///
34 | public WorldData CurrentWorldInstance { get; }
35 |
36 | = new(IntPtr.Zero);
37 |
38 | ///
39 | /// Gets the data related to the current area instance.
40 | ///
41 | public AreaInstance CurrentAreaInstance { get; }
42 |
43 | = new(IntPtr.Zero);
44 |
45 | ///
46 | /// Gets the UiRoot main child which contains all the UiElements of the game.
47 | ///
48 | public ImportantUiElements GameUi { get; }
49 |
50 | = new(IntPtr.Zero);
51 |
52 | ///
53 | /// Gets the data related to the root ui element.
54 | ///
55 | internal UiElementBase UiRoot { get; }
56 |
57 | = new(IntPtr.Zero);
58 |
59 | ///
60 | protected override void CleanUpData()
61 | {
62 | this.CurrentAreaInstance.Address = IntPtr.Zero;
63 | this.UiRoot.Address = IntPtr.Zero;
64 | this.GameUi.Address = IntPtr.Zero;
65 | this.CurrentWorldInstance.Address = IntPtr.Zero;
66 | }
67 |
68 | ///
69 | protected override void UpdateData(bool hasAddressChanged)
70 | {
71 | var reader = Core.Process.Handle;
72 | var data = reader.ReadMemory(this.Address);
73 | this.CurrentWorldInstance.Address = data.WorldData;
74 | this.CurrentAreaInstance.Address = data.AreaInstanceData;
75 | this.UiRoot.Address = data.UiRootPtr;
76 | this.GameUi.Address = data.IngameUi;
77 | }
78 |
79 | private IEnumerator OnPerFrame()
80 | {
81 | // TODO optimization: convert this into OnAreaChange.
82 | while (true)
83 | {
84 | yield return new Wait(GameHelperEvents.PerFrameDataUpdate);
85 | if (this.Address != IntPtr.Zero)
86 | {
87 | this.UpdateData(false);
88 | }
89 | }
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/States/InGameStateObjects/Item.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.States.InGameStateObjects
6 | {
7 | using System;
8 | using GameHelper.RemoteEnums;
9 | using GameOffsets.Objects.States.InGameState;
10 |
11 | ///
12 | /// Points to the item in the game.
13 | /// Item is basically anything that can be put in the inventory/stash.
14 | ///
15 | public class Item : Entity
16 | {
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// address of the Entity.
21 | internal Item(IntPtr address)
22 | : base(address) { }
23 |
24 | ///
25 | protected override void UpdateData(bool hasAddressChanged)
26 | {
27 | var reader = Core.Process.Handle;
28 |
29 | // NOTE: ItemStruct is defined in EntityOffsets.cs file.
30 | var itemData = reader.ReadMemory(this.Address);
31 |
32 | // this.Id will always be 0x00 because Items don't have
33 | // Id associated with them.
34 | this.IsValid = true;
35 | this.EntityType = EntityTypes.InventoryItem;
36 | this.UpdateComponentData(itemData, hasAddressChanged);
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/TerrainHeightHelper.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects
6 | {
7 | using System;
8 | using ImGuiNET;
9 |
10 | ///
11 | /// Contains the static data for calculating the terrain height.
12 | ///
13 | public class TerrainHeightHelper : RemoteObjectBase
14 | {
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | /// address of the remote memory object.
19 | /// expected size of this remote memory object.
20 | internal TerrainHeightHelper(IntPtr address, int size)
21 | : base(address)
22 | {
23 | this.Values = new byte[size];
24 | }
25 |
26 | ///
27 | /// Gets the values associated with this class.
28 | ///
29 | public byte[] Values { get; private set; }
30 |
31 | ///
32 | internal override void ToImGui()
33 | {
34 | base.ToImGui();
35 | ImGui.Text(string.Join(' ', this.Values));
36 | }
37 |
38 | ///
39 | protected override void CleanUpData()
40 | {
41 | for (var i = 0; i < this.Values.Length; i++)
42 | {
43 | this.Values[i] = 0;
44 | }
45 | }
46 |
47 | ///
48 | protected override void UpdateData(bool hasAddressChanged)
49 | {
50 | var reader = Core.Process.Handle;
51 | this.Values = reader.ReadMemoryArray(this.Address, this.Values.Length);
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/UiElement/LargeMapUiElement.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.UiElement
6 | {
7 | using System;
8 | using System.Numerics;
9 | using ImGuiNET;
10 |
11 | ///
12 | /// Points to the LargeMap UiElement.
13 | /// It is exactly like any other element, except its in-memory position is its center
14 | ///
15 | public class LargeMapUiElement : MapUiElement
16 | {
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// address to the Map Ui Element of the game.
21 | internal LargeMapUiElement(IntPtr address)
22 | : base(address) { }
23 |
24 | ///
25 | public override Vector2 Postion => new(Core.GameCull.Value);
26 |
27 | ///
28 | public override Vector2 Size => new(Core.Process.WindowArea.Width - (Core.GameCull.Value * 2), Core.Process.WindowArea.Height);
29 |
30 |
31 | ///
32 | /// Gets the center of the map.
33 | ///
34 | public Vector2 Center => base.Postion;
35 |
36 | ///
37 | /// Converts the class data to ImGui.
38 | ///
39 | internal override void ToImGui()
40 | {
41 | base.ToImGui();
42 | ImGui.Text($"Center (without shift/default-shift) {this.Center}");
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/GameHelper/RemoteObjects/UiElement/MapUiElement.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.RemoteObjects.UiElement
6 | {
7 | using System;
8 | using System.Numerics;
9 | using GameOffsets.Objects.UiElement;
10 | using ImGuiNET;
11 |
12 | ///
13 | /// Points to the Map UiElement.
14 | ///
15 | public class MapUiElement : UiElementBase
16 | {
17 | private Vector2 defaultShift = Vector2.Zero;
18 | private Vector2 shift = Vector2.Zero;
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// address to the Map Ui Element of the game.
24 | internal MapUiElement(IntPtr address)
25 | : base(address) { }
26 |
27 | ///
28 | /// Gets the value indicating how much map has shifted.
29 | ///
30 | public Vector2 Shift => this.shift;
31 |
32 | ///
33 | /// Gets the value indicating shifted amount at rest (default).
34 | ///
35 | public Vector2 DefaultShift => this.defaultShift;
36 |
37 | ///
38 | /// Gets the value indicating amount of zoom in the Map.
39 | /// Normally values are between 0.5f - 1.5f.
40 | ///
41 | public float Zoom { get; private set; } = 0.5f;
42 |
43 | ///
44 | /// Converts the class data to ImGui.
45 | ///
46 | internal override void ToImGui()
47 | {
48 | base.ToImGui();
49 | ImGui.Text($"Shift {this.shift}");
50 | ImGui.Text($"Default Shift {this.defaultShift}");
51 | ImGui.Text($"Zoom {this.Zoom}");
52 | }
53 |
54 | ///
55 | protected override void CleanUpData()
56 | {
57 | base.CleanUpData();
58 | this.shift = default;
59 | this.defaultShift = default;
60 | this.Zoom = 0.5f;
61 | }
62 |
63 | ///
64 | protected override void UpdateData(bool hasAddressChanged)
65 | {
66 | base.UpdateData(hasAddressChanged);
67 | var reader = Core.Process.Handle;
68 | var data = reader.ReadMemory(this.Address);
69 | this.shift.X = data.Shift.X;
70 | this.shift.Y = data.Shift.Y;
71 |
72 | this.defaultShift.X = data.DefaultShift.X;
73 | this.defaultShift.Y = data.DefaultShift.Y;
74 |
75 | this.Zoom = data.Zoom;
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/GameHelper/Ui/DataVisualization.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.Ui
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Linq;
10 | using Coroutine;
11 | using CoroutineEvents;
12 | using ImGuiNET;
13 | using Utils;
14 |
15 | ///
16 | /// Visualize the and other miscellaneous data.
17 | ///
18 | public static class DataVisualization
19 | {
20 | ///
21 | /// Initializes the co-routines.
22 | ///
23 | internal static void InitializeCoroutines()
24 | {
25 | CoroutineHandler.Start(DataVisualizationRenderCoRoutine());
26 | }
27 |
28 | ///
29 | /// Draws the window for Data Visualization.
30 | ///
31 | /// co-routine IWait.
32 | private static IEnumerator DataVisualizationRenderCoRoutine()
33 | {
34 | while (true)
35 | {
36 | yield return new Wait(GameHelperEvents.OnRender);
37 | if (!Core.GHSettings.ShowDataVisualization)
38 | {
39 | continue;
40 | }
41 |
42 | if (ImGui.Begin("Data Visualization", ref Core.GHSettings.ShowDataVisualization))
43 | {
44 | if (ImGui.CollapsingHeader("Settings"))
45 | {
46 | var fields = Core.GHSettings.GetType().GetFields().ToList();
47 | for (var i = 0; i < fields.Count; i++)
48 | {
49 | var field = fields[i];
50 | ImGui.Text($"{field.Name}: {field.GetValue(Core.GHSettings)}");
51 | }
52 |
53 | ImGui.Text($"Current SDL Window Size:{Core.Overlay.Size}");
54 | ImGui.Text($"Current SDL Window Pos: {Core.Overlay.Position}");
55 | }
56 |
57 | if (ImGui.CollapsingHeader("Game Process"))
58 | {
59 | if (Core.Process.Address != IntPtr.Zero)
60 | {
61 | ImGuiHelper.IntPtrToImGui("Base Address", Core.Process.Address);
62 | ImGui.Text($"Process: {Core.Process.Information}");
63 | ImGui.Text($"WindowArea: {Core.Process.WindowArea}");
64 | ImGui.Text($"Foreground: {Core.Process.Foreground}");
65 | if (ImGui.TreeNode("Static Addresses"))
66 | {
67 | foreach (var saddr in Core.Process.StaticAddresses)
68 | {
69 | ImGuiHelper.IntPtrToImGui(saddr.Key, saddr.Value);
70 | }
71 |
72 | ImGui.TreePop();
73 | }
74 | }
75 | else
76 | {
77 | ImGui.Text("Game not found.");
78 | }
79 | }
80 |
81 | Core.RemoteObjectsToImGuiCollapsingHeader();
82 | }
83 |
84 | ImGui.End();
85 | }
86 | }
87 | }
88 | }
--------------------------------------------------------------------------------
/GameHelper/Ui/OverlayKiller.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.Ui
6 | {
7 | using System.Collections.Generic;
8 | using System.Diagnostics;
9 | using System.Numerics;
10 | using Coroutine;
11 | using CoroutineEvents;
12 | using ImGuiNET;
13 |
14 | ///
15 | /// Kills the overlay.
16 | ///
17 | public static class OverlayKiller
18 | {
19 | private static readonly Stopwatch Sw = Stopwatch.StartNew();
20 | private static readonly int Timelimit = 20;
21 | private static readonly Vector2 Size = new(400);
22 |
23 | ///
24 | /// Initializes the co-routines.
25 | ///
26 | internal static void InitializeCoroutines()
27 | {
28 | CoroutineHandler.Start(OverlayKillerCoRoutine());
29 | CoroutineHandler.Start(OnAreaChange());
30 | }
31 |
32 | private static IEnumerator OverlayKillerCoRoutine()
33 | {
34 | while (true)
35 | {
36 | yield return new Wait(GameHelperEvents.OnRender);
37 | if (!Core.States.InGameStateObject.CurrentWorldInstance.AreaDetails.IsBattleRoyale)
38 | {
39 | Sw.Restart();
40 | continue;
41 | }
42 |
43 | ImGui.SetNextWindowSize(Size);
44 | ImGui.Begin("Player Vs Player (PVP) Detected");
45 | ImGui.TextWrapped("Please don't cheat in PvP mode. GameHelper was not " +
46 | "created for PvP cheating. Overlay will close " +
47 | $"in {Timelimit - (int)Sw.Elapsed.TotalSeconds} seconds.");
48 | ImGui.End();
49 |
50 | if (Sw.Elapsed.TotalSeconds > Timelimit)
51 | {
52 | Core.Overlay.Close();
53 | }
54 | }
55 | }
56 |
57 | private static IEnumerator OnAreaChange()
58 | {
59 | while (true)
60 | {
61 | yield return new Wait(RemoteEvents.AreaChanged);
62 | Sw.Restart();
63 | }
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/GameHelper/Utils/JsonHelper.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.Utils
6 | {
7 | using System.IO;
8 | using Newtonsoft.Json;
9 |
10 | ///
11 | /// Utility functions to help read/write to Json files.
12 | ///
13 | internal static class JsonHelper
14 | {
15 | ///
16 | /// Creates new instance or load from the file if file exists.
17 | ///
18 | /// Class name to (De)serialize.
19 | /// file to load from.
20 | /// class objecting containing the data (if data exits).
21 | public static T CreateOrLoadJsonFile(FileInfo file)
22 | where T : new()
23 | {
24 | file.Refresh();
25 | file.Directory.Create();
26 | if (file.Exists)
27 | {
28 | var content = File.ReadAllText(file.FullName);
29 | return JsonConvert.DeserializeObject(content);
30 | }
31 |
32 | T obj = new();
33 | SafeToFile(obj, file);
34 | return obj;
35 | }
36 |
37 | ///
38 | /// Save the class object into the file.
39 | ///
40 | /// class object to save in the file.
41 | /// file to save in.
42 | public static void SafeToFile(object classObject, FileInfo file)
43 | {
44 | var content = JsonConvert.SerializeObject(classObject, Formatting.Indented);
45 | File.WriteAllText(file.FullName, content);
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/GameHelper/Utils/MathHelper.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.Utils
6 | {
7 | using System.Numerics;
8 |
9 | ///
10 | /// Utility functions to help with some math.
11 | ///
12 | public static class MathHelper
13 | {
14 | ///
15 | /// Linearly interpolates between two points.
16 | /// Interpolates between the points a and b by the interpolant t.
17 | /// The parameter t is clamped to the range[0, 1].
18 | /// This is most commonly used to find a point some fraction of the way along a line between two endpoints
19 | /// (e.g.to move an object gradually between those points).
20 | /// The value returned equals a + (b - a) * t (which can also be written a * (1-t) + b*t).
21 | /// When t = 0, Lerp(a, b, t) returns a.
22 | /// When t = 1, Lerp(a, b, t) returns b.
23 | /// When t = 0.5, Lerp(a, b, t) returns the point midway between a and b.
24 | ///
25 | /// Starting point.
26 | /// Destination point.
27 | /// Interpolation ratio.
28 | /// Interpolated value, equals to a + (b - a) * t.
29 | public static float Lerp(float a, float b, float t)
30 | {
31 | return a + (b - a) * t;
32 | }
33 |
34 | ///
35 | /// Linearly interpolates between two vectors.
36 | /// Interpolates between the vectors a and b by the interpolant t.
37 | /// The parameter t is clamped to the range[0, 1].
38 | /// This is most commonly used to find a point some fraction of the way along a line between two endpoints
39 | /// (e.g.to move an object gradually between those points).
40 | /// Similar to .
41 | ///
42 | /// Starting point.
43 | /// Destination point.
44 | /// Interpolation ratio.
45 | /// Interpolated value, equals to a + (b - a) * t.
46 | public static Vector2 Lerp(Vector2 a, Vector2 b, float t)
47 | {
48 | return new Vector2(Lerp(a.X, b.X, t), Lerp(a.Y, b.Y, t));
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/GameHelper/Utils/RemoteObjectPropertyDetail.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameHelper.Utils
6 | {
7 | using System.Reflection;
8 |
9 | ///
10 | /// Stores some information about RemoteObject Property.
11 | ///
12 | internal struct RemoteObjectPropertyDetail
13 | {
14 | ///
15 | /// Name of the property.
16 | ///
17 | public string Name;
18 |
19 | ///
20 | /// Value of the property.
21 | ///
22 | public object Value;
23 |
24 | ///
25 | /// ToImGui method of the property.
26 | ///
27 | public MethodInfo ToImGui;
28 | }
29 | }
--------------------------------------------------------------------------------
/GameOffsets/GameOffsets.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | false
6 |
7 |
8 |
9 | x64
10 | 1701;1702; 1591
11 |
12 |
13 |
14 | x64
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/GameOffsets/GameProcessName.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets
2 | {
3 | using System.Collections.Generic;
4 |
5 | public struct GameProcessDetails
6 | {
7 | ///
8 | /// Name of the Game Process (Normally name of the executable file without .exe)
9 | /// and the main window title. See task-manager to find the exact process name
10 | /// and convert the game to the window mode to see the window title on the game.
11 | ///
12 | public static readonly Dictionary ProcessName = new()
13 | {
14 | { "PathOfExile", "Path of Exile".ToLower() }, // also works on Garena
15 | { "PathOfExile_KG", "Path of Exile".ToLower() },
16 | { "PathOfExileSteam", "Path of Exile".ToLower() },
17 | { "PathOfExile_x64", "Path of Exile".ToLower() }
18 | };
19 |
20 | public static readonly List Contributors = new()
21 | {
22 | "Dax***",
23 | "Scrippydoo",
24 | "Riyu",
25 | "Noneyatemp",
26 | "hienngocloveyou"
27 | };
28 | }
29 | }
--------------------------------------------------------------------------------
/GameOffsets/Natives/StdBucket.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Natives
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | ///
7 | /// Not sure the name of this structure. POE game uses it in a lot of different places
8 | /// it might be a stdbucket, std unordered_set or std_unordered_multiset.
9 | /// TODO: Create c++ HelloWorld program,
10 | /// Create these structures (name it var),
11 | /// Fill 1 value,
12 | /// Use cheat engine on that HelloWorld Program.
13 | /// HINT: use cout << &var << endl; to print memory address.
14 | /// NOTE: A reader function that uses this datastructure exists
15 | /// in SafeMemoryHandle class. If you modify this datastructure
16 | /// modify that function too.
17 | ///
18 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
19 | public struct StdBucket
20 | {
21 | public long PAD_00;
22 | public IntPtr Data; // ComponentArrayStructure
23 | public long Capacity; // actually, it's Capacity number - 1.
24 | public int Unknown3; // byte + padd
25 | public float Unknown4;
26 | public int PAD_20; // it's actually Counter (i.e. amount of items in the bucket) but unstable, do not use this.
27 | public int PAD_24;
28 | }
29 |
30 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
31 | public struct StdBucketNode
32 | where TValue : struct
33 | {
34 | public byte Flag0;
35 | public byte Flag1;
36 | public byte Flag2;
37 | public byte Flag3;
38 | public byte Flag4;
39 | public byte Flag5;
40 | public byte Flag6;
41 | public byte Flag7;
42 |
43 | public TValue Pointer0;
44 | public TValue Pointer1;
45 | public TValue Pointer2;
46 | public TValue Pointer3;
47 | public TValue Pointer4;
48 | public TValue Pointer5;
49 | public TValue Pointer6;
50 | public TValue Pointer7;
51 |
52 | public static byte InValidPointerFlagValue = 0xFF;
53 | }
54 | }
--------------------------------------------------------------------------------
/GameOffsets/Natives/StdList.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Natives
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | ///
7 | /// A structure to read the c++ stdlist stored in the memory.
8 | /// NOTE: A reader function that uses this datastructure exists
9 | /// in SafeMemoryHandle class. If you modify this datastructure
10 | /// modify that function too.
11 | ///
12 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
13 | public struct StdList
14 | {
15 | public IntPtr Head;
16 | public int Size; // according to debugger this is long but for now int is working fine.
17 | public int PAD_C;
18 | }
19 |
20 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
21 | public struct StdListNode
22 | where TValue : struct
23 | {
24 | public IntPtr Next;
25 | public IntPtr Previous;
26 | public TValue Data;
27 | }
28 |
29 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
30 | public struct StdListNode
31 | {
32 | public IntPtr Next;
33 | public IntPtr Previous;
34 | }
35 | }
--------------------------------------------------------------------------------
/GameOffsets/Natives/StdMap.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Natives
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | ///
7 | /// A structure to read the c++ stdmap stored in the memory.
8 | /// NOTE: A reader function that uses this datastructure exists
9 | /// in SafeMemoryHandle class. If you modify this datastructure
10 | /// modify that too.
11 | ///
12 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
13 | public struct StdMap
14 | {
15 | public IntPtr Head;
16 | public int Size; // according to debugger this is long but for now int is working fine.
17 | public int PAD_C;
18 | }
19 |
20 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
21 | public struct StdMapNode
22 | where TKey : struct
23 | where TValue : struct
24 | {
25 | public IntPtr Left; // 0x00
26 | public IntPtr Parent; // 0x08
27 | public IntPtr Right; // 0x10
28 | public byte Color; // 0x18
29 | public bool IsNil; // 0x19
30 | public byte pad_1A;
31 | public byte pad_1B;
32 | public uint pad_1C;
33 | public StdMapNodeData Data; // 0x20
34 | }
35 |
36 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
37 | public struct StdMapNodeData
38 | where TKey : struct
39 | where TValue : struct
40 | {
41 | public TKey Key;
42 | public TValue Value;
43 | }
44 | }
--------------------------------------------------------------------------------
/GameOffsets/Natives/StdTuple2D.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Natives
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public struct StdTuple2D
7 | {
8 | public T X;
9 | public T Y;
10 |
11 | public StdTuple2D(T x, T y)
12 | {
13 | this.X = x;
14 | this.Y = y;
15 | }
16 |
17 | public override string ToString()
18 | {
19 | return $"X: {this.X}, Y: {this.Y}";
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/GameOffsets/Natives/StdTuple3D.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Natives
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public struct StdTuple3D
7 | {
8 | public T X;
9 | public T Y;
10 | public T Z;
11 |
12 | public override string ToString()
13 | {
14 | return $"X: {this.X}, Y: {this.Y}, Z: {this.Z}";
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/GameOffsets/Natives/StdVector.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Natives
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
7 | public struct StdVector
8 | {
9 | public IntPtr First;
10 | public IntPtr Last;
11 | public IntPtr End;
12 |
13 | ///
14 | /// Counts the number of elements in the StdVector.
15 | ///
16 | /// Number of bytes in 1 element.
17 | ///
18 | public long TotalElements(int elementSize)
19 | {
20 | return (this.Last.ToInt64() - this.First.ToInt64()) / elementSize;
21 | }
22 |
23 | public override string ToString()
24 | {
25 | return $"First: {this.First.ToInt64():X} - " +
26 | $"Last: {this.Last.ToInt64():X} - " +
27 | $"Size (bytes): {this.TotalElements(1)}";
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/GameOffsets/Natives/StdWString.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameOffsets.Natives
6 | {
7 | using System;
8 | using System.Runtime.InteropServices;
9 |
10 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
11 | public struct StdWString
12 | {
13 | public IntPtr Buffer;
14 |
15 | //// There is an optimization in std::wstring, where
16 | //// if a Capacity is less than or equal to 8
17 | //// then the wstring is stored locally (without a pointer).
18 | //// Since the pointer takes 8 bytes and 8 Capacity wstring takes 16 bytes
19 | //// wstring reserves 8 bytes over here which is then used to store the string.
20 | public IntPtr ReservedBytes;
21 | public int Length; // according to debugger this is long but for now int is working fine.
22 | public int PAD_14;
23 | public int Capacity; // according to debugger this is long but for now int is working fine.
24 | public int PAD_1C;
25 |
26 | public override string ToString()
27 | {
28 | return $"Buffer: {this.Buffer.ToInt64():X}, ReservedBytes: {this.ReservedBytes.ToInt64():X}, " +
29 | $"Length: {this.Length}, Capacity: {this.Capacity}";
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/GameOffsets/Natives/Util.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Natives
2 | {
3 | using System;
4 |
5 | public static class Util
6 | {
7 | ///
8 | /// Checks if the bit is set or not. Pos can be any number from 0 to 7.
9 | ///
10 | public static Func isBitSetByte = (x, pos) => (x & (1 << pos)) != 0;
11 |
12 | ///
13 | /// Checks if the bit is set or not. Pos can be any number from 0 to 31.
14 | ///
15 | public static Func isBitSetUint = (x, pos) => (x & (1 << pos)) != 0;
16 | }
17 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/AreaChangeOffset.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public struct AreaChangeOffset
7 | {
8 | public int counter;
9 | }
10 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Actor.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
6 | public struct ActorOffset
7 | {
8 | [FieldOffset(0x234)] public int AnimationId;
9 | }
10 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Base.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct BaseOffsets
8 | {
9 | [FieldOffset(0x0000)] public ComponentHeader Header;
10 | [FieldOffset(0x0010)] public IntPtr BaseInternalPtr; //BaseItemTypes.dat
11 | }
12 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Buffs.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 | using Natives;
6 |
7 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
8 | public struct BuffsOffsets
9 | {
10 | [FieldOffset(0x000)] public ComponentHeader Header;
11 | [FieldOffset(0x158)] public StdVector StatusEffectPtr;
12 | }
13 |
14 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
15 | public struct StatusEffectStruct
16 | {
17 | [FieldOffset(0x0008)] public IntPtr BuffDefinationPtr; //// BuffDefination.DAT file
18 | [FieldOffset(0x0018)] public float TotalTime;
19 |
20 | [FieldOffset(0x001C)] public float TimeLeft;
21 |
22 | // [FieldOffset(0x0020)] public float unknown0; // always set to 1.
23 | [FieldOffset(0x0028)] public uint SourceEntityId;
24 |
25 | //[FieldOffset(0x0030)] public long Unknown1;
26 | //[FieldOffset(0x0038)] public int unknown2;
27 | [FieldOffset(0x003E)] public ushort Charges; // 2 bytes long but 1 is enough
28 | [FieldOffset(0x0042)] public byte Effectiveness;
29 |
30 | public override string ToString()
31 | {
32 | var maxTime = float.IsInfinity(this.TotalTime) ? "Inf" : this.TotalTime.ToString();
33 | var timeLeft = float.IsInfinity(this.TimeLeft) ? "Inf" : this.TimeLeft.ToString();
34 | return $"BuffDefinationPtr: {this.BuffDefinationPtr.ToInt64():X}, MaxTime: {maxTime}, " +
35 | $"TimeLeft: {timeLeft}, Charges: {this.Charges}, " +
36 | $"Effectiveness: {this.Effectiveness}, " +
37 | $"Source Entity Id: {this.SourceEntityId}";
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Charges.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
6 | public struct ChargesOffsets
7 | {
8 | [FieldOffset(0x0000)] public ComponentHeader Header;
9 | [FieldOffset(0x0018)] public int current;
10 | }
11 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Chest.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct ChestOffsets
8 | {
9 | [FieldOffset(0x000)] public ComponentHeader Header;
10 | [FieldOffset(0x158)] public IntPtr ChestsDataPtr;
11 | [FieldOffset(0x160)] public bool IsOpened;
12 | }
13 |
14 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
15 | public struct ChestsStructInternal
16 | {
17 | [FieldOffset(0x21)] public bool IsLabelVisible;
18 | [FieldOffset(0x50)] public IntPtr StrongboxDatPtr;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/ComponentHeader.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
6 | public struct ComponentHeader
7 | {
8 | [FieldOffset(0x0000)] public long StaticPtr;
9 | [FieldOffset(0x0008)] public long EntityPtr;
10 | }
11 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Life.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct LifeOffset
8 | {
9 | [FieldOffset(0x000)] public ComponentHeader Header;
10 | [FieldOffset(0x190)] public VitalStruct Mana;
11 | [FieldOffset(0x1C8)] public VitalStruct EnergyShield;
12 | [FieldOffset(0x228)] public VitalStruct Health;
13 | }
14 |
15 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
16 | public struct VitalStruct
17 | {
18 | public IntPtr PtrToLifeComponent;
19 |
20 | ///
21 | /// This is greater than zero if Vital is regenerating
22 | /// For value = 0 or less than 0, Vital isn't regenerating
23 | ///
24 | public float Regeneration;
25 |
26 | public int Total;
27 |
28 | public int Current;
29 |
30 | ///
31 | /// e.g. Clarity reserve flat Vital
32 | ///
33 | public int ReservedFlat;
34 |
35 | ///
36 | /// e.g. Heralds reserve % Vital.
37 | /// ReservedFlat does not change this value.
38 | /// Note that it's an integer, this is due to 20.23% is stored as 2023
39 | ///
40 | public int ReservedPercent;
41 |
42 | ///
43 | /// Final Reserved amount of Vital after all the calculations.
44 | ///
45 | public int ReservedTotal => (int)Math.Ceiling(this.ReservedPercent / 10000f * this.Total) + this.ReservedFlat;
46 |
47 | ///
48 | /// Final un-reserved amount of Vital after all the calculations.
49 | ///
50 | public int Unreserved => this.Total - this.ReservedTotal;
51 |
52 | ///
53 | /// Returns current Vital in percentage (excluding the reserved vital) or returns zero in case the Vital
54 | /// doesn't exists.
55 | ///
56 | ///
57 | public int CurrentInPercent()
58 | {
59 | if (this.Total == 0)
60 | {
61 | return 0;
62 | }
63 |
64 | return (int)Math.Round(100d * this.Current / this.Unreserved);
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/ObjectMagicProperties.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
6 | public struct ObjectMagicPropertiesOffsets
7 | {
8 | [FieldOffset(0x00)] public ComponentHeader Header;
9 | [FieldOffset(0x13C)] public int Rarity;
10 | }
11 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Player.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System.Runtime.InteropServices;
4 | using Natives;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct PlayerOffsets
8 | {
9 | [FieldOffset(0x000)] public ComponentHeader Header;
10 | [FieldOffset(0x160)] public StdWString Name;
11 | }
12 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Positioned.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
6 | public struct PositionedOffsets
7 | {
8 | [FieldOffset(0x000)] public ComponentHeader Header;
9 |
10 | [FieldOffset(0x1D9)] public byte Reaction;
11 | // [FieldOffset(0x1E8)] public StdTuple2D GridPosition;
12 | // [FieldOffset(0x214)] public StdTuple2D WorldPosition;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Render.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System.Runtime.InteropServices;
4 | using Natives;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct RenderOffsets
8 | {
9 | [FieldOffset(0x0000)] public ComponentHeader Header;
10 |
11 | // Same as Positioned Component CurrentWorldPosition,
12 | // but this one contains Z axis; Z axis is where the HealthBar is.
13 | // If you want to use ground Z axis, swap current one with TerrainHeight.
14 | [FieldOffset(0x78)] public StdTuple3D CurrentWorldPosition;
15 |
16 | // Changing this value will move the in-game healthbar up/down.
17 | // Not sure if it's really X,Y,Z or something else. They all move
18 | // healthbar up/down. This might be useless.
19 | [FieldOffset(0x84)] public StdTuple3D CharactorModelBounds;
20 | // [FieldOffset(0x00A0)] public StdWString ClassName;
21 |
22 | // Exactly the same as provided in the Positioned component.
23 | // [FieldOffset(0x00C0)] public float RotationCurrent;
24 | // [FieldOffset(0x00C4)] public float RotationFuture;
25 | [FieldOffset(0xD8)] public float TerrainHeight;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/Shrine.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
6 | public struct ShrineOffsets
7 | {
8 | [FieldOffset(0x0000)] public ComponentHeader Header;
9 |
10 | // [FieldOffset(0x0020)] public int EntityIdWhoLastPickedTheShrine;
11 | [FieldOffset(0x0024)] public bool IsUsed;
12 | // [FieldOffset(0x0030)] public long ShrineDatRowPtr; //ShrineDatRowStruct
13 | }
14 |
15 | /*
16 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
17 | public struct ShrineDatRowStruct
18 | {
19 | [FieldOffset(0x0000)] public long IdString;
20 | //0 means it's not going to come back again.
21 | [FieldOffset(0x0008)] public int TimeoutInSeconds;
22 | [FieldOffset(0x000C)] public long DisplayName;
23 | [FieldOffset(0x0014)] public bool IsRegain;
24 | [FieldOffset(0x001D)] public bool PlayerShrineBuffDatRowPtr; //ShrineBuffDatStruct
25 | [FieldOffset(0x0025)] public int Unknown0;
26 | [FieldOffset(0x0029)] public int Unknown1;
27 | [FieldOffset(0x002D)] public long Description;
28 | [FieldOffset(0x0035)] public long MonsterShrineBuffDatRowPtr; //ShrineBuffDatStruct
29 | }
30 |
31 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
32 | public struct ShrineBuffDatStruct
33 | {
34 | [FieldOffset(0x0000)] public long IdString;
35 | [FieldOffset(0x0008)] public long BuffStatTotalKeys;
36 | [FieldOffset(0x0010)] public long BuffStatValuesPtr; //Ids (int) for BuffStats.dat
37 | [FieldOffset(0x0020)] public long BuffDefinationRowPtr; //BuffDefinations.DAT file Row
38 | }
39 | */
40 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/Components/TriggerableBlockage.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.Components
2 | {
3 | using System.Runtime.InteropServices;
4 |
5 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
6 | public struct TriggerableBlockageOffsets
7 | {
8 | [FieldOffset(0x000)] public ComponentHeader Header;
9 | [FieldOffset(0x0030)] public bool IsBlocked;
10 | }
11 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/FilesStructures/BaseItemTypesDatOffsets.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.FilesStructures
2 | {
3 | using System.Runtime.InteropServices;
4 | using Natives;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct BaseItemTypesDatOffsets
8 | {
9 | [FieldOffset(0x0030)] public StdWString BaseNamePtr;
10 | }
11 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/FilesStructures/WorldAreaDatOffsets.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.FilesStructures
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct WorldAreaDatOffsets
8 | {
9 | [FieldOffset(0x00)] public IntPtr IdPtr;
10 | [FieldOffset(0x08)] public IntPtr NamePtr;
11 | [FieldOffset(0x10)] public int Act;
12 | [FieldOffset(0x14)] public bool IsTown;
13 | [FieldOffset(0x15)] public bool HasWaypoint;
14 | }
15 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/GameStateOffsets.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 | using Natives;
6 |
7 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
8 | public struct GameStateStaticOffset
9 | {
10 | [FieldOffset(0x00)] public IntPtr GameState;
11 | }
12 |
13 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
14 | public struct GameStateOffset
15 | {
16 | [FieldOffset(0x08)] public StdVector CurrentStatePtr; // Used in RemoteObject -> CurrentState
17 | [FieldOffset(0x48)] public IntPtr State0;
18 | [FieldOffset(0x58)] public IntPtr State1;
19 | [FieldOffset(0x68)] public IntPtr State2;
20 | [FieldOffset(0x78)] public IntPtr State3;
21 | [FieldOffset(0x88)] public IntPtr State4;
22 | [FieldOffset(0x98)] public IntPtr State5;
23 | [FieldOffset(0xA8)] public IntPtr State6;
24 | [FieldOffset(0xB8)] public IntPtr State7;
25 | [FieldOffset(0xC8)] public IntPtr State8;
26 | [FieldOffset(0xD8)] public IntPtr State9;
27 | [FieldOffset(0xE8)] public IntPtr State10;
28 | [FieldOffset(0xF8)] public IntPtr State11;
29 | }
30 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/LoadedFilesOffset.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 | using Natives;
6 |
7 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
8 | public struct LoadedFilesRootObject
9 | {
10 | public StdBucket LoadedFiles;
11 | public static int TotalCount = 0x10;
12 | }
13 |
14 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
15 | public struct FilesPointerStructure
16 | {
17 | public IntPtr Useless0;
18 | public IntPtr FilesPointer;
19 | public IntPtr Useless1;
20 | }
21 |
22 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
23 | public struct FileInfoValueStruct
24 | {
25 | [FieldOffset(0x08)] public StdWString Name;
26 |
27 | //[FieldOffset(0x28)] public int FileType;
28 | //[FieldOffset(0x30)] public IntPtr UnknownPtr;
29 | [FieldOffset(0x38)] public int AreaChangeCount;
30 |
31 | // This saves a hell lot of memory but for debugging purposes
32 | // Feel free to set it to 0.
33 | public static readonly int IGNORE_FIRST_X_AREAS = 2;
34 | }
35 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/States/AreaLoadingStateOffset.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.States
2 | {
3 | using System.Runtime.InteropServices;
4 | using Natives;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct AreaLoadingStateOffset
8 | {
9 | [FieldOffset(0xC8)] public int IsLoading;
10 |
11 | [FieldOffset(0x368)] public uint TotalLoadingScreenTimeMs;
12 | [FieldOffset(0x3A8)] public StdWString CurrentAreaName; // use isloading/totalLoadingScreenTimeMs offset diff
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/States/InGameState/EntityOffsets.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.States.InGameState
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 | using Natives;
6 |
7 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
8 | public struct ItemStruct
9 | {
10 | [FieldOffset(0x00)] public IntPtr VTablePtr;
11 | [FieldOffset(0x08)] public IntPtr EntityDetailsPtr;
12 | [FieldOffset(0x10)] public StdVector ComponentListPtr;
13 | }
14 |
15 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
16 | public struct EntityOffsets
17 | {
18 | [FieldOffset(0x00)] public ItemStruct ItemBase;
19 | [FieldOffset(0x30)] public StdVector UnknownListPtr;
20 | [FieldOffset(0x60)] public uint Id;
21 | [FieldOffset(0x70)] public byte IsValid; // 0x0C = Valid, 0x03 = Invalid
22 | }
23 |
24 | public static class EntityHelper
25 | {
26 | // 0th bit set = invalid. test byte ptr [rcx+5C],01
27 | // pass IsValid byte to this function.
28 | public static Func IsValidEntity = param => { return !Util.isBitSetByte(param, 0); };
29 |
30 | public static Func IsFriendly = param => { return (param & 0x7F) == 0x01; };
31 | }
32 |
33 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
34 | public struct EntityDetails
35 | {
36 | [FieldOffset(0x08)] public StdWString name;
37 | [FieldOffset(0x30)] public IntPtr ComponentLookUpPtr;
38 | }
39 |
40 | // DRY this with LoadedFilesOffset
41 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
42 | public struct ComponentLookUpStruct
43 | {
44 | [FieldOffset(0x00)] public IntPtr Unknown0;
45 | [FieldOffset(0x08)] public IntPtr Unknown1;
46 | [FieldOffset(0x10)] public StdVector Unknown2;
47 | [FieldOffset(0x28)] public StdBucket ComponentsNameAndIndex;
48 | }
49 |
50 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
51 | public struct ComponentNameAndIndexStruct
52 | {
53 | public IntPtr NamePtr;
54 | public int Index;
55 | public int PAD_0xC;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/States/InGameState/ImportantUiElementsOffsets.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.States.InGameState
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | ///
7 | /// All offsets over here are UiElements.
8 | ///
9 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
10 | public struct ImportantUiElementsOffsets
11 | {
12 | [FieldOffset(0x678)] public IntPtr MapParentPtr;
13 | }
14 |
15 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
16 | public struct MapParentStruct
17 | {
18 | [FieldOffset(0x280)] public IntPtr LargeMapPtr;
19 | [FieldOffset(0x288)] public IntPtr MiniMapPtr;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/States/InGameState/InventoryOffset.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.States.InGameState
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 | using Natives;
6 |
7 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
8 | public struct PreInventoryStruct
9 | {
10 | [FieldOffset(0x10)] public IntPtr ptr;
11 | }
12 |
13 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
14 | public struct InventoryStruct
15 | {
16 | //[FieldOffset(0x00)] public int InventoryType;
17 | //[FieldOffset(0x04)] public int InventorySlot;
18 | //[FieldOffset(0x08)] public byte ShouldShowBoxes; // there are some other useless flags right after this byte.
19 | [FieldOffset(0x144)] public StdTuple2D TotalBoxes; // X * Y * 8 = StdVector.ItemList.Length.
20 |
21 | //[FieldOffset(0x18)] public int CanPutItem0; // setting this to 1 will block user from putting items.
22 | //[FieldOffset(0x1C)] public int CanPutItem1; // same as above.
23 | [FieldOffset(0x168)] public StdVector ItemList;
24 |
25 | // use ItemList, reading StdMap requires more reads than reading StdVector
26 | [FieldOffset(0x180)] public StdMap ItemsHashMap;
27 |
28 | // [FieldOffset(0x58)] public StdVector WierdUiElementsData;
29 | [FieldOffset(0x1C8)] public int ServerRequestCounter;
30 | }
31 |
32 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
33 | public struct ItemHashKey
34 | {
35 | public int ServerRequestCounterSnapShot;
36 | public int PAD_8;
37 | }
38 |
39 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
40 | public struct ItemHashValue
41 | {
42 | public IntPtr InventoryItemStructPtr;
43 | public IntPtr UselessItemPtr;
44 | }
45 |
46 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
47 | public struct InventoryItemStruct
48 | {
49 | [FieldOffset(0x00)] public IntPtr Item; // ItemStruct in EntityOffsets.cs
50 | [FieldOffset(0x08)] public StdTuple2D SlotStart;
51 | [FieldOffset(0x10)] public StdTuple2D SlotEnd;
52 | [FieldOffset(0x18)] public int ServerRequestCounterSnapShot;
53 | }
54 | }
--------------------------------------------------------------------------------
/GameOffsets/Objects/States/InGameState/ServerDataOffset.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.States.InGameState
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 | using Natives;
6 |
7 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
8 | public struct ServerDataStructure
9 | {
10 | public const int SKIP = 0x9300; // for reducing struct size.
11 | [FieldOffset(0x9288 + 0x278 - SKIP)] public StdVector PlayerInventories; // InventoryArrayStruct
12 |
13 | }
14 |
15 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
16 | public struct InventoryArrayStruct
17 | {
18 | [FieldOffset(0x00)] public int InventoryId;
19 | [FieldOffset(0x04)] public int PAD_0;
20 | [FieldOffset(0x08)] public IntPtr InventoryPtr0; // InventoryStruct
21 | [FieldOffset(0x10)] public IntPtr InventoryPtr1; // this points to 0x10 bytes before InventoryPtr0
22 | [FieldOffset(0x18)] public long PAD_1;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/States/InGameState/WorldDataOffset.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace GameOffsets.Objects.States.InGameState
6 | {
7 | using System;
8 | using System.Numerics;
9 | using System.Runtime.InteropServices;
10 |
11 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
12 | public struct WorldDataOffset
13 | {
14 | [FieldOffset(0xA0)] public IntPtr WorldAreaDetailsPtr;
15 | [FieldOffset(0xA8)] public CameraStructure CameraStructurePtr;
16 | }
17 |
18 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
19 | public struct WorldAreaDetailsStruct
20 | {
21 | [FieldOffset(0x88)] public IntPtr WorldAreaDetailsRowPtr; // WorldArea.dat Offsets
22 | }
23 |
24 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
25 | public struct CameraStructure
26 | {
27 | [FieldOffset(0x00)] public IntPtr CodePtr;
28 | // [FieldOffset(0x8)] public int Width;
29 | // [FieldOffset(0xC)] public int Height;
30 |
31 | // First value is changing when we change the screen size (ratio)
32 | // 4 bytes before the matrix doesn't change
33 | // matrix is duplicated, meaning when first matrix finish, 2nd one start with exact same values.
34 | [FieldOffset(0x80)] public Matrix4x4 WorldToScreenMatrix;
35 | // [FieldOffset(0xF0)] public Vector3 Position;
36 | // [FieldOffset(0x1C4)] public float ZFar;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/States/InGameStateOffset.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.States
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct InGameStateOffset
8 | {
9 | [FieldOffset(0x18)] public IntPtr AreaInstanceData;
10 | [FieldOffset(0x78)] public IntPtr WorldData;
11 | [FieldOffset(0x1A0)] public IntPtr UiRootPtr;
12 | [FieldOffset(0x450)] public IntPtr IngameUi;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/UiElement/MapUiElement.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.UiElement
2 | {
3 | using System.Runtime.InteropServices;
4 | using Natives;
5 |
6 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
7 | public struct MapUiElementOffset
8 | {
9 | [FieldOffset(0x000)] public UiElementBaseOffset UiElementBase;
10 | [FieldOffset(0x270)] public StdTuple2D Shift;
11 | [FieldOffset(0x278)] public StdTuple2D DefaultShift; //new v2=(0, -20f)
12 | [FieldOffset(0x2B4)] public float Zoom;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/GameOffsets/Objects/UiElement/UiElementBaseOffset.cs:
--------------------------------------------------------------------------------
1 | namespace GameOffsets.Objects.UiElement
2 | {
3 | using System;
4 | using System.Runtime.InteropServices;
5 | using Natives;
6 |
7 | [StructLayout(LayoutKind.Explicit, Pack = 1)]
8 | public struct UiElementBaseOffset
9 | {
10 | [FieldOffset(0x000)] public IntPtr Vtable;
11 | [FieldOffset(0x028)] public IntPtr Self;
12 |
13 | [FieldOffset(0x030)] public StdVector ChildrensPtr; // both points to same children UiElements.
14 |
15 | // [FieldOffset(0x038)] public StdVector ChildrensPtr1; // both points to same children UiElements.
16 | [FieldOffset(0xA8)] public StdTuple2D PositionModifier;
17 | [FieldOffset(0xB0)] public StdWString Id;
18 |
19 | [FieldOffset(0xD2)] public byte ScaleIndex;
20 |
21 | // Following Ptr is basically pointing to InGameState+0x458.
22 | // No idea what InGameState+0x458 is pointing to.
23 | // [FieldOffset(0x088)] public IntPtr UnknownPtr;
24 | [FieldOffset(0xE0)] public IntPtr ParentPtr; // UiElement.
25 | [FieldOffset(0xE8)] public StdTuple2D RelativePosition; // variable
26 |
27 | [FieldOffset(0x100)] public float LocalScaleMultiplier;
28 |
29 | // [FieldOffset(0x108)] public float Scale; // !!do not use this!!, this scale provided by game is wrong.
30 | [FieldOffset(0x160)] public uint Flags; // variable
31 |
32 | [FieldOffset(0x180)] public StdTuple2D UnscaledSize; // variable
33 | // Tooltip????
34 | }
35 |
36 | public static class UiElementBaseFuncs
37 | {
38 | private const int SHOULD_MODIFY_BINARY_POS = 0x0A;
39 | private const int IS_VISIBLE_BINARY_POS = 0x0B;
40 |
41 | public const int SCALE_INDEX_1 = 0x002;
42 | public const int SCALE_INDEX_3 = 0x004;
43 | public const int SCALE_INDEX_2 = 0x000;
44 |
45 | public static Func IsVisibleChecker = param =>
46 | {
47 | return Util.isBitSetUint(param, IS_VISIBLE_BINARY_POS);
48 | };
49 |
50 | public static Func ShouldModifyPos = param =>
51 | {
52 | return Util.isBitSetUint(param, SHOULD_MODIFY_BINARY_POS);
53 | };
54 |
55 | public static Func Unknown1 = param => { return Util.isBitSetUint(param, 0x02); };
56 |
57 | public static Func Unknown2 = param => { return Util.isBitSetUint(param, 0x03); };
58 |
59 | public static Func Unknown3 = param => { return Util.isBitSetUint(param, 0x13); };
60 | }
61 | }
--------------------------------------------------------------------------------
/HealthBars/Controller/SpriteController.cs:
--------------------------------------------------------------------------------
1 | namespace HealthBars.Controller
2 | {
3 | using System;
4 | using System.Globalization;
5 | using System.Numerics;
6 | using GameHelper;
7 | using GameHelper.Utils;
8 | using ImGuiNET;
9 |
10 | ///
11 | ///
12 | public class SpriteController
13 | {
14 | private readonly SpriteAtlas spriteAtlas;
15 | private readonly uint markColor = ImGuiHelper.Color(255, 255, 255, 100);
16 |
17 | ///
18 | /// Initialize SpriteController
19 | ///
20 | ///
21 | public SpriteController(SpriteAtlas spriteAtlas)
22 | {
23 | this.spriteAtlas = spriteAtlas;
24 | }
25 |
26 | ///
27 | /// Draw sprite from sprite atlas.
28 | ///
29 | ///
30 | ///
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | ///
37 | public void DrawSprite(
38 | string spriteName,
39 | Vector2 drawCoordinates,
40 | float scale,
41 | float virtualWidthFill,
42 | float virtualHeightFill,
43 | bool marks,
44 | bool border = false,
45 | uint borderColor = 0)
46 | {
47 | var sprite = this.spriteAtlas.GetSprite(spriteName);
48 | var offsetX = 0f;
49 | var offsetY = 23.17313f + Core.States.InGameStateObject.CurrentAreaInstance.Zoom * 14.69196f;
50 |
51 | if (sprite == null)
52 | {
53 | return;
54 | }
55 |
56 | var draw = ImGui.GetBackgroundDrawList();
57 |
58 | var bounds = new Vector2(
59 | sprite.VirtualBounds.X * ((virtualWidthFill < 0 ? 100 : virtualWidthFill) / 100),
60 | sprite.VirtualBounds.Y * ((virtualHeightFill < 0 ? 100 : virtualHeightFill) / 100)
61 | ) * scale;
62 | var vBounds = sprite.VirtualBounds * scale;
63 | var half = new Vector2(offsetX + vBounds.X / 2, offsetY);
64 | var pos = drawCoordinates - half;
65 |
66 | draw.AddImage(this.spriteAtlas.TexturePtr, pos, pos + bounds, sprite.Uv[0], sprite.Uv[1]);
67 |
68 | if (marks)
69 | {
70 | Vector2 markLine = new(0, vBounds.Y - 1.5f);
71 | Vector2 mark25 = new(vBounds.X * 0.25f, 0);
72 | Vector2 mark50 = new(vBounds.X * 0.5f, 0);
73 | Vector2 mark75 = new(vBounds.X * 0.75f, 0);
74 |
75 | draw.AddLine(pos + mark25, pos + markLine + mark25, this.markColor);
76 | draw.AddLine(pos + mark50, pos + markLine + mark50, this.markColor);
77 | draw.AddLine(pos + mark75, pos + markLine + mark75, this.markColor);
78 | }
79 |
80 | if (border)
81 | {
82 | draw.AddRect(pos, pos + vBounds, borderColor, 0f, ImDrawFlags.RoundCornersNone, 4f);
83 | }
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/HealthBars/HealthBars.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Library
5 | net5.0
6 | true
7 |
8 |
9 |
10 | x64
11 |
12 |
13 |
14 | x64
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | false
25 | false
26 |
27 |
28 |
29 |
30 |
31 | PreserveNewest
32 |
33 |
34 | PreserveNewest
35 |
36 |
37 |
38 |
39 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/HealthBars/Sprite.cs:
--------------------------------------------------------------------------------
1 | namespace HealthBars
2 | {
3 | using System.Numerics;
4 |
5 | ///
6 | /// Sprite class.
7 | ///
8 | public class Sprite
9 | {
10 | ///
11 | /// Sprite virtual outer space.
12 | ///
13 | public readonly Vector2 VirtualBounds;
14 |
15 | ///
16 | /// Initialization of instance.
17 | ///
18 | ///
19 | ///
20 | ///
21 | public Sprite(CubeObject frame, CubeObject spriteSheetSize, Vector2 virtualBounds)
22 | {
23 | this.VirtualBounds = virtualBounds;
24 |
25 | this.X = frame.X;
26 | this.Y = frame.Y;
27 | this.W = frame.W;
28 | this.H = frame.H;
29 |
30 | this.Uv = new Vector2[]
31 | {
32 | new(this.X / spriteSheetSize.W, this.Y / spriteSheetSize.H),
33 | new((this.X + this.W) / spriteSheetSize.W, (this.Y + this.H) / spriteSheetSize.H)
34 | };
35 | }
36 |
37 | ///
38 | /// Precalculated uv.
39 | ///
40 | public Vector2[] Uv { get; }
41 |
42 | private float H { get; }
43 | private float W { get; }
44 | private float X { get; }
45 | private float Y { get; }
46 | }
47 | }
--------------------------------------------------------------------------------
/HealthBars/SpritesheetMetadata.cs:
--------------------------------------------------------------------------------
1 | // ReSharper disable All
2 |
3 | #pragma warning disable 1591
4 | namespace HealthBars
5 | {
6 | using System.Collections.Concurrent;
7 | using System.Text.Json.Serialization;
8 |
9 | public class SpritesheetMetadata
10 | {
11 | [JsonPropertyName("frames")] public ConcurrentDictionary Frames;
12 |
13 | [JsonPropertyName("meta")] public MetaObject Meta;
14 | }
15 |
16 | public class FrameObject
17 | {
18 | [JsonPropertyName("frame")] public CubeObject Frame;
19 |
20 | [JsonPropertyName("rotated")] public bool Rotated;
21 |
22 | [JsonPropertyName("sourceSize")] public CubeObject SourceSize;
23 |
24 | [JsonPropertyName("spriteSourceSize")] public CubeObject SpriteSourceSize;
25 |
26 | [JsonPropertyName("trimmed")] public bool Trimmed;
27 | }
28 |
29 | public class MetaObject
30 | {
31 | [JsonPropertyName("app")] public string App;
32 |
33 | [JsonPropertyName("format")] public string Format;
34 |
35 | [JsonPropertyName("image")] public string Image;
36 |
37 | [JsonPropertyName("scale")] public float Scale;
38 |
39 | [JsonPropertyName("size")] public CubeObject Size;
40 |
41 | [JsonPropertyName("version")] public string Version;
42 | }
43 |
44 | public class CubeObject
45 | {
46 | [JsonPropertyName("h")] public float H;
47 |
48 | [JsonPropertyName("w")] public float W;
49 |
50 | [JsonPropertyName("x")] public float X;
51 |
52 | [JsonPropertyName("y")] public float Y;
53 | }
54 | }
--------------------------------------------------------------------------------
/HealthBars/View/Entities/CommonFriendly.cs:
--------------------------------------------------------------------------------
1 | namespace HealthBars.View.Entities
2 | {
3 | using System.Numerics;
4 | using Controller;
5 |
6 | ///
7 | public abstract class CommonFriendly : Default
8 | {
9 | ///
10 | /// Adds an Energy shield bar
11 | ///
12 | ///
13 | ///
14 | ///
15 | protected static void AddEnergyShieldBar(SpriteController spriteController, EntityParams eP, float scale)
16 | {
17 | var healthPos = eP.Pos + new Vector2(0, 1) * scale;
18 | spriteController.DrawSprite("ES", healthPos, scale, eP.EsPercent, -1, false, eP.DrawBorder, eP.BorderColor);
19 | }
20 |
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | protected static void AddHealthBar(SpriteController spriteController, EntityParams eP, float scale)
27 | {
28 | var hpPos = eP.Pos + new Vector2(0, 1) * scale;
29 | spriteController.DrawSprite("EmptyHP", hpPos, scale, 100f - eP.HpReserved, -1, false);
30 | spriteController.DrawSprite("HP", hpPos, scale, eP.HpPercent, -1, eP.Settings.ShowFriendlyGradationMarks);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/HealthBars/View/Entities/CurrentPlayer.cs:
--------------------------------------------------------------------------------
1 | namespace HealthBars.View.Entities
2 | {
3 | using Controller;
4 |
5 | ///
6 | public class CurrentPlayer : CommonFriendly
7 | {
8 | ///
9 | public override void Draw(EntityParams eP, SpriteController spriteController)
10 | {
11 | var scale = RarityBarScale(eP);
12 |
13 | AddDoubleEmptyBar(spriteController, eP, scale);
14 | AddManaBar(spriteController, eP, scale);
15 | AddHealthBar(spriteController, eP, scale);
16 | if (eP.EsTotal > 0)
17 | {
18 | AddEnergyShieldBar(spriteController, eP, scale);
19 | }
20 | }
21 |
22 | ///
23 | public override bool ShouldDraw(EntityParams entityParams)
24 | {
25 | return entityParams.Settings.ShowPlayerBars;
26 | }
27 |
28 | private static float RarityBarScale(EntityParams entityParams)
29 | {
30 | return entityParams.Settings.PlayerBarScale;
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/HealthBars/View/Entities/Default.cs:
--------------------------------------------------------------------------------
1 | namespace HealthBars.View.Entities
2 | {
3 | using System.Numerics;
4 | using Controller;
5 |
6 | ///
7 | public abstract class Default : IEntity
8 | {
9 | ///
10 | public abstract void Draw(EntityParams eP, SpriteController spriteController);
11 |
12 | ///
13 | public abstract bool ShouldDraw(EntityParams entityParams);
14 |
15 | ///
16 | /// Draws an empty bar sprite
17 | ///
18 | ///
19 | ///
20 | ///
21 | protected static void AddEmptyBar(SpriteController spriteController, EntityParams eP, float scale)
22 | {
23 | spriteController.DrawSprite("MonsterBar", eP.Pos, scale, -1, -1, false, eP.DrawBorder, eP.BorderColor);
24 | }
25 |
26 | ///
27 | /// Draws a double empty bar sprite
28 | ///
29 | ///
30 | ///
31 | ///
32 | protected static void AddDoubleEmptyBar(SpriteController spriteController, EntityParams eP, float scale)
33 | {
34 | spriteController.DrawSprite("PlayerBars", eP.Pos, scale, -1, -1, false, eP.DrawBorder, eP.BorderColor);
35 | }
36 |
37 |
38 | ///
39 | /// Draws a mana bar sprite
40 | ///
41 | ///
42 | ///
43 | ///
44 | protected static void AddManaBar(SpriteController spriteController, EntityParams eP, float scale)
45 | {
46 | var manaPos = eP.Pos + new Vector2(0, 10) * scale;
47 |
48 | spriteController.DrawSprite("EmptyMana", manaPos, scale, 100f - eP.ManaReserved, -1, false);
49 | spriteController.DrawSprite("Mana", manaPos, scale, eP.ManaPercent, -1, false);
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/HealthBars/View/Entities/Enemy.cs:
--------------------------------------------------------------------------------
1 | namespace HealthBars.View.Entities
2 | {
3 | using System.Numerics;
4 | using Controller;
5 | using GameHelper.RemoteEnums;
6 | using GameHelper.Utils;
7 |
8 | ///
9 | public class Enemy : Default
10 | {
11 | ///
12 | public override void Draw(EntityParams eP, SpriteController spriteController)
13 | {
14 | var scale = RarityBarScale(eP);
15 |
16 | if (eP.Settings.ShowEnemyMana)
17 | {
18 | AddDoubleEmptyBar(spriteController, eP, scale);
19 | AddManaBar(spriteController, eP, scale);
20 | }
21 | else
22 | {
23 | AddEmptyBar(spriteController, eP, scale);
24 | }
25 |
26 | AddHealthBar(spriteController, eP, scale);
27 | }
28 |
29 | ///
30 | public override bool ShouldDraw(EntityParams entityParams)
31 | {
32 | var rarity = entityParams.Rarity;
33 | var settings = entityParams.Settings;
34 |
35 | return entityParams.HasMagicProperties && (
36 | rarity == Rarity.Normal && settings.ShowNormalBar ||
37 | rarity == Rarity.Magic && settings.ShowMagicBar ||
38 | rarity == Rarity.Rare && settings.ShowRareBar ||
39 | rarity == Rarity.Unique && settings.ShowUniqueBar
40 | );
41 | }
42 |
43 | private static void AddHealthBar(SpriteController spriteController, EntityParams eP, float scale)
44 | {
45 | var hpPos = eP.Pos + new Vector2(0, 1) * scale;
46 | spriteController.DrawSprite("EmptyHP", hpPos, scale, 100f - eP.HpReserved, -1, false);
47 |
48 | var inCullingRange = InCullingRange(eP, eP.HpPercent);
49 | var cullingColor = ImGuiHelper.Color(eP.Settings.CullRangeColor * 255f);
50 | spriteController.DrawSprite("EnemyHP", hpPos, scale, eP.HpPercent, -1, eP.Settings.ShowEnemyGradationMarks,
51 | inCullingRange, cullingColor);
52 | }
53 |
54 | private static float RarityBarScale(EntityParams entityParams)
55 | {
56 | return entityParams.Rarity switch
57 | {
58 | Rarity.Unique => entityParams.Settings.UniqueBarScale,
59 | Rarity.Rare => entityParams.Settings.RareBarScale,
60 | Rarity.Magic => entityParams.Settings.MagicBarScale,
61 | _ => entityParams.Settings.NormalBarScale
62 | };
63 | }
64 |
65 | private static bool InCullingRange(EntityParams entityParams, float hpPercent)
66 | {
67 | return entityParams.ShowCulling && hpPercent > 0 && hpPercent < entityParams.Settings.CullingRange;
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/HealthBars/View/Entities/Friendly.cs:
--------------------------------------------------------------------------------
1 | namespace HealthBars.View.Entities
2 | {
3 | using Controller;
4 |
5 | ///
6 | public class Friendly : CommonFriendly
7 | {
8 | ///
9 | public override void Draw(EntityParams eP, SpriteController spriteController)
10 | {
11 | var scale = RarityBarScale(eP);
12 |
13 | AddEmptyBar(spriteController, eP, scale);
14 | AddHealthBar(spriteController, eP, scale);
15 | if (eP.EsTotal > 0)
16 | {
17 | AddEnergyShieldBar(spriteController, eP, scale);
18 | }
19 | }
20 |
21 | ///
22 | public override bool ShouldDraw(EntityParams entityParams)
23 | {
24 | return entityParams.Settings.ShowFriendlyBars;
25 | }
26 |
27 |
28 | private static float RarityBarScale(EntityParams entityParams)
29 | {
30 | return entityParams.Settings.FriendlyBarScale;
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/HealthBars/View/Entities/IEntity.cs:
--------------------------------------------------------------------------------
1 | namespace HealthBars.View.Entities
2 | {
3 | using Controller;
4 |
5 | ///
6 | ///
7 | public interface IEntity
8 | {
9 | ///
10 | ///
11 | ///
12 | ///
13 | public void Draw(EntityParams eP, SpriteController spriteController);
14 |
15 | ///
16 | ///
17 | ///
18 | ///
19 | public bool ShouldDraw(EntityParams entityParams);
20 | }
21 | }
--------------------------------------------------------------------------------
/HealthBars/View/Entities/Invalid.cs:
--------------------------------------------------------------------------------
1 | namespace HealthBars.View.Entities
2 | {
3 | using System;
4 | using System.Numerics;
5 | using Controller;
6 | using GameHelper.RemoteEnums;
7 | using GameHelper.Utils;
8 |
9 | ///
10 | public class Invalid : Default
11 | {
12 | ///
13 | public override void Draw(EntityParams eP, SpriteController spriteController)
14 | {
15 | throw new Exception("Can not draw invalid entity.");
16 | }
17 |
18 | ///
19 | public override bool ShouldDraw(EntityParams entityParams)
20 | {
21 | throw new Exception("Can not draw invalid entity.");
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/HealthBars/View/EntityFactory.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | namespace HealthBars.View
3 | {
4 | using Entities;
5 | using GameHelper;
6 | using GameHelper.RemoteObjects.Components;
7 | using GameHelper.RemoteObjects.States.InGameStateObjects;
8 |
9 | ///
10 | ///
11 | public class EntityFactory
12 | {
13 | private readonly Invalid invalid = new();
14 | private readonly Enemy enemy = new();
15 | private readonly Friendly friendly = new();
16 | private readonly CurrentPlayer player = new();
17 |
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | public bool TryGetEntity(Entity entity, out IEntity drawEntity)
24 | {
25 | drawEntity = this.invalid;
26 | var hasVital = entity.TryGetComponent(out var entityLife);
27 | if (!hasVital || !entityLife.IsAlive)
28 | {
29 | return false;
30 | }
31 |
32 | var isBlockage = entity.TryGetComponent(out _);
33 | if (isBlockage)
34 | {
35 | return false;
36 | }
37 |
38 | var hasRender = entity.TryGetComponent(out _);
39 | if (!hasRender)
40 | {
41 | return false;
42 | }
43 |
44 | var hasPositioned = entity.TryGetComponent(out var positioned);
45 | if (!hasPositioned)
46 | {
47 | return false;
48 | }
49 |
50 | var isPlayer = entity.TryGetComponent(out _);
51 | var hasMagicProperties = entity.TryGetComponent(out _);
52 | if (!hasMagicProperties && !isPlayer)
53 | {
54 | return false;
55 | }
56 |
57 | var willDieAfterTime = entity.TryGetComponent(out _);
58 | if (willDieAfterTime)
59 | {
60 | return false;
61 | }
62 |
63 | var isCurrentPlayer =
64 | entity.Address == Core.States.InGameStateObject.CurrentAreaInstance.Player.Address;
65 |
66 | if (isCurrentPlayer)
67 | {
68 | drawEntity = this.player;
69 | return true;
70 | }
71 |
72 | var isFriendly = positioned.IsFriendly;
73 | if (isFriendly)
74 | {
75 | drawEntity = this.friendly;
76 | return true;
77 | }
78 |
79 | drawEntity = this.enemy;
80 | return true;
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/HealthBars/sprites/ES.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/HealthBars/sprites/ES.png
--------------------------------------------------------------------------------
/HealthBars/sprites/EmptyHP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/HealthBars/sprites/EmptyHP.png
--------------------------------------------------------------------------------
/HealthBars/sprites/EmptyMana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/HealthBars/sprites/EmptyMana.png
--------------------------------------------------------------------------------
/HealthBars/sprites/EnemyHP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/HealthBars/sprites/EnemyHP.png
--------------------------------------------------------------------------------
/HealthBars/sprites/HP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/HealthBars/sprites/HP.png
--------------------------------------------------------------------------------
/HealthBars/sprites/Mana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/HealthBars/sprites/Mana.png
--------------------------------------------------------------------------------
/HealthBars/sprites/MonsterBar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/HealthBars/sprites/MonsterBar.png
--------------------------------------------------------------------------------
/HealthBars/sprites/PlayerBars.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/HealthBars/sprites/PlayerBars.png
--------------------------------------------------------------------------------
/HealthBars/spritesheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/HealthBars/spritesheet.png
--------------------------------------------------------------------------------
/Launcher/AutoUpdate.cs:
--------------------------------------------------------------------------------
1 | namespace Launcher
2 | {
3 | using Newtonsoft.Json;
4 | using Newtonsoft.Json.Linq;
5 | using System;
6 | using System.Diagnostics;
7 | using System.IO;
8 | using System.Net;
9 |
10 | public static class AutoUpdate
11 | {
12 | private static string upgrade_url = "https://api.github.com/repos/BanditTech/GameOverlay/releases/latest";
13 | private static string version_file_name = "VERSION.txt";
14 | private static string release_file_name = "release.zip";
15 | private static string self_exe_name = AppDomain.CurrentDomain.FriendlyName;
16 |
17 | private static JObject get_latest_version_info()
18 | {
19 | var httpWebRequest = (HttpWebRequest)WebRequest.Create(upgrade_url);
20 | httpWebRequest.ContentType = "application/json";
21 | httpWebRequest.Accept = "*/*";
22 | httpWebRequest.Method = "GET";
23 | httpWebRequest.UserAgent = "curl/7.83.0";
24 | var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
25 | using var streamReader = new StreamReader(httpResponse.GetResponseStream());
26 | var jsonObject = JsonConvert.DeserializeObject(streamReader.ReadToEnd());
27 | return jsonObject;
28 | }
29 |
30 | private static string extract_download_url(JObject info)
31 | {
32 | var asserts = info["assets"];
33 | foreach (var assert in asserts)
34 | {
35 | if (assert["name"].ToString() == release_file_name)
36 | {
37 | return assert["browser_download_url"].ToString();
38 | }
39 | }
40 |
41 | return string.Empty;
42 | }
43 |
44 | public static bool UpgradeGameHelper(string gameHelperDir)
45 | {
46 | var versionFile = Path.Combine(gameHelperDir, version_file_name);
47 | if (!File.Exists(versionFile))
48 | {
49 | Console.WriteLine($"{versionFile} is missing, skipping upgrade process.");
50 | return false;
51 | }
52 |
53 | var currentVersion = File.ReadAllText(versionFile).Trim();
54 | var info = get_latest_version_info();
55 | string latestVersion;
56 | if (info["tag_name"] != null)
57 | {
58 | latestVersion = info["tag_name"].ToString();
59 | }
60 | else
61 | {
62 | Console.WriteLine($"Failed to upgrade because I couldn't find tag in {info}.");
63 | return false;
64 | }
65 |
66 | var downloadUrl = extract_download_url(info);
67 | if (string.IsNullOrEmpty(downloadUrl))
68 | {
69 | Console.WriteLine($"Upgrade failed because I couldn't find {release_file_name} in {info}.");
70 | return false;
71 | }
72 |
73 | if (currentVersion != latestVersion)
74 | {
75 | Console.WriteLine($"Your version is {currentVersion}. Latest version is {latestVersion}, downloading now...");
76 | using var client = new WebClient();
77 | client.DownloadFile(downloadUrl, release_file_name);
78 | Process.Start("powershell.exe", $"Start-sleep -Seconds 3; Expand-Archive -Force {release_file_name} .; Remove-Item -Force {release_file_name}; ./{self_exe_name}.exe -Force");
79 | return true;
80 |
81 | }
82 |
83 | return false;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Launcher/GameHelperFinder.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace Launcher
6 | {
7 | using System;
8 | using System.IO;
9 | using System.Reflection;
10 |
11 | public static class GameHelperFinder
12 | {
13 | private const string GameHelperFileName = "GameHelper.exe";
14 |
15 | ///
16 | /// Finds the GameHelper on the file system.
17 | ///
18 | /// directory in which game helper is located
19 | /// path to game helper exe file
20 | ///
21 | public static bool TryFindGameHelperExe(out string gameHelperDir, out string gameHelperLoc)
22 | {
23 | gameHelperDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
24 | gameHelperLoc = Path.Join(gameHelperDir, GameHelperFileName);
25 | if (!new FileInfo(gameHelperLoc).Exists)
26 | {
27 | Console.WriteLine($"GameHelper.exe not found in {gameHelperDir} directory.");
28 | Console.Write("Provide GameHelper.exe path:");
29 | var path = Console.ReadLine().Trim();
30 | if (File.GetAttributes(path).HasFlag(FileAttributes.Directory))
31 | {
32 | gameHelperDir = path;
33 | }
34 | else
35 | {
36 | gameHelperDir = Path.GetDirectoryName(path);
37 | }
38 |
39 | gameHelperLoc = Path.Join(gameHelperDir, GameHelperFileName);
40 | if (!new FileInfo(gameHelperLoc).Exists)
41 | {
42 | return false;
43 | }
44 | }
45 |
46 | return true;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Launcher/GameHelperTransformer.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace Launcher
6 | {
7 | using System.IO;
8 | using AsmResolver.PE;
9 | using AsmResolver.PE.File;
10 | using AsmResolver.PE.File.Headers;
11 | using AsmResolver.PE.Win32Resources.Builder;
12 | using AsmResolver.PE.Win32Resources.Version;
13 |
14 | ///
15 | /// A helper class to transform the GameHelper tool name and metadata info.
16 | ///
17 | public static class GameHelperTransformer
18 | {
19 | ///
20 | /// Transforms the GameHelper tool name and metadata info.
21 | ///
22 | /// string to replace the name and metadata info with.
23 | ///
24 | public static string TransformGameHelperExecutable(string gameHelperDir, string gameHelperLoc, string newName)
25 | {
26 | var newPath = Path.Join(gameHelperDir, $"{newName}.exe");
27 | TemporaryFileManager.AddFile(newPath);
28 | TransformExecutable(gameHelperLoc, newPath, newName);
29 | return newPath;
30 | }
31 |
32 | private static void TransformExecutable(string inputPath, string outputPath, string infoName)
33 | {
34 | var peFile = PEFile.FromFile(inputPath);
35 | var peImage = PEImage.FromFile(peFile);
36 | var versionInfo = VersionInfoResource.FromDirectory(peImage.Resources);
37 | var stringInfo = versionInfo.GetChild(StringFileInfo.StringFileInfoKey);
38 | var stringTable = stringInfo.Tables[0];
39 | stringTable[StringTable.CommentsKey] = "";
40 | stringTable[StringTable.CompanyNameKey] = infoName;
41 | stringTable[StringTable.FileDescriptionKey] = infoName;
42 | stringTable[StringTable.InternalNameKey] = infoName;
43 | stringTable[StringTable.OriginalFilenameKey] = Path.GetFileName(outputPath);
44 | stringTable[StringTable.ProductNameKey] = infoName;
45 | versionInfo.WriteToDirectory(peImage.Resources);
46 | var resourceDirectoryBuffer = new ResourceDirectoryBuffer();
47 | resourceDirectoryBuffer.AddDirectory(peImage.Resources);
48 | var directory = peFile.OptionalHeader.GetDataDirectory(DataDirectoryIndex.ResourceDirectory);
49 | var section = peFile.GetSectionContainingRva(directory.VirtualAddress);
50 | section.Contents = resourceDirectoryBuffer;
51 | peFile.Write(outputPath);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Launcher/Launcher.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net5.0
6 | app.manifest
7 | Launcher.Program
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Launcher/LocationValidator.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace Launcher
6 | {
7 | using System;
8 | using System.IO;
9 | using System.Reflection;
10 | using System.Text.RegularExpressions;
11 |
12 | ///
13 | /// A helper class to validate location.
14 | ///
15 | public static class LocationValidator
16 | {
17 | private static readonly Regex BadNameRegex = new(
18 | @"poe|path\s*of\s*exile|overlay|helper|hud|desktop",
19 | RegexOptions.IgnoreCase);
20 |
21 | ///
22 | /// Checks the GameHelper tool path name to make sure it doesn't have any bad information.
23 | /// If it does, print the issue to the stdout.
24 | ///
25 | /// returns true in case of good path otherwise false.
26 | public static bool IsGameHelperLocationGood(out string message)
27 | {
28 | message = null;
29 | var currentProcessPath = Assembly.GetExecutingAssembly().Location;
30 | var directoryPath = Path.GetDirectoryName(currentProcessPath);
31 | var pathMatch = BadNameRegex.Match(directoryPath);
32 | if (pathMatch.Success)
33 | {
34 | message = $"You have downloaded GameHelper in a bad folder/pathname. " +
35 | $"Your folder/pathname contains \"{pathMatch.Value}\". " +
36 | $"This is bad for your account. Please rename/move GameHelper to a better folder/pathname.";
37 | return false;
38 | }
39 |
40 | return true;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Launcher/MiscHelper.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace Launcher
6 | {
7 | using System;
8 | using System.Linq;
9 |
10 | ///
11 | /// A helper class containing misc functions.
12 | ///
13 | public static class MiscHelper
14 | {
15 | ///
16 | /// Utility function that returns randomly generated string.
17 | ///
18 | /// randomly generated string.
19 | public static string GenerateRandomString()
20 | {
21 | //more common letters!
22 | const string characters = "qwertyuiopasdfghjklzxcvbnm" + "eioadfc";
23 | var random = new Random();
24 |
25 | char GetRandomCharacter()
26 | {
27 | return characters[random.Next(0, characters.Length)];
28 | }
29 |
30 | string GetWord()
31 | {
32 | return char.ToUpperInvariant(GetRandomCharacter()) +
33 | new string(Enumerable.Range(0, random.Next(5, 10))
34 | .Select(_ => GetRandomCharacter())
35 | .ToArray());
36 | }
37 |
38 | return string.Join(' ', Enumerable.Range(0, random.Next(1, 4)).Select(_ => GetWord()));
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Launcher/Program.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace Launcher
6 | {
7 | using System;
8 | using System.Diagnostics;
9 | using System.Threading;
10 |
11 | public static class Program
12 | {
13 | private static int Main(string[] args)
14 | {
15 | if (!GameHelperFinder.TryFindGameHelperExe(out var gameHelperDir, out var gameHelperLoc))
16 | {
17 | Console.WriteLine($"GameHelper.exe is also not found in {gameHelperDir}");
18 | Console.ReadKey();
19 | return 1;
20 | }
21 |
22 | try
23 | {
24 | var isWaiting = false;
25 | if (args.Length == 0)
26 | {
27 | Console.WriteLine("Are you waiting for a new GameHelper release? (yes/no)");
28 | isWaiting = Console.ReadLine().ToLowerInvariant().StartsWith("y");
29 | }
30 |
31 | do
32 | {
33 | if (AutoUpdate.UpgradeGameHelper(gameHelperDir))
34 | {
35 | // Returning because Launcher should auto-restart on exit.
36 | return 0;
37 | }
38 | else if (isWaiting)
39 | {
40 | Console.WriteLine("Didn't find any new version, sleeping for 5 mins....");
41 | Thread.Sleep(5 * 60 * 1000);
42 | }
43 | }
44 | while (isWaiting);
45 | }
46 | catch (Exception ex)
47 | {
48 | Console.WriteLine($"Failed to upgrade GameHelper due to: {ex}");
49 | Console.ReadKey();
50 | }
51 |
52 | try
53 | {
54 | Console.WriteLine("Preparing GameHelper...");
55 | var newName = MiscHelper.GenerateRandomString();
56 | TemporaryFileManager.Purge();
57 | //TODO: if functionality extends, should probably utilize an argument parser, but good for now
58 | if (!LocationValidator.IsGameHelperLocationGood(out var message))
59 | {
60 | Console.WriteLine(message);
61 | Console.Write("Press any key to ignore this warning.");
62 | Console.ReadLine();
63 | }
64 |
65 | var gameHelperPath = GameHelperTransformer.TransformGameHelperExecutable(gameHelperDir, gameHelperLoc, newName);
66 | Console.WriteLine($"Starting GameHelper at '{gameHelperPath}'...");
67 | Process.Start(gameHelperPath);
68 | }
69 | catch (Exception ex)
70 | {
71 | Console.WriteLine($"Failed to launch GameHelper due to: {ex}");
72 | Console.ReadKey();
73 | }
74 |
75 | return 0;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/Launcher/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Launcher": {
4 | "commandName": "Project",
5 | "commandLineArgs": "-allowPath"
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/Launcher/TemporaryFileManager.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) None. All rights reserved.
3 | //
4 |
5 | namespace Launcher
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using System.IO;
10 | using System.Linq;
11 | using System.Reflection;
12 | using Newtonsoft.Json;
13 |
14 | ///
15 | /// A helper class to manage the temporary executables created by the .
16 | ///
17 | public static class TemporaryFileManager
18 | {
19 | private const string StoreFileName = "tempFileLocations.dat";
20 |
21 | ///
22 | /// Adds the file to the manager.
23 | ///
24 | /// file pathname.
25 | public static void AddFile(string path)
26 | {
27 | var fileList = GetFileList();
28 | WriteFileList(fileList.Append(Path.GetRelativePath(GetDirectoryPath(), path)));
29 | }
30 |
31 | ///
32 | /// Purge all the files added into the .
33 | /// This includes the files added in the previous executions of .
34 | ///
35 | public static void Purge()
36 | {
37 | var fileList = GetFileList();
38 | var directoryPath = GetDirectoryPath();
39 | foreach (var file in fileList.Select(x => Path.Join(directoryPath, x)))
40 | {
41 | try
42 | {
43 | if (File.Exists(file))
44 | {
45 | File.Delete(file);
46 | }
47 | }
48 | catch (Exception ex)
49 | {
50 | Console.WriteLine(ex.ToString());
51 | }
52 | }
53 |
54 | WriteFileList(Array.Empty());
55 | }
56 |
57 | private static IReadOnlyList GetFileList()
58 | {
59 | try
60 | {
61 | var tempFileName = GetFullTemporaryFileName();
62 | if (!File.Exists(tempFileName))
63 | {
64 | return Array.Empty();
65 | }
66 |
67 | var fileContent = File.ReadAllText(tempFileName);
68 | return JsonConvert.DeserializeObject>(fileContent);
69 | }
70 | catch (Exception ex)
71 | {
72 | Console.WriteLine(ex.ToString());
73 | return Array.Empty();
74 | }
75 | }
76 |
77 | private static void WriteFileList(IEnumerable list)
78 | {
79 | File.WriteAllText(GetFullTemporaryFileName(), JsonConvert.SerializeObject(list.Distinct()));
80 | }
81 |
82 | private static string GetFullTemporaryFileName()
83 | {
84 | return Path.Join(GetDirectoryPath(), StoreFileName);
85 | }
86 |
87 | private static string GetDirectoryPath()
88 | {
89 | var currentProcessPath = Assembly.GetExecutingAssembly().Location;
90 | return Path.GetDirectoryName(currentProcessPath);
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Launcher/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
59 |
60 |
61 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/PreloadAlert/PreloadAlert.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | Library
6 | true
7 |
8 |
9 |
10 | x64
11 |
12 |
13 |
14 | x64
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | false
24 | false
25 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/PreloadAlert/PreloadSettings.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace PreloadAlert
6 | {
7 | using System.Numerics;
8 | using GameHelper.Plugin;
9 |
10 | ///
11 | /// Preload GUI settings.
12 | ///
13 | public sealed class PreloadSettings : IPSettings
14 | {
15 | ///
16 | /// Background color of the preload alert window.
17 | ///
18 | public Vector4 BackgroundColor = new(Vector3.Zero, 0.8f);
19 |
20 | ///
21 | /// Gets a value indicating whether to hide the Ui when not in the game or game in background.
22 | ///
23 | public bool EnableHideUi = false;
24 |
25 | ///
26 | /// Gets a value indicating whether the preload alert window should hide when in town/hideout.
27 | ///
28 | public bool HideWhenInTownOrHideout = false;
29 |
30 | ///
31 | /// Gets a value indicating whether the preload alert window should hide when empty.
32 | ///
33 | public bool HideWindowWhenEmpty = false;
34 |
35 | ///
36 | /// Gets a value indicating whether the preload alert window is locked or not.
37 | ///
38 | public bool Locked = false;
39 |
40 | ///
41 | /// Position of the preload alert window.
42 | ///
43 | public Vector2 Pos = Vector2.Zero;
44 |
45 | ///
46 | /// Size of the preload alert window.
47 | ///
48 | public Vector2 Size = Vector2.Zero;
49 | }
50 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GameOverlay
2 |
3 | No support will be given for this project, that said feel free to fork and do whatever with the codebase as per the original authors wishes.
4 |
5 | For a more advanced tool, check out ExileAPI.
6 |
--------------------------------------------------------------------------------
/Radar/Helper.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace Radar
6 | {
7 | using System;
8 | using System.Numerics;
9 |
10 | ///
11 | /// Contains the helper functions.
12 | ///
13 | public static class Helper
14 | {
15 | ///
16 | /// Map rotation in Radian format.
17 | ///
18 | public static readonly double CameraAngle = 38.7 * Math.PI / 180;
19 | private static double diagonalLength = 0x00;
20 | private static float scale = 0.5f;
21 | private static float cos = 0x00;
22 | private static float sin = 0x00;
23 |
24 | ///
25 | /// Sets the diagonal length of the Mini/Large Map UiElement,
26 | /// depending on what's visible.
27 | ///
28 | public static double DiagonalLength
29 | {
30 | private get
31 | {
32 | return diagonalLength;
33 | }
34 |
35 | set
36 | {
37 | if (value > 0 && value != diagonalLength)
38 | {
39 | diagonalLength = value;
40 | UpdateCosSin();
41 | }
42 | }
43 | }
44 |
45 | ///
46 | /// Sets the scale of the Mini/Large Map, depending on what's visible.
47 | ///
48 | public static float Scale
49 | {
50 | private get
51 | {
52 | return scale;
53 | }
54 |
55 | set
56 | {
57 | if (value > 0 && value != scale)
58 | {
59 | scale = value;
60 | UpdateCosSin();
61 | }
62 | }
63 | }
64 |
65 | ///
66 | /// Converts Entity to Player delta w.r.t Grid Postion
67 | /// to the Minimap pixel location Delta.
68 | ///
69 | ///
70 | /// Grid postion delta between player and the entity to draw.
71 | /// This is due to the fact that player always remains at center of the mini/large,
72 | /// if we ignore the map shifting feature.
73 | ///
74 | ///
75 | /// Terrain level difference between player and entity.
76 | ///
77 | /// nothing.
78 | public static Vector2 DeltaInWorldToMapDelta(Vector2 delta, float deltaZ)
79 | {
80 | // WorldPosition distance between 2 points
81 | // divide it by GridPosition distance between 2 points.
82 | // Rounded to 2 decimal points.
83 | deltaZ /= 10.87f;
84 | return new Vector2((delta.X - delta.Y) * cos, (deltaZ - (delta.X + delta.Y)) * sin);
85 | }
86 |
87 | private static void UpdateCosSin()
88 | {
89 | // Magic number that works with diagnonal length.
90 | float mapScale = 240f / Scale;
91 | cos = (float)(DiagonalLength * Math.Cos(CameraAngle) / mapScale);
92 | sin = (float)(DiagonalLength * Math.Sin(CameraAngle) / mapScale);
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Radar/Radar.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Library
5 | net5.0
6 | true
7 |
8 |
9 |
10 | x64
11 |
12 |
13 |
14 | x64
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | false
29 | false
30 |
31 |
32 |
33 |
34 |
35 | PreserveNewest
36 |
37 |
38 | PreserveNewest
39 |
40 |
41 |
42 |
43 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Radar/icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BanditTech/GameOverlay/bc73cedc0b7e362b3007c93decede42b9ca6d635/Radar/icons.png
--------------------------------------------------------------------------------
/SamplePluginTemplate/Changeme/Changeme.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | Library
6 | true
7 |
8 |
9 |
10 | x64
11 |
12 |
13 |
14 | x64
15 |
16 |
17 |
18 |
19 |
20 | all
21 | runtime; build; native; contentfiles; analyzers; buildtransitive
22 |
23 |
24 |
25 |
26 |
27 | false
28 | false
29 |
30 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/SamplePluginTemplate/Changeme/ChangemeCore.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace Changeme
6 | {
7 | using GameHelper.Plugin;
8 |
9 | ///
10 | /// plugin.
11 | ///
12 | public sealed class ChangemeCore : PCore
13 | {
14 | ///
15 | public override void DrawSettings()
16 | {
17 | }
18 |
19 | ///
20 | public override void DrawUI()
21 | {
22 | }
23 |
24 | ///
25 | public override void OnDisable()
26 | {
27 | }
28 |
29 | ///
30 | public override void OnEnable()
31 | {
32 | }
33 |
34 | ///
35 | public override void SaveSettings()
36 | {
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/SamplePluginTemplate/Changeme/ChangemeSettings.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) PlaceholderCompany. All rights reserved.
3 | //
4 |
5 | namespace Changeme
6 | {
7 | using GameHelper.Plugin;
8 |
9 | ///
10 | /// plugin settings class.
11 | ///
12 | public sealed class ChangemeSettings : IPSettings
13 | {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------