Minecraft 1.19.3

This commit is contained in:
LOOHP 2022-12-07 21:38:20 +00:00
parent c720a0fd67
commit 50fd145d77
13 changed files with 45343 additions and 28768 deletions

View File

@ -136,7 +136,7 @@
</executions> </executions>
</plugin> </plugin>
</plugins> </plugins>
<finalName>${project.artifactId}-${project.version}-1.19.2</finalName> <finalName>${project.artifactId}-${project.version}-1.19.3</finalName>
</build> </build>
<profiles> <profiles>

View File

@ -131,8 +131,8 @@ public class Limbo {
//=========================== //===========================
public final String SERVER_IMPLEMENTATION_VERSION = "1.19.2"; public final String SERVER_IMPLEMENTATION_VERSION = "1.19.3";
public final int SERVER_IMPLEMENTATION_PROTOCOL = 760; public final int SERVER_IMPLEMENTATION_PROTOCOL = 761;
public final String LIMBO_IMPLEMENTATION_VERSION; public final String LIMBO_IMPLEMENTATION_VERSION;
private AtomicBoolean isRunning; private AtomicBoolean isRunning;

View File

@ -41,12 +41,12 @@ import java.io.OutputStreamWriter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.HashSet; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Optional; import java.util.Optional;
import java.util.Properties; import java.util.Properties;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
public class ServerProperties { public class ServerProperties {
@ -77,7 +77,7 @@ public class ServerProperties {
private double ticksPerSecond; private double ticksPerSecond;
private boolean handshakeVerbose; private boolean handshakeVerbose;
private boolean enforceWhitelist; private boolean enforceWhitelist;
private Set<UUID> whitelist; private Map<UUID, String> whitelist;
private String resourcePackSHA1; private String resourcePackSHA1;
private String resourcePackLink; private String resourcePackLink;
@ -191,20 +191,26 @@ public class ServerProperties {
} }
enforceWhitelist = Boolean.parseBoolean(prop.getProperty("enforce-whitelist")); enforceWhitelist = Boolean.parseBoolean(prop.getProperty("enforce-whitelist"));
if (enforceWhitelist) { reloadWhitelist();
reloadWhitelist();
}
Limbo.getInstance().getConsole().sendMessage("Loaded server.properties"); Limbo.getInstance().getConsole().sendMessage("Loaded server.properties");
} }
public void reloadWhitelist() { public void reloadWhitelist() {
Console console = Limbo.getInstance().getConsole(); Console console = Limbo.getInstance().getConsole();
File whitelistFile = new File("whitelist.json");
whitelist = new HashSet<>(); if (!whitelistFile.exists()) {
try (PrintWriter pw = new PrintWriter(new OutputStreamWriter(Files.newOutputStream(whitelistFile.toPath())))) {
pw.println("[]");
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
whitelist = new HashMap<>();
try { try {
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();
Object obj = parser.parse(new InputStreamReader(Files.newInputStream(new File("whitelist.json").toPath()), StandardCharsets.UTF_8)); Object obj = parser.parse(new InputStreamReader(Files.newInputStream(whitelistFile.toPath()), StandardCharsets.UTF_8));
if (!(obj instanceof JSONArray)) { if (!(obj instanceof JSONArray)) {
console.sendMessage("whitelist: expected [] got {}"); console.sendMessage("whitelist: expected [] got {}");
@ -231,8 +237,9 @@ public class ServerProperties {
} }
String uuidStr = (String) o; String uuidStr = (String) o;
UUID allowedUuid = UUID.fromString(uuidStr); UUID uuid = UUID.fromString(uuidStr);
whitelist.add(allowedUuid); String name = element.containsKey("name") ? (String) element.get("name") : null;
whitelist.put(uuid, name);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -352,7 +359,7 @@ public class ServerProperties {
} }
public boolean uuidWhitelisted(UUID uuid) { public boolean uuidWhitelisted(UUID uuid) {
return whitelist.contains(uuid); return whitelist.containsKey(uuid);
} }
public String getResourcePackLink() { public String getResourcePackLink() {

View File

@ -107,7 +107,7 @@ public class Channel implements AutoCloseable {
@Override @Override
public synchronized void close() throws Exception { public synchronized void close() throws Exception {
if (valid.compareAndSet(false, true)) { if (valid.compareAndSet(true, false)) {
input.close(); input.close();
output.close(); output.close();
} }

View File

@ -21,12 +21,12 @@ 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.PlayerSpawnEvent;
import com.loohp.limbo.events.player.PluginMessageEvent; 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;
@ -88,7 +88,6 @@ import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse;
import com.loohp.limbo.utils.NamespacedKey; import com.loohp.limbo.utils.NamespacedKey;
import com.loohp.limbo.world.BlockPosition; import com.loohp.limbo.world.BlockPosition;
import com.loohp.limbo.world.World; import com.loohp.limbo.world.World;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
@ -104,11 +103,14 @@ import java.io.DataInput;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -121,8 +123,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.io.StringWriter;
import java.io.PrintWriter;
public class ClientConnection extends Thread { public class ClientConnection extends Thread {
@ -429,7 +429,7 @@ public class ClientConnection extends Thread {
boolean bungeeGuardFound = false; boolean bungeeGuardFound = false;
if (skinData != "") { if (!skinData.equals("")) {
JSONArray skinJson = (JSONArray) new JSONParser().parse(skinData); JSONArray skinJson = (JSONArray) new JSONParser().parse(skinData);
for (Object obj : skinJson) { for (Object obj : skinJson) {
@ -460,10 +460,10 @@ public class ClientConnection extends Thread {
disconnectDuringLogin(new BaseComponent[] {new TextComponent(ChatColor.RED + "Please connect from the proxy!")}); disconnectDuringLogin(new BaseComponent[] {new TextComponent(ChatColor.RED + "Please connect from the proxy!")});
} }
} }
int messageId = this.random.nextInt(); int messageId = this.random.nextInt();
while (clientSocket.isConnected()) { while (clientSocket.isConnected()) {
PacketIn packetIn = channel.readPacket(); PacketIn packetIn = channel.readPacket();
if (packetIn instanceof PacketLoginInLoginStart) { if (packetIn instanceof PacketLoginInLoginStart) {
PacketLoginInLoginStart start = (PacketLoginInLoginStart) packetIn; PacketLoginInLoginStart start = (PacketLoginInLoginStart) packetIn;
String username = start.getUsername(); String username = start.getUsername();
@ -474,7 +474,10 @@ public class ClientConnection extends Thread {
continue; continue;
} }
UUID uuid = isBungeecord || isBungeeGuard ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); UUID uuid = isBungeecord || isBungeeGuard ? bungeeUUID : (start.hasUniqueId() ? start.getUniqueId() : null);
if (uuid == null) {
uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
}
if (!properties.enforceWhitelist() && properties.uuidWhitelisted(uuid)) { if (!properties.enforceWhitelist() && properties.uuidWhitelisted(uuid)) {
disconnectDuringLogin(TextComponent.fromLegacyText("You are not whitelisted on the server")); disconnectDuringLogin(TextComponent.fromLegacyText("You are not whitelisted on the server"));
@ -489,7 +492,6 @@ public class ClientConnection extends Thread {
player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager()); player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40)); player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
Limbo.getInstance().addPlayer(player); Limbo.getInstance().addPlayer(player);
break; break;
} else if (packetIn instanceof PacketLoginInPluginMessaging) { } else if (packetIn instanceof PacketLoginInPluginMessaging) {
PacketLoginInPluginMessaging response = (PacketLoginInPluginMessaging) packetIn; PacketLoginInPluginMessaging response = (PacketLoginInPluginMessaging) packetIn;
@ -557,7 +559,7 @@ public class ClientConnection extends Thread {
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;
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PlayerInfoAction.ADD_PLAYER, player.getUniqueId(), new PlayerInfoData.PlayerInfoDataAddPlayer(player.getName(), Optional.ofNullable(skin), properties.getDefaultGamemode(), 0, false, Optional.empty())); PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(EnumSet.of(PlayerInfoAction.ADD_PLAYER, PlayerInfoAction.UPDATE_GAME_MODE, PlayerInfoAction.UPDATE_LISTED, PlayerInfoAction.UPDATE_LATENCY, PlayerInfoAction.UPDATE_DISPLAY_NAME), player.getUniqueId(), new PlayerInfoData.PlayerInfoDataAddPlayer(player.getName(), true, Optional.ofNullable(skin), properties.getDefaultGamemode(), 0, false, Optional.empty()));
sendPacket(info); sendPacket(info);
Set<PlayerAbilityFlags> flags = new HashSet<>(); Set<PlayerAbilityFlags> flags = new HashSet<>();
@ -619,7 +621,9 @@ public class ClientConnection extends Thread {
keepAliveTask = new TimerTask() { keepAliveTask = new TimerTask() {
@Override @Override
public void run() { public void run() {
if (ready) { if (state.equals(ClientState.DISCONNECTED)) {
this.cancel();
} else if (ready && state.equals(ClientState.PLAY)) {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (now - getLastPacketTimestamp() > 15000) { if (now - getLastPacketTimestamp() > 15000) {
PacketPlayOutKeepAlive keepAlivePacket = new PacketPlayOutKeepAlive(now); PacketPlayOutKeepAlive keepAlivePacket = new PacketPlayOutKeepAlive(now);
@ -629,8 +633,6 @@ public class ClientConnection extends Thread {
} catch (Exception e) { } catch (Exception e) {
} }
} }
} else {
this.cancel();
} }
} }
}; };

View File

@ -27,7 +27,7 @@ import com.loohp.limbo.utils.DataTypeIO;
public class PacketHandshakingIn extends PacketIn { public class PacketHandshakingIn extends PacketIn {
public static enum HandshakeType { public enum HandshakeType {
STATUS(1), STATUS(1),
LOGIN(2); LOGIN(2);

View File

@ -22,12 +22,15 @@ package com.loohp.limbo.network.protocol.packets;
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 java.util.Optional;
import java.util.UUID;
import com.loohp.limbo.utils.DataTypeIO; import com.loohp.limbo.utils.DataTypeIO;
public class PacketLoginInLoginStart extends PacketIn { public class PacketLoginInLoginStart extends PacketIn {
private String username; private String username;
private Optional<UUID> uuid;
public PacketLoginInLoginStart(String username) { public PacketLoginInLoginStart(String username) {
this.username = username; this.username = username;
@ -35,13 +38,10 @@ public class PacketLoginInLoginStart extends PacketIn {
public PacketLoginInLoginStart(DataInputStream in) throws IOException { public PacketLoginInLoginStart(DataInputStream in) throws IOException {
this.username = DataTypeIO.readString(in, StandardCharsets.UTF_8); this.username = DataTypeIO.readString(in, StandardCharsets.UTF_8);
boolean hasSigData = in.readBoolean(); if (in.readBoolean()) {
if (hasSigData) { this.uuid = Optional.of(DataTypeIO.readUUID(in));
in.readLong(); } else {
int publicKeyLength = DataTypeIO.readVarInt(in); this.uuid = Optional.empty();
in.readFully(new byte[publicKeyLength]);
int signatureLength = DataTypeIO.readVarInt(in);
in.readFully(new byte[signatureLength]);
} }
} }
@ -49,4 +49,11 @@ public class PacketLoginInLoginStart extends PacketIn {
return username; return username;
} }
public boolean hasUniqueId() {
return uuid.isPresent();
}
public UUID getUniqueId() {
return uuid.orElse(null);
}
} }

View File

@ -137,10 +137,10 @@ public class PacketPlayOutLogin extends PacketOut {
output.writeInt(entityId); output.writeInt(entityId);
output.writeBoolean(isHardcore); output.writeBoolean(isHardcore);
output.writeByte((byte) gamemode.getId()); output.writeByte((byte) gamemode.getId());
output.writeByte((byte) gamemode.getId()); output.writeByte(-1);
DataTypeIO.writeVarInt(output, worlds.size()); DataTypeIO.writeVarInt(output, worlds.size());
for (int u = 0; u < worlds.size(); u++) { for (World world : worlds) {
DataTypeIO.writeString(output, new NamespacedKey(worlds.get(u).getName()).toString(), StandardCharsets.UTF_8); DataTypeIO.writeString(output, new NamespacedKey(world.getName()).toString(), StandardCharsets.UTF_8);
} }
DataTypeIO.writeCompoundTag(output, dimensionCodec); DataTypeIO.writeCompoundTag(output, dimensionCodec);
DataTypeIO.writeString(output, world.getEnvironment().getNamespacedKey().toString(), StandardCharsets.UTF_8); DataTypeIO.writeString(output, world.getEnvironment().getNamespacedKey().toString(), StandardCharsets.UTF_8);

View File

@ -23,6 +23,7 @@ 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 java.util.EnumSet;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
@ -33,31 +34,26 @@ import com.loohp.limbo.utils.GameMode;
public class PacketPlayOutPlayerInfo extends PacketOut { public class PacketPlayOutPlayerInfo extends PacketOut {
public enum PlayerInfoAction { public enum PlayerInfoAction {
ADD_PLAYER(0), UPDATE_GAMEMODE(1), UPDATE_LATENCY(2), UPDATE_DISPLAY_NAME(3), REMOVE_PLAYER(4); ADD_PLAYER,
INITIALIZE_CHAT,
private final int id; UPDATE_GAME_MODE,
UPDATE_LISTED,
PlayerInfoAction(int id) { UPDATE_LATENCY,
this.id = id; UPDATE_DISPLAY_NAME;
}
public int getId() {
return id;
}
} }
private PlayerInfoAction action; private EnumSet<PlayerInfoAction> actions;
private UUID uuid; private UUID uuid;
private PlayerInfoData data; private PlayerInfoData data;
public PacketPlayOutPlayerInfo(PlayerInfoAction action, UUID uuid, PlayerInfoData data) { public PacketPlayOutPlayerInfo(EnumSet<PlayerInfoAction> actions, UUID uuid, PlayerInfoData data) {
this.action = action; this.actions = actions;
this.uuid = uuid; this.uuid = uuid;
this.data = data; this.data = data;
} }
public PlayerInfoAction getAction() { public EnumSet<PlayerInfoAction> getActions() {
return action; return actions;
} }
public UUID getUuid() { public UUID getUuid() {
@ -74,41 +70,52 @@ public class PacketPlayOutPlayerInfo 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.writeVarInt(output, action.getId());
DataTypeIO.writeEnumSet(output, actions, PlayerInfoAction.class);
DataTypeIO.writeVarInt(output, 1); DataTypeIO.writeVarInt(output, 1);
DataTypeIO.writeUUID(output, uuid); DataTypeIO.writeUUID(output, uuid);
switch (action) { PlayerInfoDataAddPlayer data = (PlayerInfoDataAddPlayer) this.data;
case ADD_PLAYER: for (PlayerInfoAction action : actions) {
PlayerInfoDataAddPlayer data = (PlayerInfoDataAddPlayer) this.data; switch (action) {
DataTypeIO.writeString(output, data.getName(), StandardCharsets.UTF_8); case ADD_PLAYER: {
if (data.getProperty().isPresent()) { DataTypeIO.writeString(output, data.getName(), StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, 1); if (data.getProperty().isPresent()) {
DataTypeIO.writeString(output, "textures", StandardCharsets.UTF_8); DataTypeIO.writeVarInt(output, 1);
DataTypeIO.writeString(output, data.getProperty().get().getSkin(), StandardCharsets.UTF_8); DataTypeIO.writeString(output, "textures", StandardCharsets.UTF_8);
output.writeBoolean(true); DataTypeIO.writeString(output, data.getProperty().get().getSkin(), StandardCharsets.UTF_8);
DataTypeIO.writeString(output, data.getProperty().get().getSignature(), StandardCharsets.UTF_8); output.writeBoolean(true);
} else { DataTypeIO.writeString(output, data.getProperty().get().getSignature(), StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, 0); } else {
DataTypeIO.writeVarInt(output, 0);
}
break;
}
case INITIALIZE_CHAT: {
break;
}
case UPDATE_GAME_MODE: {
DataTypeIO.writeVarInt(output, data.getGamemode().getId());
break;
}
case UPDATE_LISTED: {
output.writeBoolean(data.isListed());
break;
}
case UPDATE_LATENCY: {
DataTypeIO.writeVarInt(output, data.getPing());
break;
}
case UPDATE_DISPLAY_NAME: {
if (data.getDisplayNameJson().isPresent()) {
output.writeBoolean(true);
DataTypeIO.writeString(output, data.getDisplayNameJson().get(), StandardCharsets.UTF_8);
} else {
output.writeBoolean(false);
}
break;
}
} }
DataTypeIO.writeVarInt(output, data.getGamemode().getId());
DataTypeIO.writeVarInt(output, data.getPing());
if (data.getDisplayNameJson().isPresent()) {
output.writeBoolean(true);
DataTypeIO.writeString(output, data.getDisplayNameJson().get(), StandardCharsets.UTF_8);
} else {
output.writeBoolean(false);
}
output.writeBoolean(false);
break;
case REMOVE_PLAYER:
break;
case UPDATE_DISPLAY_NAME:
break;
case UPDATE_GAMEMODE:
break;
case UPDATE_LATENCY:
break;
} }
return buffer.toByteArray(); return buffer.toByteArray();
@ -121,15 +128,16 @@ public class PacketPlayOutPlayerInfo extends PacketOut {
public static class PlayerInfoDataAddPlayer extends PlayerInfoData { public static class PlayerInfoDataAddPlayer extends PlayerInfoData {
private String name; private String name;
private boolean listed;
private Optional<PlayerSkinProperty> skin; private Optional<PlayerSkinProperty> skin;
private GameMode gamemode; private GameMode gamemode;
private int ping; private int ping;
private boolean hasDisplayName; private boolean hasDisplayName;
private Optional<String> displayNameJson; private Optional<String> displayNameJson;
public PlayerInfoDataAddPlayer(String name, Optional<PlayerSkinProperty> skin, GameMode gamemode, int ping, public PlayerInfoDataAddPlayer(String name, boolean listed, Optional<PlayerSkinProperty> skin, GameMode gamemode, int ping, boolean hasDisplayName, Optional<String> displayNameJson) {
boolean hasDisplayName, Optional<String> displayNameJson) {
this.name = name; this.name = name;
this.listed = listed;
this.skin = skin; this.skin = skin;
this.gamemode = gamemode; this.gamemode = gamemode;
this.ping = ping; this.ping = ping;
@ -141,6 +149,10 @@ public class PacketPlayOutPlayerInfo extends PacketOut {
return name; return name;
} }
public boolean isListed() {
return listed;
}
public Optional<PlayerSkinProperty> getProperty() { public Optional<PlayerSkinProperty> getProperty() {
return skin; return skin;
} }

View File

@ -24,6 +24,9 @@ import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.BitSet;
import java.util.EnumSet;
import java.util.UUID; import java.util.UUID;
import com.loohp.limbo.world.BlockPosition; import com.loohp.limbo.world.BlockPosition;
@ -34,6 +37,47 @@ import net.querz.nbt.tag.Tag;
public class DataTypeIO { public class DataTypeIO {
public static <E extends Enum<E>> void writeEnumSet(DataOutputStream out, EnumSet<E> enumset, Class<E> oclass) throws IOException {
E[] ae = oclass.getEnumConstants();
BitSet bitset = new BitSet(ae.length);
for (int i = 0; i < ae.length; ++i) {
bitset.set(i, enumset.contains(ae[i]));
}
writeFixedBitSet(out, bitset, ae.length);
}
public static <E extends Enum<E>> EnumSet<E> readEnumSet(DataInputStream in, Class<E> oclass) throws IOException {
E[] ae = oclass.getEnumConstants();
BitSet bitset = readFixedBitSet(in, ae.length);
EnumSet<E> enumset = EnumSet.noneOf(oclass);
for (int i = 0; i < ae.length; ++i) {
if (bitset.get(i)) {
enumset.add(ae[i]);
}
}
return enumset;
}
public static void writeFixedBitSet(DataOutputStream out, BitSet bitset, int i) throws IOException {
if (bitset.length() > i) {
int j = bitset.length();
throw new RuntimeException("BitSet is larger than expected size (" + j + ">" + i + ")");
} else {
byte[] abyte = bitset.toByteArray();
out.write(Arrays.copyOf(abyte, -Math.floorDiv(-i, 8)));
}
}
public static BitSet readFixedBitSet(DataInputStream in, int i) throws IOException {
byte[] abyte = new byte[-Math.floorDiv(-i, 8)];
in.readFully(abyte);
return BitSet.valueOf(abyte);
}
public static void writeBlockPosition(DataOutputStream out, BlockPosition position) throws IOException { public static void writeBlockPosition(DataOutputStream out, BlockPosition position) throws IOException {
out.writeLong(((position.getX() & 0x3FFFFFF) << 38) | ((position.getZ() & 0x3FFFFFF) << 12) | (position.getY() & 0xFFF)); out.writeLong(((position.getX() & 0x3FFFFFF) << 38) | ((position.getZ() & 0x3FFFFFF) << 12) | (position.getY() & 0xFFF));
} }

File diff suppressed because it is too large Load Diff

View File

@ -12,44 +12,44 @@
"PacketLoginOutPluginMessaging": "0x04" "PacketLoginOutPluginMessaging": "0x04"
}, },
"PlayIn": { "PlayIn": {
"0x12": "PacketPlayInKeepAlive", "0x11": "PacketPlayInKeepAlive",
"0x04": "ServerboundChatCommandPacket", "0x04": "ServerboundChatCommandPacket",
"0x05": "PacketPlayInChat", "0x05": "PacketPlayInChat",
"0x15": "PacketPlayInPositionAndLook", "0x14": "PacketPlayInPositionAndLook",
"0x14": "PacketPlayInPosition", "0x13": "PacketPlayInPosition",
"0x16": "PacketPlayInRotation", "0x15": "PacketPlayInRotation",
"0x0D": "PacketPlayInPluginMessaging", "0x0C": "PacketPlayInPluginMessaging",
"0x09": "PacketPlayInTabComplete", "0x08": "PacketPlayInTabComplete",
"0x28": "PacketPlayInHeldItemChange", "0x28": "PacketPlayInHeldItemChange",
"0x24": "PacketPlayInResourcePackStatus" "0x24": "PacketPlayInResourcePackStatus"
}, },
"PlayOut": { "PlayOut": {
"PacketPlayOutLogin": "0x25", "PacketPlayOutLogin": "0x24",
"PacketPlayOutPositionAndLook": "0x39", "PacketPlayOutPositionAndLook": "0x38",
"PacketPlayOutSpawnPosition": "0x4D", "PacketPlayOutSpawnPosition": "0x4C",
"ClientboundSystemChatPacket": "0x62", "ClientboundSystemChatPacket": "0x60",
"PacketPlayOutPlayerAbilities": "0x31", "PacketPlayOutPlayerAbilities": "0x30",
"ClientboundLevelChunkWithLightPacket": "0x21", "ClientboundLevelChunkWithLightPacket": "0x20",
"PacketPlayOutUnloadChunk": "0x1C", "PacketPlayOutUnloadChunk": "0x1B",
"PacketPlayOutKeepAlive": "0x20", "PacketPlayOutKeepAlive": "0x1F",
"PacketPlayOutPlayerInfo": "0x37", "PacketPlayOutPlayerInfo": "0x36",
"PacketPlayOutUpdateViewPosition": "0x4B", "PacketPlayOutUpdateViewPosition": "0x4A",
"PacketPlayOutDisconnect": "0x19", "PacketPlayOutDisconnect": "0x17",
"PacketPlayOutPluginMessaging": "0x16", "PacketPlayOutPluginMessaging": "0x15",
"PacketPlayOutTabComplete": "0x0E", "PacketPlayOutTabComplete": "0x0D",
"PacketPlayOutDeclareCommands": "0x0F", "PacketPlayOutDeclareCommands": "0x0E",
"PacketPlayOutRespawn": "0x3E", "PacketPlayOutRespawn": "0x3E",
"PacketPlayOutGameState": "0x1D", "PacketPlayOutGameState": "0x1C",
"PacketPlayOutEntityDestroy": "0x3B", "PacketPlayOutEntityDestroy": "0x3A",
"PacketPlayOutEntityMetadata": "0x50", "PacketPlayOutEntityMetadata": "0x4E",
"PacketPlayOutSpawnEntity": "0x00", "PacketPlayOutSpawnEntity": "0x00",
"PacketPlayOutHeldItemChange": "0x4A", "PacketPlayOutHeldItemChange": "0x49",
"PacketPlayOutPlayerListHeaderFooter": "0x63", "PacketPlayOutPlayerListHeaderFooter": "0x61",
"PacketPlayOutResourcePackSend": "0x3D", "PacketPlayOutResourcePackSend": "0x3C",
"ClientboundSetTitlesAnimationPacket": "0x5E", "ClientboundSetTitlesAnimationPacket": "0x5C",
"ClientboundSetTitleTextPacket": "0x5D", "ClientboundSetTitleTextPacket": "0x5B",
"ClientboundSetSubtitleTextPacket": "0x5B", "ClientboundSetSubtitleTextPacket": "0x59",
"ClientboundClearTitlesPacket": "0x0D" "ClientboundClearTitlesPacket": "0x0C"
}, },
"StatusIn": { "StatusIn": {
"0x01": "PacketStatusInPing", "0x01": "PacketStatusInPing",

View File

@ -81,6 +81,6 @@ required-resource-pack=false
#JSON formatted text to show when prompting the player to install the resource pack (May be left blank) #JSON formatted text to show when prompting the player to install the resource pack (May be left blank)
resource-pack-prompt={"text":"","extra":[{"text":"Install server resource pack!","color":"yellow"}]} resource-pack-prompt={"text":"","extra":[{"text":"Install server resource pack!","color":"yellow"}]}
#Whether to enforce the player allowlist. If true, loads and enforces the allowlist from 'allowlist.json' #Whether to enforce the player whitelist. If true, enforces the whitelist from 'whitelist.json'
#in the same format as vanilla minecraft servers #in the same format as vanilla minecraft servers
enforce-allowlist=false enforce-whitelist=false