From cfcc94c874b044028800c33f5dd54cec23956d7c Mon Sep 17 00:00:00 2001 From: adpist Date: Thu, 16 Oct 2025 21:40:21 +0200 Subject: [PATCH 01/18] add support for fixed values tier and merc tier in nip files --- pkg/nip/rule.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/pkg/nip/rule.go b/pkg/nip/rule.go index 7831de0..3bafcbf 100644 --- a/pkg/nip/rule.go +++ b/pkg/nip/rule.go @@ -23,6 +23,8 @@ var ( fixedPropsRegexp = regexp.MustCompile(`(\[(type|quality|class|name|flag|color|prefix|suffix)]\s*(<=|<|>|>=|!=|==)\s*([a-zA-Z0-9]+))`) statsRegexp = regexp.MustCompile(`\[(.*?)]`) maxQtyRegexp = regexp.MustCompile(`(\[maxquantity]\s*(<=|<|>|>=|!=|==)\s*([0-9]+))`) + tierRegexp = regexp.MustCompile(`(\[tier]\s*(<=|<|>|>=|!=|==)\s*([0-9]+))`) + mercTierRegexp = regexp.MustCompile(`(\[merctier]\s*(<=|<|>|>=|!=|==)\s*([0-9]+))`) ) type Rule struct { @@ -31,6 +33,8 @@ type Rule struct { LineNumber int Enabled bool maxQuantity int + tier float64 + mercTier float64 stage1 *vm.Program stage2 *vm.Program requiredStats []string @@ -61,6 +65,32 @@ func (r Rules) EvaluateAll(it data.Item) (Rule, RuleResult) { return bestMatchingRule, bestMatch } +func (r Rules) EvaluateTiers(it data.Item, tierRulesIndexes []int) (Rule, Rule) { + highestTierRule := Rule{} + highestMercTierRule := Rule{} + for _, ruleIndex := range tierRulesIndexes { + if ruleIndex < len(r) { + rule := r[ruleIndex] + if rule.Enabled { + result, err := rule.Evaluate(it) + if err != nil { + continue + } + if result == RuleResultFullMatch || result == RuleResultPartial { + if rule.tier > highestTierRule.tier { + highestTierRule = rule + } + if rule.mercTier > highestMercTierRule.mercTier { + highestMercTierRule = rule + } + } + } + } + } + + return highestTierRule, highestMercTierRule +} + var fixedPropsList = map[string]int{"type": 0, "quality": 0, "class": 0, "name": 0, "flag": 0, "color": 0, "prefix": 0, "suffix": 0} func NewRule(rawRule string, filename string, lineNumber int) (Rule, error) { @@ -77,6 +107,28 @@ func NewRule(rawRule string, filename string, lineNumber int) (Rule, error) { rule = strings.ReplaceAll(rule, prop[0], "") } + // Try to get the tier value and purge it from the rule, we can not evaluate it yet + tier := 0.0 + for _, prop := range tierRegexp.FindAllStringSubmatch(rule, -1) { + parsedTier, err := strconv.Atoi(prop[3]) + if err != nil { + return Rule{}, fmt.Errorf("error parsing tier value %s: %w", prop[3], err) + } + tier = float64(parsedTier) + rule = strings.ReplaceAll(rule, prop[0], "") + } + + // Try to get the merctier value and purge it from the rule, we can not evaluate it yet + mercTier := 0.0 + for _, prop := range mercTierRegexp.FindAllStringSubmatch(rule, -1) { + parsedMercTier, err := strconv.Atoi(prop[3]) + if err != nil { + return Rule{}, fmt.Errorf("error parsing merctier value %s: %w", prop[3], err) + } + mercTier = float64(parsedMercTier) + rule = strings.ReplaceAll(rule, prop[0], "") + } + // Sanitize again, just in case we messed up the rule while parsing maxquantity rule = sanitizeLine(rule) if rule == "" { @@ -89,6 +141,8 @@ func NewRule(rawRule string, filename string, lineNumber int) (Rule, error) { LineNumber: lineNumber, Enabled: true, maxQuantity: maxQuantity, + tier: tier, + mercTier: mercTier, } parts := strings.Split(rule, "#") @@ -372,3 +426,11 @@ func getRequiredStatsForRule(line string) []string { func (r Rule) MaxQuantity() int { return r.maxQuantity } + +func (r Rule) Tier() float64 { + return r.tier +} + +func (r Rule) MercTier() float64 { + return r.mercTier +} From f3263ba4f8a7f208ed436fa4032f6130c4037f65 Mon Sep 17 00:00:00 2001 From: adpist Date: Thu, 16 Oct 2025 23:33:18 +0200 Subject: [PATCH 02/18] add function to skip tier rules when evaluating --- pkg/nip/rule.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pkg/nip/rule.go b/pkg/nip/rule.go index 3bafcbf..8559c9d 100644 --- a/pkg/nip/rule.go +++ b/pkg/nip/rule.go @@ -65,6 +65,31 @@ func (r Rules) EvaluateAll(it data.Item) (Rule, RuleResult) { return bestMatchingRule, bestMatch } +func (r Rules) EvaluateAllIgnoreTiers(it data.Item) (Rule, RuleResult) { + bestMatch := RuleResultNoMatch + bestMatchingRule := Rule{} + for _, rule := range r { + if rule.Enabled { + if rule.tier > 0 || rule.mercTier > 0 { + continue + } + result, err := rule.Evaluate(it) + if err != nil { + continue + } + if result == RuleResultFullMatch { + return rule, result + } + if result == RuleResultPartial { + bestMatch = result + bestMatchingRule = rule + } + } + } + + return bestMatchingRule, bestMatch +} + func (r Rules) EvaluateTiers(it data.Item, tierRulesIndexes []int) (Rule, Rule) { highestTierRule := Rule{} highestMercTierRule := Rule{} From ab0f68ec5ec667f1135b640d52652774a83bf2de Mon Sep 17 00:00:00 2001 From: guiyomu-dev <22749537+guiyomu-dev@users.noreply.github.com> Date: Fri, 17 Oct 2025 10:04:10 +0200 Subject: [PATCH 03/18] fix offsets for lobby games --- pkg/memory/game_reader.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/memory/game_reader.go b/pkg/memory/game_reader.go index 700deb4..694caf2 100644 --- a/pkg/memory/game_reader.go +++ b/pkg/memory/game_reader.go @@ -430,11 +430,11 @@ func (gd *GameReader) IsDismissableModalPresent() (bool, string) { } func (gd *GameReader) LastGameName() string { - return gd.ReadStringFromMemory(gd.moduleBaseAddressPtr+0x2587FB8, 0) + return gd.ReadStringFromMemory(gd.moduleBaseAddressPtr+0x256E668, 0) } func (gd *GameReader) LastGamePass() string { - return gd.ReadStringFromMemory(gd.moduleBaseAddressPtr+0x2588018, 0) + return gd.ReadStringFromMemory(gd.moduleBaseAddressPtr+0x256E6C8, 0) } func (gd *GameReader) FPS() int { From d4ef3b0308502a418242d4281054bf9a920fc8e0 Mon Sep 17 00:00:00 2001 From: guiyomu-dev <22749537+guiyomu-dev@users.noreply.github.com> Date: Fri, 17 Oct 2025 10:04:30 +0200 Subject: [PATCH 04/18] fix offset for terror zones --- pkg/memory/terrorzones.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/memory/terrorzones.go b/pkg/memory/terrorzones.go index e42e980..f5bcf6d 100644 --- a/pkg/memory/terrorzones.go +++ b/pkg/memory/terrorzones.go @@ -5,10 +5,10 @@ import ( ) func (gd *GameReader) TerrorZones() (areas []area.ID) { - tz := gd.moduleBaseAddressPtr + tzOnline + tzPtr := uintptr(gd.ReadUInt(gd.moduleBaseAddressPtr+tzOnline, Uint64)) for i := 0; i < 8; i++ { - tzArea := gd.ReadUInt(tz+uintptr(i*Uint32), Uint32) + tzArea := gd.ReadUInt(tzPtr+uintptr(i*Uint32), Uint32) if tzArea != 0 { areas = append(areas, area.ID(tzArea)) } From 5731cd16872a69b998889c06665d5c247d1622eb Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Fri, 17 Oct 2025 13:19:38 +0100 Subject: [PATCH 05/18] Add TZ online AOB scan --- pkg/memory/offset.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/memory/offset.go b/pkg/memory/offset.go index 9f5be86..9bf5ffc 100644 --- a/pkg/memory/offset.go +++ b/pkg/memory/offset.go @@ -17,6 +17,7 @@ type Offset struct { FPS uintptr KeyBindingsOffset uintptr KeyBindingsSkillsOffset uintptr + TZ uintptr } func calculateOffsets(process *Process) Offset { @@ -84,6 +85,11 @@ func calculateOffsets(process *Process) Offset { relativeOffset := int32(binary.LittleEndian.Uint32(bytes)) keyBindingsSkillsOffset = uintptr(int64(pattern) + 15 + int64(relativeOffset)) + // Terror Zones + pattern = process.FindPattern(memory, "\x48\x89\x05\xCC\xCC\xCC\xCC\x48\x8D\x05\xCC\xCC\xCC\xCC\x48\x89\x05\xCC\xCC\xCC\xCC\x48\x8D\x05\xCC\xCC\xCC\xCC\x48\x89\x15\xCC\xCC\xCC\xCC\x48\x89\x15", "xxx????xxx????xxx????xxx????xxx????xxx") + tzPtr := process.ReadUInt(pattern+3, Uint32) + tzOffset := pattern - process.moduleBaseAddressPtr + 7 + uintptr(tzPtr) + return Offset{ GameData: gameDataOffset, UnitTable: unitTableOffset, @@ -97,5 +103,6 @@ func calculateOffsets(process *Process) Offset { FPS: fpsOffset, KeyBindingsOffset: keyBindingsOffset, KeyBindingsSkillsOffset: keyBindingsSkillsOffset, + TZ: tzOffset, } } From aebef7b72136fb4612f43091595e50e85108d85e Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Fri, 17 Oct 2025 13:20:18 +0100 Subject: [PATCH 06/18] Replace hardcoded TZ offset with AOB scan --- pkg/memory/terrorzones.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/memory/terrorzones.go b/pkg/memory/terrorzones.go index f5bcf6d..a72ba9b 100644 --- a/pkg/memory/terrorzones.go +++ b/pkg/memory/terrorzones.go @@ -5,7 +5,7 @@ import ( ) func (gd *GameReader) TerrorZones() (areas []area.ID) { - tzPtr := uintptr(gd.ReadUInt(gd.moduleBaseAddressPtr+tzOnline, Uint64)) + tzPtr := uintptr(gd.ReadUInt(gd.moduleBaseAddressPtr+gd.offset.TZ, Uint64)) for i := 0; i < 8; i++ { tzArea := gd.ReadUInt(tzPtr+uintptr(i*Uint32), Uint32) From 1313a1747b3d0b28a448e859208f3ee29bc82fbd Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Fri, 17 Oct 2025 13:20:43 +0100 Subject: [PATCH 07/18] Remove hardcoded TZ offset --- pkg/memory/addresses.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/memory/addresses.go b/pkg/memory/addresses.go index 1b95015..eaca023 100644 --- a/pkg/memory/addresses.go +++ b/pkg/memory/addresses.go @@ -2,5 +2,4 @@ package memory const ( tzOffline = 0x29B3208 - tzOnline = 0x29B3188 ) From 56601ab9ce44a03b18ef587a3fc12c853ff845cf Mon Sep 17 00:00:00 2001 From: guiyomu-dev <22749537+guiyomu-dev@users.noreply.github.com> Date: Fri, 17 Oct 2025 17:49:36 +0200 Subject: [PATCH 08/18] keep only actual tz zones --- pkg/memory/terrorzones.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/memory/terrorzones.go b/pkg/memory/terrorzones.go index f5bcf6d..4023857 100644 --- a/pkg/memory/terrorzones.go +++ b/pkg/memory/terrorzones.go @@ -5,10 +5,12 @@ import ( ) func (gd *GameReader) TerrorZones() (areas []area.ID) { - tzPtr := uintptr(gd.ReadUInt(gd.moduleBaseAddressPtr+tzOnline, Uint64)) + structPtr := gd.moduleBaseAddressPtr + tzOnline + zonesPtr := uintptr(gd.ReadUInt(structPtr, Uint64)) + actualActiveZoneCount := int(gd.ReadUInt(structPtr+0x8, Uint8)) - for i := 0; i < 8; i++ { - tzArea := gd.ReadUInt(tzPtr+uintptr(i*Uint32), Uint32) + for i := 0; i < actualActiveZoneCount; i++ { + tzArea := gd.ReadUInt(zonesPtr+uintptr(i*Uint32), Uint32) if tzArea != 0 { areas = append(areas, area.ID(tzArea)) } From ce23058fb473216aa0625829f302ae7fc5827cbf Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Fri, 17 Oct 2025 14:37:36 +0100 Subject: [PATCH 09/18] Add quests AOB Resolves to originally used offset (0x22D8369) --- pkg/memory/offset.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/memory/offset.go b/pkg/memory/offset.go index 9f5be86..407473e 100644 --- a/pkg/memory/offset.go +++ b/pkg/memory/offset.go @@ -17,6 +17,7 @@ type Offset struct { FPS uintptr KeyBindingsOffset uintptr KeyBindingsSkillsOffset uintptr + Quests uintptr } func calculateOffsets(process *Process) Offset { @@ -84,6 +85,12 @@ func calculateOffsets(process *Process) Offset { relativeOffset := int32(binary.LittleEndian.Uint32(bytes)) keyBindingsSkillsOffset = uintptr(int64(pattern) + 15 + int64(relativeOffset)) + // Quest Bytes Data + pattern = process.FindPattern(memory, "\x42\xc6\x84\x28\x00\x00\x00\x00\x00\x49\xff\xc5\x49\x83\xfd\x29", "xxxx?????xxxxxxx") + bytes = process.ReadBytesFromMemory(pattern+4, 4) + questOffset := uintptr(binary.LittleEndian.Uint32(bytes)) + questDataOffset := questOffset + 1 + return Offset{ GameData: gameDataOffset, UnitTable: unitTableOffset, @@ -97,5 +104,6 @@ func calculateOffsets(process *Process) Offset { FPS: fpsOffset, KeyBindingsOffset: keyBindingsOffset, KeyBindingsSkillsOffset: keyBindingsSkillsOffset, + Quests: questDataOffset, } } From 06a59974acebe40d0c76067b98d566abf7dfd3be Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Fri, 17 Oct 2025 14:38:07 +0100 Subject: [PATCH 10/18] Use AOB scan for quests instead of hardcoded offset --- pkg/memory/game_reader.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/memory/game_reader.go b/pkg/memory/game_reader.go index 694caf2..9679c44 100644 --- a/pkg/memory/game_reader.go +++ b/pkg/memory/game_reader.go @@ -97,7 +97,7 @@ func (gd *GameReader) GetData() data.Data { // q1 := uintptr(gd.Process.ReadUInt(gd.moduleBaseAddressPtr+0x22E2978, Uint64)) // q2 := uintptr(gd.Process.ReadUInt(q1, Uint64)) // q2 := uintptr(gd.Process.ReadUInt(gd.moduleBaseAddressPtr+0x22F1E79, Uint64)) - gameQuestsBytes := gd.Process.ReadBytesFromMemory(gd.moduleBaseAddressPtr+0x22D8369, 85) + gameQuestsBytes := gd.Process.ReadBytesFromMemory(gd.moduleBaseAddressPtr+gd.offset.Quests, 85) // gameQuestsBytes = gameQuestsBytes[3:] d := data.Data{ From bd10a7f70622e68aa1bf523a84976ca84d42ec24 Mon Sep 17 00:00:00 2001 From: guiyomu-dev <22749537+guiyomu-dev@users.noreply.github.com> Date: Sat, 18 Oct 2025 10:40:29 +0200 Subject: [PATCH 11/18] add pattern for keybinding --- pkg/memory/offset.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/memory/offset.go b/pkg/memory/offset.go index c94bb3a..60268c3 100644 --- a/pkg/memory/offset.go +++ b/pkg/memory/offset.go @@ -76,14 +76,16 @@ func calculateOffsets(process *Process) Offset { fpsOffset := pattern - process.moduleBaseAddressPtr + 6 + fpsOffsetPtr // Keybindings - pattern = process.FindPattern(memory, "\x00\xA8\x00\x00\x00\x00\x7F\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x0F\x00\x00\x00\x00\x00\x00\x80\x4C\x6F\x00\x00\x79\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x52", "xx????x?xx????xxxxxxxxxxxxx??x?xxxxxxxxxxx") - keyBindingsOffset := pattern + 0x65 + pattern = process.FindPattern(memory, "\x48\x8D\x05\xAF\xEE", "xxxxx") + bytes = process.ReadBytesFromMemory(pattern+3, 4) + relativeOffset := int32(binary.LittleEndian.Uint32(bytes)) + keyBindingsOffset := pattern - process.moduleBaseAddressPtr + 7 + uintptr(relativeOffset) // KeyBindings Skills pattern = process.FindPattern(memory, "\x0F\x10\x04\x24\x48\x6B\xC8\x1C\x48\x8D\x05", "xxxxxxxxxxx") var keyBindingsSkillsOffset uintptr bytes = process.ReadBytesFromMemory(pattern+11, 4) - relativeOffset := int32(binary.LittleEndian.Uint32(bytes)) + relativeOffset = int32(binary.LittleEndian.Uint32(bytes)) keyBindingsSkillsOffset = uintptr(int64(pattern) + 15 + int64(relativeOffset)) // Terror Zones From e882b40af472610e939a302e2e8b15fca578c3db Mon Sep 17 00:00:00 2001 From: guiyomu-dev <22749537+guiyomu-dev@users.noreply.github.com> Date: Sat, 18 Oct 2025 10:49:41 +0200 Subject: [PATCH 12/18] update offset --- pkg/memory/keybindings.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/memory/keybindings.go b/pkg/memory/keybindings.go index 3ae5124..9359a35 100644 --- a/pkg/memory/keybindings.go +++ b/pkg/memory/keybindings.go @@ -8,7 +8,7 @@ import ( ) func (gd *GameReader) GetKeyBindings() data.KeyBindings { - blob := gd.ReadBytesFromMemory(gd.moduleBaseAddressPtr+0x1DE5C24, 0x500) + blob := gd.ReadBytesFromMemory(gd.moduleBaseAddressPtr+gd.offset.KeyBindingsOffset, 0x500) blobSkills := gd.ReadBytesFromMemory(gd.offset.KeyBindingsSkillsOffset, 0x500) skillsKB := [16]data.SkillBinding{} From 923f44d46a9d2f7c52a1a4c548f2e44accf2da21 Mon Sep 17 00:00:00 2001 From: adpist Date: Sat, 18 Oct 2025 13:36:39 +0200 Subject: [PATCH 13/18] Do not erase learned skill by a skill with charges --- pkg/memory/player.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/pkg/memory/player.go b/pkg/memory/player.go index d2267fe..16d1b9f 100644 --- a/pkg/memory/player.go +++ b/pkg/memory/player.go @@ -133,10 +133,20 @@ func (gd *GameReader) getSkills(skillListPtr uintptr) map[skill.ID]skill.Points quantity := gd.Process.ReadUInt(skillPtr+0x40, Uint16) charges := gd.Process.ReadUInt(skillPtr+0x48, Uint16) - skills[skill.ID(skillTxt)] = skill.Points{ - Level: lvl, - Quantity: quantity, - Charges: charges, + shouldSetSkill := true + existingSkill, exists := skills[skill.ID(skillTxt)] + if exists { + if existingSkill.Charges == 0 && charges > 0 { + shouldSetSkill = false + } + } + + if shouldSetSkill { + skills[skill.ID(skillTxt)] = skill.Points{ + Level: lvl, + Quantity: quantity, + Charges: charges, + } } skillPtr = uintptr(gd.Process.ReadUInt(skillPtr+0x08, Uint64)) From e5a60b63dde0fb1177adcc2260cf42eb8e61105c Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Sat, 18 Oct 2025 23:03:15 +0100 Subject: [PATCH 14/18] Add ping AOB scan --- pkg/memory/offset.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/memory/offset.go b/pkg/memory/offset.go index 60268c3..fdd15f3 100644 --- a/pkg/memory/offset.go +++ b/pkg/memory/offset.go @@ -19,6 +19,7 @@ type Offset struct { KeyBindingsSkillsOffset uintptr TZ uintptr Quests uintptr + Ping uintptr } func calculateOffsets(process *Process) Offset { @@ -99,6 +100,12 @@ func calculateOffsets(process *Process) Offset { questOffset := uintptr(binary.LittleEndian.Uint32(bytes)) questDataOffset := questOffset + 1 + // Ping + pattern = process.FindPattern(memory, "\x48\x8B\x0D\xCC\xCC\xCC\xCC\x49\x2B\xC7", "xxx????xxx") + bytes = process.ReadBytesFromMemory(pattern+3, 4) + relativeOffset = int32(binary.LittleEndian.Uint32(bytes)) + pingOffset := pattern - process.moduleBaseAddressPtr + 7 + uintptr(relativeOffset) + return Offset{ GameData: gameDataOffset, UnitTable: unitTableOffset, @@ -114,5 +121,6 @@ func calculateOffsets(process *Process) Offset { KeyBindingsSkillsOffset: keyBindingsSkillsOffset, TZ: tzOffset, Quests: questDataOffset, + Ping: pingOffset, } } From fafcbc8728be1bcb55868f5cbed40d9ca1fcc21b Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Sat, 18 Oct 2025 23:03:47 +0100 Subject: [PATCH 15/18] Add ping to game_reader --- pkg/memory/game_reader.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/memory/game_reader.go b/pkg/memory/game_reader.go index 9679c44..500cb7b 100644 --- a/pkg/memory/game_reader.go +++ b/pkg/memory/game_reader.go @@ -111,6 +111,7 @@ func (gd *GameReader) GetData() data.Data { LastGameName: gd.LastGameName(), LastGamePassword: gd.LastGamePass(), FPS: gd.FPS(), + Ping: gd.Ping(), }, Monsters: monsters, Corpses: gd.Corpses(pu.Position, hover), @@ -441,6 +442,12 @@ func (gd *GameReader) FPS() int { return int(gd.ReadUInt(gd.moduleBaseAddressPtr+gd.offset.FPS, Uint32)) } +func (gd *GameReader) Ping() int { + ptrToStructPtr := gd.moduleBaseAddressPtr + gd.offset.Ping + structPtrAddr := gd.ReadUInt(ptrToStructPtr, Uint64) + return int(gd.ReadUInt(uintptr(structPtrAddr+36), Uint32)) +} + func (gd *GameReader) HasMerc() bool { return gd.ReadUInt(gd.Process.moduleBaseAddressPtr+gd.offset.UI+0x8, Uint8) != 0 } From 28d41070ce7c5e4d0069071652e2d529f8008317 Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Sat, 18 Oct 2025 23:03:59 +0100 Subject: [PATCH 16/18] Add ping to OnlineGame --- pkg/data/data.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/data/data.go b/pkg/data/data.go index 203fc7c..dc6f832 100644 --- a/pkg/data/data.go +++ b/pkg/data/data.go @@ -66,6 +66,7 @@ type OnlineGame struct { LastGameName string LastGamePassword string FPS int + Ping int } type Panel struct { From d7b909977866b2f4c102a99f03b5a16feecf1aa0 Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Sat, 18 Oct 2025 21:42:45 +0100 Subject: [PATCH 17/18] Add legacy graphics AOB scan --- pkg/memory/offset.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/memory/offset.go b/pkg/memory/offset.go index 60268c3..56820ba 100644 --- a/pkg/memory/offset.go +++ b/pkg/memory/offset.go @@ -19,6 +19,7 @@ type Offset struct { KeyBindingsSkillsOffset uintptr TZ uintptr Quests uintptr + LegacyGraphics uintptr } func calculateOffsets(process *Process) Offset { @@ -99,6 +100,11 @@ func calculateOffsets(process *Process) Offset { questOffset := uintptr(binary.LittleEndian.Uint32(bytes)) questDataOffset := questOffset + 1 + // LegacyGraphics + pattern = process.FindPattern(memory, "\x80\x3D\x00\x00\x00\x00\x00\x48\x8D\x54\x24\x30", "xx?????xxxxx") + legacyGfxPtr := uintptr(process.ReadUInt(pattern+2, Uint32)) + legacyGfxOffset := pattern - process.moduleBaseAddressPtr + 7 + legacyGfxPtr + return Offset{ GameData: gameDataOffset, UnitTable: unitTableOffset, @@ -114,5 +120,6 @@ func calculateOffsets(process *Process) Offset { KeyBindingsSkillsOffset: keyBindingsSkillsOffset, TZ: tzOffset, Quests: questDataOffset, + LegacyGraphics: legacyGfxOffset, } } From 53b61d0d55d494dba065f21ad15865d6dfef9fdb Mon Sep 17 00:00:00 2001 From: CarlPoppa Date: Sat, 18 Oct 2025 21:43:10 +0100 Subject: [PATCH 18/18] Use legacy graphics AOB scan in game_reader --- pkg/memory/game_reader.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/memory/game_reader.go b/pkg/memory/game_reader.go index 9679c44..aa2ee5b 100644 --- a/pkg/memory/game_reader.go +++ b/pkg/memory/game_reader.go @@ -314,7 +314,7 @@ func (gd *GameReader) GetSelectedCharacterName() string { } func (gd *GameReader) LegacyGraphics() bool { - return gd.ReadUInt(gd.Process.moduleBaseAddressPtr+0x22D845F, Uint8) != 0 + return gd.ReadUInt(gd.Process.moduleBaseAddressPtr+gd.offset.LegacyGraphics, Uint8) != 0 } func (gd *GameReader) IsOnline() bool {