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/hncom/login.d, selery/hncom/login.d)
28  */
29 module selery.hncom.login;
30 
31 import selery.hncom.about;
32 import selery.hncom.io;
33 
34 import xpacket : BigEndian;
35 
36 /**
37  * First packet sent by the client after the connection is established.
38  * It contains informations used by the hub to check permissions and compatibility.
39  */
40 @serverbound class ConnectionRequest : HncomPacket {
41 	
42 	enum ubyte ID = 1;
43 	
44 	/**
45 	 * Version of the protocol used by the client that must match the hub's one.
46 	 */
47 	@BigEndian uint protocol = __PROTOCOL__;
48 	
49 	/**
50 	 * Name of the node that will be validated by the hub. It should always be
51 	 * lowercase and only contain letters, numbers, dashes and underscores.
52 	 */
53 	string name;
54 	
55 	/**
56 	 * Password, if the hub requires one, or an empty string.
57 	 */
58 	string password;
59 	
60 	/**
61 	 * Indicates whether the node accepts clients when they first connect to the
62 	 * hub or exclusively when they are transferred.
63 	 */
64 	bool main = true;
65 	
66 	mixin Make;
67 	
68 }
69 
70 /**
71  * Reply to ConnectionRequest sent only when the node's ip is accepted by the hub.
72  * It contains the connection status (accepted or an error code) and the hub's protocol.
73  */
74 @clientbound class ConnectionResponse : HncomPacket {
75 	
76 	enum ubyte ID = 2;
77 	
78 	enum : ubyte {
79 		
80 		OK,
81 		OUTDATED_HUB,				/// The hub uses an old version of hncom
82 		OUTDATED_NODE,				/// The node uses an old version of hncom
83 		PASSWORD_REQUIRED,			/// A password is required to connect
84 		WRONG_PASSWORD,				/// The password doesn't match the hub's one
85 		INVALID_NAME_LENGTH,		/// The name is too short or too long
86 		INVALID_NAME_CHARACTERS,	/// The name contains invalid characters
87 		NAME_ALREADY_USED,			/// There's already a node connected with the same name
88 		NAME_RESERVED,				/// The name cannot be used because the hub has reserved it for something else
89 		BLOCKED_BY_PLUGIN,			/// A plugin has blocked the node from connecting
90 		
91 	}
92 	
93 	/**
94 	 * Indicates the status of connection. If not 0, it indicates an error.
95 	 */
96 	ubyte status;
97 	
98 	/**
99 	 * Indicates the version of the protocol used by the hub when the status
100 	 * code indicates that the hub or the node is obsolete.
101 	 */
102 	uint protocol = __PROTOCOL__;
103 	
104 	mixin Make;
105 	
106 }
107 
108 /**
109  * Hub's informations.
110  */
111 @clientbound class HubInfo : HncomPacket {
112 	
113 	enum ubyte ID = 3;
114 	
115 	enum int UNLIMITED = -1;
116 	
117 	struct GameInfo { string motd; uint[] protocols; bool onlineMode; ushort port; }
118 	
119 	/**
120 	 * Server's id, either given by a snoop system or randomly generated at runtime.
121 	 */
122 	ulong serverId;
123 	
124 	/**
125 	 * First number of the 4,294,967,296 (2^32) reserved by the hub to create the node's UUIDs.
126 	 * Every UUID generated by the node is formed by the server's id (most signicant)
127 	 * and the next reserved uuid (least significant). This way every UUID in the hub
128 	 * and in the connected nodes is always different.
129 	 */
130 	ulong reservedUUIDs;
131 	
132 	/**
133 	 * Unformatted name of the server as indicated in the hub's configuration file.
134 	 */
135 	string displayName;
136 	
137 	/**
138 	 * Informations about the games supported by the hub.
139 	 */
140 	GameInfo[ubyte] gamesInfo;
141 	
142 	/**
143 	 * Number of players currently online and connected to other nodes.
144 	 */
145 	uint online;
146 	
147 	/**
148 	 * Number of maximum players that can connect to the server (that is the sum
149 	 * of the max players of the nodes already connected).
150 	 * The number may change after the current node connects.
151 	 */
152 	int max;
153 	
154 	/**
155 	 * Languages accepted by the server in format ISO 639.1 (language code) underscore
156 	 * ISO 3166 (country code), e.g. en_US.
157 	 * The list must contain at least one element.
158 	 */
159 	string[] acceptedLanguages;
160 	
161 	/**
162 	 * Indicates whether the web admin protocol is active on the hub. If it is the
163 	 * node should send the port where it will listen for connections in its info packet.
164 	 */
165 	bool webAdmin;
166 	
167 	/**
168 	 * Optional informations about the server's software, social accounts, system and options.
169 	 * Example:
170 	 * ---
171 	 * {
172 	 *   "software": {
173 	 *      "name": "Selery",
174 	 *      "version": "0.1.0",
175 	 *      "stable": true
176 	 *   },
177 	 *   "minecraft": {
178 	 *      "edu": false,
179 	 *      "realm": true
180 	 *   },
181 	 *   "social": {
182 	 *      "website": "example.com",
183 	 *      "facebook": "example-official",
184 	 *      "twitter": "example_tweets",
185 	 *      "youtube": "examplechannel",
186 	 *      "instagram": "example",
187 	 *      "google-plus": "example-plus"
188 	 *   },
189 	 *   "system": {
190 	 *      "os": "Ubuntu 16.04",
191 	 *      "cpu": "Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz",
192 	 *      "cores": 2,
193 	 *      "ram": 2147483648
194 	 *   }
195 	 * }
196 	 * ---
197 	 */
198 	string additionalJSON;
199 	
200 	mixin Make;
201 	
202 }
203 
204 /**
205  * Node's informations.
206  */
207 @serverbound class NodeInfo : HncomPacket {
208 	
209 	enum ubyte ID = 4;
210 	
211 	enum uint UNLIMITED = 0;
212 	
213 	struct Plugin { uint id; string name; string version_; }
214 	
215 	/**
216 	 * Informations about the games accepted by the node. There should be at least
217 	 * one combination of game/protocols that is also accepted by hub as indicated
218 	 * in HubInfo.gamesInfo, otherwise the node will never receive any player.
219 	 */
220 	uint[][ubyte] acceptedGames;
221 	
222 	/**
223 	 * Maximum number of players accepted by node.
224 	 */
225 	uint max;
226 	
227 	/**
228 	 * List of plugins currently loaded on the node.
229 	 * This field is used only for information purposes (as displaying the
230 	 * plugins in the querying protocol).
231 	 */
232 	Plugin[] plugins;
233 	
234 	/**
235 	 * Port where the node is listening for connections, if the web admin protocol
236 	 * is active on the hub.
237 	 */
238 	ushort webAdminPort;
239 	
240 	/**
241 	 * Optional informations about the server's software and system,
242 	 * similar to HubInfo's additionalJson field.
243 	 * Example:
244 	 * ---
245 	 * {
246 	 *   "software": {
247 	 *      "name": "Selery",
248 	 *      "version": "0.1.0",
249 	 *      "stable": true
250 	 *   },
251 	 *   "system": {
252 	 *      "os": "Windows 10",
253 	 *      "cpu": "Intel(R) Core(TM) i7-5700U CPU @ 3.40GHz",
254 	 *      "cores": 4,
255 	 *      "ram": 8589934592
256 	 *   }
257 	 * }
258 	 * ---
259 	 */
260 	string additionalJSON;
261 	
262 	mixin Make;
263 	
264 }