1 /* 2 * Copyright (c) 2017 SEL 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * See the GNU Lesser General Public License for more details. 13 * 14 */ 15 module sel.hncom.status; 16 17 import std.json : JSONValue; 18 import std.socket : Address; 19 import std.typecons : Tuple; 20 import std.uuid : UUID; 21 22 import sel.hncom.about; 23 import sel.hncom.io : IO; 24 25 /** 26 * Used to calculate latency by both the hub and the node. 27 * When this packet is received it should be immeditaly sent back to the sender 28 * without any change. 29 */ 30 @clientbound @serverbound struct Latency { 31 32 enum ubyte ID = 7; 33 34 /** 35 * Id of the ping/pong. Should be unique for the session. 36 */ 37 uint id; 38 39 mixin IO!(id); 40 41 } 42 43 /** 44 * Notifies the node that the hub's reloadeable settings have been reloaded and that 45 * the node should also reload its resources (for example plugin's settings). 46 * The fields of the packet may be empty if not updated during the reload. 47 */ 48 @clientbound struct Reload { 49 50 enum ubyte ID = 8; 51 52 /** 53 * Display name of the server in the same format as HubInfo's displayName field. 54 */ 55 string displayName; 56 57 /** 58 * New MOTDs (message of the day) for the supported games. 59 */ 60 string[ubyte] motds; 61 62 /** 63 * Main language of the server in the same format as HubInfo's language field. 64 */ 65 string language; 66 67 /** 68 * 69 */ 70 string[] acceptedLanguages; 71 72 /** 73 * 74 */ 75 JSONValue additionalJSON; 76 77 mixin IO!(displayName, motds, language, acceptedLanguages, additionalJSON); 78 79 } 80 81 /** 82 * Sends a logged message to the hub. 83 */ 84 @serverbound struct Log { 85 86 enum ubyte ID = 9; 87 88 enum int NO_WORLD = -1; 89 90 /** 91 * Unix time (in milliseconds) that indicates the exact creation time of the 92 * log (for ordering purposes). 93 */ 94 ulong timestamp; 95 96 /** 97 * Id of the world that has generated the log, if the log comes from a world, -1 otherwise. 98 */ 99 int worldId = -1; 100 101 /** 102 * Name of the logger thas has generated the log, if the log doesn't come from a world. 103 */ 104 string logger; 105 106 /** 107 * Logged message. It may contain Minecraft formatting codes. 108 */ 109 string message; 110 111 /** 112 * Identifier of the command that has generated the log or -1 if the 113 * log wasn't generated by a command. 114 */ 115 int commandId = -1; 116 117 mixin IO!(timestamp, worldId, logger, message, commandId); 118 119 } 120 121 /** 122 * Notifies the node that another node (that is not the receiver) has connected to the hub. 123 */ 124 @clientbound struct AddNode { 125 126 enum ubyte ID = 10; 127 128 /** 129 * Identifier given by the hub to uniquey identify the node. 130 */ 131 uint hubId; 132 133 /** 134 * Node's name used for displaying and identification purposes. 135 */ 136 string name; 137 138 /** 139 * Whether the node is a main node. 140 */ 141 bool main; 142 143 /** 144 * Indicates the games and protocols accepted by the node. 145 */ 146 uint[][ubyte] acceptedGames; 147 148 mixin IO!(hubId, name, main, acceptedGames); 149 150 } 151 152 /** 153 * Notifies the node that another node, previously added with AddNode, 154 * has disconnected from the hub. 155 */ 156 @clientbound struct RemoveNode { 157 158 enum ubyte ID = 11; 159 160 /** 161 * Node's id given by the hub. 162 */ 163 uint hubId; 164 165 mixin IO!(hubId); 166 167 } 168 169 /** 170 * Receives a binary message sent by another node using SendMessage. 171 */ 172 @clientbound struct ReceiveMessage { 173 174 enum ubyte ID = 12; 175 176 /** 177 * Id of the node that has sent the message. 178 */ 179 uint sender; 180 181 /** 182 * Indicates whether the message was broadcasted to every connected node. 183 */ 184 bool broadcasted; 185 186 /** 187 * Bytes received. It could be serialised data or a plugin-defined packet. 188 */ 189 ubyte[] payload; 190 191 mixin IO!(sender, payload); 192 193 } 194 195 /** 196 * Sends a binary message to some selected nodes or broadcast it. 197 */ 198 @serverbound struct SendMessage { 199 200 enum ubyte ID = 13; 201 202 /** 203 * Addressees of the message. If the array is empty the message is 204 * broadcasted to every connected node but the sender. 205 */ 206 uint[] addressees; 207 208 /** 209 * Bytes to be sent/broadcasted. It may be serialised data or a plugin-defined packet. 210 */ 211 ubyte[] payload; 212 213 mixin IO!(addressees, payload); 214 215 } 216 217 /** 218 * Updates the number of players on the server. 219 */ 220 @clientbound struct UpdatePlayers { 221 222 enum ubyte ID = 14; 223 224 enum int UNLIMITED = -1; 225 226 /** 227 * Players currently online in the whole server (connected to a node). 228 */ 229 uint online; 230 231 /** 232 * Maximum number of players that can connect to server, which is the sum of 233 * the max players of every connected node. 234 */ 235 int max; 236 237 mixin IO!(online, max); 238 239 } 240 241 /** 242 * Updates the number of players that can be accepted by the node. 243 * If the given number is smaller than the players currently connected 244 * to the node no player should be kicked. 245 */ 246 @serverbound struct UpdateMaxPlayers { 247 248 enum ubyte ID = 15; 249 250 enum uint UNLIMITED = 0; 251 252 /** 253 * Maximum number of players accepted by node. 254 */ 255 uint max; 256 257 mixin IO!(max); 258 259 } 260 261 /** 262 * Updates the usage of the system's resources of the node. 263 */ 264 @serverbound struct UpdateUsage { 265 266 enum ubyte ID = 16; 267 268 /** 269 * Kibibytes of RAM used by the node. 270 */ 271 uint ram; 272 273 /** 274 * Percentage of CPU used by the node. It may be higher than 100 275 * if the node has more than 1 CPU 276 */ 277 float cpu; 278 279 mixin IO!(ram, cpu); 280 281 } 282 283 /** 284 * Executes a command on the node. 285 */ 286 @clientbound struct RemoteCommand { 287 288 enum ubyte ID = 17; 289 290 enum : ubyte { 291 292 HUB = 1, 293 EXTERNAL_CONSOLE, 294 REMOTE_PANEL, 295 RCON, 296 297 } 298 299 /** 300 * Origin of the command. It could be the hub itself or an external source. 301 */ 302 ubyte origin; 303 304 /** 305 * Address of the sender if the command has been sent from an external source. 306 * It's `null` when the hub is the sender. 307 */ 308 Address sender; 309 310 /** 311 * Commands and arguments that should be executed on the node. 312 * For example `say hello world` or `kill @a`. 313 */ 314 string command; 315 316 /** 317 * Identifier of the command. It's sent back in Log's commandId field 318 * when the command generates output. 319 */ 320 uint commandId; 321 322 mixin IO!(origin, sender, command, commandId); 323 324 } 325 326 /** 327 * Notifies the hub that a new world has been created on the node. 328 */ 329 @serverbound struct AddWorld { 330 331 enum ubyte ID = 18; 332 333 /** 334 * Id of the world. It's unique on the node. 335 */ 336 uint worldId; 337 338 /** 339 * Name of the world, it doesn't need to be unique. 340 */ 341 string name; 342 343 /** 344 * World's dimension in the MCPE format (0: overworld, 1: nether, 2: end). 345 */ 346 ubyte dimension; 347 348 /** 349 * Id of the world's parent or -1 if the world has no parent. This is usually used 350 * for nether/end which are children of an overworld world. 351 */ 352 int parent = -1; 353 354 mixin IO!(worldId, name, dimension, parent); 355 356 } 357 358 /** 359 * Notifies the hub that a world has been removed from the node. 360 */ 361 @serverbound struct RemoveWorld { 362 363 enum ubyte ID = 19; 364 365 /** 366 * Id of the world that has been removed, previosly added using the 367 * AddWorld packet. 368 */ 369 uint worldId; 370 371 mixin IO!(worldId); 372 373 } 374 375 @clientbound struct ListInfo { 376 377 alias EntryUUID = Tuple!(ubyte, "game", UUID, "uuid"); 378 379 alias EntryUsername = Tuple!(ubyte, "game", string, "username"); 380 381 enum ubyte ID = 20; 382 383 enum : ubyte { 384 385 WHITELIST, 386 BLACKLIST 387 388 } 389 390 ubyte list; 391 392 EntryUUID[] entriesByUUID; 393 394 EntryUsername[] entriesByUsername; 395 396 string[] entriesByIp; 397 398 mixin IO!(list, entriesByUUID, entriesByUsername, entriesByIp); 399 400 } 401 402 @clientbound @serverbound struct UpdateListByUUID { 403 404 enum ubyte ID = 21; 405 406 ubyte list; 407 408 ubyte game; 409 410 UUID uuid; 411 412 mixin IO!(list, game, uuid); 413 414 } 415 416 @clientbound @serverbound struct UpdateListByUsername { 417 418 enum ubyte ID = 22; 419 420 ubyte list; 421 422 ubyte game; 423 424 string username; 425 426 mixin IO!(list, game, username); 427 428 } 429 430 @clientbound @serverbound struct UpdateListByIp { 431 432 enum ubyte ID = 23; 433 434 ubyte list; 435 436 string ip; 437 438 mixin IO!(list, ip); 439 440 } 441 442 @clientbound struct PanelCredentials { 443 444 enum ubyte ID = 24; 445 446 string address; 447 ubyte[64] hash; 448 uint worldId; 449 450 mixin IO!(address, hash, worldId); 451 452 }