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