diff --git a/fabric/build.gradle b/fabric/build.gradle index 5b7d9bb1..04e71492 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -18,6 +18,7 @@ dependencies { mappings loom.officialMojangMappings() modImplementation "net.fabricmc:fabric-loader:${project.fabric_loader_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + modImplementation "com.google.code.findbugs:jsr305:3.0.2" } sourceSets { diff --git a/fabric/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java b/fabric/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java index 243275d8..bd6fc1ac 100644 --- a/fabric/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java +++ b/fabric/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java @@ -11,7 +11,6 @@ import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.PauseScreen; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.server.IntegratedServer; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.server.commands.BanIpCommands; @@ -20,8 +19,6 @@ import net.minecraft.server.commands.DeOpCommands; import net.minecraft.server.commands.OpCommand; import net.minecraft.server.commands.WhitelistCommand; -import net.minecraft.server.players.PlayerList; -import io.github.satxm.mcwifipnp.mixin.PlayerListAccessor; public class MCWiFiPnP implements ModInitializer { public static final String MODID = "mcwifipnp"; @@ -39,6 +36,7 @@ public void onInitialize() { BanIpCommands.register(dispatcher); BanListCommands.register(dispatcher); BanPlayerCommands.register(dispatcher); + OfflinePlayerCommand.register(dispatcher); }); } @@ -65,9 +63,4 @@ private void onServerStop(MinecraftServer server) { MCWiFiPnPUnit.CloseUPnPPort(server); } - public static void setMaxPlayers(IntegratedServer server, int num) { - PlayerList playerList = server.getPlayerList(); - ((PlayerListAccessor) playerList).setMaxPlayers(num); - } - } diff --git a/forge/build.gradle b/forge/build.gradle index 20acfd90..7078ef8f 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -2,6 +2,7 @@ plugins { id 'eclipse' id 'idea' id 'net.minecraftforge.gradle' version '[6.0.24,6.2)' + id 'org.spongepowered.mixin' version '0.7.+' } java.toolchain.languageVersion = JavaLanguageVersion.of(21) @@ -21,8 +22,6 @@ minecraft { copyIdeResources = true - accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') - runs { configureEach { @@ -48,7 +47,9 @@ minecraft { dependencies { minecraft "net.minecraftforge:forge:${project.minecraft_version}-${project.forge_version}" + annotationProcessor "org.spongepowered:mixin:0.8.5:processor" implementation('net.sf.jopt-simple:jopt-simple:5.0.4') { version { strictly '5.0.4' } } + implementation "com.google.code.findbugs:jsr305:3.0.2" } sourceSets { @@ -63,6 +64,15 @@ sourceSets { } } +mixin { + // MixinGradle Settings + add sourceSets.main, 'mcwifipnp.refmap.json' + config 'mcwifipnp.mixins.json' + + debug.verbose = true + debug.export = true +} + tasks.named('processResources', ProcessResources).configure { var replaceProperties = [ mod_version : project.mod_version, diff --git a/forge/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java b/forge/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java index f60ac52b..bca98dfa 100644 --- a/forge/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java +++ b/forge/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java @@ -9,7 +9,6 @@ import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.PauseScreen; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.server.IntegratedServer; import net.minecraft.network.chat.Component; import net.minecraft.server.commands.BanIpCommands; import net.minecraft.server.commands.BanListCommands; @@ -17,7 +16,6 @@ import net.minecraft.server.commands.DeOpCommands; import net.minecraft.server.commands.OpCommand; import net.minecraft.server.commands.WhitelistCommand; -import net.minecraft.server.players.PlayerList; import net.minecraftforge.client.event.ScreenEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegisterCommandsEvent; @@ -57,11 +55,6 @@ public void onServerStopping(ServerStoppingEvent event) { MCWiFiPnPUnit.CloseUPnPPort(event.getServer()); } - public static void setMaxPlayers(IntegratedServer server, int num) { - PlayerList playerList = server.getPlayerList(); - playerList.maxPlayers = num; - } - public static void onAfterInitScreen(Minecraft client, Screen screen, List children, Consumer add, Consumer remove) { if (screen instanceof PauseScreen pauseScreen && screen.getClass() == PauseScreen.class) { diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 67c20ecf..4a515ab9 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -21,10 +21,6 @@ repositories { } minecraft { - accessTransformers { - file('src/main/resources/META-INF/accesstransformer.cfg') - } - runs { configureEach { workingDirectory project.file('run') @@ -43,6 +39,7 @@ minecraft { dependencies { implementation "net.neoforged:neoforge:${project.neo_version}" + implementation "com.google.code.findbugs:jsr305:3.0.2" } sourceSets { diff --git a/neoforge/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java b/neoforge/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java index 4038bc8e..4a918035 100644 --- a/neoforge/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java +++ b/neoforge/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java @@ -9,7 +9,6 @@ import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.PauseScreen; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.server.IntegratedServer; import net.minecraft.network.chat.Component; import net.minecraft.server.commands.BanIpCommands; import net.minecraft.server.commands.BanListCommands; @@ -17,7 +16,6 @@ import net.minecraft.server.commands.DeOpCommands; import net.minecraft.server.commands.OpCommand; import net.minecraft.server.commands.WhitelistCommand; -import net.minecraft.server.players.PlayerList; import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.Mod; @@ -59,11 +57,6 @@ public void onServerStopping(ServerStoppingEvent event) { MCWiFiPnPUnit.CloseUPnPPort(event.getServer()); } - public static void setMaxPlayers(IntegratedServer server, int num) { - PlayerList playerList = server.getPlayerList(); - playerList.maxPlayers = num; - } - public static void onAfterInitScreen(Minecraft client, Screen screen, List children, Consumer add, Consumer remove) { if (screen instanceof PauseScreen pauseScreen && screen.getClass() == PauseScreen.class) { diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 7ef4d80e..b7484746 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -13,11 +13,11 @@ logoFile="mcwifipnp.png" authors="Satxm" description="A Minecraft LAN World Tool With WLAN UPnP." -#[[mixins]] -#config="mcwifipnp.mixins.json" +[[mixins]] +config="mcwifipnp.mixins.json" -[[accessTransformers]] -file="META-INF/accesstransformer.cfg" +#[[accessTransformers]] +#file="META-INF/accesstransformer.cfg" [[dependencies.mcwifipnp]] modId="neoforge" diff --git a/quilt/build.gradle b/quilt/build.gradle index 1565a695..164864b9 100644 --- a/quilt/build.gradle +++ b/quilt/build.gradle @@ -27,10 +27,9 @@ dependencies { officialMojangMappings() } modImplementation "org.quiltmc:quilt-loader:${project.quilt_loader_version}" - modImplementation "org.quiltmc:qsl:${project.qsl_version}" - modImplementation "org.quiltmc.quilted-fabric-api:quilted-fabric-api:${qfapi_version}" + modImplementation "com.google.code.findbugs:jsr305:3.0.2" } sourceSets { diff --git a/quilt/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java b/quilt/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java index 2eca882c..c2275f2d 100644 --- a/quilt/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java +++ b/quilt/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnP.java @@ -12,7 +12,6 @@ import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.PauseScreen; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.server.IntegratedServer; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.server.commands.BanIpCommands; @@ -21,8 +20,6 @@ import net.minecraft.server.commands.DeOpCommands; import net.minecraft.server.commands.OpCommand; import net.minecraft.server.commands.WhitelistCommand; -import net.minecraft.server.players.PlayerList; -import io.github.satxm.mcwifipnp.mixin.PlayerListAccessor; public class MCWiFiPnP implements ModInitializer { public static final String MODID = "mcwifipnp"; @@ -66,9 +63,4 @@ private void onServerStop(MinecraftServer server) { MCWiFiPnPUnit.CloseUPnPPort(server); } - public static void setMaxPlayers(IntegratedServer server, int num) { - PlayerList playerList = server.getPlayerList(); - ((PlayerListAccessor) playerList).setMaxPlayers(num); - } - } diff --git a/quilt/src/main/java/io/github/satxm/mcwifipnp/mixin/PlayerListAccessor.java b/quilt/src/main/java/io/github/satxm/mcwifipnp/mixin/PlayerListAccessor.java deleted file mode 100644 index ac6bd420..00000000 --- a/quilt/src/main/java/io/github/satxm/mcwifipnp/mixin/PlayerListAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.satxm.mcwifipnp.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.server.players.PlayerList; - -@Mixin(PlayerList.class) -public interface PlayerListAccessor { - @Accessor - @Mutable - public void setMaxPlayers(int maxPlayers); -} \ No newline at end of file diff --git a/quilt/src/main/resources/mcwifipnp.mixins.json b/quilt/src/main/resources/mcwifipnp.mixins.json deleted file mode 100644 index e9af5cdb..00000000 --- a/quilt/src/main/resources/mcwifipnp.mixins.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "io.github.satxm.mcwifipnp.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "PlayerListAccessor" - ], - "injectors": { - "defaultRequire": 1 - } -} \ No newline at end of file diff --git a/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnPUnit.java b/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnPUnit.java index ef3a07b9..3eaa9c5d 100644 --- a/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnPUnit.java +++ b/src/main/java/io/github/satxm/mcwifipnp/MCWiFiPnPUnit.java @@ -12,14 +12,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.WeakHashMap; +import java.util.*; +import io.github.satxm.mcwifipnp.mixin.PlayerListAccessor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -54,7 +49,6 @@ public class MCWiFiPnPUnit { public static Config getConfig(MinecraftServer server) { return Objects.requireNonNull(configMap.get(server), "no config for server???"); } - public static void OpenToLan() { Minecraft client = Minecraft.getInstance(); @@ -67,13 +61,15 @@ public static void OpenToLan() { ? PublishCommand.getSuccessMessage(cfg.port) : Component.translatable("commands.publish.failed"); client.gui.getChat().addMessage(component); - MCWiFiPnP.setMaxPlayers(server,cfg.maxPlayers); + ((PlayerListAccessor) playerList).setMaxPlayers(cfg.maxPlayers); server.setUsesAuthentication(cfg.OnlineMode); server.setPvpAllowed(cfg.PvP); server.setEnforceWhitelist(cfg.Whitelist); playerList.setUsingWhiteList(cfg.Whitelist); playerList.getOps().add(new ServerOpListEntry(server.getSingleplayerProfile(), 4, playerList.canBypassPlayerLimit(server.getSingleplayerProfile()))); playerList.setAllowCommandsForAllPlayers(cfg.AllPlayersCheats); + UUIDFixer.EnableUUIDFix = cfg.EnableUUIDFix; + UUIDFixer.alwaysOfflinePlayers = cfg.alwaysOfflinePlayers; new Thread(() -> { MCWiFiPnPUnit.UseUPnP(cfg, client); @@ -196,6 +192,8 @@ public static class Config { public boolean UseUPnP = true; public boolean AllowCommands = false; public boolean OnlineMode = true; + public boolean EnableUUIDFix = false; + public List alwaysOfflinePlayers = Collections.emptyList(); public boolean PvP = true; public boolean CopyToClipboard = true; public transient Path location; diff --git a/src/main/java/io/github/satxm/mcwifipnp/OfflinePlayerCommand.java b/src/main/java/io/github/satxm/mcwifipnp/OfflinePlayerCommand.java new file mode 100644 index 00000000..113785c9 --- /dev/null +++ b/src/main/java/io/github/satxm/mcwifipnp/OfflinePlayerCommand.java @@ -0,0 +1,135 @@ +package io.github.satxm.mcwifipnp; + +import com.mojang.authlib.GameProfile; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.commands.arguments.GameProfileArgument; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.players.PlayerList; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.Component; +import org.apache.commons.lang3.StringUtils; + + +public class OfflinePlayerCommand { + private static final SimpleCommandExceptionType ERROR_ALREADY_IN = new SimpleCommandExceptionType(Component.translatable("commands.whitelist.add.failed")); + private static final SimpleCommandExceptionType ERROR_NOT_IN = new SimpleCommandExceptionType(Component.translatable("commands.whitelist.remove.failed")); + + public OfflinePlayerCommand() { + } + + public static void register(CommandDispatcher commandDispatcher) { + commandDispatcher.register((LiteralArgumentBuilder)((LiteralArgumentBuilder)((LiteralArgumentBuilder)((LiteralArgumentBuilder) Commands.literal("offlineplayer").requires((commandSourceStack) -> { + return commandSourceStack.hasPermission(3); + })).then(Commands.literal("list").executes((commandContext) -> { + return showList((CommandSourceStack)commandContext.getSource()); + }))).then(Commands.literal("add").then(Commands.argument("targets", GameProfileArgument.gameProfile()).suggests((commandContext, suggestionsBuilder) -> { + MinecraftServer server = ((CommandSourceStack)commandContext.getSource()).getServer(); + PlayerList playerList = server.getPlayerList(); + MCWiFiPnPUnit.ReadingConfig(server); + MCWiFiPnPUnit.Config cfg = MCWiFiPnPUnit.getConfig(server); + List alwaysOfflinePlayers = cfg.alwaysOfflinePlayers; + return SharedSuggestionProvider.suggest(playerList.getPlayers().stream().filter((serverPlayer) -> { + return !alwaysOfflinePlayers.contains(serverPlayer.getGameProfile().getName()); + }).map((serverPlayer) -> { + return serverPlayer.getGameProfile().getName(); + }), suggestionsBuilder); + }).executes((commandContext) -> { + return addPlayers((CommandSourceStack)commandContext.getSource(), GameProfileArgument.getGameProfiles(commandContext, "targets")); + })))).then(Commands.literal("remove").then(Commands.argument("targets", GameProfileArgument.gameProfile()).suggests((commandContext, suggestionsBuilder) -> { + MinecraftServer server = ((CommandSourceStack)commandContext.getSource()).getServer(); + PlayerList playerList = server.getPlayerList(); + MCWiFiPnPUnit.ReadingConfig(server); + MCWiFiPnPUnit.Config cfg = MCWiFiPnPUnit.getConfig(server); + List alwaysOfflinePlayers = cfg.alwaysOfflinePlayers; + return SharedSuggestionProvider.suggest(alwaysOfflinePlayers.stream(), suggestionsBuilder); + }).executes((commandContext) -> { + return removePlayers((CommandSourceStack)commandContext.getSource(), GameProfileArgument.getGameProfiles(commandContext, "targets")); + })))); + } + + private static int addPlayers(CommandSourceStack commandSourceStack, Collection collection) throws CommandSyntaxException { + + MinecraftServer server = commandSourceStack.getServer(); + MCWiFiPnPUnit.ReadingConfig(server); + MCWiFiPnPUnit.Config cfg = MCWiFiPnPUnit.getConfig(server); + List alwaysOfflinePlayers = cfg.alwaysOfflinePlayers; + int i = 0; + Iterator var4 = collection.iterator(); + + while(var4.hasNext()) { + GameProfile gameProfile = (GameProfile)var4.next(); + if (!alwaysOfflinePlayers.contains(gameProfile.getName())) { + alwaysOfflinePlayers.add(gameProfile.getName()); + MCWiFiPnPUnit.saveConfig(cfg); + commandSourceStack.sendSuccess(() -> { + return Component.translatable("commands.whitelist.add.success", new Object[]{Component.literal(gameProfile.getName())}); + }, true); + ++i; + } + } + + if (i == 0) { + throw ERROR_ALREADY_IN.create(); + } else { + return i; + } + } + + private static int removePlayers(CommandSourceStack commandSourceStack, Collection collection) throws CommandSyntaxException { + MinecraftServer server = commandSourceStack.getServer(); + MCWiFiPnPUnit.ReadingConfig(server); + MCWiFiPnPUnit.Config cfg = MCWiFiPnPUnit.getConfig(server); + List alwaysOfflinePlayers = cfg.alwaysOfflinePlayers; + + int i = 0; + Iterator var4 = collection.iterator(); + + while(var4.hasNext()) { + GameProfile gameProfile = (GameProfile)var4.next(); + if (alwaysOfflinePlayers.contains(gameProfile.getName())) { + alwaysOfflinePlayers.remove(gameProfile.getName()); + MCWiFiPnPUnit.saveConfig(cfg); + commandSourceStack.sendSuccess(() -> { + return Component.translatable("commands.whitelist.remove.success", new Object[]{Component.literal(gameProfile.getName())}); + }, true); + ++i; + } + } + + if (i == 0) { + throw ERROR_NOT_IN.create(); + } else { + commandSourceStack.getServer().kickUnlistedPlayers(commandSourceStack); + return i; + } + } + + private static int showList(CommandSourceStack commandSourceStack) { + MinecraftServer server = commandSourceStack.getServer(); + MCWiFiPnPUnit.ReadingConfig(server); + MCWiFiPnPUnit.Config cfg = MCWiFiPnPUnit.getConfig(server); + List alwaysOfflinePlayers = cfg.alwaysOfflinePlayers; + + if (alwaysOfflinePlayers.size() == 0) { + commandSourceStack.sendSuccess(() -> { + return Component.translatable("commands.whitelist.none"); + }, false); + } else { + commandSourceStack.sendSuccess(() -> { + return Component.translatable("commands.whitelist.list", new Object[]{alwaysOfflinePlayers.size(), StringUtils.join(alwaysOfflinePlayers,", ")}); + }, false); + } + + return alwaysOfflinePlayers.size(); + } +} diff --git a/src/main/java/io/github/satxm/mcwifipnp/OnlineMode.java b/src/main/java/io/github/satxm/mcwifipnp/OnlineMode.java new file mode 100644 index 00000000..abaf15c1 --- /dev/null +++ b/src/main/java/io/github/satxm/mcwifipnp/OnlineMode.java @@ -0,0 +1,51 @@ +package io.github.satxm.mcwifipnp; + +import net.minecraft.network.chat.Component; +import net.minecraft.util.ByIdMap; +import net.minecraft.util.StringRepresentable; + +import java.util.function.IntFunction; + +public enum OnlineMode { + ONLINE(true, false,"online"), + OFFLINE(false, false,"offline"), + FIXUUID(false, true,"fixuuid"); + + private final boolean onlinemode, fixuuid; + private final String name; + private final Component displayName, toolTip; + + OnlineMode(boolean onlinemode, boolean fixuuid, final String string) { + this.onlinemode = onlinemode; + this.fixuuid = fixuuid; + this.name = string; + this.displayName = Component.translatable("mcwifipnp.gui.OnlineMode." + string); + this.toolTip = Component.translatable("mcwifipnp.gui.OnlineMode." + string +".info"); + } + + public Component getDisplayName() { + return this.displayName; + } + + public Component gettoolTip() { + return this.toolTip; + } + + public static OnlineMode of(boolean onlinemode, boolean fixuuid) { + if (onlinemode) { + return ONLINE; + } else { + return fixuuid ? FIXUUID : OFFLINE; + } + } + + public boolean getOnlieMode() { + return this.onlinemode; + } + + public boolean getFixUUID() { + return this.fixuuid; + } + + +} diff --git a/src/main/java/io/github/satxm/mcwifipnp/ShareToLanScreenNew.java b/src/main/java/io/github/satxm/mcwifipnp/ShareToLanScreenNew.java index faa14c55..a01eeef8 100644 --- a/src/main/java/io/github/satxm/mcwifipnp/ShareToLanScreenNew.java +++ b/src/main/java/io/github/satxm/mcwifipnp/ShareToLanScreenNew.java @@ -3,22 +3,21 @@ import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.CycleButton; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.components.*; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.util.HttpUtil; import net.minecraft.world.level.GameType; +import java.util.Collections; public class ShareToLanScreenNew extends Screen { private final MCWiFiPnPUnit.Config cfg; private EditBox EditPort; private EditBox EditMotd; private EditBox EditPlayers; + private EditBox EditOfflinePlayers; private final Screen lastScreen; public ShareToLanScreenNew(Screen screen) { @@ -35,6 +34,7 @@ public ShareToLanScreenNew(Screen screen) { cfg.AllowCommands = client.getSingleplayerServer().getWorldData().isAllowCommands(); cfg.GameMode = client.getSingleplayerServer().getDefaultGameType().getName(); cfg.OnlineMode = client.getSingleplayerServer().usesAuthentication(); + cfg.alwaysOfflinePlayers = Collections.emptyList(); cfg.needsDefaults = false; } } @@ -57,7 +57,7 @@ protected void init() { this.addRenderableWidget(StartLanServer); this.addRenderableWidget( - Button.builder(CommonComponents.GUI_CANCEL, button -> this.minecraft.setScreen(this.lastScreen)) + Button.builder(CommonComponents.GUI_CANCEL, button -> this.onClose()) .bounds(this.width / 2 + 5, this.height - 32, 150, 20).build()); this.addRenderableWidget(CycleButton.builder(GameType::getShortDisplayName) @@ -165,10 +165,14 @@ protected void init() { cfg.Whitelist = Whitelist; })).setTooltip(Tooltip.create(Component.translatable("mcwifipnp.gui.Whitelist.info"))); - this.addRenderableWidget(CycleButton.onOffBuilder(cfg.OnlineMode).create(this.width / 2 - 155, 148, 150, 20, - Component.translatable("mcwifipnp.gui.OnlineMode"), (cycleButton, OnlineMode) -> { - cfg.OnlineMode = OnlineMode; - })).setTooltip(Tooltip.create(Component.translatable("mcwifipnp.gui.OnlineMode.info"))); + this.addRenderableWidget(CycleButton.builder(OnlineMode::getDisplayName) + .withValues(OnlineMode.values()) + .withInitialValue(OnlineMode.of(cfg.OnlineMode, cfg.EnableUUIDFix)).withTooltip((OnlineMode) -> Tooltip.create(OnlineMode.gettoolTip())) + .create(this.width / 2 - 155, 148, 150, 20, + Component.translatable("mcwifipnp.gui.OnlineMode"), (cycleButton, OnlineMode) -> { + cfg.OnlineMode = OnlineMode.getOnlieMode(); + cfg.EnableUUIDFix = OnlineMode.getFixUUID(); + })); this.addRenderableWidget(CycleButton.onOffBuilder(cfg.PvP).create(this.width / 2 + 5, 148, 150, 20, Component.translatable("mcwifipnp.gui.PvP"), (cycleButton, PvP) -> { @@ -186,6 +190,10 @@ protected void init() { })).setTooltip(Tooltip.create(Component.translatable("mcwifipnp.gui.CopyIP.info"))); } + public void onClose() { + this.minecraft.setScreen(this.lastScreen); + } + public void render(GuiGraphics guiGraphics, int i, int j, float f) { super.render(guiGraphics, i, j, f); guiGraphics.drawCenteredString(this.font, this.title, this.width / 2, 16, 16777215); @@ -197,8 +205,6 @@ public void render(GuiGraphics guiGraphics, int i, int j, float f) { 16777215); guiGraphics.drawCenteredString(this.font, Component.translatable("lanServer.otherPlayers"), this.width / 2, 104, 16777215); - EditPort.render(guiGraphics, i, j, f); - EditPlayers.render(guiGraphics, i, j, f); - EditMotd.render(guiGraphics, i, j, f); + } } diff --git a/src/main/java/io/github/satxm/mcwifipnp/UUIDFixer.java b/src/main/java/io/github/satxm/mcwifipnp/UUIDFixer.java new file mode 100644 index 00000000..ce69baf7 --- /dev/null +++ b/src/main/java/io/github/satxm/mcwifipnp/UUIDFixer.java @@ -0,0 +1,69 @@ +package io.github.satxm.mcwifipnp; + +import java.io.IOException; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import javax.annotation.Nullable; + +import org.apache.commons.io.IOUtils; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class UUIDFixer { + public static boolean EnableUUIDFix = false; + public static List alwaysOfflinePlayers = Collections.emptyList(); + private static final Logger LOGGER = LogManager.getLogger(MCWiFiPnP.class); + + + /** + * Mixin/ Coremod callback + */ + public static UUID hookEntry(String playerName) { + if (alwaysOfflinePlayers.contains(playerName)) + return null; + + if (EnableUUIDFix) + return getOfficialUUID(playerName); + + return null; + } + + @Nullable + public static UUID getOfficialUUID(String playerName) { + LOGGER.info(playerName); + String url = "https://api.mojang.com/users/profiles/minecraft/" + playerName; + try { + String UUIDJson = IOUtils.toString(new URL(url), Charset.defaultCharset()); + if (!UUIDJson.isEmpty()) { + JsonObject root = JsonParser.parseString(UUIDJson).getAsJsonObject(); + String playerName2 = root.getAsJsonPrimitive("name").getAsString(); + String uuidString = root.getAsJsonPrimitive("id").getAsString(); + // com.mojang.util.UUIDTypeAdapter.fromString(String) + long uuidMSB = Long.parseLong(uuidString.substring(0, 8), 16); + uuidMSB <<= 32; + uuidMSB |= Long.parseLong(uuidString.substring(8, 16), 16); + long uuidLSB = Long.parseLong(uuidString.substring(16, 24), 16); + uuidLSB <<= 32; + uuidLSB |= Long.parseLong(uuidString.substring(24, 32), 16); + UUID uuid = new UUID(uuidMSB, uuidLSB); + + LOGGER.info(playerName + " UUID: "+uuid); + + if (playerName2.equalsIgnoreCase(playerName)) + return uuid; + } + } catch (IOException | JsonSyntaxException e) { + e.printStackTrace(); + } + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/io/github/satxm/mcwifipnp/mixin/MixinUUIDUtil.java b/src/main/java/io/github/satxm/mcwifipnp/mixin/MixinUUIDUtil.java new file mode 100644 index 00000000..5ff0afbc --- /dev/null +++ b/src/main/java/io/github/satxm/mcwifipnp/mixin/MixinUUIDUtil.java @@ -0,0 +1,22 @@ +package io.github.satxm.mcwifipnp.mixin; + +import java.util.UUID; +import io.github.satxm.mcwifipnp.UUIDFixer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import net.minecraft.core.UUIDUtil; + + +@Mixin(UUIDUtil.class) +public abstract class MixinUUIDUtil { + @Inject(method = "createOfflinePlayerUUID", at = @At("HEAD"), cancellable = true) + private static void detour_createOfflinePlayerUUID(String playerName, CallbackInfoReturnable ci) { + UUID uuid = UUIDFixer.hookEntry(playerName); + if (uuid != null) { + ci.setReturnValue(uuid); + ci.cancel(); + } + } +} \ No newline at end of file diff --git a/fabric/src/main/java/io/github/satxm/mcwifipnp/mixin/PlayerListAccessor.java b/src/main/java/io/github/satxm/mcwifipnp/mixin/PlayerListAccessor.java similarity index 100% rename from fabric/src/main/java/io/github/satxm/mcwifipnp/mixin/PlayerListAccessor.java rename to src/main/java/io/github/satxm/mcwifipnp/mixin/PlayerListAccessor.java diff --git a/src/main/resources/assets/mcwifipnp/lang/en_us.json b/src/main/resources/assets/mcwifipnp/lang/en_us.json index 82fcbdaf..5b975929 100644 --- a/src/main/resources/assets/mcwifipnp/lang/en_us.json +++ b/src/main/resources/assets/mcwifipnp/lang/en_us.json @@ -12,20 +12,32 @@ "mcwifipnp.gui.Whitelist":"Whitelist", "mcwifipnp.gui.Whitelist.info":"Enforce whitelist. When enabled, only whitelisted players can connect to the server. Use /whitelist to add players to the list.", "mcwifipnp.gui.OnlineMode": "Online Mode", - "mcwifipnp.gui.OnlineMode.info": "Connects to the Minecraft account database to verify logins. Disable to allow offline accounts to join.", - "mcwifipnp.gui.PvP":"PvP", + "mcwifipnp.gui.OnlineMode.info": "Whether to let the server compare and verify the login information against the Mojang server database.", + "mcwifipnp.gui.OnlineMode.online": "Enable", + "mcwifipnp.gui.OnlineMode.online.info": "Enabe Online Mode will only allow players who login with a Microsoft account to join this server.", + "mcwifipnp.gui.OnlineMode.offline": "Disable", + "mcwifipnp.gui.OnlineMode.offline.info": "Disabe Online Mode will allow players who login in offline mode to join this server.", + "mcwifipnp.gui.OnlineMode.fixuuid": "Disable + UUID Fixer", + "mcwifipnp.gui.OnlineMode.fixuuid.info": "Attempt to match the Mojang server user name with the player name for offline mode players to obtain a unique UUID. \nMeanwhile, UUIDs are retained for users logging in with Microsoft accounts.\nIt can also prevent the loss of backpack and inventory items.", + "mcwifipnp.gui.PvP": "PvP", "mcwifipnp.gui.PvP.info":"Toggles PvP. Disabling PvP will also prevent you from taking damage from your own projectiles.", "mcwifipnp.gui.UseUPnP": "Forward Port", "mcwifipnp.gui.UseUPnP.info": "Whether to use the UPnP function to map the LAN game port number.", "mcwifipnp.gui.Local": "Local", "mcwifipnp.gui.Global": "Global", "mcwifipnp.gui.CopyIP": "Get IP", - "mcwifipnp.gui.CopyToClipboard": "Get IP to copying to clipboard", + "mcwifipnp.gui.CopyIP.info": "Get IP to copying to clipboard", "mcwifipnp.upnp.success": "Successfully forwarded port %s", "mcwifipnp.upnp.clipboard": "Successfully got %s, Due to factors such as NAT, these IPs may still not be able to connect directly.", "mcwifipnp.upnp.cantgetip": "Couldn't get public IP! Please check your network settings. Your IPv4 may contain multiple NATs or you do not have IPv6.", "mcwifipnp.upnp.failed.mapped": "Unable to forward port %s: Port was already mapped by another UPnP service, Please change the port number.", "mcwifipnp.upnp.failed.disabled": "Unable to forward port %s: UPnP is not enabled on your router, You may need to use port mapping software.", "mcwifipnp.upnp.failed.unknownerror": "Unable to forward port %s: Unknown error while adding port mapping, Please use a port mapping software.", - "mcwifipnp.upnp.failed": "Unable to forward port %s!" + "mcwifipnp.upnp.failed": "Unable to forward port %s!", + "mcwifipnp.commands.offlineplayers.add.failed": "Player is already in force offline list", + "mcwifipnp.commands.offlineplayers.add.success": "Added %s to the force offline list", + "mcwifipnp.commands.offlineplayers.list": "There are %s players in force offline list: %s", + "mcwifipnp.commands.offlineplayers.none": "There are no players in force offline list", + "mcwifipnp.commands.offlineplayers.remove.failed": "Player is not in force offline list", + "mcwifipnp.commands.offlineplayers.remove.success": "Removed %s from the force offline list" } diff --git a/src/main/resources/assets/mcwifipnp/lang/es_es.json b/src/main/resources/assets/mcwifipnp/lang/es_es.json index c3f29f9b..65f5e43a 100644 --- a/src/main/resources/assets/mcwifipnp/lang/es_es.json +++ b/src/main/resources/assets/mcwifipnp/lang/es_es.json @@ -13,6 +13,12 @@ "mcwifipnp.gui.Whitelist.info": "Habilita la lista blanca. Cuando está activada, solo los jugadores en la lista blanca pueden conectarse al servidor. Usa /whitelist para agregar jugadores a la lista.", "mcwifipnp.gui.OnlineMode": "Modo en Línea", "mcwifipnp.gui.OnlineMode.info": "Conecta a la base de datos de cuentas de Minecraft para verificar los inicios de sesión. Desactívalo para permitir que las cuentas sin conexión se unan.", + "mcwifipnp.gui.OnlineMode.online": "Enable", + "mcwifipnp.gui.OnlineMode.online.info": "Enabe Online Mode will only allow players who login with a Microsoft account to join this server.", + "mcwifipnp.gui.OnlineMode.offline": "Disable", + "mcwifipnp.gui.OnlineMode.offline.info": "Disabe Online Mode will allow players who login in offline mode to join this server.", + "mcwifipnp.gui.OnlineMode.fixuuid": "Disable + UUID Fixer", + "mcwifipnp.gui.OnlineMode.fixuuid.info": "Attempt to match the Mojang server user name with the player name for offline mode players to obtain a unique UUID. \nMeanwhile, UUIDs are retained for users logging in with Microsoft accounts.\nIt can also prevent the loss of backpack and inventory items.", "mcwifipnp.gui.PvP": "PvP", "mcwifipnp.gui.PvP.info": "Activa o desactiva el PvP. Deshabilitar el PvP también evitará que recibas daño de tus propios proyectiles.", "mcwifipnp.gui.UseUPnP": "Reenviar Puerto", @@ -20,12 +26,18 @@ "mcwifipnp.gui.Local": "Local", "mcwifipnp.gui.Global": "Global", "mcwifipnp.gui.CopyIP": "Obtener IP", - "mcwifipnp.gui.CopyToClipboard": "Obtener IP y copiar al portapapeles", + "mcwifipnp.gui.CopyIP.info": "Obtener IP y copiar al portapapeles", "mcwifipnp.upnp.success": "Puerto %s reenviado con éxito", "mcwifipnp.upnp.clipboard": "Obtención exitosa de %s. Debido a factores como NAT, es posible que estas IP no puedan conectarse directamente.", "mcwifipnp.upnp.cantgetip": "¡No se pudo obtener la IP pública! Verifica la configuración de tu red. Tu IPv4 puede contener múltiples NAT o no tener IPv6.", "mcwifipnp.upnp.failed.mapped": "No se pudo reenviar el puerto %s: El puerto ya estaba asignado por otro servicio UPnP. Cambia el número de puerto.", "mcwifipnp.upnp.failed.disabled": "No se pudo reenviar el puerto %s: UPnP no está habilitado en tu enrutador. Puede que necesites usar software de asignación de puertos.", "mcwifipnp.upnp.failed.unknownerror": "No se pudo reenviar el puerto %s: Error desconocido al agregar la asignación de puertos. Usa un software de asignación de puertos.", - "mcwifipnp.upnp.failed": "No se pudo reenviar el puerto %s." + "mcwifipnp.upnp.failed": "No se pudo reenviar el puerto %s.", + "mcwifipnp.commands.offlineplayers.add.failed": "Player is already in force offline list", + "mcwifipnp.commands.offlineplayers.add.success": "Added %s to the force offline list", + "mcwifipnp.commands.offlineplayers.list": "There are %s players in force offline list: %s", + "mcwifipnp.commands.offlineplayers.none": "There are no players in force offline list", + "mcwifipnp.commands.offlineplayers.remove.failed": "Player is not in force offline list", + "mcwifipnp.commands.offlineplayers.remove.success": "Removed %s from the force offline list" } diff --git a/src/main/resources/assets/mcwifipnp/lang/ru_ru.json b/src/main/resources/assets/mcwifipnp/lang/ru_ru.json index ee790687..a5c822fd 100644 --- a/src/main/resources/assets/mcwifipnp/lang/ru_ru.json +++ b/src/main/resources/assets/mcwifipnp/lang/ru_ru.json @@ -13,6 +13,12 @@ "mcwifipnp.gui.Whitelist.info": "Принудительное включение белого списка. Если эта функция включена, только игроки, внесённые в этот список, смогут подключаться к серверу. Используйте /whitelist для добавления игроков в список.", "mcwifipnp.gui.OnlineMode": "Проверка лицензии", "mcwifipnp.gui.OnlineMode.info": "Подключается к базе данных учётных записей Minecraft для проверки логинов. Отключите, чтобы разрешить подключение учётных записей без лицензии.", + "mcwifipnp.gui.OnlineMode.online": "启用", + "mcwifipnp.gui.OnlineMode.online.info": "启用正版验证将只允许使用微软帐户登录的玩家加入本服务器。", + "mcwifipnp.gui.OnlineMode.offline": "禁用", + "mcwifipnp.gui.OnlineMode.offline.info": "禁用正版验证将允许使用离线模式登录的玩家加入本服务器。", + "mcwifipnp.gui.OnlineMode.fixuuid": "禁用 + 修复UUID", + "mcwifipnp.gui.OnlineMode.fixuuid.info": "尝试使用离线模式登录的玩家名匹配Mojang服务器用户名称以获取唯一UUID。\n同时为使用微软帐户登录的用户保留UUID。\n它也可以防止背包和物品栏内容丢失。", "mcwifipnp.gui.PvP": "PvP", "mcwifipnp.gui.PvP.info": "Переключает возможность игроков наносить прямой урон друг другу. Отключение режима PvP также не позволит вам получать урон от ваших собственных снарядов.", "mcwifipnp.gui.UseUPnP": "Переадресация порта", @@ -20,12 +26,18 @@ "mcwifipnp.gui.Local": "Локальный", "mcwifipnp.gui.Global": "Глобалный", "mcwifipnp.gui.CopyIP": "Получить IP", - "mcwifipnp.gui.CopyToClipboard": "Получить IP для копирования в буфер обмена", + "mcwifipnp.gui.CopyIP.info": "Получить IP для копирования в буфер обмена", "mcwifipnp.upnp.success": "Порт %s успешно переадресован", "mcwifipnp.upnp.clipboard": "Успешно получен %s, из-за таких факторов, как NAT, эти IP-адреса, возможно, по-прежнему не смогут подключиться напрямую.", "mcwifipnp.upnp.cantgetip": "Не удалось получить публичный IP! Пожалуйста, проверьте настройки вашей сети. Возможно, ваш IPv4 содержит несколько NAT-адресов или у вас нет IPv6.", "mcwifipnp.upnp.failed.mapped": "Не удаётся переадресовать порт %s: порт уже был сопоставлен другой службой UPnP. Пожалуйста, измените номер порта.", "mcwifipnp.upnp.failed.disabled": "Не удаётся переадресовать порт %s: UPnP на вашем маршрутизаторе не включен. Возможно, вам потребуется использовать программное обеспечение для сопоставления портов.", "mcwifipnp.upnp.failed.unknownerror": "Не удаётся переадресовать порт %s: неизвестная ошибка при добавлении сопоставления портов. Пожалуйста, используйте программное обеспечение для сопоставления портов.", - "mcwifipnp.upnp.failed": "Не удаётся переадресовать порт %s!" + "mcwifipnp.upnp.failed": "Не удаётся переадресовать порт %s!", + "mcwifipnp.commands.offlineplayers.add.failed": "玩家已在强制离线模式列表内", + "mcwifipnp.commands.offlineplayers.add.success": "已将%s加入强制离线模式列表", + "mcwifipnp.commands.offlineplayers.list": "强制离线模式列表中共有%s名玩家:%s", + "mcwifipnp.commands.offlineplayers.none": "强制离线模式列表中没有玩家", + "mcwifipnp.commands.offlineplayers.remove.failed": "玩家不在强制离线模式列表内", + "mcwifipnp.commands.offlineplayers.remove.success": "已将%s移出强制离线模式列表" } diff --git a/src/main/resources/assets/mcwifipnp/lang/zh_cn.json b/src/main/resources/assets/mcwifipnp/lang/zh_cn.json index 33c964a1..c9587dad 100644 --- a/src/main/resources/assets/mcwifipnp/lang/zh_cn.json +++ b/src/main/resources/assets/mcwifipnp/lang/zh_cn.json @@ -1,20 +1,26 @@ { - "mcwifipnp.gui.port":"端口号", - "mcwifipnp.gui.port.info":"局域网游戏端口号。\n请将编辑框留空,或输入一个介于1024至65535之间的数字。", + "mcwifipnp.gui.port": "端口号", + "mcwifipnp.gui.port.info": "局域网游戏端口号。\n请将编辑框留空,或输入一个介于1024至65535之间的数字。", "mcwifipnp.gui.port.invalid": "端口无效。\n请将编辑框留空,或输入一个介于1024至65535之间的数字。", "mcwifipnp.gui.port.unavailable": "端口不可用。\n请将编辑框留空,或输入一个介于1024至65535之间的新数字。", - "mcwifipnp.gui.players":"允许玩家数", - "mcwifipnp.gui.players.info":"服务器同时能容纳的最大玩家数量。", - "mcwifipnp.gui.motd":"服务器信息", - "mcwifipnp.gui.motd.info":"玩家客户端的多人游戏服务器列表中显示于名称下方的服务器信息。", - "mcwifipnp.gui.AllPlayersCheats":"其他玩家作弊", - "mcwifipnp.gui.AllPlayersCheats.info":"是否允许其他玩家作弊,你可以使用/op命令开放某人的作弊权限。", - "mcwifipnp.gui.Whitelist":"白名单", - "mcwifipnp.gui.Whitelist.info":"是否服务器的白名单。当启用时,只有白名单上的用户才能连接服务器。", + "mcwifipnp.gui.players": "允许玩家数", + "mcwifipnp.gui.players.info": "服务器同时能容纳的最大玩家数量。", + "mcwifipnp.gui.motd": "服务器信息", + "mcwifipnp.gui.motd.info": "玩家客户端的多人游戏服务器列表中显示于名称下方的服务器信息。", + "mcwifipnp.gui.AllPlayersCheats": "其他玩家作弊", + "mcwifipnp.gui.AllPlayersCheats.info": "是否允许其他玩家作弊,你可以使用/op命令开放某人的作弊权限。", + "mcwifipnp.gui.Whitelist": "白名单", + "mcwifipnp.gui.Whitelist.info": "是否服务器的白名单。当启用时,只有白名单上的用户才能连接服务器。", "mcwifipnp.gui.OnlineMode": "正版验证", - "mcwifipnp.gui.OnlineMode.info": "是否让服务器对比Minecraft账户数据库验证登录信息。", - "mcwifipnp.gui.PvP":"PvP", - "mcwifipnp.gui.PvP.info":"是否允许PvP。也只有在允许PvP时玩家自己的箭才会受到伤害。", + "mcwifipnp.gui.OnlineMode.info": "是否让服务器比对Mojang服务器数据库验证登录信息。", + "mcwifipnp.gui.OnlineMode.online": "启用", + "mcwifipnp.gui.OnlineMode.online.info": "启用正版验证将只允许使用微软帐户登录的玩家加入本服务器。", + "mcwifipnp.gui.OnlineMode.offline": "禁用", + "mcwifipnp.gui.OnlineMode.offline.info": "禁用正版验证将允许使用离线模式登录的玩家加入本服务器。", + "mcwifipnp.gui.OnlineMode.fixuuid": "禁用 + 修复UUID", + "mcwifipnp.gui.OnlineMode.fixuuid.info": "尝试使用离线模式登录的玩家名匹配Mojang服务器用户名称以获取唯一UUID。\n同时为使用微软帐户登录的用户保留UUID。\n它也可以防止背包和物品栏内容丢失。", + "mcwifipnp.gui.PvP": "PvP", + "mcwifipnp.gui.PvP.info": "是否允许PvP。也只有在允许PvP时玩家自己的箭才会受到伤害。", "mcwifipnp.gui.UseUPnP": "映射端口", "mcwifipnp.gui.UseUPnP.info": "是否使用UPnP功能映射局域网游戏端口号。", "mcwifipnp.gui.Local": "内网", @@ -27,5 +33,11 @@ "mcwifipnp.upnp.failed.mapped": "无法转发端口%s:端口%s已被另一个UPnP服务映射,请更换端口。", "mcwifipnp.upnp.failed.disabled": "无法转发端口%s:路由器上未启用UPnP,你可能需要端口映射软件。", "mcwifipnp.upnp.failed.unknownerror": "无法转发端口%s:添加端口映射时出现未知错误,请使用端口映射软件。", - "mcwifipnp.upnp.failed": "无法转发端口%s!请使用端口映射软件。" + "mcwifipnp.upnp.failed": "无法转发端口%s!请使用端口映射软件。", + "mcwifipnp.commands.offlineplayers.add.failed": "玩家已在强制离线模式列表内", + "mcwifipnp.commands.offlineplayers.add.success": "已将%s加入强制离线模式列表", + "mcwifipnp.commands.offlineplayers.list": "强制离线模式列表中共有%s名玩家:%s", + "mcwifipnp.commands.offlineplayers.none": "强制离线模式列表中没有玩家", + "mcwifipnp.commands.offlineplayers.remove.failed": "玩家不在强制离线模式列表内", + "mcwifipnp.commands.offlineplayers.remove.success": "已将%s移出强制离线模式列表" } diff --git a/src/main/resources/assets/mcwifipnp/lang/zh_hk.json b/src/main/resources/assets/mcwifipnp/lang/zh_hk.json index 8dc5ac32..394fb320 100644 --- a/src/main/resources/assets/mcwifipnp/lang/zh_hk.json +++ b/src/main/resources/assets/mcwifipnp/lang/zh_hk.json @@ -1,20 +1,26 @@ { - "mcwifipnp.gui.port":"端口號", - "mcwifipnp.gui.port.info":"局域網遊戲端口碼。\n請闕之,抑再入1024至65535間之數。", + "mcwifipnp.gui.port": "端口號", + "mcwifipnp.gui.port.info": "局域網遊戲端口碼。\n請闕之,抑再入1024至65535間之數。", "mcwifipnp.gui.port.invalid": "端口碼不可用。\n請闕之,抑再入1024至65535間之數。", "mcwifipnp.gui.port.unavailable": "端口碼不可用。\n請闕之,抑再入1024至65535間之另數。", - "mcwifipnp.gui.players":"允許玩家數", - "mcwifipnp.gui.players.info":"服務器同時能容納的最大玩家數量。", - "mcwifipnp.gui.motd":"伺服器信息", - "mcwifipnp.gui.motd.info":"玩家客戶端的多人遊戲服務器列錶中顯示於名稱下方的服務器信息。", - "mcwifipnp.gui.AllPlayersCheats":"其他玩家作弊", - "mcwifipnp.gui.AllPlayersCheats.info":"是否允許其他玩家作弊,你可以使用/op命令開放某人的作弊權限。", - "mcwifipnp.gui.Whitelist":"白名单", - "mcwifipnp.gui.Whitelist.info":"是否服務器的白名單。當啓用時,隻有白名單上的用戶才能連接服務器。", + "mcwifipnp.gui.players": "允許玩家數", + "mcwifipnp.gui.players.info": "服務器同時能容納的最大玩家數量。", + "mcwifipnp.gui.motd": "伺服器信息", + "mcwifipnp.gui.motd.info": "玩家客戶端的多人遊戲服務器列錶中顯示於名稱下方的服務器信息。", + "mcwifipnp.gui.AllPlayersCheats": "其他玩家作弊", + "mcwifipnp.gui.AllPlayersCheats.info": "是否允許其他玩家作弊,你可以使用/op命令開放某人的作弊權限。", + "mcwifipnp.gui.Whitelist": "白名单", + "mcwifipnp.gui.Whitelist.info": "是否服務器的白名單。當啓用時,隻有白名單上的用戶才能連接服務器。", "mcwifipnp.gui.OnlineMode": "正版驗證", "mcwifipnp.gui.OnlineMode.info": "是否讓服務器對比Minecraft賬戶數據庫驗證登入信息。", - "mcwifipnp.gui.PvP":"PvP", - "mcwifipnp.gui.PvP.info":"是否允許PvP。也隻有在允許PvP時玩家自己的箭才會受到傷害。", + "mcwifipnp.gui.OnlineMode.online": "启用", + "mcwifipnp.gui.OnlineMode.online.info": "启用正版验证将只允许使用微软帐户登录的玩家加入本服务器。", + "mcwifipnp.gui.OnlineMode.offline": "禁用", + "mcwifipnp.gui.OnlineMode.offline.info": "禁用正版验证将允许使用离线模式登录的玩家加入本服务器。", + "mcwifipnp.gui.OnlineMode.fixuuid": "禁用 + 修复UUID", + "mcwifipnp.gui.OnlineMode.fixuuid.info": "尝试使用离线模式登录的玩家名匹配Mojang服务器用户名称以获取唯一UUID。\n同时为使用微软帐户登录的用户保留UUID。\n它也可以防止背包和物品栏内容丢失。", + "mcwifipnp.gui.PvP": "PvP", + "mcwifipnp.gui.PvP.info": "是否允許PvP。也隻有在允許PvP時玩家自己的箭才會受到傷害。", "mcwifipnp.gui.UseUPnP": "映射端口", "mcwifipnp.gui.UseUPnP.info": "是否使用UPnP功能映射局域網遊戲端口號。", "mcwifipnp.gui.Local": "內網", @@ -27,5 +33,11 @@ "mcwifipnp.upnp.failed.mapped": "無法轉發端口%s:端口%s已被另一個UPnP服務映射,請更換端口。", "mcwifipnp.upnp.failed.disabled": "無法轉發端口%s:路由器上未啟用UPnP,你可能需要端口映射軟件。", "mcwifipnp.upnp.failed.unknownerror": "無法轉發端口%s:添加端口映射時出現未知錯誤,請使用端口映射軟件。", - "mcwifipnp.upnp.failed": "無法轉發端口%s!請使用端口映射軟件。" + "mcwifipnp.upnp.failed": "無法轉發端口%s!請使用端口映射軟件。", + "mcwifipnp.commands.offlineplayers.add.failed": "玩家已在强制离线模式列表内", + "mcwifipnp.commands.offlineplayers.add.success": "已将%s加入强制离线模式列表", + "mcwifipnp.commands.offlineplayers.list": "强制离线模式列表中共有%s名玩家:%s", + "mcwifipnp.commands.offlineplayers.none": "强制离线模式列表中没有玩家", + "mcwifipnp.commands.offlineplayers.remove.failed": "玩家不在强制离线模式列表内", + "mcwifipnp.commands.offlineplayers.remove.success": "已将%s移出强制离线模式列表" } diff --git a/src/main/resources/assets/mcwifipnp/lang/zh_tw.json b/src/main/resources/assets/mcwifipnp/lang/zh_tw.json index 6587f1e4..562988f7 100644 --- a/src/main/resources/assets/mcwifipnp/lang/zh_tw.json +++ b/src/main/resources/assets/mcwifipnp/lang/zh_tw.json @@ -1,31 +1,43 @@ { - "mcwifipnp.gui.port":"連接埠", - "mcwifipnp.gui.port.info":"區域網路遊戲連接埠。\n將編輯框留空或輸入 1024 到 65535 之間的數字。", + "mcwifipnp.gui.port": "連接埠", + "mcwifipnp.gui.port.info": "區域網路遊戲連接埠。\n將編輯框留空或輸入 1024 到 65535 之間的數字。", "mcwifipnp.gui.port.invalid": "連接埠不可用。\n將編輯框留空或輸入 1024 到 65535 之間的數字。", "mcwifipnp.gui.port.unavailable": "連接埠不可用。\n將編輯框留空或輸入 1024 到 65535 之間不同的數字。", - "mcwifipnp.gui.players":"允許玩家數", - "mcwifipnp.gui.players.info":"伺服器同時能容納的最大玩家數量。", - "mcwifipnp.gui.motd":"伺服器資訊", - "mcwifipnp.gui.motd.info":"玩家用戶端的多人遊戲伺服器清單中顯示於名稱下方的伺服器資訊。", - "mcwifipnp.gui.AllPlayersCheats":"其他玩家是否能作弊", - "mcwifipnp.gui.AllPlayersCheats.info":"是否允許其他玩家作弊,你可以使用 /op 指令開放某人的作弊權限。", - "mcwifipnp.gui.Whitelist":"白名單", - "mcwifipnp.gui.Whitelist.info":"是否伺服器的白名單。當啟用時,只有白名單上的使用者才能連線伺服器。", + "mcwifipnp.gui.players": "允許玩家數", + "mcwifipnp.gui.players.info": "伺服器同時能容納的最大玩家數量。", + "mcwifipnp.gui.motd": "伺服器資訊", + "mcwifipnp.gui.motd.info": "玩家用戶端的多人遊戲伺服器清單中顯示於名稱下方的伺服器資訊。", + "mcwifipnp.gui.AllPlayersCheats": "其他玩家是否能作弊", + "mcwifipnp.gui.AllPlayersCheats.info": "是否允許其他玩家作弊,你可以使用 /op 指令開放某人的作弊權限。", + "mcwifipnp.gui.Whitelist": "白名單", + "mcwifipnp.gui.Whitelist.info": "是否伺服器的白名單。當啟用時,只有白名單上的使用者才能連線伺服器。", "mcwifipnp.gui.OnlineMode": "正版驗證", - "mcwifipnp.gui.OnlineMode.info": "是否讓伺服器對比 Minecraft 帳號資料庫驗證登入資訊。", - "mcwifipnp.gui.PvP":"PvP", - "mcwifipnp.gui.PvP.info":"是否允許 PvP。也只有在允許 PvP 時玩家自己的箭才會受到傷害。", + "mcwifipnp.gui.OnlineMode.info": "是否讓伺服器對比 Mojang 伺服器帳號資料庫驗證登入資訊。", + "mcwifipnp.gui.OnlineMode.online": "啟用", + "mcwifipnp.gui.OnlineMode.online.info": "啟用正版驗證將只允許使用微軟帳戶登入的玩家加入本服務器。", + "mcwifipnp.gui.OnlineMode.offline": "禁用", + "mcwifipnp.gui.OnlineMode.offline.info": "禁用正版驗證將允許使用離線模式登入的玩家加入本服務器。", + "mcwifipnp.gui.OnlineMode.fixuuid": "禁用+修復UUID", + "mcwifipnp.gui.OnlineMode.fixuuid.info": "嘗試使用離線模式登入的玩家名匹配Mojang服務器用戶名稱以獲取唯一UUID。\n同時為使用微軟帳戶登入的用戶保留UUID。\n它也可以防止背包和物品欄內容遺失。", + "mcwifipnp.gui.PvP": "PvP", + "mcwifipnp.gui.PvP.info": "是否允許 PvP。也只有在允許 PvP 時玩家自己的箭才會受到傷害。", "mcwifipnp.gui.UseUPnP": "連接埠轉送", "mcwifipnp.gui.UseUPnP.info": "是否使用 UPnP 功能轉送區域網路遊戲連接埠。", "mcwifipnp.gui.Local": "內網", "mcwifipnp.gui.Global": "公網", "mcwifipnp.gui.CopyIP": "取得 IP", - "mcwifipnp.gui.CopyToClipboard": "取得內網 IP 地址及公網 IP 地址", + "mcwifipnp.gui.CopyIP.info": "取得內網 IP 地址及公網 IP 地址,以便於你直接複製。", "mcwifipnp.upnp.success": "成功連接埠轉送 %s", "mcwifipnp.upnp.clipboard": "成功取得到 %s,由於 NAT 等因素,這些 IP 可能仍舊無法直接聯機。", "mcwifipnp.upnp.cantgetip": "無法取得 IP!請檢查你的網路設定。你的 IPv4 可能包含多級 NAT 或者你無 IPv6。", - "mcwifipnp.upnp.failed.mapped": "無法連接埠轉送 %s:連接埠 %s 已被另一個 UPnP 服務轉送,請變更連接埠。", + "mcwifipnp.upnp.failed.mapped": "無法連接埠轉送 %s:連接埠 %s 已被另一個 UPnP 服務轉送,請變更連接埠。", "mcwifipnp.upnp.failed.disabled": "無法連接埠轉送 %s:路由器上未啟用 UPnP,你可能需要連接埠轉送軟體。", - "mcwifipnp.upnp.failed.unknownerror": "無法連接埠轉送 %s:增加連接埠轉送時出現未知錯誤,請使用連接埠轉送軟體。", - "mcwifipnp.upnp.failed": "無法連接埠轉送 %s!請使用連接埠轉送軟體。" + "mcwifipnp.upnp.failed.unknownerror": "無法連接埠轉送 %s:增加連接埠轉送時出現未知錯誤,請使用連接埠轉送軟體。", + "mcwifipnp.upnp.failed": "無法連接埠轉送 %s!請使用連接埠轉送軟體。", + "mcwifipnp.commands.offlineplayers.add.failed": "玩家已在強制離線模式清單內", + "mcwifipnp.commands.offlineplayers.add.success": "已將%s加入強制離線模式清單", + "mcwifipnp.commands.offlineplayers.list": "強制離線模式清單中共有%s名玩家:%s", + "mcwifipnp.commands.offlineplayers.none": "強制離線模式清單中沒有玩家", + "mcwifipnp.commands.offlineplayers.remove.failed": "玩家不在強制離線模式清單內", + "mcwifipnp.commands.offlineplayers.remove.success": "已將%s移出強制離線模式清單" } diff --git a/fabric/src/main/resources/mcwifipnp.mixins.json b/src/main/resources/mcwifipnp.mixins.json similarity index 79% rename from fabric/src/main/resources/mcwifipnp.mixins.json rename to src/main/resources/mcwifipnp.mixins.json index e9af5cdb..ab4ce7ad 100644 --- a/fabric/src/main/resources/mcwifipnp.mixins.json +++ b/src/main/resources/mcwifipnp.mixins.json @@ -4,7 +4,8 @@ "package": "io.github.satxm.mcwifipnp.mixin", "compatibilityLevel": "JAVA_21", "client": [ - "PlayerListAccessor" + "PlayerListAccessor", + "MixinUUIDUtil" ], "injectors": { "defaultRequire": 1