mirror of
https://github.com/Suiranoil/SkinRestorer.git
synced 2026-01-16 04:42:12 +00:00
migrate mappings to official
This commit is contained in:
11
build.gradle
11
build.gradle
@@ -39,11 +39,18 @@ subprojects {
|
||||
build.finalizedBy(mergeJars)
|
||||
assemble.finalizedBy(mergeJars)
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'ParchmentMC'
|
||||
url = 'https://maven.parchmentmc.org'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "net.minecraft:minecraft:$rootProject.minecraft_version"
|
||||
mappings loom.layered {
|
||||
it.mappings("net.fabricmc:yarn:$rootProject.yarn_mappings:v2")
|
||||
it.mappings("dev.architectury:yarn-mappings-patch-neoforge:$rootProject.yarn_mappings_patch_neoforge_version")
|
||||
officialMojangMappings()
|
||||
parchment("org.parchmentmc.data:parchment-$rootProject.minecraft_version:$rootProject.parchment_mappings@zip")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ import net.lionarius.skinrestorer.skin.provider.SkinProvider;
|
||||
import net.lionarius.skinrestorer.util.FileUtils;
|
||||
import net.lionarius.skinrestorer.util.PlayerUtils;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.WorldSavePath;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.storage.LevelResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -57,13 +57,13 @@ public final class SkinRestorer {
|
||||
}
|
||||
|
||||
public static void onServerStarted(MinecraftServer server) {
|
||||
Path worldSkinDirectory = server.getSavePath(WorldSavePath.ROOT).resolve(SkinRestorer.MOD_ID);
|
||||
Path worldSkinDirectory = server.getWorldPath(LevelResource.ROOT).resolve(SkinRestorer.MOD_ID);
|
||||
FileUtils.tryMigrateOldSkinDirectory(worldSkinDirectory);
|
||||
|
||||
SkinRestorer.skinStorage = new SkinStorage(new SkinIO(worldSkinDirectory));
|
||||
}
|
||||
|
||||
public static CompletableFuture<Pair<Collection<ServerPlayerEntity>, Collection<GameProfile>>> setSkinAsync(MinecraftServer server, Collection<GameProfile> targets, Supplier<SkinResult> skinSupplier) {
|
||||
public static CompletableFuture<Pair<Collection<ServerPlayer>, Collection<GameProfile>>> setSkinAsync(MinecraftServer server, Collection<GameProfile> targets, Supplier<SkinResult> skinSupplier) {
|
||||
return CompletableFuture.<Pair<Property, Collection<GameProfile>>>supplyAsync(() -> {
|
||||
SkinResult result = skinSupplier.get();
|
||||
if (result.isError()) {
|
||||
@@ -80,14 +80,14 @@ public final class SkinRestorer {
|
||||
HashSet<GameProfile> acceptedProfiles = new HashSet<>(targets);
|
||||
|
||||
return Pair.of(skin, acceptedProfiles);
|
||||
}).<Pair<Collection<ServerPlayerEntity>, Collection<GameProfile>>>thenApplyAsync(pair -> {
|
||||
}).<Pair<Collection<ServerPlayer>, Collection<GameProfile>>>thenApplyAsync(pair -> {
|
||||
Property skin = pair.left(); // NullPtrException will be caught by 'exceptionally'
|
||||
|
||||
Collection<GameProfile> acceptedProfiles = pair.right();
|
||||
HashSet<ServerPlayerEntity> acceptedPlayers = new HashSet<>();
|
||||
HashSet<ServerPlayer> acceptedPlayers = new HashSet<>();
|
||||
|
||||
for (GameProfile profile : acceptedProfiles) {
|
||||
ServerPlayerEntity player = server.getPlayerManager().getPlayer(profile.getId());
|
||||
ServerPlayer player = server.getPlayerList().getPlayer(profile.getId());
|
||||
|
||||
if (player == null || PlayerUtils.areSkinPropertiesEquals(skin, PlayerUtils.getPlayerSkin(player)))
|
||||
continue;
|
||||
|
||||
@@ -12,10 +12,10 @@ import net.lionarius.skinrestorer.skin.SkinResult;
|
||||
import net.lionarius.skinrestorer.skin.SkinVariant;
|
||||
import net.lionarius.skinrestorer.skin.provider.SkinProvider;
|
||||
import net.lionarius.skinrestorer.util.TranslationUtils;
|
||||
import net.minecraft.command.argument.GameProfileArgumentType;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.arguments.GameProfileArgument;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -23,19 +23,19 @@ import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.argument;
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
import static net.minecraft.commands.Commands.argument;
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
|
||||
public final class SkinCommand {
|
||||
|
||||
private SkinCommand() {}
|
||||
|
||||
public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
|
||||
LiteralArgumentBuilder<ServerCommandSource> base =
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
||||
LiteralArgumentBuilder<CommandSourceStack> base =
|
||||
literal("skin")
|
||||
.then(buildAction("clear", SkinResult::empty));
|
||||
|
||||
LiteralArgumentBuilder<ServerCommandSource> set = literal("set");
|
||||
LiteralArgumentBuilder<CommandSourceStack> set = literal("set");
|
||||
|
||||
for (Map.Entry<String, SkinProvider> entry : SkinRestorer.getProviders()) {
|
||||
set.then(buildAction(entry.getKey(), entry.getValue()));
|
||||
@@ -46,8 +46,8 @@ public final class SkinCommand {
|
||||
dispatcher.register(base);
|
||||
}
|
||||
|
||||
private static LiteralArgumentBuilder<ServerCommandSource> buildAction(String name, SkinProvider provider) {
|
||||
LiteralArgumentBuilder<ServerCommandSource> action = literal(name);
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> buildAction(String name, SkinProvider provider) {
|
||||
LiteralArgumentBuilder<CommandSourceStack> action = literal(name);
|
||||
|
||||
if (provider.hasVariantSupport()) {
|
||||
for (SkinVariant variant : SkinVariant.values()) {
|
||||
@@ -71,13 +71,13 @@ public final class SkinCommand {
|
||||
return action;
|
||||
}
|
||||
|
||||
private static ArgumentBuilder<ServerCommandSource, LiteralArgumentBuilder<ServerCommandSource>> buildAction(String name, Supplier<SkinResult> supplier) {
|
||||
private static ArgumentBuilder<CommandSourceStack, LiteralArgumentBuilder<CommandSourceStack>> buildAction(String name, Supplier<SkinResult> supplier) {
|
||||
return buildArgument(literal(name), context -> supplier.get());
|
||||
}
|
||||
|
||||
private static <T extends ArgumentBuilder<ServerCommandSource, T>> ArgumentBuilder<ServerCommandSource, T> buildArgument(
|
||||
ArgumentBuilder<ServerCommandSource, T> argument,
|
||||
Function<CommandContext<ServerCommandSource>, SkinResult> provider
|
||||
private static <T extends ArgumentBuilder<CommandSourceStack, T>> ArgumentBuilder<CommandSourceStack, T> buildArgument(
|
||||
ArgumentBuilder<CommandSourceStack, T> argument,
|
||||
Function<CommandContext<CommandSourceStack>, SkinResult> provider
|
||||
) {
|
||||
return argument
|
||||
.executes(context -> skinAction(
|
||||
@@ -87,47 +87,47 @@ public final class SkinCommand {
|
||||
.then(makeTargetsArgument(provider));
|
||||
}
|
||||
|
||||
private static RequiredArgumentBuilder<ServerCommandSource, GameProfileArgumentType.GameProfileArgument> makeTargetsArgument(
|
||||
Function<CommandContext<ServerCommandSource>, SkinResult> provider
|
||||
private static RequiredArgumentBuilder<CommandSourceStack, GameProfileArgument.Result> makeTargetsArgument(
|
||||
Function<CommandContext<CommandSourceStack>, SkinResult> provider
|
||||
) {
|
||||
return argument("targets", GameProfileArgumentType.gameProfile())
|
||||
.requires(source -> source.hasPermissionLevel(2))
|
||||
return argument("targets", GameProfileArgument.gameProfile())
|
||||
.requires(source -> source.hasPermission(2))
|
||||
.executes(context -> skinAction(
|
||||
context.getSource(),
|
||||
GameProfileArgumentType.getProfileArgument(context, "targets"),
|
||||
GameProfileArgument.getGameProfiles(context, "targets"),
|
||||
true,
|
||||
() -> provider.apply(context)
|
||||
));
|
||||
}
|
||||
|
||||
private static int skinAction(ServerCommandSource src, Collection<GameProfile> targets, boolean setByOperator, Supplier<SkinResult> skinSupplier) {
|
||||
private static int skinAction(CommandSourceStack 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();
|
||||
Collection<ServerPlayer> players = pair.left();
|
||||
|
||||
if (profiles.isEmpty()) {
|
||||
src.sendError(Text.of(TranslationUtils.getTranslation().skinActionFailed));
|
||||
src.sendFailure(Component.nullToEmpty(TranslationUtils.getTranslation().skinActionFailed));
|
||||
return;
|
||||
}
|
||||
|
||||
if (setByOperator) {
|
||||
src.sendFeedback(() -> Text.of(
|
||||
src.sendSuccess(() -> Component.nullToEmpty(
|
||||
String.format(TranslationUtils.getTranslation().skinActionAffectedProfile,
|
||||
String.join(", ", profiles.stream().map(GameProfile::getName).toList()))), true);
|
||||
|
||||
if (!players.isEmpty()) {
|
||||
src.sendFeedback(() -> Text.of(
|
||||
src.sendSuccess(() -> Component.nullToEmpty(
|
||||
String.format(TranslationUtils.getTranslation().skinActionAffectedPlayer,
|
||||
String.join(", ", players.stream().map(p -> p.getGameProfile().getName()).toList()))), true);
|
||||
}
|
||||
} else {
|
||||
src.sendFeedback(() -> Text.of(TranslationUtils.getTranslation().skinActionOk), true);
|
||||
src.sendSuccess(() -> Component.nullToEmpty(TranslationUtils.getTranslation().skinActionOk), true);
|
||||
}
|
||||
});
|
||||
return targets.size();
|
||||
}
|
||||
|
||||
private static int skinAction(ServerCommandSource src, Supplier<SkinResult> skinSupplier) {
|
||||
private static int skinAction(CommandSourceStack src, Supplier<SkinResult> skinSupplier) {
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package net.lionarius.skinrestorer.mixin;
|
||||
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.skin.SkinResult;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.CommonListenerCookie;
|
||||
import net.minecraft.server.players.PlayerList;
|
||||
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.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(PlayerList.class)
|
||||
public abstract class PlayerListMixin {
|
||||
|
||||
@Shadow
|
||||
public abstract List<ServerPlayer> getPlayers();
|
||||
|
||||
@Shadow @Final
|
||||
private MinecraftServer server;
|
||||
|
||||
@Inject(method = "remove", at = @At("TAIL"))
|
||||
private void remove(ServerPlayer player, CallbackInfo ci) {
|
||||
SkinRestorer.getSkinStorage().removeSkin(player.getUUID());
|
||||
}
|
||||
|
||||
@Inject(method = "removeAll", at = @At("HEAD"))
|
||||
private void removeAll(CallbackInfo ci) {
|
||||
for (ServerPlayer player : getPlayers()) {
|
||||
SkinRestorer.getSkinStorage().removeSkin(player.getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "placeNewPlayer", at = @At("HEAD"))
|
||||
private void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie cookie, CallbackInfo ci) {
|
||||
SkinRestorer.setSkinAsync(server, Collections.singleton(player.getGameProfile()), () -> SkinResult.ofNullable(SkinRestorer.getSkinStorage().getSkin(player.getUUID())));
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package net.lionarius.skinrestorer.mixin;
|
||||
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.skin.SkinResult;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.network.ConnectedClientData;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
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.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(PlayerManager.class)
|
||||
public abstract class PlayerManagerMixin {
|
||||
|
||||
@Shadow
|
||||
public abstract List<ServerPlayerEntity> getPlayerList();
|
||||
|
||||
@Shadow @Final
|
||||
private MinecraftServer server;
|
||||
|
||||
@Inject(method = "remove", at = @At("TAIL"))
|
||||
private void remove(ServerPlayerEntity player, CallbackInfo ci) {
|
||||
SkinRestorer.getSkinStorage().removeSkin(player.getUuid());
|
||||
}
|
||||
|
||||
@Inject(method = "disconnectAllPlayers", at = @At("HEAD"))
|
||||
private void disconnectAllPlayers(CallbackInfo ci) {
|
||||
for (ServerPlayerEntity player : getPlayerList()) {
|
||||
SkinRestorer.getSkinStorage().removeSkin(player.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "onPlayerConnect", at = @At("HEAD"))
|
||||
private void onPlayerConnected(ClientConnection connection, ServerPlayerEntity player, ConnectedClientData clientData, CallbackInfo ci) {
|
||||
SkinRestorer.setSkinAsync(server, Collections.singleton(player.getGameProfile()), () -> SkinResult.ofNullable(SkinRestorer.getSkinStorage().getSkin(player.getUuid())));
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import com.mojang.authlib.GameProfile;
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.skin.SkinResult;
|
||||
import net.lionarius.skinrestorer.skin.SkinVariant;
|
||||
import net.minecraft.server.network.ServerLoginNetworkHandler;
|
||||
import net.minecraft.server.network.ServerLoginPacketListenerImpl;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -15,34 +15,34 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Mixin(ServerLoginNetworkHandler.class)
|
||||
public abstract class ServerLoginNetworkHandlerMixin {
|
||||
@Mixin(ServerLoginPacketListenerImpl.class)
|
||||
public abstract class ServerLoginPacketListenerImplMixin {
|
||||
|
||||
@Shadow @Nullable
|
||||
private GameProfile profile;
|
||||
private GameProfile authenticatedProfile;
|
||||
|
||||
@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;"),
|
||||
@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;"),
|
||||
cancellable = true)
|
||||
public void waitForSkin(CallbackInfo ci) {
|
||||
if (skinrestorer_pendingSkin == null) {
|
||||
skinrestorer_pendingSkin = CompletableFuture.supplyAsync(() -> {
|
||||
assert profile != null;
|
||||
SkinRestorer.LOGGER.debug("Fetching {}'s skin", profile.getName());
|
||||
assert authenticatedProfile != null;
|
||||
SkinRestorer.LOGGER.debug("Fetching {}'s skin", authenticatedProfile.getName());
|
||||
|
||||
if (!SkinRestorer.getSkinStorage().hasSavedSkin(profile.getId())) { // when player joins for the first time fetch Mojang skin by his username
|
||||
if (!SkinRestorer.getSkinStorage().hasSavedSkin(authenticatedProfile.getId())) { // when player joins for the first time fetch Mojang skin by his username
|
||||
SkinResult result = SkinRestorer.getProvider("mojang").map(
|
||||
provider -> provider.getSkin(profile.getName(), SkinVariant.CLASSIC)
|
||||
provider -> provider.getSkin(authenticatedProfile.getName(), SkinVariant.CLASSIC)
|
||||
).orElse(SkinResult.empty());
|
||||
|
||||
if (!result.isError())
|
||||
SkinRestorer.getSkinStorage().setSkin(profile.getId(), result.getSkin());
|
||||
SkinRestorer.getSkinStorage().setSkin(authenticatedProfile.getId(), result.getSkin());
|
||||
}
|
||||
|
||||
return SkinResult.ofNullable(SkinRestorer.getSkinStorage().getSkin(profile.getId()));
|
||||
return SkinResult.ofNullable(SkinRestorer.getSkinStorage().getSkin(authenticatedProfile.getId()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@ package net.lionarius.skinrestorer.util;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import net.minecraft.network.packet.s2c.play.*;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerChunkManager;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.players.PlayerList;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -18,47 +18,47 @@ public final class PlayerUtils {
|
||||
|
||||
private PlayerUtils() {}
|
||||
|
||||
public static boolean isFakePlayer(ServerPlayerEntity player) {
|
||||
return player.getClass() != ServerPlayerEntity.class; // if the player isn't a server player entity, it must be someone's fake player
|
||||
public static boolean isFakePlayer(ServerPlayer player) {
|
||||
return player.getClass() != ServerPlayer.class; // if the player isn't a server player entity, it must be someone's fake player
|
||||
}
|
||||
|
||||
public static void refreshPlayer(ServerPlayerEntity player) {
|
||||
ServerWorld serverWorld = player.getServerWorld();
|
||||
PlayerManager playerManager = serverWorld.getServer().getPlayerManager();
|
||||
ServerChunkManager chunkManager = serverWorld.getChunkManager();
|
||||
public static void refreshPlayer(ServerPlayer player) {
|
||||
ServerLevel serverLevel = player.serverLevel();
|
||||
PlayerList playerList = serverLevel.getServer().getPlayerList();
|
||||
ServerChunkCache chunkSource = serverLevel.getChunkSource();
|
||||
|
||||
playerManager.sendToAll(new BundleS2CPacket(
|
||||
playerList.broadcastAll(new ClientboundBundlePacket(
|
||||
List.of(
|
||||
new PlayerRemoveS2CPacket(List.of(player.getUuid())),
|
||||
PlayerListS2CPacket.entryFromPlayer(Collections.singleton(player))
|
||||
new ClientboundPlayerInfoRemovePacket(List.of(player.getUUID())),
|
||||
ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Collections.singleton(player))
|
||||
)
|
||||
));
|
||||
|
||||
if (!player.isDead()) {
|
||||
chunkManager.unloadEntity(player);
|
||||
chunkManager.loadEntity(player);
|
||||
player.networkHandler.send(new BundleS2CPacket(
|
||||
if (!player.isDeadOrDying()) {
|
||||
chunkSource.removeEntity(player);
|
||||
chunkSource.addEntity(player);
|
||||
player.connection.send(new ClientboundBundlePacket(
|
||||
List.of(
|
||||
new PlayerRespawnS2CPacket(player.createCommonPlayerSpawnInfo(serverWorld), PlayerRespawnS2CPacket.KEEP_ALL),
|
||||
new GameStateChangeS2CPacket(GameStateChangeS2CPacket.INITIAL_CHUNKS_COMING, 0)
|
||||
new ClientboundRespawnPacket(player.createCommonSpawnInfo(serverLevel), ClientboundRespawnPacket.KEEP_ALL_DATA),
|
||||
new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0)
|
||||
)
|
||||
), null);
|
||||
player.networkHandler.requestTeleport(player.getX(), player.getY(), player.getZ(), player.getYaw(), player.getPitch());
|
||||
player.networkHandler.send(new EntityVelocityUpdateS2CPacket(player), null);
|
||||
player.sendAbilitiesUpdate();
|
||||
player.addExperience(0);
|
||||
playerManager.sendCommandTree(player);
|
||||
playerManager.sendWorldInfo(player, serverWorld);
|
||||
playerManager.sendPlayerStatus(player);
|
||||
playerManager.sendStatusEffects(player);
|
||||
));
|
||||
player.connection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
|
||||
player.connection.send(new ClientboundSetEntityMotionPacket(player));
|
||||
player.onUpdateAbilities();
|
||||
player.giveExperiencePoints(0);
|
||||
playerList.sendPlayerPermissionLevel(player);
|
||||
playerList.sendLevelInfo(player, serverLevel);
|
||||
playerList.sendAllPlayerInfo(player);
|
||||
playerList.sendActivePlayerEffects(player);
|
||||
}
|
||||
}
|
||||
|
||||
public static Property getPlayerSkin(ServerPlayerEntity player) {
|
||||
public static Property getPlayerSkin(ServerPlayer player) {
|
||||
return player.getGameProfile().getProperties().get(TEXTURES_KEY).stream().findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public static void applyRestoredSkin(ServerPlayerEntity player, Property skin) {
|
||||
public static void applyRestoredSkin(ServerPlayer player, Property skin) {
|
||||
GameProfile profile = player.getGameProfile();
|
||||
profile.getProperties().removeAll(TEXTURES_KEY);
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"package": "net.lionarius.skinrestorer.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"PlayerManagerMixin",
|
||||
"ServerLoginNetworkHandlerMixin"
|
||||
"PlayerListMixin",
|
||||
"ServerLoginPacketListenerImplMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
||||
@@ -2,9 +2,9 @@ package net.lionarius.skinrestorer.fabric.mixin;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import net.lionarius.skinrestorer.command.SkinCommand;
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.commands.CommandBuildContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -12,15 +12,15 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(CommandManager.class)
|
||||
public abstract class CommandManagerMixin {
|
||||
@Mixin(Commands.class)
|
||||
public abstract class CommandsMixin {
|
||||
|
||||
@Final @Shadow
|
||||
private CommandDispatcher<ServerCommandSource> dispatcher;
|
||||
private CommandDispatcher<CommandSourceStack> dispatcher;
|
||||
|
||||
@Inject(method = "<init>", at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/command/AdvancementCommand;register(Lcom/mojang/brigadier/CommandDispatcher;)V"))
|
||||
private void init(CommandManager.RegistrationEnvironment environment, CommandRegistryAccess commandRegistryAccess, CallbackInfo ci) {
|
||||
target = "Lnet/minecraft/server/commands/AdvancementCommands;register(Lcom/mojang/brigadier/CommandDispatcher;)V"))
|
||||
private void init(Commands.CommandSelection environment, CommandBuildContext commandRegistryAccess, CallbackInfo ci) {
|
||||
SkinCommand.register(dispatcher);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
public abstract class MinecraftServerMixin {
|
||||
|
||||
@Inject(method = "runServer",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Util;getMeasuringTimeNano()J", ordinal = 0))
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;getNanos()J", ordinal = 0))
|
||||
private void onServerStarted(CallbackInfo ci) {
|
||||
SkinRestorer.onServerStarted((MinecraftServer) (Object) this);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"package": "net.lionarius.skinrestorer.fabric.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"CommandManagerMixin",
|
||||
"CommandsMixin",
|
||||
"MinecraftServerMixin"
|
||||
],
|
||||
"injectors": {
|
||||
|
||||
@@ -12,8 +12,9 @@ archives_name=skin-restorer
|
||||
capitalized_name=SkinRestorer
|
||||
|
||||
# Mappings
|
||||
yarn_mappings=1.21+build.4
|
||||
yarn_mappings_patch_neoforge_version=1.21+build.4
|
||||
#yarn_mappings=1.21+build.4
|
||||
#yarn_mappings_patch_neoforge_version=1.21+build.4
|
||||
parchment_mappings=2024.06.23
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/versions.html
|
||||
|
||||
Reference in New Issue
Block a user