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);
|
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)) {
|
if (!skinMap.containsKey(uuid)) {
|
||||||
var skin = skinIO.loadSkin(uuid);
|
var skin = skinIO.loadSkin(uuid);
|
||||||
|
if (!cache)
|
||||||
|
return skin;
|
||||||
|
|
||||||
setSkin(uuid, skin);
|
setSkin(uuid, skin);
|
||||||
}
|
}
|
||||||
|
|
||||||
return skinMap.get(uuid);
|
return skinMap.get(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SkinValue getSkin(UUID uuid) {
|
||||||
|
return this.getSkin(uuid, true);
|
||||||
|
}
|
||||||
|
|
||||||
public void removeSkin(UUID uuid, boolean save) {
|
public void removeSkin(UUID uuid, boolean save) {
|
||||||
var skin = skinMap.remove(uuid);
|
var skin = skinMap.remove(uuid);
|
||||||
if (skin != null && save)
|
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) {
|
public static Property getPlayerSkin(GameProfile profile) {
|
||||||
return Iterables.getFirst(profile.getProperties().get(TEXTURES_KEY), null);
|
return Iterables.getFirst(profile.getProperties().get(TEXTURES_KEY), null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
"ChunkMapAccessor",
|
"ChunkMapAccessor",
|
||||||
"PlayerListMixin",
|
"PlayerListMixin",
|
||||||
"ServerLoginPacketListenerImplMixin",
|
"ServerLoginPacketListenerImplMixin",
|
||||||
"TrackedEntityAccessorInvoker"
|
"TrackedEntityAccessorInvoker",
|
||||||
|
"SkullBlockEntityMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|||||||
Reference in New Issue
Block a user