diff --git a/AquaNet/.env b/AquaNet/.env.example
similarity index 65%
rename from AquaNet/.env
rename to AquaNet/.env.example
index 2c5fa305..c374df19 100644
--- a/AquaNet/.env
+++ b/AquaNet/.env.example
@@ -7,4 +7,10 @@ VITE_TURNSTILE_SITE_KEY=0x4AAAAAAASGA2KQEIelo9P9
VITE_DISCORD_INVITE=https://discord.gg/FNgveqFF7s
VITE_TELEGRAM_INVITE=https://t.me/+zBL4RZdyfvUzZGU1
VITE_QQ_INVITE=https://qm.qq.com/q/dpYmGoVHnG
-VITE_GITHUB_REPOSITORY=https://github.com/MewoLab/AquaDX
\ No newline at end of file
+VITE_GITHUB_REPOSITORY=https://github.com/MewoLab/AquaDX
+
+# example:
+# https://aquadx.net/#accesskey=....
+VITE_ACCESSCODE_QKEY=accesskey
+
+VITE_DEFAULT_GAME=mai2
\ No newline at end of file
diff --git a/AquaNet/.gitignore b/AquaNet/.gitignore
index 69166fea..6deb399a 100644
--- a/AquaNet/.gitignore
+++ b/AquaNet/.gitignore
@@ -35,4 +35,6 @@ dist-ssr
public/chu3
# local env file
-*.local
\ No newline at end of file
+*.local
+
+.env
diff --git a/AquaNet/public/announcement.txt b/AquaNet/public/announcement.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/AquaNet/src/App.svelte b/AquaNet/src/App.svelte
index 948ebb61..7ff3e1ae 100644
--- a/AquaNet/src/App.svelte
+++ b/AquaNet/src/App.svelte
@@ -9,7 +9,8 @@
import Settings from "./pages/User/Settings.svelte";
import MaiPhoto from "./pages/MaiPhoto.svelte";
import { pfp, tooltip } from "./libs/ui"
- import { ANNOUNCEMENT } from "./libs/config";
+ import { ANNOUNCEMENT } from "./libs/announcement";
+ import { DEFAULT_GAME } from "./libs/config"
import { t } from "./libs/i18n";
import Transfer from "./pages/Transfer/Transfer.svelte";
import { link } from "d3";
@@ -34,7 +35,7 @@
let me: AquaNetUser
let playedMai = false
- let recentGame: string = "mai2";
+ let recentGame: string = DEFAULT_GAME;
if (USER.isLoggedIn())
{
@@ -60,9 +61,9 @@
AquaNet
{/if}
- {#if ANNOUNCEMENT}
+ {#if $ANNOUNCEMENT}
- {t('navigation.notice')}: {ANNOUNCEMENT}
+ {t('navigation.notice')}: {$ANNOUNCEMENT}
{/if}
{t('navigation.home').toLowerCase()}
diff --git a/AquaNet/src/libs/acUrl.ts b/AquaNet/src/libs/acUrl.ts
new file mode 100644
index 00000000..9d79c7b9
--- /dev/null
+++ b/AquaNet/src/libs/acUrl.ts
@@ -0,0 +1,35 @@
+// card handler. for dealing user QR scan.
+// this will assumes that the link of the generated QR code in [access code]
+// page has been altered by modder to link to custom
+
+import { ACCESSCODE_QKEY } from "./config";
+
+const query = new URLSearchParams(location.hash.slice(1));
+const lsKey = "acurl"
+
+export const url_has = (): boolean => query.has(ACCESSCODE_QKEY);
+export const get = (): string => localStorage.getItem(lsKey) || "";
+export const has = (): boolean => !!localStorage.getItem(lsKey);
+export const clear = (): void => localStorage.removeItem(lsKey);
+
+export function check() {
+ if (!url_has()) return
+
+ console.log("Found access code in URL. Saving.")
+ localStorage.setItem(lsKey, query.get(ACCESSCODE_QKEY) || "")
+}
+
+export function preview() {
+ const card = get()
+ const masked =
+ card.slice(0, 4) +
+ "x".repeat(card.length - 4);
+
+ return masked.match(/.{1,4}/g)?.join(" ");
+}
+
+export function previewR() {
+ const card = get()
+
+ return card.match(/.{1,4}/g)?.join(" ");
+}
\ No newline at end of file
diff --git a/AquaNet/src/libs/announcement.ts b/AquaNet/src/libs/announcement.ts
new file mode 100644
index 00000000..63b0f2ff
--- /dev/null
+++ b/AquaNet/src/libs/announcement.ts
@@ -0,0 +1,11 @@
+import { writable } from "svelte/store"
+
+export const ANNOUNCEMENT = writable('')
+
+// This task must not bother the existing one. Keep it async in the background instead
+void (async () => {
+ let r = await fetch("/announcement.txt")
+ if (!r.ok) return;
+
+ ANNOUNCEMENT.set(await r.text())
+})()
\ No newline at end of file
diff --git a/AquaNet/src/libs/config.ts b/AquaNet/src/libs/config.ts
index df32060b..a668266c 100644
--- a/AquaNet/src/libs/config.ts
+++ b/AquaNet/src/libs/config.ts
@@ -17,7 +17,8 @@ export const FADE_OUT = { duration: 200 }
export const FADE_IN = { delay: 400 }
export const DEFAULT_PFP = '/assets/imgs/no_profile.png'
-export const ANNOUNCEMENT = '' // If set, will add an announcement to the top bar. Keep it short.
+// Key name for access key scanned from QR code
+export const ACCESSCODE_QKEY = import.meta.env.VITE_ACCESSCODE_QKEY || "accesskey"
// Documentation for Userbox mode can be found in `docs/aquabox-url-mode.md`
// Please note that if this is set, it must be manually unset by users in Chuni Settings -> Update Userbox -> Switch to URL mode -> (empty value) -> Enter key
@@ -25,6 +26,8 @@ export const USERBOX_DEFAULT_URL = ""
export const HAS_USERBOX_ASSETS = true
+export const DEFAULT_GAME = import.meta.env.VITE_DEFAULT_GAME || "mai2"
+
// Meow meow meow
// Matching servers
@@ -45,4 +48,4 @@ export const CHU3_MATCHINGS: ChusanMatchingOption[] = [
reflector: "http://reflector.naominet.live:18080/",
coop: ["RinNET", "MysteriaNET"],
},
-]
+]
\ No newline at end of file
diff --git a/AquaNet/src/libs/i18n/en_ref.ts b/AquaNet/src/libs/i18n/en_ref.ts
index c0cadac9..a2eb5ab1 100644
--- a/AquaNet/src/libs/i18n/en_ref.ts
+++ b/AquaNet/src/libs/i18n/en_ref.ts
@@ -60,6 +60,7 @@ export const EN_REF_Welcome = {
'welcome.verified': 'Your email has been verified! You can now log in now.',
'welcome.verification-failed': 'Verification failed: ${message}. Please try again.',
'welcome.password-reset-done': 'Your password has been updated! Please log back in.',
+ 'welcome.login_link': 'Login / register to link your card.'
}
export const EN_REF_LEADERBOARD = {
diff --git a/AquaNet/src/pages/Home.svelte b/AquaNet/src/pages/Home.svelte
index c36f120c..681d6307 100644
--- a/AquaNet/src/pages/Home.svelte
+++ b/AquaNet/src/pages/Home.svelte
@@ -6,6 +6,7 @@
import { t } from "../libs/i18n";
import ImportDataAction from "./Home/ImportDataAction.svelte";
import DashboardTabs from "../components/DashboardTabs.svelte";
+ import * as acUrl from "../libs/acUrl";
USER.ensureLoggedIn();
@@ -13,6 +14,10 @@
let error = "";
USER.me().then((m) => me = m).catch(e => error = e.message)
+
+ if (acUrl.has()) {
+ location.href = "/cards"
+ }
diff --git a/AquaNet/src/pages/Home/LinkCard.svelte b/AquaNet/src/pages/Home/LinkCard.svelte
index db1ad025..513e69a9 100644
--- a/AquaNet/src/pages/Home/LinkCard.svelte
+++ b/AquaNet/src/pages/Home/LinkCard.svelte
@@ -9,6 +9,8 @@
import StatusOverlays from "../../components/StatusOverlays.svelte"
import { t } from "../../libs/i18n"
import DashboardTabs from "../../components/DashboardTabs.svelte";
+ import * as acUrl from "../../libs/acUrl"
+ import { ACCESSCODE_QKEY } from "../../libs/config";
// State
let state: 'ready' | 'linking-AC' | 'linking-SN' | 'loading' = "loading"
@@ -27,7 +29,10 @@
// Always put the ghost card at the top
m.cards.sort((a, b) => a.isGhost ? -1 : 1)
state = "ready"
+
+ linkQR()
}).catch(e => error = e.message)
+ acUrl.check()
updateMe()
// Data conflict overlay
@@ -273,6 +278,16 @@
};
inputACChange();
}
+
+ function linkQR() {
+ if (!acUrl.has()) return;
+
+ inputAC = acUrl.get()
+ if (inputAC.length !== 20) return inputAC = "";
+
+ inputACChange()
+ acUrl.clear()
+ }
diff --git a/AquaNet/src/pages/Ranking.svelte b/AquaNet/src/pages/Ranking.svelte
index c942835f..52269922 100644
--- a/AquaNet/src/pages/Ranking.svelte
+++ b/AquaNet/src/pages/Ranking.svelte
@@ -9,8 +9,9 @@
import UserCard from "../components/UserCard.svelte";
import Tooltip from "../components/Tooltip.svelte";
import Cap from "./Ranking/Cap.svelte";
+ import { DEFAULT_GAME } from "../libs/config";
- export let game: GameName = 'mai2';
+ export let game: GameName = DEFAULT_GAME;
title(`Ranking`);
diff --git a/AquaNet/src/pages/Welcome.svelte b/AquaNet/src/pages/Welcome.svelte
index 9442fc57..0676cffd 100644
--- a/AquaNet/src/pages/Welcome.svelte
+++ b/AquaNet/src/pages/Welcome.svelte
@@ -6,6 +6,14 @@
import { USER } from "../libs/sdk";
import { t } from "../libs/i18n"
+ import * as acUrl from "../libs/acUrl"
+ const hasAc = acUrl.has()
+ let previewAc = ""
+
+ if (hasAc) {
+ previewAc = acUrl.preview() || ""
+ }
+
let params = new URLSearchParams(window.location.search)
let state = "home"
@@ -178,6 +186,13 @@
AquaNet
+
+ {#if hasAc}
+ {t('welcome.login_link')}:
+ {previewAc}
+ {/if}
+
+
{#if state === "home"}
@@ -329,6 +344,9 @@
margin-bottom: 32px
opacity: 0.9
+ #welcome
+ margin-bottom: 32px
+
.btn-group
display: flex
gap: 8px