1 /* 2 * Copyright (c) 2017-2018 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 /** 16 * Copyright: 2017-2020 sel-project 17 * License: LGPL-3.0 18 * Authors: Kripth 19 * Source: $(HTTP github.com/sel-project/sel-server/sel/server/client.d, sel/server/client.d) 20 */ 21 module sel.server.client; 22 23 import core.atomic : atomicOp; 24 25 import std.json : JSONValue; 26 import std.socket : Address; 27 import std.uuid : UUID; 28 29 enum InputMode { 30 31 keyboard, 32 touch, 33 controller, 34 35 } 36 37 /** 38 * Represents a generic game client. 39 */ 40 class Client { 41 42 // same as hncom's 43 public enum ubyte BEDROCK = 0; 44 public enum ubyte JAVA = 1; 45 46 protected enum VERSION_MINECRAFT = "Minecraft"; 47 protected enum VERSION_JAVA = "Minecraft: Java Edition"; 48 protected enum VERSION_EDU = "Minecraft: Education Edition"; 49 50 private static shared uint _id; 51 52 public immutable uint id; 53 public immutable ubyte type; 54 public immutable uint protocol; 55 56 private Address _address; 57 private string _username; 58 private UUID _uuid; 59 60 public immutable string gameName; 61 public immutable string gameVersion; 62 public immutable string game; 63 64 public string serverIp; 65 public ushort serverPort; 66 67 public string skinName; 68 public immutable(ubyte)[] skinData; 69 public string skinGeometryName; 70 public immutable(ubyte)[] skinGeometryData; 71 public immutable(ubyte)[] skinCape; 72 public InputMode inputMode = InputMode.keyboard; 73 public string language; 74 75 public JSONValue gameData; 76 77 public void delegate(ubyte[]) handler; 78 79 public shared this(ubyte type, uint protocol, Address address, string username, UUID uuid, string gameName, string gameVersion) { 80 this.id = atomicOp!"+="(_id, 1); 81 this.type = type; 82 this.protocol = protocol; 83 this._address = cast(shared)address; 84 this._username = username; 85 this._uuid = cast(shared)uuid; 86 this.gameName = gameName; 87 this.gameVersion = gameVersion; 88 this.game = gameName ~ " " ~ gameVersion; 89 //TODO set handler 90 } 91 92 /** 93 * Gets the client's address. May be either an ipv4 or ipv6, depending on 94 * the address where the server is binded to. 95 * Example: 96 * --- 97 * if(cast(InternetAddress)client.address) { 98 * writeln(client, " is ipv6"); 99 * } 100 * --- 101 */ 102 public shared pure nothrow @property @trusted @nogc Address address() { 103 return cast()this._address; 104 } 105 106 /** 107 * Gets the client's username. 108 */ 109 public shared pure nothrow @property @safe @nogc string username() { 110 return this._username; 111 } 112 113 /** 114 * Gets the client's UUID. 115 */ 116 public shared pure nothrow @property @safe @nogc UUID uuid() { 117 return cast()this._uuid; 118 } 119 120 public abstract shared synchronized void send(ubyte[] packet); 121 122 public abstract shared synchronized void directSend(ubyte[] payload); 123 124 public final shared void disconnect(string message, bool translation=false, string[] params=[]) { 125 this.disconnectImpl(message, translation, params); 126 } 127 128 public final shared void disconnect(string message, string[] params) { 129 this.disconnect(message, true, params); 130 } 131 132 protected abstract shared void disconnectImpl(string message, bool translation, string[] params); 133 134 public shared string toString() { 135 return "Client(" ~ this.username ~ ", " ~ this.uuid.toString() ~ ")"; 136 } 137 138 }