aboutsummaryrefslogtreecommitdiff
path: root/mod/src/main/java/moe/ymc/acron/mixin
diff options
context:
space:
mode:
Diffstat (limited to 'mod/src/main/java/moe/ymc/acron/mixin')
-rw-r--r--mod/src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java38
-rw-r--r--mod/src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java41
-rw-r--r--mod/src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java21
-rw-r--r--mod/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java33
-rw-r--r--mod/src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java47
-rw-r--r--mod/src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java65
-rw-r--r--mod/src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java43
-rw-r--r--mod/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java32
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