mirror of
https://github.com/Suiranoil/SkinRestorer.git
synced 2026-01-16 04:42:12 +00:00
support custom skins for player head block
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
package net.lionarius.skinrestorer.mixin;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.util.PlayerUtils;
|
||||
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.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<CompletableFuture<Optional<GameProfile>>> cir) {
|
||||
var profileOpt = services.profileCache().get(name);
|
||||
|
||||
skinrestorer$replaceSkin(profileOpt, cir);
|
||||
}
|
||||
|
||||
@Inject(method = "fetchProfileById", at = @At("HEAD"),
|
||||
cancellable = true)
|
||||
private static void fetchProfileById(UUID id, Services services, BooleanSupplier cacheUninitialized, CallbackInfoReturnable<CompletableFuture<Optional<GameProfile>>> cir) {
|
||||
var profileOpt = services.profileCache().get(id);
|
||||
|
||||
skinrestorer$replaceSkin(profileOpt, cir);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static void skinrestorer$replaceSkin(Optional<GameProfile> profileOpt, CallbackInfoReturnable<CompletableFuture<Optional<GameProfile>>> cir) {
|
||||
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);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,15 +17,22 @@ public class SkinStorage {
|
||||
return this.skinMap.containsKey(uuid) || this.skinIO.skinExists(uuid);
|
||||
}
|
||||
|
||||
public SkinValue getSkin(UUID uuid) {
|
||||
public SkinValue getSkin(UUID uuid, boolean cache) {
|
||||
if (!skinMap.containsKey(uuid)) {
|
||||
var skin = skinIO.loadSkin(uuid);
|
||||
if (!cache)
|
||||
return skin;
|
||||
|
||||
setSkin(uuid, skin);
|
||||
}
|
||||
|
||||
return skinMap.get(uuid);
|
||||
}
|
||||
|
||||
public SkinValue getSkin(UUID uuid) {
|
||||
return this.getSkin(uuid, true);
|
||||
}
|
||||
|
||||
public void removeSkin(UUID uuid, boolean save) {
|
||||
var skin = skinMap.remove(uuid);
|
||||
if (skin != null && save)
|
||||
|
||||
@@ -96,6 +96,13 @@ public final class PlayerUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static GameProfile cloneGameProfile(GameProfile profile) {
|
||||
var newProfile = new GameProfile(profile.getId(), profile.getName());
|
||||
newProfile.getProperties().putAll(profile.getProperties());
|
||||
|
||||
return newProfile;
|
||||
}
|
||||
|
||||
public static Property getPlayerSkin(GameProfile profile) {
|
||||
return Iterables.getFirst(profile.getProperties().get(TEXTURES_KEY), null);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"ChunkMapAccessor",
|
||||
"PlayerListMixin",
|
||||
"ServerLoginPacketListenerImplMixin",
|
||||
"TrackedEntityAccessorInvoker"
|
||||
"TrackedEntityAccessorInvoker",
|
||||
"SkullBlockEntityMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
||||
Reference in New Issue
Block a user