From f36390a3d57224fc25c960ef4353bdc810606cbd Mon Sep 17 00:00:00 2001 From: Lionarius Date: Sat, 4 Oct 2025 22:12:25 +0300 Subject: [PATCH] port to 1.21.9 --- build.gradle | 2 +- .../lionarius/skinrestorer/SkinRestorer.java | 27 ++++---- .../skinrestorer/command/SkinCommand.java | 44 +++++++----- .../skinshuffle/SkinShuffleCompatibility.java | 2 +- .../mixin/GameProfileCacheAccessor.java | 14 ---- .../skinrestorer/mixin/PlayerAccessor.java | 15 ++++ .../skinrestorer/mixin/PlayerListMixin.java | 2 +- .../ServerLoginPacketListenerImplMixin.java | 16 ++--- .../mixin/SkullBlockEntityMixin.java | 69 ------------------- .../skin/provider/ElyBySkinProvider.java | 2 +- .../skin/provider/MojangSkinProvider.java | 27 ++++---- .../skinrestorer/util/JsonUtils.java | 2 - .../skinrestorer/util/PlayerUtils.java | 24 ++++--- .../resources/META-INF/accesstransformer.cfg | 1 - .../main/resources/skinrestorer.accesswidener | 2 - .../main/resources/skinrestorer.mixins.json | 3 +- fabric/gradle.properties | 2 +- .../skinshuffle/SkinShuffleCompatibility.java | 2 +- forge/gradle.properties | 6 +- .../skinshuffle/SkinShufflePacketHandler.java | 2 +- gradle.properties | 10 +-- neoforge/build.gradle | 2 - neoforge/gradle.properties | 2 +- .../SkinShuffleModEventHandler.java | 3 +- 24 files changed, 112 insertions(+), 169 deletions(-) delete mode 100644 common/src/main/java/net/lionarius/skinrestorer/mixin/GameProfileCacheAccessor.java create mode 100644 common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerAccessor.java delete mode 100644 common/src/main/java/net/lionarius/skinrestorer/mixin/SkullBlockEntityMixin.java diff --git a/build.gradle b/build.gradle index b092859..5be6436 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { // see https://fabricmc.net/develop/ for new versions - id 'fabric-loom' version '1.10-SNAPSHOT' apply false + id 'fabric-loom' version '1.11-SNAPSHOT' apply false // see https://projects.neoforged.net/neoforged/moddevgradle for new versions id 'net.neoforged.moddev' version '2.0.+' apply false // see https://files.minecraftforge.net/net/minecraftforge/gradle/ForgeGradle/ for new versions diff --git a/common/src/main/java/net/lionarius/skinrestorer/SkinRestorer.java b/common/src/main/java/net/lionarius/skinrestorer/SkinRestorer.java index f2270f1..2296958 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/SkinRestorer.java +++ b/common/src/main/java/net/lionarius/skinrestorer/SkinRestorer.java @@ -1,12 +1,12 @@ package net.lionarius.skinrestorer; import com.google.common.base.Throwables; -import com.mojang.authlib.GameProfile; import com.mojang.brigadier.CommandDispatcher; import net.lionarius.skinrestorer.command.SkinCommand; import net.lionarius.skinrestorer.config.Config; import net.lionarius.skinrestorer.config.provider.BuiltInProviderConfig; import net.lionarius.skinrestorer.exception.TransparentException; +import net.lionarius.skinrestorer.mixin.PlayerAccessor; import net.lionarius.skinrestorer.platform.Services; import net.lionarius.skinrestorer.skin.SkinIO; import net.lionarius.skinrestorer.skin.SkinStorage; @@ -108,23 +108,26 @@ public final class SkinRestorer { MineskinSkinProvider.reload(); } - public static Collection applySkin(MinecraftServer server, Iterable targets, SkinValue value, boolean save) { + public static Collection applySkin(MinecraftServer server, Iterable targets, SkinValue value, boolean save) { var acceptedPlayers = new HashSet(); - for (var profile : targets) { - if (!SkinRestorer.getSkinStorage().hasSavedSkin(profile.getId())) - value = value.setOriginalValue(PlayerUtils.getPlayerSkin(profile)); + for (var player : targets) { + var profile = player.getGameProfile(); + var skin = PlayerUtils.getPlayerSkin(profile); - if (PlayerUtils.areSkinPropertiesEquals(value.value(), PlayerUtils.getPlayerSkin(profile))) + if (!SkinRestorer.getSkinStorage().hasSavedSkin(profile.id())) + value = value.setOriginalValue(skin); + + if (PlayerUtils.areSkinPropertiesEquals(value.value(), skin)) continue; if (save) - SkinRestorer.getSkinStorage().setSkin(profile.getId(), value); + SkinRestorer.getSkinStorage().setSkin(profile.id(), value); - PlayerUtils.applyRestoredSkin(profile, value.value()); + var newProfile = PlayerUtils.applyRestoredSkin(profile, value.value()); + ((PlayerAccessor) player).setGameProfile(newProfile); - var player = server.getPlayerList().getPlayer(profile.getId()); - if (player == null) + if (player.connection == null) continue; PlayerUtils.refreshPlayer(player); @@ -136,13 +139,13 @@ public final class SkinRestorer { return acceptedPlayers; } - public static Collection applySkin(MinecraftServer server, Iterable targets, SkinValue value) { + public static Collection applySkin(MinecraftServer server, Iterable targets, SkinValue value) { return SkinRestorer.applySkin(server, targets, value, true); } public static CompletableFuture, String>> setSkinAsync( MinecraftServer server, - Collection targets, + Collection targets, SkinProviderContext context, boolean save ) { diff --git a/common/src/main/java/net/lionarius/skinrestorer/command/SkinCommand.java b/common/src/main/java/net/lionarius/skinrestorer/command/SkinCommand.java index 8dd93ea..c2ab49d 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/command/SkinCommand.java +++ b/common/src/main/java/net/lionarius/skinrestorer/command/SkinCommand.java @@ -1,6 +1,5 @@ package net.lionarius.skinrestorer.command; -import com.mojang.authlib.GameProfile; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.ArgumentBuilder; @@ -18,10 +17,12 @@ import net.lionarius.skinrestorer.util.PlayerUtils; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.GameProfileArgument; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.NameAndId; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; @@ -72,37 +73,41 @@ public final class SkinCommand { SkinProviderContext context = null; var save = true; - if (!SkinRestorer.getSkinStorage().hasSavedSkin(profile.getId())) { - if (profile.getProperties().containsKey(PlayerUtils.TEXTURES_KEY)) { + if (!SkinRestorer.getSkinStorage().hasSavedSkin(profile.id())) { + if (profile.properties().containsKey(PlayerUtils.TEXTURES_KEY)) { save = false; context = MojangSkinProvider.skinProviderContextFromProfile(profile); } } else { - context = SkinRestorer.getSkinStorage().getSkin(profile.getId()).toProviderContext(); + context = SkinRestorer.getSkinStorage().getSkin(profile.id()).toProviderContext(); } if (context == null) return 0; - return SkinCommand.setSubcommand(src, Collections.singleton(profile), context, save, false); + return SkinCommand.setSubcommand(src, Collections.singleton(new NameAndId(profile)), context, save, false); } private static int resetSubcommand( CommandSourceStack src, - Collection targets, + Collection targets, boolean setByOperator ) { var updatedPlayers = new HashSet(); - for (var profile : targets) { + for (var nameAndId : targets) { SkinValue skin = null; - if (SkinRestorer.getSkinStorage().hasSavedSkin(profile.getId())) - skin = SkinRestorer.getSkinStorage().getSkin(profile.getId()).replaceValueWithOriginal(); + if (SkinRestorer.getSkinStorage().hasSavedSkin(nameAndId.id())) + skin = SkinRestorer.getSkinStorage().getSkin(nameAndId.id()).replaceValueWithOriginal(); if (skin == null) continue; - var updatedPlayer = SkinRestorer.applySkin(src.getServer(), Collections.singleton(profile), skin, false); - SkinRestorer.getSkinStorage().deleteSkin(profile.getId()); + var player = src.getServer().getPlayerList().getPlayer(nameAndId.id()); + if (player == null) + continue; + + var updatedPlayer = SkinRestorer.applySkin(src.getServer(), Collections.singleton(player), skin, false); + SkinRestorer.getSkinStorage().deleteSkin(nameAndId.id()); updatedPlayers.addAll(updatedPlayer); } @@ -118,19 +123,24 @@ public final class SkinCommand { if (src.getPlayer() == null) return 0; - return resetSubcommand(src, Collections.singleton(src.getPlayer().getGameProfile()), false); + return resetSubcommand(src, Collections.singleton(src.getPlayer().nameAndId()), false); } private static int setSubcommand( CommandSourceStack src, - Collection targets, + Collection targets, SkinProviderContext context, boolean save, boolean setByOperator ) { src.sendSystemMessage(Translation.translatableWithFallback(Translation.COMMAND_SKIN_LOADING_KEY)); - SkinRestorer.setSkinAsync(src.getServer(), targets, context, save).thenAccept(result -> { + var profileTargets = targets.stream() + .map(nameAndId -> src.getServer().getPlayerList().getPlayer(nameAndId.id())) + .filter(Objects::nonNull) + .toList(); + + SkinRestorer.setSkinAsync(src.getServer(), profileTargets, context, save).thenAccept(result -> { if (result.isError()) { src.sendFailure(Translation.translatableWithFallback( Translation.COMMAND_SKIN_FAILED_KEY, @@ -149,7 +159,7 @@ public final class SkinCommand { private static int setSubcommand( CommandSourceStack src, - Collection targets, + Collection targets, SkinProviderContext context, boolean setByOperator ) { @@ -163,7 +173,7 @@ public final class SkinCommand { if (src.getPlayer() == null) return 0; - return setSubcommand(src, Collections.singleton(src.getPlayer().getGameProfile()), context, false); + return setSubcommand(src, Collections.singleton(src.getPlayer().nameAndId()), context, false); } private static int configReloadSubcommand(CommandContext context) { @@ -256,7 +266,7 @@ public final class SkinCommand { } private static RequiredArgumentBuilder makeTargetsArgument( - BiFunction, Collection, Integer> consumer + BiFunction, Collection, Integer> consumer ) { return argument("targets", GameProfileArgument.gameProfile()) .requires(source -> source.hasPermission(2)) diff --git a/common/src/main/java/net/lionarius/skinrestorer/compat/skinshuffle/SkinShuffleCompatibility.java b/common/src/main/java/net/lionarius/skinrestorer/compat/skinshuffle/SkinShuffleCompatibility.java index 3b60331..431fe20 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/compat/skinshuffle/SkinShuffleCompatibility.java +++ b/common/src/main/java/net/lionarius/skinrestorer/compat/skinshuffle/SkinShuffleCompatibility.java @@ -43,7 +43,7 @@ public class SkinShuffleCompatibility { server.execute(() -> { SkinRestorer.applySkin( server, - Collections.singleton(player.getGameProfile()), + Collections.singleton(player), new SkinValue(SkinShuffleSkinProvider.PROVIDER_NAME, null, null, property), !server.usesAuthentication() ); diff --git a/common/src/main/java/net/lionarius/skinrestorer/mixin/GameProfileCacheAccessor.java b/common/src/main/java/net/lionarius/skinrestorer/mixin/GameProfileCacheAccessor.java deleted file mode 100644 index f129fc3..0000000 --- a/common/src/main/java/net/lionarius/skinrestorer/mixin/GameProfileCacheAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.lionarius.skinrestorer.mixin; - -import net.minecraft.server.players.GameProfileCache; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.Map; - -@Mixin(GameProfileCache.class) -public interface GameProfileCacheAccessor { - - @Accessor - Map getProfilesByName(); -} diff --git a/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerAccessor.java b/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerAccessor.java new file mode 100644 index 0000000..61a4d04 --- /dev/null +++ b/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerAccessor.java @@ -0,0 +1,15 @@ +package net.lionarius.skinrestorer.mixin; + +import com.mojang.authlib.GameProfile; +import net.minecraft.world.entity.player.Player; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + + +@Mixin(Player.class) +public interface PlayerAccessor { + @Accessor("gameProfile") + @Mutable + void setGameProfile(GameProfile properties); +} diff --git a/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java b/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java index ccaed02..4752301 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java +++ b/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java @@ -57,6 +57,6 @@ public abstract class PlayerListMixin { @Unique private static void skinrestorer$tryApplySkin(MinecraftServer server, ServerPlayer player) { if (SkinRestorer.getSkinStorage().hasSavedSkin(player.getUUID())) - SkinRestorer.applySkin(server, Collections.singleton(player.getGameProfile()), SkinRestorer.getSkinStorage().getSkin(player.getUUID())); + SkinRestorer.applySkin(server, Collections.singleton(player), SkinRestorer.getSkinStorage().getSkin(player.getUUID())); } } diff --git a/common/src/main/java/net/lionarius/skinrestorer/mixin/ServerLoginPacketListenerImplMixin.java b/common/src/main/java/net/lionarius/skinrestorer/mixin/ServerLoginPacketListenerImplMixin.java index ca9780c..09a97dc 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/mixin/ServerLoginPacketListenerImplMixin.java +++ b/common/src/main/java/net/lionarius/skinrestorer/mixin/ServerLoginPacketListenerImplMixin.java @@ -27,7 +27,7 @@ public abstract class ServerLoginPacketListenerImplMixin { private CompletableFuture skinrestorer$pendingSkin; @Inject(method = "verifyLoginAndFinishConnectionSetup", at = @At(value = "INVOKE", - target = "Lnet/minecraft/server/players/PlayerList;canPlayerLogin(Ljava/net/SocketAddress;Lcom/mojang/authlib/GameProfile;)Lnet/minecraft/network/chat/Component;"), + target = "Lnet/minecraft/server/players/PlayerList;canPlayerLogin(Ljava/net/SocketAddress;Lnet/minecraft/server/players/NameAndId;)Lnet/minecraft/network/chat/Component;"), cancellable = true) public void waitForSkin(CallbackInfo ci) { if (skinrestorer$pendingSkin == null) { @@ -37,14 +37,14 @@ public abstract class ServerLoginPacketListenerImplMixin { assert profile != null; var originalSkin = PlayerUtils.getPlayerSkin(profile); - if (SkinRestorer.getSkinStorage().hasSavedSkin(profile.getId())) { + if (SkinRestorer.getSkinStorage().hasSavedSkin(profile.id())) { if (originalSkin != null) { // update to the latest official skin - var value = SkinRestorer.getSkinStorage().getSkin(profile.getId()); - SkinRestorer.getSkinStorage().setSkin(profile.getId(), value.setOriginalValue(originalSkin)); + var value = SkinRestorer.getSkinStorage().getSkin(profile.id()); + SkinRestorer.getSkinStorage().setSkin(profile.id(), value.setOriginalValue(originalSkin)); } if (SkinRestorer.getConfig().refreshSkinOnJoin()) { - var currentSkin = SkinRestorer.getSkinStorage().getSkin(profile.getId()); + var currentSkin = SkinRestorer.getSkinStorage().getSkin(profile.id()); var context = currentSkin.toProviderContext(); skinrestorer$fetchSkin(profile, context); @@ -56,7 +56,7 @@ public abstract class ServerLoginPacketListenerImplMixin { if (originalSkin == null && SkinRestorer.getConfig().fetchSkinOnFirstJoin()) { var context = new SkinProviderContext( SkinRestorer.getConfig().firstJoinSkinProvider().getName(), - profile.getName(), + profile.name(), null ); skinrestorer$fetchSkin(profile, context); @@ -72,7 +72,7 @@ public abstract class ServerLoginPacketListenerImplMixin { @Unique private static void skinrestorer$fetchSkin(GameProfile profile, SkinProviderContext context) { - SkinRestorer.LOGGER.debug("Fetching {}'s skin", profile.getName()); + SkinRestorer.LOGGER.debug("Fetching {}'s skin", profile.name()); var result = SkinRestorer.getProvider(context.name()).map( provider -> provider.fetchSkin(context.argument(), context.variant()) @@ -80,7 +80,7 @@ public abstract class ServerLoginPacketListenerImplMixin { if (!result.isError()) { var value = SkinValue.fromProviderContextWithValue(context, result.getSuccessValue().orElse(null)); - SkinRestorer.getSkinStorage().setSkin(profile.getId(), value); + SkinRestorer.getSkinStorage().setSkin(profile.id(), value); } else { SkinRestorer.LOGGER.warn("Failed to fetch skin '{}:{}'", context.name(), context.argument(), result.getErrorValue()); } diff --git a/common/src/main/java/net/lionarius/skinrestorer/mixin/SkullBlockEntityMixin.java b/common/src/main/java/net/lionarius/skinrestorer/mixin/SkullBlockEntityMixin.java deleted file mode 100644 index 21d4d38..0000000 --- a/common/src/main/java/net/lionarius/skinrestorer/mixin/SkullBlockEntityMixin.java +++ /dev/null @@ -1,69 +0,0 @@ -package net.lionarius.skinrestorer.mixin; - -import com.mojang.authlib.GameProfile; -import net.lionarius.skinrestorer.SkinRestorer; -import net.lionarius.skinrestorer.util.PlayerUtils; -import net.minecraft.Util; -import net.minecraft.server.Services; -import net.minecraft.world.level.block.entity.SkullBlockEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.Locale; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.function.BooleanSupplier; - -@Mixin(SkullBlockEntity.class) -public abstract class SkullBlockEntityMixin { - - @Inject(method = "fetchProfileByName", at = @At("HEAD"), - cancellable = true) - private static void fetchProfileByName(String name, Services services, CallbackInfoReturnable>> cir) { - if (name == null) - return; - - var profileOpt = Optional.empty(); - var gameProfileInfo = ((GameProfileCacheAccessor) services.profileCache()).getProfilesByName().get(name.toLowerCase(Locale.ROOT)); - - if (gameProfileInfo != null) - profileOpt = Optional.of(gameProfileInfo.getProfile()); - - skinrestorer$replaceSkin(profileOpt, cir); - } - - @Inject(method = "fetchProfileById", at = @At("HEAD"), - cancellable = true) - private static void fetchProfileById(UUID id, Services services, BooleanSupplier cacheUninitialized, CallbackInfoReturnable>> cir) { - if (id == null) - return; - - var profileOpt = services.profileCache().get(id); - - skinrestorer$replaceSkin(profileOpt, cir); - } - - @Unique - private static void skinrestorer$replaceSkin(Optional profileOpt, CallbackInfoReturnable>> cir) { - if (SkinRestorer.getMinecraftServer() == null) - return; - - if (profileOpt.isEmpty()) - return; - - var profile = PlayerUtils.cloneGameProfile(profileOpt.get()); - - if (SkinRestorer.getSkinStorage().hasSavedSkin(profile.getId())) { - cir.setReturnValue(CompletableFuture.supplyAsync(() -> { - var skin = SkinRestorer.getSkinStorage().getSkin(profile.getId(), false); - PlayerUtils.applyRestoredSkin(profile, skin.value()); - - return Optional.of(profile); - }, Util.backgroundExecutor().forName("getProfile"))); - } - } -} diff --git a/common/src/main/java/net/lionarius/skinrestorer/skin/provider/ElyBySkinProvider.java b/common/src/main/java/net/lionarius/skinrestorer/skin/provider/ElyBySkinProvider.java index b8496f1..a8bdfc7 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/skin/provider/ElyBySkinProvider.java +++ b/common/src/main/java/net/lionarius/skinrestorer/skin/provider/ElyBySkinProvider.java @@ -106,6 +106,6 @@ public final class ElyBySkinProvider implements SkinProvider { if (response.statusCode() != 200) throw new IllegalArgumentException("no profile with name " + username); - return JsonUtils.fromJson(response.body(), MinecraftProfilePropertiesResponse.class).toProfile(); + return JsonUtils.fromJson(response.body(), MinecraftProfilePropertiesResponse.class).profile(); } } diff --git a/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java b/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java index 56f6bff..b41e10f 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java +++ b/common/src/main/java/net/lionarius/skinrestorer/skin/provider/MojangSkinProvider.java @@ -8,6 +8,7 @@ import com.mojang.authlib.*; import com.mojang.authlib.properties.Property; import com.mojang.authlib.yggdrasil.YggdrasilEnvironment; import com.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse; +import com.mojang.authlib.yggdrasil.response.NameAndId; import com.mojang.util.UndashedUuid; import net.lionarius.skinrestorer.SkinRestorer; import net.lionarius.skinrestorer.exception.TransparentException; @@ -16,7 +17,7 @@ import net.lionarius.skinrestorer.util.JsonUtils; import net.lionarius.skinrestorer.util.PlayerUtils; import net.lionarius.skinrestorer.util.Result; import net.lionarius.skinrestorer.util.WebUtils; -import net.minecraft.server.players.GameProfileCache; +import net.minecraft.server.players.CachedUserNameToIdResolver; import net.minecraft.util.StringUtil; import org.jetbrains.annotations.NotNull; @@ -31,13 +32,11 @@ import java.util.concurrent.TimeUnit; public final class MojangSkinProvider implements SkinProvider { public static final String PROVIDER_NAME = "mojang"; - + public static final String PROFILE_CACHE_FILENAME = "mojang_profile_cache.json"; private static final Environment ENVIRONMENT; private static final URI SERVICES_SERVER_URI; private static final URI SESSION_SERVER_URI; - - public static final String PROFILE_CACHE_FILENAME = "mojang_profile_cache.json"; - private static final GameProfileCache PROFILE_CACHE; + private static final CachedUserNameToIdResolver PROFILE_CACHE; private static LoadingCache> SKIN_CACHE; @@ -51,13 +50,13 @@ public final class MojangSkinProvider implements SkinProvider { throw new IllegalArgumentException(e); } - PROFILE_CACHE = new GameProfileCache(new GameProfileRepository() { + PROFILE_CACHE = new CachedUserNameToIdResolver(new GameProfileRepository() { @Override public void findProfilesByNames(String[] names, ProfileLookupCallback callback) { for (var name : names) { try { var profile = MojangSkinProvider.getProfile(name); - callback.onProfileLookupSucceeded(profile); + callback.onProfileLookupSucceeded(profile.name(), profile.id()); } catch (IOException e) { throw new TransparentException(e); } @@ -65,10 +64,10 @@ public final class MojangSkinProvider implements SkinProvider { } @Override - public Optional findProfileByName(String name) { + public Optional findProfileByName(String name) { try { var profile = MojangSkinProvider.getProfile(name); - return Optional.of(profile); + return Optional.of(new NameAndId(profile.id(), profile.name())); } catch (IOException e) { throw new TransparentException(e); } @@ -95,7 +94,7 @@ public final class MojangSkinProvider implements SkinProvider { } public static SkinProviderContext skinProviderContextFromProfile(GameProfile gameProfile) { - return new SkinProviderContext(MojangSkinProvider.PROVIDER_NAME, gameProfile.getName(), null); + return new SkinProviderContext(MojangSkinProvider.PROVIDER_NAME, gameProfile.name(), null); } @Override @@ -118,7 +117,7 @@ public final class MojangSkinProvider implements SkinProvider { if (cachedProfile.isEmpty()) throw new IllegalArgumentException("no profile found for " + username); - return Result.success(SKIN_CACHE.get(cachedProfile.get().getId())); + return Result.success(SKIN_CACHE.get(cachedProfile.get().id())); } catch (UncheckedExecutionException e) { return Result.error((Exception) e.getCause()); } catch (Exception e) { @@ -133,7 +132,7 @@ public final class MojangSkinProvider implements SkinProvider { return Optional.ofNullable(textures); } - private static GameProfile getProfile(final String name) throws IOException { + private static NameAndId getProfile(final String name) throws IOException { var request = HttpRequest.newBuilder() .uri(MojangSkinProvider.SERVICES_SERVER_URI .resolve("/minecraft/profile/lookup/name/") @@ -148,7 +147,7 @@ public final class MojangSkinProvider implements SkinProvider { if (response.statusCode() != 200) throw new IllegalArgumentException("no profile with name " + name); - return JsonUtils.fromJson(response.body(), GameProfile.class); + return JsonUtils.fromJson(response.body(), NameAndId.class); } private static GameProfile getProfileWithProperties(UUID uuid) throws IOException { @@ -166,6 +165,6 @@ public final class MojangSkinProvider implements SkinProvider { if (response.statusCode() != 200) throw new IllegalArgumentException("no profile with uuid " + uuid); - return JsonUtils.fromJson(response.body(), MinecraftProfilePropertiesResponse.class).toProfile(); + return JsonUtils.fromJson(response.body(), MinecraftProfilePropertiesResponse.class).profile(); } } diff --git a/common/src/main/java/net/lionarius/skinrestorer/util/JsonUtils.java b/common/src/main/java/net/lionarius/skinrestorer/util/JsonUtils.java index 7eef4e1..a3726b3 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/util/JsonUtils.java +++ b/common/src/main/java/net/lionarius/skinrestorer/util/JsonUtils.java @@ -4,7 +4,6 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.PropertyMap; import com.mojang.util.UUIDTypeAdapter; @@ -22,7 +21,6 @@ public final class JsonUtils { .registerTypeAdapterFactory(new PostProcessingEnabler()) .registerTypeAdapter(UUID.class, new UUIDTypeAdapter()) .registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()) - .registerTypeAdapter(GameProfile.class, new GameProfile.Serializer()) .setPrettyPrinting() .create(); diff --git a/common/src/main/java/net/lionarius/skinrestorer/util/PlayerUtils.java b/common/src/main/java/net/lionarius/skinrestorer/util/PlayerUtils.java index 5ee7122..031a510 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/util/PlayerUtils.java +++ b/common/src/main/java/net/lionarius/skinrestorer/util/PlayerUtils.java @@ -1,12 +1,13 @@ package net.lionarius.skinrestorer.util; import com.google.common.collect.Iterables; +import com.google.common.collect.LinkedHashMultimap; import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; import com.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse; import net.lionarius.skinrestorer.mixin.ChunkMapAccessor; -import net.lionarius.skinrestorer.mixin.TrackedEntityAccessorInvoker; import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.game.*; import net.minecraft.server.level.ChunkMap; @@ -97,21 +98,26 @@ public final class PlayerUtils { } public static GameProfile cloneGameProfile(GameProfile profile) { - var newProfile = new GameProfile(profile.getId(), profile.getName()); - newProfile.getProperties().putAll(profile.getProperties()); + var newProfile = new GameProfile(profile.id(), profile.name()); + newProfile.properties().putAll(profile.properties()); return newProfile; } public static Property getPlayerSkin(GameProfile profile) { - return Iterables.getFirst(profile.getProperties().get(TEXTURES_KEY), null); + return Iterables.getFirst(profile.properties().get(TEXTURES_KEY), null); } - public static void applyRestoredSkin(GameProfile profile, Property skin) { - profile.getProperties().removeAll(TEXTURES_KEY); + public static GameProfile applyRestoredSkin(GameProfile profile, Property skin) { + var propertiesMap = profile.properties(); - if (skin != null) - profile.getProperties().put(TEXTURES_KEY, skin); + var newProperties = LinkedHashMultimap.create(propertiesMap); + newProperties.removeAll(TEXTURES_KEY); + if (skin != null) { + newProperties.put(TEXTURES_KEY, skin); + } + + return new GameProfile(profile.id(), profile.name(), new PropertyMap(newProperties)); } public static boolean areSkinPropertiesEquals(Property x, Property y) { @@ -135,7 +141,7 @@ public final class PlayerUtils { public static GameProfile toProfile(MinecraftProfilePropertiesResponse response) { final GameProfile profile = new GameProfile(response.id(), response.name()); - profile.getProperties().putAll(response.properties()); + profile.properties().putAll(response.properties()); return profile; } } diff --git a/common/src/main/resources/META-INF/accesstransformer.cfg b/common/src/main/resources/META-INF/accesstransformer.cfg index 8c8e31a..e69de29 100644 --- a/common/src/main/resources/META-INF/accesstransformer.cfg +++ b/common/src/main/resources/META-INF/accesstransformer.cfg @@ -1 +0,0 @@ -public net.minecraft.server.players.GameProfileCache$GameProfileInfo diff --git a/common/src/main/resources/skinrestorer.accesswidener b/common/src/main/resources/skinrestorer.accesswidener index 28ef0d1..9ab2173 100644 --- a/common/src/main/resources/skinrestorer.accesswidener +++ b/common/src/main/resources/skinrestorer.accesswidener @@ -1,3 +1 @@ accessWidener v2 named - -accessible class net/minecraft/server/players/GameProfileCache$GameProfileInfo diff --git a/common/src/main/resources/skinrestorer.mixins.json b/common/src/main/resources/skinrestorer.mixins.json index 1956e5a..741efe1 100644 --- a/common/src/main/resources/skinrestorer.mixins.json +++ b/common/src/main/resources/skinrestorer.mixins.json @@ -10,8 +10,7 @@ "PlayerListMixin", "ServerLoginPacketListenerImplMixin", "TrackedEntityAccessorInvoker", - "SkullBlockEntityMixin", - "GameProfileCacheAccessor" + "PlayerAccessor" ], "injectors": { "defaultRequire": 1 diff --git a/fabric/gradle.properties b/fabric/gradle.properties index d4f3a28..7dc2ea4 100644 --- a/fabric/gradle.properties +++ b/fabric/gradle.properties @@ -1,6 +1,6 @@ # Fabric, see https://fabricmc.net/develop/ for new versions fabric_loader_version=0.15.0 -fabric_api_version=0.127.0+1.21.6 +fabric_api_version=0.133.14+1.21.9 optional_dependencies=fabric-api additional_modloaders=quilt diff --git a/fabric/src/main/java/net/lionarius/skinrestorer/fabric/compat/skinshuffle/SkinShuffleCompatibility.java b/fabric/src/main/java/net/lionarius/skinrestorer/fabric/compat/skinshuffle/SkinShuffleCompatibility.java index 662ae14..b8073a4 100644 --- a/fabric/src/main/java/net/lionarius/skinrestorer/fabric/compat/skinshuffle/SkinShuffleCompatibility.java +++ b/fabric/src/main/java/net/lionarius/skinrestorer/fabric/compat/skinshuffle/SkinShuffleCompatibility.java @@ -32,6 +32,6 @@ public final class SkinShuffleCompatibility { } private static void handleSkinRefreshPacket(SkinShuffleSkinRefreshPayload payload, ServerPlayNetworking.Context context) { - net.lionarius.skinrestorer.compat.skinshuffle.SkinShuffleCompatibility.handleSkinRefresh(context.player().getServer(), context.player(), payload); + net.lionarius.skinrestorer.compat.skinshuffle.SkinShuffleCompatibility.handleSkinRefresh(SkinRestorer.getMinecraftServer(), context.player(), payload); } } diff --git a/forge/gradle.properties b/forge/gradle.properties index 1d49e44..d1e8843 100644 --- a/forge/gradle.properties +++ b/forge/gradle.properties @@ -1,5 +1,5 @@ # Forge, see https://files.minecraftforge.net/net/minecraftforge/forge/ for new versions -forge_version=56.0.0 -forge_loader_version_range=[56,) +forge_version=59.0.0 +forge_loader_version_range=[59,) # Forge sometimes skips minor minecraft versions (like 1.20.5) -forge_minecraft_version=1.21.6 +forge_minecraft_version=1.21.9 diff --git a/forge/src/main/java/net/lionarius/skinrestorer/forge/compat/skinshuffle/SkinShufflePacketHandler.java b/forge/src/main/java/net/lionarius/skinrestorer/forge/compat/skinshuffle/SkinShufflePacketHandler.java index badc589..efd5049 100644 --- a/forge/src/main/java/net/lionarius/skinrestorer/forge/compat/skinshuffle/SkinShufflePacketHandler.java +++ b/forge/src/main/java/net/lionarius/skinrestorer/forge/compat/skinshuffle/SkinShufflePacketHandler.java @@ -40,6 +40,6 @@ public class SkinShufflePacketHandler { if (!context.isServerSide() || sender == null) return; - SkinShuffleCompatibility.handleSkinRefresh(sender.getServer(), sender, payload); + SkinShuffleCompatibility.handleSkinRefresh(SkinRestorer.getMinecraftServer(), sender, payload); } } diff --git a/gradle.properties b/gradle.properties index 11b2125..2ee5965 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,9 +3,9 @@ group=net.lionarius java_version=21 # Common -minecraft_version=1.21.6 -minecraft_version_list=1.21.6,1.21.7,1.21.8 -minecraft_version_range=[1.21.6, 1.22) +minecraft_version=1.21.9 +minecraft_version_list=1.21.9 +minecraft_version_range=[1.21.9, 1.22) mod_id=skinrestorer mod_name=SkinRestorer mod_version=2.4.3 @@ -21,8 +21,8 @@ description=A server-side mod for managing skins. mineskin_client_version=3.0.6-SNAPSHOT # ParchmentMC mappings, see https://parchmentmc.org/docs/getting-started#choose-a-version for new versions -parchment_minecraft=1.21.5 -parchment_version=2025.06.15 +parchment_minecraft=1.21.8 +parchment_version=2025.09.14 # Publishing curseforge_id=443823 diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 0385d9e..0c9aca9 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -55,6 +55,4 @@ dependencies { prefer mineskin_client_version } } - - additionalRuntimeClasspath "org.mineskin:java-client:${mineskin_client_version}" } diff --git a/neoforge/gradle.properties b/neoforge/gradle.properties index 4fe7510..4ecb081 100644 --- a/neoforge/gradle.properties +++ b/neoforge/gradle.properties @@ -1,3 +1,3 @@ # NeoForge, see https://projects.neoforged.net/neoforged/neoforge for new versions -neoforge_version=21.6.0-beta +neoforge_version=21.9.0-beta neoforge_loader_version_range=[4,) diff --git a/neoforge/src/main/java/net/lionarius/skinrestorer/neoforge/compat/skinshuffle/SkinShuffleModEventHandler.java b/neoforge/src/main/java/net/lionarius/skinrestorer/neoforge/compat/skinshuffle/SkinShuffleModEventHandler.java index fdd2fdc..99c41f4 100644 --- a/neoforge/src/main/java/net/lionarius/skinrestorer/neoforge/compat/skinshuffle/SkinShuffleModEventHandler.java +++ b/neoforge/src/main/java/net/lionarius/skinrestorer/neoforge/compat/skinshuffle/SkinShuffleModEventHandler.java @@ -1,5 +1,6 @@ package net.lionarius.skinrestorer.neoforge.compat.skinshuffle; +import net.lionarius.skinrestorer.SkinRestorer; import net.lionarius.skinrestorer.compat.skinshuffle.*; import net.lionarius.skinrestorer.compat.skinshuffle.SkinShuffleCompatibility; import net.minecraft.server.level.ServerPlayer; @@ -26,6 +27,6 @@ public final class SkinShuffleModEventHandler { private static void handleSkinRefreshPacket(SkinShuffleSkinRefreshPayload payload, IPayloadContext context) { var player = (ServerPlayer) context.player(); - SkinShuffleCompatibility.handleSkinRefresh(player.getServer(), player, payload); + SkinShuffleCompatibility.handleSkinRefresh(SkinRestorer.getMinecraftServer(), player, payload); } }