mayhem-party/src/device/input/parse/v01/v01.go

126 lines
2.2 KiB
Go

package v01
import (
"context"
"encoding/json"
"io/ioutil"
"log"
"mayhem-party/src/device/input/button"
"mayhem-party/src/device/input/raw"
"os"
"sync"
"time"
"gopkg.in/yaml.v2"
)
var (
FlagDebug = os.Getenv("DEBUG") == "true"
FlagParseV01Config = os.Getenv("V01_CONFIG")
)
type (
V01 struct {
ctx context.Context
can context.CancelFunc
src raw.Raw
cfg config
telemetryc chan message
}
)
func NewV01(ctx context.Context, src raw.Raw) *V01 {
var cfg config
cfg.lock = &sync.Mutex{}
b, _ := ioutil.ReadFile(FlagParseV01Config)
yaml.Unmarshal(b, &cfg)
ctx, can := context.WithCancel(ctx)
result := &V01{
ctx: ctx,
can: can,
src: src,
cfg: cfg,
telemetryc: make(chan message),
}
go result.listen()
go result.dotelemetry()
return result
}
func (v01 *V01) CloseWrap() raw.Raw {
v01.can()
return v01.src
}
func (v01 *V01) Close() {
v01.can()
v01.src.Close()
}
func (v01 *V01) Read() []button.Button {
line := v01.src.Read()
var msg message
if err := json.Unmarshal(line, &msg); err != nil {
log.Printf("%v: %s", err, line)
}
v01.telemetry(msg)
buttons := v01.transform(msg).buttons()
if v01.cfg.Quiet {
for i := range buttons {
buttons[i].Down = false
}
}
return buttons
}
func (v01 *V01) dotelemetry() {
for {
select {
case <-v01.ctx.Done():
return
case msg := <-v01.telemetryc:
v01._telemetry(msg)
}
}
}
func (v01 *V01) telemetry(msg message) {
select {
case v01.telemetryc <- msg:
default:
}
}
func (v01 *V01) _telemetry(msg message) {
// TODO oof
v01.cfg.lock.Lock()
defer v01.cfg.lock.Unlock()
if v01.cfg.Users == nil {
v01.cfg.Users = map[string]configUser{}
}
u := v01.cfg.Users[msg.U]
u.Meta.LastLag = time.Now().UnixNano()/int64(time.Millisecond) - msg.T
u.Meta.LastTSMS = msg.T
if FlagDebug {
log.Printf("%s|%dms", msg.U, u.Meta.LastLag)
}
v01.cfg.Users[msg.U] = u
}
func (v01 *V01) transform(msg message) message {
if len(v01.cfg.Players) == 0 {
return msg
}
user := v01.cfg.Users[msg.U]
if user.State.Player < 1 {
msg.Y = ""
msg.N = ""
return msg
}
player := v01.cfg.Players[user.State.Player-1]
msg.Y = player.Transformation.pipe(msg.Y)
msg.N = player.Transformation.pipe(msg.N)
return msg
}