From eb916c395b39cc682c483d717ae12e8994ed669e Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Tue, 16 Jan 2018 16:03:04 +0100 Subject: [PATCH] Add forge server mod for ReplayRestrictions (fixes #102) --- .../restrictions/ReplayModRestrictions.java | 95 +++++++++++++++++++ .../com/replaymod/restrictions/Setting.java | 19 ++++ src/main/resources/mcmod.info | 16 ++++ 3 files changed, 130 insertions(+) create mode 100644 src/main/java/com/replaymod/restrictions/ReplayModRestrictions.java create mode 100644 src/main/java/com/replaymod/restrictions/Setting.java diff --git a/src/main/java/com/replaymod/restrictions/ReplayModRestrictions.java b/src/main/java/com/replaymod/restrictions/ReplayModRestrictions.java new file mode 100644 index 00000000..9a0fbd28 --- /dev/null +++ b/src/main/java/com/replaymod/restrictions/ReplayModRestrictions.java @@ -0,0 +1,95 @@ +package com.replaymod.restrictions; + +import com.replaymod.core.SettingsRegistry; +import com.replaymod.core.utils.Restrictions; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandler; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.EventBus; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.PlayerEvent; +import net.minecraftforge.fml.common.network.FMLEmbeddedChannel; +import net.minecraftforge.fml.common.network.FMLOutboundHandler; +import net.minecraftforge.fml.common.network.NetworkRegistry; +import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; +import net.minecraftforge.fml.relauncher.Side; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +@Mod(modid = ReplayModRestrictions.MOD_ID, + version = "@MOD_VERSION@", + acceptedMinecraftVersions = "@MC_VERSION@", + acceptableRemoteVersions = "*", + serverSideOnly = true, + useMetadata = true) +public class ReplayModRestrictions { + public static final String MOD_ID = "replaymod-restrictions"; + + public static Logger LOGGER; + + private final SettingsRegistry settingsRegistry = new SettingsRegistry(); + private FMLEmbeddedChannel channel; + + @Mod.EventHandler + public void preInit(FMLPreInitializationEvent event) { + LOGGER = event.getModLog(); + + Configuration config = new Configuration(event.getSuggestedConfigurationFile()); + config.load(); + settingsRegistry.setConfiguration(config); + + settingsRegistry.register(Setting.class); + } + + @Mod.EventHandler + public void init(FMLInitializationEvent event) { + EventBus bus = FMLCommonHandler.instance().bus(); + bus.register(this); + + channel = NetworkRegistry.INSTANCE.newChannel(Restrictions.PLUGIN_CHANNEL, new RestrictionsChannelHandler()).get(Side.SERVER); + } + + @Mod.EventHandler + public void postInit(FMLPostInitializationEvent event) throws IOException { + settingsRegistry.save(); // Save default values to disk + } + + @ChannelHandler.Sharable + private static class RestrictionsChannelHandler extends ChannelDuplexHandler {} + + @SubscribeEvent + public void onUserJoin(PlayerEvent.PlayerLoggedInEvent event) { + Map restrictions = new HashMap<>(); + if (settingsRegistry.get(Setting.NO_XRAY)) restrictions.put("no_xray", new byte[0]); + if (settingsRegistry.get(Setting.NO_NOCLIP)) restrictions.put("no_noclip", new byte[0]); + if (settingsRegistry.get(Setting.ONLY_FIRST_PERSON)) restrictions.put("only_first_person", new byte[0]); + if (settingsRegistry.get(Setting.ONLY_RECORDING_PLAYER)) restrictions.put("only_recording_player", new byte[0]); + if (settingsRegistry.get(Setting.HIDE_COORDINATES)) restrictions.put("hide_coordinates", new byte[0]); + + PacketBuffer buf = new PacketBuffer(Unpooled.buffer()); + for (Map.Entry e : restrictions.entrySet()) { + byte[] bytes = e.getKey().getBytes(); + buf.writeByte(bytes.length); + buf.writeBytes(bytes); + buf.writeByte(1); + buf.writeBytes(e.getValue()); + } + + FMLProxyPacket packet = new FMLProxyPacket(buf, Restrictions.PLUGIN_CHANNEL); + + channel.attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER); + channel.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(event.player); + channel.writeAndFlush(packet).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); + } +} diff --git a/src/main/java/com/replaymod/restrictions/Setting.java b/src/main/java/com/replaymod/restrictions/Setting.java new file mode 100644 index 00000000..7a36e936 --- /dev/null +++ b/src/main/java/com/replaymod/restrictions/Setting.java @@ -0,0 +1,19 @@ +package com.replaymod.restrictions; + +import com.replaymod.core.SettingsRegistry; + +public final class Setting extends SettingsRegistry.SettingKeys { + public static final Setting NO_XRAY = make("no_xray", false); + public static final Setting NO_NOCLIP = make("no_noclip", false); + public static final Setting ONLY_FIRST_PERSON = make("only_first_person", false); + public static final Setting ONLY_RECORDING_PLAYER = make("only_recording_player", false); + public static final Setting HIDE_COORDINATES = make("hide_coordinates", false); + + private static Setting make(String key, T defaultValue) { + return new Setting<>("restrictions", key, defaultValue); + } + + public Setting(String category, String key, T defaultValue) { + super(category, key, null, defaultValue); + } +} diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 065f181d..3cd255eb 100755 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -134,6 +134,22 @@ "screenshots": [], "dependencies": [] }, + { + "modid": "replaymod-restrictions", + "name": "Replay Mod - Restrictions", + "description": "Server-side Restrictions Module of the ReplayMod - Restrict what clients can do in replays", + "version": "${version}", + "mcversion": "${mcversion}", + "url": "https://replaymod.com", + "updateUrl": "https://replaymod.com/download", + "authorList": [ + "CrushedPixel", + "johni0702" + ], + "logoFile": "replaymod_logo.png", + "screenshots": [], + "dependencies": [] + }, { "modid": "replaymod-compat", "name": "Replay Mod - Compatibility",