Add modular capture backends, resolution profiles, Wayland support

This commit is contained in:
Hoid 2026-02-14 10:00:19 +00:00
parent 3b363192f2
commit 80ba9b1b90
16 changed files with 2266 additions and 45 deletions

View file

@ -1,20 +1,11 @@
// D2R-specific configuration: screen regions, colors, timings.
// D2R-specific configuration: colors, timings, and resolution profiles.
package d2r
import "image"
import (
"image"
// ScreenRegions defines UI element positions at 1920x1080.
type ScreenRegions struct {
HealthOrb image.Rectangle
ManaOrb image.Rectangle
XPBar image.Rectangle
Belt image.Rectangle
Minimap image.Rectangle
Inventory image.Rectangle
Stash image.Rectangle
SkillLeft image.Rectangle
SkillRight image.Rectangle
}
"git.cloonar.com/openclawd/iso-bot/pkg/engine/resolution"
)
// HSVRange defines a color range in HSV space.
type HSVRange struct {
@ -44,10 +35,8 @@ type Timings struct {
// Config holds all D2R-specific configuration.
type Config struct {
Resolution image.Point
Regions ScreenRegions
Colors Colors
Timings Timings
Colors Colors
Timings Timings
// Loot settings
PickupUniques bool
@ -63,21 +52,9 @@ type Config struct {
ChickenThreshold float64 // exit game if health below this
}
// DefaultConfig returns the default D2R config for 1920x1080.
// DefaultConfig returns the default D2R configuration.
func DefaultConfig() Config {
return Config{
Resolution: image.Point{X: 1920, Y: 1080},
Regions: ScreenRegions{
HealthOrb: image.Rect(28, 545, 198, 715),
ManaOrb: image.Rect(1722, 545, 1892, 715),
XPBar: image.Rect(0, 1058, 1920, 1080),
Belt: image.Rect(838, 1010, 1082, 1058),
Minimap: image.Rect(1600, 0, 1920, 320),
Inventory: image.Rect(960, 330, 1490, 770),
Stash: image.Rect(430, 330, 960, 770),
SkillLeft: image.Rect(194, 1036, 246, 1088),
SkillRight: image.Rect(1674, 1036, 1726, 1088),
},
Colors: Colors{
HealthFilled: HSVRange{0, 100, 100, 10, 255, 255},
ManaFilled: HSVRange{100, 100, 100, 130, 255, 255},
@ -105,3 +82,45 @@ func DefaultConfig() Config {
ChickenThreshold: 0.2,
}
}
// RegisterProfiles registers D2R resolution profiles with the resolution registry.
func RegisterProfiles(registry *resolution.Registry) error {
profiles := []*resolution.Profile{
// 1920x1080 (1080p) - Primary resolution
{
Width: 1920,
Height: 1080,
Label: "1080p",
Regions: map[string]image.Rectangle{
"health_orb": image.Rect(28, 545, 198, 715),
"mana_orb": image.Rect(1722, 545, 1892, 715),
"xp_bar": image.Rect(0, 1058, 1920, 1080),
"belt": image.Rect(838, 1010, 1082, 1058),
"minimap": image.Rect(1600, 0, 1920, 320),
"inventory": image.Rect(960, 330, 1490, 770),
"stash": image.Rect(430, 330, 960, 770),
"skill_left": image.Rect(194, 1036, 246, 1088),
"skill_right": image.Rect(1674, 1036, 1726, 1088),
},
},
// 1280x720 (720p) - Secondary resolution
{
Width: 1280,
Height: 720,
Label: "720p",
Regions: map[string]image.Rectangle{
"health_orb": image.Rect(19, 363, 132, 477),
"mana_orb": image.Rect(1148, 363, 1261, 477),
"xp_bar": image.Rect(0, 705, 1280, 720),
"belt": image.Rect(559, 673, 721, 705),
"minimap": image.Rect(1067, 0, 1280, 213),
"inventory": image.Rect(640, 220, 993, 513),
"stash": image.Rect(287, 220, 640, 513),
"skill_left": image.Rect(129, 691, 164, 726),
"skill_right": image.Rect(1116, 691, 1151, 726),
},
},
}
return registry.RegisterMultiple("d2r", profiles)
}

View file

@ -9,12 +9,16 @@ import (
// Detector implements plugin.GameDetector for D2R.
type Detector struct {
config Config
config Config
services plugin.EngineServices
}
// NewDetector creates a D2R state detector.
func NewDetector(config Config) *Detector {
return &Detector{config: config}
func NewDetector(config Config, services plugin.EngineServices) *Detector {
return &Detector{
config: config,
services: services,
}
}
// DetectState analyzes a screenshot and returns the current game state.
@ -48,6 +52,13 @@ func (d *Detector) DetectState(frame image.Image) plugin.GameState {
// ReadVitals reads health and mana from the orbs.
func (d *Detector) ReadVitals(frame image.Image) plugin.VitalStats {
// TODO: Analyze health/mana orb regions using color detection
// Get region coordinates from the engine services
healthRegion := d.services.Region("health_orb")
manaRegion := d.services.Region("mana_orb")
_ = healthRegion // Use these regions for color analysis
_ = manaRegion
return plugin.VitalStats{}
}

View file

@ -2,23 +2,27 @@
package d2r
import (
"fmt"
"image"
"git.cloonar.com/openclawd/iso-bot/pkg/plugin"
"git.cloonar.com/openclawd/iso-bot/pkg/engine/resolution"
)
// Plugin implements plugin.Plugin for D2R.
type Plugin struct {
config Config
services plugin.EngineServices
detector *Detector
reader *Reader
config Config
services plugin.EngineServices
detector *Detector
reader *Reader
resolutionRegistry *resolution.Registry
}
// New creates a new D2R plugin with default config.
func New() *Plugin {
return &Plugin{
config: DefaultConfig(),
resolutionRegistry: resolution.NewRegistry(),
}
}
@ -36,8 +40,14 @@ func (p *Plugin) Info() plugin.PluginInfo {
// Init initializes the plugin with engine services.
func (p *Plugin) Init(services plugin.EngineServices) error {
p.services = services
p.detector = NewDetector(p.config)
p.reader = NewReader(p.config)
// Register D2R resolution profiles
if err := RegisterProfiles(p.resolutionRegistry); err != nil {
return fmt.Errorf("failed to register D2R profiles: %w", err)
}
p.detector = NewDetector(p.config, services)
p.reader = NewReader(p.config, services)
return nil
}
@ -63,3 +73,8 @@ func (p *Plugin) DefaultLootFilter() plugin.LootFilter {
// TODO: Return default rule engine
return nil
}
// SupportedResolutions returns resolutions available for D2R.
func (p *Plugin) SupportedResolutions() []image.Point {
return p.resolutionRegistry.SupportedResolutions("d2r")
}

View file

@ -9,12 +9,16 @@ import (
// Reader implements plugin.ScreenReader for D2R.
type Reader struct {
config Config
config Config
services plugin.EngineServices
}
// NewReader creates a D2R screen reader.
func NewReader(config Config) *Reader {
return &Reader{config: config}
func NewReader(config Config, services plugin.EngineServices) *Reader {
return &Reader{
config: config,
services: services,
}
}
// FindItems detects item labels on the ground.