From 2439d013db19b1f437b8d2f71573ce0cdf26bca6 Mon Sep 17 00:00:00 2001 From: Daniel Norris Date: Thu, 24 Aug 2023 01:09:13 +0100 Subject: [PATCH] feat(forge20): port to 1.20.1 --- forge16/build.gradle | 2 + forge20/build.gradle | 72 ++++++++++ .../broadcaster/BetterPokeBroadcaster.java | 63 +++++++++ .../broadcaster/api/type/BroadcasterType.java | 19 +++ .../api/type/BroadcasterTypeRegistry.java | 39 ++++++ .../type/impl/AbstractBroadcasterType.java | 54 ++++++++ .../impl/type/CaptureBroadcasterType.java | 50 +++++++ .../type/impl/type/DefeatBroadcasterType.java | 90 ++++++++++++ .../type/impl/type/FleeBroadcasterType.java | 86 ++++++++++++ .../type/impl/type/SpawnBroadcasterType.java | 65 +++++++++ .../broadcaster/api/util/BroadcasterUtil.java | 64 +++++++++ .../command/PokeBroadcasterCommand.java | 26 ++++ .../config/BetterPokeBroadcasterConfig.java | 129 ++++++++++++++++++ forge20/src/main/resources/META-INF/mods.toml | 29 ++++ forge20/src/main/resources/pack.mcmeta | 6 + settings.gradle | 3 +- 16 files changed, 796 insertions(+), 1 deletion(-) create mode 100644 forge20/build.gradle create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/BetterPokeBroadcaster.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/BroadcasterType.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/BroadcasterTypeRegistry.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/AbstractBroadcasterType.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/CaptureBroadcasterType.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/DefeatBroadcasterType.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/FleeBroadcasterType.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/SpawnBroadcasterType.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/api/util/BroadcasterUtil.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/command/PokeBroadcasterCommand.java create mode 100644 forge20/src/main/java/com/envyful/better/poke/broadcaster/config/BetterPokeBroadcasterConfig.java create mode 100644 forge20/src/main/resources/META-INF/mods.toml create mode 100644 forge20/src/main/resources/pack.mcmeta diff --git a/forge16/build.gradle b/forge16/build.gradle index f55a2f8..8649c6a 100644 --- a/forge16/build.gradle +++ b/forge16/build.gradle @@ -3,6 +3,8 @@ plugins { id("com.github.johnrengelman.shadow") version "8.1.1" } +java.toolchain.languageVersion = JavaLanguageVersion.of(17) + forgeVersion = "1.16.5" minecraft { diff --git a/forge20/build.gradle b/forge20/build.gradle new file mode 100644 index 0000000..3e476c0 --- /dev/null +++ b/forge20/build.gradle @@ -0,0 +1,72 @@ +plugins { + id 'net.minecraftforge.gradle' version '[6.0,6.2)' + id("com.github.johnrengelman.shadow") version "8.1.1" +} + +forgeVersion = "1.20.1" + +minecraft { + mappings channel: 'official', version: '1.20.1' +} + +sourceSets.main.resources { srcDir 'src/generated/resources' } + +repositories { + maven { + name = 'spongepowered-repo' + url = 'https://repo.spongepowered.org/maven' + } + + maven { url 'https://jitpack.io' } + maven { url "https://maven.envyware.co.uk/releases" } + + ivy { + setUrl('https://download.nodecdn.net/containers/reforged/server/release') + metadataSources { + artifact() + } + patternLayout { + artifact('[revision]/[artifact].[ext]') + } + } +} + +dependencies { + minecraft "net.minecraftforge:forge:1.20.1-47.1.44" + + implementation 'pixelmon:Pixelmon-1.20.1-9.2.0-server:9.2.0' + + implementation 'com.github.EnvyWare.ForgePlaceholderAPI:api:2.0.4' + + implementation group: 'org.spongepowered', name: 'configurate-yaml', version: '4.0.0' + + shadow group: 'com.envyful.api', name: 'commons', version: '5.0.1' + shadow (group: 'com.envyful.api', name: 'forge20', version: '5.0.1') { + transitive = false; + } + shadow (group: 'com.envyful.api', name: 'reforged20', version: '5.0.1') { + transitive = false; + } +} + +shadowJar { + finalizedBy('reobfJar') + configurations = [project.configurations.shadow] + zip64 = true + setArchiveClassifier('') + setArchiveBaseName(rootProject.name + "-Forge") + + relocate('org.spongepowered.configurate', 'com.envyful.better.poke.broadcaster.shade.configurate') + relocate('org.yaml.snakeyaml', 'com.envyful.better.poke.broadcaster.shade.snakeyaml') + relocate('io.leangen.geantyref', 'com.envyful.better.poke.broadcaster.shade.geantyref') + relocate('com.google.gson', 'com.envyful.better.poke.broadcaster.shade.gson') + relocate('com.zaxxer', 'com.envyful.better.poke.broadcaster.shade.hikari') + relocate('org.slf4j', 'com.envyful.better.poke.broadcaster.shade.slf4j') + relocate('com.envyful.api', 'com.envyful.better.poke.broadcaster.shade.envy.api') + relocate('org.bstats', 'com.envyful.better.poke.broadcaster.shade.bstats') + + exclude "**/module-info.class" +} + +jar.finalizedBy('shadowJar') +build.finalizedBy('versionedRelease') \ No newline at end of file diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/BetterPokeBroadcaster.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/BetterPokeBroadcaster.java new file mode 100644 index 0000000..082c997 --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/BetterPokeBroadcaster.java @@ -0,0 +1,63 @@ +package com.envyful.better.poke.broadcaster; + +import com.envyful.api.concurrency.UtilLogger; +import com.envyful.api.config.yaml.YamlConfigFactory; +import com.envyful.api.forge.command.ForgeCommandFactory; +import com.envyful.better.poke.broadcaster.api.type.BroadcasterTypeRegistry; +import com.envyful.better.poke.broadcaster.command.PokeBroadcasterCommand; +import com.envyful.better.poke.broadcaster.config.BetterPokeBroadcasterConfig; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.RegisterCommandsEvent; +import net.minecraftforge.event.server.ServerStartingEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; + +@Mod(BetterPokeBroadcaster.MOD_ID) +public class BetterPokeBroadcaster { + + public static final String MOD_ID = "betterpokebroadcaster"; + + private static BetterPokeBroadcaster instance; + + private ForgeCommandFactory commandFactory = new ForgeCommandFactory(); + + private BetterPokeBroadcasterConfig config; + private Logger logger = LogManager.getLogger(MOD_ID); + + public BetterPokeBroadcaster() { + UtilLogger.setLogger(logger); + instance = this; + MinecraftForge.EVENT_BUS.register(this); + BroadcasterTypeRegistry.init(); + } + + @SubscribeEvent + public void onServerStart(ServerStartingEvent event) { + this.reloadConfig(); + } + + public void reloadConfig() { + try { + this.config = YamlConfigFactory.getInstance(BetterPokeBroadcasterConfig.class); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @SubscribeEvent + public void onCommandRegister(RegisterCommandsEvent event) { + this.commandFactory.registerCommand(event.getDispatcher(), new PokeBroadcasterCommand()); + } + + public static BetterPokeBroadcaster getInstance() { + return instance; + } + + public BetterPokeBroadcasterConfig getConfig() { + return this.config; + } +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/BroadcasterType.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/BroadcasterType.java new file mode 100644 index 0000000..116e490 --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/BroadcasterType.java @@ -0,0 +1,19 @@ +package com.envyful.better.poke.broadcaster.api.type; + +import com.pixelmonmod.pixelmon.entities.pixelmon.PixelmonEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.eventbus.api.Event; + +public interface BroadcasterType { + + String id(); + + boolean isCorrectEvent(Event e); + + PixelmonEntity getPixelmon(Event e); + + ServerPlayer getNearestPlayer(Event e, PixelmonEntity entity, double range); + + String translateMessage(Event e, String line, PixelmonEntity pixelmon, ServerPlayer nearestPlayer); + +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/BroadcasterTypeRegistry.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/BroadcasterTypeRegistry.java new file mode 100644 index 0000000..be6f291 --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/BroadcasterTypeRegistry.java @@ -0,0 +1,39 @@ +package com.envyful.better.poke.broadcaster.api.type; + +import com.envyful.better.poke.broadcaster.api.type.impl.type.CaptureBroadcasterType; +import com.envyful.better.poke.broadcaster.api.type.impl.type.DefeatBroadcasterType; +import com.envyful.better.poke.broadcaster.api.type.impl.type.FleeBroadcasterType; +import com.envyful.better.poke.broadcaster.api.type.impl.type.SpawnBroadcasterType; +import com.google.common.collect.Maps; +import com.pixelmonmod.pixelmon.Pixelmon; +import net.minecraftforge.common.MinecraftForge; + +import java.util.Map; + +public class BroadcasterTypeRegistry { + + private static final Map> TYPES = Maps.newHashMap(); + + public static void init() { + + } + + static { + register(new SpawnBroadcasterType()); + register(new CaptureBroadcasterType()); + register(new DefeatBroadcasterType()); + register(new FleeBroadcasterType()); + } + + public static void register(BroadcasterType type) { + TYPES.put(type.id().toLowerCase(), type); + + MinecraftForge.EVENT_BUS.register(type); + Pixelmon.EVENT_BUS.register(type); + } + + public static BroadcasterType get(String id) { + return TYPES.get(id.toLowerCase()); + } + +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/AbstractBroadcasterType.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/AbstractBroadcasterType.java new file mode 100644 index 0000000..fcf8aa5 --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/AbstractBroadcasterType.java @@ -0,0 +1,54 @@ +package com.envyful.better.poke.broadcaster.api.type.impl; + +import com.envyful.better.poke.broadcaster.api.type.BroadcasterType; +import com.pixelmonmod.pixelmon.entities.pixelmon.PixelmonEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.eventbus.api.Event; + +public abstract class AbstractBroadcasterType implements BroadcasterType { + + protected final String id; + protected final Class clazz; + + public AbstractBroadcasterType(String id, Class clazz) { + this.id = id; + this.clazz = clazz; + } + + @Override + public String id() { + return this.id; + } + + @Override + public boolean isCorrectEvent(Event e) { + if (!e.getClass().isAssignableFrom(this.clazz)) { + return false; + } + + return this.isEvent(this.clazz.cast(e)); + } + + protected abstract boolean isEvent(A a); + + @Override + public PixelmonEntity getPixelmon(Event e) { + return this.getEntity(this.clazz.cast(e)); + } + + protected abstract PixelmonEntity getEntity(A a); + + @Override + public String translateMessage(Event e, String line, PixelmonEntity pixelmon, ServerPlayer nearestPlayer) { + return this.translateEventMessage(this.clazz.cast(e), line, pixelmon, nearestPlayer); + } + + protected abstract String translateEventMessage(A a, String line, PixelmonEntity pixelmon, ServerPlayer nearestPlayer); + + @Override + public ServerPlayer getNearestPlayer(Event event, PixelmonEntity entity, double range) { + return this.findNearestPlayer(this.clazz.cast(event), entity, range); + } + + protected abstract ServerPlayer findNearestPlayer(A a, PixelmonEntity entity, double range); +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/CaptureBroadcasterType.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/CaptureBroadcasterType.java new file mode 100644 index 0000000..90cdff4 --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/CaptureBroadcasterType.java @@ -0,0 +1,50 @@ +package com.envyful.better.poke.broadcaster.api.type.impl.type; + +import com.envyful.api.forge.world.UtilWorld; +import com.envyful.api.reforged.pixelmon.sprite.UtilSprite; +import com.envyful.better.poke.broadcaster.BetterPokeBroadcaster; +import com.envyful.better.poke.broadcaster.api.type.impl.AbstractBroadcasterType; +import com.envyful.better.poke.broadcaster.api.util.BroadcasterUtil; +import com.pixelmonmod.pixelmon.api.events.CaptureEvent; +import com.pixelmonmod.pixelmon.api.util.helpers.BiomeHelper; +import com.pixelmonmod.pixelmon.entities.pixelmon.PixelmonEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class CaptureBroadcasterType extends AbstractBroadcasterType { + + public CaptureBroadcasterType() { + super("capture", CaptureEvent.SuccessfulCapture.class); + } + + @Override + protected boolean isEvent(CaptureEvent.SuccessfulCapture event) { + return true; + } + + @Override + protected PixelmonEntity getEntity(CaptureEvent.SuccessfulCapture event) { + return event.getPokemon(); + } + + @Override + protected String translateEventMessage(CaptureEvent.SuccessfulCapture event, String line, PixelmonEntity pixelmon, ServerPlayer nearestPlayer) { + return UtilSprite.replacePokemonPlaceholders(line.replace("%player%", nearestPlayer.getName().getString()) + .replace("%x%", pixelmon.getX() + "") + .replace("%y%", pixelmon.getY() + "") + .replace("%z%", pixelmon.getZ() + "") + .replace("%world%", UtilWorld.getName(pixelmon.level()) + "") + .replace("%pokemon%", pixelmon.getPokemonName()) + .replace("%biome%", BiomeHelper.getLocalizedBiomeName(pixelmon.level().getBiome(pixelmon.blockPosition())).getString()), pixelmon.getPokemon(), BetterPokeBroadcaster.getInstance().getConfig().getPlaceholderFormat()); + } + + @Override + protected ServerPlayer findNearestPlayer(CaptureEvent.SuccessfulCapture successfulCapture, PixelmonEntity entity, double range) { + return successfulCapture.getPlayer(); + } + + @SubscribeEvent + public void onCapture(CaptureEvent.SuccessfulCapture event) { + BroadcasterUtil.handleEvent(event); + } +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/DefeatBroadcasterType.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/DefeatBroadcasterType.java new file mode 100644 index 0000000..f468faf --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/DefeatBroadcasterType.java @@ -0,0 +1,90 @@ +package com.envyful.better.poke.broadcaster.api.type.impl.type; + +import com.envyful.api.forge.world.UtilWorld; +import com.envyful.api.reforged.pixelmon.sprite.UtilSprite; +import com.envyful.better.poke.broadcaster.BetterPokeBroadcaster; +import com.envyful.better.poke.broadcaster.api.type.impl.AbstractBroadcasterType; +import com.envyful.better.poke.broadcaster.api.util.BroadcasterUtil; +import com.pixelmonmod.pixelmon.api.battles.BattleEndCause; +import com.pixelmonmod.pixelmon.api.battles.BattleResults; +import com.pixelmonmod.pixelmon.api.events.battles.BattleEndEvent; +import com.pixelmonmod.pixelmon.api.util.helpers.BiomeHelper; +import com.pixelmonmod.pixelmon.battles.controller.participants.BattleParticipant; +import com.pixelmonmod.pixelmon.battles.controller.participants.WildPixelmonParticipant; +import com.pixelmonmod.pixelmon.entities.pixelmon.PixelmonEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.EntityType; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +import java.util.Map; +import java.util.Objects; + +public class DefeatBroadcasterType extends AbstractBroadcasterType { + + public DefeatBroadcasterType() { + super("defeat", BattleEndEvent.class); + } + + @Override + protected boolean isEvent(BattleEndEvent event) { + PixelmonEntity entity = this.getEntity(event); + + if (entity == null) { + return false; + } + + BattleResults result = this.getResult(event, EntityType.PLAYER); + + if (result == null) { + return false; + } + + if (event.getCause() != BattleEndCause.NORMAL) { + return false; + } + + return result == BattleResults.VICTORY; + } + + public BattleResults getResult(BattleEndEvent event, EntityType entityType) { + for (Map.Entry entry : event.getResults().entrySet()) { + if (Objects.equals(entityType, entry.getKey().getEntity().getType())) { + return entry.getValue(); + } + } + + return null; + } + + @Override + protected PixelmonEntity getEntity(BattleEndEvent event) { + for (BattleParticipant battleParticipant : event.getResults().keySet()) { + if (battleParticipant instanceof WildPixelmonParticipant) { + return (PixelmonEntity)((WildPixelmonParticipant) battleParticipant).getEntity(); + } + } + + return null; + } + + @Override + protected String translateEventMessage(BattleEndEvent event, String line, PixelmonEntity pixelmon, ServerPlayer nearestPlayer) { + return UtilSprite.replacePokemonPlaceholders(line.replace("%nearest_name%", nearestPlayer == null ? "None" : nearestPlayer.getName().getString()) + .replace("%x%", pixelmon.getX() + "") + .replace("%y%", pixelmon.getY() + "") + .replace("%z%", pixelmon.getZ() + "") + .replace("%world%", UtilWorld.getName(pixelmon.level()) + "") + .replace("%pokemon%", pixelmon.getPokemonName()) + .replace("%biome%", BiomeHelper.getLocalizedBiomeName(pixelmon.level().getBiome(pixelmon.blockPosition())).getString()), pixelmon.getPokemon(), BetterPokeBroadcaster.getInstance().getConfig().getPlaceholderFormat()); + } + + @Override + public ServerPlayer findNearestPlayer(BattleEndEvent event, PixelmonEntity entity, double range) { + return (ServerPlayer) entity.level().getNearestPlayer(entity, range); + } + + @SubscribeEvent + public void onBattleEnd(BattleEndEvent event) { + BroadcasterUtil.handleEvent(event); + } +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/FleeBroadcasterType.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/FleeBroadcasterType.java new file mode 100644 index 0000000..07d549b --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/FleeBroadcasterType.java @@ -0,0 +1,86 @@ +package com.envyful.better.poke.broadcaster.api.type.impl.type; + +import com.envyful.api.forge.world.UtilWorld; +import com.envyful.api.reforged.pixelmon.sprite.UtilSprite; +import com.envyful.better.poke.broadcaster.BetterPokeBroadcaster; +import com.envyful.better.poke.broadcaster.api.type.impl.AbstractBroadcasterType; +import com.envyful.better.poke.broadcaster.api.util.BroadcasterUtil; +import com.pixelmonmod.pixelmon.api.battles.BattleEndCause; +import com.pixelmonmod.pixelmon.api.battles.BattleResults; +import com.pixelmonmod.pixelmon.api.events.battles.BattleEndEvent; +import com.pixelmonmod.pixelmon.api.util.helpers.BiomeHelper; +import com.pixelmonmod.pixelmon.battles.controller.participants.BattleParticipant; +import com.pixelmonmod.pixelmon.battles.controller.participants.WildPixelmonParticipant; +import com.pixelmonmod.pixelmon.entities.pixelmon.PixelmonEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.EntityType; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +import java.util.Map; +import java.util.Objects; + +public class FleeBroadcasterType extends AbstractBroadcasterType { + + public FleeBroadcasterType() { + super("flee", BattleEndEvent.class); + } + + @Override + protected boolean isEvent(BattleEndEvent event) { + PixelmonEntity entity = this.getEntity(event); + + if (entity == null) { + return false; + } + + BattleResults result = this.getResult(event, EntityType.PLAYER); + + if (result == null) { + return false; + } + + return event.getCause() == BattleEndCause.FLEE; + } + + public BattleResults getResult(BattleEndEvent event, EntityType entityType) { + for (Map.Entry entry : event.getResults().entrySet()) { + if (Objects.equals(entityType, entry.getKey().getEntity().getType())) { + return entry.getValue(); + } + } + + return null; + } + + @Override + protected PixelmonEntity getEntity(BattleEndEvent event) { + for (BattleParticipant battleParticipant : event.getResults().keySet()) { + if (battleParticipant instanceof WildPixelmonParticipant) { + return (PixelmonEntity)((WildPixelmonParticipant) battleParticipant).getEntity(); + } + } + + return null; + } + + @Override + protected String translateEventMessage(BattleEndEvent event, String line, PixelmonEntity pixelmon, ServerPlayer nearestPlayer) { + return UtilSprite.replacePokemonPlaceholders(line.replace("%nearest_name%", nearestPlayer == null ? "None" : nearestPlayer.getName().getString()) + .replace("%x%", pixelmon.getX() + "") + .replace("%y%", pixelmon.getY() + "") + .replace("%z%", pixelmon.getZ() + "") + .replace("%world%", UtilWorld.getName(pixelmon.level()) + "") + .replace("%pokemon%", pixelmon.getPokemonName()) + .replace("%biome%", BiomeHelper.getLocalizedBiomeName(pixelmon.level().getBiome(pixelmon.blockPosition())).getString()), pixelmon.getPokemon(), BetterPokeBroadcaster.getInstance().getConfig().getPlaceholderFormat()); + } + + @Override + public ServerPlayer findNearestPlayer(BattleEndEvent event, PixelmonEntity entity, double range) { + return (ServerPlayer) entity.level().getNearestPlayer(entity, range); + } + + @SubscribeEvent + public void onBattleEnd(BattleEndEvent event) { + BroadcasterUtil.handleEvent(event); + } +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/SpawnBroadcasterType.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/SpawnBroadcasterType.java new file mode 100644 index 0000000..b866713 --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/type/impl/type/SpawnBroadcasterType.java @@ -0,0 +1,65 @@ +package com.envyful.better.poke.broadcaster.api.type.impl.type; + +import com.envyful.api.forge.world.UtilWorld; +import com.envyful.api.reforged.pixelmon.sprite.UtilSprite; +import com.envyful.better.poke.broadcaster.BetterPokeBroadcaster; +import com.envyful.better.poke.broadcaster.api.type.impl.AbstractBroadcasterType; +import com.envyful.better.poke.broadcaster.api.util.BroadcasterUtil; +import com.pixelmonmod.pixelmon.api.events.spawning.SpawnEvent; +import com.pixelmonmod.pixelmon.api.util.helpers.BiomeHelper; +import com.pixelmonmod.pixelmon.entities.pixelmon.PixelmonEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class SpawnBroadcasterType extends AbstractBroadcasterType { + + public SpawnBroadcasterType() { + super("spawn", SpawnEvent.class); + } + + @Override + protected boolean isEvent(SpawnEvent spawnEvent) { + Entity entity = spawnEvent.action.getOrCreateEntity(); + + if (!(entity instanceof PixelmonEntity)) { + return false; + } + + PixelmonEntity pixelmon = (PixelmonEntity) entity; + + if (pixelmon.getOwner() != null) { + return false; + } + + return true; + } + + @Override + protected PixelmonEntity getEntity(SpawnEvent spawnEvent) { + return (PixelmonEntity) spawnEvent.action.getOrCreateEntity(); + } + + @Override + protected String translateEventMessage(SpawnEvent spawnEvent, String line, PixelmonEntity pixelmon, ServerPlayer nearestPlayer) { + return UtilSprite.replacePokemonPlaceholders(line.replace("%nearest_name%", nearestPlayer == null ? "None" : nearestPlayer.getName().getString()) + .replace("%x%", pixelmon.getX() + "") + .replace("%y%", pixelmon.getY() + "") + .replace("%z%", pixelmon.getZ() + "") + .replace("%world%", UtilWorld.getName(pixelmon.level()) + "") + .replace("%pokemon%", pixelmon.getPokemonName()) + .replace("%biome%", BiomeHelper.getLocalizedBiomeName(pixelmon.level().getBiome(pixelmon.blockPosition())).getString()), + pixelmon.getPokemon(), BetterPokeBroadcaster.getInstance().getConfig().getPlaceholderFormat()); + } + + @Override + public ServerPlayer findNearestPlayer(SpawnEvent event, PixelmonEntity entity, double range) { + return (ServerPlayer) entity.level().getNearestPlayer(event.action.spawnLocation.cause, range); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onPixelmonSpawn(SpawnEvent event) { + BroadcasterUtil.handleEvent(event); + } +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/util/BroadcasterUtil.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/util/BroadcasterUtil.java new file mode 100644 index 0000000..9a50fd2 --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/api/util/BroadcasterUtil.java @@ -0,0 +1,64 @@ +package com.envyful.better.poke.broadcaster.api.util; + +import com.envyful.api.concurrency.UtilConcurrency; +import com.envyful.api.discord.DiscordWebHook; +import com.envyful.api.forge.chat.UtilChatColour; +import com.envyful.better.poke.broadcaster.BetterPokeBroadcaster; +import com.envyful.better.poke.broadcaster.api.type.BroadcasterType; +import com.envyful.better.poke.broadcaster.api.type.BroadcasterTypeRegistry; +import com.envyful.better.poke.broadcaster.config.BetterPokeBroadcasterConfig; +import com.pixelmonmod.pixelmon.entities.pixelmon.PixelmonEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.eventbus.api.Event; +import net.minecraftforge.server.ServerLifecycleHooks; + +import java.io.IOException; + +public class BroadcasterUtil { + + public static void handleEvent(Event event) { + UtilConcurrency.runAsync(() -> { + for (BetterPokeBroadcasterConfig.BroadcastOption option : BetterPokeBroadcaster.getInstance().getConfig().getOptions()) { + BroadcasterType broadcasterType = BroadcasterTypeRegistry.get(option.getType()); + + if (broadcasterType == null || !broadcasterType.isCorrectEvent(event)) { + continue; + } + + PixelmonEntity pixelmon = broadcasterType.getPixelmon(event); + + if (pixelmon == null || !option.getSpec().matches(pixelmon)) { + continue; + } + + ServerPlayer nearestPlayer = broadcasterType.getNearestPlayer(event, pixelmon, option.getNearestPlayerRadius()); + + if (nearestPlayer == null && option.isNearestPlayerOnly()) { + continue; + } + + for (String broadcast : option.getBroadcasts()) { + if (option.isNearestPlayerOnly()) { + nearestPlayer.sendSystemMessage(UtilChatColour.colour(broadcasterType.translateMessage(event, broadcast, pixelmon, nearestPlayer))); + } else { + ServerLifecycleHooks.getCurrentServer().getPlayerList().broadcastSystemMessage( + UtilChatColour.colour(broadcasterType.translateMessage(event, broadcast, pixelmon, nearestPlayer)), true + ); + } + } + + if (option.isWebHookEnabled()) { + DiscordWebHook webHook = option.getWebHook(event, nearestPlayer, broadcasterType, pixelmon); + + if (webHook != null) { + try { + webHook.execute(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + }); + } +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/command/PokeBroadcasterCommand.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/command/PokeBroadcasterCommand.java new file mode 100644 index 0000000..ed528ac --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/command/PokeBroadcasterCommand.java @@ -0,0 +1,26 @@ +package com.envyful.better.poke.broadcaster.command; + +import com.envyful.api.command.annotate.Command; +import com.envyful.api.command.annotate.Permissible; +import com.envyful.api.command.annotate.executor.CommandProcessor; +import com.envyful.api.command.annotate.executor.Sender; +import com.envyful.better.poke.broadcaster.BetterPokeBroadcaster; +import net.minecraft.commands.CommandSource; +import net.minecraft.network.chat.Component; + +@Command( + value = "pokebroadcaster", + description = "Reloads the config", + aliases = { + "betterpokebroadcaster" + } +) +@Permissible("better.poke.broadcaster.reload") +public class PokeBroadcasterCommand { + + @CommandProcessor + public void onCommand(@Sender CommandSource source, String[] args) { + BetterPokeBroadcaster.getInstance().reloadConfig(); + source.sendSystemMessage(Component.literal("Reloaded config")); + } +} diff --git a/forge20/src/main/java/com/envyful/better/poke/broadcaster/config/BetterPokeBroadcasterConfig.java b/forge20/src/main/java/com/envyful/better/poke/broadcaster/config/BetterPokeBroadcasterConfig.java new file mode 100644 index 0000000..d4d08dd --- /dev/null +++ b/forge20/src/main/java/com/envyful/better/poke/broadcaster/config/BetterPokeBroadcasterConfig.java @@ -0,0 +1,129 @@ +package com.envyful.better.poke.broadcaster.config; + +import com.envyful.api.config.data.ConfigPath; +import com.envyful.api.config.yaml.AbstractYamlConfig; +import com.envyful.api.discord.DiscordWebHook; +import com.envyful.api.reforged.pixelmon.config.SpriteConfig; +import com.envyful.api.reforged.pixelmon.sprite.UtilSprite; +import com.envyful.better.poke.broadcaster.BetterPokeBroadcaster; +import com.envyful.better.poke.broadcaster.api.type.BroadcasterType; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.pixelmonmod.api.pokemon.PokemonSpecification; +import com.pixelmonmod.api.pokemon.PokemonSpecificationProxy; +import com.pixelmonmod.pixelmon.entities.pixelmon.PixelmonEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.eventbus.api.Event; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; + +@ConfigSerializable +@ConfigPath("config/BetterPokeBroadcaster/config.yml") +public class BetterPokeBroadcasterConfig extends AbstractYamlConfig { + + private Map broadcastOptions = ImmutableMap.of( + "one", new BroadcastOption("spawn", "shiny", 30, "none", false, Lists.newArrayList( + "&8-------", + "&a%pokemon% %nearest_name% %x%, %y%, %z%, %world%", + "&8-------" + )), + "two", new BroadcastOption("spawn", "legendary", 30, "none", false, Lists.newArrayList( + "&8-------", + "&a%pokemon% %nearest_name% %x%, %y%, %z%, %world%", + "&8-------") + ), + "three", new BroadcastOption("defeat", "legendary", 30, "none", false, Lists.newArrayList( + "&8-------", + "&a%pokemon% %nearest_name% %x%, %y%, %z%, %world%", + "&8-------") + ) + ); + + private SpriteConfig placeholderFormat = new SpriteConfig(); + + public BetterPokeBroadcasterConfig() { + super(); + } + + public List getOptions() { + return Lists.newArrayList(broadcastOptions.values()); + } + + public SpriteConfig getPlaceholderFormat() { + return this.placeholderFormat; + } + + @ConfigSerializable + public static class BroadcastOption { + + private String type; + private String spec; + private transient PokemonSpecification pokemonSpec; + private double nearestPlayerRadius; + private List broadcasts; + private String webhook; + private String readFile = null; + private boolean nearestPlayerOnly; + + public BroadcastOption(String type, String spec, double nearestPlayerRadius, String webhook, + boolean nearestPlayerOnly, List broadcasts) { + this.type = type; + this.spec = spec; + this.nearestPlayerRadius = nearestPlayerRadius; + this.broadcasts = broadcasts; + this.webhook = webhook; + this.nearestPlayerOnly = nearestPlayerOnly; + } + + public BroadcastOption() { + } + + public String getType() { + return this.type; + } + + public double getNearestPlayerRadius() { + return this.nearestPlayerRadius; + } + + public PokemonSpecification getSpec() { + if (this.pokemonSpec == null) { + this.pokemonSpec = PokemonSpecificationProxy.create(this.spec); + } + + return this.pokemonSpec; + } + + public List getBroadcasts() { + return this.broadcasts; + } + + public boolean isWebHookEnabled() { + return this.webhook == null || !this.webhook.equalsIgnoreCase("none"); + } + + public boolean isNearestPlayerOnly() { + return this.nearestPlayerOnly; + } + + public DiscordWebHook getWebHook(Event event, ServerPlayer nearestPlayer, BroadcasterType type, PixelmonEntity pixelmon) { + if (this.readFile == null) { + try { + this.readFile = UtilSprite.replacePokemonPlaceholders(String.join(System.lineSeparator(), Files.readAllLines(Paths.get(this.webhook), StandardCharsets.UTF_8)), pixelmon.getPokemon(), BetterPokeBroadcaster.getInstance().getConfig().getPlaceholderFormat()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return DiscordWebHook.fromJson( + type.translateMessage(event, this.readFile, pixelmon, nearestPlayer) + ); + } + } +} diff --git a/forge20/src/main/resources/META-INF/mods.toml b/forge20/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..3bdc341 --- /dev/null +++ b/forge20/src/main/resources/META-INF/mods.toml @@ -0,0 +1,29 @@ +modLoader="javafml" +loaderVersion="[36,)" +license="MIT" +issueTrackerURL="https://github.com/EnvyWare/BetterPokeBroadcaster/issues" + +[[mods]] +modId="betterpokebroadcaster" +version="1.2.0" +displayName="BetterPokeBroadcaster" +displayURL="https://github.com/EnvyWare" +credits="https://github.com/EnvyWare" +authors="https://github.com/EnvyWare" +description=''' +Adds TRACKING +''' + +[[dependencies.betterpokebroadcaster]] +modId="forge" +mandatory=true +versionRange="[47.1.28,)" +ordering="NONE" +side="BOTH" + +[[dependencies.betterpokebroadcaster]] +modId="minecraft" +mandatory=true +versionRange="[1.20.1,1.21)" +ordering="NONE" +side="BOTH" \ No newline at end of file diff --git a/forge20/src/main/resources/pack.mcmeta b/forge20/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..6dd7184 --- /dev/null +++ b/forge20/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "BetterPokeBroadcaster", + "pack_format": 15 + } +} diff --git a/settings.gradle b/settings.gradle index 2778e02..61c4d3b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,4 +15,5 @@ plugins { } rootProject.name = 'BetterPokeBroadcaster' -include 'forge16' \ No newline at end of file +include 'forge16' +include 'forge20' \ No newline at end of file