From 6026709ff41925216232dda4323b54f38bfa8c4f Mon Sep 17 00:00:00 2001 From: Cosmiiko <29412451+Cosmiiko@users.noreply.github.com> Date: Sun, 11 Apr 2021 18:36:05 +0200 Subject: [PATCH] Add config & direct native api usage --- .../java/com/cosmiiko/bsodod/BSODOnDeath.java | 55 +++++++++++++++--- src/main/java/com/cosmiiko/bsodod/Config.java | 57 +++++++++++++++++++ src/main/java/com/cosmiiko/bsodod/NtDll.java | 16 ++++++ 3 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/cosmiiko/bsodod/Config.java create mode 100644 src/main/java/com/cosmiiko/bsodod/NtDll.java diff --git a/src/main/java/com/cosmiiko/bsodod/BSODOnDeath.java b/src/main/java/com/cosmiiko/bsodod/BSODOnDeath.java index d2d0dd3..ab6f4ec 100644 --- a/src/main/java/com/cosmiiko/bsodod/BSODOnDeath.java +++ b/src/main/java/com/cosmiiko/bsodod/BSODOnDeath.java @@ -1,6 +1,6 @@ package com.cosmiiko.bsodod; - +import com.sun.jna.Memory; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraftforge.api.distmarker.Dist; @@ -8,25 +8,30 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.File; import java.io.IOException; -import java.util.UUID; @Mod("bsodod") public class BSODOnDeath { private static final Logger LOGGER = LogManager.getLogger(); private boolean hasDied = false; + private boolean timerStarted = false; public BSODOnDeath() { FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); MinecraftForge.EVENT_BUS.register(this); + + ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, Config.CLIENT_SPEC); } private void setup(final FMLCommonSetupEvent event) @@ -52,8 +57,14 @@ public void onPlayerTick(TickEvent.PlayerTickEvent event) // Player has respawned if (ply.getHealth() > 0.0F && hasDied) + { hasDied = false; + // Start the timer of the blue screen + timerStarted = true; + } + + if (ply.getHealth() == 0.0F && !hasDied) { hasDied = true; @@ -74,22 +85,48 @@ public void onPlayerTick(TickEvent.PlayerTickEvent event) // Desktop doesn't work, throws a HeadlessException for some reason // See https://stackoverflow.com/questions/5226212/how-to-open-the-default-webbrowser-using-java for this hack - String url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; - Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url); + Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + Config.openUrl); } catch (IOException e) { LOGGER.error("Error during Rick Roll attempt: ", e); } + } + } - try { - // Runs this (https://github.com/peewpw/Invoke-BSOD) BSOD powershell script by peewpw - Runtime.getRuntime().exec("powershell -Command IEX((New-Object Net.Webclient).DownloadString('https://raw.githubusercontent.com/peewpw/Invoke-BSOD/master/Invoke-BSOD.ps1'));Invoke-BSOD"); + private int tickCounter = 0; + + @SubscribeEvent + public void onClientTickEvent(TickEvent.ClientTickEvent event) + { + if (timerStarted) + { + if (tickCounter % 40 == 0) + { + LOGGER.info("BSOD in " + (Config.delayInSecs - tickCounter/40) + " secs"); } - catch (IOException e) + + if (tickCounter == Config.delayInSecs*40) { - LOGGER.error("Error during BSOD attempt: ", e); + // Enable the shutdown privilege + NtDll.INSTANCE.RtlAdjustPrivilege(19, true, false, new Memory(1)); + + if (Config.defused) + { + LOGGER.info("You would have gotten a blue screen here but the mod is defused."); + } + else + { + // Raise an error and shutdown because of it + NtDll.INSTANCE.NtRaiseHardError(0xDEADDEAD, 0, 0, 0, 6, new Memory(32)); + } + + timerStarted = false; + tickCounter = 0; + return; } + + tickCounter++; } } } diff --git a/src/main/java/com/cosmiiko/bsodod/Config.java b/src/main/java/com/cosmiiko/bsodod/Config.java new file mode 100644 index 0000000..fde2d58 --- /dev/null +++ b/src/main/java/com/cosmiiko/bsodod/Config.java @@ -0,0 +1,57 @@ +package com.cosmiiko.bsodod; + +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.config.ModConfig; +import org.apache.commons.lang3.tuple.Pair; + +// Thank god for https://cadiboo.github.io/tutorials/1.15.1/forge/3.3-config/ and screw Forge's docs +@Mod.EventBusSubscriber(modid = "bsodod", bus = Mod.EventBusSubscriber.Bus.MOD) +public class Config { + public static final ClientConfig CLIENT; + public static final ForgeConfigSpec CLIENT_SPEC; + + static { + final Pair specPair = new ForgeConfigSpec.Builder().configure(ClientConfig::new); + CLIENT_SPEC = specPair.getRight(); + CLIENT = specPair.getLeft(); + } + + public static class ClientConfig { + public final ForgeConfigSpec.ConfigValue openUrl; + public final ForgeConfigSpec.ConfigValue delayInSecs; + public final ForgeConfigSpec.ConfigValue defused; + + public ClientConfig(ForgeConfigSpec.Builder builder) { + openUrl = builder + .comment("URL Opened before the bluescreen. Set to 'none' to disable.") + .define("openUrl", "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); + + delayInSecs = builder + .comment("Delay in seconds before the blue screen.") + .define("delayInSecs", 5); + + defused = builder + .comment("Whether or not the mod is defused. If true, you will not blue screen.") + .define("defused", false); + } + } + + @SubscribeEvent + public static void onModConfigEvent(final ModConfig.ModConfigEvent configEvent) { + if (configEvent.getConfig().getSpec() == Config.CLIENT_SPEC) { + Config.bakeConfig(); + } + } + + public static String openUrl; + public static Integer delayInSecs; + public static Boolean defused; + + public static void bakeConfig() { + openUrl = CLIENT.openUrl.get(); + delayInSecs = CLIENT.delayInSecs.get(); + defused = CLIENT.defused.get(); + } +} diff --git a/src/main/java/com/cosmiiko/bsodod/NtDll.java b/src/main/java/com/cosmiiko/bsodod/NtDll.java new file mode 100644 index 0000000..a72a8f7 --- /dev/null +++ b/src/main/java/com/cosmiiko/bsodod/NtDll.java @@ -0,0 +1,16 @@ +package com.cosmiiko.bsodod; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; + +public interface NtDll extends StdCallLibrary { + NtDll INSTANCE = Native.loadLibrary("NtDll", NtDll.class, W32APIOptions.DEFAULT_OPTIONS); + + // See http://www.pinvoke.net/default.aspx/ntdll.RtlAdjustPrivilege + public long RtlAdjustPrivilege(long Privilege, boolean bEnablePrivilege, boolean IsThreadPrivilege, Pointer PreviousValue); + + // See http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FError%2FNtRaiseHardError.html + public long NtRaiseHardError(long ErrorStatus, long NumberOfParameters, long UnicodeStringParameterMask, int Parameters, long ValidResponseOption, Pointer Response); +}