diff options
Diffstat (limited to 'mod/src/main/java/moe/ymc/acron/mixin')
8 files changed, 320 insertions, 0 deletions
diff --git a/mod/src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java b/mod/src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java new file mode 100644 index 0000000..9aaed2e --- /dev/null +++ b/mod/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 AC_LOGGER = LogManager.getLogger(); + + @Shadow + @Final + private CommandDispatcher<ServerCommandSource> dispatcher; + + @Inject(method = "<init>", at = @At("RETURN")) + private void onRegister(CommandManager.RegistrationEnvironment arg, CallbackInfo ci) { + AC_LOGGER.debug("onRegister"); + dispatcher.register( + literal("acron").requires(player -> player.hasPermissionLevel(4)).then( + literal("rule").then( + literal("update") + .executes(new ConfigReloadCmd())) + ) + ); + } +} diff --git a/mod/src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java b/mod/src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java new file mode 100644 index 0000000..9e16569 --- /dev/null +++ b/mod/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.EventQueue; +import moe.ymc.acron.s2c.event.EventEntityDeath; +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 AC_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) { + AC_LOGGER.debug("onDeath[{}]", + getUuid()); + EventQueue.enqueue(new EventEntityDeath(new Entity(this), + getDamageTracker().getDeathMessage().getString())); + } +}
\ No newline at end of file diff --git a/mod/src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java b/mod/src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java new file mode 100644 index 0000000..32d2fbf --- /dev/null +++ b/mod/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 AC_LOGGER = LogManager.getLogger(); + + @Inject(at = @At("RETURN"), method = "<init>") + private void init(CallbackInfo info) { + AC_LOGGER.debug("init"); + MinecraftServerHolder.setServer((MinecraftDedicatedServer) (Object) this); + } +} diff --git a/mod/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java b/mod/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java new file mode 100644 index 0000000..cb813b4 --- /dev/null +++ b/mod/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java @@ -0,0 +1,33 @@ +package moe.ymc.acron.mixin; + +import moe.ymc.acron.s2c.EventQueue; +import moe.ymc.acron.s2c.event.EventLagging; +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 AC_LOGGER = LogManager.getLogger(); + + @Redirect(method = "runServer()V", + remap = false, + 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) { + AC_LOGGER.debug("Lag: {}ms, {} ticks", + o1, + o2); + EventQueue.enqueue(new EventLagging((long) o1, (long) o2)); + } + } +} diff --git a/mod/src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java b/mod/src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java new file mode 100644 index 0000000..94a48b5 --- /dev/null +++ b/mod/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.EventQueue; +import moe.ymc.acron.s2c.event.EventDisconnected; +import moe.ymc.acron.s2c.event.EventPlayerJoined; +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 AC_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) { + AC_LOGGER.debug("addToServer: {}", + entity.getUuid()); + EventQueue.enqueue(new EventPlayerJoined(new Entity(entity))); + } +} diff --git a/mod/src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java b/mod/src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java new file mode 100644 index 0000000..f49914e --- /dev/null +++ b/mod/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 AC_LOGGER = LogManager.getLogger(); + + @Shadow + @Final + private List<ChannelFuture> channels; + + @Shadow + @Final + public static Lazy<NioEventLoopGroup> DEFAULT_CHANNEL; + + @Inject(at = @At("RETURN"), method = "<init>") + private void init(CallbackInfo info) { + AC_LOGGER.debug("Adding Acron channel."); + Lazy<? extends MultithreadEventLoopGroup> group; + Class<? extends ServerChannel> channel; + if (Epoll.isAvailable() && Config.getGlobalConfig().useNativeTransport()) { + channel = EpollServerSocketChannel.class; + group = EPOLL_CHANNEL; + AC_LOGGER.info("Using native transport."); + } else { + channel = NioServerSocketChannel.class; + group = DEFAULT_CHANNEL; + AC_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/mod/src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java b/mod/src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java new file mode 100644 index 0000000..58bef78 --- /dev/null +++ b/mod/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.EventQueue; +import moe.ymc.acron.s2c.event.EventDisconnected; +import moe.ymc.acron.s2c.event.EventPlayerMessage; +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 AC_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/mod/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java b/mod/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java new file mode 100644 index 0000000..4c6758b --- /dev/null +++ b/mod/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java @@ -0,0 +1,32 @@ +package moe.ymc.acron.mixin; + +import moe.ymc.acron.s2c.EventQueue; +import moe.ymc.acron.s2c.event.EventEntityDeath; +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 AC_LOGGER = LogManager.getLogger(); + + public ServerPlayerEntityMixin(EntityType<? extends LivingEntity> entityType, World world) { + super(entityType, world); + } + + @Inject(at = @At("HEAD"), method = "onDeath") + public void onDeath(DamageSource source, CallbackInfo ci) { + AC_LOGGER.debug("onDeath: {}", + getUuid()); + EventQueue.enqueue(new EventEntityDeath(new moe.ymc.acron.s2c.Entity(this), + getDamageTracker().getDeathMessage().getString())); + } +}
\ No newline at end of file |