-
Notifications
You must be signed in to change notification settings - Fork 0
/
net.go
131 lines (108 loc) · 2.09 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
120
121
122
123
124
125
126
127
128
129
130
131
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)
if len(inc) == 0 {
return &m
}
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]
}
} else {
if i < len(base) {
m[-i] = 0
}
}
return &m
}
func patch(base []byte, diff *Diff) []byte {
bs := make([]byte, len(base))
copy(bs, base)
for i, v := range *diff {
if i >= 0 {
if i < len(bs) {
bs[i] = v
} else {
bs = append(bs, (*diff)[i])
}
} else if i*-1 < len(bs) {
bs = bs[:i*-1]
}
}
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,
}
}