aboutsummaryrefslogtreecommitdiff
path: root/loader/src/main
diff options
context:
space:
mode:
authorsyeyoung <cyoung06@naver.com>2023-02-07 10:23:39 +0900
committersyeyoung <cyoung06@naver.com>2023-02-07 10:23:39 +0900
commitb9f5d57e6ceb50067ac88863655ebfdb92985f7a (patch)
treea4b054872b88d98aadc1949e4b44709d832929a6 /loader/src/main
parent544fdb38a545ff346a8d12349067c805caac3862 (diff)
downloadSkyblock-Dungeons-Guide-b9f5d57e6ceb50067ac88863655ebfdb92985f7a.tar.gz
Skyblock-Dungeons-Guide-b9f5d57e6ceb50067ac88863655ebfdb92985f7a.tar.bz2
Skyblock-Dungeons-Guide-b9f5d57e6ceb50067ac88863655ebfdb92985f7a.zip
- New Privacy Policy GUI
Signed-off-by: syeyoung <cyoung06@naver.com>
Diffstat (limited to 'loader/src/main')
-rwxr-xr-xloader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java6
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java26
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiDisplayer.java19
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiPrivacyPolicy.java83
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/SpecialGuiScreen.java3
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetPrivacyPolicy.java101
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/GuiScreenAdapter.java3
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/PolicyVersion.java52
-rw-r--r--loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/DomElementRegistry.java1
-rw-r--r--loader/src/main/resources/assets/dungeons_guide_loader/gui/privacyPolicy/privacyPolicy.gui74
10 files changed, 266 insertions, 102 deletions
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
index 4a7ef695..6039823b 100755
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java
@@ -32,6 +32,7 @@ import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotificationAutoClos
import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.richtext.fonts.DefaultFontRenderer;
import kr.syeyoung.dungeonsguide.launcher.loader.*;
import kr.syeyoung.dungeonsguide.launcher.util.ProgressStateHolder;
+import kr.syeyoung.dungeonsguide.launcher.util.cursor.GLCursors;
import lombok.Getter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.IReloadableResourceManager;
@@ -61,6 +62,7 @@ public class Main
{
public static final String MOD_ID = "dungeons_guide_loader";
public static final String VERSION = "4.0.0";
+ public static final String POLICY = "https://v2.dungeons.guide/privacyPolicy.gui";
public static final String DOMAIN = "https://v2.dungeons.guide/api";
private static Main main;
@@ -278,6 +280,10 @@ public class Main
@EventHandler
public void preInit(FMLPreInitializationEvent preInitializationEvent) {
+ try {
+ GLCursors.setupCursors();
+ } catch (Exception e) {}
+
Security.addProvider(new BouncyCastleProvider());
// setup static variables
main = this;
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java
index 9a491b08..6f9a2d65 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java
@@ -27,10 +27,12 @@ import kr.syeyoung.dungeonsguide.launcher.exceptions.auth.AuthenticationUnavaila
import kr.syeyoung.dungeonsguide.launcher.exceptions.auth.PrivacyPolicyRequiredException;
import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiDisplayer;
import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiLoadingError;
-import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiPrivacyPolicy;
+import kr.syeyoung.dungeonsguide.launcher.gui.screen.WidgetPrivacyPolicy;
import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.Notification;
import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.NotificationManager;
import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotification;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.GuiScreenAdapter;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.GlobalHUDScale;
import net.minecraft.client.Minecraft;
import net.minecraftforge.common.MinecraftForge;
import org.apache.logging.log4j.LogManager;
@@ -73,6 +75,7 @@ public class AuthManager {
else if (currentToken instanceof PrivacyPolicyRequiredToken) throw new PrivacyPolicyRequiredException();
throw new IllegalStateException("weird token: "+currentToken);
}
+ final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder().setNameFormat("DgAuth Pool").build());
private volatile boolean initlock = false;
@@ -85,8 +88,6 @@ public class AuthManager {
initlock = true;
- ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("DgAuth Pool").build();
- final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, namedThreadFactory);
scheduler.scheduleAtFixedRate(() -> {
boolean shouldReAuth = false;
if (getToken().isUserVerified() && !getToken().getUUID().replace("-", "").equals(Minecraft.getMinecraft().getSession().getPlayerID())) {
@@ -131,7 +132,7 @@ public class AuthManager {
if (currentToken instanceof PrivacyPolicyRequiredToken) {
- GuiDisplayer.INSTANCE.displayGui(new GuiPrivacyPolicy());
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetPrivacyPolicy())));
throw new PrivacyPolicyRequiredException();
}
@@ -140,12 +141,13 @@ public class AuthManager {
NotificationManager.getInstance().removeNotification(privacyPolicyRequired);
} catch (Exception e) {
if (e instanceof PrivacyPolicyRequiredException) {
+ NotificationManager.getInstance().removeNotification(authenticationFailure);
NotificationManager.getInstance().updateNotification(privacyPolicyRequired, new WidgetNotification(privacyPolicyRequired, Notification.builder()
.title("Privacy Policy")
.description("Please accept Dungeons Guide\nPrivacy Policy to enjoy server based\nfeatures of Dungeons Guide\n\n(Including Auto-Update/Remote-Jar)")
.titleColor(0xFFFF0000)
.onClick(() -> {
- GuiDisplayer.INSTANCE.displayGui(new GuiPrivacyPolicy());
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetPrivacyPolicy())));
})
.build()));
} else {
@@ -167,8 +169,18 @@ public class AuthManager {
return currentToken;
}
+ private volatile boolean accepting = false;
+ public synchronized void acceptPrivacyPolicy(long version) {
+ if (accepting) return;
+ accepting = true;
+ scheduler.schedule(() -> {try {
+ acceptPrivacyPolicy0(version);
+ } catch (Exception e) {e.printStackTrace();} finally {
+ accepting = false;
+ }}, 0, TimeUnit.MILLISECONDS);
+ }
- public AuthToken acceptPrivacyPolicy(long version) {
+ private AuthToken acceptPrivacyPolicy0(long version) {
if (reauthLock) {
while(reauthLock);
return currentToken;
@@ -188,7 +200,7 @@ public class AuthManager {
.description("Please accept the Dungeons Guide\nPrivacy Policy to enjoy server based\nfeatures of Dungeons Guide\n\n(Including Auto-Update/Remote-Jar)")
.titleColor(0xFFFF0000)
.onClick(() -> {
- GuiDisplayer.INSTANCE.displayGui(new GuiPrivacyPolicy());
+ GuiDisplayer.INSTANCE.displayGui(new GuiScreenAdapter(new GlobalHUDScale(new WidgetPrivacyPolicy())));
})
.build()));
} else {
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiDisplayer.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiDisplayer.java
index 35d9a9ea..ad942ffb 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiDisplayer.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiDisplayer.java
@@ -20,6 +20,7 @@ package kr.syeyoung.dungeonsguide.launcher.gui.screen;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiMainMenu;
+import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -31,7 +32,7 @@ public class GuiDisplayer {
public static GuiDisplayer INSTANCE = new GuiDisplayer();
private GuiDisplayer() {}
- private Queue<SpecialGuiScreen> guiScreensToShow = new LinkedList<>();
+ private Queue<GuiScreen> guiScreensToShow = new LinkedList<>();
private boolean isMcLoaded;
@@ -40,23 +41,21 @@ public class GuiDisplayer {
if (guiOpenEvent.gui instanceof GuiMainMenu) {
isMcLoaded = true;
}
- if (guiScreensToShow.size() > 0 && guiOpenEvent.gui != guiScreensToShow.peek()) {
- SpecialGuiScreen gui = guiScreensToShow.peek();
+ if (isMcLoaded && !guiScreensToShow.isEmpty()) {
+ GuiScreen gui = guiScreensToShow.poll();
if (gui == null) return;
- gui.setOnDismiss(guiScreensToShow::poll);
guiOpenEvent.gui = gui;
}
}
- public void displayGui(SpecialGuiScreen specialGuiScreen) {
+ public void displayGui(GuiScreen specialGuiScreen) {
if (specialGuiScreen == null) return;
if (!guiScreensToShow.contains(specialGuiScreen))
guiScreensToShow.add(specialGuiScreen);
- if (isMcLoaded) {
- SpecialGuiScreen gui = guiScreensToShow.peek();
- if (gui == null) return;
- gui.setOnDismiss(guiScreensToShow::poll);
- Minecraft.getMinecraft().displayGuiScreen(gui);
+ if (isMcLoaded && Minecraft.getMinecraft().isCallingFromMinecraftThread()) {
+ Minecraft.getMinecraft().displayGuiScreen(null);
+ } else if (isMcLoaded) {
+ Minecraft.getMinecraft().addScheduledTask(() -> Minecraft.getMinecraft().displayGuiScreen(null));
}
}
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiPrivacyPolicy.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiPrivacyPolicy.java
deleted file mode 100644
index 66b26111..00000000
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiPrivacyPolicy.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2022 cyoung06 (syeyoung)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.launcher.gui.screen;
-
-import kr.syeyoung.dungeonsguide.launcher.auth.AuthManager;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.FontRenderer;
-import net.minecraft.client.gui.GuiButton;
-import net.minecraft.client.gui.ScaledResolution;
-import org.lwjgl.opengl.GL11;
-
-import java.io.IOException;
-
-public class GuiPrivacyPolicy extends SpecialGuiScreen {
- @Override
- public void initGui() {
- super.initGui();
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
-
- int width = Math.min(300, sr.getScaledWidth() / 2 - 20);
-
- this.buttonList.add(new GuiButton(0, sr.getScaledWidth()/2 + 10,sr.getScaledHeight()-40, width, 20,"Accept Privacy Policy"));
- this.buttonList.add(new GuiButton(1, sr.getScaledWidth() / 2 - 10 - width,sr.getScaledHeight()-40, width, 20,"Deny and Play Without DG"));
- }
-
-
- @Override
- protected void actionPerformed(GuiButton button) throws IOException {
- super.actionPerformed(button);
- if (button.id == 0) {
- // accept
- try {
- AuthManager.getInstance().acceptPrivacyPolicy(1);
- } catch (Exception e) {
- e.printStackTrace();
-// GuiDisplayer.INSTANCE.displayGui(new GuiLoadingError(e));
- // display tooltip.
- }
- dismiss();
- } else if (button.id == 1) {
- dismiss();
- }
- }
-
-
- @Override
- public void drawScreen(int mouseX, int mouseY, float partialTicks) {
- super.drawBackground(0);
-
- ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
- FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
-
- final String ACCEPT_POLICY_MSG = "Please accept or deny the Dungeons Guide Privacy Policy to continue";
-
- fontRenderer.drawString(ACCEPT_POLICY_MSG, (sr.getScaledWidth()-fontRenderer.getStringWidth(ACCEPT_POLICY_MSG))/2,40,0xFFFF0000);
- fontRenderer.drawString("Blah blah legal stuff", (sr.getScaledWidth()-fontRenderer.getStringWidth(ACCEPT_POLICY_MSG))/2,sr.getScaledHeight() / 2, 0xFFFFFFFF);
-
- super.drawScreen(mouseX, mouseY, partialTicks);
- }
-
- public static void clip(ScaledResolution resolution, int x, int y, int width, int height) {
- if (width < 0 || height < 0) return;
-
- int scale = resolution.getScaleFactor();
- GL11.glScissor((x ) * scale, Minecraft.getMinecraft().displayHeight - (y + height) * scale, (width) * scale, height * scale);
- }
-}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/SpecialGuiScreen.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/SpecialGuiScreen.java
index efe5c36a..280b5b3e 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/SpecialGuiScreen.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/SpecialGuiScreen.java
@@ -29,7 +29,8 @@ public abstract class SpecialGuiScreen extends GuiScreen {
}
protected void dismiss() {
- onDismiss.run();
+ if (onDismiss != null)
+ onDismiss.run();
Minecraft.getMinecraft().displayGuiScreen(null);
}
}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetPrivacyPolicy.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetPrivacyPolicy.java
new file mode 100644
index 00000000..0ee99c92
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/WidgetPrivacyPolicy.java
@@ -0,0 +1,101 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.launcher.gui.screen;
+
+import kr.syeyoung.dungeonsguide.launcher.LetsEncrypt;
+import kr.syeyoung.dungeonsguide.launcher.Main;
+import kr.syeyoung.dungeonsguide.launcher.auth.AuthManager;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.Widget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.DomElementRegistry;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.ParsedWidgetConverter;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.On;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.data.Parser;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.data.ParserElement;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.data.W3CBackedParser;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.util.ResourceLocation;
+import org.apache.commons.io.IOUtils;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class WidgetPrivacyPolicy extends AnnotatedImportOnlyWidget {
+ private static final ExecutorService executor = Executors.newSingleThreadExecutor();
+ @Bind(variableName = "policy")
+ public final BindableAttribute<Widget> policy = new BindableAttribute<>(Widget.class);
+ @Bind(variableName = "policyVisibility")
+ public final BindableAttribute<String> policyVisibility = new BindableAttribute<>(String.class, "loading");
+
+ @Bind(variableName = "policyVersion")
+ public final BindableAttribute<Integer> version = new BindableAttribute<>(Integer.class, 0);
+
+ public WidgetPrivacyPolicy() {
+ super(new ResourceLocation("dungeons_guide_loader:gui/privacyPolicy/privacyPolicy.gui"));
+ reload();
+ }
+
+ @On(functionName = "accept")
+ public void accept() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ AuthManager.getInstance().acceptPrivacyPolicy(version.getValue());
+ Minecraft.getMinecraft().displayGuiScreen(null);
+ }
+ @On(functionName = "deny")
+ public void deny() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ Minecraft.getMinecraft().displayGuiScreen(null);
+ }
+
+ @On(functionName = "reload")
+ public void reload() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ policyVisibility.setValue("loading");
+ executor.submit(() -> {
+ try {
+ HttpsURLConnection urlConnection = (HttpsURLConnection) new URL(Main.POLICY).openConnection();
+ urlConnection.setSSLSocketFactory(LetsEncrypt.LETS_ENCRYPT);
+ urlConnection.setRequestProperty("User-Agent", "DungeonsGuide/4.0");
+ urlConnection.setConnectTimeout(1000);
+ urlConnection.setReadTimeout(3000);
+ urlConnection.setRequestMethod("GET");
+ urlConnection.setDoInput(true);
+
+ try (W3CBackedParser parser = new W3CBackedParser(urlConnection.getInputStream())) {
+ ParserElement element = parser.getRootNode();
+ ParsedWidgetConverter converter = DomElementRegistry.obtainConverter(element.getNodeName());
+ Widget w = converter.convert(this, element);
+ policy.setValue(w);
+ policyVisibility.setValue("loaded");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ policyVisibility.setValue("failed");
+ }
+ });
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/GuiScreenAdapter.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/GuiScreenAdapter.java
index d4d46834..44dfb230 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/GuiScreenAdapter.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/GuiScreenAdapter.java
@@ -261,7 +261,8 @@ public class GuiScreenAdapter extends GuiScreen {
view.setCursor(EnumCursor.DEFAULT);
this.mouseMove(i, j);
EnumCursor newCursor = view.getCurrentCursor();
- if (prevCursor != newCursor) Mouse.setNativeCursor(GLCursors.getCursor(newCursor));
+ if (prevCursor != newCursor)
+ Mouse.setNativeCursor(GLCursors.getCursor(newCursor));
} catch (Throwable e) {
if (e.getMessage() == null || !e.getMessage().contains("hack to stop"))
e.printStackTrace();
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/PolicyVersion.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/PolicyVersion.java
new file mode 100644
index 00000000..e0384810
--- /dev/null
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/PolicyVersion.java
@@ -0,0 +1,52 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.launcher.guiv2.elements;
+
+import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.DomElement;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.Widget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.layouter.Layouter;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.primitive.ConstraintBox;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.primitive.Size;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedExportOnlyWidget;
+import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Export;
+
+import java.util.Collections;
+import java.util.List;
+
+public class PolicyVersion extends AnnotatedExportOnlyWidget implements Layouter {
+ @Export(attributeName = "version")
+ public final BindableAttribute<Integer> docVersion = new BindableAttribute<>(Integer.class);
+ @Export(attributeName = "policyVersion")
+ public final BindableAttribute<Integer> bindVersion = new BindableAttribute<>(Integer.class);
+
+ public PolicyVersion() {
+ docVersion.exportTo(bindVersion);
+ }
+
+ @Override
+ public List<Widget> build(DomElement buildContext) {
+ return Collections.EMPTY_LIST;
+ }
+
+ @Override
+ public Size layout(DomElement buildContext, ConstraintBox constraintBox) {
+ return new Size(0,0);
+ }
+}
diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/DomElementRegistry.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/DomElementRegistry.java
index 4a4eff58..efa7a5fc 100644
--- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/DomElementRegistry.java
+++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/xml/DomElementRegistry.java
@@ -84,6 +84,7 @@ public class DomElementRegistry {
register("InvertStencil", new ExportedWidgetConverter(NegativeStencil::new));
register("WrapGrid", new ExportedWidgetConverter(Wrap::new));
+ register("PolicyVersion", new ExportedWidgetConverter(PolicyVersion::new));
register("ColorButton", new DelegatingWidgetConverter(new ResourceLocation("dungeons_guide_loader:gui/elements/simpleButton.gui")));
register("RoundButton", new DelegatingWidgetConverter(new ResourceLocation("dungeons_guide_loader:gui/elements/dgButton.gui")));
register("IconButton", new DelegatingWidgetConverter(new ResourceLocation("dungeons_guide_loader:gui/elements/iconButton.gui")));
diff --git a/loader/src/main/resources/assets/dungeons_guide_loader/gui/privacyPolicy/privacyPolicy.gui b/loader/src/main/resources/assets/dungeons_guide_loader/gui/privacyPolicy/privacyPolicy.gui
new file mode 100644
index 00000000..2f40ee0b
--- /dev/null
+++ b/loader/src/main/resources/assets/dungeons_guide_loader/gui/privacyPolicy/privacyPolicy.gui
@@ -0,0 +1,74 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU Affero General Public License as published
+ ~ by the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU Affero General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Affero General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+
+<bgcolor backgroundColor="#FF111111">
+ <align vAlign="CENTER">
+ <ConstrainedBox maxHeight="450">
+ <col crossAlign="CENTER">
+ <size width="0" height="10"/>
+ <Text text="Please accept Dungeons Guide privacy policy to use server based features of Dungeons Guide" color="#FFFFFFFF"/>
+ <size width="0" height="10"/>
+ <flexible>
+ <align hAlign="CENTER">
+ <padding left="10" right="10">
+ <border>
+ <line slot="left" dir="VERTICAL" thickness="1.0" color="#FFFFFFFF"/>
+ <line slot="top" dir="HORIZONTAL" thickness="1.0" color="#FFFFFFFF"/>
+ <line slot="bottom" dir="HORIZONTAL" thickness="1.0" color="#FFFFFFFF"/>
+ <line slot="right" dir="VERTICAL" thickness="1.0" color="#FFFFFFFF"/>
+ <ConstrainedBox maxWidth="600" slot="content">
+ <bgcolor backgroundColor="#FF999999">
+ <SelectiveContainer bind:visible="policyVisibility">
+ <align vAlign="CENTER" hAlign="CENTER" slot="loading">
+ <Text text="Loading..."/>
+ </align>
+ <align vAlign="CENTER" hAlign="CENTER" slot="failed">
+ <col mainAlign="CENTER">
+ <Text text="Failed to load"/>
+ <size width="0" height="5"/>
+ <size width="50" height="20">
+ <RoundButton on:click="reload" text="Reload"/>
+ </size>
+ </col>
+ </align>
+ <ScrollablePanel direction="VERTICAL" slot="loaded">
+ <slot bind:child="policy"/>
+ </ScrollablePanel>
+
+ </SelectiveContainer>
+ </bgcolor>
+ </ConstrainedBox>
+ </border>
+ </padding>
+ </align>
+ </flexible>
+ <size width="0" height="15"/>
+ <row mainAlign="CENTER">
+ <size width="50" height="20">
+ <RoundButton text="Accept" on:click="accept"/>
+ </size>
+ <size width="5" height="0"/>
+ <size width="50" height="20">
+ <RoundButton text="Deny" on:click="deny"/>
+ </size>
+ </row>
+ <size width="0" height="10"/>
+ </col>
+ </ConstrainedBox>
+ </align>
+</bgcolor> \ No newline at end of file