224 lines
5.5 KiB
C++
224 lines
5.5 KiB
C++
|
#include "networked_multiplayer_enet.h"
|
||
|
|
||
|
void NetworkedMultiplayerENet::set_transfer_mode(TransferMode p_mode) {
|
||
|
|
||
|
transfer_mode=p_mode;
|
||
|
}
|
||
|
|
||
|
void NetworkedMultiplayerENet::set_target_peer(const StringName &p_peer){
|
||
|
|
||
|
target_peer=p_peer;
|
||
|
}
|
||
|
void NetworkedMultiplayerENet::set_channel(int p_channel){
|
||
|
|
||
|
send_channel=p_channel;
|
||
|
}
|
||
|
|
||
|
|
||
|
StringName NetworkedMultiplayerENet::get_packet_peer() const{
|
||
|
|
||
|
ERR_FAIL_COND_V(!active,StringName());
|
||
|
ERR_FAIL_COND_V(incoming_packets.size()==0,StringName());
|
||
|
|
||
|
return incoming_packets.front()->get().from;
|
||
|
|
||
|
}
|
||
|
int NetworkedMultiplayerENet::get_packet_channel() const{
|
||
|
|
||
|
ERR_FAIL_COND_V(!active,0);
|
||
|
ERR_FAIL_COND_V(incoming_packets.size()==0,0);
|
||
|
return incoming_packets.front()->get().from_channel;
|
||
|
}
|
||
|
|
||
|
|
||
|
Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int p_max_channels, int p_in_bandwidth, int p_out_bandwidth){
|
||
|
|
||
|
ERR_FAIL_COND_V(active,ERR_ALREADY_IN_USE);
|
||
|
|
||
|
ENetAddress address;
|
||
|
address.host = ENET_HOST_ANY;
|
||
|
/* Bind the server to port 1234. */
|
||
|
address.port = 1234;
|
||
|
|
||
|
host = enet_host_create (& address /* the address to bind the server host to */,
|
||
|
p_max_clients /* allow up to 32 clients and/or outgoing connections */,
|
||
|
p_max_channels /* allow up to 2 channels to be used, 0 and 1 */,
|
||
|
p_in_bandwidth /* assume any amount of incoming bandwidth */,
|
||
|
p_out_bandwidth /* assume any amount of outgoing bandwidth */);
|
||
|
|
||
|
ERR_FAIL_COND_V(!host,ERR_CANT_CREATE);
|
||
|
|
||
|
active=true;
|
||
|
server=true;
|
||
|
return OK;
|
||
|
}
|
||
|
Error NetworkedMultiplayerENet::create_client(const IP_Address& p_ip,int p_port, int p_max_channels, int p_in_bandwidth, int p_out_bandwidth){
|
||
|
|
||
|
ERR_FAIL_COND_V(active,ERR_ALREADY_IN_USE);
|
||
|
|
||
|
|
||
|
return OK;
|
||
|
}
|
||
|
|
||
|
void NetworkedMultiplayerENet::poll(){
|
||
|
|
||
|
ERR_FAIL_COND(!active);
|
||
|
|
||
|
_pop_current_packet();
|
||
|
|
||
|
ENetEvent event;
|
||
|
/* Wait up to 1000 milliseconds for an event. */
|
||
|
while (enet_host_service (host, & event, 1000) > 0)
|
||
|
{
|
||
|
switch (event.type)
|
||
|
{
|
||
|
case ENET_EVENT_TYPE_CONNECT: {
|
||
|
/* Store any relevant client information here. */
|
||
|
|
||
|
IP_Address ip;
|
||
|
ip.host=event.peer -> address.host;
|
||
|
|
||
|
StringName *new_id = memnew( StringName );
|
||
|
*new_id = String(ip) +":"+ itos(event.peer -> address.port);
|
||
|
|
||
|
peer_map[*new_id]=event.peer;
|
||
|
|
||
|
emit_signal("peer_connected",*new_id);
|
||
|
|
||
|
} break;
|
||
|
case ENET_EVENT_TYPE_DISCONNECT: {
|
||
|
|
||
|
/* Reset the peer's client information. */
|
||
|
|
||
|
StringName *id = (StringName*)event.peer -> data;
|
||
|
|
||
|
emit_signal("peer_disconnected",*id);
|
||
|
|
||
|
peer_map.erase(*id);
|
||
|
memdelete( id );
|
||
|
} break;
|
||
|
case ENET_EVENT_TYPE_RECEIVE: {
|
||
|
|
||
|
Packet packet;
|
||
|
packet.packet = event.packet;
|
||
|
|
||
|
StringName *id = (StringName*)event.peer -> data;
|
||
|
packet.from_channel=event.channelID;
|
||
|
packet.from=*id;
|
||
|
|
||
|
incoming_packets.push_back(packet);
|
||
|
//destroy packet later..
|
||
|
|
||
|
}break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void NetworkedMultiplayerENet::disconnect() {
|
||
|
|
||
|
ERR_FAIL_COND(!active);
|
||
|
|
||
|
_pop_current_packet();
|
||
|
|
||
|
enet_host_destroy(host);
|
||
|
active=false;
|
||
|
incoming_packets.clear();
|
||
|
}
|
||
|
|
||
|
void NetworkedMultiplayerENet::_bind_methods() {
|
||
|
|
||
|
ObjectTypeDB::bind_method(_MD("create_server","port","max_clients","max_channels","in_bandwidth","out_bandwidth"),&NetworkedMultiplayerENet::create_server,DEFVAL(32),DEFVAL(1),DEFVAL(0),DEFVAL(0));
|
||
|
ObjectTypeDB::bind_method(_MD("create_client","ip","port","max_channels","in_bandwidth","out_bandwidth"),&NetworkedMultiplayerENet::create_client,DEFVAL(1),DEFVAL(0),DEFVAL(0));
|
||
|
ObjectTypeDB::bind_method(_MD("disconnect"),&NetworkedMultiplayerENet::disconnect);
|
||
|
|
||
|
}
|
||
|
|
||
|
int NetworkedMultiplayerENet::get_available_packet_count() const {
|
||
|
|
||
|
return incoming_packets.size();
|
||
|
}
|
||
|
Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer,int &r_buffer_size) const{
|
||
|
|
||
|
ERR_FAIL_COND_V(incoming_packets.size()==0,ERR_UNAVAILABLE);
|
||
|
|
||
|
_pop_current_packet();
|
||
|
|
||
|
current_packet = incoming_packets.front()->get();
|
||
|
incoming_packets.pop_front();
|
||
|
|
||
|
r_buffer=(const uint8_t**)¤t_packet.packet->data;
|
||
|
r_buffer_size=current_packet.packet->dataLength;
|
||
|
|
||
|
return OK;
|
||
|
}
|
||
|
Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer,int p_buffer_size){
|
||
|
|
||
|
ERR_FAIL_COND_V(incoming_packets.size()==0,ERR_UNAVAILABLE);
|
||
|
|
||
|
Map<StringName,ENetPeer*>::Element *E=NULL;
|
||
|
|
||
|
if (target_peer!=StringName()) {
|
||
|
peer_map.find(target_peer);
|
||
|
if (!E) {
|
||
|
ERR_EXPLAIN("Invalid Target Peer: "+String(target_peer));
|
||
|
ERR_FAIL_V(ERR_INVALID_PARAMETER);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int packet_flags=0;
|
||
|
switch(transfer_mode) {
|
||
|
case TRANSFER_MODE_UNRELIABLE: {
|
||
|
packet_flags=ENET_PACKET_FLAG_UNSEQUENCED;
|
||
|
} break;
|
||
|
case TRANSFER_MODE_RELIABLE: {
|
||
|
packet_flags=ENET_PACKET_FLAG_RELIABLE;
|
||
|
} break;
|
||
|
case TRANSFER_MODE_ORDERED: {
|
||
|
packet_flags=ENET_PACKET_FLAG_RELIABLE;
|
||
|
} break;
|
||
|
}
|
||
|
|
||
|
/* Create a reliable packet of size 7 containing "packet\0" */
|
||
|
ENetPacket * packet = enet_packet_create (p_buffer,p_buffer_size,packet_flags);
|
||
|
|
||
|
if (target_peer==StringName()) {
|
||
|
enet_host_broadcast(host,send_channel,packet);
|
||
|
} else {
|
||
|
enet_peer_send (E->get(), send_channel, packet);
|
||
|
}
|
||
|
|
||
|
enet_host_flush(host);
|
||
|
|
||
|
return OK;
|
||
|
}
|
||
|
|
||
|
int NetworkedMultiplayerENet::get_max_packet_size() const {
|
||
|
|
||
|
return 1<<24; //anything is good
|
||
|
}
|
||
|
|
||
|
void NetworkedMultiplayerENet::_pop_current_packet() const {
|
||
|
|
||
|
if (current_packet.packet) {
|
||
|
enet_packet_destroy(current_packet.packet);
|
||
|
current_packet.packet=NULL;
|
||
|
current_packet.from=StringName();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
NetworkedMultiplayerENet::NetworkedMultiplayerENet(){
|
||
|
|
||
|
active=false;
|
||
|
server=false;
|
||
|
send_channel=0;
|
||
|
current_packet.packet=NULL;
|
||
|
transfer_mode=TRANSFER_MODE_ORDERED;
|
||
|
}
|
||
|
NetworkedMultiplayerENet::~NetworkedMultiplayerENet(){
|
||
|
|
||
|
if (active) {
|
||
|
disconnect();
|
||
|
}
|
||
|
}
|