89 lines
1.9 KiB
Go
89 lines
1.9 KiB
Go
package itemwatcher
|
|
|
|
import (
|
|
"context"
|
|
"github.com/faiface/beep"
|
|
"github.com/faiface/beep/speaker"
|
|
"github.com/faiface/beep/wav"
|
|
"github.com/hectorgimenez/d2go/pkg/itemfilter"
|
|
"github.com/hectorgimenez/d2go/pkg/memory"
|
|
"github.com/hectorgimenez/d2go/pkg/nip"
|
|
"log"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
type Watcher struct {
|
|
gr *memory.GameReader
|
|
rules []nip.Rule
|
|
alreadyNotifiedItemIDs map[int]interface{}
|
|
}
|
|
|
|
func NewWatcher(gr *memory.GameReader, rules []nip.Rule) *Watcher {
|
|
return &Watcher{gr: gr, rules: rules}
|
|
}
|
|
|
|
func (w *Watcher) Start(ctx context.Context) error {
|
|
w.alreadyNotifiedItemIDs = make(map[int]interface{}, 0)
|
|
audioBuffer, err := initAudio()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil
|
|
default:
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
d := w.gr.GetData()
|
|
for _, i := range d.Items.Ground {
|
|
if !itemfilter.Evaluate(i, w.rules) {
|
|
continue
|
|
}
|
|
|
|
if _, found := w.alreadyNotifiedItemIDs[int(i.UnitID)]; found {
|
|
continue
|
|
}
|
|
|
|
log.Printf("%s: Item detected: %s. Quality: %s", time.Now().Format(time.RFC3339), i.Name, i.Quality.ToString())
|
|
|
|
w.alreadyNotifiedItemIDs[int(i.UnitID)] = nil
|
|
speaker.Play(audioBuffer.Streamer(0, audioBuffer.Len()))
|
|
}
|
|
|
|
// Cleanup the already notified list when item is out of range
|
|
for k := range w.alreadyNotifiedItemIDs {
|
|
found := false
|
|
for _, i := range d.Items.Ground {
|
|
if int(i.UnitID) == k {
|
|
found = true
|
|
}
|
|
}
|
|
if !found {
|
|
delete(w.alreadyNotifiedItemIDs, k)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func initAudio() (*beep.Buffer, error) {
|
|
f, err := os.Open("assets/ching.wav")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
streamer, format, err := wav.Decode(f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
|
|
buffer := beep.NewBuffer(format)
|
|
buffer.Append(streamer)
|
|
streamer.Close()
|
|
|
|
return buffer, nil
|
|
}
|