From 60f9a65e4c735de8b16bf5b36d04181b48da5fc8 Mon Sep 17 00:00:00 2001 From: ErdbeerbaerLP <27149563+ErdbeerbaerLP@users.noreply.github.com> Date: Mon, 14 Jun 2021 21:28:51 +0200 Subject: [PATCH] 1.12 backport Signed-off-by: ErdbeerbaerLP <27149563+ErdbeerbaerLP@users.noreply.github.com> --- build.gradle | 76 ++++--- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../forge/DiscordIntegration.java | 184 ++++++++-------- .../forge/VotifierEventHandler.java | 20 ++ .../forge/command/DCCommandSender.java | 32 +-- .../forge/command/McCommandDiscord.java | 167 +++++++++----- .../mixin/MixinNetHandlerPlayServer.java | 20 +- .../forge/mixin/MixinWhitelist.java | 14 +- .../forge/util/ForgeMessageUtils.java | 106 +-------- .../forge/util/ForgeServerInterface.java | 65 +++--- src/main/resources/META-INF/mods.toml | 34 --- src/main/resources/mcmod.info | 17 ++ src/main/resources/pack.mcmeta | 2 +- translations/English.toml | 207 ------------------ translations/German.toml | 199 ----------------- translations/README.md | 3 - update_checker.json | 112 ---------- 18 files changed, 365 insertions(+), 897 deletions(-) create mode 100644 src/main/java/de/erdbeerbaerlp/dcintegration/forge/VotifierEventHandler.java delete mode 100644 src/main/resources/META-INF/mods.toml create mode 100644 src/main/resources/mcmod.info delete mode 100644 translations/English.toml delete mode 100644 translations/German.toml delete mode 100644 translations/README.md delete mode 100644 update_checker.json diff --git a/build.gradle b/build.gradle index c12a013e..a2a15b29 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ buildscript { } } dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '4.+', changing: true + classpath 'net.minecraftforge.gradle:ForgeGradle:3.+' classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT' classpath "com.github.jengelman.gradle.plugins:shadow:4.0.4" } @@ -67,7 +67,9 @@ repositories { name = 'sonatype-oss' url = 'https://oss.sonatype.org/content/repositories/snapshots/' } - maven{ + + maven { url "https://maven.latmod.com/" } //FTB + maven { name = 'howaner' url = "http://repo.howaner.de/" } @@ -75,7 +77,7 @@ repositories { //Forge minecraft { - mappings channel: 'snapshot', version: '20210309-1.16.5' + mappings channel: 'snapshot', version: '20171003-1.12' runs { server { workingDirectory project.file('run') @@ -98,12 +100,15 @@ configurations { embed compile.extendsFrom(embed) } -task release{ +task release { } shadowJar { - classifier = '1.16' + classifier = '1.12' configurations = [project.configurations.embed] + relocate 'org.slf4j', 'dcshadow.slf4j' + exclude('module-info.class', 'META-INF/versions/9/module-info.class') + // Keeping them causes errors when loaded by forge } reobf { shadowJar { @@ -119,16 +124,28 @@ artifacts { dependencies { // ========= Common ===================== - embed 'de.erdbeerbaerlp:DiscordIntegration-Core:c68715a546' + embed('de.erdbeerbaerlp:DiscordIntegration-Core:c68715a546') // ========= Minecraft Forge ============= - minecraft 'net.minecraftforge:forge:1.16.5-36.1.16' + minecraft 'net.minecraftforge:forge:1.12.2-14.23.5.2855' //Mixin annotationProcessor 'org.spongepowered:mixin:0.8.2:processor' //Dynmap-API compileOnly('com.github.webbukkit:DynmapCoreAPI:2.5') + + // FTB Utilities + compile "com.feed_the_beast.mods:FTBUtilities:5.+" + compile "com.feed_the_beast.mods:FTBLib:5.+" + + //Votifier Forge + compile 'com.github.upcraftlp:votifier:master-SNAPSHOT' + + //Mixin + embed("org.spongepowered:mixin:0.8-SNAPSHOT") { + transitive = false + } } @@ -139,21 +156,26 @@ mixin { //Manifest attributes jar { - classifier = "1.16" + classifier = "1.12" manifest { attributes([ - 'Maven-Artifact' : "${project.group}:${project.archivesBaseName}:${project.version}", - 'Timestamp' : System.currentTimeMillis(), - "Specification-Title" : "dcintegration", - "Specification-Vendor" : "dcintegration", - "Specification-Version" : "1", // We are version 1 of ourselves - "Implementation-Title" : project.name, - "Implementation-Version" : "${version}", - "Implementation-Vendor" : "dcintegration", - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), - 'MixinConnector' : 'de.erdbeerbaerlp.dcintegration.forge.DCMixinConnector' + 'Maven-Artifact' : "${project.group}:${project.archivesBaseName}:${project.version}", + 'Timestamp' : System.currentTimeMillis(), + "Specification-Title" : "dcintegration", + "Specification-Vendor" : "dcintegration", + "Specification-Version" : "1", // We are version 1 of ourselves + "Implementation-Title" : project.name, + "Implementation-Version" : "${version}", + "Implementation-Vendor" : "dcintegration", + "Implementation-Timestamp" : new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), + 'MixinConnector' : 'de.erdbeerbaerlp.dcintegration.forge.DCMixinConnector', + 'TweakClass' : 'org.spongepowered.asm.launch.MixinTweaker', + 'MixinConfigs' : 'mixins.dcintegration.json', + "ForceLoadAsMod" : "true", + 'FMLCorePluginContainsFMLMod': 'true' ]) } + } //Curseforge publishing @@ -164,30 +186,32 @@ curseforge { id = '324952' changelog = project.changelog releaseType = 'beta' - addGameVersion '1.16.5' + addGameVersion '1.12.2' mainArtifact(jar) { - displayName = "DiscordIntegration-Forge $version (MC 1.16.5)" + displayName = "DiscordIntegration-Forge $version (MC 1.12.2)" + } + relations { + optionalDependency 'voting' + requiredDependency 'mixinbootstrap' } - //relations { - //} } } } import com.modrinth.minotaur.TaskModrinthUpload -task publishModrinth (type: TaskModrinthUpload){ +task publishModrinth(type: TaskModrinthUpload) { if (project.hasProperty('modrinth.apikey')) { // $GRADLE_USER_HOME/gradle.properties token = getProperty("modrinth.apikey") // Use an environment property! projectId = 'rbJ7eS5V' versionNumber = version - versionName = "DiscordIntegration-Forge $version (MC 1.16.5)" + versionName = "DiscordIntegration-Forge $version (MC 1.12.2)" uploadFile = shadowJar changelog = project.changelog - addGameVersion('1.16.5') + addGameVersion('1.12.2') addLoader('forge') versionType = "BETA" } } -tasks.release.dependsOn(tasks.build, tasks.curseforge,tasks.publishModrinth) +tasks.release.dependsOn(tasks.build, tasks.curseforge, tasks.publishModrinth) diff --git a/gradle.properties b/gradle.properties index 042e17aa..d9ccaa1b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,4 +2,4 @@ # This is required to provide enough memory for the Minecraft decompilation process. org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false -changelog=Fixed even more bugs \ No newline at end of file +changelog=Final 1.12 backport, expect and report bugs, broken features and crashes!\nSupport for this 1.12 branch ends on 31.9.2021\n\n!!! Mod uses new config file !!!\nOld config won't be deleted\n\nInstall MixinBootstrap for full feature access \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 256053eb..f779b6b5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip diff --git a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/DiscordIntegration.java b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/DiscordIntegration.java index 0cc3b0ed..e3f20b88 100644 --- a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/DiscordIntegration.java +++ b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/DiscordIntegration.java @@ -1,8 +1,8 @@ package de.erdbeerbaerlp.dcintegration.forge; -import com.mojang.brigadier.exceptions.CommandSyntaxException; import dcshadow.net.kyori.adventure.text.Component; import dcshadow.net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import dcshadow.net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import de.erdbeerbaerlp.dcintegration.common.Discord; import de.erdbeerbaerlp.dcintegration.common.compat.DynmapListener; import de.erdbeerbaerlp.dcintegration.common.discordCommands.CommandRegistry; @@ -18,47 +18,38 @@ import de.erdbeerbaerlp.dcintegration.forge.util.ForgeMessageUtils; import de.erdbeerbaerlp.dcintegration.forge.util.ForgeServerInterface; import net.dv8tion.jda.api.entities.*; -import net.minecraft.entity.passive.TameableEntity; -import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.passive.EntityTameable; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.event.CommandEvent; -import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.ServerChatEvent; import net.minecraftforge.event.entity.living.LivingDeathEvent; import net.minecraftforge.event.entity.player.AdvancementEvent; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.ExtensionPoint; -import net.minecraftforge.fml.InterModComms; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent; -import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; -import net.minecraftforge.fml.event.server.FMLServerStartedEvent; -import net.minecraftforge.fml.event.server.FMLServerStoppedEvent; -import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.fml.loading.FMLEnvironment; -import net.minecraftforge.fml.network.FMLNetworkConstants; +import net.minecraftforge.fml.common.event.*; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.PlayerEvent; import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.tuple.Pair; import java.io.File; import java.util.ArrayList; import java.util.Date; import java.util.UUID; import java.util.concurrent.ExecutionException; -import java.util.regex.Pattern; -import java.util.stream.Stream; +import java.util.concurrent.Executors; import static de.erdbeerbaerlp.dcintegration.common.util.Variables.discordDataDir; import static de.erdbeerbaerlp.dcintegration.common.util.Variables.discord_instance; -@Mod(DiscordIntegration.MODID) +@Mod(modid = DiscordIntegration.MODID, version = "2.2.0", name = "Discord Integration", serverSideOnly = true, acceptableRemoteVersions = "*") + public class DiscordIntegration { /** * Modid @@ -71,15 +62,14 @@ public class DiscordIntegration { private boolean stopped = false; public DiscordIntegration() { + } + @Mod.EventHandler + public void modConstruction(FMLConstructionEvent ev) { Configuration.instance().loadConfig(); - - if(!Configuration.instance().general.botToken.equals("INSERT BOT TOKEN HERE") && FMLEnvironment.dist != Dist.CLIENT) { //Prevent events when token not set or on client - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::serverSetup); + if (!Configuration.instance().general.botToken.equals("INSERT BOT TOKEN HERE")) { //Prevent events when token not set MinecraftForge.EVENT_BUS.register(this); - ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, - () -> Pair.of(() -> FMLNetworkConstants.IGNORESERVERONLY, (a, b) -> true)); - }else{ + } else { System.err.println("Please check the config file and set an bot token"); } @@ -105,8 +95,10 @@ public DiscordIntegration() { } } + @Mod.EventHandler + public void preInit(FMLPreInitializationEvent ev) { + - public void serverSetup(FMLDedicatedServerSetupEvent ev) { CommandRegistry.registerDefaultCommandsFromConfig(); Variables.discord_instance = new Discord(new ForgeServerInterface()); try { @@ -123,23 +115,48 @@ public void serverSetup(FMLDedicatedServerSetupEvent ev) { } } catch (InterruptedException | NullPointerException ignored) { } + if (Loader.isModLoaded("votifier")) { + MinecraftForge.EVENT_BUS.register(new VotifierEventHandler()); + } + } + + @Mod.EventHandler + public void serverStarting(FMLServerStartingEvent ev) { + ev.registerServerCommand(new McCommandDiscord()); + } + + + @Mod.EventHandler + public void imc(FMLInterModComms.IMCEvent ev) { + for (FMLInterModComms.IMCMessage e : ev.getMessages()) { + System.out.println("[IMC-Message] Sender: " + e.getSender() + "Key: " + e.key); + if (isModIDBlacklisted(e.getSender())) continue; + if (e.isStringMessage() && (e.key.equals("Discord-Message") || e.key.equals("sendMessage"))) { + discord_instance.sendMessage(e.getStringValue()); + } + //Compat with imc from another discord integration mod + if (e.isNBTMessage() && e.key.equals("sendMessage")) { + final NBTTagCompound msg = e.getNBTValue(); + discord_instance.sendMessage(msg.getString("message")); + } + } } @SubscribeEvent - public void playerJoin(final PlayerEvent.PlayerLoggedInEvent ev) { - if(PlayerLinkController.getSettings(null,ev.getPlayer().getUniqueID()).hideFromDiscord)return; + public void playerJoin(final net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent ev) { + if (PlayerLinkController.getSettings(null, ev.player.getUniqueID()).hideFromDiscord) return; if (discord_instance != null) { - discord_instance.sendMessage(Configuration.instance().localization.playerJoin.replace("%player%", ForgeMessageUtils.formatPlayerName(ev.getPlayer()))); + discord_instance.sendMessage(Configuration.instance().localization.playerJoin.replace("%player%", ForgeMessageUtils.formatPlayerName(ev.player))); // Fix link status (if user does not have role, give the role to the user, or vice versa) final Thread fixLinkStatus = new Thread(() -> { if (Configuration.instance().linking.linkedRoleID.equals("0")) return; - final UUID uuid = ev.getPlayer().getUniqueID(); + final UUID uuid = ev.player.getUniqueID(); if (!PlayerLinkController.isPlayerLinked(uuid)) return; final Guild guild = discord_instance.getChannel().getGuild(); final Role linkedRole = guild.getRoleById(Configuration.instance().linking.linkedRoleID); if (PlayerLinkController.isPlayerLinked(uuid)) { - final Member member = guild.getMemberById(PlayerLinkController.getDiscordFromPlayer(uuid)); + final Member member = guild.getMemberById(PlayerLinkController.getDiscordFromPlayer(uuid)); if (!member.getRoles().contains(linkedRole)) guild.addRoleToMember(member, linkedRole).queue(); } @@ -151,31 +168,26 @@ public void playerJoin(final PlayerEvent.PlayerLoggedInEvent ev) { @SubscribeEvent public void advancement(AdvancementEvent ev) { - if(PlayerLinkController.getSettings(null,ev.getPlayer().getUniqueID()).hideFromDiscord)return; + if (PlayerLinkController.getSettings(null, ev.getEntityPlayer().getUniqueID()).hideFromDiscord) return; if (discord_instance != null && ev.getAdvancement() != null && ev.getAdvancement().getDisplay() != null && ev.getAdvancement().getDisplay().shouldAnnounceToChat()) discord_instance.sendMessage(Configuration.instance().localization.advancementMessage.replace("%player%", - TextFormatting.getTextWithoutFormattingCodes(ForgeMessageUtils.formatPlayerName(ev.getPlayer()))) + TextFormatting.getTextWithoutFormattingCodes(ForgeMessageUtils.formatPlayerName(ev.getEntityPlayer()))) .replace("%name%", TextFormatting.getTextWithoutFormattingCodes(ev.getAdvancement() .getDisplay() .getTitle() - .getString())) + .getUnformattedText())) .replace("%desc%", TextFormatting.getTextWithoutFormattingCodes(ev.getAdvancement() .getDisplay() .getDescription() - .getString())) + .getUnformattedText())) .replace("\\n", "\n")); } - @SubscribeEvent - public void registerCommands(final RegisterCommandsEvent ev) { - new McCommandDiscord(ev.getDispatcher()); - } - - @SubscribeEvent + @Mod.EventHandler public void serverStarted(final FMLServerStartedEvent ev) { System.out.println("Started"); Variables.started = new Date().getTime(); @@ -187,18 +199,21 @@ public void serverStarted(final FMLServerStartedEvent ev) { discord_instance.startThreads(); } UpdateChecker.runUpdateCheck(); - if(ModList.get().getModContainerById("dynmap").isPresent()){ + if (Loader.isModLoaded("dynmap")) { new DynmapListener().register(); } } @SubscribeEvent public void command(CommandEvent ev) { - String command = ev.getParseResults().getReader().getString().replaceFirst(Pattern.quote("/"), ""); + String command = ev.getCommand().getName() + " "; + for (String s : ev.getParameters()) { + command += s + " "; + } if (!Configuration.instance().commandLog.channelID.equals("0")) { if (!ArrayUtils.contains(Configuration.instance().commandLog.ignoredCommands, command.split(" ")[0])) discord_instance.sendMessage(Configuration.instance().commandLog.message - .replace("%sender%", ev.getParseResults().getContext().getLastChild().getSource().getName()) + .replace("%sender%", ev.getSender().getName()) .replace("%cmd%", command) .replace("%cmd-no-args%", command.split(" ")[0]), discord_instance.getChannel(Configuration.instance().commandLog.channelID)); } @@ -213,17 +228,14 @@ public void command(CommandEvent ev) { raw = true; msg = "*" + MessageUtils.escapeMarkdown(msg.replaceFirst("me ", "").trim()) + "*"; } - try { - discord_instance.sendMessage(ev.getParseResults().getContext().getSource().getName(), ev.getParseResults().getContext().getSource().assertIsEntity().getUniqueID().toString(), new DiscordMessage(null, msg, !raw), discord_instance.getChannel(Configuration.instance().advanced.chatOutputChannelID)); - } catch (CommandSyntaxException e) { - if (msg.startsWith(Configuration.instance().messages.sayCommandIgnoredPrefix)) return; - discord_instance.sendMessage(msg); - } + if (ev.getSender() instanceof DedicatedServer) discord_instance.sendMessage(msg); + else if (ev.getSender() instanceof EntityPlayer || ev.getSender() instanceof FakePlayer) + discord_instance.sendMessage(ev.getCommand().getName(), ev.getSender().getCommandSenderEntity().getUniqueID().toString(), new DiscordMessage(null, msg, !raw), discord_instance.getChannel(Configuration.instance().advanced.chatOutputChannelID)); } } } - @SubscribeEvent + @Mod.EventHandler public void serverStopping(FMLServerStoppingEvent ev) { if (discord_instance != null) { discord_instance.sendMessage(Configuration.instance().localization.serverStopped); @@ -232,16 +244,20 @@ public void serverStopping(FMLServerStoppingEvent ev) { this.stopped = true; } - @SubscribeEvent + @Mod.EventHandler public void serverStopped(FMLServerStoppedEvent ev) { - if (discord_instance != null) { - if (!stopped && discord_instance.getJDA() != null) ev.getServer().runImmediately(() -> { - discord_instance.stopThreads(); - try { + FMLCommonHandler.instance().getMinecraftServerInstance().callFromMainThread(Executors.callable(this::stopDiscord)); //Attempt to force send the messages before server finally closes + } + public void stopDiscord(){ + if (discord_instance != null && !stopped && discord_instance.getJDA() != null) { + discord_instance.stopThreads(); + try { + if (Configuration.instance().webhook.enable) discord_instance.sendMessageReturns(Configuration.instance().localization.serverCrash, discord_instance.getChannel(Configuration.instance().advanced.serverChannelID)).get(); - } catch (InterruptedException | ExecutionException ignored) { - } - }); + else + discord_instance.sendMessage(Configuration.instance().localization.serverCrash, discord_instance.getChannel(Configuration.instance().advanced.serverChannelID)); + } catch (InterruptedException | ExecutionException ignored) { + } discord_instance.kill(); } } @@ -250,21 +266,9 @@ private boolean isModIDBlacklisted(String sender) { return ArrayUtils.contains(Configuration.instance().forgeSpecific.IMC_modIdBlacklist, sender); } - //Still untested - @SubscribeEvent - public void imc(InterModProcessEvent ev) { - final Stream stream = ev.getIMCStream(); - stream.forEach((msg) -> { - System.out.println("[IMC-Message] Sender: " + msg.getSenderModId() + " method: " + msg.getMethod()); - if (isModIDBlacklisted(msg.getSenderModId())) return; - if ((msg.getMethod().equals("Discord-Message") || msg.getMethod().equals("sendMessage"))) { - discord_instance.sendMessage(msg.getMessageSupplier().get().toString()); - } - }); - } @SubscribeEvent public void chat(ServerChatEvent ev) { - if(PlayerLinkController.getSettings(null,ev.getPlayer().getUniqueID()).hideFromDiscord)return; + if (PlayerLinkController.getSettings(null, ev.getPlayer().getUniqueID()).hideFromDiscord) return; final ITextComponent msg = ev.getComponent(); if (discord_instance.callEvent((e) -> { if (e instanceof ForgeDiscordEventHandler) { @@ -277,24 +281,24 @@ public void chat(ServerChatEvent ev) { final MessageEmbed embed = ForgeMessageUtils.genItemStackEmbedIfAvailable(msg); if (discord_instance != null) { TextChannel channel = discord_instance.getChannel(Configuration.instance().advanced.chatOutputChannelID); - if(channel == null ) return; + if (channel == null) return; discord_instance.sendMessage(ForgeMessageUtils.formatPlayerName(ev.getPlayer()), ev.getPlayer().getUniqueID().toString(), new DiscordMessage(embed, text, true), channel); - final String json = ITextComponent.Serializer.toJson(msg); - Component comp = GsonComponentSerializer.gson().deserialize(json); - final String editedJson = GsonComponentSerializer.gson().serialize(MessageUtils.mentionsToNames(comp,channel.getGuild())); - ev.setComponent(ITextComponent.Serializer.getComponentFromJson(editedJson)); + final String componentText = msg.getUnformattedText(); + Component comp = LegacyComponentSerializer.legacySection().deserialize(componentText); + final String editedJson = GsonComponentSerializer.gson().serialize(MessageUtils.mentionsToNames(comp, channel.getGuild())); + ev.setComponent(ITextComponent.Serializer.jsonToComponent(editedJson)); } } @SubscribeEvent public void death(LivingDeathEvent ev) { - if(PlayerLinkController.getSettings(null,ev.getEntity().getUniqueID()).hideFromDiscord)return; - if (ev.getEntity() instanceof PlayerEntity || (ev.getEntity() instanceof TameableEntity && ((TameableEntity) ev.getEntity()).getOwner() instanceof PlayerEntity && Configuration.instance().messages.sendDeathMessagesForTamedAnimals)) { + if (PlayerLinkController.getSettings(null, ev.getEntity().getUniqueID()).hideFromDiscord) return; + if (ev.getEntity() instanceof EntityPlayer || (ev.getEntity() instanceof EntityTameable && ((EntityTameable) ev.getEntity()).getOwner() instanceof EntityPlayer && Configuration.instance().messages.sendDeathMessagesForTamedAnimals)) { if (discord_instance != null) { final ITextComponent deathMessage = ev.getSource().getDeathMessage(ev.getEntityLiving()); final MessageEmbed embed = ForgeMessageUtils.genItemStackEmbedIfAvailable(deathMessage); - discord_instance.sendMessage(new DiscordMessage(embed, Configuration.instance().localization.playerDeath.replace("%player%", ForgeMessageUtils.formatPlayerName(ev.getEntity())).replace("%msg%", TextFormatting.getTextWithoutFormattingCodes(deathMessage.getString()).replace(ev.getEntity().getName().getUnformattedComponentText() + " ", ""))), discord_instance.getChannel(Configuration.instance().advanced.deathsChannelID)); + discord_instance.sendMessage(new DiscordMessage(embed, Configuration.instance().localization.playerDeath.replace("%player%", ForgeMessageUtils.formatPlayerName(ev.getEntity())).replace("%msg%", TextFormatting.getTextWithoutFormattingCodes(deathMessage.getUnformattedText()).replace(ev.getEntity().getName() + " ", ""))), discord_instance.getChannel(Configuration.instance().advanced.deathsChannelID)); } } } @@ -302,12 +306,12 @@ public void death(LivingDeathEvent ev) { @SubscribeEvent public void playerLeave(PlayerEvent.PlayerLoggedOutEvent ev) { if (stopped) return; //Try to fix player leave messages after stop! - if(PlayerLinkController.getSettings(null,ev.getPlayer().getUniqueID()).hideFromDiscord)return; - if (discord_instance != null && !timeouts.contains(ev.getPlayer().getUniqueID())) - discord_instance.sendMessage(Configuration.instance().localization.playerLeave.replace("%player%", ForgeMessageUtils.formatPlayerName(ev.getPlayer()))); - else if (discord_instance != null && timeouts.contains(ev.getPlayer().getUniqueID())) { - discord_instance.sendMessage(Configuration.instance().localization.playerTimeout.replace("%player%", ForgeMessageUtils.formatPlayerName(ev.getPlayer()))); - timeouts.remove(ev.getPlayer().getUniqueID()); + if (PlayerLinkController.getSettings(null, ev.player.getUniqueID()).hideFromDiscord) return; + if (discord_instance != null && !timeouts.contains(ev.player.getUniqueID())) + discord_instance.sendMessage(Configuration.instance().localization.playerLeave.replace("%player%", ForgeMessageUtils.formatPlayerName(ev.player))); + else if (discord_instance != null && timeouts.contains(ev.player.getUniqueID())) { + discord_instance.sendMessage(Configuration.instance().localization.playerTimeout.replace("%player%", ForgeMessageUtils.formatPlayerName(ev.player))); + timeouts.remove(ev.player.getUniqueID()); } } } diff --git a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/VotifierEventHandler.java b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/VotifierEventHandler.java new file mode 100644 index 00000000..047775f2 --- /dev/null +++ b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/VotifierEventHandler.java @@ -0,0 +1,20 @@ +package de.erdbeerbaerlp.dcintegration.forge; + +import com.github.upcraftlp.votifier.api.VoteReceivedEvent; +import de.erdbeerbaerlp.dcintegration.common.storage.Configuration; +import de.erdbeerbaerlp.dcintegration.common.util.Variables; +import de.erdbeerbaerlp.dcintegration.forge.util.ForgeMessageUtils; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.AbstractMap; + + +public class VotifierEventHandler +{ + @SubscribeEvent + public void voteEvent(VoteReceivedEvent ev) { + if (Variables.discord_instance != null && Configuration.instance().votifier.enabled) + Variables.discord_instance.sendMessage(Configuration.instance().votifier.votifierChannelID.isEmpty() ? Variables.discord_instance.getChannel() : Variables.discord_instance.getChannel(Configuration.instance().votifier.votifierChannelID), Configuration.instance().votifier.message.replace("%player%", ForgeMessageUtils + .formatPlayerName(new AbstractMap.SimpleEntry<>(ev.getEntityPlayer().getUniqueID(),ev.getEntityPlayer().getName()), false)).replace("%addr%", ev.getRemoteAddress()).replace("%site%", ev.getServiceDescriptor()), Configuration.instance().votifier.avatarURL, Configuration.instance().votifier.name); + } +} \ No newline at end of file diff --git a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/command/DCCommandSender.java b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/command/DCCommandSender.java index ebdc4904..59e5f34c 100644 --- a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/command/DCCommandSender.java +++ b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/command/DCCommandSender.java @@ -1,56 +1,56 @@ package de.erdbeerbaerlp.dcintegration.forge.command; import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.mojang.authlib.GameProfile; import de.erdbeerbaerlp.dcintegration.common.storage.Configuration; import de.erdbeerbaerlp.dcintegration.common.util.MessageUtils; import de.erdbeerbaerlp.dcintegration.common.util.Variables; import net.dv8tion.jda.api.entities.User; import net.minecraft.util.text.ITextComponent; -import net.minecraft.world.World; -import net.minecraft.world.server.ServerWorld; +import net.minecraft.world.WorldServer; import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.fml.server.ServerLifecycleHooks; +import net.minecraftforge.fml.common.FMLCommonHandler; import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +@SuppressWarnings("EntityConstructor") public class DCCommandSender extends FakePlayer { + private static final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder().setNameFormat(DCCommandSender.class.getSimpleName()).setDaemon(true).build()); private static final UUID uuid = UUID.fromString(Configuration.instance().commands.senderUUID); - private final String channelID; + private String channelID; public DCCommandSender(User user, String channel) { - super(ServerLifecycleHooks.getCurrentServer().getWorld(World.OVERWORLD), new GameProfile(uuid, "@" + user.getName() + "#" + user.getDiscriminator())); + super(FMLCommonHandler.instance().getMinecraftServerInstance().worlds[0], new GameProfile(uuid, "@" + user.getName() + "#" + user.getDiscriminator())); this.channelID = channel; } - public DCCommandSender(ServerWorld world, String name, String channel) { + @SuppressWarnings("unused") + public DCCommandSender(WorldServer world, String name, String channel) { super(world, new GameProfile(uuid, "@" + name)); this.channelID = channel; } private static String textComponentToDiscordMessage(ITextComponent component) { - if (component == null) return ""; - return MessageUtils.convertMCToMarkdown(component.getString()); - } + return MessageUtils.removeFormatting(component.getUnformattedText()); - @Override - public void sendMessage(ITextComponent textComponent, UUID uuid) { - Variables.discord_instance.sendMessageFuture(textComponentToDiscordMessage(textComponent), channelID); } @Override - public boolean shouldReceiveFeedback() { + public boolean canUseCommand(int i, String s) { return true; } @Override - public boolean shouldReceiveErrors() { - return true; + public void sendMessage(ITextComponent component) { + Preconditions.checkNotNull(component); + Variables.discord_instance.sendMessageFuture(textComponentToDiscordMessage(component), channelID); } - @Override public void sendStatusMessage(ITextComponent component, boolean actionBar) { Preconditions.checkNotNull(component); diff --git a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/command/McCommandDiscord.java b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/command/McCommandDiscord.java index 02026d10..3cf109b6 100644 --- a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/command/McCommandDiscord.java +++ b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/command/McCommandDiscord.java @@ -1,65 +1,126 @@ package de.erdbeerbaerlp.dcintegration.forge.command; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import de.erdbeerbaerlp.dcintegration.common.addon.AddonLoader; import de.erdbeerbaerlp.dcintegration.common.storage.Configuration; import de.erdbeerbaerlp.dcintegration.common.storage.PlayerLinkController; import de.erdbeerbaerlp.dcintegration.common.util.Variables; -import net.minecraft.command.CommandSource; -import net.minecraft.command.Commands; -import net.minecraft.util.text.StringTextComponent; +import de.erdbeerbaerlp.dcintegration.forge.DiscordIntegration; +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.Style; -import net.minecraft.util.text.TextComponentUtils; +import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.event.ClickEvent; import net.minecraft.util.text.event.HoverEvent; -import net.minecraftforge.fml.server.ServerLifecycleHooks; - - -public class McCommandDiscord { - public McCommandDiscord(CommandDispatcher dispatcher) { - final LiteralArgumentBuilder l = Commands.literal("discord"); - if (Configuration.instance().ingameCommand.enabled) l.executes((ctx) -> { - ctx.getSource().sendFeedback(TextComponentUtils.func_240648_a_(new StringTextComponent(Configuration.instance().ingameCommand.message), - Style.EMPTY.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new StringTextComponent(Configuration.instance().ingameCommand.hoverMessage))) - .setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, Configuration.instance().ingameCommand.inviteURL))), false); - return 0; - }); - l.then(Commands.literal("restart").requires((p) -> p.hasPermissionLevel(3)).executes((ctx) -> { - new Thread(() -> { - if (Variables.discord_instance.restart()) { - ctx.getSource().sendFeedback(new StringTextComponent(TextFormatting.GREEN + "Discord bot restarted!"), true); - } else - ctx.getSource().sendErrorMessage(new StringTextComponent(TextFormatting.RED + "Failed to properly restart the discord bot!")); - }).start(); - return 0; - })).then(Commands.literal("ignore").executes((ctx) -> { - ctx.getSource().sendFeedback( - new StringTextComponent(Variables.discord_instance.togglePlayerIgnore(ctx.getSource().asPlayer().getUniqueID()) ? Configuration.instance().localization.commands.commandIgnore_unignore : Configuration.instance().localization.commands.commandIgnore_ignore), true); - return 0; - })).then(Commands.literal("link").executes((ctx) -> { - if (Configuration.instance().linking.enableLinking && ServerLifecycleHooks.getCurrentServer().isServerInOnlineMode() && !Configuration.instance().linking.whitelistMode) { - if (PlayerLinkController.isPlayerLinked(ctx.getSource().asPlayer().getUniqueID())) { - ctx.getSource().sendFeedback(new StringTextComponent(TextFormatting.RED + Configuration.instance().localization.linking.alreadyLinked.replace("%player%", Variables.discord_instance.getJDA().getUserById(PlayerLinkController.getDiscordFromBedrockPlayer(ctx.getSource().asPlayer().getUniqueID())).getAsTag())), false); - return 0; +import net.minecraftforge.common.config.Config; +import net.minecraftforge.common.config.ConfigManager; +import net.minecraftforge.fml.common.FMLCommonHandler; + +import java.util.ArrayList; +import java.util.List; + + +public class McCommandDiscord implements ICommand +{ + private final ArrayList opTabComps = new ArrayList<>(); + private final ArrayList normalTabComps = new ArrayList<>(); + private final ArrayList aliases = new ArrayList<>(); + + public McCommandDiscord() { + aliases.add("dc"); + aliases.add("disc"); + normalTabComps.add("ignore"); + + opTabComps.add("reload"); + opTabComps.add("restart"); + opTabComps.addAll(normalTabComps); + } + + @Override + public String getName() { + return "discord"; + } + + @Override + public String getUsage(ICommandSender sender) { + return "/discord"; + } + + @Override + public void execute(MinecraftServer server, ICommandSender sender, String[] args) { + if (args.length > 0 && sender instanceof EntityPlayer) { + if (sender.canUseCommand(4, "discord")) { + switch (args[0]) { + case "reload": + new Thread(() -> { + ConfigManager.sync(DiscordIntegration.MODID, Config.Type.INSTANCE); + sender.sendMessage(new TextComponentString(TextFormatting.GREEN + "Config reloaded " + (Variables.discord_instance + .restart() ? "and discord bot properly restarted" : (TextFormatting.RED + "but failed to properly restart the discord bot")) + "!")); + }).start(); + return; + case "restart": + new Thread(() -> { + if (Variables.discord_instance.restart()) { + sender.sendMessage(new TextComponentString(TextFormatting.GREEN + "Discord bot restarted!")); + } + else sender.sendMessage(new TextComponentString(TextFormatting.RED + "Failed to properly restart the discord bot!")); + }).start(); + return; + default: + break; } - final int r = Variables.discord_instance.genLinkNumber(ctx.getSource().asPlayer().getUniqueID()); - ctx.getSource().sendFeedback(TextComponentUtils.func_240648_a_(new StringTextComponent(Configuration.instance().localization.linking.linkMsgIngame.replace("%num%", r + "").replace("%prefix%", Configuration.instance().commands.prefix)), Style.EMPTY.setFormatting(TextFormatting.AQUA).setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, Configuration.instance().commands.prefix + "link " + r)).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new StringTextComponent(Configuration.instance().localization.linking.hoverMsg_copyClipboard)))), false); - } else { - ctx.getSource().sendFeedback(new StringTextComponent(TextFormatting.RED + Configuration.instance().localization.commands.subcommandDisabled), false); } - return 0; - })).then(Commands.literal("stop").requires((p) -> p.hasPermissionLevel(4)).executes((ctx) -> { - Variables.discord_instance.kill(); - ctx.getSource().sendFeedback(new StringTextComponent("DiscordIntegration was successfully stopped!"), false); - return 0; - })).then(Commands.literal("reload").requires((p) -> p.hasPermissionLevel(4)).executes((ctx) -> { - Configuration.instance().loadConfig(); - AddonLoader.reloadAll(); - ctx.getSource().sendFeedback(new StringTextComponent(Configuration.instance().localization.commands.configReloaded), true); - return 0; - })); - dispatcher.register(l); + switch (args[0]) { + case "ignore": + sender.sendMessage( + new TextComponentString(Variables.discord_instance.togglePlayerIgnore(((EntityPlayer) sender).getUniqueID()) ? Configuration.instance().localization.commands.commandIgnore_unignore : Configuration.instance().localization.commands.commandIgnore_ignore)); + return; + case "link": + if (Configuration.instance().linking.enableLinking && FMLCommonHandler.instance().getMinecraftServerInstance().isServerInOnlineMode() && !Configuration.instance().linking.whitelistMode) { + if (PlayerLinkController.isPlayerLinked(sender.getCommandSenderEntity().getUniqueID())) { + sender.sendMessage(new TextComponentString(TextFormatting.RED + Configuration.instance().localization.linking.alreadyLinked.replace("%player%", Variables.discord_instance.getJDA().getUserById(PlayerLinkController.getDiscordFromBedrockPlayer(sender.getCommandSenderEntity().getUniqueID())).getAsTag()))); + break; + } + final int r = Variables.discord_instance.genLinkNumber(sender.getCommandSenderEntity().getUniqueID()); + sender.sendMessage(new TextComponentString(Configuration.instance().localization.linking.linkMsgIngame.replace("%num%", r + "").replace("%prefix%", Configuration.instance().commands.prefix)).setStyle(new Style().setColor(TextFormatting.AQUA).setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, Configuration.instance().commands.prefix + "link " + r)).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Configuration.instance().localization.linking.hoverMsg_copyClipboard))))); + } else { + sender.sendMessage(new TextComponentString(TextFormatting.RED + Configuration.instance().localization.commands.subcommandDisabled)); + } + break; + default: + break; + } + } + sender.sendMessage(new TextComponentString(Configuration.instance().ingameCommand.message).setStyle(new Style().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Configuration.instance().ingameCommand.hoverMessage))) + .setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, Configuration.instance().ingameCommand.inviteURL)))); } -} + + @Override + public int compareTo(ICommand o) { + return 0; + } + + @Override + public List getAliases() { + return aliases; + } + + @Override + public boolean checkPermission(MinecraftServer server, ICommandSender sender) { + return true; + } + + @Override + public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, BlockPos targetPos) { + + return sender.canUseCommand(4, "discord") ? opTabComps : normalTabComps; + } + + @Override + public boolean isUsernameIndex(String[] args, int index) { + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/mixin/MixinNetHandlerPlayServer.java b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/mixin/MixinNetHandlerPlayServer.java index 77e53ce0..ad630556 100644 --- a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/mixin/MixinNetHandlerPlayServer.java +++ b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/mixin/MixinNetHandlerPlayServer.java @@ -1,27 +1,31 @@ package de.erdbeerbaerlp.dcintegration.forge.mixin; + import de.erdbeerbaerlp.dcintegration.forge.DiscordIntegration; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.network.play.ServerPlayNetHandler; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.util.text.TextComponentTranslation; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + /** * Mixin used to detect player timeouts */ -@Mixin(value = ServerPlayNetHandler.class, priority = 1001) -public class MixinNetHandlerPlayServer { +@Mixin(value = NetHandlerPlayServer.class, priority = 1001) +public abstract class MixinNetHandlerPlayServer +{ @Shadow - public ServerPlayerEntity player; + public EntityPlayerMP player; @Inject(method = "disconnect", at = @At("HEAD")) private void onDisconnect(final ITextComponent textComponent, CallbackInfo ci) { - if (textComponent.equals(new TranslationTextComponent("disconnect.timeout"))) - DiscordIntegration.timeouts.add(this.player.getUniqueID()); + if (textComponent.equals(new TextComponentTranslation("disconnect.timeout"))) DiscordIntegration.timeouts.add(this.player.getUniqueID()); } + + } \ No newline at end of file diff --git a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/mixin/MixinWhitelist.java b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/mixin/MixinWhitelist.java index d6c93e00..c7ce02a0 100644 --- a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/mixin/MixinWhitelist.java +++ b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/mixin/MixinWhitelist.java @@ -5,9 +5,7 @@ import de.erdbeerbaerlp.dcintegration.common.storage.PlayerLinkController; import de.erdbeerbaerlp.dcintegration.common.util.Variables; import net.minecraft.server.management.PlayerList; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.StringTextComponent; -import net.minecraftforge.fml.server.ServerLifecycleHooks; +import net.minecraftforge.fml.common.FMLCommonHandler; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -17,15 +15,15 @@ @Mixin(PlayerList.class) public class MixinWhitelist { - @Inject(method = "canPlayerLogin", at = @At("HEAD"), cancellable = true) - private void canLogin(SocketAddress address, GameProfile profile, CallbackInfoReturnable cir) { - if (Configuration.instance().linking.whitelistMode && ServerLifecycleHooks.getCurrentServer().isServerInOnlineMode()) { + @Inject(method = "allowUserToConnect", at = @At("HEAD"), cancellable = true) + private void canLogin(SocketAddress address, GameProfile profile, CallbackInfoReturnable cir) { + if (Configuration.instance().linking.whitelistMode && FMLCommonHandler.instance().getMinecraftServerInstance().isServerInOnlineMode()) { try { if (!PlayerLinkController.isPlayerLinked(profile.getId())) { - cir.setReturnValue(new StringTextComponent(Configuration.instance().localization.linking.notWhitelisted)); + cir.setReturnValue(Configuration.instance().localization.linking.notWhitelisted); } } catch (IllegalStateException e) { - cir.setReturnValue(new StringTextComponent("Please check " + Variables.discordDataDir + "LinkedPlayers.json\n\n" + e.toString())); + cir.setReturnValue("Please check " + Variables.discordDataDir + "LinkedPlayers.json\n\n" + e.toString()); } } } diff --git a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/util/ForgeMessageUtils.java b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/util/ForgeMessageUtils.java index 8fc77be2..cfe07151 100644 --- a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/util/ForgeMessageUtils.java +++ b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/util/ForgeMessageUtils.java @@ -1,30 +1,16 @@ package de.erdbeerbaerlp.dcintegration.forge.util; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.exceptions.CommandSyntaxException; import dcshadow.org.apache.commons.collections4.keyvalue.DefaultMapEntry; -import de.erdbeerbaerlp.dcintegration.common.storage.Configuration; import de.erdbeerbaerlp.dcintegration.common.util.MessageUtils; -import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.MessageEmbed; -import net.minecraft.command.arguments.ComponentArgument; -import net.minecraft.command.arguments.NBTCompoundTagArgument; import net.minecraft.entity.Entity; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.*; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.registry.Registry; -import net.minecraft.util.text.*; -import net.minecraft.util.text.TextComponent; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.registries.IForgeRegistry; -import java.util.Arrays; import java.util.Map; import java.util.UUID; @@ -48,96 +34,12 @@ public static String formatPlayerName(Map.Entry p, boolean chatFor * @return an {@link MessageEmbed} when there was an Item info, or {@link null} if there was no item info OR the item info was disabled */ public static MessageEmbed genItemStackEmbedIfAvailable(final ITextComponent component) { - if (!Configuration.instance().forgeSpecific.sendItemInfo) return null; - final JsonObject json = p.parse(ITextComponent.Serializer.toJson(component)).getAsJsonObject(); - System.out.println("Generating embed..."); - System.out.println("JSON: " + json); - if (json.has("with")) { - final JsonArray args = json.getAsJsonArray("with"); - for (JsonElement el : args) { - if (el instanceof JsonObject) { - JsonObject arg1 = (JsonObject) el; - if (arg1.has("hoverEvent")) { - final JsonObject hoverEvent = arg1.getAsJsonObject("hoverEvent"); - if (hoverEvent.has("action") && hoverEvent.get("action").getAsString().equals("show_item") && hoverEvent.has("contents")) { - if (hoverEvent.getAsJsonObject("contents").has("tag")) { - final JsonObject item = hoverEvent.getAsJsonObject("contents").getAsJsonObject(); - try { - final ItemStack is = new ItemStack(itemreg.getValue(new ResourceLocation(item.get("id").getAsString()))); - if (item.has("tag")) { - final CompoundNBT tag = NBTCompoundTagArgument.nbt().parse(new StringReader(item.get("tag").getAsString())); - is.setTag(tag); - } - final CompoundNBT itemTag = is.getOrCreateTag(); - final EmbedBuilder b = new EmbedBuilder(); - String title = is.hasDisplayName() ? is.getDisplayName().getUnformattedComponentText() : new TranslationTextComponent(is.getTranslationKey()).getUnformattedComponentText(); - if (title.isEmpty()) - title = is.getItem().getRegistryName().toString(); - else - b.setFooter(is.getItem().getRegistryName().toString()); - b.setTitle(title); - final StringBuilder tooltip = new StringBuilder(); - boolean[] flags = new boolean[6]; // Enchantments, Modifiers, Unbreakable, CanDestroy, CanPlace, Other - Arrays.fill(flags, false); // Set everything visible - - if (itemTag.contains("HideFlags")) { - final int input = (itemTag.getInt("HideFlags")); - for (int i = 0; i < flags.length; i++) { - flags[i] = (input & (1 << i)) != 0; - } - } - //Add Enchantments - if (!flags[0]) { - //Implementing this code myself because the original is broken - for (int i = 0; i < is.getEnchantmentTagList().size(); ++i) { - final CompoundNBT compoundnbt = is.getEnchantmentTagList().getCompound(i); - Registry.ENCHANTMENT.getOptional(ResourceLocation.tryCreate(compoundnbt.getString("id"))).ifPresent((ench) -> { - if (compoundnbt.get("lvl") != null) { - final int level; - if (compoundnbt.get("lvl") instanceof StringNBT) { - level = Integer.parseInt(compoundnbt.getString("lvl").replace("s", "")); - } else - level = compoundnbt.getInt("lvl") == 0 ? compoundnbt.getShort("lvl") : compoundnbt.getInt("lvl"); - tooltip.append(TextFormatting.getTextWithoutFormattingCodes(ench.getDisplayName(level).getString())).append("\n"); - } - }); - }/* - EnchantmentHelper.getEnchantments(is).forEach((ench, lvl) -> { - tooltip.append(TextFormatting.getTextWithoutFormattingCodes(ench.getDisplayName(lvl).getUnformattedComponentText())).append("\n"); - });*/ - } - //Add Lores - final ListNBT list = itemTag.getCompound("display").getList("Lore", 8); - list.forEach((nbt) -> { - try { - if (nbt instanceof StringNBT) { - final TextComponent comp = (TextComponent) ComponentArgument.component().parse(new StringReader(nbt.getString())); - tooltip.append("_").append(comp.getUnformattedComponentText()).append("_\n"); - } - } catch (CommandSyntaxException e) { - e.printStackTrace(); - } - }); - //Add 'Unbreakable' Tag - if (!flags[2] && itemTag.contains("Unbreakable") && itemTag.getBoolean("Unbreakable")) - tooltip.append("Unbreakable\n"); - - b.setDescription(tooltip.toString()); - return b.build(); - } catch (CommandSyntaxException ignored) { - //Just go on and ignore it - } - } - } - } - } - } - } return null; + // NOT IMPLEMENTED YET } public static String formatPlayerName(Entity p) { - final Map.Entry e = new DefaultMapEntry(p.getUniqueID(), p.getDisplayName().getUnformattedComponentText().isEmpty() ? p.getName().getUnformattedComponentText() : p.getDisplayName().getUnformattedComponentText()); + final Map.Entry e = new DefaultMapEntry(p.getUniqueID(), p.getDisplayName().getUnformattedComponentText().isEmpty() ? p.getName() : p.getDisplayName().getUnformattedComponentText()); return formatPlayerName(e); } } diff --git a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/util/ForgeServerInterface.java b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/util/ForgeServerInterface.java index fba455ae..3b8564cd 100644 --- a/src/main/java/de/erdbeerbaerlp/dcintegration/forge/util/ForgeServerInterface.java +++ b/src/main/java/de/erdbeerbaerlp/dcintegration/forge/util/ForgeServerInterface.java @@ -1,8 +1,6 @@ package de.erdbeerbaerlp.dcintegration.forge.util; import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.exceptions.CommandSyntaxException; import dcshadow.dev.vankka.mcdiscordreserializer.minecraft.MinecraftSerializer; import dcshadow.net.kyori.adventure.text.Component; import dcshadow.net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; @@ -19,16 +17,13 @@ import net.dv8tion.jda.api.entities.MessageReaction; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.requests.RestAction; -import net.minecraft.command.arguments.ComponentArgument; -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.network.play.server.SPlaySoundPacket; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.SoundEvents; +import net.minecraft.network.play.server.SPacketSoundEffect; import net.minecraft.util.SoundCategory; -import net.minecraft.util.SoundEvents; -import net.minecraft.util.Util; -import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.StringTextComponent; -import net.minecraftforge.fml.server.ServerLifecycleHooks; +import net.minecraft.util.text.TextComponentString; +import net.minecraftforge.fml.common.FMLCommonHandler; import java.util.*; @@ -38,35 +33,35 @@ public class ForgeServerInterface extends ServerInterface { @Override public int getMaxPlayers() { - return ServerLifecycleHooks.getCurrentServer() == null ? -1 : ServerLifecycleHooks.getCurrentServer().getMaxPlayers(); + return FMLCommonHandler.instance().getMinecraftServerInstance() == null ? -1 : FMLCommonHandler.instance().getMinecraftServerInstance().getMaxPlayers(); } @Override public int getOnlinePlayers() { - return ServerLifecycleHooks.getCurrentServer() == null ? -1 : ServerLifecycleHooks.getCurrentServer().getOnlinePlayerNames().length; + return FMLCommonHandler.instance().getMinecraftServerInstance() == null ? -1 : FMLCommonHandler.instance().getMinecraftServerInstance().getOnlinePlayerNames().length; } @Override public void sendMCMessage(Component msg) { - final List l = ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayers(); + final List l = FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayers(); try { - for (final ServerPlayerEntity p : l) { + for (final EntityPlayerMP p : l) { if (!Variables.discord_instance.ignoringPlayers.contains(p.getUniqueID()) && !(PlayerLinkController.isPlayerLinked(p.getUniqueID()) && PlayerLinkController.getSettings(null, p.getUniqueID()).ignoreDiscordChatIngame)) { - final Map.Entry ping = ComponentUtils.parsePing(msg, p.getUniqueID(), p.getName().getUnformattedComponentText()); + final Map.Entry ping = ComponentUtils.parsePing(msg, p.getUniqueID(), p.getName()); final String jsonComp = GsonComponentSerializer.gson().serialize(ping.getValue()).replace("\\\\n", "\n"); - final ITextComponent comp = ComponentArgument.component().parse(new StringReader(jsonComp)); - p.sendMessage(comp, Util.DUMMY_UUID); + final ITextComponent comp = ITextComponent.Serializer.jsonToComponent(jsonComp); + p.sendMessage(comp); if (ping.getKey()) { if (PlayerLinkController.getSettings(null, p.getUniqueID()).pingSound) { - p.connection.sendPacket(new SPlaySoundPacket(SoundEvents.BLOCK_NOTE_BLOCK_PLING.getRegistryName(), SoundCategory.MASTER, new Vector3d(p.getPosX(), p.getPosY(), p.getPosZ()), 1, 1)); + p.connection.sendPacket(new SPacketSoundEffect(SoundEvents.BLOCK_NOTE_PLING, SoundCategory.MASTER, p.posX, p.posY, p.posZ, 1, 1)); } } } } //Send to server console too final String jsonComp = GsonComponentSerializer.gson().serialize(msg).replace("\\\\n", "\n"); - final ITextComponent comp = ComponentArgument.component().parse(new StringReader(jsonComp)); - ServerLifecycleHooks.getCurrentServer().sendMessage(comp, Util.DUMMY_UUID); + final ITextComponent comp = ITextComponent.Serializer.jsonToComponent(jsonComp); + FMLCommonHandler.instance().getMinecraftServerInstance().sendMessage(comp); } catch (Exception e) { e.printStackTrace(); } @@ -74,8 +69,8 @@ public void sendMCMessage(Component msg) { @Override public void sendMCReaction(Member member, RestAction retrieveMessage, UUID targetUUID, MessageReaction.ReactionEmote reactionEmote) { - final List l = ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayers(); - for (final ServerPlayerEntity p : l) { + final List l = FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayers(); + for (final EntityPlayerMP p : l) { if (p.getUniqueID().equals(targetUUID) && !Variables.discord_instance.ignoringPlayers.contains(p.getUniqueID()) && !PlayerLinkController.getSettings(null, p.getUniqueID()).ignoreDiscordChatIngame && !PlayerLinkController.getSettings(null, p.getUniqueID()).ignoreReactions) { final String emote = reactionEmote.isEmote() ? ":" + reactionEmote.getEmote().getName() + ":" : MessageUtils.formatEmoteMessage(new ArrayList<>(), reactionEmote.getEmoji()); @@ -93,12 +88,9 @@ public void sendMCReaction(Member member, RestAction retrieveMessage, U @Override public void runMcCommand(String cmd, MessageReceivedEvent cmdMsg) { final DCCommandSender s = new DCCommandSender(cmdMsg.getAuthor(), cmdMsg.getTextChannel().getId()); - if (s.hasPermissionLevel(4)) { - try { - ServerLifecycleHooks.getCurrentServer().getCommandManager().getDispatcher().execute(cmd.trim(), s.getCommandSource()); - } catch (CommandSyntaxException e) { - discord_instance.sendMessage(e.getMessage()); - } + if (s.canUseCommand(4, "")) { + FMLCommonHandler.instance().getMinecraftServerInstance().getCommandManager().executeCommand(s, cmd.trim()); + } else discord_instance.sendMessage("Sorry, but the bot has no permissions...\nAdd this into the servers ops.json:\n```json\n {\n \"uuid\": \"" + Configuration.instance().commands.senderUUID + "\",\n \"name\": \"DiscordFakeUser\",\n \"level\": 4,\n \"bypassesPlayerLimit\": false\n }\n```", cmdMsg.getTextChannel()); @@ -107,35 +99,36 @@ public void runMcCommand(String cmd, MessageReceivedEvent cmdMsg) { @Override public HashMap getPlayers() { final HashMap players = new HashMap<>(); - for (ServerPlayerEntity p : ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayers()) { - players.put(p.getUniqueID(), p.getDisplayName().getUnformattedComponentText().isEmpty() ? p.getName().getUnformattedComponentText() : p.getDisplayName().getUnformattedComponentText()); + for (EntityPlayerMP p : FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayers()) { + players.put(p.getUniqueID(), p.getDisplayName().getUnformattedComponentText().isEmpty() ? p.getName() : p.getDisplayName().getUnformattedComponentText()); } return players; } @Override public void sendMCMessage(String msg, UUID player) { - ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayerByUUID(player).sendMessage(new StringTextComponent(msg), Util.DUMMY_UUID); + FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayerByUUID(player).sendMessage(new TextComponentString(msg)); } @Override public boolean isOnlineMode() { - return Configuration.instance().bungee.isBehindBungee || ServerLifecycleHooks.getCurrentServer().isServerInOnlineMode(); + return Configuration.instance().bungee.isBehindBungee || FMLCommonHandler.instance().getMinecraftServerInstance().isServerInOnlineMode(); } - private void sendReactionMCMessage(ServerPlayerEntity target, String msg) { + private void sendReactionMCMessage(EntityPlayerMP target, String msg) { final Component msgComp = MinecraftSerializer.INSTANCE.serialize(msg.replace("\n", "\\n"), DiscordEventListener.mcSerializerOptions); final String jsonComp = GsonComponentSerializer.gson().serialize(msgComp).replace("\\\\n", "\n"); try { - final ITextComponent comp = ComponentArgument.component().parse(new StringReader(jsonComp)); - target.sendMessage(comp, Util.DUMMY_UUID); + final ITextComponent comp = ITextComponent.Serializer.jsonToComponent(jsonComp); + target.sendMessage(comp); } catch (Exception e) { e.printStackTrace(); } } + @Override public String getNameFromUUID(UUID uuid) { - return ServerLifecycleHooks.getCurrentServer().getMinecraftSessionService().fillProfileProperties(new GameProfile(uuid, ""), false).getName(); + return FMLCommonHandler.instance().getMinecraftServerInstance().getMinecraftSessionService().fillProfileProperties(new GameProfile(uuid, ""), false).getName(); } } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml deleted file mode 100644 index 3eb0b498..00000000 --- a/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,34 +0,0 @@ -modLoader = "javafml" #mandatory -# A version range to match for said mod loader - for regular FML @Mod it will be the forge version -loaderVersion = "[32,)" #mandatory -license = "MIT License" -# A URL to refer people to when problems occur with this mod -issueTrackerURL = "https://github.com/ErdbeerbaerLP/Discord-Chat-Integration/issues" #optional -# A list of mods - how many allowed here is determined by the individual mod loader -[[mods]] #mandatory -# The modid of the mod -modId = "dcintegration" #mandatory -# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it -version = "${file.jarVersion}" #mandatory -# A display name for the mod -displayName = "Discord Integration" #mandatory -# A URL for the "homepage" for this mod, displayed in the mod UI -displayURL = "https://curseforge.com/projects/dcintegration" #optional -# A text field displayed in the mod UI -authors = "ErdbeerbaerLP" #optional -# The description text for the mod (multi line!) (#mandatory) -description = ''' -This mod links your server chat with a channel on your discord server. -''' -[[dependencies.dcintegration]] -modId = "minecraft" -mandatory = true -versionRange = "[1.16.3,1.16.5]" # Assuming Mojang does not spit out more updates -ordering = "NONE" -side = "SERVER" -[[dependencies.dcintegration]] -modId = "forge" -mandatory = true -versionRange = "[32.0.98,)" -ordering = "NONE" -side = "BOTH" \ No newline at end of file diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info new file mode 100644 index 00000000..4c811266 --- /dev/null +++ b/src/main/resources/mcmod.info @@ -0,0 +1,17 @@ +[ + { + "modid": "dcintegration", + "name": "Discord Integration", + "description": "This mod links your server chat with a channel on your discord server.", + "version": "${version}", + "mcversion": "${mcversion}", + "url": "https://curseforge.com/projects/dcintegration", + "authorList": ["ErdbeerbaerLP"], + "logoFile": "", + "screenshots": [], + "dependencies": [ + "ftbutilities", + "votifier" + ] + } +] \ No newline at end of file diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 237de2e6..7e44d985 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,7 +1,7 @@ { "pack": { "description": "examplemod resources", - "pack_format": 5, + "pack_format": 3, "_comment": "A pack_format of 4 requires json lang files. Note: we require v4 pack meta for all mods." } } diff --git a/translations/English.toml b/translations/English.toml deleted file mode 100644 index 499030ca..00000000 --- a/translations/English.toml +++ /dev/null @@ -1,207 +0,0 @@ -[localization] -# This is what will be displayed ingame when someone types into the bot's channel -# PLACEHOLDERS: -# %user% - The username -# %id% - The user ID -# %msg% - The message -ingame_discordMessage = "§6[§5DISCORD§6]§r <%user%> %msg%" -# This is what will be displayed ingame when someone sends an reply into the bot's channel -# PLACEHOLDERS: -# %user% - The username -# %id% - The user ID -# %msg% - The reply message -# %ruser% - The username of the message that got the reply -# %rmsg% - The replied message -ingame_discordReplyMessage = "§6[§5DISCORD§6]§r §a%user%§r in reply to §3%ruser%§r: %msg%" -# Message shown when hovering over the username of an discord message -# PLACEHOLDERS: -# %user% - The username/nickname (Someone123) -# %user#tag% - The username with tag (someone#0001) -# %id% - The user ID -# -# NOTE: using an @ here can cause ping sounds ingame -discordUserHover = "§3Discord User %user#tag%\n§aClick to mention" -# This message will edited in / sent when the server finished starting -serverStarted = "Server Started!" -# Message to show while the server is starting -# This will be edited to SERVER_STARTED_MSG when webhook is false -serverStarting = "Server Starting..." -# This message will be sent when the server was stopped -serverStopped = "Server Stopped!" -# The message to print to discord when it was possible to detect a server crash -serverCrash = "Server Crash Detected :thinking:" -# Gets sent when an player joins -# -# PLACEHOLDERS: -# %player% - The player's name -playerJoin = "%player% joined" -# Gets sent when an player leaves -# -# PLACEHOLDERS: -# %player% - The player's name -playerLeave = "%player% left" -# Gets sent when an player dies -# -# PLACEHOLDERS: -# %player% - The player's name -# %msg% - The death message -playerDeath = "%player% %msg%" -# Message sent instead of playerLeave, when the player times out -# -# PLACEHOLDERS: -# %player% - The player's name -playerTimeout = "%player% timed out!" -# Gets sent when an player finishes an advancement -# Supports MulitLined messages using \n -# -# PLACEHOLDERS: -# %player% - The player's name -# %name% - The advancement name -# %desc% - The advancement description -advancementMessage = "%player% just made the advancement **%name%**\n_%desc%_" -# The chat message in discord, sent from an player in-game -# -# PLACEHOLDERS: -# %player% - The player's name -# %msg% - The chat message -discordChatMessage = "%player%: %msg%" -# Sent to a player when someone reacts to his messages -# PLACEHOLDERS: -# %name% - (Nick-)Name of the user who reacted (format: 'SomeNickName') -# %name2% - Name of the user who reacted with discord discriminator (format: 'SomeName#0123') -# %msg% - Content of the message which got the reaction -# %emote% - The reacted emote -reactionMessage = "§6[§5DISCORD§6]§r§7 %name% reacted to your message \"§9%msg%§7\" with '%emote%'" - -# Strings about the discord commands -[localization.commands] -# Shown in console when trying to use the discord command -ingameOnly = "This command can only be executed ingame" -# Shown when successfully reloading the config file -configReloaded = "Config reloaded!" -# Shown when an subcommand is disabled -subcommandDisabled = "This subcommand is disabled!" -# Message sent when user does not have permission to run a command -noPermission = "You don't have permission to execute this command!" -# Message sent when an invalid command was typed -# -# PLACEHOLDERS: -# %prefix% - Command prefix -unknownCommand = "Unknown command, try `%prefix%help` for a list of commands" -# Message if a player provides less arguments than required -notEnoughArguments = "Not enough arguments" -# Message if a player provides too many arguments -tooManyArguments = "Too many arguments" -# Message if a player can not be found -# -# PLACEHOLDERS: -# %player% - The player's name -playerNotFound = "Can not find player \"%player%\"" -# The message for 'list' when no player is online -cmdList_empty = "There is no player online..." -# The header for 'list' when one player is online -cmdList_one = "There is 1 player online:" -# The header for 'list' -# PLACEHOLDERS: -# %amount% - The amount of players online -cmdList_header = "There are %amount% players online:" -# Header of the help command -cmdHelp_header = "Your available commands in this channel:" -# Message sent when ignoring Discord messages -commandIgnore_ignore = "You are now ignoring Discord messages!" -# Message sent when unignoring Discord messages -commandIgnore_unignore = "You are no longer ignoring Discord messages!" -# Message sent when using the uptime command -# -# PLACEHOLDERS: -# %uptime% - Uptime in uptime format, see uptimeFormat -cmdUptime_message = "The server is running for %uptime%" -# The format of the uptime command -# For more help with the formatting visit https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/DurationFormatUtils.html -uptimeFormat = "dd 'days' HH 'hours' mm 'minutes'" - -# Command descriptions -[localization.commands.descriptions] -settings = "Allows you to edit your personal settings" -uptime = "Displays the server uptime" -help = "Displays a list of all commands" -list = "Lists all players currently online" -link = "Links your Discord account with your Minecraft account" -whitelist = "Whitelists you on the server by linking with Discord" - -# Strings about the account linking feature -[localization.linking] -# Sent to the user when he linked his discord successfully -# PLACEHOLDERS: -# %player% - The in-game player name -# %prefix% - Command prefix -linkSuccessful = "Your account is now linked with %player%.\nUse %prefix%settings here to view and set some user-specific settings" -# Sent to the user when linking fails -linkFailed = "Account link failed" -# Sent when an already linked user attempts to link an account -# PLACEHOLDERS: -# %player% - The in-game player name -alreadyLinked = "Your account is already linked with %player%" -# Sent when attempting to use personal commands while not linked -# PLACEHOLDERS: -# %method% - The currently enabled method for linking -notLinked = "Your account is not linked! Link it first using %method%" -# Message of the link method in whitelist mode -# Used by %method% placeholder -linkMethodWhitelist = "`%prefix%whitelist ` here" -# Message of the link method in normal mode -# Used by %method% placeholder -linkMethodIngame = "`/discord link` ingame" -# Sent when attempting to whitelist-link with an non uuid string -# PLACEHOLDERS: -# %arg% - The provided argument -# %prefix% - Command prefix -link_argumentNotUUID = "Argument \"%arg%\" is not an valid UUID. Use `%prefix%whitelist `" -# Sent when attempting to link with an unknown number -invalidLinkNumber = "Invalid link number! Use `/discord link` ingame to get your link number" -# Sent when attempting to link with an invalid number -linkNumberNAN = "This is not a number. Use `/discord link` ingame to get your link number" -# Message shown to players who are not whitelisted using discord -# No effect if discord whitelist is off -notWhitelisted = "§cYou are not whitelisted.\nJoin the discord server for more information\nhttps://discord.gg/someserver" -# Sent when trying to link without an required role -link_requiredRole = "You need to have an role to use this" -# Sent when trying to link as an non-member -link_notMember = "You are not member of the Discord-Server this bot is operating in!" -# Sent to the user when he linked his discord successfully -# PLACEHOLDERS: -# %name% - The linked discord name -# %name#tag% - The linked discord name with tag -linkSuccessfulIngame = "Your account is now linked with discord-user %name#tag%" -# Message shown to players who want to link their discord account ingame -# -# PLACEHOLDERS: -# %num% - The link number -# %prefix% - Command prefix -linkMsgIngame = "Send this command as a direct message to the bot to link your account: %prefix%link %num%\nThis number will expire after 10 minutes" -# Shown when hovering over the link message -hoverMsg_copyClipboard = "Click to copy command to clipboard" - -# Strings about the personal settings feature -[localization.personalSettings] -# Message for getting an setting's value -personalSettingGet = "This settings value is `%bool%`" -# Sent when user sucessfully updates an prersonal setting -settingUpdateSuccessful = "Successfully updated setting!" -# Header of the personal settings list -personalSettingsHeader = "Personal Settings list:" -# Error message when providing an invalid personal setting name -invalidPersonalSettingKey = "`%key%` is not an valid setting!" -# PLACEHOLDERS: -# %prefix% - Returns the current command prefix -settingsCommandUsage = "Usages:\n\n%prefix%settings - lists all available keys\n%prefix%settings get - Gets the current settings value\n%prefix%settings set - Sets an Settings value" -# Sent when setting an personal setting fails -settingUpdateFailed = "Failed to set value :/" - -# Descriptions of the settings -[localization.personalSettings.descriptons] -ignoreDiscordChatIngame = "Configure if you want to ignore discord chat ingame" -useDiscordNameInChannel = "Should the bot send messages using your discord name and avatar instead of your in-game name and skin?" -ignoreReactions = "Configure if you want to ignore discord reactions ingame" -pingSound = "Toggle the ingame ping sound" -hideFromDiscord = "Setting this to true will hide all of your minecraft messages from discord" \ No newline at end of file diff --git a/translations/German.toml b/translations/German.toml deleted file mode 100644 index 310ae611..00000000 --- a/translations/German.toml +++ /dev/null @@ -1,199 +0,0 @@ -[localization] -# This is what will be displayed ingame when someone types into the bot's channel -# PLACEHOLDERS: -# %user% - The username -# %id% - The user ID -# %msg% - The Message -ingame_discordMessage = "§6[§5DISCORD§6]§r <%user%> %msg%" -# Message shown when hovering over the username of an discord message -# PLACEHOLDERS: -# %user% - The username/nickname (Someone123) -# %user% - The username with tag (someone#0001) -# %id% - The user ID -# -# NOTE: using an @ here can cause ping sounds ingame -discordMessageHover = "§3Gesendet von Discord-Nutzer %user#tag%\n§aKlicken zum Erwähnen" -# This message will edited in / sent when the server finished starting -serverStarted = "Server gestartet!" -# Message to show while the server is starting -# This will be edited to SERVER_STARTED_MSG when webhook is false -serverStarting = "Server Startet..." -# This message will be sent when the server was stopped -serverStopped = "Server gestoppt!" -# The message to print to discord when it was possible to detect a server crash -serverCrash = "Server Crash erkannt :thinking:" -# Gets sent when an player joins -# -# PLACEHOLDERS: -# %player% - The player's name -playerJoin = "%player% hat den Server betreten" -# Gets sent when an player leaves -# -# PLACEHOLDERS: -# %player% - The player's name -playerLeave = "%player% hat den Server verlassen" -# Gets sent when an player dies -# -# PLACEHOLDERS: -# %player% - The player's name -# %msg% - The death message -playerDeath = "%player% %msg%" -# Message sent instead of playerLeave, when the player times out -# -# PLACEHOLDERS: -# %player% - The player's name -playerTimeout = "%player% timed out!" -# Gets sent when an player finishes an advancement -# Supports MulitLined messages using \n -# -# PLACEHOLDERS: -# %player% - The player's name -# %name% - The advancement name -# %desc% - The advancement description -advancementMessage = "%player% hat den Fortschritt **%name%** erreicht\n_%desc%_" -# The chat message in discord, sent from an player in-game -# -# PLACEHOLDERS: -# %player% - The player's name -# %msg% - The chat message -discordChatMessage = "%player%: %msg%" -# Sent to a player when someone reacts to his messages -# PLACEHOLDERS: -# %name% - (Nick-)Name of the user who reacted (format: 'SomeNickName') -# %name2% - Name of the user who reacted with discord discriminator (format: 'SomeName#0123') -# %msg% - Content of the message which got the reaction -# %emote% - The reacted emote -reactionMessage = "§6[§5DISCORD§6]§r§7 %name% hat auf deine Nachricht \"§9%msg%§7\" mit '%emote%' reagiert" - -# Strings about the discord commands -[localization.commands] -# Shown in console when trying to use the discord command -ingameOnly = "Dieser Befehl kann nur in-game ausgeführt werden" -# Shown when successfully reloading the config file -configReloaded = "Konfiguration neugeladen!" -# Shown when an subcommand is disabled -subcommandDisabled = "Dieser unterbefehl ist deaktiviert!" -# Message sent when user does not have permission to run a command -noPermission = "Du hast keine erlaubnis diesen Befehl auszuführen!" -# Message sent when an invalid command was typed -# -# PLACEHOLDERS: -# %prefix% - Command prefix -unknownCommand = "Unbekannter Befehl, nutze `%prefix%help` für eine Befehlsliste" -# Message if a player provides less arguments than required -notEnoughArguments = "Nicht genug Argumente" -# Message if a player provides too many arguments -tooManyArguments = "Zu viele Argumente" -# Message if a player can not be found -# -# PLACEHOLDERS: -# %player% - The player's name -playerNotFound = "Kann Spieler \"%player%\" nicht finden" -# The message for 'list' when no player is online -cmdList_empty = "Es ist kein Spieler online..." -# The header for 'list' when one player is online -cmdList_one = "Es ist 1 Spieler online:" -# The header for 'list' -# PLACEHOLDERS: -# %amount% - The amount of players online -cmdList_header = "Es sind %amount% Spieler online:" -# Header of the help command -cmdHelp_header = "Deine vorhandenen Befehle in diesem Kanal:" -# Message sent when ignoring Discord messages -commandIgnore_ignore = "Du ignorierst nun Discord-Nachrichten!" -# Message sent when unignoring Discord messages -commandIgnore_unignore = "Du ignorierst nun keine Discord-Nachrichten mehr!" -# Message sent when using the uptime command -# -# PLACEHOLDERS: -# %uptime% - Uptime in uptime format, see uptimeFormat -cmdUptime_message = "Der Server löuft seit%uptime%" -# The format of the uptime command -# For more help with the formatting visit https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/DurationFormatUtils.html -uptimeFormat = "dd 'Tagen' HH 'Stunden' mm 'Minuten'" - -# Command descriptions -[localization.commands.descriptions] -settings = "Erlaubt es dir, deine Persönlchen Einstellungen zu ändern" -uptime = "Zeigt die Uptime des Servers an" -help = "Zeigt eine Liste aller Befehle" -list = "Listet alle Spieler, die auf dem Server online sind" -link = "Verbindet deinen Discord-Account mit deinem Minecraft Account" -whitelist = "Fügt dich zur Discord-Basierten Whitelist des Servers hinzu" - -# Strings about the account linking feature -[localization.linking] -# Sent to the user when he linked his discord successfully -# PLACEHOLDERS: -# %player% - The in-game player name -# %prefix% - Command prefix -linkSuccessful = "Dein Account ist jetzt mit %player% verbunden.\nNutze %prefix%settings hier um persönliche Einstellungen vorzunehmen" -# Sent to the user when linking fails -linkFailed = "Accountverbindung Fehlgeschlagen" -# Sent when an already linked user attempts to link an account -# PLACEHOLDERS: -# %player% - The in-game player name -alreadyLinked = "Dein Account ist bereits mit %player% verbunden" -# Sent when attempting to use personal commands while not linked -# PLACEHOLDERS: -# %method% - The currently enabled method for linking -notLinked = "Dein Account ist nicht Verbunden! Verbinde ihn erst mit %method%" -# Message of the link method in whitelist mode -# Used by %method% placeholder -linkMethodWhitelist = "`%prefix%whitelist ` hier" -# Message of the link method in normal mode -# Used by %method% placeholder -linkMethodIngame = "`/discord link` ingame" -# Sent when attempting to whitelist-link with an non uuid string -# PLACEHOLDERS: -# %arg% - The provided argument -# %prefix% - Command prefix -link_argumentNotUUID = "Argument \"%arg%\" ist keine Valide UUID. Nutze `%prefix%whitelist `" -# Sent when attempting to link with an unknown number -invalidLinkNumber = "Unbekannte Link-Nummer Nutze `/discord link` ingame um eine zu erhalten" -# Sent when attempting to link with an invalid number -linkNumberNAN = "Das ist keine Zahl. Nutze `/discord link` ingame um eine Link-Nummer zu erhalten" -# Message shown to players who are not whitelisted using discord -# No effect if discord whitelist is off -notWhitelisted = "§cDu bist nicht Whitelisted.\nKomm auf unseren Discord für weitere Informationen\nhttps://discord.gg/myserver" -# Sent when trying to link without an required role -link_requiredRole = "Du musst eine bestimmte Rolle haben um deinen Account zu verbinden" -# Sent when trying to link as an non-member -link_notMember = "Du bist nicht auf dem Discord-Server auf dem der Bot arbeitet!" -# Sent to the user when he linked his discord successfully -# PLACEHOLDERS: -# %name% - The linked discord name -# %name#tag% - The linked discord name with tag -linkSuccessfulIngame = "Dein Account ist nun mit dem Discord-Nutzer %name#tag% verbunden" -# Message shown to players who want to link their discord account ingame -# -# PLACEHOLDERS: -# %num% - The link number -# %prefix% - Command prefix -linkMsgIngame = "Sende diesen Befehl als Direkt-Nachricht an den Bot: %prefix%link %num%\nDiese Nummer läuft nach 10 Minuten ab" -# Shown when hovering over the link message -hoverMsg_copyClipboard = "Klicken um Befehl zu Kopieren" - -# Strings about the personal settings feature -[localization.personalSettings] -# Message for getting an setting's value -personalSettingGet = "Der Wert dieser Einstellung ist `%bool%`" -# Sent when user sucessfully updates an prersonal setting -settingUpdateSuccessful = "Einstellung erfolgreich aktualisiert!" -# Header of the personal settings list -personalSettingsHeader = "Liste der persönlichen Einstellungen:" -# Error message when providing an invalid personal setting name -invalidPersonalSettingKey = "`%key%` ist keine valide Einstellung!" -# PLACEHOLDERS: -# %prefix% - Returns the current command prefix -settingsCommandUsage = "Nutzung:\n\n%prefix%settings - Listet alle vorhandenen Einstellungen\n%prefix%settings get - Gibt den aktuellen Wert der Einstellung aus\n%prefix%settings set - Setzt den Wert der Einstellung" -# Sent when setting an personal setting fails -settingUpdateFailed = "Konnte Wert nicht setzen :/" - -# Descriptions of the settings -[localization.personalSettings.descriptons] -ignoreDiscordChatIngame = "Aktivieren, um Discord-Nachrichten in-game komplett abzuschalten" -useDiscordNameInChannel = "Soll der Bot deinen Discord Namen anstelle deines Minecraft Namens in Discord verwenden?" -ignoreReactions = "Aktivieren, um Reaktionen von Nachrichten in Discord zu ignorieren" -pingSound = "(De-)Aktiviere den ingame Ping-Sound" -hideFromDiscord = "Aktivieren, um keine Discord-Nachrichten zu senden" \ No newline at end of file diff --git a/translations/README.md b/translations/README.md deleted file mode 100644 index c9a9c1f1..00000000 --- a/translations/README.md +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains pre-translated localization config sections - -You can install them by simply pasting them in your config file (replace the default localization section) \ No newline at end of file diff --git a/update_checker.json b/update_checker.json deleted file mode 100644 index 2f447221..00000000 --- a/update_checker.json +++ /dev/null @@ -1,112 +0,0 @@ -[ - { - "version": "2.1.1", - "changelog": "Multiple bugfixes", - "type": "release" - }, - { - "version": "2.1.0", - "changelog": "New Features:\nPlatform-Independent Addon Loader\nGeyser Floodgate support (standalone spigot only, not working with bungee!)\nStreaming status\n\nBug Fixes:\nFix Crash with forge\nFix wrong output in list command\nFix multiple possible crash-situations\nFix some placeholders not being replaced", - "type": "release" - }, - { - "version": "2.0.9", - "changelog": "Bug Fixes:\nFix Crash with forge", - "type": "beta" - }, - { - "version": "2.0.8", - "changelog": "New Features:\nDynmap Integration for Forge\n\nBug Fixes:\nFix Server started message before server was done starting on Spigot", - "type": "beta" - }, - { - "version": "2.0.7", - "changelog": "Bug Fixes:\nFix command log channel in DiscordSRV migration", - "type": "beta" - }, - { - "version": "2.0.6", - "changelog": "New Features:\nID mentions (<@userid>) from ingame are now visible as name mentions (@SomeUser) after sending\nMoved another hardcoded String into config file\n\nBug Fixes:\nFixed plugin.yml version numbering\nFixed some hover and click events not working on spigot\nFix possible error or crash when not linked\nFix ping sound not working on Forge", - "type": "beta" - }, - { - "version": "2.0.5", - "changelog": "New Features:\nCommand log can be filtered to exclude commands\n\nBug Fixes:\nFix advancements not working in spigot\nFix default advancement message in config\n\n\n\nNote: This is an alpha version which may contain multiple bugs", - "type": "alpha" - }, - { - "version": "2.0.4", - "changelog": "Ported to spigot (jar works on both forge and spigot)\n\n\nNew Features:\nAdded in-game reaction notifications and ping/mention sound (@Player or @Discord#1234 (if linked) from discord will play sound to target)\nMoved more hardcoded strings into the localization config section (This also moves many options around which resets them)\n(Spigot) Added Votifier integration\n(Spigot) Added config migration from DiscordSRV (Just replace the jar and it should work)\n(Spigot) Added Dynmap integration (Forge will follow soon)\n\nBug Fixes:\nFix bot-channel only commands working everywhere\nFix user and role pings not working\n\n\n\nNote: This is an alpha version which may contain multiple bugs", - "type": "alpha" - }, - { - "version": "2.0.2", - "changelog": "Add workaround for memory leak with newlines\nFix caching\nAdd config option for player avatar url", - "type": "beta" - }, - { - "version": "2.0.1", - "changelog": "Fixed non-webhook mode crash\n[Config Change] Changed Admin role ID to Admin role IDs (array) to support multiple roles", - "type": "beta" - }, - { - "version": "2.0.0", - "changelog": "FINALLY fixed mod shutdown delay\nFixed mod not loading in newer forge versions\nUpdated dependencies\nDone some code cleanup and rewriting\nAdded webhook caching\n\nNOTE: Update will use new config file!\nTo migrate, you can use this default configuration file: https://gist.githubusercontent.com/ErdbeerbaerLP/2b8e4ad30c14bc2941e0f7de63bcaf62/raw/Discord-Integration.toml (save it as Discord-Integration.toml)", - "type": "beta" - }, - { - "version": "1.3.4", - "changelog": "Fixed mod not loading in newer forge versions\nUpdated dependencies", - "type": "beta" - }, - { - "version": "1.3.3", - "changelog": "Fixed mod not loading in newer forge versions, Now using mixin provided by forge itself.\nAdded config option to require an space at the end of the command prefix\nRemoved channel description feature", - "type": "beta" - }, - { - "version": "1.3.2", - "changelog": "Fixed clients seeing, that they are missing an mod", - "type": "beta" - }, - { - "version": "1.3.1", - "changelog": "Fixed player avatars not working", - "type": "beta" - }, - { - "version": "1.3.0", - "changelog": "Fixed crash without emojicord\nFixed avatar URL not working\nMoved around the link configs. THIS WILL RESET THE \"allow-linking\" CONFIG VALUE!\nAdded link role (you get it in discord when linking to minecraft)\nMore configurable messages", - "type": "beta" - }, - { - "version": "1.2.9", - "changelog": "Fixed server crash when linked player joins", - "type": "beta" - }, - { - "version": "1.2.8", - "changelog": "Fixed linked player name not being used in some messages (join/leave/...)", - "type": "beta" - }, - { - "version": "1.2.7", - "changelog": "Added config option to ignore /say messages starting with an specific prefix\nAdded full Emojicord integration (required emotes enabled on client and emojicord on installed server!)", - "type": "beta" - }, - { - "version": "1.2.6", - "changelog": "Fix possible crashes with update checker and fix forgetting to increment version number :/", - "type": "beta" - }, - { - "version": "1.2.5", - "changelog": "Fixed formatting issues with command, advancement and maybe more messages", - "type": "beta" - }, - { - "version": "1.2.4", - "type": "beta", - "changelog": "Added update checker\nAdded small event handler\nFix ingame /discord command to show the invite message again\nRemoved seconds from default uptime format because of rate limits\nFix disabling item tooltips\nFixed disabling shutdown message\nEmotes now no longer show thier ID but only the name" - } -]