From 24f4ab7f37685f06f34b19bb0b55c54c4685e3b2 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 11 Jun 2025 15:35:27 +0200 Subject: [PATCH] Fix RPlayer not showing when same player is present Add DevLobby20 to LobbySystem build.gradle.kts --- LobbySystem/build.gradle.kts | 9 ++ .../src/de/steamwar/entity/RPlayer.java | 83 ++++++++++++++++++- 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/LobbySystem/build.gradle.kts b/LobbySystem/build.gradle.kts index aa511a0c..8662545c 100644 --- a/LobbySystem/build.gradle.kts +++ b/LobbySystem/build.gradle.kts @@ -34,3 +34,12 @@ dependencies { compileOnly(libs.nms20) compileOnly(libs.worldedit15) } + +tasks.register("DevLobby20") { + group = "run" + description = "Run a 1.20 Dev Lobby" + dependsOn(":SpigotCore:shadowJar") + dependsOn(":LobbySystem:jar") + template = "Lobby20" + worldName = "Lobby" +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java index b4aaa3ee..6205f5a6 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java @@ -19,22 +19,38 @@ package de.steamwar.entity; -import de.steamwar.Reflection; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import de.steamwar.Reflection; import de.steamwar.core.BountifulWrapper; import de.steamwar.core.Core; import de.steamwar.core.FlatteningWrapper; import de.steamwar.core.ProtocolWrapper; import lombok.Getter; +import lombok.SneakyThrows; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; import java.util.function.Consumer; import java.util.function.Function; +import java.util.stream.Collectors; @Getter public class RPlayer extends REntity { @@ -61,17 +77,76 @@ public class RPlayer extends REntity { private static final Object skinPartsDataWatcher = BountifulWrapper.impl.getDataWatcherObject(skinPartsIndex(), Byte.class); + private final UUID actualUUID; private final String name; public RPlayer(REntityServer server, UUID uuid, String name, Location location) { - super(server, EntityType.PLAYER, uuid, location,0); + super(server, EntityType.PLAYER, UUID.randomUUID(), location,0); + this.actualUUID = uuid; this.name = name; server.addEntity(this); } + private static final Map skinData = new LinkedHashMap() { + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > 100; + } + }; + + @SneakyThrows + public static Property fetchSkinData(UUID uuid) { + if (skinData.containsKey(uuid)) { + return skinData.get(uuid); + } + + String url = "https://sessionserver.mojang.com/session/minecraft/profile/" + uuid.toString().replace("-", "") + "?unsigned=false"; + + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + connection.setReadTimeout(5000); + connection.setConnectTimeout(5000); + connection.setRequestProperty("User-Agent", "SkinFetcher"); + + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + return null; + } + + InputStream is = connection.getInputStream(); + String json = new BufferedReader(new InputStreamReader(is)) + .lines().collect(Collectors.joining("\n")); + + JsonObject obj = JsonParser.parseString(json).getAsJsonObject(); + JsonArray properties = obj.getAsJsonArray("properties"); + for (JsonElement propElement : properties) { + JsonObject prop = propElement.getAsJsonObject(); + if (prop.get("name").getAsString().equals("textures")) { + Property property = new Property( + prop.get("name").getAsString(), + prop.get("value").getAsString(), + prop.get("signature").getAsString() + ); + skinData.put(uuid, property); + return property; + } + } + + throw new IOException("Failed to fetch skin profile"); + } + + private GameProfile getGameProfile() { + Property property = fetchSkinData(actualUUID); + if (property != null) { + GameProfile gameProfile = new GameProfile(uuid, name); + gameProfile.getProperties().put("textures", property); + return gameProfile; + } else { + return new GameProfile(actualUUID, name); + } + } + @Override void list(Consumer packetSink) { - packetSink.accept(ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.ADD, new GameProfile(uuid, name), GameMode.CREATIVE)); + packetSink.accept(ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.ADD, getGameProfile(), GameMode.CREATIVE)); } @Override @@ -88,7 +163,7 @@ public class RPlayer extends REntity { @Override void delist(Consumer packetSink) { - packetSink.accept(ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.REMOVE, new GameProfile(uuid, name), GameMode.CREATIVE)); + packetSink.accept(ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.REMOVE, getGameProfile(), GameMode.CREATIVE)); } private static final Class namedSpawnPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundAddPlayerPacket");