From edf8bafb85a8af6093879f467dca00c7e40a5dee Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:00:30 +0500 Subject: [PATCH 01/14] refactor(common): move variable from parent class to child class --- .../common/network/AbstractEternalEmpiresPayload.java | 10 ++++------ .../common/network/packet/UpdateDiscordRpcPayload.java | 6 ++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/common/src/main/java/net/eternalempires/mod/common/network/AbstractEternalEmpiresPayload.java b/common/src/main/java/net/eternalempires/mod/common/network/AbstractEternalEmpiresPayload.java index d19fe1e..05ea833 100644 --- a/common/src/main/java/net/eternalempires/mod/common/network/AbstractEternalEmpiresPayload.java +++ b/common/src/main/java/net/eternalempires/mod/common/network/AbstractEternalEmpiresPayload.java @@ -51,11 +51,6 @@ */ @Slf4j public abstract class AbstractEternalEmpiresPayload implements CustomPacketPayload { - - @NotNull - public static final CustomPacketPayload.Type<@NotNull UpdateDiscordRpcPayload> TYPE = - new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "mod")); - protected final byte[] data; @Nullable @@ -170,5 +165,8 @@ protected String extractJsonField(final @NotNull String fieldName) { * @apiNote Will likely be moved in the future to a more robust handling. * @param service this is an instance of the RichPresenceService. */ - public abstract void handlePayload(@NotNull RichPresenceService service); + public void handlePayload(@NotNull RichPresenceService service) {}; + + //Parameter-less handlePayload() for ModCheckPayload + public void handlePayload() {}; } diff --git a/common/src/main/java/net/eternalempires/mod/common/network/packet/UpdateDiscordRpcPayload.java b/common/src/main/java/net/eternalempires/mod/common/network/packet/UpdateDiscordRpcPayload.java index 73c5cd3..87ca5f0 100644 --- a/common/src/main/java/net/eternalempires/mod/common/network/packet/UpdateDiscordRpcPayload.java +++ b/common/src/main/java/net/eternalempires/mod/common/network/packet/UpdateDiscordRpcPayload.java @@ -26,12 +26,14 @@ import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; +import net.eternalempires.mod.common.Constants; import net.eternalempires.mod.common.network.AbstractEternalEmpiresPayload; import net.eternalempires.mod.common.util.discord.RichPresenceService; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,6 +50,10 @@ @Slf4j public final class UpdateDiscordRpcPayload extends AbstractEternalEmpiresPayload { + @NotNull + public static final CustomPacketPayload.Type<@NotNull UpdateDiscordRpcPayload> TYPE = + new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "mod")); + @NotNull public static final StreamCodec<@NotNull ByteBuf, @NotNull UpdateDiscordRpcPayload> BYTEBUF_CODEC = StreamCodec.of((buf, value) -> buf.writeBytes(value.data), From 60a66ca9785ff1cfd2908c4e69bbd67304d747e3 Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:01:28 +0500 Subject: [PATCH 02/14] feat(network): add ModCheckPayload packet for client detection --- .../network/packet/ModCheckPayload.java | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 common/src/main/java/net/eternalempires/mod/common/network/packet/ModCheckPayload.java diff --git a/common/src/main/java/net/eternalempires/mod/common/network/packet/ModCheckPayload.java b/common/src/main/java/net/eternalempires/mod/common/network/packet/ModCheckPayload.java new file mode 100644 index 0000000..eb8f55b --- /dev/null +++ b/common/src/main/java/net/eternalempires/mod/common/network/packet/ModCheckPayload.java @@ -0,0 +1,119 @@ +package net.eternalempires.mod.common.network.packet; + +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import net.eternalempires.mod.common.Constants; +import net.eternalempires.mod.common.network.AbstractEternalEmpiresPayload; +import net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class ModCheckPayload extends AbstractEternalEmpiresPayload { + + public static final CustomPacketPayload.Type TYPE = + new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "modcheck")); + + public static final StreamCodec BYTEBUF_CODEC = + StreamCodec.of((buf, value) -> buf.writeBytes(value.data), + buf -> { + final byte[] data = new byte[buf.readableBytes()]; + buf.readBytes(data); + return new ModCheckPayload(data); + }); + + public static final StreamCodec FORGE_CODEC = + StreamCodec.of( + (buf, packet) -> buf.writeBytes(packet.data), + buf -> { + byte[] data = new byte[buf.readableBytes()]; + buf.readBytes(data); + return new ModCheckPayload(data); + } + ); + + public static final StreamCodec FABRIC_CODEC = + StreamCodec.of((buf, value) -> buf.writeBytes(value.data), + buf -> { + final byte[] data = new byte[buf.readableBytes()]; + buf.readBytes(data); + return new ModCheckPayload(data); + }); + + public ModCheckPayload(FriendlyByteBuf buffer) { + super(buffer); + } + + public ModCheckPayload(byte[] data) { + super(data); + } + + @Override + public @NotNull Type type() { + return TYPE; + } + + private List extractModIds() { + try { + List modIds = new ArrayList<>(); + + // Extract the "data" object first, then get "modIds" from within it + String dataJson = extractJsonField("data"); + if (dataJson != null) { + // Parse the nested modIds array from the data object + // The dataJson should contain something like: {"modIds":["mod1","mod2","mod3"]} + int modIdsStart = dataJson.indexOf("\"modIds\":"); + if (modIdsStart != -1) { + int arrayStart = dataJson.indexOf("[", modIdsStart); + int arrayEnd = dataJson.indexOf("]", arrayStart); + + if (arrayStart != -1 && arrayEnd != -1) { + String modIdsArray = dataJson.substring(arrayStart + 1, arrayEnd); + String[] mods = modIdsArray.replace("\"", "").split(","); + for (String mod : mods) { + String trimmed = mod.trim(); + if (!trimmed.isEmpty()) { + modIds.add(trimmed); + } + } + } + } + } + + return modIds; + } catch (Exception e) { + log.error("[EternalEmpires] Failed to extract mod IDs from JSON", e); + return new ArrayList<>(); + } + } + + @Override + public void handlePayload() { + log.info("[EternalEmpires] Received JSON: {}", json); + + final String type = getTypeField(); + + if (!"prohibited_mod_ids".equalsIgnoreCase(type)) { + log.info("[EternalEmpires] Ignoring non-disallowed_mod_ids payload: type={}", type); + return; + } + + List serverDisallowedMods = extractModIds(); + if (serverDisallowedMods.isEmpty()) { + log.warn("[EternalEmpires] No mod IDs found in server packet"); + return; + } + + log.info("[EternalEmpires] Server disallowed mods: {}", serverDisallowedMods); + + // Delegate to the loader-specific handler + ModCheckHandler.performModCheck(serverDisallowedMods); + } +} \ No newline at end of file From 78d2177589c0b191f9451063d6fa801deb5a7ae6 Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:02:50 +0500 Subject: [PATCH 03/14] feat(modcheck): add IModListProvider interface for installed mod lookup --- .../common/util/modlistcheck/IModListProvider.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/IModListProvider.java diff --git a/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/IModListProvider.java b/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/IModListProvider.java new file mode 100644 index 0000000..c54993f --- /dev/null +++ b/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/IModListProvider.java @@ -0,0 +1,14 @@ +package net.eternalempires.mod.common.util.modlistcheck; + +import java.util.Map; +import java.util.Set; + +public interface IModListProvider { + Set getInstalledModIds(); + + /** + * Gets a map of mod ID to mod name for all installed mods + * @return Map where key is mod ID and value is mod display name + */ + Map getModIdToNameMap(); +} \ No newline at end of file From 63d10fd24e1873f52c83fc401bf0194290d28a1a Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:03:24 +0500 Subject: [PATCH 04/14] feat(fabric): implement IModListProvider for Fabric loader --- .../fabric/client/FabricModListProvider.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 fabric/src/main/java/net/eternalempires/mod/fabric/client/FabricModListProvider.java diff --git a/fabric/src/main/java/net/eternalempires/mod/fabric/client/FabricModListProvider.java b/fabric/src/main/java/net/eternalempires/mod/fabric/client/FabricModListProvider.java new file mode 100644 index 0000000..2f56d2a --- /dev/null +++ b/fabric/src/main/java/net/eternalempires/mod/fabric/client/FabricModListProvider.java @@ -0,0 +1,33 @@ +package net.eternalempires.mod.fabric.client; + +import net.eternalempires.mod.common.util.modlistcheck.IModListProvider; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class FabricModListProvider implements IModListProvider { + + @Override + public Set getInstalledModIds() { + return FabricLoader.getInstance().getAllMods().stream() + .map(modContainer -> modContainer.getMetadata().getId()) + .collect(Collectors.toSet()); + } + + @Override + public Map getModIdToNameMap() { + Map modIdToNameMap = new HashMap<>(); + + for (ModContainer modContainer : FabricLoader.getInstance().getAllMods()) { + String modId = modContainer.getMetadata().getId(); + String modName = modContainer.getMetadata().getName(); + modIdToNameMap.put(modId, modName); + } + + return modIdToNameMap; + } +} \ No newline at end of file From fcf19e7fc040e8d1dc676442103c115984dad1fe Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:04:26 +0500 Subject: [PATCH 05/14] chore(fabric): register FabricModListProvider in client initializer --- .../mod/fabric/client/EternalEmpiresClientModInitializer.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fabric/src/main/java/net/eternalempires/mod/fabric/client/EternalEmpiresClientModInitializer.java b/fabric/src/main/java/net/eternalempires/mod/fabric/client/EternalEmpiresClientModInitializer.java index 659611c..f0d24c5 100644 --- a/fabric/src/main/java/net/eternalempires/mod/fabric/client/EternalEmpiresClientModInitializer.java +++ b/fabric/src/main/java/net/eternalempires/mod/fabric/client/EternalEmpiresClientModInitializer.java @@ -27,6 +27,7 @@ import com.google.inject.Injector; import lombok.extern.slf4j.Slf4j; import net.eternalempires.mod.common.client.EternalEmpiresClient; +import net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler; import net.eternalempires.mod.fabric.listeners.JoinListener; import net.eternalempires.mod.fabric.listeners.LogoutListener; import net.eternalempires.mod.fabric.network.PacketHandlersFabric; @@ -53,5 +54,7 @@ public void onInitializeClient() { ClientPlayConnectionEvents.JOIN.register(injector.getInstance(JoinListener.class)); ClientPlayConnectionEvents.DISCONNECT.register(injector.getInstance(LogoutListener.class)); + + ModCheckHandler.setModListProvider(new FabricModListProvider()); } } \ No newline at end of file From fc725d366cbaa697d79175dc9daf5b34a09a4e5c Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:05:01 +0500 Subject: [PATCH 06/14] feat(forge): implement IModListProvider for Forge loader --- .../forge/client/ForgeModListProvider.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 forge/src/main/java/net/eternalempires/mod/forge/client/ForgeModListProvider.java diff --git a/forge/src/main/java/net/eternalempires/mod/forge/client/ForgeModListProvider.java b/forge/src/main/java/net/eternalempires/mod/forge/client/ForgeModListProvider.java new file mode 100644 index 0000000..cd88ad4 --- /dev/null +++ b/forge/src/main/java/net/eternalempires/mod/forge/client/ForgeModListProvider.java @@ -0,0 +1,33 @@ +package net.eternalempires.mod.forge.client; + +import net.eternalempires.mod.common.util.modlistcheck.IModListProvider; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.forgespi.language.IModInfo; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class ForgeModListProvider implements IModListProvider { + + @Override + public Set getInstalledModIds() { + return ModList.get().getMods().stream() + .map(IModInfo::getModId) + .collect(Collectors.toSet()); + } + + @Override + public Map getModIdToNameMap() { + Map modIdToNameMap = new HashMap<>(); + + for (IModInfo modInfo : ModList.get().getMods()) { + String modId = modInfo.getModId(); + String modName = modInfo.getDisplayName(); + modIdToNameMap.put(modId, modName); + } + + return modIdToNameMap; + } +} \ No newline at end of file From b9acfd8f4a260ad228f50daff820b94ae93bc8c6 Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:05:18 +0500 Subject: [PATCH 07/14] chore(forge): register ForgeModListProvider in client initializer --- .../java/net/eternalempires/mod/forge/ClientModEvents.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/forge/src/main/java/net/eternalempires/mod/forge/ClientModEvents.java b/forge/src/main/java/net/eternalempires/mod/forge/ClientModEvents.java index 3d11b64..5b331e3 100644 --- a/forge/src/main/java/net/eternalempires/mod/forge/ClientModEvents.java +++ b/forge/src/main/java/net/eternalempires/mod/forge/ClientModEvents.java @@ -29,6 +29,8 @@ import net.eternalempires.mod.common.Constants; import net.eternalempires.mod.common.client.EternalEmpiresClient; import net.eternalempires.mod.common.util.CommonService; +import net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler; +import net.eternalempires.mod.forge.client.ForgeModListProvider; import net.eternalempires.mod.forge.network.PacketHandler; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.eventbus.api.listener.SubscribeEvent; @@ -65,5 +67,7 @@ public static void clientSetup(final @NotNull FMLClientSetupEvent event) { final PacketHandler packetHandler = injector.getInstance(PacketHandler.class); event.enqueueWork(packetHandler::register); + + ModCheckHandler.setModListProvider(new ForgeModListProvider()); } } From f3da576151c4e2421b39be735c30493be371a1aa Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:08:46 +0500 Subject: [PATCH 08/14] feat(fabric): add ModCheckPayload registration and handler --- .../fabric/network/PacketHandlersFabric.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/fabric/src/main/java/net/eternalempires/mod/fabric/network/PacketHandlersFabric.java b/fabric/src/main/java/net/eternalempires/mod/fabric/network/PacketHandlersFabric.java index 671ed8e..b9df93e 100644 --- a/fabric/src/main/java/net/eternalempires/mod/fabric/network/PacketHandlersFabric.java +++ b/fabric/src/main/java/net/eternalempires/mod/fabric/network/PacketHandlersFabric.java @@ -28,6 +28,7 @@ import com.google.inject.Singleton; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import net.eternalempires.mod.common.network.packet.ModCheckPayload; import net.eternalempires.mod.common.network.packet.UpdateDiscordRpcPayload; import net.eternalempires.mod.common.util.discord.RichPresenceService; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; @@ -50,8 +51,10 @@ public final class PacketHandlersFabric { public void register() { PayloadTypeRegistry.playS2C().register(UpdateDiscordRpcPayload.TYPE, UpdateDiscordRpcPayload.FABRIC_CODEC); + PayloadTypeRegistry.playS2C().register(ModCheckPayload.TYPE, ModCheckPayload.FABRIC_CODEC); - ClientPlayNetworking.registerGlobalReceiver(UpdateDiscordRpcPayload.TYPE, this::handleContext); + ClientPlayNetworking.registerGlobalReceiver(UpdateDiscordRpcPayload.TYPE, this::handleRpcContext); + ClientPlayNetworking.registerGlobalReceiver(ModCheckPayload.TYPE, this::handleModListContext); } /** @@ -61,7 +64,7 @@ public void register() { * @param payload the payload * @param context the context */ - private void handleContext( + private void handleRpcContext( final @NotNull UpdateDiscordRpcPayload payload, final @NotNull ClientPlayNetworking.Context context ) { @@ -77,4 +80,18 @@ private void handleContext( } }); } + + private void handleModListContext( + final @NotNull ModCheckPayload payload, + final @NotNull ClientPlayNetworking.Context context + ) { + context.client().execute(() -> { + try { + log.info("Received ModCheck payload: {}", payload); + payload.handlePayload(); + } catch (Exception e) { + log.warn("Failed to handle ModCheck payload ", e); + } + }); + } } \ No newline at end of file From c52a78bcec5011cac7d6ba1966c3a73042206728 Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:09:17 +0500 Subject: [PATCH 09/14] feat(forge): add ModCheckPayload channel and handler --- .../mod/forge/network/PacketHandler.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/forge/src/main/java/net/eternalempires/mod/forge/network/PacketHandler.java b/forge/src/main/java/net/eternalempires/mod/forge/network/PacketHandler.java index 9a1dae1..3f5d2e4 100644 --- a/forge/src/main/java/net/eternalempires/mod/forge/network/PacketHandler.java +++ b/forge/src/main/java/net/eternalempires/mod/forge/network/PacketHandler.java @@ -26,6 +26,7 @@ import com.google.inject.Inject; import net.eternalempires.mod.common.Constants; +import net.eternalempires.mod.common.network.packet.ModCheckPayload; import net.eternalempires.mod.common.network.packet.UpdateDiscordRpcPayload; import net.eternalempires.mod.common.util.discord.RichPresenceService; import net.minecraft.resources.ResourceLocation; @@ -57,6 +58,20 @@ public PacketHandler(@NotNull RichPresenceService richPresenceService) { packet.handlePayload(richPresenceService); }) .build(); + + @NotNull SimpleChannel checkProhibitedMods = ChannelBuilder.named( + ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "modcheck")) + .serverAcceptedVersions((status, i) -> true) + .clientAcceptedVersions((status, i) -> true) + .networkProtocolVersion(1) + .simpleChannel() + .play() + .clientbound() + .add(ModCheckPayload.class, ModCheckPayload.FORGE_CODEC, + (packet, context) -> { + packet.handlePayload(); + }) + .build(); } /** From 3b1ae7f767e2b208c8c3a74763d7cac8b8279a15 Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:09:55 +0500 Subject: [PATCH 10/14] feat(neoforge): add NeoForgeModListProvider for installed mod detection --- .../client/NeoForgeModListProvider.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 neoforge/src/main/java/net/eternalempires/mod/neoforge/client/NeoForgeModListProvider.java diff --git a/neoforge/src/main/java/net/eternalempires/mod/neoforge/client/NeoForgeModListProvider.java b/neoforge/src/main/java/net/eternalempires/mod/neoforge/client/NeoForgeModListProvider.java new file mode 100644 index 0000000..27df61f --- /dev/null +++ b/neoforge/src/main/java/net/eternalempires/mod/neoforge/client/NeoForgeModListProvider.java @@ -0,0 +1,33 @@ +package net.eternalempires.mod.neoforge.client; + +import net.eternalempires.mod.common.util.modlistcheck.IModListProvider; +import net.neoforged.fml.ModList; +import net.neoforged.neoforgespi.language.IModInfo; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class NeoForgeModListProvider implements IModListProvider { + + @Override + public Set getInstalledModIds() { + return ModList.get().getMods().stream() + .map(IModInfo::getModId) + .collect(Collectors.toSet()); + } + + @Override + public Map getModIdToNameMap() { + Map modIdToNameMap = new HashMap<>(); + + for (IModInfo modInfo : ModList.get().getMods()) { + String modId = modInfo.getModId(); + String modName = modInfo.getDisplayName(); + modIdToNameMap.put(modId, modName); + } + + return modIdToNameMap; + } +} \ No newline at end of file From 13432b7f59704d542d44bdb6095abb5ed18a8c54 Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:10:27 +0500 Subject: [PATCH 11/14] feat(neoforge): register ModCheckPayload and integrate NeoForgeModListProvider --- .../mod/neoforge/ClientModEvents.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/neoforge/src/main/java/net/eternalempires/mod/neoforge/ClientModEvents.java b/neoforge/src/main/java/net/eternalempires/mod/neoforge/ClientModEvents.java index 917bc22..65f4fb8 100644 --- a/neoforge/src/main/java/net/eternalempires/mod/neoforge/ClientModEvents.java +++ b/neoforge/src/main/java/net/eternalempires/mod/neoforge/ClientModEvents.java @@ -5,8 +5,11 @@ import lombok.extern.slf4j.Slf4j; import net.eternalempires.mod.common.Constants; import net.eternalempires.mod.common.client.EternalEmpiresClient; +import net.eternalempires.mod.common.network.packet.ModCheckPayload; import net.eternalempires.mod.common.network.packet.UpdateDiscordRpcPayload; import net.eternalempires.mod.common.util.CommonService; +import net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler; +import net.eternalempires.mod.neoforge.client.NeoForgeModListProvider; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; @@ -43,6 +46,7 @@ public static void clientSetup(final @NotNull FMLClientSetupEvent event) { final Injector injector = EternalEmpiresClient.init(); commonService = injector.getInstance(CommonService.class); + ModCheckHandler.setModListProvider(new NeoForgeModListProvider()); } /** @@ -64,6 +68,7 @@ public static void register(final @NotNull RegisterPayloadHandlersEvent event) { context.enqueueWork(() -> { log.debug("Received JSON: {}", updateDiscordRpcPayload.json()); + assert commonService != null; updateDiscordRpcPayload.handlePayload(Objects.requireNonNull( commonService.getRichPresenceService(), "ClientModEvents is not initialized!" @@ -71,5 +76,14 @@ public static void register(final @NotNull RegisterPayloadHandlersEvent event) { }); } ); + + registrar.playToClient( + ModCheckPayload.TYPE, + ModCheckPayload.BYTEBUF_CODEC, + (modCheckPayload, context) -> context.enqueueWork(() -> { + log.info("[EternalEmpires] Received ModCheck JSON: {}", modCheckPayload.json()); + modCheckPayload.handlePayload(); + }) + ); } } From d60472802208bcbdd649f84256bdaffdcc82e6db Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:11:07 +0500 Subject: [PATCH 12/14] feat(common): add ModCheckHandler for detecting disallowed mods and disconnecting clients --- .../util/modlistcheck/ModCheckHandler.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/ModCheckHandler.java diff --git a/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/ModCheckHandler.java b/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/ModCheckHandler.java new file mode 100644 index 0000000..2815abb --- /dev/null +++ b/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/ModCheckHandler.java @@ -0,0 +1,107 @@ +package net.eternalempires.mod.common.util.modlistcheck; + +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.ClickEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; + +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@Slf4j +public class ModCheckHandler { + + /** + * -- SETTER -- + * This should be called by each mod loader's initialization to set their specific provider + */ + @Setter + private static IModListProvider modListProvider; + + public static void performModCheck(List serverDisallowedMods) { + if (modListProvider == null) { + log.warn("[EternalEmpires] No mod list provider set! Cannot perform mod check."); + return; + } + + Set installedMods = modListProvider.getInstalledModIds(); + log.info("[EternalEmpires] Client installed mods: {}", installedMods); + + List foundDisallowedMods = serverDisallowedMods.stream() + .filter(installedMods::contains) + .collect(Collectors.toList()); + + if (!foundDisallowedMods.isEmpty()) { + log.warn("[EternalEmpires] Found disallowed mods on client: {}", foundDisallowedMods); + disconnectWithModError(foundDisallowedMods); + } else { + log.info("[EternalEmpires] No disallowed mods found, connection allowed"); + } + } + + private static void disconnectWithModError(List foundModIds) { + log.info("[EternalEmpires] Disconnecting player due to disallowed mods: {}", foundModIds); + + Map modIdToNameMap = modListProvider.getModIdToNameMap(); + + Component title = Component.literal("Eternal Empires MMORPG") + .setStyle(Style.EMPTY.withColor(0xFF5555).withBold(true)); + + Component failed = Component.translatable("mod.join.prohibited.failed") + .setStyle(Style.EMPTY.withColor(0xFF5555)); + + Component explanation = Component.translatable( + "mod.join.prohibited.explanation" + ).setStyle(Style.EMPTY.withColor(0xAAAAAA)); + + String modsJoined = foundModIds.stream() + .map(id -> modIdToNameMap.getOrDefault(id, id)) + .collect(Collectors.joining(", ")); + + Component modsHeader = Component.translatable("mod.join.prohibited.modsHeader") + .setStyle(Style.EMPTY.withColor(0xFF5555)); + + Component modsList = Component.literal(modsJoined) + .setStyle(Style.EMPTY.withColor(0xAAAAAA)); + + Component supportLine1 = Component.translatable( + "mod.join.prohibited.supportLine1" + ).setStyle(Style.EMPTY.withColor(0xAAAAAA)); + + Component supportUrl = Component.literal("https://eternalempires.link/0c942d") + .setStyle(Style.EMPTY + .withColor(0xFF5555) // red + .withUnderlined(true) // underline so it looks clickable + .withClickEvent(new ClickEvent.OpenUrl(URI.create("https://eternalempires.link/0c942d"))) + ); + + Component disconnectReason = Component.empty() + .append(title).append("\n") + .append(failed).append("\n\n") + .append(explanation).append("\n\n") + .append(modsHeader).append("\n") + .append(modsList).append("\n\n") + .append(supportLine1).append(supportUrl); + + Minecraft minecraft = Minecraft.getInstance(); + if (minecraft.getConnection() != null) { + minecraft.getConnection().getConnection().disconnect(disconnectReason); + } +/* + minecraft.execute(() -> { + minecraft.setScreen(new DisconnectedScreen( + new TitleScreen(), + Component.literal("Disconnected"), + disconnectReason + )); + }); + + + */ + } +} \ No newline at end of file From f4702605f2e80469a0c9238d0a4bfb6e35e2b257 Mon Sep 17 00:00:00 2001 From: Sameer Date: Wed, 10 Sep 2025 23:11:40 +0500 Subject: [PATCH 13/14] feat(common): add localization files for disallowed mod kick messages --- .../main/resources/assets/eternalempires/lang/af_za.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ar_sa.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ast_es.json | 5 +++++ .../main/resources/assets/eternalempires/lang/az_az.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ba_ru.json | 5 +++++ .../src/main/resources/assets/eternalempires/lang/bar.json | 5 +++++ .../main/resources/assets/eternalempires/lang/be_by.json | 5 +++++ .../main/resources/assets/eternalempires/lang/bg_bg.json | 5 +++++ .../main/resources/assets/eternalempires/lang/br_fr.json | 5 +++++ .../main/resources/assets/eternalempires/lang/bs_ba.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ca_es.json | 5 +++++ .../main/resources/assets/eternalempires/lang/cs_cz.json | 5 +++++ .../main/resources/assets/eternalempires/lang/cy_gb.json | 5 +++++ .../main/resources/assets/eternalempires/lang/da_dk.json | 5 +++++ .../main/resources/assets/eternalempires/lang/de_at.json | 5 +++++ .../main/resources/assets/eternalempires/lang/de_ch.json | 5 +++++ .../main/resources/assets/eternalempires/lang/de_de.json | 5 +++++ .../main/resources/assets/eternalempires/lang/el_gr.json | 5 +++++ .../main/resources/assets/eternalempires/lang/en_au.json | 5 +++++ .../main/resources/assets/eternalempires/lang/en_ca.json | 5 +++++ .../main/resources/assets/eternalempires/lang/en_gb.json | 5 +++++ .../main/resources/assets/eternalempires/lang/en_nz.json | 5 +++++ .../main/resources/assets/eternalempires/lang/en_us.json | 6 ++++++ .../main/resources/assets/eternalempires/lang/en_za.json | 5 +++++ .../main/resources/assets/eternalempires/lang/es_ar.json | 5 +++++ .../main/resources/assets/eternalempires/lang/es_cl.json | 5 +++++ .../main/resources/assets/eternalempires/lang/es_ec.json | 5 +++++ .../main/resources/assets/eternalempires/lang/es_es.json | 5 +++++ .../main/resources/assets/eternalempires/lang/es_mx.json | 5 +++++ .../main/resources/assets/eternalempires/lang/es_uy.json | 5 +++++ .../main/resources/assets/eternalempires/lang/es_ve.json | 5 +++++ .../main/resources/assets/eternalempires/lang/et_ee.json | 5 +++++ .../main/resources/assets/eternalempires/lang/eu_es.json | 5 +++++ .../main/resources/assets/eternalempires/lang/fa_ir.json | 5 +++++ .../main/resources/assets/eternalempires/lang/fi_fi.json | 5 +++++ .../main/resources/assets/eternalempires/lang/fo_fo.json | 5 +++++ .../main/resources/assets/eternalempires/lang/fr_ca.json | 5 +++++ .../main/resources/assets/eternalempires/lang/fr_ch.json | 5 +++++ .../main/resources/assets/eternalempires/lang/fr_fr.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ga_ie.json | 5 +++++ .../main/resources/assets/eternalempires/lang/gd_gb.json | 5 +++++ .../main/resources/assets/eternalempires/lang/gl_es.json | 5 +++++ .../main/resources/assets/eternalempires/lang/haw_us.json | 5 +++++ .../main/resources/assets/eternalempires/lang/he_il.json | 5 +++++ .../main/resources/assets/eternalempires/lang/hi_in.json | 5 +++++ .../main/resources/assets/eternalempires/lang/hr_hr.json | 5 +++++ .../main/resources/assets/eternalempires/lang/hu_hu.json | 5 +++++ .../main/resources/assets/eternalempires/lang/hy_am.json | 5 +++++ .../main/resources/assets/eternalempires/lang/id_id.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ig_ng.json | 5 +++++ .../main/resources/assets/eternalempires/lang/is_is.json | 5 +++++ .../main/resources/assets/eternalempires/lang/it_it.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ja_jp.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ka_ge.json | 5 +++++ .../main/resources/assets/eternalempires/lang/kk_kz.json | 5 +++++ .../main/resources/assets/eternalempires/lang/kn_in.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ko_kr.json | 5 +++++ .../main/resources/assets/eternalempires/lang/la_la.json | 5 +++++ .../main/resources/assets/eternalempires/lang/lb_lu.json | 5 +++++ .../main/resources/assets/eternalempires/lang/lt_lt.json | 5 +++++ .../main/resources/assets/eternalempires/lang/lv_lv.json | 5 +++++ .../main/resources/assets/eternalempires/lang/mk_mk.json | 5 +++++ .../main/resources/assets/eternalempires/lang/mn_mn.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ms_my.json | 5 +++++ .../main/resources/assets/eternalempires/lang/mt_mt.json | 5 +++++ .../main/resources/assets/eternalempires/lang/nl_nl.json | 5 +++++ .../main/resources/assets/eternalempires/lang/nn_no.json | 5 +++++ .../main/resources/assets/eternalempires/lang/no_no.json | 5 +++++ .../main/resources/assets/eternalempires/lang/pl_pl.json | 5 +++++ .../main/resources/assets/eternalempires/lang/pt_br.json | 5 +++++ .../main/resources/assets/eternalempires/lang/pt_pt.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ro_ro.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ru_ru.json | 5 +++++ .../main/resources/assets/eternalempires/lang/sk_sk.json | 5 +++++ .../main/resources/assets/eternalempires/lang/sl_si.json | 5 +++++ .../main/resources/assets/eternalempires/lang/sq_al.json | 5 +++++ .../main/resources/assets/eternalempires/lang/sr_sp.json | 5 +++++ .../resources/assets/eternalempires/lang/sr_sp_latn.json | 5 +++++ .../main/resources/assets/eternalempires/lang/sv_se.json | 5 +++++ .../main/resources/assets/eternalempires/lang/ta_in.json | 5 +++++ .../main/resources/assets/eternalempires/lang/th_th.json | 5 +++++ .../main/resources/assets/eternalempires/lang/tr_tr.json | 5 +++++ .../main/resources/assets/eternalempires/lang/uk_ua.json | 5 +++++ .../main/resources/assets/eternalempires/lang/vi_vn.json | 5 +++++ .../main/resources/assets/eternalempires/lang/yi_de.json | 5 +++++ .../main/resources/assets/eternalempires/lang/yo_ng.json | 5 +++++ .../main/resources/assets/eternalempires/lang/zh_cn.json | 5 +++++ .../main/resources/assets/eternalempires/lang/zh_tw.json | 5 +++++ 88 files changed, 441 insertions(+) create mode 100644 common/src/main/resources/assets/eternalempires/lang/af_za.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ar_sa.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ast_es.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/az_az.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ba_ru.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/bar.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/be_by.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/bg_bg.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/br_fr.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/bs_ba.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ca_es.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/cs_cz.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/cy_gb.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/da_dk.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/de_at.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/de_ch.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/de_de.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/el_gr.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/en_au.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/en_ca.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/en_gb.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/en_nz.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/en_us.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/en_za.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/es_ar.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/es_cl.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/es_ec.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/es_es.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/es_mx.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/es_uy.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/es_ve.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/et_ee.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/eu_es.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/fa_ir.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/fi_fi.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/fo_fo.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/fr_ca.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/fr_ch.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/fr_fr.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ga_ie.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/gd_gb.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/gl_es.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/haw_us.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/he_il.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/hi_in.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/hr_hr.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/hu_hu.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/hy_am.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/id_id.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ig_ng.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/is_is.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/it_it.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ja_jp.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ka_ge.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/kk_kz.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/kn_in.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ko_kr.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/la_la.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/lb_lu.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/lt_lt.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/lv_lv.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/mk_mk.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/mn_mn.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ms_my.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/mt_mt.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/nl_nl.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/nn_no.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/no_no.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/pl_pl.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/pt_br.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/pt_pt.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ro_ro.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ru_ru.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/sk_sk.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/sl_si.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/sq_al.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/sr_sp.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/sr_sp_latn.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/sv_se.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/ta_in.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/th_th.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/tr_tr.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/uk_ua.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/vi_vn.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/yi_de.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/yo_ng.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/zh_cn.json create mode 100644 common/src/main/resources/assets/eternalempires/lang/zh_tw.json diff --git a/common/src/main/resources/assets/eternalempires/lang/af_za.json b/common/src/main/resources/assets/eternalempires/lang/af_za.json new file mode 100644 index 0000000..8f59c3d --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/af_za.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Die volgende wysigings word beïnvloed deur ons riglyne:", + "mod.join.prohibited.failed":"Verbinding het misluk", + "mod.join.prohibited.explanation":"Dit wil voorkom asof u mods gebruik wat nie is nie\n", + "mod.join.prohibited.supportLine1":"As u verdere hulp benodig, kan u ons ondersteuningspan kontak\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ar_sa.json b/common/src/main/resources/assets/eternalempires/lang/ar_sa.json new file mode 100644 index 0000000..14e9553 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ar_sa.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"تتأثر التعديلات التالية بإرشاداتنا:", + "mod.join.prohibited.failed":"فشل الاتصال", + "mod.join.prohibited.explanation":"يبدو أنك تستخدم MODs غير كذلك\n", + "mod.join.prohibited.supportLine1":"إذا كنت بحاجة إلى مزيد من المساعدة ، يمكنك الاتصال بفريق الدعم الخاص بنا\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ast_es.json b/common/src/main/resources/assets/eternalempires/lang/ast_es.json new file mode 100644 index 0000000..7748685 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ast_es.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/az_az.json b/common/src/main/resources/assets/eternalempires/lang/az_az.json new file mode 100644 index 0000000..ad4c67c --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/az_az.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Aşağıdakı dəyişikliklər təlimatımızdan təsirlənir:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ba_ru.json b/common/src/main/resources/assets/eternalempires/lang/ba_ru.json new file mode 100644 index 0000000..5a1f428 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ba_ru.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Түбәндәге үҙгәрештәргә беҙҙең йүнәлештәргә йоғонто яһай:", + "mod.join.prohibited.failed":"Бәйләнеш уңышһыҙлыҡҡа осраны", + "mod.join.prohibited.explanation":"Күрәһең, һеҙ ҡулланыу модтар, улар түгел\n", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/bar.json b/common/src/main/resources/assets/eternalempires/lang/bar.json new file mode 100644 index 0000000..7748685 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/bar.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/be_by.json b/common/src/main/resources/assets/eternalempires/lang/be_by.json new file mode 100644 index 0000000..b6c9ef6 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/be_by.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"На наступныя мадыфікацыі ўплываюць нашы рэкамендацыі:", + "mod.join.prohibited.failed":"Злучэнне не атрымалася", + "mod.join.prohibited.explanation":"Здаецца, вы выкарыстоўваеце моды, якіх няма\n", + "mod.join.prohibited.supportLine1":"Калі вам патрэбна дадатковая дапамога, вы можаце звязацца з нашай камандай падтрымкі\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/bg_bg.json b/common/src/main/resources/assets/eternalempires/lang/bg_bg.json new file mode 100644 index 0000000..1431d73 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/bg_bg.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Следните модификации са засегнати от нашите насоки:", + "mod.join.prohibited.failed":"Връзката не успя", + "mod.join.prohibited.explanation":"Изглежда, че използвате модове, които не са\n", + "mod.join.prohibited.supportLine1":"Ако имате нужда от допълнителна помощ, можете да се свържете с нашия екип за поддръжка\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/br_fr.json b/common/src/main/resources/assets/eternalempires/lang/br_fr.json new file mode 100644 index 0000000..f43d036 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/br_fr.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Ar c\u0027hemmoù da heul a zo gwallet gant hor c\u0027hemennadennoù :", + "mod.join.prohibited.failed":"C\u0027hwitet eo ar c\u0027hennaskañ", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/bs_ba.json b/common/src/main/resources/assets/eternalempires/lang/bs_ba.json new file mode 100644 index 0000000..d367857 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/bs_ba.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Na sledeće izmjene utiče na naše smernice:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"Ako vam je potrebna dodatna pomoć, možete se obratiti našem timu za podršku\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ca_es.json b/common/src/main/resources/assets/eternalempires/lang/ca_es.json new file mode 100644 index 0000000..27c39c5 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ca_es.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Ha fallat la connexió", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"Si necessiteu més ajuda, podeu contactar amb el nostre equip de suport\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/cs_cz.json b/common/src/main/resources/assets/eternalempires/lang/cs_cz.json new file mode 100644 index 0000000..fa274db --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/cs_cz.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Následující úpravy jsou ovlivněny našimi pokyny:", + "mod.join.prohibited.failed":"Připojení selhalo", + "mod.join.prohibited.explanation":"Zdá se, že používáte mody, které nejsou\n", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/cy_gb.json b/common/src/main/resources/assets/eternalempires/lang/cy_gb.json new file mode 100644 index 0000000..441081e --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/cy_gb.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Effeithir ar yr addasiadau canlynol gan ein canllawiau:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"Mae\u0027n ymddangos eich bod chi\u0027n defnyddio mods nad ydyn nhw\n", + "mod.join.prohibited.supportLine1":"Os oes angen cymorth pellach arnoch, gallwch gysylltu â\u0027n tîm cymorth\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/da_dk.json b/common/src/main/resources/assets/eternalempires/lang/da_dk.json new file mode 100644 index 0000000..1e88692 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/da_dk.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Forbindelsen mislykkedes", + "mod.join.prohibited.explanation":"Det ser ud til, at du bruger mods, der ikke er\n", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/de_at.json b/common/src/main/resources/assets/eternalempires/lang/de_at.json new file mode 100644 index 0000000..e586894 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/de_at.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Verbindung ist fehlgeschlagen", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"Wenn Sie weitere Unterstützung benötigen, können Sie sich an unser Support -Team wenden\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/de_ch.json b/common/src/main/resources/assets/eternalempires/lang/de_ch.json new file mode 100644 index 0000000..7748685 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/de_ch.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/de_de.json b/common/src/main/resources/assets/eternalempires/lang/de_de.json new file mode 100644 index 0000000..5ce88d8 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/de_de.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Die folgenden Änderungen werden von unseren Richtlinien beeinflusst:", + "mod.join.prohibited.failed":"Verbindung ist fehlgeschlagen", + "mod.join.prohibited.explanation":"Es scheint, dass Sie Mods verwenden, die nicht sind\n", + "mod.join.prohibited.supportLine1":"Wenn Sie weitere Unterstützung benötigen, können Sie sich an unser Support -Team wenden\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/el_gr.json b/common/src/main/resources/assets/eternalempires/lang/el_gr.json new file mode 100644 index 0000000..0ed5ae2 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/el_gr.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Απέτυχε η σύνδεση", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/en_au.json b/common/src/main/resources/assets/eternalempires/lang/en_au.json new file mode 100644 index 0000000..0e17396 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/en_au.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/en_ca.json b/common/src/main/resources/assets/eternalempires/lang/en_ca.json new file mode 100644 index 0000000..7748685 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/en_ca.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/en_gb.json b/common/src/main/resources/assets/eternalempires/lang/en_gb.json new file mode 100644 index 0000000..7748685 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/en_gb.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/en_nz.json b/common/src/main/resources/assets/eternalempires/lang/en_nz.json new file mode 100644 index 0000000..7748685 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/en_nz.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/en_us.json b/common/src/main/resources/assets/eternalempires/lang/en_us.json new file mode 100644 index 0000000..ec36fb9 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/en_us.json @@ -0,0 +1,6 @@ +{ + "mod.join.prohibited.failed": "Connection failed", + "mod.join.prohibited.explanation": "It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.modsHeader": "The following modifications are affected by our guidelines:", + "mod.join.prohibited.supportLine1": "If you need further assistance, you can contact our support team\nat any time at " +} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/en_za.json b/common/src/main/resources/assets/eternalempires/lang/en_za.json new file mode 100644 index 0000000..0e17396 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/en_za.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/es_ar.json b/common/src/main/resources/assets/eternalempires/lang/es_ar.json new file mode 100644 index 0000000..97b2db7 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/es_ar.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Las siguientes modificaciones se ven afectadas por nuestras pautas:", + "mod.join.prohibited.failed":"Falló la conexión", + "mod.join.prohibited.explanation":"Parece que está utilizando mods que no\n", + "mod.join.prohibited.supportLine1":"Si necesita más ayuda, puede comunicarse con nuestro equipo de soporte\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/es_cl.json b/common/src/main/resources/assets/eternalempires/lang/es_cl.json new file mode 100644 index 0000000..97b2db7 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/es_cl.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Las siguientes modificaciones se ven afectadas por nuestras pautas:", + "mod.join.prohibited.failed":"Falló la conexión", + "mod.join.prohibited.explanation":"Parece que está utilizando mods que no\n", + "mod.join.prohibited.supportLine1":"Si necesita más ayuda, puede comunicarse con nuestro equipo de soporte\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/es_ec.json b/common/src/main/resources/assets/eternalempires/lang/es_ec.json new file mode 100644 index 0000000..97b2db7 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/es_ec.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Las siguientes modificaciones se ven afectadas por nuestras pautas:", + "mod.join.prohibited.failed":"Falló la conexión", + "mod.join.prohibited.explanation":"Parece que está utilizando mods que no\n", + "mod.join.prohibited.supportLine1":"Si necesita más ayuda, puede comunicarse con nuestro equipo de soporte\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/es_es.json b/common/src/main/resources/assets/eternalempires/lang/es_es.json new file mode 100644 index 0000000..97b2db7 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/es_es.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Las siguientes modificaciones se ven afectadas por nuestras pautas:", + "mod.join.prohibited.failed":"Falló la conexión", + "mod.join.prohibited.explanation":"Parece que está utilizando mods que no\n", + "mod.join.prohibited.supportLine1":"Si necesita más ayuda, puede comunicarse con nuestro equipo de soporte\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/es_mx.json b/common/src/main/resources/assets/eternalempires/lang/es_mx.json new file mode 100644 index 0000000..6e45131 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/es_mx.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Falló la conexión", + "mod.join.prohibited.explanation":"Parece que está utilizando mods que no\n", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/es_uy.json b/common/src/main/resources/assets/eternalempires/lang/es_uy.json new file mode 100644 index 0000000..41ae1d3 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/es_uy.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Las siguientes modificaciones se ven afectadas por nuestras pautas:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"Parece que está utilizando mods que no\n", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/es_ve.json b/common/src/main/resources/assets/eternalempires/lang/es_ve.json new file mode 100644 index 0000000..835635f --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/es_ve.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Las siguientes modificaciones se ven afectadas por nuestras pautas:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"Si necesita más ayuda, puede comunicarse con nuestro equipo de soporte\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/et_ee.json b/common/src/main/resources/assets/eternalempires/lang/et_ee.json new file mode 100644 index 0000000..228b892 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/et_ee.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Meie juhised mõjutavad järgmisi muudatusi:", + "mod.join.prohibited.failed":"Ühendus ebaõnnestus", + "mod.join.prohibited.explanation":"Näib, et kasutate modifikatsioone, mis pole\n", + "mod.join.prohibited.supportLine1":"Kui vajate täiendavat abi, võite pöörduda meie tugimeeskonna poole\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/eu_es.json b/common/src/main/resources/assets/eternalempires/lang/eu_es.json new file mode 100644 index 0000000..6fddf43 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/eu_es.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Aldaketa hauek gure jarraibideei eragiten diete:", + "mod.join.prohibited.failed":"Konexioak huts egin du", + "mod.join.prohibited.explanation":"Badirudi ez diren modak erabiltzen ari zarela\n", + "mod.join.prohibited.supportLine1":"Laguntza gehiago behar izanez gero, jar zaitezke gure laguntza taldearekin harremanetan\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/fa_ir.json b/common/src/main/resources/assets/eternalempires/lang/fa_ir.json new file mode 100644 index 0000000..41d6a79 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/fa_ir.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"اصلاحات زیر تحت تأثیر دستورالعمل های ما است:", + "mod.join.prohibited.failed":"اتصال شکست خورد", + "mod.join.prohibited.explanation":"به نظر می رسد که شما از حالت هایی استفاده می کنید که نیستند\n", + "mod.join.prohibited.supportLine1":"در صورت نیاز به کمک بیشتر ، می توانید با تیم پشتیبانی ما تماس بگیرید\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/fi_fi.json b/common/src/main/resources/assets/eternalempires/lang/fi_fi.json new file mode 100644 index 0000000..e8ba635 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/fi_fi.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Ohjeemme vaikuttavat seuraaviin muutoksiin:", + "mod.join.prohibited.failed":"Yhteys epäonnistui", + "mod.join.prohibited.explanation":"Vaikuttaa siltä, ​​että käytät modit, jotka eivät ole\n", + "mod.join.prohibited.supportLine1":"Jos tarvitset lisäapua, voit ottaa yhteyttä tukitiimiin\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/fo_fo.json b/common/src/main/resources/assets/eternalempires/lang/fo_fo.json new file mode 100644 index 0000000..b47b5df --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/fo_fo.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Fylgjandi broytingar eru ávirkaðar av okkara leiðreglum:", + "mod.join.prohibited.failed":"Sambandið miseydnaðist", + "mod.join.prohibited.explanation":"Tað sær út til, at tú brúkar mods, sum ikki eru\n", + "mod.join.prohibited.supportLine1":"Um tú hevur tørv á fleiri hjálp, kanst tú seta teg í samband við okkara stuðulstoymi\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/fr_ca.json b/common/src/main/resources/assets/eternalempires/lang/fr_ca.json new file mode 100644 index 0000000..c4227c1 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/fr_ca.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Les modifications suivantes sont affectées par nos directives:", + "mod.join.prohibited.failed":"Échec de la connexion", + "mod.join.prohibited.explanation":"Il semble que vous utilisez des mods qui ne sont pas\n", + "mod.join.prohibited.supportLine1":"Si vous avez besoin d\u0027aide supplémentaire, vous pouvez contacter notre équipe d\u0027assistance\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/fr_ch.json b/common/src/main/resources/assets/eternalempires/lang/fr_ch.json new file mode 100644 index 0000000..c4227c1 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/fr_ch.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Les modifications suivantes sont affectées par nos directives:", + "mod.join.prohibited.failed":"Échec de la connexion", + "mod.join.prohibited.explanation":"Il semble que vous utilisez des mods qui ne sont pas\n", + "mod.join.prohibited.supportLine1":"Si vous avez besoin d\u0027aide supplémentaire, vous pouvez contacter notre équipe d\u0027assistance\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/fr_fr.json b/common/src/main/resources/assets/eternalempires/lang/fr_fr.json new file mode 100644 index 0000000..c4227c1 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/fr_fr.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Les modifications suivantes sont affectées par nos directives:", + "mod.join.prohibited.failed":"Échec de la connexion", + "mod.join.prohibited.explanation":"Il semble que vous utilisez des mods qui ne sont pas\n", + "mod.join.prohibited.supportLine1":"Si vous avez besoin d\u0027aide supplémentaire, vous pouvez contacter notre équipe d\u0027assistance\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ga_ie.json b/common/src/main/resources/assets/eternalempires/lang/ga_ie.json new file mode 100644 index 0000000..09f8c42 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ga_ie.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Bíonn tionchar ag ár dtreoirlínte ar na modhnuithe seo a leanas:", + "mod.join.prohibited.failed":"Theip ar nasc", + "mod.join.prohibited.explanation":"Dealraíonn sé go bhfuil mods á n -úsáid agat nach bhfuil\n", + "mod.join.prohibited.supportLine1":"Má theastaíonn tuilleadh cúnaimh uait, is féidir leat teagmháil a dhéanamh lenár bhfoireann tacaíochta\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/gd_gb.json b/common/src/main/resources/assets/eternalempires/lang/gd_gb.json new file mode 100644 index 0000000..1470a95 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/gd_gb.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Tha an stiùirichean againn a \u0027toirt buaidh air na h-atharrachaidhean a leanas:", + "mod.join.prohibited.failed":"Dh\u0027fhàillig ceangal", + "mod.join.prohibited.explanation":"Tha e coltach gu bheil thu a \u0027cleachdadh mhodhan nach eil\n", + "mod.join.prohibited.supportLine1":"Ma tha feum agad air tuilleadh cuideachaidh, faodaidh tu fios a chuir chun sgioba taic againn\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/gl_es.json b/common/src/main/resources/assets/eternalempires/lang/gl_es.json new file mode 100644 index 0000000..25d590b --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/gl_es.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"As nosas directrices afectan as seguintes modificacións:", + "mod.join.prohibited.failed":"Fallou a conexión", + "mod.join.prohibited.explanation":"Parece que está a usar mods que non o son\n", + "mod.join.prohibited.supportLine1":"Se necesitas máis axuda, podes contactar co noso equipo de asistencia\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/haw_us.json b/common/src/main/resources/assets/eternalempires/lang/haw_us.json new file mode 100644 index 0000000..6f01417 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/haw_us.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Hoʻopiliʻia nā loli e pili ana i kā mākou alakaʻi:", + "mod.join.prohibited.failed":"Ua pio ka pilina", + "mod.join.prohibited.explanation":"ʻIkeʻia e hoʻohana anaʻoe e hoʻohana ana i nā modsʻaʻole\n", + "mod.join.prohibited.supportLine1":"Inā makemakeʻoe i ke kōkua hou aku, hiki iāʻoe ke hoʻokaʻaʻike i kā mākou hui kākoʻo\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/he_il.json b/common/src/main/resources/assets/eternalempires/lang/he_il.json new file mode 100644 index 0000000..749dff0 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/he_il.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"השינויים הבאים מושפעים מההנחיות שלנו:", + "mod.join.prohibited.failed":"החיבור נכשל", + "mod.join.prohibited.explanation":"נראה שאתה משתמש במצבים שאינם\n", + "mod.join.prohibited.supportLine1":"אם אתה זקוק לסיוע נוסף, תוכל ליצור קשר עם צוות התמיכה שלנו\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/hi_in.json b/common/src/main/resources/assets/eternalempires/lang/hi_in.json new file mode 100644 index 0000000..2f9a379 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/hi_in.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"निम्नलिखित संशोधन हमारे दिशानिर्देशों से प्रभावित हैं:", + "mod.join.prohibited.failed":"कनेक्शन विफल", + "mod.join.prohibited.explanation":"ऐसा प्रतीत होता है कि आप उन मॉड्स का उपयोग कर रहे हैं जो नहीं हैं\n", + "mod.join.prohibited.supportLine1":"यदि आपको और सहायता की आवश्यकता है, तो आप हमारी सहायता टीम से संपर्क कर सकते हैं\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/hr_hr.json b/common/src/main/resources/assets/eternalempires/lang/hr_hr.json new file mode 100644 index 0000000..59b3293 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/hr_hr.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Sljedeće modifikacije utječu naše smjernice:", + "mod.join.prohibited.failed":"Veza nije uspjela", + "mod.join.prohibited.explanation":"Čini se da koristite modove koji nisu\n", + "mod.join.prohibited.supportLine1":"Ako vam je potrebna dodatna pomoć, možete se obratiti našem timu za podršku\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/hu_hu.json b/common/src/main/resources/assets/eternalempires/lang/hu_hu.json new file mode 100644 index 0000000..cf322ac --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/hu_hu.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"A következő módosításokat érinti iránymutatásaink:", + "mod.join.prohibited.failed":"A kapcsolat sikertelen", + "mod.join.prohibited.explanation":"Úgy tűnik, hogy olyan modokat használ, amelyek nem\n", + "mod.join.prohibited.supportLine1":"Ha további segítségre van szüksége, vegye fel a kapcsolatot a támogatási csapatunkkal\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/hy_am.json b/common/src/main/resources/assets/eternalempires/lang/hy_am.json new file mode 100644 index 0000000..77cf085 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/hy_am.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Հետեւյալ փոփոխությունները ազդում են մեր ուղեցույցներից.", + "mod.join.prohibited.failed":"Միացումը ձախողվեց", + "mod.join.prohibited.explanation":"Պարզվում է, որ դուք օգտագործում եք ռեժիմներ, որոնք չեն\n", + "mod.join.prohibited.supportLine1":"Եթե ​​Ձեզ անհրաժեշտ է հետագա օգնություն, կարող եք կապվել մեր աջակցության թիմին\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/id_id.json b/common/src/main/resources/assets/eternalempires/lang/id_id.json new file mode 100644 index 0000000..281b156 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/id_id.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Modifikasi berikut dipengaruhi oleh pedoman kami:", + "mod.join.prohibited.failed":"Koneksi gagal", + "mod.join.prohibited.explanation":"Tampaknya Anda menggunakan mod yang tidak\n", + "mod.join.prohibited.supportLine1":"Jika Anda memerlukan bantuan lebih lanjut, Anda dapat menghubungi tim dukungan kami\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ig_ng.json b/common/src/main/resources/assets/eternalempires/lang/ig_ng.json new file mode 100644 index 0000000..153b057 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ig_ng.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Ntụziaka anyị na-emetụta mgbanwe ndị a:", + "mod.join.prohibited.failed":"Njikọ kụrụ", + "mod.join.prohibited.explanation":"Ọ dị ka ị na-eji mods na-abụghị\n", + "mod.join.prohibited.supportLine1":"Ọ bụrụ na ịchọrọ enyemaka ọzọ, ịnwere ike ịkpọtụrụ ndị otu nkwado anyị\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/is_is.json b/common/src/main/resources/assets/eternalempires/lang/is_is.json new file mode 100644 index 0000000..5a3ad9e --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/is_is.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Eftirfarandi breytingar hafa áhrif á leiðbeiningar okkar:", + "mod.join.prohibited.failed":"Tenging mistókst", + "mod.join.prohibited.explanation":"Það virðist sem þú notar mods sem eru það ekki\n", + "mod.join.prohibited.supportLine1":"Ef þú þarft frekari aðstoð geturðu haft samband við stuðningsteymi okkar\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/it_it.json b/common/src/main/resources/assets/eternalempires/lang/it_it.json new file mode 100644 index 0000000..dd47ca5 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/it_it.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Le seguenti modifiche sono influenzate dalle nostre linee guida:", + "mod.join.prohibited.failed":"Connessione non riuscita", + "mod.join.prohibited.explanation":"Sembra che tu stia usando mod che non lo sono\n", + "mod.join.prohibited.supportLine1":"Se hai bisogno di ulteriore assistenza, puoi contattare il nostro team di supporto\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ja_jp.json b/common/src/main/resources/assets/eternalempires/lang/ja_jp.json new file mode 100644 index 0000000..fcb4be3 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ja_jp.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"次の変更は、ガイドラインの影響を受けます。", + "mod.join.prohibited.failed":"接続に失敗しました", + "mod.join.prohibited.explanation":"そうでないmodを使用しているようです\n", + "mod.join.prohibited.supportLine1":"さらにサポートが必要な場合は、サポートチームに連絡できます\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ka_ge.json b/common/src/main/resources/assets/eternalempires/lang/ka_ge.json new file mode 100644 index 0000000..508520d --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ka_ge.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"შემდეგ მოდიფიკაციებზე გავლენას ახდენს ჩვენი მითითებები:", + "mod.join.prohibited.failed":"კავშირი ვერ მოხერხდა", + "mod.join.prohibited.explanation":"როგორც ჩანს, თქვენ იყენებთ მოდებს, რომლებიც არ არიან\n", + "mod.join.prohibited.supportLine1":"თუ დამატებითი დახმარება გჭირდებათ, შეგიძლიათ დაუკავშირდეთ ჩვენს დამხმარე გუნდს\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/kk_kz.json b/common/src/main/resources/assets/eternalempires/lang/kk_kz.json new file mode 100644 index 0000000..602bac0 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/kk_kz.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Келесі түрлендірулерге біздің нұсқауларымыз әсер етеді:", + "mod.join.prohibited.failed":"Қосылу сәтсіз аяқталды", + "mod.join.prohibited.explanation":"Сіз жоқ модтерді қолданып жатқан сияқтысыз\n", + "mod.join.prohibited.supportLine1":"Егер сізге қосымша көмек қажет болса, сіз біздің қолдау тобымызбен байланыса аласыз\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/kn_in.json b/common/src/main/resources/assets/eternalempires/lang/kn_in.json new file mode 100644 index 0000000..3c5628a --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/kn_in.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"ನಮ್ಮ ಮಾರ್ಗಸೂಚಿಗಳಿಂದ ಈ ಕೆಳಗಿನ ಮಾರ್ಪಾಡುಗಳು ಪರಿಣಾಮ ಬೀರುತ್ತವೆ:", + "mod.join.prohibited.failed":"ಸಂಪರ್ಕ ವಿಫಲವಾಗಿದೆ", + "mod.join.prohibited.explanation":"ನೀವು ಇಲ್ಲದ ಮೋಡ್‌ಗಳನ್ನು ಬಳಸುತ್ತಿರುವಿರಿ ಎಂದು ತೋರುತ್ತದೆ\n", + "mod.join.prohibited.supportLine1":"ನಿಮಗೆ ಹೆಚ್ಚಿನ ಸಹಾಯ ಬೇಕಾದರೆ, ನೀವು ನಮ್ಮ ಬೆಂಬಲ ತಂಡವನ್ನು ಸಂಪರ್ಕಿಸಬಹುದು\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ko_kr.json b/common/src/main/resources/assets/eternalempires/lang/ko_kr.json new file mode 100644 index 0000000..a83c5df --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ko_kr.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"다음 수정은 지침의 영향을받습니다.", + "mod.join.prohibited.failed":"연결이 실패했습니다", + "mod.join.prohibited.explanation":"그렇지 않은 모드를 사용하는 것 같습니다.\n", + "mod.join.prohibited.supportLine1":"추가 지원이 필요한 경우 지원 팀에 문의하십시오.\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/la_la.json b/common/src/main/resources/assets/eternalempires/lang/la_la.json new file mode 100644 index 0000000..b00c81b --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/la_la.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"In his modificationes sunt affectus a nostris guidelines:", + "mod.join.prohibited.failed":"Connection defuit", + "mod.join.prohibited.explanation":"Videtur quod vos es usura mods qui non sunt\n", + "mod.join.prohibited.supportLine1":"Si opus adhuc auxilium, vos can contact noster firmamentum quadrigis\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/lb_lu.json b/common/src/main/resources/assets/eternalempires/lang/lb_lu.json new file mode 100644 index 0000000..1b91fe6 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/lb_lu.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Déi folgend Ännerunge ginn vun eise Richtlinnen betraff:", + "mod.join.prohibited.failed":"Verbindung net gescheitert", + "mod.join.prohibited.explanation":"Et schéngt datt Dir Mods benotzt, déi net sinn\n", + "mod.join.prohibited.supportLine1":"Wann Dir weider Hëllef braucht, kënnt Dir eis Support Team kontaktéieren\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/lt_lt.json b/common/src/main/resources/assets/eternalempires/lang/lt_lt.json new file mode 100644 index 0000000..dbb1315 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/lt_lt.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Mūsų gairės turi įtakos šiems modifikacijoms:", + "mod.join.prohibited.failed":"Ryšys nepavyko", + "mod.join.prohibited.explanation":"Atrodo, kad naudojate modus, kurie nėra\n", + "mod.join.prohibited.supportLine1":"Jei jums reikia papildomos pagalbos, galite susisiekti su mūsų palaikymo komanda\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/lv_lv.json b/common/src/main/resources/assets/eternalempires/lang/lv_lv.json new file mode 100644 index 0000000..06f744e --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/lv_lv.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Mūsu vadlīnijas ietekmē šādas modifikācijas:", + "mod.join.prohibited.failed":"Savienojums neizdevās", + "mod.join.prohibited.explanation":"Šķiet, ka jūs izmantojat modus, kas nav\n", + "mod.join.prohibited.supportLine1":"Ja jums nepieciešama papildu palīdzība, varat sazināties ar mūsu atbalsta komandu\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/mk_mk.json b/common/src/main/resources/assets/eternalempires/lang/mk_mk.json new file mode 100644 index 0000000..3d4a659 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/mk_mk.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Следниве измени се под влијание на нашите упатства:", + "mod.join.prohibited.failed":"Врската не успеа", + "mod.join.prohibited.explanation":"Се чини дека користите режими што не се\n", + "mod.join.prohibited.supportLine1":"Ако ви треба дополнителна помош, можете да контактирате со нашиот тим за поддршка\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/mn_mn.json b/common/src/main/resources/assets/eternalempires/lang/mn_mn.json new file mode 100644 index 0000000..a70cefa --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/mn_mn.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Дараах өөрчлөлтүүд бидний удирдамжид нөлөөлдөг.", + "mod.join.prohibited.failed":"Холболт амжилтгүй болсон", + "mod.join.prohibited.explanation":"Энэ нь та биш горимыг ашиглаж байгаа бололтой\n", + "mod.join.prohibited.supportLine1":"Хэрэв танд нэмэлт тусламж хэрэгтэй бол та манай дэмжлэг авах багтай холбоо барьж болно\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ms_my.json b/common/src/main/resources/assets/eternalempires/lang/ms_my.json new file mode 100644 index 0000000..1b220f5 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ms_my.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Pengubahsuaian berikut dipengaruhi oleh garis panduan kami:", + "mod.join.prohibited.failed":"Sambungan gagal", + "mod.join.prohibited.explanation":"Nampaknya anda menggunakan mod yang tidak\n", + "mod.join.prohibited.supportLine1":"Sekiranya anda memerlukan bantuan lanjut, anda boleh menghubungi pasukan sokongan kami\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/mt_mt.json b/common/src/main/resources/assets/eternalempires/lang/mt_mt.json new file mode 100644 index 0000000..4557378 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/mt_mt.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Il-modifiki li ġejjin huma affettwati mil-linji gwida tagħna:", + "mod.join.prohibited.failed":"Il-konnessjoni falliet", + "mod.join.prohibited.explanation":"Jidher li qed tuża mods li mhumiex\n", + "mod.join.prohibited.supportLine1":"Jekk għandek bżonn aktar għajnuna, tista \u0027tikkuntattja lit-tim ta\u0027 appoġġ tagħna\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/nl_nl.json b/common/src/main/resources/assets/eternalempires/lang/nl_nl.json new file mode 100644 index 0000000..28e1b80 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/nl_nl.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"De volgende wijzigingen worden beïnvloed door onze richtlijnen:", + "mod.join.prohibited.failed":"Verbinding mislukt", + "mod.join.prohibited.explanation":"Het lijkt erop dat u mods gebruikt die dat niet zijn\n", + "mod.join.prohibited.supportLine1":"Als u verdere hulp nodig hebt, kunt u contact opnemen met ons ondersteuningsteam\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/nn_no.json b/common/src/main/resources/assets/eternalempires/lang/nn_no.json new file mode 100644 index 0000000..7748685 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/nn_no.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"The following modifications are affected by our guidelines:", + "mod.join.prohibited.failed":"Connection failed", + "mod.join.prohibited.explanation":"It appears that you are using mods that are not\npermitted on Eternal Empires. We kindly request that you review\nyour mod list and remove these modifications from the game.", + "mod.join.prohibited.supportLine1":"If you need further assistance, you can contact our support team\nat any time at "} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/no_no.json b/common/src/main/resources/assets/eternalempires/lang/no_no.json new file mode 100644 index 0000000..bdf673f --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/no_no.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Følgende modifikasjoner påvirkes av retningslinjene våre:", + "mod.join.prohibited.failed":"Tilkoblingen mislyktes", + "mod.join.prohibited.explanation":"Det ser ut til at du bruker mods som ikke er det\n", + "mod.join.prohibited.supportLine1":"Hvis du trenger ytterligere hjelp, kan du kontakte vårt supportteam\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/pl_pl.json b/common/src/main/resources/assets/eternalempires/lang/pl_pl.json new file mode 100644 index 0000000..dabaa4b --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/pl_pl.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Nasze wytyczne mają wpływ na następujące modyfikacje:", + "mod.join.prohibited.failed":"Połączenie nie powiodło się", + "mod.join.prohibited.explanation":"Wygląda na to, że używasz modów, które nie są\n", + "mod.join.prohibited.supportLine1":"Jeśli potrzebujesz dalszej pomocy, możesz skontaktować się z naszym zespołem wsparcia\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/pt_br.json b/common/src/main/resources/assets/eternalempires/lang/pt_br.json new file mode 100644 index 0000000..0e4bbd0 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/pt_br.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"As seguintes modificações são afetadas por nossas diretrizes:", + "mod.join.prohibited.failed":"A conexão falhou", + "mod.join.prohibited.explanation":"Parece que você está usando mods que não são\n", + "mod.join.prohibited.supportLine1":"Se você precisar de mais assistência, entre em contato com nossa equipe de suporte\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/pt_pt.json b/common/src/main/resources/assets/eternalempires/lang/pt_pt.json new file mode 100644 index 0000000..0e4bbd0 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/pt_pt.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"As seguintes modificações são afetadas por nossas diretrizes:", + "mod.join.prohibited.failed":"A conexão falhou", + "mod.join.prohibited.explanation":"Parece que você está usando mods que não são\n", + "mod.join.prohibited.supportLine1":"Se você precisar de mais assistência, entre em contato com nossa equipe de suporte\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ro_ro.json b/common/src/main/resources/assets/eternalempires/lang/ro_ro.json new file mode 100644 index 0000000..eb91c26 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ro_ro.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Următoarele modificări sunt afectate de orientările noastre:", + "mod.join.prohibited.failed":"Conexiunea a eșuat", + "mod.join.prohibited.explanation":"Se pare că utilizați moduri care nu sunt\n", + "mod.join.prohibited.supportLine1":"Dacă aveți nevoie de asistență suplimentară, puteți contacta echipa noastră de asistență\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ru_ru.json b/common/src/main/resources/assets/eternalempires/lang/ru_ru.json new file mode 100644 index 0000000..e02f36d --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ru_ru.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Наши руководящие принципы влияют на следующие модификации:", + "mod.join.prohibited.failed":"Соединение не удалось", + "mod.join.prohibited.explanation":"Похоже, что вы используете моды, которые не\n", + "mod.join.prohibited.supportLine1":"Если вам нужна дополнительная помощь, вы можете связаться с нашей командой поддержки\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/sk_sk.json b/common/src/main/resources/assets/eternalempires/lang/sk_sk.json new file mode 100644 index 0000000..10a6665 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/sk_sk.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Našimi pokynmi sú ovplyvnené nasledujúce úpravy:", + "mod.join.prohibited.failed":"Spojenie zlyhalo", + "mod.join.prohibited.explanation":"Zdá sa, že používate mody, ktoré nie sú\n", + "mod.join.prohibited.supportLine1":"Ak potrebujete ďalšiu pomoc, môžete kontaktovať náš podporný tím\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/sl_si.json b/common/src/main/resources/assets/eternalempires/lang/sl_si.json new file mode 100644 index 0000000..5d46e68 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/sl_si.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Na naslednje spremembe vplivajo naše smernice:", + "mod.join.prohibited.failed":"Povezava ni uspela", + "mod.join.prohibited.explanation":"Kaže, da uporabljate mode, ki niso\n", + "mod.join.prohibited.supportLine1":"Če potrebujete dodatno pomoč, se lahko obrnete na našo podporno skupino\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/sq_al.json b/common/src/main/resources/assets/eternalempires/lang/sq_al.json new file mode 100644 index 0000000..a3ddda0 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/sq_al.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Ndryshimet e mëposhtme preken nga udhëzimet tona:", + "mod.join.prohibited.failed":"Lidhja dështoi", + "mod.join.prohibited.explanation":"Duket se ju jeni duke përdorur mods që nuk janë\n", + "mod.join.prohibited.supportLine1":"Nëse keni nevojë për ndihmë të mëtejshme, mund të kontaktoni ekipin tonë mbështetës\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/sr_sp.json b/common/src/main/resources/assets/eternalempires/lang/sr_sp.json new file mode 100644 index 0000000..cea6957 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/sr_sp.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Следеће модификације утичу на наше смернице:", + "mod.join.prohibited.failed":"Веза није успела", + "mod.join.prohibited.explanation":"Изгледа да користите модс који нису\n", + "mod.join.prohibited.supportLine1":"Ако вам је потребна додатна помоћ, можете се обратити нашем тиму за подршку\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/sr_sp_latn.json b/common/src/main/resources/assets/eternalempires/lang/sr_sp_latn.json new file mode 100644 index 0000000..cea6957 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/sr_sp_latn.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Следеће модификације утичу на наше смернице:", + "mod.join.prohibited.failed":"Веза није успела", + "mod.join.prohibited.explanation":"Изгледа да користите модс који нису\n", + "mod.join.prohibited.supportLine1":"Ако вам је потребна додатна помоћ, можете се обратити нашем тиму за подршку\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/sv_se.json b/common/src/main/resources/assets/eternalempires/lang/sv_se.json new file mode 100644 index 0000000..7921488 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/sv_se.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Följande ändringar påverkas av våra riktlinjer:", + "mod.join.prohibited.failed":"Anslutningen misslyckades", + "mod.join.prohibited.explanation":"Det verkar som om du använder mods som inte är det\n", + "mod.join.prohibited.supportLine1":"Om du behöver ytterligare hjälp kan du kontakta vårt supportteam\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/ta_in.json b/common/src/main/resources/assets/eternalempires/lang/ta_in.json new file mode 100644 index 0000000..88b9c83 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/ta_in.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"எங்கள் வழிகாட்டுதல்களால் பின்வரும் மாற்றங்கள் பாதிக்கப்படுகின்றன:", + "mod.join.prohibited.failed":"இணைப்பு தோல்வியடைந்தது", + "mod.join.prohibited.explanation":"நீங்கள் இல்லாத மோட்ஸைப் பயன்படுத்துகிறீர்கள் என்று தோன்றுகிறது\n", + "mod.join.prohibited.supportLine1":"உங்களுக்கு மேலும் உதவி தேவைப்பட்டால், நீங்கள் எங்கள் ஆதரவு குழுவை தொடர்பு கொள்ளலாம்\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/th_th.json b/common/src/main/resources/assets/eternalempires/lang/th_th.json new file mode 100644 index 0000000..c0116dd --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/th_th.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"การแก้ไขต่อไปนี้ได้รับผลกระทบจากแนวทางของเรา:", + "mod.join.prohibited.failed":"การเชื่อมต่อล้มเหลว", + "mod.join.prohibited.explanation":"ดูเหมือนว่าคุณกำลังใช้ mods ที่ไม่ได้\n", + "mod.join.prohibited.supportLine1":"หากคุณต้องการความช่วยเหลือเพิ่มเติมคุณสามารถติดต่อทีมสนับสนุนของเรา\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/tr_tr.json b/common/src/main/resources/assets/eternalempires/lang/tr_tr.json new file mode 100644 index 0000000..082440c --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/tr_tr.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Aşağıdaki değişiklikler yönergelerimizden etkilenmektedir:", + "mod.join.prohibited.failed":"Bağlantı başarısız oldu", + "mod.join.prohibited.explanation":"Görünüşe göre olmayan modlar kullanıyorsunuz\n", + "mod.join.prohibited.supportLine1":"Daha fazla yardıma ihtiyacınız varsa, destek ekibimizle iletişime geçebilirsiniz.\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/uk_ua.json b/common/src/main/resources/assets/eternalempires/lang/uk_ua.json new file mode 100644 index 0000000..104df96 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/uk_ua.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"На наші вказівки впливають такі модифікації:", + "mod.join.prohibited.failed":"Не вдалося з\u0027єднання", + "mod.join.prohibited.explanation":"Здається, ви використовуєте моди, які не є\n", + "mod.join.prohibited.supportLine1":"Якщо вам потрібна додаткова допомога, ви можете зв’язатися з нашою командою підтримки\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/vi_vn.json b/common/src/main/resources/assets/eternalempires/lang/vi_vn.json new file mode 100644 index 0000000..2982825 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/vi_vn.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Các sửa đổi sau đây bị ảnh hưởng bởi các hướng dẫn của chúng tôi:", + "mod.join.prohibited.failed":"Kết nối không thành công", + "mod.join.prohibited.explanation":"Có vẻ như bạn đang sử dụng các mod không\n", + "mod.join.prohibited.supportLine1":"Nếu bạn cần hỗ trợ thêm, bạn có thể liên hệ với nhóm hỗ trợ của chúng tôi\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/yi_de.json b/common/src/main/resources/assets/eternalempires/lang/yi_de.json new file mode 100644 index 0000000..5f2909a --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/yi_de.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"די ווייַטערדיק מאַדאַפאַקיישאַנז זענען אַפעקטאַד דורך אונדזער גיידליינז:", + "mod.join.prohibited.failed":"קאַנעקשאַן ניט אַנדערש", + "mod.join.prohibited.explanation":"עס אויס אַז איר נוצן מאָדס וואָס זענען נישט\n", + "mod.join.prohibited.supportLine1":"אויב איר דאַרפֿן ווייַטער הילף, איר קענט קאָנטאַקט אונדזער שטיצן מאַנשאַפֿט\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/yo_ng.json b/common/src/main/resources/assets/eternalempires/lang/yo_ng.json new file mode 100644 index 0000000..a625422 --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/yo_ng.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"Awọn iyipada wọnyi ni o kan nipasẹ awọn itọsọna wa:", + "mod.join.prohibited.failed":"Asopọ kuna", + "mod.join.prohibited.explanation":"O han pe o nlo awọn Mods ti kii ṣe\n", + "mod.join.prohibited.supportLine1":"Ti o ba nilo iranlọwọ siwaju, o le kan si ẹgbẹ atilẹyin wa\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/zh_cn.json b/common/src/main/resources/assets/eternalempires/lang/zh_cn.json new file mode 100644 index 0000000..555c24e --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/zh_cn.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"以下修改受我们的准则影响:", + "mod.join.prohibited.failed":"连接失败", + "mod.join.prohibited.explanation":"看来您正在使用不使用的mod\n", + "mod.join.prohibited.supportLine1":"如果您需要进一步的帮助,可以联系我们的支持团队\n"} \ No newline at end of file diff --git a/common/src/main/resources/assets/eternalempires/lang/zh_tw.json b/common/src/main/resources/assets/eternalempires/lang/zh_tw.json new file mode 100644 index 0000000..555c24e --- /dev/null +++ b/common/src/main/resources/assets/eternalempires/lang/zh_tw.json @@ -0,0 +1,5 @@ +{ + "mod.join.prohibited.modsHeader":"以下修改受我们的准则影响:", + "mod.join.prohibited.failed":"连接失败", + "mod.join.prohibited.explanation":"看来您正在使用不使用的mod\n", + "mod.join.prohibited.supportLine1":"如果您需要进一步的帮助,可以联系我们的支持团队\n"} \ No newline at end of file From a955db56970d59a6aded8c17d46cba0241df2ca4 Mon Sep 17 00:00:00 2001 From: Sameer Date: Sat, 13 Sep 2025 01:05:31 +0500 Subject: [PATCH 14/14] chore: apply license headers, nullability annotations, and final modifiers --- .../AbstractEternalEmpiresPayload.java | 12 +- .../network/packet/ModCheckPayload.java | 85 +++++++++++-- .../util/modlistcheck/IModListProvider.java | 56 ++++++++- .../util/modlistcheck/ModCheckHandler.java | 112 ++++++++++++++---- .../fabric/client/FabricModListProvider.java | 67 ++++++++++- .../forge/client/ForgeModListProvider.java | 67 ++++++++++- .../client/NeoForgeModListProvider.java | 67 ++++++++++- 7 files changed, 412 insertions(+), 54 deletions(-) diff --git a/common/src/main/java/net/eternalempires/mod/common/network/AbstractEternalEmpiresPayload.java b/common/src/main/java/net/eternalempires/mod/common/network/AbstractEternalEmpiresPayload.java index 05ea833..07ae335 100644 --- a/common/src/main/java/net/eternalempires/mod/common/network/AbstractEternalEmpiresPayload.java +++ b/common/src/main/java/net/eternalempires/mod/common/network/AbstractEternalEmpiresPayload.java @@ -167,6 +167,14 @@ protected String extractJsonField(final @NotNull String fieldName) { */ public void handlePayload(@NotNull RichPresenceService service) {}; - //Parameter-less handlePayload() for ModCheckPayload - public void handlePayload() {}; + /** + * Handles the payload without requiring any external service dependencies. + * This variant exists to support subclasses such as + * {@link net.eternalempires.mod.common.network.packet.ModCheckPayload}, + * which perform their own internal processing without relying on + * {@link net.eternalempires.mod.common.util.discord.RichPresenceService}. + * Default implementation is a no-op; subclasses should override to provide + * concrete handling logic. + */ + public void handlePayload() {} } diff --git a/common/src/main/java/net/eternalempires/mod/common/network/packet/ModCheckPayload.java b/common/src/main/java/net/eternalempires/mod/common/network/packet/ModCheckPayload.java index eb8f55b..5807704 100644 --- a/common/src/main/java/net/eternalempires/mod/common/network/packet/ModCheckPayload.java +++ b/common/src/main/java/net/eternalempires/mod/common/network/packet/ModCheckPayload.java @@ -1,3 +1,27 @@ +/* + * MIT License + * + * Copyright (c) 2025 EternalEmpires.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *s + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package net.eternalempires.mod.common.network.packet; import io.netty.buffer.ByteBuf; @@ -15,13 +39,23 @@ import java.util.ArrayList; import java.util.List; +/** + * This is effectively a custom-payload-packet that is sent from the minecraft server through the plugin-message-channel. + * This packet that gets send to the client upon joining so client can validate present mods. + * It's data will be (de)serialized as json and transferred byte-wise. + * + * @see AbstractEternalEmpiresPayload + * + * @since 09/07/2025 + * @author EternalEmpires + */ @Slf4j public class ModCheckPayload extends AbstractEternalEmpiresPayload { - public static final CustomPacketPayload.Type TYPE = + public static final @NotNull CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "modcheck")); - public static final StreamCodec BYTEBUF_CODEC = + public static final @NotNull StreamCodec BYTEBUF_CODEC = StreamCodec.of((buf, value) -> buf.writeBytes(value.data), buf -> { final byte[] data = new byte[buf.readableBytes()]; @@ -29,7 +63,7 @@ public class ModCheckPayload extends AbstractEternalEmpiresPayload { return new ModCheckPayload(data); }); - public static final StreamCodec FORGE_CODEC = + public static final @NotNull StreamCodec FORGE_CODEC = StreamCodec.of( (buf, packet) -> buf.writeBytes(packet.data), buf -> { @@ -39,7 +73,7 @@ public class ModCheckPayload extends AbstractEternalEmpiresPayload { } ); - public static final StreamCodec FABRIC_CODEC = + public static final @NotNull StreamCodec FABRIC_CODEC = StreamCodec.of((buf, value) -> buf.writeBytes(value.data), buf -> { final byte[] data = new byte[buf.readableBytes()]; @@ -47,20 +81,47 @@ public class ModCheckPayload extends AbstractEternalEmpiresPayload { return new ModCheckPayload(data); }); - public ModCheckPayload(FriendlyByteBuf buffer) { + /** + * Constructs a new payload by reading all remaining bytes + * from the provided {@link FriendlyByteBuf}. + * + * @param buffer the buffer containing the raw packet data + */ + public ModCheckPayload(@NotNull FriendlyByteBuf buffer) { super(buffer); } - public ModCheckPayload(byte[] data) { + /** + * Constructs a new payload from a raw byte array. + * + * @param data the raw packet data + */ + public ModCheckPayload(byte @NotNull [] data) { super(data); } + /** + * Returns the unique type identifier for this custom payload. + * Used by Minecraft’s networking system to distinguish packet types. + * + * @return the {@link Type} of this payload + */ @Override public @NotNull Type type() { return TYPE; } - private List extractModIds() { + /** + * Extracts a list of mod IDs from the JSON data contained in this payload. + *

+ * Looks for a {@code "modIds"} array inside the {@code "data"} object. + * If found, the array is parsed into a list of trimmed strings. + *

+ * In case of malformed JSON or unexpected structure, an empty list is returned. + * + * @return a list of mod IDs provided by the server + */ + private @NotNull List extractModIds() { try { List modIds = new ArrayList<>(); @@ -94,6 +155,16 @@ private List extractModIds() { } } + /** + * Processes this payload on the client. + *

+ * Specifically, it checks whether the payload type matches + * {@code "prohibited_mod_ids"}. If so, it extracts the mod IDs and + * delegates validation to {@link ModCheckHandler}. + *

+ * Logs the JSON, handles empty or malformed cases, and ensures the + * client is disconnected if disallowed mods are detected. + */ @Override public void handlePayload() { log.info("[EternalEmpires] Received JSON: {}", json); diff --git a/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/IModListProvider.java b/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/IModListProvider.java index c54993f..1de1f73 100644 --- a/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/IModListProvider.java +++ b/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/IModListProvider.java @@ -1,14 +1,62 @@ +/* + * MIT License + * + * Copyright (c) 2025 EternalEmpires.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *s + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package net.eternalempires.mod.common.util.modlistcheck; +import org.jetbrains.annotations.NotNull; + import java.util.Map; import java.util.Set; + +/** + * Abstraction for retrieving information about installed mods on the client. + * Each supported mod loader (e.g., Fabric, Forge, NeoForge) must provide its + * own implementation of this interface so that {@link ModCheckHandler} can + * query the installed mods in a loader-agnostic way. + * Implementations are expected to return both the set of installed mod IDs and + * a mapping from mod ID to a user-friendly display name. + * + * @see ModCheckHandler + * + * @since 09/07/2025 + * @author EternalEmpires + */ public interface IModListProvider { - Set getInstalledModIds(); /** - * Gets a map of mod ID to mod name for all installed mods - * @return Map where key is mod ID and value is mod display name + * Gets the set of installed mod IDs on the client. + * + * @return a non-null set of mod IDs (may be empty, but never null) + */ + @NotNull Set<@NotNull String> getInstalledModIds(); + + /** + * Gets a map of mod ID to mod display name for all installed mods. + * + * @return a non-null map where keys are non-null mod IDs and values are + * non-null display names (may be empty, but never null) */ - Map getModIdToNameMap(); + @NotNull Map<@NotNull String, @NotNull String> getModIdToNameMap(); } \ No newline at end of file diff --git a/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/ModCheckHandler.java b/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/ModCheckHandler.java index 2815abb..7b75a67 100644 --- a/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/ModCheckHandler.java +++ b/common/src/main/java/net/eternalempires/mod/common/util/modlistcheck/ModCheckHandler.java @@ -1,3 +1,27 @@ +/* + * MIT License + * + * Copyright (c) 2025 EternalEmpires.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *s + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package net.eternalempires.mod.common.util.modlistcheck; import lombok.Setter; @@ -6,6 +30,7 @@ import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Style; +import org.jetbrains.annotations.NotNull; import java.net.URI; import java.util.List; @@ -13,6 +38,23 @@ import java.util.Set; import java.util.stream.Collectors; +/** + * Central handler responsible for verifying client-installed mods against + * a server-provided disallowed list. + * This class delegates to a loader-specific {@link IModListProvider} (set + * during each loader’s initialization) to gather the installed mods. It then + * compares the results to the server’s prohibited list and disconnects the + * player if any matches are found. + * On violation, the handler constructs a styled, localized disconnect screen + * detailing which mods caused the rejection and providing a support URL for + * further guidance. + * + * @see IModListProvider + * @see net.eternalempires.mod.common.network.packet.ModCheckPayload + * + * @since 09/07/2025 + * @author EternalEmpires + */ @Slf4j public class ModCheckHandler { @@ -23,16 +65,31 @@ public class ModCheckHandler { @Setter private static IModListProvider modListProvider; - public static void performModCheck(List serverDisallowedMods) { + /** + * Performs a client-side check against a list of server-provided + * disallowed mod IDs. + *

+ * This method queries the loader-specific {@link IModListProvider} + * for installed mods, compares them against the prohibited list + * sent by the server, and takes appropriate action: + *

    + *
  • If no disallowed mods are found, the connection proceeds normally.
  • + *
  • If one or more disallowed mods are detected, the client is + * disconnected with a styled error message.
  • + *
+ * + * @param serverDisallowedMods the list of mod IDs the server has prohibited + */ + public static void performModCheck(@NotNull final List serverDisallowedMods) { if (modListProvider == null) { log.warn("[EternalEmpires] No mod list provider set! Cannot perform mod check."); return; } - Set installedMods = modListProvider.getInstalledModIds(); + final Set installedMods = modListProvider.getInstalledModIds(); log.info("[EternalEmpires] Client installed mods: {}", installedMods); - List foundDisallowedMods = serverDisallowedMods.stream() + final List foundDisallowedMods = serverDisallowedMods.stream() .filter(installedMods::contains) .collect(Collectors.toList()); @@ -44,43 +101,57 @@ public static void performModCheck(List serverDisallowedMods) { } } - private static void disconnectWithModError(List foundModIds) { + /** + * Disconnects the client with a custom error screen when one or more + * prohibited mods are detected. + *

+ * The disconnect message includes: + *

    + *
  • Server branding/title
  • + *
  • A localized failure explanation
  • + *
  • The list of offending mods by display name
  • + *
  • A clickable support URL for further guidance
  • + *
+ * + * @param foundModIds the IDs of prohibited mods detected on the client + */ + private static void disconnectWithModError(@NotNull final List foundModIds) { log.info("[EternalEmpires] Disconnecting player due to disallowed mods: {}", foundModIds); - Map modIdToNameMap = modListProvider.getModIdToNameMap(); + final Map modIdToNameMap = modListProvider.getModIdToNameMap(); - Component title = Component.literal("Eternal Empires MMORPG") + final Component title = Component.literal("Eternal Empires MMORPG") .setStyle(Style.EMPTY.withColor(0xFF5555).withBold(true)); - Component failed = Component.translatable("mod.join.prohibited.failed") + final Component failed = Component.translatable("mod.join.prohibited.failed") .setStyle(Style.EMPTY.withColor(0xFF5555)); - Component explanation = Component.translatable( + final Component explanation = Component.translatable( "mod.join.prohibited.explanation" ).setStyle(Style.EMPTY.withColor(0xAAAAAA)); - String modsJoined = foundModIds.stream() + final String modsJoined = foundModIds.stream() .map(id -> modIdToNameMap.getOrDefault(id, id)) .collect(Collectors.joining(", ")); - Component modsHeader = Component.translatable("mod.join.prohibited.modsHeader") + final Component modsHeader = Component.translatable("mod.join.prohibited.modsHeader") .setStyle(Style.EMPTY.withColor(0xFF5555)); - Component modsList = Component.literal(modsJoined) + final Component modsList = Component.literal(modsJoined) .setStyle(Style.EMPTY.withColor(0xAAAAAA)); - Component supportLine1 = Component.translatable( + final Component supportLine1 = Component.translatable( "mod.join.prohibited.supportLine1" ).setStyle(Style.EMPTY.withColor(0xAAAAAA)); - Component supportUrl = Component.literal("https://eternalempires.link/0c942d") + final Component supportUrl = Component.literal("https://eternalempires.link/0c942d") .setStyle(Style.EMPTY .withColor(0xFF5555) // red .withUnderlined(true) // underline so it looks clickable .withClickEvent(new ClickEvent.OpenUrl(URI.create("https://eternalempires.link/0c942d"))) ); - Component disconnectReason = Component.empty() + final Component disconnectReason = Component.empty() .append(title).append("\n") .append(failed).append("\n\n") .append(explanation).append("\n\n") @@ -88,20 +159,9 @@ private static void disconnectWithModError(List foundModIds) { .append(modsList).append("\n\n") .append(supportLine1).append(supportUrl); - Minecraft minecraft = Minecraft.getInstance(); + final Minecraft minecraft = Minecraft.getInstance(); if (minecraft.getConnection() != null) { minecraft.getConnection().getConnection().disconnect(disconnectReason); } -/* - minecraft.execute(() -> { - minecraft.setScreen(new DisconnectedScreen( - new TitleScreen(), - Component.literal("Disconnected"), - disconnectReason - )); - }); - - - */ } } \ No newline at end of file diff --git a/fabric/src/main/java/net/eternalempires/mod/fabric/client/FabricModListProvider.java b/fabric/src/main/java/net/eternalempires/mod/fabric/client/FabricModListProvider.java index 2f56d2a..ffc74af 100644 --- a/fabric/src/main/java/net/eternalempires/mod/fabric/client/FabricModListProvider.java +++ b/fabric/src/main/java/net/eternalempires/mod/fabric/client/FabricModListProvider.java @@ -1,30 +1,87 @@ +/* + * MIT License + * + * Copyright (c) 2025 EternalEmpires.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *s + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package net.eternalempires.mod.fabric.client; import net.eternalempires.mod.common.util.modlistcheck.IModListProvider; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; +import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +/** + * Fabric-specific implementation of {@link IModListProvider}. + * Uses the {@link FabricLoader} API to query all mods visible to the + * Fabric client runtime. Provides both the set of installed mod IDs + * and a mapping of mod IDs to their display names. + * This implementation is registered by the Fabric loader during + * client initialization so that {@link net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler} + * can perform server-side mod validation. + * + * @see IModListProvider + * @see net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler + * + * @since 09/07/2025 + * @author EternalEmpires + */ public class FabricModListProvider implements IModListProvider { + /** + * Retrieves the set of all installed mod IDs visible to the Fabric client. + *

+ * This implementation queries the {@link FabricLoader} runtime and collects + * the {@code id} from each discovered {@link ModContainer}. + * + * @return a set containing the IDs of all installed mods + */ @Override - public Set getInstalledModIds() { + public @NotNull Set getInstalledModIds() { return FabricLoader.getInstance().getAllMods().stream() .map(modContainer -> modContainer.getMetadata().getId()) .collect(Collectors.toSet()); } + /** + * Builds a mapping of installed mod IDs to their corresponding display names. + *

+ * This method iterates over all {@link ModContainer} instances reported by + * {@link FabricLoader}, extracting both the {@code id} and {@code name} + * from each mod’s metadata. + * + * @return a map where keys are mod IDs and values are their human-readable names + */ @Override - public Map getModIdToNameMap() { - Map modIdToNameMap = new HashMap<>(); + public @NotNull Map getModIdToNameMap() { + final Map modIdToNameMap = new HashMap<>(); for (ModContainer modContainer : FabricLoader.getInstance().getAllMods()) { - String modId = modContainer.getMetadata().getId(); - String modName = modContainer.getMetadata().getName(); + final String modId = modContainer.getMetadata().getId(); + final String modName = modContainer.getMetadata().getName(); modIdToNameMap.put(modId, modName); } diff --git a/forge/src/main/java/net/eternalempires/mod/forge/client/ForgeModListProvider.java b/forge/src/main/java/net/eternalempires/mod/forge/client/ForgeModListProvider.java index cd88ad4..6d99b07 100644 --- a/forge/src/main/java/net/eternalempires/mod/forge/client/ForgeModListProvider.java +++ b/forge/src/main/java/net/eternalempires/mod/forge/client/ForgeModListProvider.java @@ -1,30 +1,87 @@ +/* + * MIT License + * + * Copyright (c) 2025 EternalEmpires.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *s + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package net.eternalempires.mod.forge.client; import net.eternalempires.mod.common.util.modlistcheck.IModListProvider; import net.minecraftforge.fml.ModList; import net.minecraftforge.forgespi.language.IModInfo; +import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; + +/** + * Forge-specific implementation of {@link IModListProvider}. + * Uses the {@link ModList} API provided by Forge to query all mods + * visible to the client runtime. Supplies both the set of installed + * mod IDs and a mapping of mod IDs to their display names. + * This implementation is registered during Forge client initialization + * so that {@link net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler} + * can enforce server-defined mod restrictions. + * @see IModListProvider + * @see net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler + * + * @since 09/07/2025 + * @author EternalEmpires + */ public class ForgeModListProvider implements IModListProvider { + /** + * Retrieves the set of all installed mod IDs visible to the Forge client. + *

+ * This implementation queries the {@link ModList} provided by Forge and + * collects the {@code modId} from each {@link IModInfo}. + * + * @return a set containing the IDs of all installed mods + */ @Override - public Set getInstalledModIds() { + public @NotNull Set getInstalledModIds() { return ModList.get().getMods().stream() .map(IModInfo::getModId) .collect(Collectors.toSet()); } + /** + * Builds a mapping of installed mod IDs to their corresponding display names. + *

+ * This method iterates over all {@link IModInfo} entries reported by + * {@link ModList}, extracting both the {@code modId} and the human-readable + * {@code displayName} for each mod. + * + * @return a map where keys are mod IDs and values are their display names + */ @Override - public Map getModIdToNameMap() { - Map modIdToNameMap = new HashMap<>(); + public @NotNull Map getModIdToNameMap() { + final Map modIdToNameMap = new HashMap<>(); for (IModInfo modInfo : ModList.get().getMods()) { - String modId = modInfo.getModId(); - String modName = modInfo.getDisplayName(); + final String modId = modInfo.getModId(); + final String modName = modInfo.getDisplayName(); modIdToNameMap.put(modId, modName); } diff --git a/neoforge/src/main/java/net/eternalempires/mod/neoforge/client/NeoForgeModListProvider.java b/neoforge/src/main/java/net/eternalempires/mod/neoforge/client/NeoForgeModListProvider.java index 27df61f..0275fdb 100644 --- a/neoforge/src/main/java/net/eternalempires/mod/neoforge/client/NeoForgeModListProvider.java +++ b/neoforge/src/main/java/net/eternalempires/mod/neoforge/client/NeoForgeModListProvider.java @@ -1,30 +1,87 @@ +/* + * MIT License + * + * Copyright (c) 2025 EternalEmpires.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *s + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + package net.eternalempires.mod.neoforge.client; import net.eternalempires.mod.common.util.modlistcheck.IModListProvider; import net.neoforged.fml.ModList; import net.neoforged.neoforgespi.language.IModInfo; +import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +/** + * NeoForge-specific implementation of {@link IModListProvider}. + * Uses the {@link ModList} API provided by NeoForge to query all mods + * visible to the client runtime. Supplies both the set of installed + * mod IDs and a mapping of mod IDs to their display names. + * This implementation is registered during NeoForge client initialization + * so that {@link net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler} + * can enforce server-defined mod restrictions. + * + * @see IModListProvider + * @see net.eternalempires.mod.common.util.modlistcheck.ModCheckHandler + * + * @since 09/07/2025 + * @author EternalEmpires + */ public class NeoForgeModListProvider implements IModListProvider { + /** + * Retrieves the set of all installed mod IDs visible to the NeoForge client. + *

+ * This implementation queries the {@link ModList} provided by NeoForge and + * collects the {@code modId} from each {@link IModInfo}. + * + * @return a set containing the IDs of all installed mods + */ @Override - public Set getInstalledModIds() { + public @NotNull Set getInstalledModIds() { return ModList.get().getMods().stream() .map(IModInfo::getModId) .collect(Collectors.toSet()); } + /** + * Builds a mapping of installed mod IDs to their corresponding display names. + *

+ * This method iterates over all {@link IModInfo} entries reported by + * {@link ModList}, extracting both the {@code modId} and the human-readable + * {@code displayName} for each mod. + * + * @return a map where keys are mod IDs and values are their display names + */ @Override - public Map getModIdToNameMap() { - Map modIdToNameMap = new HashMap<>(); + public @NotNull Map getModIdToNameMap() { + final Map modIdToNameMap = new HashMap<>(); for (IModInfo modInfo : ModList.get().getMods()) { - String modId = modInfo.getModId(); - String modName = modInfo.getDisplayName(); + final String modId = modInfo.getModId(); + final String modName = modInfo.getDisplayName(); modIdToNameMap.put(modId, modName); }