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/event/node/player.d, selery/event/node/player.d) 28 */ 29 module selery.event.node.player; 30 31 import std.conv : to; 32 33 import selery.about : Software; 34 import selery.event.event : Cancellable; 35 import selery.event.node.server : NodeServerEvent; 36 import selery.hncom.player : Add, Remove; 37 import selery.node.server : NodeServer; 38 import selery.player.player : PlayerInfo, Player; 39 import selery.world.world : WorldInfo, World; 40 41 class PlayerEvent : NodeServerEvent { 42 43 private const(PlayerInfo) _player; 44 45 public pure nothrow @safe @nogc this(shared NodeServer server, inout PlayerInfo player) { 46 super(server); 47 this._player = player; 48 } 49 50 public final pure nothrow @property @safe @nogc const(PlayerInfo) player() { 51 return this._player; 52 } 53 54 } 55 56 /** 57 * Event called after the Player class for the now logged in player is created. 58 * It's the first event called after the creation of the player, before PlayerPreSpawnEvent. 59 * While this event is handled the client will see the "loading world" screen in its device, 60 * waiting for the chunks that will be sent after PlayerPreSpawnEvent (that is called by 61 * the world and every time a player changes world). That also means that this event 62 * will be called only once per player-session. 63 */ 64 final class PlayerJoinEvent : PlayerEvent { 65 66 enum Reason : ubyte { 67 68 firstJoin = Add.FIRST_JOIN, 69 transferred = Add.TRANSFERRED, 70 forciblyTransferred = Add.FORCIBLY_TRANSFERRED 71 72 } 73 74 private immutable ubyte _reason; 75 76 public shared(WorldInfo) world; 77 78 public pure nothrow @safe @nogc this(shared NodeServer server, inout PlayerInfo player, ubyte reason) { 79 super(server, player); 80 this._reason = reason; 81 } 82 83 public pure nothrow @property @safe @nogc ubyte reason() { 84 return this._reason; 85 } 86 87 } 88 89 /** 90 * Event called when a player leaves the server, after PlayerDespawnEvent. 91 * It's the last event called for the player, after it lefts the server, and 92 * is only called once, like PlayerJoinEvent. 93 * Example: 94 * --- 95 * @effect playerleft(PlayerLeftEvent event) { 96 * assert(!event.player.online); 97 * } 98 * --- 99 */ 100 final class PlayerLeftEvent : PlayerEvent { 101 102 enum Reason : ubyte { 103 104 left = Remove.LEFT, 105 timedOut = Remove.TIMED_OUT, 106 kicked = Remove.KICKED, 107 transferred = Remove.TRANSFERRED 108 109 } 110 111 private immutable ubyte _reason; 112 113 public pure nothrow @safe @nogc this(shared NodeServer server, inout PlayerInfo player, ubyte reason) { 114 super(server, player); 115 this._reason = reason; 116 } 117 118 public pure nothrow @property @safe @nogc ubyte reason() { 119 return this._reason; 120 } 121 122 } 123 124 /** 125 * Event called when the player's language is updated (from the client or from 126 * a plugin). The old and the new languages will always be one in the server's accepted 127 * ones, as indicated in the hub's configuration file (accepted-languages field). 128 * Example: 129 * --- 130 * @event changeLanguage(PlayerLanguageUpdatedEvent event) { 131 * log(event.player.name, " is changing language from ", event.currentLanguage, " to ", event.newLanguage); 132 * } 133 * --- 134 */ 135 final class PlayerLanguageUpdatedEvent : PlayerEvent, Cancellable { 136 137 mixin Cancellable.Implementation; 138 139 public immutable string oldLanguage; 140 public immutable string newLanguage; 141 142 public pure nothrow @safe @nogc this(shared NodeServer server, inout PlayerInfo player, string lang) { 143 super(server, player); 144 this.oldLanguage = player.language; 145 this.newLanguage = lang; 146 } 147 148 } 149 150 /** 151 * Event called when the player's latency is updated from the hub. 152 * Example: 153 * --- 154 * @event updateLatency(PlayerLatencyUpdatedEvent event) { 155 * event.player.title = event.latency.to!string ~ " ms"; 156 * } 157 * --- 158 */ 159 final class PlayerLatencyUpdatedEvent : PlayerEvent { 160 161 public pure nothrow @safe @nogc this(shared NodeServer server, inout PlayerInfo player) { 162 super(server, player); 163 } 164 165 /** 166 * Gets the player's latency. 167 * Example: 168 * --- 169 * assert(event.latency == event.player.latency); 170 * --- 171 */ 172 public pure nothrow @property @safe @nogc uint latency() { 173 return this.player.latency; 174 } 175 176 } 177 178 /** 179 * Event called when the player's packet loss is updated from the hub. 180 * The packet loss is only calculated for players that use a connectionless 181 * protocol like UDP (only Minecraft: Pocket Edition). 182 * Example: 183 * --- 184 * @event updatePacketLoss(PlayerPacketLossUpdatedEvent event) { 185 * event.player.title = event.packetLoss.to!string ~ "%"; 186 * assert(event.player.pe); 187 * } 188 * --- 189 */ 190 final class PlayerPacketLossUpdatedEvent : PlayerEvent { 191 192 public pure nothrow @safe @nogc this(shared NodeServer server, inout PlayerInfo player) { 193 super(server, player); 194 } 195 196 /** 197 * Gets the player's packet loss. 198 * Example: 199 * --- 200 * assert(event.packetLoss == event.player.packetLoss); 201 * --- 202 */ 203 public pure nothrow @property @safe @nogc float packetLoss() { 204 return this.player.packetLoss; 205 } 206 207 }