-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
host.go
161 lines (136 loc) · 3.69 KB
/
host.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package enet
// #include <enet/enet.h>
import "C"
import (
"errors"
"unsafe"
)
// Host for communicating with peers
type Host interface {
Destroy()
Service(timeout uint32) Event
Connect(addr Address, channelCount int, data uint32) (Peer, error)
CompressWithRangeCoder() error
BroadcastBytes(data []byte, channel uint8, flags PacketFlags) error
BroadcastPacket(packet Packet, channel uint8) error
BroadcastString(str string, channel uint8, flags PacketFlags) error
EnableChecksum()
ConnectedPeers() []enetPeer
UsingNewPacketForServer(state bool)
UsingNewPacket(state bool)
GetAddress() Address
}
type enetHost struct {
cHost *C.struct__ENetHost
}
func (host *enetHost) GetAddress() Address {
return &enetAddress{
cAddr: host.cHost.address,
}
}
func (host enetHost) ConnectedPeers() []enetPeer {
var connectedList = make([]enetPeer, 0)
for i := 0; i < int(host.cHost.peerCount); i++ {
currentPeer := (*C.ENetPeer)(unsafe.Pointer(uintptr(unsafe.Pointer(host.cHost.peers)) + uintptr(i)*C.sizeof_ENetPeer))
if currentPeer.state != C.ENET_PEER_STATE_CONNECTED {
continue
}
connectedList = append(connectedList, enetPeer{cPeer: currentPeer})
}
return connectedList
}
func (host *enetHost) Destroy() {
C.enet_host_destroy(host.cHost)
}
func (host *enetHost) UsingNewPacketForServer(state bool) {
if state {
host.cHost.usingNewPacketForServer = 1
} else {
host.cHost.usingNewPacketForServer = 0
}
}
func (host *enetHost) UsingNewPacket(state bool) {
if state {
host.cHost.usingNewPacket = 1
} else {
host.cHost.usingNewPacket = 0
}
}
func (host *enetHost) Service(timeout uint32) Event {
ret := &enetEvent{}
C.enet_host_service(
host.cHost,
&ret.cEvent,
(C.enet_uint32)(timeout),
)
return ret
}
func (host *enetHost) Connect(addr Address, channelCount int, data uint32) (Peer, error) {
peer := C.enet_host_connect(
host.cHost,
&(addr.(*enetAddress)).cAddr,
(C.size_t)(channelCount),
(C.enet_uint32)(data),
)
if peer == nil {
return nil, errors.New("couldn't connect to foreign peer")
}
return enetPeer{
cPeer: peer,
}, nil
}
func (host *enetHost) CompressWithRangeCoder() error {
status := C.enet_host_compress_with_range_coder(host.cHost)
if status == -1 {
return errors.New("couldn't set the packet compressor to default range coder because context is nil")
} else if status != 0 {
return errors.New("couldn't set the packet compressor to default range coder for unknown reason")
}
return nil
}
func (host *enetHost) EnableChecksum() {
host.cHost.checksum = C.ENetChecksumCallback(C.enet_crc32)
return
}
// NewHost creats a host for communicating to peers
func NewHost(addr Address, peerCount, channelLimit uint64, incomingBandwidth, outgoingBandwidth uint32) (Host, error) {
var cAddr *C.struct__ENetAddress
if addr != nil {
cAddr = &(addr.(*enetAddress)).cAddr
}
host := C.enet_host_create(
cAddr,
(C.size_t)(peerCount),
(C.size_t)(channelLimit),
(C.enet_uint32)(incomingBandwidth),
(C.enet_uint32)(outgoingBandwidth),
)
if host == nil {
return nil, errors.New("unable to create host")
}
return &enetHost{
cHost: host,
}, nil
}
func (host *enetHost) BroadcastBytes(data []byte, channel uint8, flags PacketFlags) error {
packet, err := NewPacket(data, flags)
if err != nil {
return err
}
return host.BroadcastPacket(packet, channel)
}
func (host *enetHost) BroadcastPacket(packet Packet, channel uint8) error {
C.enet_host_broadcast(
host.cHost,
(C.enet_uint8)(channel),
packet.(enetPacket).cPacket,
)
return nil
}
func (host *enetHost) BroadcastString(str string, channel uint8, flags PacketFlags) error {
packet, err := NewPacket([]byte(str), flags)
if err != nil {
return err
}
return host.BroadcastPacket(packet, channel)
}