From 175677a1a519fc4239a5ce49766a4cd8f1d76402 Mon Sep 17 00:00:00 2001 From: leedagee Date: Thu, 21 Jul 2022 15:22:26 +0800 Subject: [PATCH] Minecraft 1.18 support --- bridge-1.18/build.gradle | 171 ++++++++++++++++++ .../telegrambridge/TelegramBridgeMod.java | 78 ++++++++ .../telegrambridge/config/ForgeConfig.java | 87 +++++++++ .../telegrambridge/handlers/PlayerList.java | 59 ++++++ .../handlers/ToMinecraftResender.java | 46 +++++ .../handlers/ToTelegramEvent.java | 64 +++++++ .../handlers/ToTelegramResender.java | 29 +++ .../src/main/resources/META-INF/mods.toml | 53 ++++++ .../assets/telegrambridge/lang/en_us.lang | 8 + .../assets/telegrambridge/lang/ru_ru.lang | 7 + bridge-1.18/src/main/resources/pack.mcmeta | 7 + .../src/main/resources/telegrambridge.png | Bin 0 -> 29889 bytes core/build.gradle | 8 +- settings.gradle | 1 + 14 files changed, 614 insertions(+), 4 deletions(-) create mode 100644 bridge-1.18/build.gradle create mode 100644 bridge-1.18/src/main/java/ru/glitchless/telegrambridge/TelegramBridgeMod.java create mode 100644 bridge-1.18/src/main/java/ru/glitchless/telegrambridge/config/ForgeConfig.java create mode 100644 bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/PlayerList.java create mode 100644 bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToMinecraftResender.java create mode 100644 bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToTelegramEvent.java create mode 100644 bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToTelegramResender.java create mode 100644 bridge-1.18/src/main/resources/META-INF/mods.toml create mode 100644 bridge-1.18/src/main/resources/assets/telegrambridge/lang/en_us.lang create mode 100644 bridge-1.18/src/main/resources/assets/telegrambridge/lang/ru_ru.lang create mode 100644 bridge-1.18/src/main/resources/pack.mcmeta create mode 100644 bridge-1.18/src/main/resources/telegrambridge.png diff --git a/bridge-1.18/build.gradle b/bridge-1.18/build.gradle new file mode 100644 index 0000000..bf7f243 --- /dev/null +++ b/bridge-1.18/build.gradle @@ -0,0 +1,171 @@ +buildscript { + repositories { + maven { url = 'https://maven.minecraftforge.net' } + jcenter() + mavenCentral() + maven { + url 'https://plugins.gradle.org/m2/' + } + } + dependencies { + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true + classpath "gradle.plugin.com.matthewprenger:CurseGradle:1.4.0" + } +} +apply plugin: 'net.minecraftforge.gradle' +apply plugin: "com.matthewprenger.cursegradle" +// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. + +version = "1.18.2-${project.mod_version}" +group = "ru.glitchless.telegrambridge" // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = 'telegrambridge' + +java.toolchain.languageVersion = JavaLanguageVersion.of(17) + +minecraft { + // The mappings can be changed at any time, and must be in the following format. + // snapshot_YYYYMMDD Snapshot are built nightly. + // stable_# Stables are built at the discretion of the MCP team. + // Use non-default mappings at your own risk. they may not always work. + // Simply re-run your setup task after changing the mappings to update your workspace. + mappings channel: 'official', version: '1.18.2' + // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. + + // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + + // Default run configurations. + // These can be tweaked, removed, or duplicated as needed. + runs { + client { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + + // Recommended logging level for the console + property 'forge.logging.console.level', 'debug' + + mods { + examplemod { + source sourceSets.main + } + } + } + + server { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + + // Recommended logging level for the console + property 'forge.logging.console.level', 'debug' + + mods { + examplemod { + source sourceSets.main + } + } + } + + data { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + + // Recommended logging level for the console + property 'forge.logging.console.level', 'debug' + + args '--mod', 'examplemod', '--all', '--output', file('src/generated/resources/') + + mods { + examplemod { + source sourceSets.main + } + } + } + } +} + +processResources { + // this will ensure that this task is redone when the versions change. + inputs.property "version", project.mod_version + + filesMatching("*/mods.toml") { + expand "version": project.mod_version + } +} + +configurations { + embed + compile.extendsFrom(embed) +} + +dependencies { + // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed + // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. + // The userdev artifact is a special name and will get all sorts of transformations applied to it. + minecraft 'net.minecraftforge:forge:1.18.2-40.1.68' + + // You may put jars on which you depend on in ./libs or you may define them like so.. + // compile "some.group:artifact:version:classifier" + // compile "some.group:artifact:version" + + // Real examples + // compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env + // compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env + + // The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. + // provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' + + // These dependencies get remapped to your current MCP mappings + // deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev' + + // For more info... + // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html + // http://www.gradle.org/docs/current/userguide/dependency_management.html + embed project(":core") + compileOnly project(":core") +} + +// Example for how to get properties into the manifest for reading by the runtime.. +jar { + manifest { + attributes([ + "Specification-Title" : "telegrambridge", + "Specification-Vendor" : "lionzxy", + "Specification-Version" : "1", // We are version 1 of ourselves + "Implementation-Title" : project.name, + "Implementation-Version" : "${project.mod_version}", + "Implementation-Vendor" : "lionzxy", + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) + } + from configurations.embed.collect { + exclude '.classpath' + exclude '.project' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/LICENSE' + exclude 'module-info.class' + exclude 'META-INF/NOTICE' + it.isDirectory() ? it : zipTree(it) + } +} + +artifacts { + archives jar +} + +curseforge { + apiKey = "${CurseForgeApiToken}" + project { + id = '357271' + changelog = "${last_changelog}" + releaseType = "${mod_state}" + addGameVersion '1.18' + mainArtifact(jar) { + displayName = "TelegramBridge $project.version" + } + } +} diff --git a/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/TelegramBridgeMod.java b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/TelegramBridgeMod.java new file mode 100644 index 0000000..f405c0d --- /dev/null +++ b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/TelegramBridgeMod.java @@ -0,0 +1,78 @@ +package ru.glitchless.telegrambridge; + +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.server.ServerStartingEvent; +import net.minecraftforge.event.server.ServerStoppedEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.VersionChecker; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import ru.glitchless.telegrambridge.config.ForgeConfig; +import ru.glitchless.telegrambridge.core.config.TelegramBridgeConfig; +import ru.glitchless.telegrambridge.core.telegramapi.TelegramContext; +import ru.glitchless.telegrambridge.core.telegramapi.TelegramLoop; +import ru.glitchless.telegrambridge.handlers.PlayerList; +import ru.glitchless.telegrambridge.handlers.ToMinecraftResender; +import ru.glitchless.telegrambridge.handlers.ToTelegramEvent; + +@Mod(TelegramBridgeMod.MODID) +public class TelegramBridgeMod { + public static final String MODID = "telegrambridge"; + public static final String NAME = "Telegram Bridge"; + public static final String VERSION = "1.0"; + public static final String UPDATE_URL = "https://www.curseforge.com/minecraft/mc-mods/telegram-bridge"; + + private static final Logger logger = LogManager.getLogger(); + private static TelegramContext context; + private static TelegramLoop telegramLoop; + + public TelegramBridgeMod() { + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); + + ForgeConfig.initConfig(MODID); + + MinecraftForge.EVENT_BUS.register(this); + } + + public static TelegramContext getContext() { + return context; + } + + + public void setup(final FMLCommonSetupEvent event) { + context = new TelegramContext(logger); + telegramLoop = new TelegramLoop(context); + + context.addListener(new ToMinecraftResender()); + context.addListener(new PlayerList()); + } + + @SubscribeEvent + public void serverStarting(ServerStartingEvent event) { + telegramLoop.start(); + if (!TelegramBridgeConfig.relay_level.server_start) { + return; + } + ToTelegramEvent.broadcastToChats(TelegramBridgeConfig.text.server_start); + checkUpdate(); + } + + private void checkUpdate() { + if (VersionChecker.getResult(ModList.get().getModFileById(MODID).getMods().get(0)).status() + == VersionChecker.Status.OUTDATED) { + ToTelegramEvent.broadcastToChats("There's a new update for the mod! Download it [here](" + UPDATE_URL + ")!"); + } + } + + @SubscribeEvent + public void serverStopping(ServerStoppedEvent event) { + if (!TelegramBridgeConfig.relay_level.server_stop) { + return; + } + ToTelegramEvent.broadcastToChats(TelegramBridgeConfig.text.server_stop); + } +} diff --git a/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/config/ForgeConfig.java b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/config/ForgeConfig.java new file mode 100644 index 0000000..7d51b6c --- /dev/null +++ b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/config/ForgeConfig.java @@ -0,0 +1,87 @@ +package ru.glitchless.telegrambridge.config; + +import com.electronwill.nightconfig.core.file.CommentedFileConfig; +import com.electronwill.nightconfig.core.io.WritingMode; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.fml.loading.FMLPaths; +import ru.glitchless.telegrambridge.core.config.AbstractConfig; +import ru.glitchless.telegrambridge.core.config.ConfigPath; +import ru.glitchless.telegrambridge.core.config.ConfigWorkaround; +import ru.glitchless.telegrambridge.core.config.TelegramBridgeConfig; + +import javax.annotation.Nullable; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static ru.glitchless.telegrambridge.core.utils.ArrayUtils.isNullOrContainsNull; + +public class ForgeConfig implements AbstractConfig { + private final Map> specs = new HashMap<>(); + private final ForgeConfigSpec.Builder builder; + + private ForgeConfig(final ForgeConfigSpec.Builder builder) { + this.builder = builder; + } + + public static void initConfig(String modid) { + final ForgeConfigSpec.Builder configBuilder = new ForgeConfigSpec.Builder(); + final AbstractConfig abstractConfig = new ForgeConfig(configBuilder); + ConfigWorkaround.init(abstractConfig, TelegramBridgeConfig.class); + final ForgeConfigSpec forgeConfigSpec = configBuilder.build(); + final Path configPath = FMLPaths.CONFIGDIR.get().resolve(modid + ".toml"); + + final CommentedFileConfig configData = CommentedFileConfig.builder(configPath) + .sync() + .autosave() + .writingMode(WritingMode.REPLACE) + .build(); + + configData.load(); + forgeConfigSpec.setConfig(configData); + ConfigWorkaround.onReload(); + } + + @Override + public Object getValue(ConfigPath path) { + final ForgeConfigSpec.ConfigValue configValue = specs.get(path); + if (configValue == null) { + return null; + } + return configValue.get(); + } + + @Override + public void setList(ConfigPath path, List value, String... comment) { + int level = pushTo(path.getParent()); + if (!isNullOrContainsNull(comment)) { + builder.comment(comment); + } + final ForgeConfigSpec.ConfigValue configValue = builder.define(path.getName(), value, Objects::nonNull); + specs.put(path, configValue); + builder.pop(level); + } + + @Override + public void setValue(ConfigPath path, Object value, String... comment) { + int level = pushTo(path.getParent()); + if (!isNullOrContainsNull(comment)) { + builder.comment(comment); + } + final ForgeConfigSpec.ConfigValue configValue = builder.define(path.getName(), value); + specs.put(path, configValue); + + builder.pop(level); + } + + private int pushTo(@Nullable ConfigPath path) { + if (path == null) { + return 0; + } + int level = pushTo(path.getParent()); + builder.push(path.getName()); + return level + 1; + } +} diff --git a/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/PlayerList.java b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/PlayerList.java new file mode 100644 index 0000000..9f17dd6 --- /dev/null +++ b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/PlayerList.java @@ -0,0 +1,59 @@ +package ru.glitchless.telegrambridge.handlers; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.server.ServerLifecycleHooks; +import ru.glitchless.telegrambridge.TelegramBridgeMod; +import ru.glitchless.telegrambridge.core.config.TelegramBridgeConfig; +import ru.glitchless.telegrambridge.core.handlers.IMessageReceiver; +import ru.glitchless.telegrambridge.core.telegramapi.model.MessageObject; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PlayerList implements IMessageReceiver { + @Override + public boolean onTelegramObjectMessage(@Nonnull MessageObject messageObject) { + String messageText = messageObject.getText(); + + if (messageText == null || messageText.length() == 0) { + return false; + } + + if (!messageText.startsWith("/players")) { + return false; + } + + String chatId = messageObject.getChat().getId().toString(); + final List players = getPlayerList(); + if (players.isEmpty()) { + TelegramBridgeMod.getContext().sendMessage(chatId, TelegramBridgeConfig.text.player_empty); + return true; + } + + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < players.size(); i++) { + sb.append(i + 1).append(". ").append(players.get(i).replace("_", "\\_")).append('\n'); + } + final String message = TelegramBridgeConfig.text.player_list + .replace("${endline}", "\n").replace("${playerlist}", sb.toString()) + .replace("${playercount}", String.valueOf(players.size())); + TelegramBridgeMod.getContext().sendMessage(chatId, message); + return true; + } + + private List getPlayerList() { + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); + if (server == null) { + return Collections.emptyList(); + } + final List playerList = new ArrayList(); + for (ServerPlayer player : server.getPlayerList().getPlayers()) { + playerList.add(player.getGameProfile().getName()); + } + + return playerList; + } +} diff --git a/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToMinecraftResender.java b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToMinecraftResender.java new file mode 100644 index 0000000..c781ae1 --- /dev/null +++ b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToMinecraftResender.java @@ -0,0 +1,46 @@ +package ru.glitchless.telegrambridge.handlers; + +import net.minecraft.network.chat.TextComponent; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.server.ServerLifecycleHooks; +import ru.glitchless.telegrambridge.core.config.TelegramBridgeConfig; +import ru.glitchless.telegrambridge.core.handlers.BaseMessageReceiver; +import ru.glitchless.telegrambridge.core.telegramapi.model.MessageObject; +import ru.glitchless.telegrambridge.core.telegramapi.model.UserObject; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.List; + +public class ToMinecraftResender extends BaseMessageReceiver { + @Override + public boolean onTelegramObjectMessage(@Nonnull MessageObject messageObject) { + final String chatId = String.valueOf(messageObject.getChat().getId()); + + if (!findChatId(chatId)) { + return false; + } + return super.onTelegramObjectMessage(messageObject); + } + + @Override + public boolean onTelegramMessage(UserObject userObject, @Nonnull String message) { + if (isCommand(message)) { + return false; + } + if (TelegramBridgeConfig.relay_mode != TelegramBridgeConfig.RelayMode.TWO_SIDE + && TelegramBridgeConfig.relay_mode != TelegramBridgeConfig.RelayMode.TO_MINECRAFT) { + return true; // ignore + } + + String textMessage = TelegramBridgeConfig.text.chatmessage_to_minecraft.replace("${nickname}", userObject.getUsername()).replace("${message}", message); + + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); + final List players = new ArrayList<>(server.getPlayerList().getPlayers()); + for (ServerPlayer player : players) { + player.sendMessage(new TextComponent(textMessage), player.getUUID()); + } + return true; + } +} diff --git a/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToTelegramEvent.java b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToTelegramEvent.java new file mode 100644 index 0000000..3070018 --- /dev/null +++ b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToTelegramEvent.java @@ -0,0 +1,64 @@ +package ru.glitchless.telegrambridge.handlers; + +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.event.entity.living.LivingDeathEvent; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import ru.glitchless.telegrambridge.TelegramBridgeMod; +import ru.glitchless.telegrambridge.core.config.TelegramBridgeConfig; +import ru.glitchless.telegrambridge.core.utils.TextUtils; + +import javax.annotation.Nonnull; + +@Mod.EventBusSubscriber +public class ToTelegramEvent { + @SubscribeEvent + public static void onPlayerDeath(LivingDeathEvent event) { + if (!(event.getEntityLiving() instanceof ServerPlayer)) { + return; + } + final ServerPlayer player = (ServerPlayer) event.getEntityLiving(); + final Component textComponent = player.getCombatTracker().getDeathMessage(); + final String deathmessage = TextUtils.boldInText(textComponent.getString(), + player.getGameProfile().getName()); + final String message = TelegramBridgeConfig.text.death_message.replace("${deathmessage}", deathmessage); + if (event.getSource().getEntity() instanceof Player + && TelegramBridgeConfig.relay_level.user_kill_by_user) { + broadcastToChats(message); + return; + } + + if (TelegramBridgeConfig.relay_level.user_kill_by_other) { + broadcastToChats(message); + } + } + + @SubscribeEvent + public static void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) { + if (!TelegramBridgeConfig.relay_level.user_join) { + return; + } + final String message = TelegramBridgeConfig.text.player_join + .replace("${nickname}", event.getPlayer().getDisplayName().getString()); + broadcastToChats(message); + } + + @SubscribeEvent + public static void onPlayerDisconnect(PlayerEvent.PlayerLoggedOutEvent event) { + if (!TelegramBridgeConfig.relay_level.user_leave) { + return; + } + final String message = TelegramBridgeConfig.text.player_leave + .replace("${nickname}", event.getPlayer().getDisplayName().getString()); + broadcastToChats(message); + } + + public static void broadcastToChats(@Nonnull String message) { + for (String id : TelegramBridgeConfig.chat_ids) { + TelegramBridgeMod.getContext().sendMessage(id, message); + } + } +} diff --git a/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToTelegramResender.java b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToTelegramResender.java new file mode 100644 index 0000000..43ed81f --- /dev/null +++ b/bridge-1.18/src/main/java/ru/glitchless/telegrambridge/handlers/ToTelegramResender.java @@ -0,0 +1,29 @@ +package ru.glitchless.telegrambridge.handlers; + +import net.minecraftforge.event.ServerChatEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import ru.glitchless.telegrambridge.core.config.TelegramBridgeConfig; + +import static ru.glitchless.telegrambridge.handlers.ToTelegramEvent.broadcastToChats; + +@Mod.EventBusSubscriber +public class ToTelegramResender { + @SubscribeEvent + public static void onChatMessage(ServerChatEvent event) { + if (TelegramBridgeConfig.relay_mode != TelegramBridgeConfig.RelayMode.TWO_SIDE + && TelegramBridgeConfig.relay_mode != TelegramBridgeConfig.RelayMode.TO_TELEGRAM) { + return; // ignore + } + + final String message = event.getMessage(); + + if (message == null || message.isEmpty()) { + return; + } + + final String textMessage = TelegramBridgeConfig.text.chatmessage_to_telegram.replace("${nickname}", event.getUsername()).replace("${message}", message); + broadcastToChats(textMessage); + } + +} diff --git a/bridge-1.18/src/main/resources/META-INF/mods.toml b/bridge-1.18/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..2dde2a4 --- /dev/null +++ b/bridge-1.18/src/main/resources/META-INF/mods.toml @@ -0,0 +1,53 @@ +# This is an example mods.toml file. It contains the data relating to the loading mods. +# There are several mandatory fields (#mandatory), and many more that are optional (#optional). +# The overall format is standard TOML format, v0.5.0. +# Note that there are a couple of TOML lists in this file. +# Find more information on toml format here: https://github.com/toml-lang/toml +# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml +modLoader="javafml" #mandatory +# A version range to match for said mod loader - for regular FML @Mod it will be the forge version +loaderVersion="[30,)" #mandatory (30 is current forge version) +# A URL to refer people to when problems occur with this mod +issueTrackerURL="https://github.com/glitchless/MinecraftTelegramBridge/issues" #optional +# A list of mods - how many allowed here is determined by the individual mod loader +license="All rights reserved" +[[mods]] #mandatory +# The modid of the mod +modId="telegrambridge" #mandatory +# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it +version="${version}" #mandatory + # A display name for the mod +displayName="Telegram Bridge" #mandatory +# A URL to query for updates for this mod. See the JSON update specification +updateJSONURL="https://raw.githubusercontent.com/glitchless/MinecraftTelegramBridge/master/static/update.json" #optional +# A URL for the "homepage" for this mod, displayed in the mod UI +displayURL="https://www.curseforge.com/minecraft/mc-mods/telegram-bridge" #optional +# A file name (in the root of the mod JAR) containing a logo for display +logoFile="telegrambridge.png" #optional +# A text field displayed in the mod UI +credits="StealthTech for beautiful mod icon" #optional +# A text field displayed in the mod UI +authors="LionZXY" #optional +# The description text for the mod (multi line!) (#mandatory) +description=''' +Bridge between game and real world +''' +# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. +[[dependencies.telegrambridge]] #optional + # the modid of the dependency + modId="forge" #mandatory + # Does this dependency have to exist - if not, ordering below must be specified + mandatory=true #mandatory + # The version range of the dependency + versionRange="[30,)" #mandatory + # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory + ordering="NONE" + # Side this dependency is applied on - BOTH, CLIENT or SERVER + side="BOTH" +# Here's another dependency +[[dependencies.telegrambridge]] + modId="minecraft" + mandatory=true + versionRange="[1.18,)" + ordering="NONE" + side="BOTH" diff --git a/bridge-1.18/src/main/resources/assets/telegrambridge/lang/en_us.lang b/bridge-1.18/src/main/resources/assets/telegrambridge/lang/en_us.lang new file mode 100644 index 0000000..24b8fd2 --- /dev/null +++ b/bridge-1.18/src/main/resources/assets/telegrambridge/lang/en_us.lang @@ -0,0 +1,8 @@ +telegrambridge.deathmessage=\[ ${deathmessage} ] +telegrambridge.serverstart=\[ Сервер запущен ] +telegrambridge.serverstop=\[ Сервер остановлен ] +telegrambridge.playerjoin=\[ Игрок *${nickname}* зашел в игру ] +telegrambridge.playerleave=\[ Игрок *${nickname}* вышел из игры ] +telegrambridge.telegramchatmessage=*${nickname}:* ${message} +telegrambridge.minecraftchatmessage=§3Ретранслятор§f / <§b${nickname}§f> ${message} +telegrambridge.notfoundchat=Чата `${chatid}` не найдено в списке разрешенных. Вы можете его добавить в `config/telegrambridge.cfg` diff --git a/bridge-1.18/src/main/resources/assets/telegrambridge/lang/ru_ru.lang b/bridge-1.18/src/main/resources/assets/telegrambridge/lang/ru_ru.lang new file mode 100644 index 0000000..023f6e4 --- /dev/null +++ b/bridge-1.18/src/main/resources/assets/telegrambridge/lang/ru_ru.lang @@ -0,0 +1,7 @@ +telegrambridge.serverstart=\[ Сервер запущен ] +telegrambridge.serverstop=\[ Сервер остановлен ] +telegrambridge.playerjoin=\[ Игрок *${nickname}* зашел в игру ] +telegrambridge.playerleave=\[ Игрок *${nickname}* вышел из игры ] +telegrambridge.telegramchatmessage=*${nickname}:* ${message} +telegrambridge.minecraftchatmessage=§3Ретранслятор§f / <§b${nickname}§f> ${message} +telegrambridge.notfoundchat=Чата `${chatid}` не найдено в списке разрешенных. Вы можете его добавить в `config/telegrambridge.cfg` diff --git a/bridge-1.18/src/main/resources/pack.mcmeta b/bridge-1.18/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..700e07e --- /dev/null +++ b/bridge-1.18/src/main/resources/pack.mcmeta @@ -0,0 +1,7 @@ +{ + "pack": { + "description": "examplemod resources", + "pack_format": 5, + "_comment": "A pack_format of 5 requires json lang files and some texture changes from 1.15. Note: we require v5 pack meta for all mods." + } +} diff --git a/bridge-1.18/src/main/resources/telegrambridge.png b/bridge-1.18/src/main/resources/telegrambridge.png new file mode 100644 index 0000000000000000000000000000000000000000..2931baf5d156352e04edabe25cc86e912bff69cc GIT binary patch literal 29889 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 IcK6Z$12fS%l>h($ literal 0 HcmV?d00001 diff --git a/core/build.gradle b/core/build.gradle index 7b8539c..b241e3a 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -11,8 +11,8 @@ repositories { } dependencies { - compile "com.google.code.findbugs:jsr305:+" - compile "org.apache.logging.log4j:log4j-api:2.8.1" - compile "com.google.code.gson:gson:2.8.0" - compile "org.apache.commons:commons-lang3:3.5" + compileOnly "com.google.code.findbugs:jsr305:+" + compileOnly "org.apache.logging.log4j:log4j-api:2.8.1" + compileOnly "com.google.code.gson:gson:2.8.0" + compileOnly "org.apache.commons:commons-lang3:3.5" } diff --git a/settings.gradle b/settings.gradle index 7f27a37..27717e4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,5 +3,6 @@ include 'bridge-1.7' include 'bridge-1.14' include 'bridge-1.15' include 'bridge-1.16' +include 'bridge-1.18' include 'bukkit'