diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index a03de0b..114364a 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -33,6 +33,14 @@ jobs: with: java-version: ${{ matrix.java }} distribution: 'oracle' + - uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- - name: make gradle wrapper executable if: ${{ runner.os != 'Windows' }} run: | diff --git a/Core/src/main/java/fr/altarik/toolbox/core/event/PlayerLifecycleCallback.java b/Core/src/main/java/fr/altarik/toolbox/core/event/PlayerLifecycleCallback.java new file mode 100644 index 0000000..94df951 --- /dev/null +++ b/Core/src/main/java/fr/altarik/toolbox/core/event/PlayerLifecycleCallback.java @@ -0,0 +1,37 @@ +package fr.altarik.toolbox.core.event; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.ActionResult; + +public interface PlayerLifecycleCallback { + + Event PLAYER_JOIN = EventFactory.createArrayBacked(PlayerJoin.class, listeners -> player -> { + for(PlayerJoin listener : listeners) { + ActionResult result = listener.onPlayerJoin(player); + if (result != ActionResult.PASS) + return result; + } + return ActionResult.PASS; + }); + + Event PLAYER_LEAVE = EventFactory.createArrayBacked(PlayerLeave.class, listeners -> player -> { + for(PlayerLeave listener : listeners) { + ActionResult result = listener.onPlayerLeave(player); + if (result != ActionResult.PASS) + return result; + } + return ActionResult.PASS; + }); + + @FunctionalInterface + interface PlayerJoin { + ActionResult onPlayerJoin(ServerPlayerEntity player); + } + + @FunctionalInterface + interface PlayerLeave { + ActionResult onPlayerLeave(ServerPlayerEntity player); + } +} diff --git a/Core/src/main/java/fr/altarik/toolbox/core/mixin/PlayerJoinEvent.java b/Core/src/main/java/fr/altarik/toolbox/core/mixin/PlayerJoinEvent.java new file mode 100644 index 0000000..e9ec103 --- /dev/null +++ b/Core/src/main/java/fr/altarik/toolbox/core/mixin/PlayerJoinEvent.java @@ -0,0 +1,20 @@ +package fr.altarik.toolbox.core.mixin; + +import fr.altarik.toolbox.core.event.PlayerLifecycleCallback; +import net.minecraft.network.ClientConnection; +import net.minecraft.server.PlayerManager; +import net.minecraft.server.network.ConnectedClientData; +import net.minecraft.server.network.ServerPlayerEntity; +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(PlayerManager.class) +public class PlayerJoinEvent { + + @Inject(method = "onPlayerConnect", at = @At(value = "RETURN")) + private void onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, ConnectedClientData clientData, CallbackInfo ci) { + PlayerLifecycleCallback.PLAYER_JOIN.invoker().onPlayerJoin(player); + } +} diff --git a/Core/src/main/java/fr/altarik/toolbox/core/mixin/PlayerLeaveEvent.java b/Core/src/main/java/fr/altarik/toolbox/core/mixin/PlayerLeaveEvent.java new file mode 100644 index 0000000..74a9af1 --- /dev/null +++ b/Core/src/main/java/fr/altarik/toolbox/core/mixin/PlayerLeaveEvent.java @@ -0,0 +1,23 @@ +package fr.altarik.toolbox.core.mixin; + +import fr.altarik.toolbox.core.event.PlayerLifecycleCallback; +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +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 PlayerLeaveEvent { + + @Shadow + public ServerPlayerEntity player; + + @Inject(at = @At(value = "HEAD"), method = "onDisconnected") + private void onPlayerQuit(Text reason, CallbackInfo ci) { + PlayerLifecycleCallback.PLAYER_LEAVE.invoker().onPlayerLeave(player); + } +} diff --git a/Core/src/main/resources/Core.mixins.json b/Core/src/main/resources/Core.mixins.json new file mode 100644 index 0000000..d56f9fa --- /dev/null +++ b/Core/src/main/resources/Core.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "fr.altarik.toolbox.core.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "PlayerJoinEvent", + "PlayerLeaveEvent" + ], + "verbose": false, + "injectors": { + "defaultRequire": 1 + } +} diff --git a/Core/src/main/resources/fabric.mod.json b/Core/src/main/resources/fabric.mod.json index befb902..96836ec 100644 --- a/Core/src/main/resources/fabric.mod.json +++ b/Core/src/main/resources/fabric.mod.json @@ -19,7 +19,9 @@ "entrypoints": { "main": [] }, - "mixins": [], + "mixins": [ + "Core.mixins.json" + ], "depends": { "fabricloader": "^${loaderVersion}", "fabric-api": "*", diff --git a/build.gradle b/build.gradle index 36e7c7f..03c1f60 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ import fr.altarik.CreateTag import fr.altarik.ReportDiscord plugins { - id 'fabric-loom' version '1.5-SNAPSHOT' apply false + id 'fabric-loom' version '1.6-SNAPSHOT' apply false } Properties local = new Properties() diff --git a/gradle.properties b/gradle.properties index 735d21f..2ea9f21 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,10 +5,10 @@ junit_version=5.9.0 minecraft_version=1.20.4 yarn_mappings=1.20.4+build.3 loader_version=0.15.6 -fabric_version=0.95.4+1.20.4 +fabric_version=0.97.1+1.20.4 maven_group=fr.altarik.toolbox -maven_version=5.0.0 +maven_version=5.1.0 git_owner=quentinlegot git_repo=Toolbox \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a595206..e1adfb4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists