1 /** 2 Copyright: Copyright (c) 2014-2016 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 7 module netlib.baseserver; 8 9 import std.range; 10 11 import derelict.enet.enet; 12 13 import netlib.connection; 14 import netlib.clientstorage; 15 16 abstract class BaseServer : Connection 17 { 18 ClientStorage clientStorage; 19 20 void start(ConnectionSettings settings, uint host, ushort port) 21 { 22 ENetAddress address; 23 address.host = host; 24 address.port = port; 25 settings.address = &address; 26 27 super.start(settings); 28 } 29 30 /// Disconnects all clients. 31 void disconnectAll() 32 { 33 if (!isRunning) return; 34 foreach(peer; clientStorage.clientPeers.byValue) 35 { 36 enet_peer_disconnect(peer, 0); 37 } 38 } 39 40 /// Sends packet to specified clients. 41 void sendTo(R)(R clients, ubyte[] data, ubyte channel = 0) 42 if ((isInputRange!R && is(ElementType!R : ClientId)) || 43 is(R : ClientId)) 44 { 45 if (!isRunning) return; 46 ENetPacket* packet = enet_packet_create(data.ptr, data.length, 47 ENET_PACKET_FLAG_RELIABLE); 48 sendTo(clients, packet, channel); 49 } 50 51 /// ditto 52 void sendTo(R, P)(R clients, auto ref const(P) packet, ubyte channel = 0) 53 if (((isInputRange!R && is(ElementType!R : ClientId)) || 54 is(R : ClientId)) && 55 is(P == struct)) 56 { 57 sendTo(clients, createPacket(packet), channel); 58 } 59 60 /// ditto 61 void sendTo(R)(R clients, ENetPacket* packet, ubyte channel = 0) 62 if ((isInputRange!R && is(ElementType!R : ClientId)) || 63 is(R : ClientId)) 64 { 65 if (!isRunning) return; 66 static if (isInputRange!R) 67 { 68 foreach(clientId; clients) 69 { 70 if (auto peer = clientStorage[clientId]) 71 enet_peer_send(peer, channel, packet); 72 } 73 } 74 else // single ClientId 75 { 76 if (auto peer = clientStorage[clients]) 77 enet_peer_send(peer, channel, packet); 78 } 79 } 80 81 /// Sends packet to all clients. 82 void sendToAll(P)(auto ref P packet, ubyte channel = 0) 83 if (is(P == struct)) 84 { 85 sendToAll(createPacket(packet), channel); 86 } 87 88 /// ditto 89 void sendToAll(ubyte[] data, ubyte channel = 0) 90 { 91 if (!isRunning) return; 92 ENetPacket* packet = enet_packet_create(data.ptr, data.length, 93 ENET_PACKET_FLAG_RELIABLE); 94 sendToAll(packet, channel); 95 } 96 97 /// ditto 98 void sendToAll(ENetPacket* packet, ubyte channel = 0) 99 { 100 if (!isRunning) return; 101 enet_host_broadcast(host, channel, packet); 102 } 103 104 /// Sends packet to all clients except one. 105 void sendToAllExcept(P)(ClientId exceptClient, auto ref const(P) packet, ubyte channel = 0) 106 if (is(P == struct)) 107 { 108 sendToAllExcept(exceptClient, createPacket(packet), channel); 109 } 110 111 /// ditto 112 void sendToAllExcept(ClientId exceptClient, ubyte[] data, ubyte channel = 0) 113 { 114 if (!isRunning) return; 115 ENetPacket* packet = enet_packet_create(data.ptr, data.length, 116 ENET_PACKET_FLAG_RELIABLE); 117 sendToAllExcept(exceptClient, packet, channel); 118 } 119 120 /// ditto 121 void sendToAllExcept(ClientId exceptClient, ENetPacket* packet, ubyte channel = 0) 122 { 123 if (!isRunning) return; 124 foreach(clientId, peer; clientStorage.clientPeers) 125 { 126 if (clientId != exceptClient && peer) 127 enet_peer_send(peer, channel, packet); 128 } 129 } 130 }