Skip to content

Commit

Permalink
Fix #90 and #63
Browse files Browse the repository at this point in the history
  • Loading branch information
samolego committed Dec 2, 2024
1 parent 6a76f57 commit 5a9ad73
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 76 deletions.
14 changes: 5 additions & 9 deletions src/main/java/org/samo_lego/fabrictailor/FabricTailor.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.samo_lego.fabrictailor.command.FabrictailorCommand;
Expand All @@ -26,16 +28,11 @@

public class FabricTailor implements ModInitializer {

private static final Logger LOGGER = LogManager.getLogger();
public static final String MOD_ID = "fabrictailor";
public static TailorConfig config;
public static File configFile;
public static final ExecutorService THREADPOOL = Executors.newCachedThreadPool();

public static void errorLog(String error) {
LOGGER.error("[FabricTailor] An error occurred: {}", error);
}

@Override
public void onInitialize() {
CommandRegistrationCallback.EVENT.register((dispatcher, context, selection) -> {
Expand All @@ -54,9 +51,9 @@ public void onInitialize() {


ServerPlayConnectionEvents.INIT.register(NetworkHandler::onInit);

ServerConfigurationConnectionEvents.CONFIGURE.register(NetworkHandler::onConfigured);



PayloadTypeRegistry.configurationS2C().register(FabricTailorHelloPayload.TYPE, FabricTailorHelloPayload.CODEC);

PayloadTypeRegistry.playC2S().register(VanillaSkinPayload.TYPE, VanillaSkinPayload.CODEC);
Expand All @@ -70,8 +67,7 @@ public void onInitialize() {
}

public static void reloadConfig() {
// Ugly check if we are running server environment
TailorConfig newConfig = TailorConfig.loadConfigFile(configFile, new File("./server.properties").exists());
TailorConfig newConfig = TailorConfig.loadConfigFile(configFile, !Minecraft.getInstance().isLocalServer());
config.reload(newConfig);
}
}
47 changes: 27 additions & 20 deletions src/main/java/org/samo_lego/fabrictailor/command/SkinCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

public class SkinCommand {
private static final MutableComponent SKIN_SET_ERROR = TextTranslations.create("command.fabrictailor.skin.set.404").withStyle(ChatFormatting.RED);
private static final boolean TATERZENS_LOADED = FabricLoader.getInstance().isModLoaded("taterzens");
private static final MutableComponent SET_SKIN_ATTEMPT = TextTranslations.create("command.fabrictailor.skin.set.attempt");

public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
Expand All @@ -61,7 +60,7 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
ctx.getSource().sendFailure(
TextTranslations.create("command.fabrictailor.skin.set.404.url").withStyle(ChatFormatting.RED)
);
return 1;
return 0;
})
)
.then(literal("upload")
Expand All @@ -82,7 +81,7 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
ctx.getSource().sendFailure(
TextTranslations.create("command.fabrictailor.skin.set.404.path").withStyle(ChatFormatting.RED)
);
return 1;
return 0;
})
)
.then(literal("custom")
Expand All @@ -103,7 +102,7 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
ctx.getSource().sendFailure(
TextTranslations.create("command.fabrictailor.skin.set.404.playername").withStyle(ChatFormatting.RED)
);
return 1;
return 0;
})
)
.then(literal("player")
Expand All @@ -115,14 +114,14 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
ctx.getSource().sendFailure(
TextTranslations.create("command.fabrictailor.skin.set.404.playername").withStyle(ChatFormatting.RED)
);
return 1;
return 0;
})
)
.executes(ctx -> {
ctx.getSource().sendFailure(
TextTranslations.create("command.fabrictailor.skin.set.404").withStyle(ChatFormatting.RED)
);
return 1;
return 0;
})
)
.then(literal("clear")
Expand Down Expand Up @@ -155,17 +154,21 @@ private static int setSkinFile(CommandContext<CommandSourceStack> context, boole

// Warn about server path for uploads
MinecraftServer server = player.getServer();
if(server != null && server.isDedicatedServer()) {
player.displayClientMessage(
if (server != null && server.isDedicatedServer() && config.logging.skinChangeFeedback) {
player.displayClientMessage(
TextTranslations.create("hint.fabrictailor.server_skin_path").withStyle(ChatFormatting.GOLD),
false
);
}

setSkin(player, () -> setSkinFromFile(skinFilePath, useSlim));
player.displayClientMessage(TextTranslations.create("command.fabrictailor.skin.please_wait").withStyle(ChatFormatting.GOLD),
false
);

if (config.logging.skinChangeFeedback) {
player.displayClientMessage(TextTranslations.create("command.fabrictailor.skin.please_wait").withStyle(ChatFormatting.GOLD),
false
);
}

return 1;
}

Expand All @@ -189,18 +192,19 @@ public static void setSkin(ServerPlayer player, Supplier<Property> skinProvider)
long lastChange = ((TailoredPlayer) player).fabrictailor_getLastSkinChange();
long now = System.currentTimeMillis();

if(now - lastChange > config.skinChangeTimer * 1000 || lastChange == 0) {
if (now - lastChange > config.skinChangeTimer * 1000 || lastChange == 0) {
player.displayClientMessage(SET_SKIN_ATTEMPT.withStyle(ChatFormatting.AQUA), false);
THREADPOOL.submit(() -> {
Property skinData = skinProvider.get();

if (skinData == null) {
player.displayClientMessage(SKIN_SET_ERROR, false);
} else {
if (!TATERZENS_LOADED || !TaterzenSkins.setTaterzenSkin(player, skinData)) {
((TailoredPlayer) player).fabrictailor_setSkin(skinData, true);
((TailoredPlayer) player).fabrictailor_setSkin(skinData, true);

if (config.logging.skinChangeFeedback) {
player.displayClientMessage(TextTranslations.create("command.fabrictailor.skin.set.success").withStyle(ChatFormatting.GREEN), false);
}
player.displayClientMessage(TextTranslations.create("command.fabrictailor.skin.set.success").withStyle(ChatFormatting.GREEN), false);
}
});
} else {
Expand All @@ -221,12 +225,15 @@ public static boolean clearSkin(ServerPlayer player) {
long lastChange = ((TailoredPlayer) player).fabrictailor_getLastSkinChange();
long now = System.currentTimeMillis();

if(now - lastChange > config.skinChangeTimer * 1000 || lastChange == 0) {
if (now - lastChange > config.skinChangeTimer * 1000 || lastChange == 0) {
((TailoredPlayer) player).fabrictailor_clearSkin();
player.displayClientMessage(
TextTranslations.create("command.fabrictailor.skin.clear.success").withStyle(ChatFormatting.GREEN),
false
);
if (config.logging.skinChangeFeedback) {
player.displayClientMessage(
TextTranslations.create("command.fabrictailor.skin.clear.success").withStyle(ChatFormatting.GREEN),
false
);
}

return true;
}

Expand Down
21 changes: 19 additions & 2 deletions src/main/java/org/samo_lego/fabrictailor/config/TailorConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import jdk.jshell.execution.Util;
import org.samo_lego.config2brigadier.common.IBrigadierConfigurator;
import org.samo_lego.config2brigadier.common.annotation.BrigadierDescription;
import org.samo_lego.config2brigadier.common.annotation.BrigadierExcluded;
Expand All @@ -13,6 +14,7 @@
import java.util.Set;

import static org.samo_lego.fabrictailor.FabricTailor.*;
import static org.samo_lego.fabrictailor.util.Logging.error;

public class TailorConfig implements IBrigadierConfigurator {
private static final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().disableHtmlEscaping().create();
Expand All @@ -23,6 +25,21 @@ public class TailorConfig implements IBrigadierConfigurator {
@BrigadierDescription(defaultOption = "true")
@SerializedName("allow_capes")
public boolean allowCapes = true;

public Logging logging = new Logging();

public static class Logging {
@SerializedName("// Whether to send (successful) command feedback for skin changes. Errors are sent regardless.")
public final String _comment_skinChangeFeedback = "(default: true)";
@BrigadierDescription(defaultOption = "true")
@SerializedName("skin_change_feedback")
public boolean skinChangeFeedback = true;

@SerializedName("// Whether to send debug messages to console.")
public final String _comment_debug = "(default: false)";
@BrigadierDescription(defaultOption = "false")
public boolean debug = false;
}

@SerializedName("// Default skin for new players. Use command `/fabrictailor setDefaultSkin` to set those values.")
public final String _comment_defaultSkin = "";
Expand Down Expand Up @@ -68,7 +85,7 @@ public void save() {
try (Writer writer = new OutputStreamWriter(new FileOutputStream(configFile), StandardCharsets.UTF_8)) {
gson.toJson(this, writer);
} catch (IOException e) {
errorLog("Problem occurred when saving config: " + e.getMessage());
error("Problem occurred when saving config: " + e.getMessage());
}

}
Expand Down Expand Up @@ -99,7 +116,7 @@ public static TailorConfig loadConfigFile(File file, boolean serverEnvironment)
)) {
config = gson.fromJson(fileReader, TailorConfig.class);
} catch (IOException e) {
errorLog(MOD_ID + " Problem occurred when trying to load config: " + e.getMessage());
error(MOD_ID + " Problem occurred when trying to load config: " + e.getMessage());
}
}
if(config == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.samo_lego.fabrictailor.casts.TailoredPlayer;
import org.samo_lego.fabrictailor.mixin.accessors.AChunkMap;
import org.samo_lego.fabrictailor.mixin.accessors.ATrackedEntity;
import org.samo_lego.fabrictailor.util.Logging;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
Expand All @@ -49,7 +50,6 @@
import java.util.Optional;

import static org.samo_lego.fabrictailor.FabricTailor.config;
import static org.samo_lego.fabrictailor.FabricTailor.errorLog;
import static org.samo_lego.fabrictailor.mixin.accessors.APlayer.getPLAYER_MODEL_PARTS;

@Mixin(ServerPlayer.class)
Expand Down Expand Up @@ -94,9 +94,11 @@ public MServerPlayerEntity_TailoredPlayer(Level level, BlockPos blockPos, float
@Override
public void fabrictailor_reloadSkin() {
if (self.getServer() == null) {
errorLog("Tried to reload skin form client side! This should not happen!");
Logging.error("Tried to reload skin form client side! This should not happen!");
return;
}

Logging.debug("Reloading skin for player " + self.getName().getString());

// Refreshing in tablist for each player
PlayerList playerManager = self.getServer().getPlayerList();
Expand All @@ -106,11 +108,16 @@ public void fabrictailor_reloadSkin() {
ServerChunkCache manager = self.serverLevel().getChunkSource();
ChunkMap storage = manager.chunkMap;
ATrackedEntity trackerEntry = ((AChunkMap) storage).getEntityTrackers().get(self.getId());
if (config.logging.debug) {
Logging.debug("Trackers for the player: " + trackerEntry.getSeenBy().size());
trackerEntry.getSeenBy().forEach(tracking -> Logging.debug("Tracker for player: " + tracking.getPlayer().getName().getString()));
}

// Refreshing skin in world for all that see the player
trackerEntry.getSeenBy().forEach(tracking -> trackerEntry.getServerEntity().addPairing(tracking.getPlayer()));

// need to change the player entity on the client
Logging.debug("Reloading player skin on player's client.");
ServerLevel level = self.serverLevel();
this.connection.send(new ClientboundRespawnPacket(
new CommonPlayerSpawnInfo(
Expand Down Expand Up @@ -173,8 +180,11 @@ public void fabrictailor_reloadSkin() {
* @param skinData skin texture data
* @param reload whether to send packets around for skin reload
*/
@Override
public void fabrictailor_setSkin(Property skinData, boolean reload) {
Logging.debug("Setting skin for player " + self.getName().getString());
try {
Logging.debug("Clearing existing skin for player");
this.map.removeAll(TailoredPlayer.PROPERTY_TEXTURES);
} catch (Exception ignored) {
// Player has no skin data, no worries
Expand All @@ -195,7 +205,7 @@ public void fabrictailor_setSkin(Property skinData, boolean reload) {
this.lastSkinChangeTime = System.currentTimeMillis();
} catch (Error e) {
// Something went wrong when trying to set the skin
errorLog(e.getMessage());
Logging.error(e.getMessage());
}
}

Expand Down Expand Up @@ -284,10 +294,15 @@ public void fabrictailor_resetLastSkinChange() {
this.lastSkinChangeTime = 0;
}

/**
* Disables cape if needed by faking the player model customisation.
* @param clientSkinPrefs client skin preferences
* @param ci callback info
*/
@Inject(method = "updateOptions", at = @At("TAIL"))
private void disableCapeIfNeeded(ClientInformation clientInformation, CallbackInfo ci) {
private void disableCapeIfNeeded(ClientInformation clientSkinPrefs, CallbackInfo ci) {
if (!config.allowCapes) {
byte playerModel = (byte) clientInformation.modelCustomisation();
byte playerModel = (byte) clientSkinPrefs.modelCustomisation();

// Fake cape rule to be off
playerModel = (byte) (playerModel & ~(1));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.samo_lego.fabrictailor.mixin.client;

import com.google.common.net.InternetDomainName;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.authlib.yggdrasil.TextureUrlChecker;
import java.net.URI;
import static org.samo_lego.fabrictailor.FabricTailor.config;
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;
Expand All @@ -13,16 +15,16 @@
@Mixin(value = TextureUrlChecker.class, remap = false)
public final class MTextureUrlChecker_AllDomains {

@Unique
private static final String FILE_SCHEME_CONST = "file";

private MTextureUrlChecker_AllDomains() {
}

@Inject(method = "isAllowedTextureDomain",
at = @At(value = "INVOKE", target = "Ljava/net/URI;getScheme()Ljava/lang/String;"),
locals = LocalCapture.CAPTURE_FAILHARD,
cancellable = true)
private static void ft_allowAllTextureDomains(String url, CallbackInfoReturnable<Boolean> cir, URI uri) {
private static void ft_allowAllTextureDomains(String url, CallbackInfoReturnable<Boolean> cir, @Local URI uri) {
if (FILE_SCHEME_CONST.equals(uri.getScheme())) {
cir.setReturnValue(false); // todo, allow files
return;
Expand Down
Loading

0 comments on commit 5a9ad73

Please sign in to comment.