-
Notifications
You must be signed in to change notification settings - Fork 1
/
client.go
133 lines (119 loc) · 3.08 KB
/
client.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
132
133
package main
import (
"log"
"time"
"github.com/gogo/protobuf/proto"
"github.com/silbinarywolf/networkplatformer-go/gameclient"
"github.com/silbinarywolf/networkplatformer-go/netmsg"
)
const (
maxClients = 256
)
var (
client *Client
isConnected = false
lastWorldUpdateTimer time.Time
)
type Client struct {
*gameclient.Client
clientSlots []*Char
}
func NewClient() *Client {
server := &Client{
Client: gameclient.NewClient(),
clientSlots: make([]*Char, maxClients),
}
return server
}
func (c *Client) Update() {
RecvMsgLoop:
for {
select {
case buf := <-c.ChRecv():
kind := netmsg.Kind(buf[0])
buf = buf[1:]
switch kind {
case netmsg.MsgConnectResponse:
recvMsg := &netmsg.ConnectResponse{}
err := recvMsg.Unmarshal(buf)
if err != nil {
log.Fatal("marshaling error: ", err)
break
}
// Receive starting pos from server and add to chars to simulate
you.X = recvMsg.X
you.Y = recvMsg.Y
chars = append(chars, you)
isConnected = true
// Last time we received an update about the world
lastWorldUpdateTimer = time.Now()
log.Printf("%s: received login data: %v\n", kind, recvMsg)
case netmsg.MsgUpdatePlayer:
recvMsg := &netmsg.UpdatePlayer{}
err := recvMsg.Unmarshal(buf)
if err != nil {
log.Fatal("marshaling error: ", err)
break
}
clientSlot := recvMsg.GetClientSlot()
char := c.clientSlots[clientSlot]
if char == nil {
// Create char if they don't exist
char = &Char{}
chars = append(chars, char)
c.clientSlots[clientSlot] = char
}
char.X = recvMsg.X
char.Y = recvMsg.Y
char.isKeyLeftPressed = recvMsg.IsKeyLeftPressed
char.isKeyRightPressed = recvMsg.IsKeyRightPressed
case netmsg.MsgDisconnectPlayer:
recvMsg := &netmsg.DisconnectPlayer{}
err := recvMsg.Unmarshal(buf)
if err != nil {
log.Fatal("marshaling error: ", err)
break
}
clientSlot := recvMsg.GetClientSlot()
char := c.clientSlots[clientSlot]
if char == nil {
continue
}
char.RemoveFromSimulation()
c.clientSlots[clientSlot] = nil
default:
log.Printf("Unhandled netmsg kind: %s, with data: %v", kind.String(), buf)
}
case <-c.ChDisconnected():
isConnected = false
you.RemoveFromSimulation()
log.Println("Lost connection to server")
default:
// no more messages
break RecvMsgLoop
}
}
//
if you != nil && isConnected {
elapsed := time.Since(lastWorldUpdateTimer)
if elapsed > 15*time.Millisecond {
lastWorldUpdateTimer = time.Now()
// Send update data to server
sendMsg := netmsg.UpdatePlayer{
X: you.X,
Y: you.Y,
IsKeyLeftPressed: you.isKeyLeftPressed,
IsKeyRightPressed: you.isKeyRightPressed,
}
data, err := proto.Marshal(&sendMsg)
if err != nil {
log.Fatal("client update: marshaling error: ", err)
}
// send update message to server
packetData := make([]byte, 1, len(data)+1)
packetData[0] = netmsg.MsgUpdatePlayer
packetData = append(packetData, data...)
client.SendMessage(packetData)
}
}
}