Separated PlayerSpawnEvent and PlayerJoinEvent, PluginMessages now uses String channels, Added PluginMessageEvent

This commit is contained in:
LOOHP 2022-04-25 19:13:31 +01:00
parent 7ad2b19177
commit 0ac9810554
9 changed files with 135 additions and 38 deletions

View File

@ -24,7 +24,7 @@
<groupId>com.loohp</groupId> <groupId>com.loohp</groupId>
<artifactId>Limbo</artifactId> <artifactId>Limbo</artifactId>
<name>Limbo</name> <name>Limbo</name>
<version>0.6.13-ALPHA</version> <version>0.6.14-ALPHA</version>
<description>Standalone Limbo Minecraft Server.</description> <description>Standalone Limbo Minecraft Server.</description>
<url>https://github.com/LOOHP/Limbo</url> <url>https://github.com/LOOHP/Limbo</url>

View File

@ -19,23 +19,12 @@
package com.loohp.limbo.events.player; package com.loohp.limbo.events.player;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.player.Player; import com.loohp.limbo.player.Player;
public class PlayerJoinEvent extends PlayerEvent { public class PlayerJoinEvent extends PlayerEvent {
private Location spawnLocation; public PlayerJoinEvent(Player player) {
public PlayerJoinEvent(Player player, Location spawnLoc) {
super(player); super(player);
spawnLocation = spawnLoc;
} }
public Location getSpawnLocation() {
return spawnLocation;
}
public void setSpawnLocation(Location spawnLocation) {
this.spawnLocation = spawnLocation;
}
} }

View File

@ -0,0 +1,41 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2022. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.events.player;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.player.Player;
public class PlayerSpawnEvent extends PlayerEvent {
private Location spawnLocation;
public PlayerSpawnEvent(Player player, Location spawnLoc) {
super(player);
spawnLocation = spawnLoc;
}
public Location getSpawnLocation() {
return spawnLocation;
}
public void setSpawnLocation(Location spawnLocation) {
this.spawnLocation = spawnLocation;
}
}

View File

@ -0,0 +1,46 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2022. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.events.player;
import com.loohp.limbo.player.Player;
import com.loohp.limbo.utils.NamespacedKey;
import java.util.Arrays;
public class PluginMessageEvent extends PlayerEvent {
private String channel;
private byte[] data;
public PluginMessageEvent(Player player, String channel, byte[] data) {
super(player);
this.channel = channel;
this.data = data;
}
public String getChannel() {
return channel;
}
public byte[] getData() {
return Arrays.copyOf(data, data.length);
}
}

View File

@ -21,11 +21,13 @@ package com.loohp.limbo.network;
import com.loohp.limbo.Limbo; import com.loohp.limbo.Limbo;
import com.loohp.limbo.events.player.PlayerJoinEvent; import com.loohp.limbo.events.player.PlayerJoinEvent;
import com.loohp.limbo.events.player.PlayerSpawnEvent;
import com.loohp.limbo.events.player.PlayerLoginEvent; import com.loohp.limbo.events.player.PlayerLoginEvent;
import com.loohp.limbo.events.player.PlayerMoveEvent; import com.loohp.limbo.events.player.PlayerMoveEvent;
import com.loohp.limbo.events.player.PlayerQuitEvent; import com.loohp.limbo.events.player.PlayerQuitEvent;
import com.loohp.limbo.events.player.PlayerResourcePackStatusEvent; import com.loohp.limbo.events.player.PlayerResourcePackStatusEvent;
import com.loohp.limbo.events.player.PlayerSelectedSlotChangeEvent; import com.loohp.limbo.events.player.PlayerSelectedSlotChangeEvent;
import com.loohp.limbo.events.player.PluginMessageEvent;
import com.loohp.limbo.events.status.StatusPingEvent; import com.loohp.limbo.events.status.StatusPingEvent;
import com.loohp.limbo.file.ServerProperties; import com.loohp.limbo.file.ServerProperties;
import com.loohp.limbo.location.Location; import com.loohp.limbo.location.Location;
@ -41,6 +43,7 @@ import com.loohp.limbo.network.protocol.packets.PacketOut;
import com.loohp.limbo.network.protocol.packets.PacketPlayInChat; import com.loohp.limbo.network.protocol.packets.PacketPlayInChat;
import com.loohp.limbo.network.protocol.packets.PacketPlayInHeldItemChange; import com.loohp.limbo.network.protocol.packets.PacketPlayInHeldItemChange;
import com.loohp.limbo.network.protocol.packets.PacketPlayInKeepAlive; import com.loohp.limbo.network.protocol.packets.PacketPlayInKeepAlive;
import com.loohp.limbo.network.protocol.packets.PacketPlayInPluginMessaging;
import com.loohp.limbo.network.protocol.packets.PacketPlayInPosition; import com.loohp.limbo.network.protocol.packets.PacketPlayInPosition;
import com.loohp.limbo.network.protocol.packets.PacketPlayInPositionAndLook; import com.loohp.limbo.network.protocol.packets.PacketPlayInPositionAndLook;
import com.loohp.limbo.network.protocol.packets.PacketPlayInResourcePackStatus; import com.loohp.limbo.network.protocol.packets.PacketPlayInResourcePackStatus;
@ -119,7 +122,7 @@ import java.util.stream.Stream;
public class ClientConnection extends Thread { public class ClientConnection extends Thread {
private static final NamespacedKey DEFAULT_HANDLER_NAMESPACE = new NamespacedKey("default"); private static final NamespacedKey DEFAULT_HANDLER_NAMESPACE = new NamespacedKey("default");
private static final NamespacedKey BRAND_ANNOUNCE_CHANNEL = new NamespacedKey("brand"); private static final String BRAND_ANNOUNCE_CHANNEL = new NamespacedKey("brand").toString();
private final Random random = new Random(); private final Random random = new Random();
private final Socket clientSocket; private final Socket clientSocket;
@ -192,6 +195,11 @@ public class ClientConnection extends Thread {
return ready; return ready;
} }
public void sendPluginMessage(String channel, byte[] data) throws IOException {
PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(channel, data);
sendPacket(packet);
}
public synchronized void sendPacket(PacketOut packet) throws IOException { public synchronized void sendPacket(PacketOut packet) throws IOException {
if (channel.writePacket(packet)) { if (channel.writePacket(packet)) {
setLastPacketTimestamp(System.currentTimeMillis()); setLastPacketTimestamp(System.currentTimeMillis());
@ -459,8 +467,8 @@ public class ClientConnection extends Thread {
ServerProperties properties = Limbo.getInstance().getServerProperties(); ServerProperties properties = Limbo.getInstance().getServerProperties();
Location worldSpawn = properties.getWorldSpawn(); Location worldSpawn = properties.getWorldSpawn();
PlayerJoinEvent joinEvent = Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player, worldSpawn)); PlayerSpawnEvent spawnEvent = Limbo.getInstance().getEventsManager().callEvent(new PlayerSpawnEvent(player, worldSpawn));
worldSpawn = joinEvent.getSpawnLocation(); worldSpawn = spawnEvent.getSpawnLocation();
World world = worldSpawn.getWorld(); World world = worldSpawn.getWorld();
PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds(), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, 8, properties.isReducedDebugInfo(), true, false, true); PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds(), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, 8, properties.isReducedDebugInfo(), true, false, true);
@ -469,8 +477,7 @@ public class ClientConnection extends Thread {
ByteArrayOutputStream brandOut = new ByteArrayOutputStream(); ByteArrayOutputStream brandOut = new ByteArrayOutputStream();
DataTypeIO.writeString(new DataOutputStream(brandOut), properties.getServerModName(), StandardCharsets.UTF_8); DataTypeIO.writeString(new DataOutputStream(brandOut), properties.getServerModName(), StandardCharsets.UTF_8);
PacketPlayOutPluginMessaging brand = new PacketPlayOutPluginMessaging(BRAND_ANNOUNCE_CHANNEL, brandOut.toByteArray()); sendPluginMessage(BRAND_ANNOUNCE_CHANNEL, brandOut.toByteArray());
sendPacket(brand);
SkinResponse skinresponce = (isVelocityModern || isBungeeGuard || isBungeecord) && forwardedSkin != null ? forwardedSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName()); SkinResponse skinresponce = (isVelocityModern || isBungeeGuard || isBungeecord) && forwardedSkin != null ? forwardedSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName());
PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null; PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null;
@ -508,6 +515,8 @@ public class ClientConnection extends Thread {
PacketPlayOutEntityMetadata show = new PacketPlayOutEntityMetadata(player, false, Player.class.getDeclaredField("skinLayers")); PacketPlayOutEntityMetadata show = new PacketPlayOutEntityMetadata(player, false, Player.class.getDeclaredField("skinLayers"));
sendPacket(show); sendPacket(show);
Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player));
if (properties.isAllowFlight()) { if (properties.isAllowFlight()) {
PacketPlayOutGameState state = new PacketPlayOutGameState(3, player.getGamemode().getId()); PacketPlayOutGameState state = new PacketPlayOutGameState(3, player.getGamemode().getId());
sendPacket(state); sendPacket(state);
@ -643,6 +652,9 @@ public class ClientConnection extends Thread {
if (rpcheck.getLoadedValue().equals(EnumResourcePackStatus.DECLINED) && properties.getResourcePackRequired()) { if (rpcheck.getLoadedValue().equals(EnumResourcePackStatus.DECLINED) && properties.getResourcePackRequired()) {
player.disconnect(new TranslatableComponent("multiplayer.requiredTexturePrompt.disconnect")); player.disconnect(new TranslatableComponent("multiplayer.requiredTexturePrompt.disconnect"));
} }
} else if (packetIn instanceof PacketPlayInPluginMessaging) {
PacketPlayInPluginMessaging inPluginMessaging = (PacketPlayInPluginMessaging) packetIn;
Limbo.getInstance().getEventsManager().callEvent(new PluginMessageEvent(player, inPluginMessaging.getChannel(), inPluginMessaging.getData()));
} }
} catch (Exception e) { } catch (Exception e) {
break; break;

View File

@ -19,32 +19,30 @@
package com.loohp.limbo.network.protocol.packets; package com.loohp.limbo.network.protocol.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NamespacedKey;
public class PacketPlayInPluginMessaging extends PacketIn { public class PacketPlayInPluginMessaging extends PacketIn {
private NamespacedKey channel; private String channel;
private byte[] data; private byte[] data;
public PacketPlayInPluginMessaging(NamespacedKey channel, byte[] data) { public PacketPlayInPluginMessaging(String channel, byte[] data) {
this.channel = channel; this.channel = channel;
this.data = data; this.data = data;
} }
public PacketPlayInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException { public PacketPlayInPluginMessaging(DataInputStream in, int packetLength, int packetId) throws IOException {
String rawChannel = DataTypeIO.readString(in, StandardCharsets.UTF_8); String channel = DataTypeIO.readString(in, StandardCharsets.UTF_8);
channel = new NamespacedKey(rawChannel); int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getStringLength(channel, StandardCharsets.UTF_8);
int dataLength = packetLength - DataTypeIO.getVarIntLength(packetId) - DataTypeIO.getStringLength(rawChannel, StandardCharsets.UTF_8);
data = new byte[dataLength]; data = new byte[dataLength];
in.readFully(data); in.readFully(data);
} }
public NamespacedKey getChannel() { public String getChannel() {
return channel; return channel;
} }

View File

@ -19,25 +19,24 @@
package com.loohp.limbo.network.protocol.packets; package com.loohp.limbo.network.protocol.packets;
import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.NamespacedKey;
public class PacketPlayOutPluginMessaging extends PacketOut { public class PacketPlayOutPluginMessaging extends PacketOut {
private NamespacedKey channel; private String channel;
private byte[] data; private byte[] data;
public PacketPlayOutPluginMessaging(NamespacedKey channel, byte[] data) { public PacketPlayOutPluginMessaging(String channel, byte[] data) {
this.channel = channel; this.channel = channel;
this.data = data; this.data = data;
} }
public NamespacedKey getChannel() { public String getChannel() {
return channel; return channel;
} }
@ -51,7 +50,7 @@ public class PacketPlayOutPluginMessaging extends PacketOut {
DataOutputStream output = new DataOutputStream(buffer); DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass())); output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeString(output, channel.toString(), StandardCharsets.UTF_8); DataTypeIO.writeString(output, channel, StandardCharsets.UTF_8);
output.write(data); output.write(data);
return buffer.toByteArray(); return buffer.toByteArray();

View File

@ -48,6 +48,7 @@ import com.loohp.limbo.network.protocol.packets.PacketPlayOutRespawn;
import com.loohp.limbo.utils.BungeecordAdventureConversionUtils; import com.loohp.limbo.utils.BungeecordAdventureConversionUtils;
import com.loohp.limbo.utils.GameMode; import com.loohp.limbo.utils.GameMode;
import com.loohp.limbo.utils.NamespacedKey;
import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.audience.MessageType;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.identity.Identity; import net.kyori.adventure.identity.Identity;
@ -233,6 +234,15 @@ public class Player extends LivingEntity implements CommandSender {
super.teleport(location); super.teleport(location);
} }
public void sendPluginMessage(NamespacedKey channel, byte[] data) throws IOException {
sendPluginMessage(channel.toString(), data);
}
@Deprecated
public void sendPluginMessage(String channel, byte[] data) throws IOException {
clientConnection.sendPluginMessage(channel, data);
}
public void sendMessage(String message, UUID uuid) { public void sendMessage(String message, UUID uuid) {
sendMessage(Identity.identity(uuid), LegacyComponentSerializer.legacySection().deserialize(message)); sendMessage(Identity.identity(uuid), LegacyComponentSerializer.legacySection().deserialize(message));
} }

View File

@ -32,11 +32,13 @@ import com.loohp.limbo.network.protocol.packets.PacketPlayOutPluginMessaging;
public class BungeeLoginMessageUtils { public class BungeeLoginMessageUtils {
public static final String BUNGEECORD_MAIN = new NamespacedKey("bungeecord", "main").toString();
public static void sendUUIDRequest(DataOutputStream output) throws IOException { public static void sendUUIDRequest(DataOutputStream output) throws IOException {
ByteArrayDataOutput out = ByteStreams.newDataOutput(); ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("UUID"); out.writeUTF("UUID");
PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray()); PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(BUNGEECORD_MAIN, out.toByteArray());
byte[] packetByte = packet.serializePacket(); byte[] packetByte = packet.serializePacket();
DataTypeIO.writeVarInt(output, packetByte.length); DataTypeIO.writeVarInt(output, packetByte.length);
output.write(packetByte); output.write(packetByte);
@ -48,7 +50,7 @@ public class BungeeLoginMessageUtils {
if (subchannel.equals("UUID")) { if (subchannel.equals("UUID")) {
return UUID.fromString(in.readUTF()); return UUID.fromString(in.readUTF());
} else { } else {
throw new RuntimeException("Bungeecord Message receieved is not an IP"); throw new RuntimeException("Bungeecord Message received is not an IP");
} }
} }
@ -56,7 +58,7 @@ public class BungeeLoginMessageUtils {
ByteArrayDataOutput out = ByteStreams.newDataOutput(); ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("IP"); out.writeUTF("IP");
PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray()); PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(BUNGEECORD_MAIN, out.toByteArray());
byte[] packetByte = packet.serializePacket(); byte[] packetByte = packet.serializePacket();
DataTypeIO.writeVarInt(output, packetByte.length); DataTypeIO.writeVarInt(output, packetByte.length);
output.write(packetByte); output.write(packetByte);
@ -70,7 +72,7 @@ public class BungeeLoginMessageUtils {
in.readInt(); in.readInt();
return InetAddress.getByName(ip); return InetAddress.getByName(ip);
} else { } else {
throw new RuntimeException("Bungeecord Message receieved is not an IP"); throw new RuntimeException("Bungeecord Message received is not an IP");
} }
} }