From 4b1ae56648f1e118a220014e74a74d17045f842c Mon Sep 17 00:00:00 2001 From: rootEnginear Date: Sun, 15 Oct 2023 02:25:23 +0700 Subject: [PATCH] feat: add files --- README.md | 14 +++-- gradle.properties | 2 +- .../rootenginear/playground/Playground.java | 15 ----- .../proximitychat/ProximityChat.java | 24 ++++++++ .../proximitychat/command/ChannelCommand.java | 54 ++++++++++++++++++ .../proximitychat/mixin/CommandsMixin.java | 24 ++++++++ .../mixin/NetServerHandlerMixin.java | 56 +++++++++++++++++++ .../ServerConfigurationManagerMixin.java | 36 ++++++++++++ .../store/PlayerChannelData.java | 31 ++++++++++ .../struct/PlayerChannelConfig.java | 11 ++++ src/main/resources/fabric.mod.json | 6 +- src/main/resources/playground.mixins.json | 11 ---- src/main/resources/proximitychat.mixins.json | 14 +++++ 13 files changed, 262 insertions(+), 36 deletions(-) delete mode 100644 src/main/java/rootenginear/playground/Playground.java create mode 100644 src/main/java/rootenginear/proximitychat/ProximityChat.java create mode 100644 src/main/java/rootenginear/proximitychat/command/ChannelCommand.java create mode 100644 src/main/java/rootenginear/proximitychat/mixin/CommandsMixin.java create mode 100644 src/main/java/rootenginear/proximitychat/mixin/NetServerHandlerMixin.java create mode 100644 src/main/java/rootenginear/proximitychat/mixin/ServerConfigurationManagerMixin.java create mode 100644 src/main/java/rootenginear/proximitychat/store/PlayerChannelData.java create mode 100644 src/main/java/rootenginear/proximitychat/struct/PlayerChannelConfig.java delete mode 100644 src/main/resources/playground.mixins.json create mode 100644 src/main/resources/proximitychat.mixins.json diff --git a/README.md b/README.md index dfd3d79..fe1d45a 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,16 @@ -# Playground +# Proximity Chat -This is the beginning of awesome mods! +Select your chat channel and keep the chat within a circle. > **Important** -> Required [Babric](https://github.com/Turnip-Labs/babric-instance-repo/releases) to run the mod. +> - This is a **server-side mod**. You must install it on the server. +> - Required [Babric](https://github.com/Turnip-Labs/babric-instance-repo/releases) to run the mod. ## Features -- Feature #1 -- Feature #2 -- Feature #3 +- Chat can be sent to a set radius of the player using proximity channel. +- Select your channel with `/channel global` or `/channel prox`. Your later message will be sent into the selected channel. +- If you're in the global chat, you can quickly send a proximity message by adding `# ` (a hash and 1 space) in front of your message. Eg: `# Is anyone around me?`. +- Set your proximity radius with `/radius `. Eg: `/radius 50`. diff --git a/gradle.properties b/gradle.properties index 3b645be..7528a62 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,4 +12,4 @@ loader_version=0.14.19-babric.1-bta # Mod mod_version=1.0.0 mod_group=rootenginear -mod_name=playground +mod_name=proximitychat diff --git a/src/main/java/rootenginear/playground/Playground.java b/src/main/java/rootenginear/playground/Playground.java deleted file mode 100644 index 660347b..0000000 --- a/src/main/java/rootenginear/playground/Playground.java +++ /dev/null @@ -1,15 +0,0 @@ -package rootenginear.playground; - -import net.fabricmc.api.ModInitializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class Playground implements ModInitializer { - public static final String MOD_ID = "playground"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - - @Override - public void onInitialize() { - LOGGER.info("Playground initialized."); - } -} diff --git a/src/main/java/rootenginear/proximitychat/ProximityChat.java b/src/main/java/rootenginear/proximitychat/ProximityChat.java new file mode 100644 index 0000000..cd22184 --- /dev/null +++ b/src/main/java/rootenginear/proximitychat/ProximityChat.java @@ -0,0 +1,24 @@ +package rootenginear.proximitychat; + +import net.fabricmc.api.DedicatedServerModInitializer; +import net.minecraft.core.net.PropertyManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +public class ProximityChat implements DedicatedServerModInitializer { + public static final String MOD_ID = "proximitychat"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + + public static int RADIUS; + + @Override + public void onInitializeServer() { + PropertyManager propertyManagerObj = new PropertyManager(new File("server.properties")); + + RADIUS = propertyManagerObj.getIntProperty("default-proximity-radius", 50); + + LOGGER.info("Proximity Chat initialized."); + } +} diff --git a/src/main/java/rootenginear/proximitychat/command/ChannelCommand.java b/src/main/java/rootenginear/proximitychat/command/ChannelCommand.java new file mode 100644 index 0000000..9c4d35b --- /dev/null +++ b/src/main/java/rootenginear/proximitychat/command/ChannelCommand.java @@ -0,0 +1,54 @@ +package rootenginear.proximitychat.command; + +import net.minecraft.core.net.command.CommandError; +import net.minecraft.core.net.command.CommandHandler; +import net.minecraft.core.net.command.CommandSender; +import net.minecraft.core.net.command.ServerCommand; +import net.minecraft.server.MinecraftServer; +import rootenginear.proximitychat.struct.PlayerChannelConfig; + +import static rootenginear.proximitychat.store.PlayerChannelData.getPlayerChannelData; +import static rootenginear.proximitychat.store.PlayerChannelData.setPlayerChannelData; + +public class ChannelCommand extends ServerCommand { + public ChannelCommand(MinecraftServer server) { + super(server, "channel", "ch"); + } + + @Override + public boolean execute(CommandHandler handler, CommandSender sender, String[] args) { + if (!sender.isPlayer()) { + throw new CommandError("Must be used by a player!"); + } + if (args.length > 1) { + return false; + } + String name = sender.getName(); + if (args.length == 0) { + PlayerChannelConfig cfg = getPlayerChannelData(name); + sender.sendMessage(name + "'s current channel is: " + (cfg.isGlobal ? "Global" : "Proximity")); + return true; + } + switch (args[0]) { + case "global": + case "proximity": + case "prox": + setPlayerChannelData(name, args[0]); + sender.sendMessage("Changed " + name + "'s channel to: " + (args[0].equals("global") ? "Global" : "Proximity")); + return true; + default: + return false; + } + } + + @Override + public boolean opRequired(String[] args) { + return false; + } + + @Override + public void sendCommandSyntax(CommandHandler handler, CommandSender sender) { + sender.sendMessage("/channel"); + sender.sendMessage("/channel "); + } +} diff --git a/src/main/java/rootenginear/proximitychat/mixin/CommandsMixin.java b/src/main/java/rootenginear/proximitychat/mixin/CommandsMixin.java new file mode 100644 index 0000000..2e04b37 --- /dev/null +++ b/src/main/java/rootenginear/proximitychat/mixin/CommandsMixin.java @@ -0,0 +1,24 @@ +package rootenginear.proximitychat.mixin; + +import net.minecraft.core.net.command.Command; +import net.minecraft.core.net.command.Commands; +import net.minecraft.server.MinecraftServer; +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; +import rootenginear.proximitychat.command.ChannelCommand; + +import java.util.List; + +@Mixin(value = {Commands.class}, remap = false) +public class CommandsMixin { + @Shadow + public static List commands; + + @Inject(method = "initServerCommands", at = @At("TAIL")) + private static void addChannelCmd(MinecraftServer server, CallbackInfo ci) { + commands.add(new ChannelCommand(server)); + } +} diff --git a/src/main/java/rootenginear/proximitychat/mixin/NetServerHandlerMixin.java b/src/main/java/rootenginear/proximitychat/mixin/NetServerHandlerMixin.java new file mode 100644 index 0000000..7f036da --- /dev/null +++ b/src/main/java/rootenginear/proximitychat/mixin/NetServerHandlerMixin.java @@ -0,0 +1,56 @@ +package rootenginear.proximitychat.mixin; + +import net.minecraft.core.net.packet.Packet3Chat; +import net.minecraft.server.entity.player.EntityPlayerMP; +import net.minecraft.server.net.ServerConfigurationManager; +import net.minecraft.server.net.handler.NetServerHandler; +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.Redirect; +import rootenginear.proximitychat.struct.PlayerChannelConfig; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static rootenginear.proximitychat.store.PlayerChannelData.getPlayerChannelData; + +@Mixin(value = {NetServerHandler.class}, remap = false) +public class NetServerHandlerMixin { + @Shadow + private EntityPlayerMP playerEntity; + + @Redirect( + method = "handleChat(Lnet/minecraft/core/net/packet/Packet3Chat;)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/net/ServerConfigurationManager;sendEncryptedChatToAllPlayers(Ljava/lang/String;)V" + ) + ) + private void proximityChat(ServerConfigurationManager instance, String s) { + Pattern playerChatPattern = Pattern.compile("<(.+?)> §0(.+)"); + Matcher result = playerChatPattern.matcher(s); + + if (!result.matches()) { + instance.sendEncryptedChatToAllPlayers(s); + return; + } + + String playerName = result.group(1); + String msg = result.group(2); + + PlayerChannelConfig playerData = getPlayerChannelData(playerName); + if (playerData.isGlobal || msg.startsWith("# ")) { + instance.sendEncryptedChatToAllPlayers(s.replaceFirst("# ", "")); + return; + } + instance.sendPacketToPlayersAroundPoint( + this.playerEntity.x, + this.playerEntity.y, + this.playerEntity.z, + playerData.radius, + this.playerEntity.dimension, + new Packet3Chat("<✉ " + playerName + "> §0" + msg.replaceFirst("# ", "")) + ); + } +} diff --git a/src/main/java/rootenginear/proximitychat/mixin/ServerConfigurationManagerMixin.java b/src/main/java/rootenginear/proximitychat/mixin/ServerConfigurationManagerMixin.java new file mode 100644 index 0000000..18b1376 --- /dev/null +++ b/src/main/java/rootenginear/proximitychat/mixin/ServerConfigurationManagerMixin.java @@ -0,0 +1,36 @@ +package rootenginear.proximitychat.mixin; + +import net.minecraft.core.entity.player.EntityPlayer; +import net.minecraft.core.net.packet.Packet; +import net.minecraft.core.net.packet.Packet3Chat; +import net.minecraft.core.util.helper.AES; +import net.minecraft.server.entity.player.EntityPlayerMP; +import net.minecraft.server.net.ServerConfigurationManager; +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; + +import java.util.List; + +@Mixin(value = {ServerConfigurationManager.class}, remap = false) +public class ServerConfigurationManagerMixin { + @Shadow + public List playerEntities; + + @Inject(method = "func_28171_a", at = @At("HEAD"), cancellable = true) + public void sendEncryptedChatToPlayersAroundPoint(EntityPlayer entityplayer, double d, double d1, double d2, double d3, int i, Packet packet, CallbackInfo ci) { + if (packet instanceof Packet3Chat) { + for (EntityPlayerMP playerEntity : this.playerEntities) { + double d6; + double d5; + double d4; + if (playerEntity == entityplayer || playerEntity.dimension != i || !((d4 = d - playerEntity.x) * d4 + (d5 = d1 - playerEntity.y) * d5 + (d6 = d2 - playerEntity.z) * d6 < d3 * d3)) + continue; + playerEntity.playerNetServerHandler.sendPacket(new Packet3Chat(((Packet3Chat) packet).message, AES.keyChain.get(playerEntity.username))); + } + ci.cancel(); + } + } +} diff --git a/src/main/java/rootenginear/proximitychat/store/PlayerChannelData.java b/src/main/java/rootenginear/proximitychat/store/PlayerChannelData.java new file mode 100644 index 0000000..14e6b29 --- /dev/null +++ b/src/main/java/rootenginear/proximitychat/store/PlayerChannelData.java @@ -0,0 +1,31 @@ +package rootenginear.proximitychat.store; + +import rootenginear.proximitychat.ProximityChat; +import rootenginear.proximitychat.struct.PlayerChannelConfig; + +import java.util.HashMap; + +public class PlayerChannelData { + public static HashMap playerProxData = new HashMap<>(); + + public static PlayerChannelConfig getPlayerChannelData(String playerName) { + if (playerProxData.containsKey(playerName)) return playerProxData.get(playerName); + + PlayerChannelConfig t = new PlayerChannelConfig(true, ProximityChat.RADIUS); + playerProxData.put(playerName, t); + return t; + } + + public static void setPlayerChannelData(String playerName, String mode) { + if (!mode.equals("global") && !mode.equals("proximity") && !mode.equals("prox")) return; + + if (!playerProxData.containsKey(playerName)) { + playerProxData.put(playerName, new PlayerChannelConfig(mode.equals("global"), ProximityChat.RADIUS)); + return; + } + + PlayerChannelConfig t = playerProxData.get(playerName); + t.isGlobal = mode.equals("global"); + playerProxData.replace(playerName, t); + } +} diff --git a/src/main/java/rootenginear/proximitychat/struct/PlayerChannelConfig.java b/src/main/java/rootenginear/proximitychat/struct/PlayerChannelConfig.java new file mode 100644 index 0000000..9c5672e --- /dev/null +++ b/src/main/java/rootenginear/proximitychat/struct/PlayerChannelConfig.java @@ -0,0 +1,11 @@ +package rootenginear.proximitychat.struct; + +public class PlayerChannelConfig { + public boolean isGlobal; + public int radius; + + public PlayerChannelConfig(boolean isGlobal, int radius) { + this.isGlobal = isGlobal; + this.radius = radius; + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 4d34a7b..927ba23 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -16,12 +16,12 @@ "license": "CC0-1.0", "environment": "*", "entrypoints": { - "main": [ - "rootenginear.playground.Playground" + "server": [ + "rootenginear.proximitychat.ProximityChat" ] }, "mixins": [ - "playground.mixins.json" + "proximitychat.mixins.json" ], "depends": { "fabricloader": ">=0.13.3" diff --git a/src/main/resources/playground.mixins.json b/src/main/resources/playground.mixins.json deleted file mode 100644 index 97606d0..0000000 --- a/src/main/resources/playground.mixins.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "rootenginear.playground.mixin", - "compatibilityLevel": "JAVA_8", - "mixins": [ - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/src/main/resources/proximitychat.mixins.json b/src/main/resources/proximitychat.mixins.json new file mode 100644 index 0000000..88f36d4 --- /dev/null +++ b/src/main/resources/proximitychat.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "rootenginear.proximitychat.mixin", + "compatibilityLevel": "JAVA_8", + "server": [ + "CommandsMixin", + "NetServerHandlerMixin", + "ServerConfigurationManagerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +}