diff --git a/event.go b/event.go index ef05cbd..dd87620 100644 --- a/event.go +++ b/event.go @@ -34,7 +34,7 @@ type Event interface { GetPeer() Peer GetChannelID() uint8 GetData() uint32 - //GetPacket() Packet + GetPacket() Packet } type enetEvent struct { @@ -58,3 +58,9 @@ func (event *enetEvent) GetChannelID() uint8 { func (event *enetEvent) GetData() uint32 { return (uint32)(event.cEvent.data) } + +func (event *enetEvent) GetPacket() Packet { + return enetPacket{ + cPacket: event.cEvent.packet, + } +} diff --git a/packet.go b/packet.go new file mode 100644 index 0000000..ad73f21 --- /dev/null +++ b/packet.go @@ -0,0 +1,77 @@ +package enet + +// #include +import "C" +import ( + "errors" + "unsafe" +) + +// PacketFlags are bit constants +type PacketFlags uint32 + +const ( + // PacketFlagReliable packets must be received by the target peer and resend attempts + // should be made until the packet is delivered + PacketFlagReliable PacketFlags = C.ENET_PACKET_FLAG_RELIABLE + + // PacketFlagUnsequenced packets will not be sequenced with other packets not supported + // for reliable packets + PacketFlagUnsequenced = C.ENET_PACKET_FLAG_UNSEQUENCED + + // PacketFlagNoAllocate packets will not allocate data, and user must supply it instead + PacketFlagNoAllocate = C.ENET_PACKET_FLAG_NO_ALLOCATE + + // PacketFlagUnreliableFragment packets will be fragmented using unreliable (instead of + // reliable) sends if it exceeds the MTU + PacketFlagUnreliableFragment = C.ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT + + // PacketFlagSent specifies whether the packet has been sent from all queues it has been + // entered into + PacketFlagSent = C.ENET_PACKET_FLAG_SENT +) + +// Packet may be sent to or received from a peer +type Packet interface { + Destroy() + GetData() []byte + GetFlags() PacketFlags +} + +type enetPacket struct { + cPacket *C.struct__ENetPacket +} + +func (packet enetPacket) Destroy() { + C.enet_packet_destroy(packet.cPacket) +} + +func (packet enetPacket) GetData() []byte { + return C.GoBytes( + unsafe.Pointer(packet.cPacket.data), + (C.int)(packet.cPacket.dataLength), + ) +} + +func (packet enetPacket) GetFlags() PacketFlags { + return (PacketFlags)(packet.cPacket.flags) +} + +// NewPacket creates a new packet to send to peers +func NewPacket(data []byte, flags PacketFlags) (Packet, error) { + buffer := C.CBytes(data) + packet := C.enet_packet_create( + buffer, + (C.size_t)(len(data)), + (C.enet_uint32)(flags), + ) + C.free(buffer) + + if packet == nil { + return nil, errors.New("unable to create packet") + } + + return enetPacket{ + cPacket: packet, + }, nil +} diff --git a/peer.go b/peer.go index 0354900..f7ccb27 100644 --- a/peer.go +++ b/peer.go @@ -6,6 +6,10 @@ import "C" // Peer is a peer which data packets may be sent or received from type Peer interface { GetAddress() Address + + SendBytes(data []byte, channel uint8, flags PacketFlags) error + SendString(str string, channel uint8, flags PacketFlags) error + SendPacket(packet Packet, channel uint8) error } type enetPeer struct { @@ -17,3 +21,28 @@ func (peer enetPeer) GetAddress() Address { cAddr: peer.cPeer.address, } } + +func (peer enetPeer) SendBytes(data []byte, channel uint8, flags PacketFlags) error { + packet, err := NewPacket(data, flags) + if err != nil { + return err + } + return peer.SendPacket(packet, channel) +} + +func (peer enetPeer) SendString(str string, channel uint8, flags PacketFlags) error { + packet, err := NewPacket([]byte(str), flags) + if err != nil { + return err + } + return peer.SendPacket(packet, channel) +} + +func (peer enetPeer) SendPacket(packet Packet, channel uint8) error { + C.enet_peer_send( + peer.cPeer, + (C.enet_uint8)(channel), + packet.(enetPacket).cPacket, + ) + return nil +}