aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrady <thatgravyboat@gmail.com>2024-06-14 14:36:13 -0230
committerGitHub <noreply@github.com>2024-06-14 19:06:13 +0200
commit5b4f369f53ccedb84449f1209298949cd4cc185c (patch)
tree4aa70e393f1fc739defbd5180ac98d6d2356dff3
parent8e13b2bd847d4ad2aadc1b05adbb67076a768982 (diff)
downloadskyhanni-5b4f369f53ccedb84449f1209298949cd4cc185c.tar.gz
skyhanni-5b4f369f53ccedb84449f1209298949cd4cc185c.tar.bz2
skyhanni-5b4f369f53ccedb84449f1209298949cd4cc185c.zip
Feature: DownloadSourceChecker (#1914)
* Add DownloadSourceChecker * Implement suggestions
-rw-r--r--build.gradle.kts4
-rw-r--r--src/main/java/SkyHanniInstallerFrame.java4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/tweaker/DownloadSourceChecker.java150
-rw-r--r--src/main/java/at/hannibal2/skyhanni/tweaker/SkyHanniTweaker.java39
-rw-r--r--src/main/java/at/hannibal2/skyhanni/tweaker/TweakerUtils.java52
5 files changed, 247 insertions, 2 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 9396a9b53..b1a2f13ab 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -167,7 +167,7 @@ loom {
if (System.getenv("repo_action") != "true") {
property("devauth.configDir", rootProject.file(".devauth").absolutePath)
}
- arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker")
+ arg("--tweakClass", "at.hannibal2.skyhanni.tweaker.SkyHanniTweaker")
arg("--tweakClass", "io.github.notenoughupdates.moulconfig.tweaker.DevelopmentResourceTweaker")
arg("--mods", devenvMod.resolve().joinToString(",") { it.relativeTo(file("run")).path })
}
@@ -235,7 +235,7 @@ tasks.withType(Jar::class) {
this["ForceLoadAsMod"] = "true"
this["Main-Class"] = "SkyHanniInstallerFrame"
- this["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker"
+ this["TweakClass"] = "at.hannibal2.skyhanni.tweaker.SkyHanniTweaker"
this["MixinConfigs"] = "mixins.skyhanni.json"
}
}
diff --git a/src/main/java/SkyHanniInstallerFrame.java b/src/main/java/SkyHanniInstallerFrame.java
index 9381e9aef..57f586212 100644
--- a/src/main/java/SkyHanniInstallerFrame.java
+++ b/src/main/java/SkyHanniInstallerFrame.java
@@ -1,3 +1,5 @@
+import at.hannibal2.skyhanni.tweaker.DownloadSourceChecker;
+
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
@@ -94,6 +96,8 @@ public class SkyHanniInstallerFrame extends JFrame implements ActionListener, Mo
public static void main(String[] args) {
try {
+ DownloadSourceChecker.init();
+
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SkyHanniInstallerFrame frame = new SkyHanniInstallerFrame();
frame.centerFrame(frame);
diff --git a/src/main/java/at/hannibal2/skyhanni/tweaker/DownloadSourceChecker.java b/src/main/java/at/hannibal2/skyhanni/tweaker/DownloadSourceChecker.java
new file mode 100644
index 000000000..862d17186
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/tweaker/DownloadSourceChecker.java
@@ -0,0 +1,150 @@
+package at.hannibal2.skyhanni.tweaker;
+
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.UIManager;
+import java.awt.event.WindowEvent;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.net.URI;
+import java.net.URL;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class DownloadSourceChecker {
+
+ private static final String GITHUB_REPO_TEXT = "repo_id=511310721";
+ private static final String MODRINTH_URL = "/data/byNkmv5G/";
+ private static final String THE_PASSWORD = "danger";
+
+ private static final String[] PASSWORD_POPUP = {
+ "If someone asks you to type in here,",
+ "",
+ "the likelihood of them ratting you is high!",
+ "",
+ "Enter the password:"
+ };
+
+ private static final String[] SECURITY_POPUP = {
+ "The file you are trying to run is hosted on a non-trusted domain.",
+ "",
+ "Host: %s",
+ "",
+ "Please download the file from a trusted source.",
+ "",
+ "IF YOU DO NOT KNOW WHAT YOU ARE DOING, CLOSE THIS WINDOW!",
+ "",
+ "And download from the official link below."
+ };
+
+ public static void init() {
+ if (!TweakerUtils.isOnWindows()) return;
+ URI host = getDangerousHost();
+ if (host != null) {
+ openMenu(host);
+ }
+ }
+
+ private static void openMenu(URI host) {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ JFrame frame = new JFrame();
+ frame.setUndecorated(true);
+ frame.setAlwaysOnTop(true);
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+
+ AtomicBoolean close = new AtomicBoolean(true);
+
+ JPanel links = new JPanel();
+
+ links.add(TweakerUtils.createButton(
+ "Discord",
+ () -> TweakerUtils.openUrl("https://discord.com/invite/skyhanni-997079228510117908")
+ ));
+
+ links.add(TweakerUtils.createButton(
+ "Official Download",
+ () -> TweakerUtils.openUrl("https://github.com/hannibal002/SkyHanni/releases")
+ ));
+
+ JPanel buttons = new JPanel();
+
+ buttons.add(TweakerUtils.createButton(
+ "Skip (Trusted Users Only)",
+ () -> {
+ String password = JOptionPane.showInputDialog(frame, String.join("\n", PASSWORD_POPUP));
+ if (password != null && password.equals(THE_PASSWORD)) {
+ close.set(false);
+ frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
+ }
+ }
+ ));
+
+ buttons.add(TweakerUtils.createButton(
+ "Close",
+ () -> {
+ close.set(true);
+ frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
+ }
+ ));
+
+ JOptionPane.showOptionDialog(
+ frame,
+ String.format(String.join("\n", SECURITY_POPUP), uriToSimpleString(host)),
+ "SkyHanni Security Error",
+ JOptionPane.DEFAULT_OPTION,
+ JOptionPane.ERROR_MESSAGE,
+ null,
+ new JPanel[] { links, buttons },
+ links
+ );
+
+ if (!close.get()) return;
+ TweakerUtils.exit();
+ }
+
+ private static String uriToSimpleString(URI uri) {
+ return uri.getScheme() + "://" + uri.getHost() + uri.getPath();
+ }
+
+ private static URI getDangerousHost() {
+ try {
+ URL url = DownloadSourceChecker.class.getProtectionDomain().getCodeSource().getLocation();
+ File file = new File(url.getFile());
+ if (!file.isFile()) return null;
+ URI host = getHost(file);
+ if (host == null) return null;
+
+ if (host.getHost().equals("objects.githubusercontent.com") && host.getPath().contains(GITHUB_REPO_TEXT)) {
+ return null;
+ } else if (host.getHost().equals("cdn.modrinth.com") && host.getPath().startsWith(MODRINTH_URL)) {
+ return null;
+ }
+ return host;
+ } catch (Exception ignored) {
+ return null;
+ }
+ }
+
+ private static URI getHost(File file) throws Exception {
+ final File adsFile = new File(file.getAbsolutePath() + ":Zone.Identifier:$DATA");
+ String host = null;
+ try(BufferedReader reader = new BufferedReader(new FileReader(adsFile))) {
+ String line = reader.readLine();
+ while (line != null) {
+ if (line.startsWith("HostUrl=")) {
+ host = line.substring(8);
+ break;
+ }
+ line = reader.readLine();
+ }
+ }
+ return host != null ? new URI(host) : null;
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/tweaker/SkyHanniTweaker.java b/src/main/java/at/hannibal2/skyhanni/tweaker/SkyHanniTweaker.java
new file mode 100644
index 000000000..6cdb1b204
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/tweaker/SkyHanniTweaker.java
@@ -0,0 +1,39 @@
+package at.hannibal2.skyhanni.tweaker;
+
+import net.minecraft.launchwrapper.ITweaker;
+import net.minecraft.launchwrapper.Launch;
+import net.minecraft.launchwrapper.LaunchClassLoader;
+import org.spongepowered.asm.launch.MixinTweaker;
+
+import java.io.File;
+import java.util.List;
+
+@SuppressWarnings("unused")
+public class SkyHanniTweaker implements ITweaker {
+
+ public SkyHanniTweaker() {
+ DownloadSourceChecker.init();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
+ List<String> tweakClasses = (List<String>) Launch.blackboard.get("TweakClasses");
+ tweakClasses.add(MixinTweaker.class.getName());
+ }
+
+ @Override
+ public void injectIntoClassLoader(LaunchClassLoader classLoader) {
+
+ }
+
+ @Override
+ public String getLaunchTarget() {
+ return null;
+ }
+
+ @Override
+ public String[] getLaunchArguments() {
+ return new String[0];
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/tweaker/TweakerUtils.java b/src/main/java/at/hannibal2/skyhanni/tweaker/TweakerUtils.java
new file mode 100644
index 000000000..b9070e0c1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/tweaker/TweakerUtils.java
@@ -0,0 +1,52 @@
+package at.hannibal2.skyhanni.tweaker;
+
+import javax.swing.JButton;
+import java.awt.Desktop;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class TweakerUtils {
+
+ public static boolean isOnWindows() {
+ return System.getProperty("os.name").toLowerCase().contains("win");
+ }
+
+ public static void openUrl(String url) {
+ try {
+ Desktop.getDesktop().browse(new URI(url));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Taken from Skytils
+ public static void exit() {
+ try {
+ Class<?> clazz = Class.forName("java.lang.Shutdown");
+ Method method = clazz.getDeclaredMethod("exit", int.class);
+ method.setAccessible(true);
+ method.invoke(null, 0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
+ Runtime.getRuntime().exit(1);
+ return null;
+ });
+ }
+ }
+
+ public static JButton createButton(String text, Runnable action) {
+ JButton button = new JButton(text);
+ button.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ action.run();
+ }
+ });
+ return button;
+ }
+}