From 961e4bc375eb20d838a17c86922ff6c9ea5c90c1 Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Tue, 19 Nov 2024 17:40:03 +0100 Subject: [PATCH] wip --- DEVELOPMENT.md | 7 ++ pom.xml | 66 ++++++++++++-- .../java/eu/m724/tweaks/TweaksPlugin.java | 16 ++++ .../eu/m724/tweaks/motd/MotdListener.java | 87 +++++++++++++++++++ .../eu/m724/tweaks/ping/F3NameListener.java | 47 ++++------ .../eu/m724/tweaks/player/MusicPlayer.java | 70 +++++++++++++++ .../m724/tweaks/player/MyVoicechatPlugin.java | 35 ++++++++ src/main/resources/plugin.yml | 1 + 8 files changed, 290 insertions(+), 39 deletions(-) create mode 100644 DEVELOPMENT.md create mode 100644 src/main/java/eu/m724/tweaks/motd/MotdListener.java create mode 100644 src/main/java/eu/m724/tweaks/player/MusicPlayer.java create mode 100644 src/main/java/eu/m724/tweaks/player/MyVoicechatPlugin.java diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..d7d8698 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,7 @@ +To see Minecraft source code: https://git.m724.eu/Minecon724/fabric-template-minimal-source + +To setup NMS: +1. Download BuildTools, move it into an empty directory and open terminal +2. ``` + java -jar BuildTools.jar --rev 1.21.1 --remapped + ``` \ No newline at end of file diff --git a/pom.xml b/pom.xml index e18aee6..9136b71 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,7 @@ 21 21 UTF-8 + 1.21.1-R0.1-SNAPSHOT @@ -54,6 +55,39 @@ + + net.md-5 + specialsource-maven-plugin + 2.0.3 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${project.spigot.version}:txt:maps-mojang + true + org.spigotmc:spigot:${project.spigot.version}:jar:remapped-mojang + true + remapped-obf-temp-dont-use + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf-temp-dont-use.jar + org.spigotmc:minecraft-server:${project.spigot.version}:csrg:maps-spigot + org.spigotmc:spigot:${project.spigot.version}:jar:remapped-obf + + + + @@ -66,13 +100,37 @@ dmulloy2-repo https://repo.dmulloy2.net/repository/public/ + + + maxhenkel-repo + https://maven.maxhenkel.de/repository/public + org.spigotmc spigot-api - 1.21.1-R0.1-SNAPSHOT + ${project.spigot.version} + provided + + + org.spigotmc + spigot + ${project.spigot.version} + remapped-mojang + provided + + + com.comphenix.protocol + ProtocolLib + 5.3.0 + provided + + + de.maxhenkel.voicechat + voicechat-api + 2.5.0 provided @@ -81,11 +139,5 @@ 24.1.0 compile - - com.comphenix.protocol - ProtocolLib - 5.3.0 - provided - \ No newline at end of file diff --git a/src/main/java/eu/m724/tweaks/TweaksPlugin.java b/src/main/java/eu/m724/tweaks/TweaksPlugin.java index 325c402..b268f52 100644 --- a/src/main/java/eu/m724/tweaks/TweaksPlugin.java +++ b/src/main/java/eu/m724/tweaks/TweaksPlugin.java @@ -3,11 +3,14 @@ package eu.m724.tweaks; import eu.m724.tweaks.chat.ChatCommands; import eu.m724.tweaks.chat.ChatManager; import eu.m724.tweaks.door.DoorListener; +import eu.m724.tweaks.motd.MotdListener; import eu.m724.tweaks.ping.F3NameListener; import eu.m724.tweaks.ping.PingChecker; import eu.m724.tweaks.ping.PingCommands; +import eu.m724.tweaks.player.MusicPlayer; import org.bukkit.plugin.java.JavaPlugin; +import java.io.IOException; import java.util.Objects; public class TweaksPlugin extends JavaPlugin { @@ -26,5 +29,18 @@ public class TweaksPlugin extends JavaPlugin { new PingChecker(this).init(); Objects.requireNonNull(getCommand("ping")).setExecutor(new PingCommands()); Objects.requireNonNull(getCommand("dkick")).setExecutor(new PingCommands()); + + if (getServer().getPluginManager().getPlugin("voicechat") != null) { + new MusicPlayer(this).init(); + } else { + getLogger().warning("To use voice extensions, install \"Simple Voice Chat\""); + } + + try { + new MotdListener("example").init(this); + } catch (IOException e) { + getLogger().severe("Failed to initialize MOTD extension"); + throw new RuntimeException(e); + } } } diff --git a/src/main/java/eu/m724/tweaks/motd/MotdListener.java b/src/main/java/eu/m724/tweaks/motd/MotdListener.java new file mode 100644 index 0000000..40f879d --- /dev/null +++ b/src/main/java/eu/m724/tweaks/motd/MotdListener.java @@ -0,0 +1,87 @@ +package eu.m724.tweaks.motd; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.*; +import com.comphenix.protocol.reflect.StructureModifier; +import com.google.gson.JsonElement; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; +import net.minecraft.SharedConstants; +import net.minecraft.core.RegistryAccess; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.status.ServerStatus; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; + +public class MotdListener { + private final String motdSetName; + + private Component[] motds; + + public MotdListener(String motdSetName) { + this.motdSetName = motdSetName; + } + + public void init(Plugin plugin) throws IOException { + File motdSetsFile = new File(plugin.getDataFolder() + "/motd sets/" + motdSetName + ".txt"); + + // if the directory didn't exist create example motd sets + if (motdSetsFile.getParentFile().mkdirs()) { + plugin.saveResource("motd sets/" + motdSetName + ".txt", true); + } + + String fileContent = Files.readString(motdSetsFile.toPath()); + // MOTDs are split with an empty line + motds = Arrays.stream(fileContent.split("\n\n")) + .map(s -> { + JsonElement json = ComponentSerializer.toJson(TextComponent.fromLegacy(s.strip())); + return Component.Serializer.fromJson(json, RegistryAccess.EMPTY); + }) + .toArray(Component[]::new); + + plugin.getLogger().info("Loaded %d MOTDs".formatted(motds.length)); + + registerListener(plugin); + } + + private void registerListener(Plugin plugin) { + ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter( + plugin, + ListenerPriority.NORMAL, + PacketType.Status.Server.SERVER_INFO + ) { + @Override + public void onPacketSending(PacketEvent event) { + PacketContainer packet = event.getPacket(); + + Component motd = motds[ThreadLocalRandom.current().nextInt(motds.length)]; + + ServerStatus serverStatus = (ServerStatus) packet.getStructures().read(0).getHandle(); + + /* this: + * removes server mod prefix (Paper, Spigot, any brand) + * hides players + */ + ServerStatus newStatus = new ServerStatus( + motd, + Optional.empty(), + Optional.of(new ServerStatus.Version( + SharedConstants.getCurrentVersion().getName(), + SharedConstants.getProtocolVersion() + )), + serverStatus.favicon(), + false + ); + + packet.getStructures().write(0, new InternalStructure(newStatus, new StructureModifier<>(ServerStatus.class))); + } + }); + } +} diff --git a/src/main/java/eu/m724/tweaks/ping/F3NameListener.java b/src/main/java/eu/m724/tweaks/ping/F3NameListener.java index ca16aa4..b53a0f9 100644 --- a/src/main/java/eu/m724/tweaks/ping/F3NameListener.java +++ b/src/main/java/eu/m724/tweaks/ping/F3NameListener.java @@ -4,26 +4,16 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.*; import com.comphenix.protocol.reflect.StructureModifier; +import net.minecraft.network.protocol.common.custom.BrandPayload; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - public class F3NameListener { private final Plugin plugin; - private final Class brandPayloadClass; - private final Constructor brandPayloadConstructor; public F3NameListener(Plugin plugin) { this.plugin = plugin; - try { - this.brandPayloadClass = Class.forName("net.minecraft.network.protocol.common.custom.BrandPayload"); - this.brandPayloadConstructor = brandPayloadClass.getConstructor(String.class); - } catch (ClassNotFoundException | NoSuchMethodException e) { - throw new BrandPayloadReflectionException(e); - } } public void init() { @@ -57,34 +47,27 @@ public class F3NameListener { ) { @Override public void onPacketSending(PacketEvent event) { - try { - PacketContainer packet = event.getPacket(); - Object brandPayload = brandPayloadConstructor.newInstance("wait"); - InternalStructure structure = new InternalStructure(brandPayload, new StructureModifier<>(brandPayloadClass)); - packet.getStructures().write(0, structure); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new BrandPayloadReflectionException(e); - } + PacketContainer packet = event.getPacket(); + + InternalStructure structure = new InternalStructure( + new BrandPayload("wait"), + new StructureModifier<>(BrandPayload.class) + ); + + packet.getStructures().write(0, structure); } }); } private void changeBrand(Player player, String brand) { PacketContainer packet = new PacketContainer(PacketType.Play.Server.CUSTOM_PAYLOAD); - Object brandPayload; - try { - brandPayload = brandPayloadConstructor.newInstance(brand); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new BrandPayloadReflectionException(e); - } - InternalStructure structure = new InternalStructure(brandPayload, new StructureModifier<>(brandPayloadClass)); + + InternalStructure structure = new InternalStructure( + new BrandPayload(brand), + new StructureModifier<>(BrandPayload.class) + ); + packet.getStructures().write(0, structure); ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); } - - public static class BrandPayloadReflectionException extends RuntimeException { - public BrandPayloadReflectionException(Exception e) { - super(e); - } - } } diff --git a/src/main/java/eu/m724/tweaks/player/MusicPlayer.java b/src/main/java/eu/m724/tweaks/player/MusicPlayer.java new file mode 100644 index 0000000..6ce1d9f --- /dev/null +++ b/src/main/java/eu/m724/tweaks/player/MusicPlayer.java @@ -0,0 +1,70 @@ +package eu.m724.tweaks.player; + +import de.maxhenkel.voicechat.api.BukkitVoicechatService; +import de.maxhenkel.voicechat.api.VoicechatServerApi; +import de.maxhenkel.voicechat.api.VolumeCategory; +import de.maxhenkel.voicechat.api.audiochannel.AudioPlayer; +import de.maxhenkel.voicechat.api.audiochannel.EntityAudioChannel; +import de.maxhenkel.voicechat.api.opus.OpusEncoderMode; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.UnsupportedAudioFileException; +import java.io.IOException; +import java.util.UUID; + +public class MusicPlayer { + private static final String PLAYER_CATEGORY = "music_player"; + + private VoicechatServerApi voicechat = null; + + private final Plugin plugin; + + public MusicPlayer(Plugin plugin) { + this.plugin = plugin; + } + + public void init() { + BukkitVoicechatService service = plugin.getServer().getServicesManager().load(BukkitVoicechatService.class); + service.registerPlugin(new MyVoicechatPlugin(this)); + } + + void unlock(VoicechatServerApi voicechat) { + VolumeCategory category = voicechat.volumeCategoryBuilder() + .setId(PLAYER_CATEGORY) + .setName("Music players") + .build(); + + voicechat.registerVolumeCategory(category); + + this.voicechat = voicechat; + } + + public void create(Player player) { + UUID channelID = UUID.randomUUID(); + EntityAudioChannel channel = voicechat.createEntityAudioChannel(channelID, voicechat.fromEntity(player)); + + channel.setCategory(PLAYER_CATEGORY); + channel.setDistance(10); + + short[] arr; + try { + AudioInputStream audio = AudioSystem.getAudioInputStream(plugin.getResource("music.flac")); + int samples = (int) (audio.available() / audio.getFrameLength()); + arr = new short[samples]; + for (int i=0; i