From 85045e1e4a15e0a5657d189e83dd202a2c37f2b0 Mon Sep 17 00:00:00 2001 From: Yuuta Liang Date: Wed, 13 Jul 2022 11:16:27 -0700 Subject: First Commit Signed-off-by: Trumeet --- .../moe/ymc/acron/mixin/CommandManagerMixin.java | 38 +++++++++++++ .../moe/ymc/acron/mixin/LivingEntityMixin.java | 41 ++++++++++++++ .../acron/mixin/MinecraftDedicatedServerMixin.java | 21 +++++++ .../moe/ymc/acron/mixin/MinecraftServerMixin.java | 32 +++++++++++ .../mixin/ServerLoginNetworkHandlerMixin.java | 47 ++++++++++++++++ .../moe/ymc/acron/mixin/ServerNetworkIoMixin.java | 65 ++++++++++++++++++++++ .../acron/mixin/ServerPlayNetworkHandlerMixin.java | 43 ++++++++++++++ .../ymc/acron/mixin/ServerPlayerEntityMixin.java | 32 +++++++++++ 8 files changed, 319 insertions(+) create mode 100644 src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java create mode 100644 src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java create mode 100644 src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java create mode 100644 src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java create mode 100644 src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java create mode 100644 src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java create mode 100644 src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java create mode 100644 src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java (limited to 'src/main/java/moe/ymc/acron/mixin') diff --git a/src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java b/src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java new file mode 100644 index 0000000..20de2e7 --- /dev/null +++ b/src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java @@ -0,0 +1,38 @@ +package moe.ymc.acron.mixin; + +import com.mojang.brigadier.CommandDispatcher; +import moe.ymc.acron.config.ConfigReloadCmd; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Final; +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 static net.minecraft.server.command.CommandManager.literal; + + +@Mixin(CommandManager.class) +public abstract class CommandManagerMixin { + private static final Logger LOGGER = LogManager.getLogger(); + + @Shadow + @Final + private CommandDispatcher dispatcher; + + @Inject(method = "", at = @At("RETURN")) + private void onRegister(CommandManager.RegistrationEnvironment arg, CallbackInfo ci) { + LOGGER.debug("onRegister"); + dispatcher.register( + literal("acron").then( + literal("rule").then( + literal("update").requires(player -> player.hasPermissionLevel(4)) + .executes(new ConfigReloadCmd())) + ) + ); + } +} diff --git a/src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java b/src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java new file mode 100644 index 0000000..a4cb744 --- /dev/null +++ b/src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java @@ -0,0 +1,41 @@ +package moe.ymc.acron.mixin; + +import moe.ymc.acron.s2c.Entity; +import moe.ymc.acron.s2c.EventEntityDeath; +import moe.ymc.acron.s2c.EventQueue; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.damage.DamageTracker; +import net.minecraft.world.World; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +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; + +@Mixin(LivingEntity.class) +public abstract class LivingEntityMixin extends net.minecraft.entity.Entity { + private static final Logger LOGGER = LogManager.getLogger(); + + @Shadow public abstract DamageTracker getDamageTracker(); + + public LivingEntityMixin(EntityType type, World world) { + super(type, world); + } + + // The original onDeath() will call getDamageTracker().update(), + // which clears all recent damages, making the getDeathMessage() + // output always generic. + // Thus, we need to use @At("HEAD") to get the injection called + // before it does anything else. + @Inject(at = @At("HEAD"), method = "onDeath") + public void onDeath(DamageSource source, CallbackInfo ci) { + LOGGER.debug("onDeath[{}]", + getUuid()); + EventQueue.enqueue(new EventEntityDeath(new Entity(this), + getDamageTracker().getDeathMessage().getString())); + } +} \ No newline at end of file diff --git a/src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java b/src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java new file mode 100644 index 0000000..50af0b4 --- /dev/null +++ b/src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java @@ -0,0 +1,21 @@ +package moe.ymc.acron.mixin; + +import moe.ymc.acron.MinecraftServerHolder; +import net.minecraft.server.dedicated.MinecraftDedicatedServer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MinecraftDedicatedServer.class) +public class MinecraftDedicatedServerMixin { + private static final Logger LOGGER = LogManager.getLogger(); + + @Inject(at = @At("RETURN"), method = "") + private void init(CallbackInfo info) { + LOGGER.debug("init"); + MinecraftServerHolder.setServer((MinecraftDedicatedServer) (Object) this); + } +} diff --git a/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java b/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java new file mode 100644 index 0000000..fc2a88c --- /dev/null +++ b/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java @@ -0,0 +1,32 @@ +package moe.ymc.acron.mixin; + +import moe.ymc.acron.s2c.EventLagging; +import moe.ymc.acron.s2c.EventQueue; +import net.minecraft.server.MinecraftServer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(MinecraftServer.class) +public class MinecraftServerMixin { + private static final Logger LOGGER = LogManager.getLogger(); + + @Redirect(method = "runServer()V", + at = @At(value = "INVOKE", + target = "Lorg/apache/logging/log4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V")) + private void startServer(Logger instance, String s, Object o1, Object o2) { + instance.warn(s, o1, o2); + if (s.equals("Can't keep up! " + + "Is the server overloaded? " + + "Running {}ms or {} ticks behind") && + o1 instanceof Long && + o2 instanceof Long) { + LOGGER.debug("Lag: {}ms, {} ticks", + o1, + o2); + EventQueue.enqueue(new EventLagging((long) o1, (long) o2)); + } + } +} diff --git a/src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java b/src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java new file mode 100644 index 0000000..7e4115e --- /dev/null +++ b/src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java @@ -0,0 +1,47 @@ +package moe.ymc.acron.mixin; + +import com.mojang.authlib.GameProfile; +import moe.ymc.acron.s2c.Entity; +import moe.ymc.acron.s2c.EventDisconnected; +import moe.ymc.acron.s2c.EventPlayerJoined; +import moe.ymc.acron.s2c.EventQueue; +import net.minecraft.network.ClientConnection; +import net.minecraft.server.network.ServerLoginNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; +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; + +@Mixin(ServerLoginNetworkHandler.class) +public class ServerLoginNetworkHandlerMixin { + private static final Logger LOGGER = LogManager.getLogger(); + + @Shadow + @Nullable + GameProfile profile; + + @Shadow + @Final + public ClientConnection connection; + + @Inject(at = @At("RETURN"), method = "onDisconnected") + private void onDisconnected(Text reason, CallbackInfo ci) { + EventQueue.enqueue(new EventDisconnected(profile == null ? null : + new Entity(profile), + reason.getString())); + } + + @Inject(at = @At("RETURN"), method = "addToServer") + private void addToServer(ServerPlayerEntity entity, CallbackInfo ci) { + LOGGER.debug("addToServer: {}", + entity.getUuid()); + EventQueue.enqueue(new EventPlayerJoined(new Entity(entity))); + } +} diff --git a/src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java b/src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java new file mode 100644 index 0000000..7c9b60b --- /dev/null +++ b/src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java @@ -0,0 +1,65 @@ +package moe.ymc.acron.mixin; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.MultithreadEventLoopGroup; +import io.netty.channel.ServerChannel; +import io.netty.channel.epoll.Epoll; +import io.netty.channel.epoll.EpollServerSocketChannel; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import moe.ymc.acron.config.Config; +import moe.ymc.acron.net.AcronInitializer; +import net.minecraft.server.ServerNetworkIo; +import net.minecraft.util.Lazy; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Final; +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; + +import static net.minecraft.server.ServerNetworkIo.EPOLL_CHANNEL; + +@Mixin(ServerNetworkIo.class) +public class ServerNetworkIoMixin { + private static final Logger LOGGER = LogManager.getLogger(); + + @Shadow + @Final + private List channels; + + @Shadow + @Final + public static Lazy DEFAULT_CHANNEL; + + @Inject(at = @At("RETURN"), method = "") + private void init(CallbackInfo info) { + LOGGER.debug("Adding Acron channel."); + Lazy group; + Class channel; + if (Epoll.isAvailable() && Config.getGlobalConfig().useNativeTransport()) { + channel = EpollServerSocketChannel.class; + group = EPOLL_CHANNEL; + LOGGER.info("Using native transport."); + } else { + channel = NioServerSocketChannel.class; + group = DEFAULT_CHANNEL; + LOGGER.info("Not using native transport due to " + + "it is either disabled in acron.json or not available."); + } + channels.add(new ServerBootstrap() + .channel(channel) + .childHandler(new AcronInitializer()) + .group(group.get()) + .localAddress(Config.getGlobalConfig().address(), + Config.getGlobalConfig().port()) + .bind() + .syncUninterruptibly()); + + } +} diff --git a/src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java b/src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java new file mode 100644 index 0000000..0bcfb0a --- /dev/null +++ b/src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java @@ -0,0 +1,43 @@ +package moe.ymc.acron.mixin; + +import moe.ymc.acron.s2c.Entity; +import moe.ymc.acron.s2c.EventDisconnected; +import moe.ymc.acron.s2c.EventPlayerMessage; +import moe.ymc.acron.s2c.EventQueue; +import net.minecraft.network.ClientConnection; +import net.minecraft.server.filter.TextStream; +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Final; +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; + +@Mixin(ServerPlayNetworkHandler.class) +public class ServerPlayNetworkHandlerMixin { + private static final Logger LOGGER = LogManager.getLogger(); + + @Shadow + public ServerPlayerEntity player; + + @Shadow + @Final + public ClientConnection connection; + + @Inject(at = @At("RETURN"), method = "handleMessage") + private void handleMessage(TextStream.Message message, CallbackInfo ci) { + EventQueue.enqueue(new EventPlayerMessage(new Entity(player), + message.getRaw())); + } + + @Inject(at = @At("RETURN"), method = "onDisconnected") + private void onDisconnected(Text reason, CallbackInfo ci) { + EventQueue.enqueue(new EventDisconnected(new Entity(player), + reason.getString())); + } +} diff --git a/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java b/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java new file mode 100644 index 0000000..17c8517 --- /dev/null +++ b/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java @@ -0,0 +1,32 @@ +package moe.ymc.acron.mixin; + +import moe.ymc.acron.s2c.EventEntityDeath; +import moe.ymc.acron.s2c.EventQueue; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.world.World; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerPlayerEntity.class) +public abstract class ServerPlayerEntityMixin extends LivingEntity { + private static final Logger LOGGER = LogManager.getLogger(); + + public ServerPlayerEntityMixin(EntityType entityType, World world) { + super(entityType, world); + } + + @Inject(at = @At("HEAD"), method = "onDeath") + public void onDeath(DamageSource source, CallbackInfo ci) { + LOGGER.debug("onDeath: {}", + getUuid()); + EventQueue.enqueue(new EventEntityDeath(new moe.ymc.acron.s2c.Entity(this), + getDamageTracker().getDeathMessage().getString())); + } +} \ No newline at end of file -- cgit v1.2.3