Compare commits

...

4 Commits

Author SHA1 Message Date
Johannes Frohnmeyer de00f51b06
fix: build in gradle:latest
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2024-04-25 22:21:50 +02:00
Johannes Frohnmeyer 3fa30b834d
chore: update to 1.20.5
ci/woodpecker/push/woodpecker Pipeline failed Details
ci/woodpecker/tag/woodpecker Pipeline failed Details
2024-04-25 21:51:15 +02:00
Johannes Frohnmeyer 0e036599cf
fix: don't respond to events for other players if on client
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/tag/woodpecker Pipeline was successful Details
2024-03-31 14:13:42 +02:00
Johannes Frohnmeyer 3b5e262bea
fix: hook additional methods for a better chance to catch damage
ci/woodpecker/tag/woodpecker Pipeline is pending Details
ci/woodpecker/push/woodpecker Pipeline was successful Details
2024-03-31 13:58:58 +02:00
10 changed files with 99 additions and 26 deletions

View File

@ -2,7 +2,7 @@
steps:
build_test:
image: gradle:alpine
image: gradle:latest
pull: true
commands:
- mkdir artifacts

View File

@ -8,19 +8,19 @@ import java.util.function.Supplier
import javax.lang.model.element.Modifier.*
plugins {
id("jfmod") version "1.5-SNAPSHOT"
id("jfmod") version "1.6-SNAPSHOT"
}
allprojects { group = "io.gitlab.jfronny" }
base.archivesName = "breakme"
// https://fabricmc.net/develop/
val fabricVersion = "0.91.1+1.20.4"
jfMod {
minecraftVersion = "1.20.4"
minecraftVersion = "1.20.5"
yarn("build.1")
loaderVersion = "0.15.0"
libJfVersion = "3.14.1"
loaderVersion = "0.15.10"
libJfVersion = "3.15.5"
fabricApiVersion = "0.97.6+1.20.5"
modrinth {
projectId = "breakme"
@ -37,13 +37,13 @@ jfMod {
if (flavour == "") flavour = "modrinth"
dependencies {
modImplementation("io.gitlab.jfronny.libjf:libjf-config-core-v2:${jfMod.libJfVersion.get()}")
modImplementation("io.gitlab.jfronny.libjf:libjf-config-core-v2")
// Dev env
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil:${jfMod.libJfVersion.get()}")
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-config-ui-tiny:${jfMod.libJfVersion.get()}")
modLocalRuntime("net.fabricmc.fabric-api:fabric-api:$fabricVersion")
modLocalRuntime("com.terraformersmc:modmenu:9.0.0-pre.1")
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil")
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-config-ui-tiny")
modLocalRuntime("net.fabricmc.fabric-api:fabric-api")
modLocalRuntime("com.terraformersmc:modmenu:10.0.0-beta.1")
}
loom {

View File

@ -1,6 +1,7 @@
package io.gitlab.jfronny.breakme.client;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.thread.ThreadExecutor;
import java.util.Objects;
@ -10,4 +11,11 @@ public class ClientImpl implements Client {
public ThreadExecutor<Runnable> getRunner() {
return Objects.requireNonNull(MinecraftClient.getInstance());
}
@Override
public boolean isValidPlayer(PlayerEntity player) {
MinecraftClient client = MinecraftClient.getInstance();
if (client == null || client.player == null) return false;
return client.player.getUuid().equals(player.getUuid());
}
}

View File

@ -1,28 +1,47 @@
package io.gitlab.jfronny.breakme;
import io.gitlab.jfronny.breakme.client.Client;
import io.gitlab.jfronny.breakme.crash.Method;
import io.gitlab.jfronny.commons.logging.Logger;
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Language;
public class BreakMe implements ModInitializer {
public static final String MOD_ID = "breakme";
public static final Logger LOGGER = Logger.forName(MOD_ID);
public static final SystemLoggerPlus LOGGER = SystemLoggerPlus.forName(MOD_ID);
@Override
public void onInitialize() {
LOGGER.warn("Prepare for trouble");
}
public static void tryInvokeCrash(PlayerEntity player) throws Exception {
if (BreakMeConfig.event == BreakMeConfig.Cause.All
|| BreakMeConfig.event == BreakMeConfig.Cause.Damage
|| (BreakMeConfig.event == BreakMeConfig.Cause.Death && player.isDead())) {
Method method = BreakMeConfig.method;
String name = Language.getInstance().get(MOD_ID + ".jfconfig.enum.Method." + method.name(), method.name());
LOGGER.info("Invoking the crash (using " + name + ")");
method.crash();
public static void tryInvokeCrash(BreakMeConfig.Cause cause) throws Exception {
if (BreakMeConfig.event.includes(cause)) {
crash();
}
}
public static BreakMeConfig.Cause resolveEvent(PlayerEntity player) {
if (!isValidPlayer(player)) return BreakMeConfig.Cause.None;
else if (player.isDead()) return BreakMeConfig.Cause.Death;
else return BreakMeConfig.Cause.Damage;
}
public static boolean isValidPlayer(PlayerEntity player) {
if (player == null) return false;
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
return Client.INSTANCE.isValidPlayer(player);
}
return true;
}
private static void crash() throws Exception {
Method method = BreakMeConfig.method;
String name = Language.getInstance().get(MOD_ID + ".jfconfig.enum.Method." + method.name(), method.name());
LOGGER.info("Invoking the crash (using {0})", name);
method.crash();
}
}

View File

@ -13,7 +13,12 @@ public class BreakMeConfig {
Death,
All,
None
None;
public boolean includes(Cause cause) {
if (cause == null || cause == None) return false;
return this == All || this == cause;
}
}
@Verifier
@ -24,6 +29,14 @@ public class BreakMeConfig {
}
}
@Verifier
public static void validEvent() {
if (BreakMeConfig.event == null) {
BreakMeConfig.event = Cause.None;
BreakMe.LOGGER.error("Could not find specified event, defaulting to None");
}
}
static {
JFC_BreakMeConfig.ensureInitialized();
}

View File

@ -1,10 +1,12 @@
package io.gitlab.jfronny.breakme.client;
import io.gitlab.jfronny.commons.throwable.Try;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.thread.ThreadExecutor;
public interface Client {
Client INSTANCE = (Client) Try.orThrow(() -> Class.forName(Client.class.getName() + "Impl").getConstructor().newInstance());
ThreadExecutor<Runnable> getRunner();
boolean isValidPlayer(PlayerEntity player);
}

View File

@ -13,7 +13,7 @@ public class SegfaultProvider implements CrashProvider {
// Required to prevent early initialization of LWJGL for some reason
private static class Impl {
private static void crash() {
BufferUtils.zeroBuffer(PointerBuffer.create(0, 1000));
BufferUtils.zeroBuffer(PointerBuffer.create(1, 1000));
}
}
}

View File

@ -0,0 +1,21 @@
package io.gitlab.jfronny.breakme.mixin;
import io.gitlab.jfronny.breakme.BreakMe;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
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(LivingEntity.class)
public class LivingEntityMixin {
// client-side damage event when playing on a server
@Inject(at = @At("TAIL"), method = "onDamaged(Lnet/minecraft/entity/damage/DamageSource;)V")
private void onDamage(DamageSource damageSource, CallbackInfo ci) throws Exception {
if (((LivingEntity)(Object)this) instanceof PlayerEntity player) {
BreakMe.tryInvokeCrash(BreakMe.resolveEvent(player));
}
}
}

View File

@ -1,19 +1,28 @@
package io.gitlab.jfronny.breakme.mixin;
import io.gitlab.jfronny.breakme.BreakMe;
import io.gitlab.jfronny.breakme.BreakMeConfig;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
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;
@Mixin(PlayerEntity.class)
public class MixinPlayerEntity {
public class PlayerEntityMixin {
@Inject(at = @At("TAIL"), method = "damage(Lnet/minecraft/entity/damage/DamageSource;F)Z")
private void onDamage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> info) throws Exception {
if (info.getReturnValue()) {
BreakMe.tryInvokeCrash((PlayerEntity)(Object)this);
BreakMe.tryInvokeCrash(BreakMe.resolveEvent((PlayerEntity)(Object)this));
}
}
@Inject(at = @At("TAIL"), method = "onDeath(Lnet/minecraft/entity/damage/DamageSource;)V")
private void onDeath(DamageSource damageSource, CallbackInfo ci) throws Exception {
if (BreakMe.isValidPlayer((PlayerEntity)(Object)this)) {
BreakMe.tryInvokeCrash(BreakMeConfig.Cause.Death);
}
}
}

View File

@ -4,9 +4,10 @@
"package": "io.gitlab.jfronny.breakme.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
"MixinPlayerEntity"
"PlayerEntityMixin"
],
"client": [
"LivingEntityMixin"
],
"injectors": {
"defaultRequire": 1