1 /* 2 * Copyright (c) 2017-2019 sel-project 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in all 12 * copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 */ 23 /** 24 * Copyright: Copyright (c) 2017-2019 sel-project 25 * License: MIT 26 * Authors: Kripth 27 * Source: $(HTTP github.com/sel-project/selery/source/selery/node/node.d, selery/node/node.d) 28 */ 29 module selery.node.node; 30 31 import std.algorithm : canFind; 32 33 import selery.node.server : NodeServer; 34 import selery.player.player : Player; 35 36 /** 37 * A node connected to the hub where players can be transferred to. 38 */ 39 class Node { 40 41 public shared NodeServer server; 42 43 /** 44 * Id of the node, given by the hub. 45 */ 46 public immutable uint hubId; 47 48 /** 49 * Name of the node. It can only be one node with the same name 50 * online at the same time. 51 */ 52 public const string name; 53 54 /** 55 * Indicates whether the can receive player when they first 56 * connect or only when they are transferred. 57 */ 58 public immutable bool main; 59 60 /** 61 * Indicates which games and which protocols the node does accept. 62 * Example: 63 * --- 64 * auto pocket = PE in node.acceptedGames; 65 * if(pocket && (*pocket).canFind(100)) { 66 * log(node.name, " supports MCPE 1.0"); 67 * } 68 * --- 69 */ 70 uint[][ubyte] acceptedGames; 71 72 public this(shared NodeServer server, uint hubId, string name, bool main, uint[][ubyte] acceptedGames) { 73 this.server = server; 74 this.hubId = hubId; 75 this.name = name; 76 this.main = main; 77 this.acceptedGames = acceptedGames; 78 } 79 80 /** 81 * Indicates whether or not the node is still connected to 82 * the hub. 83 * Example: 84 * --- 85 * auto node = server.nodeWithName("node"); 86 * assert(node.online); 87 * --- 88 */ 89 public inout @property @safe bool online() { 90 return this.server.nodeWithHubId(this.hubId) !is null; 91 } 92 93 /** 94 * Indicates whether the node can accept the given player. 95 * If a player is transferred to a node that cannot accept it 96 * it is kicked with the "End of Stream" message by the hub. 97 */ 98 public inout @safe bool accepts(Player player) { 99 auto a = player.gameId in this.acceptedGames; 100 return a && (*a).canFind(player.protocol); 101 } 102 103 /** 104 * Sends a message to the node. 105 * Example: 106 * --- 107 * // if the other node uses the same JSON protocol 108 * node.sendMessage(`{"reply_with":12}`); 109 * server += (NodeMessageEvent event) { 110 * if(node == event.node) { 111 * assert(parseJSON(cast(string)event.payload)["reply"].integer == 12); 112 * } 113 * } 114 * --- 115 */ 116 public void sendMessage(ubyte[] payload) { 117 this.server.sendMessage(this, payload); 118 } 119 120 /// ditto 121 public void sendMessage(string message) { 122 this.sendMessage(cast(ubyte[])message); 123 } 124 125 public override bool opEquals(Object o) { 126 auto node = cast(Node)o; 127 return node !is null && node.hubId == this.hubId; 128 } 129 130 }