/
net.go
119 lines (97 loc) · 1.94 KB
/
net.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package main
import (
"crypto/rand"
"fmt"
"math/big"
"net"
"sync"
"github.com/fxamacker/cbor/v2"
log "github.com/sirupsen/logrus"
)
type Net struct {
config *Config
id string
peer *net.UDPAddr
peerMutex sync.Mutex
announceEnabled bool
announcePort int
LastState *Game
}
type Announce struct {
ID string
Port int
}
type State struct {
ID string
Game *Game
}
type Diff map[int]byte
func (msg State) String() string {
return fmt.Sprintf("{%v, Ball: {%v, %v}, Paddle1: {%v}, Paddle2: {%v}}", msg.ID, msg.Game.Ball.X, msg.Game.Ball.Y, msg.Game.Paddle1.Y, msg.Game.Paddle2.Y)
}
// diff returns the changed bytes in inc compared to base as map of byte index
// to changed byte value
func diff(base, inc []byte) *Diff {
i := 0
m := make(Diff)
for ; i < len(base) && i < len(inc); i++ {
if base[i] != inc[i] {
m[i] = inc[i]
}
}
if i < len(inc) {
for ; i < len(inc); i++ {
m[i] = inc[i]
}
}
return &m
}
func patch(base []byte, diff *Diff) []byte {
bs := make([]byte, len(base))
copy(bs, base)
for i, v := range *diff {
if i < len(bs) {
bs[i] = v
} else {
bs = append(bs, (*diff)[i])
}
}
return bs
}
func decode[T any](bs []byte) (*T, error) {
var t T
err := cbor.Unmarshal(bs, &t)
if err != nil {
return nil, err
}
return &t, nil
}
func encode[T any](t *T) ([]byte, error) {
buf, err := cbor.Marshal(t)
if err != nil {
return nil, err
}
return buf, nil
}
func getRandomID() string {
b := make([]byte, 16)
rand.Read(b)
return fmt.Sprintf("%x-%x-%x", b[0:2], b[2:4], b[4:6])
}
func NewNet(config *Config) *Net {
rp, err := rand.Int(rand.Reader, big.NewInt(65534-1024))
if err != nil {
log.Fatal(err)
}
p := int(rp.Int64()) + 1024
if config.ListenPort != 0 {
p = config.ListenPort
}
return &Net{
config: config,
id: getRandomID(),
peerMutex: sync.Mutex{},
announceEnabled: true,
announcePort: p,
}
}