Skip to content
This repository has been archived by the owner on Jan 2, 2023. It is now read-only.

Commit

Permalink
Add config & direct native api usage
Browse files Browse the repository at this point in the history
  • Loading branch information
Cosmiiko committed Apr 11, 2021
1 parent 3a5c76f commit 6026709
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 9 deletions.
55 changes: 46 additions & 9 deletions src/main/java/com/cosmiiko/bsodod/BSODOnDeath.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
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;
import net.minecraftforge.api.distmarker.OnlyIn;
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)
Expand All @@ -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;
Expand All @@ -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++;
}
}
}
57 changes: 57 additions & 0 deletions src/main/java/com/cosmiiko/bsodod/Config.java
Original file line number Diff line number Diff line change
@@ -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<ClientConfig, ForgeConfigSpec> specPair = new ForgeConfigSpec.Builder().configure(ClientConfig::new);
CLIENT_SPEC = specPair.getRight();
CLIENT = specPair.getLeft();
}

public static class ClientConfig {
public final ForgeConfigSpec.ConfigValue<String> openUrl;
public final ForgeConfigSpec.ConfigValue<Integer> delayInSecs;
public final ForgeConfigSpec.ConfigValue<Boolean> 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();
}
}
16 changes: 16 additions & 0 deletions src/main/java/com/cosmiiko/bsodod/NtDll.java
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 6026709

Please sign in to comment.