mirror of
https://github.com/Suiranoil/SkinRestorer.git
synced 2026-01-16 04:42:12 +00:00
add SkinResult class
This commit is contained in:
@@ -15,7 +15,7 @@ public class MineskinSkinProvider {
|
||||
private static final String USER_AGENT = "SkinRestorer";
|
||||
private static final String TYPE = "application/json";
|
||||
|
||||
public static Property getSkin(String url, SkinVariant variant) {
|
||||
public static SkinResult getSkin(String url, SkinVariant variant) {
|
||||
try {
|
||||
String input = ("{\"variant\":\"%s\",\"name\":\"%s\",\"visibility\":%d,\"url\":\"%s\"}")
|
||||
.formatted(variant.toString(), "none", 1, url);
|
||||
@@ -23,9 +23,9 @@ public class MineskinSkinProvider {
|
||||
JsonObject texture = JsonUtils.parseJson(WebUtils.POSTRequest(new URL(API), USER_AGENT, TYPE, TYPE, input))
|
||||
.getAsJsonObject("data").getAsJsonObject("texture");
|
||||
|
||||
return new Property("textures", texture.get("value").getAsString(), texture.get("signature").getAsString());
|
||||
return SkinResult.success(new Property("textures", texture.get("value").getAsString(), texture.get("signature").getAsString()));
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
return SkinResult.error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ public class MojangSkinProvider {
|
||||
private static final String API = "https://api.mojang.com/users/profiles/minecraft/";
|
||||
private static final String SESSION_SERVER = "https://sessionserver.mojang.com/session/minecraft/profile/";
|
||||
|
||||
public static Property getSkin(String name) {
|
||||
public static SkinResult getSkin(String name) {
|
||||
try {
|
||||
UUID uuid = getUUID(name);
|
||||
JsonObject texture = JsonUtils.parseJson(WebUtils.GETRequest(new URL(SESSION_SERVER + uuid + "?unsigned=false")))
|
||||
.getAsJsonArray("properties").get(0).getAsJsonObject();
|
||||
|
||||
return new Property("textures", texture.get("value").getAsString(), texture.get("signature").getAsString());
|
||||
return SkinResult.success(new Property("textures", texture.get("value").getAsString(), texture.get("signature").getAsString()));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
return SkinResult.error();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@ public class SkinIO {
|
||||
this.savePath = savePath;
|
||||
}
|
||||
|
||||
public boolean skinExists(UUID uuid) {
|
||||
return savePath.resolve(uuid + FILE_EXTENSION).toFile().exists();
|
||||
}
|
||||
|
||||
public Property loadSkin(UUID uuid) {
|
||||
return JsonUtils.fromJson(FileUtils.readFile(savePath.resolve(uuid + FILE_EXTENSION).toFile()), Property.class);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerChunkManager;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -67,34 +66,33 @@ public class SkinRestorer implements DedicatedServerModInitializer {
|
||||
playerManager.sendStatusEffects(player);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Pair<Collection<ServerPlayerEntity>, Collection<GameProfile>>> setSkinAsync(MinecraftServer server, Collection<GameProfile> targets, Supplier<Property> skinSupplier) {
|
||||
return CompletableFuture.<Pair<Property, Collection<GameProfile>>>supplyAsync(() -> {
|
||||
public static CompletableFuture<Pair<Collection<ServerPlayerEntity>, Collection<GameProfile>>> setSkinAsync(MinecraftServer server, Collection<GameProfile> targets, Supplier<SkinResult> skinSupplier) {
|
||||
return CompletableFuture.<Pair<Optional<Property>, Collection<GameProfile>>>supplyAsync(() -> {
|
||||
HashSet<GameProfile> acceptedProfiles = new HashSet<>();
|
||||
Property skin = skinSupplier.get();
|
||||
if (Objects.isNull(skin)) {
|
||||
SkinResult result = skinSupplier.get();
|
||||
if (result.isError()) {
|
||||
SkinRestorer.LOGGER.error("Cannot get the skin for {}", targets.stream().findFirst().orElseThrow());
|
||||
return Pair.of(null, Collections.emptySet());
|
||||
}
|
||||
|
||||
Optional<Property> skin = result.getSkin();
|
||||
|
||||
for (GameProfile profile : targets) {
|
||||
SkinRestorer.getSkinStorage().setSkin(profile.getId(), skin);
|
||||
SkinRestorer.getSkinStorage().setSkin(profile.getId(), skin.orElse(null));
|
||||
acceptedProfiles.add(profile);
|
||||
}
|
||||
|
||||
return Pair.of(skin, acceptedProfiles);
|
||||
}).<Pair<Collection<ServerPlayerEntity>, Collection<GameProfile>>>thenApplyAsync(pair -> {
|
||||
Property skin = pair.left();
|
||||
if (Objects.isNull(skin))
|
||||
return Pair.of(Collections.emptySet(), Collections.emptySet());
|
||||
Property skin = pair.left().orElse(null);
|
||||
|
||||
Collection<GameProfile> acceptedProfiles = pair.right();
|
||||
HashSet<ServerPlayerEntity> acceptedPlayers = new HashSet<>();
|
||||
JsonObject newSkinJson = gson.fromJson(new String(Base64.getDecoder().decode(skin.value()), StandardCharsets.UTF_8), JsonObject.class);
|
||||
newSkinJson.remove("timestamp");
|
||||
|
||||
for (GameProfile profile : acceptedProfiles) {
|
||||
ServerPlayerEntity player = server.getPlayerManager().getPlayer(profile.getId());
|
||||
|
||||
if (player == null || arePropertiesEquals(newSkinJson, player.getGameProfile()))
|
||||
if (player == null || areSkinPropertiesEquals(skin, getPlayerSkin(player)))
|
||||
continue;
|
||||
|
||||
applyRestoredSkin(player.getGameProfile(), skin);
|
||||
@@ -107,23 +105,44 @@ public class SkinRestorer implements DedicatedServerModInitializer {
|
||||
|
||||
public static void applyRestoredSkin(GameProfile profile, Property skin) {
|
||||
profile.getProperties().removeAll("textures");
|
||||
profile.getProperties().put("textures", skin);
|
||||
if (skin != null)
|
||||
profile.getProperties().put("textures", skin);
|
||||
}
|
||||
|
||||
private static Property getPlayerSkin(ServerPlayerEntity player) {
|
||||
return player.getGameProfile().getProperties().get("textures").stream().findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
private static boolean arePropertiesEquals(@NotNull JsonObject x, @NotNull GameProfile y) {
|
||||
Property py = y.getProperties().get("textures").stream().findFirst().orElse(null);
|
||||
if (py == null)
|
||||
return false;
|
||||
|
||||
private static JsonObject skinPropertyToJson(Property property) {
|
||||
try {
|
||||
JsonObject jy = gson.fromJson(new String(Base64.getDecoder().decode(py.value()), StandardCharsets.UTF_8), JsonObject.class);
|
||||
jy.remove("timestamp");
|
||||
return x.equals(jy);
|
||||
JsonObject json = gson.fromJson(new String(Base64.getDecoder().decode(property.value()), StandardCharsets.UTF_8), JsonObject.class);
|
||||
if (!Objects.isNull(json))
|
||||
json.remove("timestamp");
|
||||
|
||||
return json;
|
||||
} catch (Exception ex) {
|
||||
SkinRestorer.LOGGER.info("Can not compare skin", ex);
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean areSkinPropertiesEquals(Property x, Property y) {
|
||||
if (x == y)
|
||||
return true;
|
||||
|
||||
if (x == null || y == null)
|
||||
return false;
|
||||
|
||||
if (x.equals(y))
|
||||
return true;
|
||||
|
||||
JsonObject xJson = skinPropertyToJson(x);
|
||||
JsonObject yJson = skinPropertyToJson(y);
|
||||
|
||||
if (xJson == null || yJson == null)
|
||||
return false;
|
||||
|
||||
return xJson.equals(yJson);
|
||||
}
|
||||
}
|
||||
|
||||
43
src/main/java/net/lionarius/skinrestorer/SkinResult.java
Normal file
43
src/main/java/net/lionarius/skinrestorer/SkinResult.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package net.lionarius.skinrestorer;
|
||||
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class SkinResult {
|
||||
private final Property skin;
|
||||
private final boolean isError;
|
||||
|
||||
private SkinResult(Property skin, boolean isError) {
|
||||
this.skin = skin;
|
||||
this.isError = isError;
|
||||
}
|
||||
|
||||
public Optional<Property> getSkin() {
|
||||
return Optional.ofNullable(this.skin);
|
||||
}
|
||||
|
||||
public boolean isError() {
|
||||
return this.isError;
|
||||
}
|
||||
|
||||
public static SkinResult empty() {
|
||||
return new SkinResult(null, false);
|
||||
}
|
||||
|
||||
public static SkinResult error() {
|
||||
return new SkinResult(null, true);
|
||||
}
|
||||
|
||||
public static SkinResult success(@NotNull Property skin) {
|
||||
return new SkinResult(skin, false);
|
||||
}
|
||||
|
||||
public static SkinResult ofNullable(Property skin) {
|
||||
if (skin == null)
|
||||
return SkinResult.empty();
|
||||
|
||||
return SkinResult.success(skin);
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,6 @@ import java.util.UUID;
|
||||
|
||||
public class SkinStorage {
|
||||
|
||||
public static final Property DEFAULT_SKIN = new Property("textures", "ewogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJpZCIgOiAiZWZhMTFjN2U1YThlNGIwM2JjMDQ0MWRmNzk1YjE0YjIiLAogICAgICAidHlwZSIgOiAiU0tJTiIsCiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTYzNDM4OTUzYTc4MmRhNzY5NDgwYjBhNDkxMjVhOTJlMjU5MjA3NzAwY2I4ZTNlMWFhYzM4ZTQ3MWUyMDMwOCIsCiAgICAgICJwcm9maWxlSWQiIDogImZkNjBmMzZmNTg2MTRmMTJiM2NkNDdjMmQ4NTUyOTlhIiwKICAgICAgInRleHR1cmVJZCIgOiAiOTYzNDM4OTUzYTc4MmRhNzY5NDgwYjBhNDkxMjVhOTJlMjU5MjA3NzAwY2I4ZTNlMWFhYzM4ZTQ3MWUyMDMwOCIKICAgIH0KICB9LAogICJza2luIiA6IHsKICAgICJpZCIgOiAiZWZhMTFjN2U1YThlNGIwM2JjMDQ0MWRmNzk1YjE0YjIiLAogICAgInR5cGUiIDogIlNLSU4iLAogICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS85NjM0Mzg5NTNhNzgyZGE3Njk0ODBiMGE0OTEyNWE5MmUyNTkyMDc3MDBjYjhlM2UxYWFjMzhlNDcxZTIwMzA4IiwKICAgICJwcm9maWxlSWQiIDogImZkNjBmMzZmNTg2MTRmMTJiM2NkNDdjMmQ4NTUyOTlhIiwKICAgICJ0ZXh0dXJlSWQiIDogIjk2MzQzODk1M2E3ODJkYTc2OTQ4MGIwYTQ5MTI1YTkyZTI1OTIwNzcwMGNiOGUzZTFhYWMzOGU0NzFlMjAzMDgiCiAgfSwKICAiY2FwZSIgOiBudWxsCn0=",
|
||||
"T6Czh1iATQTwG/ppZyY9N7cNASVHfGkiicrFykYAve4C7vG36ql0EPf6gMfMIS2eL0FdGLznnWiEC2dUxwNCJwiEyzTo/chlxZMk4TSzkBdBU3KTUZdNZrS/YhTzhi7C4eUVaEtXMRlCVtLQUa8Nb18SFYz243C9tlDsONNk42+xHPN1vRCRGIxfJbcU/mk4/XZzS4zHwPCkB6N4dKX2F6LA+a2P+CUMBluXKF56UiT1j7DjWs8B+6ES0kkmZUGkRaxTtcyN2Rqpx/2wCroohxkyVRAdlkcnwbEHOEKGoYMKdjUWpSm8QrsLkUiyLL3IK/hgd5ET2nI/aE1AloAwr1fotmvf9KF1JIfZljoefYZIaYZ1PpvduwIkAaeeIC4FFcdcBIheHitYyXOBAr/t5E+pTzCJOttDfYggFSyGxOj5yxgXTT4gSwTKp5zkQqiCKdAQQPmgFqxhWkZ2UaE9zq+E5jSOD0OJj3FmBscdZWKoOm+mWZkXbw9z2ZvuqXAKHsi6uVJyGeUzt2hJL8eqOyAmfYsJgfxhGZen5oOlxZra8OxIYlp8TcTwzEIDievgp0dfsGPObGVgtA8D39QiwLXs6e/o0qnzl3+wQJDa/ZqDMISULkBNhPx/TvhYW5MJw3hZIj2gsbf73n+jId1GOUfTVMaFlVf7pvPNqW0PieY=");
|
||||
|
||||
private final Map<UUID, Property> skinMap = new HashMap<>();
|
||||
private final SkinIO skinIO;
|
||||
|
||||
@@ -18,6 +15,10 @@ public class SkinStorage {
|
||||
this.skinIO = skinIO;
|
||||
}
|
||||
|
||||
public boolean hasSavedSkin(UUID uuid) {
|
||||
return this.skinIO.skinExists(uuid);
|
||||
}
|
||||
|
||||
public Property getSkin(UUID uuid) {
|
||||
if (!skinMap.containsKey(uuid)) {
|
||||
Property skin = skinIO.loadSkin(uuid);
|
||||
@@ -34,9 +35,6 @@ public class SkinStorage {
|
||||
}
|
||||
|
||||
public void setSkin(UUID uuid, Property skin) {
|
||||
if (skin == null)
|
||||
skin = DEFAULT_SKIN;
|
||||
|
||||
skinMap.put(uuid, skin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package net.lionarius.skinrestorer.command;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import net.lionarius.skinrestorer.MineskinSkinProvider;
|
||||
import net.lionarius.skinrestorer.MojangSkinProvider;
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.SkinResult;
|
||||
import net.lionarius.skinrestorer.enums.SkinVariant;
|
||||
import net.lionarius.skinrestorer.util.TranslationUtils;
|
||||
import net.minecraft.command.argument.GameProfileArgumentType;
|
||||
@@ -18,7 +18,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static net.lionarius.skinrestorer.SkinStorage.DEFAULT_SKIN;
|
||||
import static net.minecraft.server.command.CommandManager.argument;
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
|
||||
@@ -58,26 +57,29 @@ public class SkinCommand {
|
||||
.then(literal("clear")
|
||||
.executes(context ->
|
||||
skinAction(context.getSource(),
|
||||
() -> DEFAULT_SKIN))
|
||||
SkinResult::empty))
|
||||
.then(argument("targets", GameProfileArgumentType.gameProfile()).requires(source -> source.hasPermissionLevel(2)).executes(context ->
|
||||
skinAction(context.getSource(), GameProfileArgumentType.getProfileArgument(context, "targets"), true,
|
||||
() -> DEFAULT_SKIN))))
|
||||
SkinResult::empty))))
|
||||
);
|
||||
}
|
||||
|
||||
private static int skinAction(ServerCommandSource src, Collection<GameProfile> targets, boolean setByOperator, Supplier<Property> skinSupplier) {
|
||||
private static int skinAction(ServerCommandSource src, Collection<GameProfile> targets, boolean setByOperator, Supplier<SkinResult> skinSupplier) {
|
||||
SkinRestorer.setSkinAsync(src.getServer(), targets, skinSupplier).thenAccept(pair -> {
|
||||
Collection<GameProfile> profiles = pair.right();
|
||||
Collection<ServerPlayerEntity> players = pair.left();
|
||||
if (profiles.size() == 0) {
|
||||
|
||||
if (profiles.isEmpty()) {
|
||||
src.sendError(Text.of(TranslationUtils.translation.skinActionFailed));
|
||||
return;
|
||||
}
|
||||
|
||||
if (setByOperator) {
|
||||
src.sendFeedback(() -> Text.of(
|
||||
String.format(TranslationUtils.translation.skinActionAffectedProfile,
|
||||
String.join(", ", profiles.stream().map(GameProfile::getName).toList()))), true);
|
||||
if (players.size() != 0) {
|
||||
|
||||
if (!players.isEmpty()) {
|
||||
src.sendFeedback(() -> Text.of(
|
||||
String.format(TranslationUtils.translation.skinActionAffectedPlayer,
|
||||
String.join(", ", players.stream().map(p -> p.getGameProfile().getName()).toList()))), true);
|
||||
@@ -89,7 +91,7 @@ public class SkinCommand {
|
||||
return targets.size();
|
||||
}
|
||||
|
||||
private static int skinAction(ServerCommandSource src, Supplier<Property> skinSupplier) {
|
||||
private static int skinAction(ServerCommandSource src, Supplier<SkinResult> skinSupplier) {
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.lionarius.skinrestorer.mixin;
|
||||
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.SkinResult;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
@@ -21,6 +22,7 @@ public abstract class PlayerManagerMixin {
|
||||
|
||||
@Shadow
|
||||
public abstract List<ServerPlayerEntity> getPlayerList();
|
||||
|
||||
@Shadow @Final
|
||||
private MinecraftServer server;
|
||||
|
||||
@@ -39,6 +41,6 @@ public abstract class PlayerManagerMixin {
|
||||
@Inject(method = "onPlayerConnect", at = @At("HEAD"))
|
||||
private void onPlayerConnected(ClientConnection connection, ServerPlayerEntity player, ConnectedClientData clientData, CallbackInfo ci) {
|
||||
if (player.getClass() != ServerPlayerEntity.class) // if the player isn't a server player entity, it must be someone's fake player
|
||||
SkinRestorer.setSkinAsync(server, Collections.singleton(player.getGameProfile()), () -> SkinRestorer.getSkinStorage().getSkin(player.getUuid()));
|
||||
SkinRestorer.setSkinAsync(server, Collections.singleton(player.getGameProfile()), () -> SkinResult.ofNullable(SkinRestorer.getSkinStorage().getSkin(player.getUuid())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
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.lionarius.skinrestorer.SkinResult;
|
||||
import net.minecraft.server.network.ServerLoginNetworkHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
@@ -21,34 +20,37 @@ import java.util.concurrent.CompletableFuture;
|
||||
@Mixin(ServerLoginNetworkHandler.class)
|
||||
public abstract class ServerLoginNetworkHandlerMixin {
|
||||
|
||||
@Shadow @Nullable
|
||||
private GameProfile profile;
|
||||
@Shadow @Final
|
||||
static Logger LOGGER;
|
||||
@Shadow @Nullable
|
||||
private GameProfile profile;
|
||||
@Shadow @Final
|
||||
static Logger LOGGER;
|
||||
|
||||
@Unique
|
||||
private CompletableFuture<Property> skinrestorer_pendingSkin;
|
||||
@Unique
|
||||
private CompletableFuture<SkinResult> skinrestorer_pendingSkin;
|
||||
|
||||
@Inject(method = "tickVerify", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;checkCanJoin(Ljava/net/SocketAddress;Lcom/mojang/authlib/GameProfile;)Lnet/minecraft/text/Text;"), cancellable = true)
|
||||
public void waitForSkin(CallbackInfo ci) {
|
||||
if (skinrestorer_pendingSkin == null) {
|
||||
skinrestorer_pendingSkin = CompletableFuture.supplyAsync(() -> {
|
||||
LOGGER.debug("Fetching {}'s skin", profile.getName());
|
||||
if (SkinRestorer.getSkinStorage().getSkin(profile.getId()) == SkinStorage.DEFAULT_SKIN)
|
||||
SkinRestorer.getSkinStorage().setSkin(profile.getId(), MojangSkinProvider.getSkin(profile.getName()));
|
||||
@Inject(method = "tickVerify", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;checkCanJoin(Ljava/net/SocketAddress;Lcom/mojang/authlib/GameProfile;)Lnet/minecraft/text/Text;"), cancellable = true)
|
||||
public void waitForSkin(CallbackInfo ci) {
|
||||
if (skinrestorer_pendingSkin == null) {
|
||||
skinrestorer_pendingSkin = CompletableFuture.supplyAsync(() -> {
|
||||
LOGGER.debug("Fetching {}'s skin", profile.getName());
|
||||
if (!SkinRestorer.getSkinStorage().hasSavedSkin(profile.getId())) {
|
||||
SkinResult result = MojangSkinProvider.getSkin(profile.getName());
|
||||
if (!result.isError())
|
||||
SkinRestorer.getSkinStorage().setSkin(profile.getId(), result.getSkin().orElse(null));
|
||||
}
|
||||
|
||||
return SkinRestorer.getSkinStorage().getSkin(profile.getId());
|
||||
});
|
||||
}
|
||||
return SkinResult.ofNullable(SkinRestorer.getSkinStorage().getSkin(profile.getId()));
|
||||
});
|
||||
}
|
||||
|
||||
if (!skinrestorer_pendingSkin.isDone()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
if (!skinrestorer_pendingSkin.isDone()) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "sendSuccessPacket", at = @At("HEAD"))
|
||||
public void applyRestoredSkinHook(GameProfile profile, CallbackInfo ci) {
|
||||
if (skinrestorer_pendingSkin != null)
|
||||
SkinRestorer.applyRestoredSkin(profile, skinrestorer_pendingSkin.getNow(SkinStorage.DEFAULT_SKIN));
|
||||
}
|
||||
@Inject(method = "sendSuccessPacket", at = @At("HEAD"))
|
||||
public void applyRestoredSkinHook(GameProfile profile, CallbackInfo ci) {
|
||||
if (skinrestorer_pendingSkin != null)
|
||||
SkinRestorer.applyRestoredSkin(profile, skinrestorer_pendingSkin.getNow(SkinResult.empty()).getSkin().orElse(null));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user