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