9 Commits

Author SHA1 Message Date
bel
50e89492cf todo 2023-03-25 09:12:44 -06:00
bel
3d9ea1296c external test on player transformation 2023-03-25 09:12:10 -06:00
bel
db69f76aa0 unit tests are good and v01cfg transforms input if players and user in players 2023-03-25 09:06:43 -06:00
bel
0ee3a8b6e8 todo 2023-03-25 00:44:30 -06:00
bel
b379f1d82c sample cfg file 2023-03-25 00:43:51 -06:00
bel
c83f9d8700 load v01 config 2023-03-25 00:30:13 -06:00
bel
6289222b69 todo 2023-03-25 00:13:22 -06:00
bel
607a65e22e if debugging then print lag to stderr 2023-03-25 00:11:12 -06:00
bel
6bbb297c59 todo 2023-03-25 00:06:32 -06:00
7 changed files with 198 additions and 24 deletions

1
go.mod
View File

@@ -5,4 +5,5 @@ go 1.19
require ( require (
github.com/go-yaml/yaml v2.1.0+incompatible // indirect github.com/go-yaml/yaml v2.1.0+incompatible // indirect
github.com/micmonay/keybd_event v1.1.1 // indirect github.com/micmonay/keybd_event v1.1.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
) )

3
go.sum
View File

@@ -2,3 +2,6 @@ github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwn
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
github.com/micmonay/keybd_event v1.1.1 h1:rv7omwXWYL9Lgf3PUq6uBgJI2k1yGkL/GD6dxc6nmSs= github.com/micmonay/keybd_event v1.1.1 h1:rv7omwXWYL9Lgf3PUq6uBgJI2k1yGkL/GD6dxc6nmSs=
github.com/micmonay/keybd_event v1.1.1/go.mod h1:CGMWMDNgsfPljzrAWoybUOSKafQPZpv+rLigt2LzNGI= github.com/micmonay/keybd_event v1.1.1/go.mod h1:CGMWMDNgsfPljzrAWoybUOSKafQPZpv+rLigt2LzNGI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

View File

@@ -0,0 +1,16 @@
users:
bel:
player: 0
message: "hi"
players:
- buttons:
up: "w"
down: "s"
left: "a"
right: "d"
l: "q"
r: "e"
a: "1"
b: "2"
x: "3"
y: "4"

View File

@@ -2,9 +2,13 @@ package button
import ( import (
"encoding/json" "encoding/json"
"io/ioutil"
"log" "log"
"mayhem-party/src/device/input/raw" "mayhem-party/src/device/input/raw"
"os" "os"
"time"
"gopkg.in/yaml.v2"
) )
var debugging = os.Getenv("DEBUG") == "true" var debugging = os.Getenv("DEBUG") == "true"
@@ -12,6 +16,7 @@ var debugging = os.Getenv("DEBUG") == "true"
type ( type (
V01 struct { V01 struct {
src raw.Raw src raw.Raw
cfg v01Cfg
} }
v01Msg struct { v01Msg struct {
T int64 T int64
@@ -19,11 +24,25 @@ type (
Y string Y string
N string N string
} }
v01Cfg struct {
Users map[string]struct {
Player int
Message string
}
Players []struct {
Transformation v01Transformation
}
}
v01Transformation map[string]string
) )
func NewV01(src raw.Raw) V01 { func NewV01(src raw.Raw) V01 {
var cfg v01Cfg
b, _ := ioutil.ReadFile(os.Getenv("BUTTON_PARSER_V01_CONFIG"))
yaml.Unmarshal(b, &cfg)
return V01{ return V01{
src: src, src: src,
cfg: cfg,
} }
} }
@@ -37,7 +56,40 @@ func (v01 V01) Read() []Button {
if err := json.Unmarshal(line, &msg); err != nil { if err := json.Unmarshal(line, &msg); err != nil {
log.Printf("%v: %s", err, line) log.Printf("%v: %s", err, line)
} }
return msg.buttons() v01.telemetry(msg)
return v01.cfg.transform(msg).buttons()
}
func (cfg v01Cfg) transform(msg v01Msg) v01Msg {
if len(cfg.Players) == 0 {
return msg
}
user := cfg.Users[msg.U]
if user.Player < 1 {
msg.Y = ""
msg.N = ""
return msg
}
player := cfg.Players[user.Player-1]
msg.Y = player.Transformation.pipe(msg.Y)
msg.N = player.Transformation.pipe(msg.N)
return msg
}
func (t v01Transformation) pipe(s string) string {
for i := range s {
if v := t[s[i:i+1]]; v != "" {
s = s[:i] + v[:1] + s[i+1:]
}
}
return s
}
func (v01 V01) telemetry(msg v01Msg) {
if debugging {
log.Printf("%s|%dms", msg.U, time.Now().UnixNano()/int64(time.Millisecond)-msg.T)
}
} }
func (msg v01Msg) buttons() []Button { func (msg v01Msg) buttons() []Button {

View File

@@ -0,0 +1,71 @@
package button_test
import (
"fmt"
"mayhem-party/src/device/input/button"
"os"
"path"
"testing"
"time"
)
func TestV01(t *testing.T) {
src := constSrc(fmt.Sprintf(`{"T":%v,"U":"bel","Y":"abc","N":"cde"}`, time.Now().UnixNano()/int64(time.Millisecond)-50))
t.Logf("(%v) %s", len(src), src.Read())
v01 := button.NewV01(src)
got := v01.Read()
want := []button.Button{
{Down: true, Char: 'a'},
{Down: true, Char: 'b'},
{Down: true, Char: 'c'},
{Down: false, Char: 'c'},
{Down: false, Char: 'd'},
{Down: false, Char: 'e'},
}
if len(got) != len(want) {
t.Fatal(len(want), len(got))
}
for i := range got {
if got[i] != want[i] {
t.Errorf("[%d] want %+v got %+v", i, want[i], got[i])
}
}
}
func TestV01WithCfg(t *testing.T) {
d := t.TempDir()
p := path.Join(d, "cfg.yaml")
os.WriteFile(p, []byte(`
users:
bel:
player: 2
players:
- transformation:
w: t
- transformation:
w: i
`), os.ModePerm)
os.Setenv("BUTTON_PARSER_V01_CONFIG", p)
t.Run("unknown user ignored", func(t *testing.T) {
v01 := button.NewV01(constSrc(`{"U":"qt","Y":"w"}`))
got := v01.Read()
if len(got) != 0 {
t.Error(got)
}
})
t.Run("player2", func(t *testing.T) {
v01 := button.NewV01(constSrc(`{"U":"bel","Y":"w","N":"w"}`))
got := v01.Read()
if len(got) != 2 {
t.Error(got)
}
if got[0] != (button.Button{Char: 'i', Down: true}) {
t.Error(got[0])
}
if got[1] != (button.Button{Char: 'i', Down: false}) {
t.Error(got[1])
}
})
}

View File

@@ -1,29 +1,51 @@
package button_test package button
import ( import (
"mayhem-party/src/device/input/button"
"testing" "testing"
) )
func TestV01(t *testing.T) { func TestV01TransformationPipe(t *testing.T) {
src := constSrc(`{"T":1,"U":"bel","Y":"abc","N":"cde"}`) cases := map[string]struct {
t.Logf("(%v) %s", len(src), src.Read()) input string
v01 := button.NewV01(src) xform map[string]string
got := v01.Read() want string
want := []button.Button{ }{
{Down: true, Char: 'a'}, "empty input": {
{Down: true, Char: 'b'}, xform: map[string]string{"a": "bc"},
{Down: true, Char: 'c'}, },
{Down: false, Char: 'c'}, "empty xform": {
{Down: false, Char: 'd'}, input: "aa",
{Down: false, Char: 'e'}, want: "aa",
},
"all": {
input: "aa",
xform: map[string]string{"a": "cc"},
want: "cc",
},
"last": {
input: "ba",
xform: map[string]string{"a": "cc"},
want: "bc",
},
"first": {
input: "ab",
xform: map[string]string{"a": "cc"},
want: "cb",
},
"noop": {
input: "bb",
xform: map[string]string{"a": "bc"},
want: "bb",
},
} }
if len(got) != len(want) {
t.Fatal(len(want), len(got)) for name, d := range cases {
} c := d
for i := range got { t.Run(name, func(t *testing.T) {
if got[i] != want[i] { got := v01Transformation(c.xform).pipe(c.input)
t.Errorf("[%d] want %+v got %+v", i, want[i], got[i]) if got != c.want {
} t.Errorf("%+v(%s) want %s got %s", c.xform, c.input, c.want, got)
}
})
} }
} }

View File

@@ -1,6 +1,5 @@
todo: todo:
- change from 'a','b','c' from rust to just 11,21,31,41 so playerName is known implicitly - send clients messages to display
- lag via UDP formatted inputs as space-delimited TS PID buttonIdx buttonIdx buttonIdx
- input.MayhemParty as a logical wrapper from mod10 but then gotta translate back - input.MayhemParty as a logical wrapper from mod10 but then gotta translate back
to char for keyboard things somewhere; space delimited? to char for keyboard things somewhere; space delimited?
- todo: rusty configs have "name" for each client - todo: rusty configs have "name" for each client
@@ -42,3 +41,13 @@ done:
- todo: input.MayhemParty as a logical wrapper from %10 but then gotta translate back - todo: input.MayhemParty as a logical wrapper from %10 but then gotta translate back
to char for keyboard things somewhere; space delimited? to char for keyboard things somewhere; space delimited?
ts: Fri Mar 24 21:16:39 MDT 2023 ts: Fri Mar 24 21:16:39 MDT 2023
- todo: change from 'a','b','c' from rust to just 11,21,31,41 so playerName is known
implicitly
ts: Sat Mar 25 00:06:21 MDT 2023
- todo: lag via UDP formatted inputs as space-delimited TS PID buttonIdx buttonIdx
buttonIdx
ts: Sat Mar 25 00:13:19 MDT 2023
- todo: map keys triggered by user to player idx and their keys
ts: Sat Mar 25 00:44:19 MDT 2023
- todo: use button.V01Cfg; map keys triggered by user to player idx and their keys
ts: Sat Mar 25 09:12:43 MDT 2023