Skip to content

Commit

Permalink
✨ More events!
Browse files Browse the repository at this point in the history
  • Loading branch information
XyperCode committed Dec 13, 2024
1 parent 7da8880 commit 8f96cff
Show file tree
Hide file tree
Showing 21 changed files with 337 additions and 2 deletions.
22 changes: 22 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,25 @@ tasks.register("javadoc", Copy) {
from(project(":common").javadoc.outputs)
into(file("build/docs/javadoc"))
}

tasks.register("jar", Copy) {
dependsOn "common:build"
dependsOn "forge:build"
dependsOn "neoforge:build"
dependsOn "fabric:build"

doFirst {
mkdir file("build/libs")
}

from(project(":common").jar.outputs)
from(project(":forge").jar.outputs)
from(project(":neoforge").jar.outputs)
from(project(":fabric").jar.outputs)
into(file("build/libs"))
}

tasks.register("build") {
dependsOn "javadoc"
dependsOn "jar"
}
6 changes: 6 additions & 0 deletions common/src/main/java/dev/ultreon/mods/xinexlib/Env.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.ultreon.mods.xinexlib;

public enum Env {
CLIENT,
SERVER
}
51 changes: 51 additions & 0 deletions common/src/main/java/dev/ultreon/mods/xinexlib/EnvExecutor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package dev.ultreon.mods.xinexlib;

import dev.ultreon.mods.xinexlib.platform.Services;

import java.util.concurrent.Callable;
import java.util.function.Supplier;

public class EnvExecutor {
public static void runInEnv(Env env, Supplier<Runnable> runnable) {
if (Services.getEnv() == env) runnable.get().run();
}

public static void runInEnv(Env env, Supplier<Runnable> runnable, Runnable fallback) {
if (Services.getEnv() == env) runnable.get().run();
else fallback.run();
}

public static <T> void runInEnvSpecific(Supplier<Runnable> client, Supplier<Runnable> server) {
if (Services.getEnv() == Env.CLIENT) client.get().run();
else server.get().run();
}

public static <T> T getInEnv(Env env, Supplier<Supplier<T>> supplier, Supplier<T> fallback) {
if (Services.getEnv() == env) return supplier.get().get();
return fallback.get();
}

public static <T> T getInEnv(Env env, Supplier<Supplier<T>> supplier) {
return getInEnv(env, supplier, () -> null);
}

public static <T> T getInEnvSpecific(Supplier<Supplier<T>> client, Supplier<Supplier<T>> server) {
if (Services.getEnv() == Env.CLIENT) return client.get().get();
return server.get().get();
}

public static <T> T callInEnv(Env env, Supplier<Callable<T>> supplier) throws Exception {
if (Services.getEnv() == env) return supplier.get().call();
return null;
}

public static <T> T callInEnv(Env env, Supplier<Callable<T>> supplier, Callable<T> fallback) throws Exception {
if (Services.getEnv() == env) return supplier.get().call();
return fallback.call();
}

public static <T> T callInEnvSpecific(Supplier<Callable<T>> client, Supplier<Callable<T>> server) throws Exception {
if (Services.getEnv() == Env.CLIENT) return client.get().call();
return server.get().call();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.ultreon.mods.xinexlib.client.event;

import dev.ultreon.mods.xinexlib.event.player.PlayerEvent;
import net.minecraft.client.player.LocalPlayer;

public interface LocalPlayerEvent extends PlayerEvent {
LocalPlayer getPlayer();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package dev.ultreon.mods.xinexlib.client.event;

import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.entity.player.Player;

public class LocalPlayerJoinEvent implements LocalPlayerEvent {
private final LocalPlayer localPlayer;

public LocalPlayerJoinEvent(LocalPlayer localPlayer) {
this.localPlayer = localPlayer;
}

@Override
public LocalPlayer getPlayer() {
return localPlayer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dev.ultreon.mods.xinexlib.client.event;

import net.minecraft.client.player.LocalPlayer;

public class LocalPlayerQuitEvent implements LocalPlayerEvent {
private final LocalPlayer localPlayer;

public LocalPlayerQuitEvent(LocalPlayer localPlayer) {
this.localPlayer = localPlayer;
}

@Override
public LocalPlayer getPlayer() {
return localPlayer;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package dev.ultreon.mods.xinexlib.event.player;

import dev.ultreon.mods.xinexlib.event.entity.EntityEvent;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;

public interface ServerPlayerEvent extends PlayerEvent, ServerEvent {
@Override
ServerPlayer getPlayer();

@Override
default MinecraftServer getServer() {
return getPlayer().getServer();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package dev.ultreon.mods.xinexlib.event.server;

import dev.ultreon.mods.xinexlib.event.level.ServerLevelEvent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.ProgressListener;

import java.util.Objects;

public class ServerLevelSaveEvent implements ServerLevelEvent {
private final ServerLevel serverLevel;
private final ProgressListener progress;
private final boolean flush;
private final boolean skipSave;

public ServerLevelSaveEvent(ServerLevel serverLevel, ProgressListener progress, boolean flush, boolean skipSave) {
this.serverLevel = serverLevel;
this.progress = progress;
this.flush = flush;
this.skipSave = skipSave;
}

@Override
public ServerLevel getServerLevel() {
return serverLevel;
}

public ProgressListener getProgress() {
return progress;
}

public boolean isFlush() {
return flush;
}

public boolean isSkipSave() {
return skipSave;
}

@Override
public boolean equals(Object o) {
if (!(o instanceof ServerLevelSaveEvent that)) return false;
return flush == that.flush && skipSave == that.skipSave && Objects.equals(serverLevel, that.serverLevel) && Objects.equals(progress, that.progress);
}

@Override
public int hashCode() {
return Objects.hash(serverLevel, progress, flush, skipSave);
}

@Override
public String toString() {
return "ServerLevelSaveEvent{" +
"serverLevel=" + serverLevel +
", progress=" + progress +
", flush=" + flush +
", skipSave=" + skipSave +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package dev.ultreon.mods.xinexlib.event.server;

import dev.ultreon.mods.xinexlib.event.player.ServerPlayerEvent;
import net.minecraft.server.level.ServerPlayer;

import java.util.Objects;

public class ServerPlayerQuitEvent implements ServerPlayerEvent {
private final ServerPlayer player;

public ServerPlayerQuitEvent(ServerPlayer player) {
this.player = player;
}

public ServerPlayer getPlayer() {
return player;
}

@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
ServerPlayerQuitEvent that = (ServerPlayerQuitEvent) o;
return Objects.equals(player, that.player);
}

@Override
public int hashCode() {
return Objects.hashCode(player);
}

@Override
public String toString() {
return "ServerPlayerQuitEvent{" +
"player=" + player + '}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dev.ultreon.mods.xinexlib.mixin;

import com.mojang.blaze3d.platform.Window;
import dev.ultreon.mods.xinexlib.client.event.ClientRenderTickEvent;
import dev.ultreon.mods.xinexlib.client.event.ClientStartedEvent;
import dev.ultreon.mods.xinexlib.client.event.ClientStoppingEvent;
import dev.ultreon.mods.xinexlib.client.event.LocalPlayerJoinEvent;
import dev.ultreon.mods.xinexlib.event.system.EventSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import org.lwjgl.glfw.GLFW;
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;

/// @author XyperCode
/// @since 0.1.0 (December 10, 2024)
@Mixin(ClientPacketListener.class)
public abstract class MixinClientPacketListener {

@Inject(at = @At("RETURN"), method = "handleLogin")
private void runTick$return(CallbackInfo ci) {
EventSystem.MAIN.publish(new LocalPlayerJoinEvent(Minecraft.getInstance().player));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package dev.ultreon.mods.xinexlib.mixin;

import dev.ultreon.mods.xinexlib.Env;
import dev.ultreon.mods.xinexlib.EnvExecutor;
import dev.ultreon.mods.xinexlib.client.event.LocalPlayerJoinEvent;
import dev.ultreon.mods.xinexlib.client.event.LocalPlayerQuitEvent;
import dev.ultreon.mods.xinexlib.event.system.EventSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.network.Connection;
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;

/// @author XyperCode
/// @since 0.1.0 (December 10, 2024)
@Mixin(Connection.class)
public abstract class MixinConnection {

@Inject(at = @At("HEAD"), method = "channelInactive")
private void channelInactive(CallbackInfo ci) {
EnvExecutor.runInEnv(Env.CLIENT, () -> () -> EventSystem.MAIN.publish(new LocalPlayerQuitEvent(Minecraft.getInstance().player)));
}

@Inject(at = @At("HEAD"), method = "disconnect(Lnet/minecraft/network/DisconnectionDetails;)V")
private void runTick$return(CallbackInfo ci) {
EnvExecutor.runInEnv(Env.CLIENT, () -> () -> EventSystem.MAIN.publish(new LocalPlayerQuitEvent(Minecraft.getInstance().player)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ private void handlePlayerLoggedIn(Connection pConnection, ServerPlayer pPlayer,
));
}

@Inject(method = "remove", at = @At(value = "HEAD"))
private void handlePlayerLoggedIn(ServerPlayer pPlayer, CallbackInfo ci) {
EventSystem.MAIN.publish(new ServerPlayerQuitEvent(pPlayer));
}

@Inject(method = "canPlayerLogin", at = @At(value = "HEAD"), cancellable = true)
private void handleLoginVerifying(SocketAddress pSocketAddress, GameProfile pGameProfile, CallbackInfoReturnable<Component> cir) {
ServerPlayerVerifyLoginEvent event = EventSystem.MAIN.publish(new ServerPlayerVerifyLoginEvent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package dev.ultreon.mods.xinexlib.mixin;

import dev.ultreon.mods.xinexlib.client.event.ClientStoppingEvent;
import dev.ultreon.mods.xinexlib.event.entity.EntitySpawnEvent;
import dev.ultreon.mods.xinexlib.event.server.ServerLevelSaveEvent;
import dev.ultreon.mods.xinexlib.event.system.EventSystem;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.ProgressListener;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import org.lwjgl.glfw.GLFW;
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;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import static java.awt.SystemColor.window;

@Mixin(ServerLevel.class)
public class MixinServerLevel {
@Inject(method = "addFreshEntity", at = @At("HEAD"), cancellable = true)
Expand All @@ -29,4 +36,9 @@ private void addExistingEntity(Entity pEntity, CallbackInfoReturnable<Boolean> c
cir.setReturnValue(false);
}
}

@Inject(at = @At("HEAD"), method = "save")
private void save(ProgressListener pProgress, boolean pFlush, boolean pSkipSave, CallbackInfo ci) {
EventSystem.MAIN.publish(new ServerLevelSaveEvent((ServerLevel) (Object) this, pProgress, pFlush, pSkipSave));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.ultreon.mods.xinexlib.platform;

import dev.ultreon.mods.xinexlib.Constants;
import dev.ultreon.mods.xinexlib.Env;
import dev.ultreon.mods.xinexlib.ModPlatform;
import dev.ultreon.mods.xinexlib.components.IComponentManager;
import dev.ultreon.mods.xinexlib.platform.services.IPlatformHelper;
Expand Down Expand Up @@ -65,4 +66,8 @@ public static IComponentManager getComponentManager(String modId) {
public static ICreativeModeTabBuilder creativeTabBuilder() {
return PLATFORM.creativeTabBuilder();
}

public static Env getEnv() {
return PLATFORM.getEnv();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.ultreon.mods.xinexlib.platform.services;

import dev.ultreon.mods.xinexlib.Env;
import dev.ultreon.mods.xinexlib.ModPlatform;
import dev.ultreon.mods.xinexlib.components.ComponentManager;
import dev.ultreon.mods.xinexlib.components.IComponentManager;
Expand Down Expand Up @@ -47,4 +48,6 @@ default IComponentManager getComponentManager(String modId) {
}

ICreativeModeTabBuilder creativeTabBuilder();

Env getEnv();
}
2 changes: 2 additions & 0 deletions common/src/main/resources/xinexlib.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
"compatibilityLevel": "JAVA_18",
"mixins": [
"MixinBlockItem",
"MixinConnection",
"MixinEntity",
"MixinLevel",
"MixinLivingEntity",
"MixinPlayerList",
"MixinServerLevel"
],
"client": [
"MixinClientPacketListener",
"MixinMinecraft"
],
"server": [],
Expand Down
Loading

0 comments on commit 8f96cff

Please sign in to comment.