1 /* 2 * Copyright (c) 2017-2018 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-2018 sel-project 25 * License: MIT 26 * Authors: Kripth 27 * Source: $(HTTP github.com/sel-project/sel-hncom/sel/hncom/status.d, sel/hncom/status.d) 28 */ 29 module sel.hncom.status; 30 31 import std.json : JSONValue; 32 import std.socket : Address; 33 import std.typecons : Tuple; 34 import std.uuid : UUID; 35 36 import sel.hncom.about; 37 import sel.hncom.io : IO; 38 39 /** 40 * Used to calculate latency by both the hub and the node. 41 * When this packet is received it should be immeditaly sent back to the sender 42 * without any change. 43 */ 44 @clientbound @serverbound struct Latency { 45 46 enum ubyte ID = 7; 47 48 /** 49 * Id of the ping/pong. Should be unique for the session. 50 */ 51 uint id; 52 53 mixin IO!(id); 54 55 } 56 57 /** 58 * Sends a logged message to the hub. 59 */ 60 @serverbound struct Log { 61 62 enum ubyte ID = 8; 63 64 alias Message = Tuple!(bool, "translation", string, "message", string[], "params"); 65 66 enum int NO_COMMAND = -1; 67 68 enum int NO_WORLD = -1; 69 70 /** 71 * Logged message or translation. It may contain Minecraft formatting codes. 72 */ 73 Message[] message; 74 75 /** 76 * Unix time (in milliseconds) that indicates the exact creation time of the 77 * log (for ordering purposes). 78 */ 79 ulong timestamp; 80 81 /** 82 * Identifier of the command that has generated the log or -1 if the 83 * log wasn't generated by a command. 84 */ 85 int commandId = NO_COMMAND; 86 87 /** 88 * Id of the world that has generated the log, if the log comes from a world, -1 otherwise. 89 */ 90 int worldId = NO_WORLD; 91 92 mixin IO!(message, timestamp, commandId, worldId); 93 94 } 95 96 /** 97 * Executes a command on the node. 98 */ 99 @clientbound struct RemoteCommand { 100 101 enum ubyte ID = 9; 102 103 enum : ubyte { 104 105 HUB = 0, 106 WEB_ADMIN = 1, 107 RCON = 2, 108 109 } 110 111 /** 112 * Origin of the command. It could be the hub itself or an external source. 113 */ 114 ubyte origin; 115 116 /** 117 * Address of the sender if the command has been sent from an external source. 118 * It's `null` when the hub is the sender. 119 */ 120 Address sender; 121 122 /** 123 * Commands and arguments that should be executed on the node. 124 * For example `say hello world` or `kill @a`. 125 */ 126 string command; 127 128 /** 129 * Identifier of the command. It's sent back in Log's commandId field 130 * when the command generates output. 131 */ 132 uint commandId; 133 134 mixin IO!(origin, sender, command, commandId); 135 136 } 137 138 /** 139 * Notifies the node that another node (that is not the receiver) has connected to the hub. 140 */ 141 @clientbound struct AddNode { 142 143 enum ubyte ID = 10; 144 145 /** 146 * Identifier given by the hub to uniquey identify the node. 147 */ 148 uint hubId; 149 150 /** 151 * Node's name used for displaying and identification purposes. 152 */ 153 string name; 154 155 /** 156 * Whether the node is a main node. 157 */ 158 bool main; 159 160 /** 161 * Indicates the games and protocols accepted by the node. 162 */ 163 uint[][ubyte] acceptedGames; 164 165 mixin IO!(hubId, name, main, acceptedGames); 166 167 } 168 169 /** 170 * Notifies the node that another node, previously added with AddNode, 171 * has disconnected from the hub. 172 */ 173 @clientbound struct RemoveNode { 174 175 enum ubyte ID = 11; 176 177 /** 178 * Node's id given by the hub. 179 */ 180 uint hubId; 181 182 mixin IO!(hubId); 183 184 } 185 186 /** 187 * Receives a binary message sent by another node using SendMessage. 188 */ 189 @clientbound struct ReceiveMessage { 190 191 enum ubyte ID = 12; 192 193 /** 194 * Id of the node that has sent the message. 195 */ 196 uint sender; 197 198 /** 199 * Indicates whether the message was broadcasted to every connected node. 200 */ 201 bool broadcasted; 202 203 /** 204 * Bytes received. It could be serialised data or a plugin-defined packet. 205 */ 206 ubyte[] payload; 207 208 mixin IO!(sender, payload); 209 210 } 211 212 /** 213 * Sends a binary message to some selected nodes or broadcast it. 214 */ 215 @serverbound struct SendMessage { 216 217 enum ubyte ID = 13; 218 219 /** 220 * Addressees of the message. If the array is empty the message is 221 * broadcasted to every connected node but the sender. 222 */ 223 uint[] addressees; 224 225 /** 226 * Bytes to be sent/broadcasted. It may be serialised data or a plugin-defined packet. 227 */ 228 ubyte[] payload; 229 230 mixin IO!(addressees, payload); 231 232 } 233 234 /** 235 * Updates the server's display name. 236 */ 237 @clientbound struct UpdateDisplayName { 238 239 enum ubyte ID = 14; 240 241 string displayName; 242 243 mixin IO!(displayName); 244 245 } 246 247 /** 248 * Updates the MOTD of one of the supported games. 249 */ 250 @clientbound struct UpdateMOTD { 251 252 enum ubyte ID = 15; 253 254 ubyte type; 255 256 string motd; 257 258 mixin IO!(type, motd); 259 260 } 261 262 /** 263 * Updates the number of players on the server. 264 */ 265 @clientbound struct UpdatePlayers { 266 267 enum ubyte ID = 16; 268 269 enum int UNLIMITED = -1; 270 271 /** 272 * Players currently online in the whole server (connected to a node). 273 */ 274 uint online; 275 276 /** 277 * Maximum number of players that can connect to server, which is the sum of 278 * the max players of every connected node. 279 */ 280 int max; 281 282 mixin IO!(online, max); 283 284 } 285 286 /** 287 * Updates the number of players that can be accepted by the node. 288 * If the given number is smaller than the players currently connected 289 * to the node no player should be kicked. 290 */ 291 @serverbound struct UpdateMaxPlayers { 292 293 enum ubyte ID = 17; 294 295 enum uint UNLIMITED = 0; 296 297 /** 298 * Maximum number of players accepted by node. 299 */ 300 uint max; 301 302 mixin IO!(max); 303 304 } 305 306 /** 307 * Updates the accepted protocols for one of the supported games. 308 */ 309 @clientbound struct UpdateSupportedProtocols { 310 311 enum ubyte ID = 18; 312 313 ubyte game; 314 315 uint[] protocols; 316 317 mixin IO!(game, protocols); 318 319 } 320 321 /** 322 * Updates the usage of the system's resources of the node. 323 */ 324 @serverbound struct UpdateUsage { 325 326 enum ubyte ID = 19; 327 328 /** 329 * Kibibytes of RAM used by the node. 330 */ 331 uint ram; 332 333 /** 334 * Percentage of CPU used by the node. It may be higher than 100 335 * if the node has more than 1 CPU 336 */ 337 float cpu; 338 339 mixin IO!(ram, cpu); 340 341 } 342 343 /** 344 * Updates the language files. The content of this packet is usually 345 * readed from plugins' language files. 346 */ 347 @serverbound struct UpdateLanguageFiles { 348 349 enum ubyte ID = 20; 350 351 string language; 352 353 string[string] messages; 354 355 mixin IO!(language, messages); 356 357 } 358 359 /** 360 * Adds a plugin that has been loaded at runtime. 361 */ 362 @serverbound struct AddPlugin { 363 364 enum ubyte ID = 21; 365 366 /** 367 * Plugin's id given by the node. It must be unique. 368 */ 369 uint id; 370 371 string name; 372 373 string version_; 374 375 mixin IO!(id, name, version_); 376 377 } 378 379 /** 380 * Removes a plugin that has been unloaded at runtime. 381 */ 382 @serverbound struct RemovePlugin { 383 384 enum ubyte ID = 22; 385 386 /** 387 * Plugin's id given in the NodeInfo packet or in the AddPlugin packet. 388 */ 389 uint id; 390 391 mixin IO!(id); 392 393 } 394 395 /** 396 * Notifies the hub that a new world has been created on the node. 397 */ 398 @serverbound struct AddWorld { 399 400 enum ubyte ID = 23; 401 402 /** 403 * Id of the world. Must be unique on the node. 404 */ 405 uint worldId; 406 407 /** 408 * World's group id. Similar worlds can be grouped together 409 * and removed with the RemoveWorldGroup packet. 410 * If the world is independent and has no group the group id must be the same 411 * as the world id. 412 */ 413 uint groupId; 414 415 /** 416 * Name of the world, it doesn't need to be unique. 417 */ 418 string name; 419 420 /** 421 * World's dimension in the MCPE format (0: overworld, 1: nether, 2: end). 422 */ 423 ubyte dimension; 424 425 /** 426 * Indicates whether the world is the node's default (the one where new players 427 * are spawned into if not handled by plugins). 428 * If the node does not support default worlds or it simply doesn't have one 429 * this field should be left to its default value (false). 430 * If the hub receives more than one default world it should consider the last 431 * received one as the default world. 432 */ 433 bool default_; 434 435 mixin IO!(worldId, groupId, name, dimension); 436 437 } 438 439 /** 440 * Notifies the hub that a world has been removed from the node. 441 */ 442 @serverbound struct RemoveWorld { 443 444 enum ubyte ID = 24; 445 446 /** 447 * Id of the world that has been removed, previosly added using the 448 * AddWorld packet. 449 */ 450 uint worldId; 451 452 mixin IO!(worldId); 453 454 } 455 456 /** 457 * Removes a group of worlds. 458 */ 459 @serverbound struct RemoveWorldGroup { 460 461 enum ubyte ID = 25; 462 463 uint groupId; 464 465 mixin IO!(groupId); 466 467 } 468 469 /** 470 * Gives the node the credentials that will be used by a remote panel 471 * client to connect to a world. 472 */ 473 @clientbound struct WebAdminCredentials { 474 475 enum ubyte ID = 26; 476 477 /** 478 * Id of the request, generated by the hub. To the request are associated the 479 * login credentials and the world to track. 480 */ 481 uint requestId; 482 483 /** 484 * Address used by the client to connect. May be a represantion of 485 * an ipv4 (`134.56.1.55`), ipv6 (`44:5:12::9`) or unix address (`~/tmp/rc`). 486 */ 487 string address; 488 489 /** 490 * Hash generated by the hub that will be used by the remote panel to 491 * perform authentication. 492 */ 493 ubyte[32] hash; 494 495 /** 496 * World group that the remote panel client will connect to. 497 */ 498 uint groupId; 499 500 mixin IO!(requestId, address, hash, groupId); 501 502 }