1
0
mirror of https://github.com/Suiranoil/SkinRestorer.git synced 2026-01-16 04:42:12 +00:00

Fix the bug that fetching skin on the main thread

This commit is contained in:
CaveNightingale
2022-10-31 19:59:36 +08:00
parent 3362c267cb
commit 45492368be
3 changed files with 71 additions and 18 deletions

View File

@@ -1,10 +1,6 @@
package net.lionarius.skinrestorer.mixin;
import com.mojang.authlib.properties.Property;
import net.lionarius.skinrestorer.MojangSkinProvider;
import net.lionarius.skinrestorer.SkinRestorer;
import net.lionarius.skinrestorer.SkinStorage;
import net.minecraft.network.ClientConnection;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.network.ServerPlayerEntity;
import org.spongepowered.asm.mixin.Mixin;
@@ -14,27 +10,15 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
import java.util.Objects;
@Mixin(PlayerManager.class)
public abstract class PlayerManagerMixin {
private static void applySkin(ServerPlayerEntity playerEntity, Property skin) {
playerEntity.getGameProfile().getProperties().removeAll("textures");
playerEntity.getGameProfile().getProperties().put("textures", skin);
}
@Shadow
public abstract List<ServerPlayerEntity> getPlayerList();
@Inject(method = "onPlayerConnect", at = @At(value = "HEAD"))
private void onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, CallbackInfo ci) {
if (SkinRestorer.getSkinStorage().getSkin(player.getUuid()) == SkinStorage.DEFAULT_SKIN)
SkinRestorer.getSkinStorage().setSkin(player.getUuid(), MojangSkinProvider.getSkin(player.getGameProfile().getName()));
applySkin(player, SkinRestorer.getSkinStorage().getSkin(player.getUuid()));
}
@Inject(method = "remove", at = @At("TAIL"))
private void remove(ServerPlayerEntity player, CallbackInfo ci) {
SkinRestorer.getSkinStorage().removeSkin(player.getUuid());

View File

@@ -0,0 +1,68 @@
package net.lionarius.skinrestorer.mixin;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import net.lionarius.skinrestorer.MojangSkinProvider;
import net.lionarius.skinrestorer.SkinRestorer;
import net.lionarius.skinrestorer.SkinStorage;
import net.minecraft.network.packet.c2s.login.LoginHelloC2SPacket;
import net.minecraft.server.network.ServerLoginNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.concurrent.CompletableFuture;
@Mixin(ServerLoginNetworkHandler.class)
public abstract class ServerLoginNetworkHandlerMixin {
@Shadow @Nullable GameProfile profile;
@Shadow protected abstract GameProfile toOfflineProfile(GameProfile profile);
@Shadow @Final
static Logger LOGGER;
private CompletableFuture<Property> skinrestorer_pendingSkin;
@Inject(method = "onHello", at = @At("RETURN"))
public void onHelloReturn(LoginHelloC2SPacket packet, CallbackInfo ci) {
assert profile != null;
GameProfile profile1;
if (!profile.isComplete()) {
profile1 = profile = toOfflineProfile(this.profile);
} else {
profile1 = profile;
}
skinrestorer_pendingSkin = CompletableFuture.supplyAsync(() -> {
LOGGER.debug("Fetching {}'s skin", profile1.getName());
if (SkinRestorer.getSkinStorage().getSkin(profile1.getId()) == SkinStorage.DEFAULT_SKIN)
SkinRestorer.getSkinStorage().setSkin(profile1.getId(), MojangSkinProvider.getSkin(profile1.getName()));
return SkinRestorer.getSkinStorage().getSkin(profile1.getId());
});
}
@Inject(method = "acceptPlayer", at = @At("HEAD"), cancellable = true)
public void waitForSkin(CallbackInfo ci) {
if (skinrestorer_pendingSkin != null && !skinrestorer_pendingSkin.isDone()) {
ci.cancel();
}
}
private static void applyRestoreSkin(ServerPlayerEntity playerEntity, Property skin) {
playerEntity.getGameProfile().getProperties().removeAll("textures");
playerEntity.getGameProfile().getProperties().put("textures", skin);
}
@Inject(method = "addToServer", at = @At("HEAD"))
public void applyRestoredSkinHook(ServerPlayerEntity player, CallbackInfo ci) {
if (skinrestorer_pendingSkin != null) {
applyRestoreSkin(player, skinrestorer_pendingSkin.getNow(SkinStorage.DEFAULT_SKIN));
}
}
}

View File

@@ -5,7 +5,8 @@
"compatibilityLevel": "JAVA_16",
"mixins": [
"CommandManagerMixin",
"PlayerManagerMixin"
"PlayerManagerMixin",
"ServerLoginNetworkHandlerMixin"
],
"injectors": {
"defaultRequire": 1