forked from BLOCKFANTASY/LOOHP-Limbo
Merge branch 'master' into feature/performance-improvements
This commit is contained in:
@@ -86,7 +86,7 @@ public class Console implements CommandSender {
|
||||
protected final PrintStream logs;
|
||||
|
||||
public Console(InputStream in, PrintStream out, PrintStream err) throws IOException {
|
||||
String fileName = new SimpleDateFormat("yyyy'-'MM'-'dd'_'HH'-'mm'-'ss'_'zzz'.log'").format(new Date());
|
||||
String fileName = new SimpleDateFormat("yyyy'-'MM'-'dd'_'HH'-'mm'-'ss'_'zzz'.log'").format(new Date()).replace(":", "");
|
||||
File dir = new File("logs");
|
||||
dir.mkdirs();
|
||||
File logs = new File(dir, fileName);
|
||||
|
||||
@@ -132,8 +132,8 @@ public final class Limbo {
|
||||
|
||||
//===========================
|
||||
|
||||
public final String SERVER_IMPLEMENTATION_VERSION = "1.21.8";
|
||||
public final int SERVER_IMPLEMENTATION_PROTOCOL = 772;
|
||||
public final String SERVER_IMPLEMENTATION_VERSION = "1.21.10";
|
||||
public final int SERVER_IMPLEMENTATION_PROTOCOL = 773;
|
||||
public final String LIMBO_IMPLEMENTATION_VERSION;
|
||||
|
||||
private final AtomicBoolean isRunning;
|
||||
|
||||
@@ -85,6 +85,7 @@ public class Unsafe {
|
||||
public void a(Player player) {
|
||||
instance.playersByName.put(player.getName(), player);
|
||||
instance.playersByUUID.put(player.getUniqueId(), player);
|
||||
instance.getMetrics().updatePlayersCount();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of Limbo.
|
||||
*
|
||||
* Copyright (C) 2025. LoohpJames <jamesloohp@gmail.com>
|
||||
* Copyright (C) 2025. 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.location;
|
||||
|
||||
import com.loohp.limbo.world.BlockPosition;
|
||||
import com.loohp.limbo.world.World;
|
||||
|
||||
public class GlobalPos {
|
||||
|
||||
private final World world;
|
||||
private final BlockPosition pos;
|
||||
|
||||
public GlobalPos(World world, BlockPosition pos) {
|
||||
this.world = world;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public BlockPosition getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public static GlobalPos from(Location location) {
|
||||
return new GlobalPos(location.getWorld(), BlockPosition.from(location));
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
@@ -49,6 +50,9 @@ import java.util.zip.GZIPOutputStream;
|
||||
@SuppressWarnings("unchecked")
|
||||
public class Metrics {
|
||||
|
||||
// The name of the server software
|
||||
private static final String SERVER_SOFTWARE = "Limbo";
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
@@ -58,29 +62,15 @@ public class Metrics {
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests = false;
|
||||
|
||||
// The name of the server software
|
||||
private final String name;
|
||||
|
||||
// The uuid of the server
|
||||
private final String serverUUID;
|
||||
|
||||
private final String limboVersion;
|
||||
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param name The name of the server software.
|
||||
* @param serverUUID The uuid of the server.
|
||||
* @param logFailedRequests Whether failed requests should be logged or not.
|
||||
* @param logger The logger for the failed requests.
|
||||
* @throws IOException
|
||||
*/
|
||||
private final AtomicInteger maxPlayerCountInPeriod = new AtomicInteger(0);
|
||||
|
||||
public Metrics() throws IOException {
|
||||
name = "Limbo";
|
||||
|
||||
// Get the config file
|
||||
File configFile = new File("plugins/bStats", "config.yml");
|
||||
FileConfiguration config = new FileConfiguration(configFile);
|
||||
@@ -108,8 +98,6 @@ public class Metrics {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
limboVersion = Limbo.getInstance().LIMBO_IMPLEMENTATION_VERSION;
|
||||
|
||||
// Load the data
|
||||
serverUUID = config.get("serverUuid", String.class);
|
||||
@@ -118,26 +106,16 @@ public class Metrics {
|
||||
startSubmitting();
|
||||
}
|
||||
|
||||
addCustomChart(new Metrics.SingleLineChart("players", new Callable<Integer>() {
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
return Limbo.getInstance().getPlayers().size();
|
||||
}
|
||||
}));
|
||||
|
||||
addCustomChart(new Metrics.SimplePie("limbo_version", new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return limboVersion;
|
||||
}
|
||||
}));
|
||||
addCustomChart(new Metrics.SingleLineChart("players", () -> maxPlayerCountInPeriod.getAndSet(0)));
|
||||
addCustomChart(new Metrics.SimplePie("limbo_version", () -> Limbo.getInstance().LIMBO_IMPLEMENTATION_VERSION));
|
||||
addCustomChart(new Metrics.SimplePie("minecraftVersion", () -> Limbo.getInstance().SERVER_IMPLEMENTATION_VERSION));
|
||||
}
|
||||
|
||||
addCustomChart(new Metrics.SimplePie("minecraftVersion", new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return Limbo.getInstance().SERVER_IMPLEMENTATION_VERSION;
|
||||
}
|
||||
}));
|
||||
/**
|
||||
* Record the max player count for the last update period.
|
||||
*/
|
||||
public void updatePlayersCount() {
|
||||
maxPlayerCountInPeriod.getAndUpdate(i -> Math.max(i, Limbo.getInstance().getPlayers().size()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,7 +154,7 @@ public class Metrics {
|
||||
private JSONObject getPluginData() {
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
data.put("pluginName", name); // Append the name of the server software
|
||||
data.put("pluginName", SERVER_SOFTWARE); // Append the name of the server software
|
||||
JSONArray customCharts = new JSONArray();
|
||||
for (CustomChart customChart : charts) {
|
||||
// Add the data of the custom charts
|
||||
@@ -232,7 +210,7 @@ public class Metrics {
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
Limbo.getInstance().getConsole().sendMessage("Could not submit stats of " + name + "\n" + e);
|
||||
Limbo.getInstance().getConsole().sendMessage("Could not submit stats of " + SERVER_SOFTWARE + "\n" + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,10 @@ import com.loohp.limbo.file.ServerProperties;
|
||||
import com.loohp.limbo.inventory.AnvilInventory;
|
||||
import com.loohp.limbo.inventory.Inventory;
|
||||
import com.loohp.limbo.inventory.ItemStack;
|
||||
import com.loohp.limbo.location.GlobalPos;
|
||||
import com.loohp.limbo.location.Location;
|
||||
import com.loohp.limbo.network.protocol.packets.ClientboundFinishConfigurationPacket;
|
||||
import com.loohp.limbo.network.protocol.packets.ClientboundLevelChunkWithLightPacket;
|
||||
import com.loohp.limbo.network.protocol.packets.ClientboundRegistryDataPacket;
|
||||
import com.loohp.limbo.network.protocol.packets.PacketHandshakingIn;
|
||||
import com.loohp.limbo.network.protocol.packets.PacketIn;
|
||||
@@ -588,12 +590,12 @@ public class ClientConnection implements Runnable {
|
||||
ByteArrayOutputStream brandOut = new ByteArrayOutputStream();
|
||||
DataTypeIO.writeString(new DataOutputStream(brandOut), properties.getServerModName(), StandardCharsets.UTF_8);
|
||||
sendPluginMessage(BRAND_ANNOUNCE_CHANNEL, brandOut.toByteArray());
|
||||
|
||||
|
||||
SkinResponse skinresponce = (isVelocityModern || isBungeeGuard || isBungeecord) && forwardedSkin != null ? forwardedSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName());
|
||||
PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null;
|
||||
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);
|
||||
|
||||
|
||||
Set<PlayerAbilityFlags> flags = new HashSet<>();
|
||||
if (properties.isAllowFlight()) {
|
||||
flags.add(PlayerAbilityFlags.FLY);
|
||||
@@ -603,7 +605,7 @@ public class ClientConnection implements Runnable {
|
||||
}
|
||||
PacketPlayOutPlayerAbilities abilities = new PacketPlayOutPlayerAbilities(0.05F, 0.1F, flags.toArray(new PlayerAbilityFlags[flags.size()]));
|
||||
sendPacket(abilities);
|
||||
|
||||
|
||||
String str = (properties.isLogPlayerIPAddresses() ? inetAddress.getHostName() : "<ip address withheld>") + ":" + clientSocket.getPort() + "|" + player.getName() + "(" + player.getUniqueId() + ")";
|
||||
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had connected to the Limbo server!");
|
||||
|
||||
@@ -616,18 +618,18 @@ public class ClientConnection implements Runnable {
|
||||
if (declare != null) {
|
||||
sendPacket(declare);
|
||||
}
|
||||
|
||||
PacketPlayOutSpawnPosition spawnPos = new PacketPlayOutSpawnPosition(BlockPosition.from(worldSpawn), worldSpawn.getPitch());
|
||||
|
||||
PacketPlayOutSpawnPosition spawnPos = new PacketPlayOutSpawnPosition(GlobalPos.from(worldSpawn), worldSpawn.getYaw(), worldSpawn.getPitch());
|
||||
sendPacket(spawnPos);
|
||||
|
||||
|
||||
PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch(), 1);
|
||||
Limbo.getInstance().getUnsafe().a(player, new Location(world, worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch()));
|
||||
sendPacket(positionLook);
|
||||
|
||||
|
||||
player.getDataWatcher().update();
|
||||
PacketPlayOutEntityMetadata show = new PacketPlayOutEntityMetadata(player, false, Player.class.getDeclaredField("skinLayers"));
|
||||
sendPacket(show);
|
||||
|
||||
|
||||
Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player));
|
||||
|
||||
if (properties.isAllowFlight()) {
|
||||
|
||||
+9
-22
@@ -20,6 +20,7 @@
|
||||
package com.loohp.limbo.network.protocol.packets;
|
||||
|
||||
import com.loohp.limbo.entity.EntityType;
|
||||
import com.loohp.limbo.location.Vector;
|
||||
import com.loohp.limbo.registry.PacketRegistry;
|
||||
import com.loohp.limbo.utils.DataTypeIO;
|
||||
|
||||
@@ -40,11 +41,9 @@ public class PacketPlayOutSpawnEntity extends PacketOut {
|
||||
private final float yaw;
|
||||
private final float headYaw;
|
||||
private final int data;
|
||||
private final short velocityX;
|
||||
private final short velocityY;
|
||||
private final short velocityZ;
|
||||
private final Vector movement;
|
||||
|
||||
public PacketPlayOutSpawnEntity(int entityId, UUID uuid, EntityType type, double x, double y, double z, float pitch, float yaw, float headYaw, int data, short velocityX, short velocityY, short velocityZ) {
|
||||
public PacketPlayOutSpawnEntity(int entityId, UUID uuid, EntityType type, double x, double y, double z, float pitch, float yaw, float headYaw, int data, Vector movement) {
|
||||
this.entityId = entityId;
|
||||
this.uuid = uuid;
|
||||
this.type = type;
|
||||
@@ -55,9 +54,7 @@ public class PacketPlayOutSpawnEntity extends PacketOut {
|
||||
this.yaw = yaw;
|
||||
this.headYaw = headYaw;
|
||||
this.data = data;
|
||||
this.velocityX = velocityX;
|
||||
this.velocityY = velocityY;
|
||||
this.velocityZ = velocityZ;
|
||||
this.movement = movement.clone();
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
@@ -100,19 +97,11 @@ public class PacketPlayOutSpawnEntity extends PacketOut {
|
||||
return data;
|
||||
}
|
||||
|
||||
public short getVelocityX() {
|
||||
return velocityX;
|
||||
}
|
||||
public Vector getMovement() {
|
||||
return movement.clone();
|
||||
}
|
||||
|
||||
public short getVelocityY() {
|
||||
return velocityY;
|
||||
}
|
||||
|
||||
public short getVelocityZ() {
|
||||
return velocityZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public byte[] serializePacket() throws IOException {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
@@ -124,13 +113,11 @@ public class PacketPlayOutSpawnEntity extends PacketOut {
|
||||
output.writeDouble(x);
|
||||
output.writeDouble(y);
|
||||
output.writeDouble(z);
|
||||
DataTypeIO.writeLpVec3(output, movement);
|
||||
output.writeByte((byte) (int) (pitch * 256.0F / 360.0F));
|
||||
output.writeByte((byte) (int) (yaw * 256.0F / 360.0F));
|
||||
output.writeByte((byte) (int) (headYaw * 256.0F / 360.0F));
|
||||
DataTypeIO.writeVarInt(output, data);
|
||||
output.writeShort(velocityX * 8000);
|
||||
output.writeShort(velocityY * 8000);
|
||||
output.writeShort(velocityZ * 8000);
|
||||
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
+26
-16
@@ -19,39 +19,49 @@
|
||||
|
||||
package com.loohp.limbo.network.protocol.packets;
|
||||
|
||||
import com.loohp.limbo.location.GlobalPos;
|
||||
import com.loohp.limbo.registry.PacketRegistry;
|
||||
import com.loohp.limbo.utils.DataTypeIO;
|
||||
import com.loohp.limbo.world.BlockPosition;
|
||||
import net.kyori.adventure.key.Key;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class PacketPlayOutSpawnPosition extends PacketOut {
|
||||
|
||||
private final BlockPosition position;
|
||||
private final float angle;
|
||||
private final GlobalPos position;
|
||||
private final float yaw;
|
||||
private final float pitch;
|
||||
|
||||
public PacketPlayOutSpawnPosition(BlockPosition position, float angle) {
|
||||
public PacketPlayOutSpawnPosition(GlobalPos position, float yaw, float pitch) {
|
||||
this.position = position;
|
||||
this.angle = angle;
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public BlockPosition getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public float getAngle() {
|
||||
return angle;
|
||||
}
|
||||
|
||||
public byte[] serializePacket() throws IOException {
|
||||
public GlobalPos getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public byte[] serializePacket() throws IOException {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
DataOutputStream output = new DataOutputStream(buffer);
|
||||
output.writeByte(PacketRegistry.getPacketId(getClass()));
|
||||
DataTypeIO.writeBlockPosition(output, position);
|
||||
output.writeFloat(angle);
|
||||
DataTypeIO.writeString(output, Key.key(position.getWorld().getName()).toString(), StandardCharsets.UTF_8);
|
||||
DataTypeIO.writeBlockPosition(output, position.getPos());
|
||||
output.writeFloat(yaw);
|
||||
output.writeFloat(pitch);
|
||||
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
@@ -96,15 +96,15 @@ public class Player extends LivingEntity implements CommandSender, InventoryHold
|
||||
protected final PlayerInventory playerInventory;
|
||||
protected final InventoryView inventoryView;
|
||||
private final AtomicInteger containerIdCounter;
|
||||
|
||||
@WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.FLOAT)
|
||||
|
||||
@WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.BYTE)
|
||||
protected byte mainHand = 1;
|
||||
@WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.BYTE)
|
||||
protected byte skinLayers = 0;
|
||||
@WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.FLOAT)
|
||||
protected float additionalHearts = 0.0F;
|
||||
@WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.VARINT)
|
||||
@WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.VARINT)
|
||||
protected int score = 0;
|
||||
@WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.BYTE)
|
||||
protected byte skinLayers = 0;
|
||||
@WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.BYTE)
|
||||
protected byte mainHand = 1;
|
||||
//@WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.NBT)
|
||||
//protected Entity leftShoulder = null;
|
||||
//@WatchableField(MetadataIndex = 20, WatchableObjectType = WatchableObjectType.NBT)
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.loohp.limbo.player;
|
||||
import com.loohp.limbo.Limbo;
|
||||
import com.loohp.limbo.entity.Entity;
|
||||
import com.loohp.limbo.location.Location;
|
||||
import com.loohp.limbo.location.Vector;
|
||||
import com.loohp.limbo.network.ClientConnection;
|
||||
import com.loohp.limbo.network.protocol.packets.ClientboundChunkBatchFinishedPacket;
|
||||
import com.loohp.limbo.network.protocol.packets.ClientboundChunkBatchStartPacket;
|
||||
@@ -81,7 +82,7 @@ public class PlayerInteractManager {
|
||||
Set<Entity> entitiesInRange = player.getWorld().getEntities().stream().filter(each -> each.getLocation().distanceSquared(location) < viewDistanceBlocks * viewDistanceBlocks).collect(Collectors.toSet());
|
||||
for (Entity entity : entitiesInRange) {
|
||||
if (!entities.contains(entity)) {
|
||||
PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getYaw(), entity.getPitch(), entity.getPitch(), 0, (short) 0, (short) 0, (short) 0);
|
||||
PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getYaw(), entity.getPitch(), entity.getPitch(), 0, new Vector(0, 0, 0));
|
||||
player.clientConnection.sendPacket(packet);
|
||||
|
||||
PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity);
|
||||
|
||||
@@ -351,4 +351,38 @@ public class DataTypeIO {
|
||||
}
|
||||
}
|
||||
|
||||
private static double sanitize(double d0) {
|
||||
return Double.isNaN(d0) ? 0.0D : Math.min(Math.max(d0, -1.7179869183E10D), 1.7179869183E10D);
|
||||
}
|
||||
|
||||
private static long pack(double d0) {
|
||||
return Math.round((d0 * 0.5D + 0.5D) * 32766.0D);
|
||||
}
|
||||
|
||||
public static void writeLpVec3(DataOutputStream out, Vector vec3d) throws IOException {
|
||||
double d0 = sanitize(vec3d.getX());
|
||||
double d1 = sanitize(vec3d.getY());
|
||||
double d2 = sanitize(vec3d.getZ());
|
||||
double d3 = Math.max(Math.abs(d0), Math.max(Math.abs(d1), Math.abs(d2)));
|
||||
|
||||
if (d3 < 3.051944088384301E-5D) {
|
||||
out.writeByte(0);
|
||||
} else {
|
||||
long i = (long) Math.ceil(d3);
|
||||
boolean flag = (i & 3L) != i;
|
||||
long j = flag ? i & 3L | 4L : i;
|
||||
long k = pack(d0 / (double) i) << 3;
|
||||
long l = pack(d1 / (double) i) << 18;
|
||||
long i1 = pack(d2 / (double) i) << 33;
|
||||
long j1 = j | k | l | i1;
|
||||
|
||||
out.writeByte((byte) ((int) j1));
|
||||
out.writeByte((byte) ((int) (j1 >> 8)));
|
||||
out.writeInt((int) (j1 >> 16));
|
||||
if (flag) {
|
||||
writeVarInt(out, (int) (i >> 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,14 +33,20 @@ public class DeclareCommands {
|
||||
|
||||
public static PacketPlayOutDeclareCommands getDeclareCommandsPacket(CommandSender sender) throws IOException {
|
||||
List<String> commands = Limbo.getInstance().getPluginManager().getTabOptions(sender, new String[0]);
|
||||
|
||||
if (commands.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
DataOutputStream output = new DataOutputStream(buffer);
|
||||
|
||||
if (commands.isEmpty()) {
|
||||
DataTypeIO.writeVarInt(output, 1);
|
||||
|
||||
output.writeByte(0);
|
||||
DataTypeIO.writeVarInt(output, 0);
|
||||
DataTypeIO.writeVarInt(output, 0);
|
||||
|
||||
return new PacketPlayOutDeclareCommands(buffer.toByteArray());
|
||||
}
|
||||
|
||||
DataTypeIO.writeVarInt(output, commands.size() * 2 + 1);
|
||||
|
||||
output.writeByte(0);
|
||||
|
||||
@@ -94,7 +94,7 @@ public class MojangAPIUtils {
|
||||
connection.addRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
connection.addRequestProperty("Pragma", "no-cache");
|
||||
if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) {
|
||||
String reply = String.join("", new BufferedReader(new InputStreamReader(connection.getInputStream())).lines().collect(Collectors.toList())).replace(" ", "");
|
||||
String reply = new BufferedReader(new InputStreamReader(connection.getInputStream())).lines().collect(Collectors.joining("")).replace(" ", "");
|
||||
String skin = reply.split("\"value\":\"")[1].split("\"")[0];
|
||||
String signature = reply.split("\"signature\":\"")[1].split("\"")[0];
|
||||
return new SkinResponse(skin, signature);
|
||||
|
||||
Reference in New Issue
Block a user