From 08af00da298e6a160d49f15063dd43aa4eb8d473 Mon Sep 17 00:00:00 2001 From: Raymond <101374892+raymonable@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:19:21 -0500 Subject: [PATCH] feat: :lipstick: aquabox on profiles + avatar fixes --- .../components/settings/ChuniSettings.svelte | 12 +++- .../settings/userbox/ChuniPenguin.svelte | 47 ++++++++++---- .../settings/userbox/ChuniUserplate.svelte | 31 ++++++---- AquaNet/src/libs/i18n/en_ref.ts | 2 + AquaNet/src/libs/sdk.ts | 2 + AquaNet/src/libs/userbox/userbox.ts | 1 + AquaNet/src/pages/UserHome.svelte | 61 +++++++++++++++++++ 7 files changed, 130 insertions(+), 26 deletions(-) diff --git a/AquaNet/src/components/settings/ChuniSettings.svelte b/AquaNet/src/components/settings/ChuniSettings.svelte index 2a5f2c33..e945f9b5 100644 --- a/AquaNet/src/components/settings/ChuniSettings.svelte +++ b/AquaNet/src/components/settings/ChuniSettings.svelte @@ -99,6 +99,7 @@ let USERBOX_SETUP_TEXT = t("userbox.new.setup"); let USERBOX_ENABLED = useLocalStorage("userboxNew", false); + let USERBOX_PROFILE_ENABLED = useLocalStorage("userboxNewProfile", false); let USERBOX_INSTALLED = false; let USERBOX_SUPPORT = "webkitGetAsEntry" in DataTransferItem.prototype; @@ -155,9 +156,9 @@ {:else}
- userboxSelected = "nameplateId"} chuniCharacter={userbox.characterId} chuniLevel={userbox.level} chuniRating={userbox.playerRating / 100} + userboxSelected = "nameplateId"} chuniCharacter={userbox.characterId} chuniLevel={userbox.level.toString()} chuniRating={userbox.playerRating / 100} chuniNameplate={userbox.nameplateId} chuniName={userbox.userName} chuniTrophyName={allItems.trophy[userbox.trophyId].name}> -
@@ -219,6 +220,13 @@ {t(`userbox.new.activate_desc`)} +
+ + +
{/if} {#if USERBOX_SUPPORT}

diff --git a/AquaNet/src/components/settings/userbox/ChuniPenguin.svelte b/AquaNet/src/components/settings/userbox/ChuniPenguin.svelte index ed9730c6..a5207fcc 100644 --- a/AquaNet/src/components/settings/userbox/ChuniPenguin.svelte +++ b/AquaNet/src/components/settings/userbox/ChuniPenguin.svelte @@ -29,10 +29,10 @@ {/await} - {#await DDSreader.getFileFromSheet("surfboard:CHU_UI_Common_Avatar_body_00.dds", 0, 0, 85, 160, 0.75) then imageURL} + {#await DDSreader.getFileFromSheet("surfboard:CHU_UI_Common_Avatar_body_00.dds", 80, 0, 110, 100, 0.75) then imageURL} Left Arm {/await} - {#await DDSreader.getFileFromSheet("surfboard:CHU_UI_Common_Avatar_body_00.dds", 0, 0, 85, 160, 0.75) then imageURL} + {#await DDSreader.getFileFromSheet("surfboard:CHU_UI_Common_Avatar_body_00.dds", 80, 0, 110, 100, 0.75) then imageURL} Right Arm {/await} @@ -77,8 +77,11 @@

- {#await DDSreader.getFileFromSheet(`avatarAccessory:${chuniSkin.toString().padStart(8, "0")}`, 0, 410, 167, 80, 0.75) then imageURL} - Feet + {#await DDSreader.getFileFromSheet(`avatarAccessory:${chuniSkin.toString().padStart(8, "0")}`, 0, 410, 85, 80, 0.75) then imageURL} + Foot + {/await} + {#await DDSreader.getFileFromSheet(`avatarAccessory:${chuniSkin.toString().padStart(8, "0")}`, 85, 410, 85, 80, 0.75) then imageURL} + Foot {/await}
@@ -88,7 +91,7 @@ 0% transform: translate(-50%, 0%) translate(0%, -50%) 50% - transform: translate(-50%, 10px) translate(0%, -50%) + transform: translate(-50%, 5px) translate(0%, -50%) 100% transform: translate(-50%, 0%) translate(0%, -50%) @keyframes chuniPenguinArmLeft @@ -108,11 +111,19 @@ img -webkit-user-drag: none + user-select: none .chuni-penguin height: 512px aspect-ratio: 1/2 position: relative + pointer-events: none + + &.chuni-penguin-float + position: absolute + top: 50% + left: 50% + transform: translate(-50%, -50%) .chuni-penguin-body, .chuni-penguin-feet transform: translate(-50%, -50%) @@ -122,21 +133,31 @@ .chuni-penguin-body top: 50% z-index: 1 - animation: chuniPenguinBodyBob 2s infinite cubic-bezier(0.45, 0, 0.55, 1) + animation: chuniPenguinBodyBob 1s infinite cubic-bezier(0.45, 0, 0.55, 1) .chuni-penguin-feet - top: 82.5% + top: 80% z-index: 0 + width: 175px + display: flex + justify-content: center + + img + margin-left: auto + margin-right: auto .chuni-penguin-arm - transform-origin: 95% 10% + transform-origin: 40% 10% position: absolute top: 40% + z-index: 2 .chuni-penguin-arm-left - left: 0% - animation: chuniPenguinArmLeft 1.5s infinite cubic-bezier(0.45, 0, 0.55, 1) + left: 15% + transform: translate(-50%, 0) + animation: chuniPenguinArmLeft 1s infinite cubic-bezier(0.45, 0, 0.55, 1) 0.5s .chuni-penguin-arm-right - left: 70% - animation: chuniPenguinArmRight 1.5s infinite cubic-bezier(0.45, 0, 0.55, 1) + left: 95% + transform: translate(-50%, 0) scaleX(-1) + animation: chuniPenguinArmRight 1s infinite cubic-bezier(0.45, 0, 0.55, 1) 0.5s .chuni-penguin-accessory transform: translate(-50%, -50%) @@ -149,7 +170,7 @@ .chuni-penguin-beak top: 29.5% .chuni-penguin-wear - top: 57.5% + top: 60% .chuni-penguin-head top: 7.5% z-index: 10 diff --git a/AquaNet/src/components/settings/userbox/ChuniUserplate.svelte b/AquaNet/src/components/settings/userbox/ChuniUserplate.svelte index 37d485c7..2cebf430 100644 --- a/AquaNet/src/components/settings/userbox/ChuniUserplate.svelte +++ b/AquaNet/src/components/settings/userbox/ChuniUserplate.svelte @@ -4,25 +4,25 @@ const DDSreader = new DDS(ddsDB); - export var chuniLevel: number = 1 + export var chuniLevel: string = "╳" export var chuniName: string = "AquaDX" export var chuniRating: number = 1.23 export var chuniNameplate: number = 1 export var chuniCharacter: number = 0 export var chuniTrophyName: string = "NEWCOMER" -{#await DDSreader?.getFile(`nameplate:${chuniNameplate.toString().padStart(8, "0")}`) then nameplateURL} +{#await DDSreader?.getFile(`nameplate:${chuniNameplate.toString().padStart(8, "0")}`, `nameplate:00000001`) then nameplateURL}
- {#await DDSreader?.getFile(`characterThumbnail:${chuniCharacter.toString().padStart(6, "0")}`) then characterThumbnailURL} + {#await DDSreader?.getFile(`characterThumbnail:${chuniCharacter.toString().padStart(6, "0")}`, `characterThumbnail:000000`) then characterThumbnailURL} Character {/await} {#await DDSreader?.getFileFromSheet("surfboard:CHU_UI_title_rank_00_v10.dds", 5, 5 + (75 * 2), 595, 64) then trophyURL}
{chuniTrophyName} - Trophy
+ Trophy {/await}
@@ -57,7 +57,7 @@ cursor: pointer .chuni-trophy - width: 410px + width: 390px height: 45px background-position: center background-size: cover @@ -74,14 +74,21 @@ font-family: sans-serif font-weight: bold + overflow-x: hidden + white-space: nowrap + text-overflow: ellipsis + z-index: 1 text-shadow: 0 1px white + margin: 0 10px - img - width: 100% - height: 100% - position: absolute - z-index: -1 + img.chuni-trophy-bg + width: 410px + height: 45px + position: absolute + top: 40px + right: 25px + z-index: -1 .chuni-character position: absolute @@ -115,9 +122,11 @@ .chuni-user-name flex: 1 0 65% box-shadow: 0 1px 0 #ccc + white-space: nowrap + text-overflow: ellipsis .chuni-user-level - font-size: 2em + font-size: 1.5em margin-left: 10px .chuni-user-name-text diff --git a/AquaNet/src/libs/i18n/en_ref.ts b/AquaNet/src/libs/i18n/en_ref.ts index 40a07673..4538ed7f 100644 --- a/AquaNet/src/libs/i18n/en_ref.ts +++ b/AquaNet/src/libs/i18n/en_ref.ts @@ -189,6 +189,8 @@ export const EN_REF_USERBOX = { 'userbox.new.activate_update': 'Update AquaBox (game files required)', 'userbox.new.activate': 'Use AquaBox', 'userbox.new.activate_desc': 'Enable displaying UserBoxes with their nameplate & avatar', + 'userbox.new.activate_profile': 'Use AquaBox on profiles', + 'userbox.new.activate_profile_desc': 'Enable displaying UserBoxes with their nameplate & avatar on profile pages', 'userbox.new.error.invalidFolder': 'The folder you selected is invalid. Ensure that your game\'s version is Lumi or newer and that the "A001" option pack is present.' } diff --git a/AquaNet/src/libs/sdk.ts b/AquaNet/src/libs/sdk.ts index b6363c5f..9b495f76 100644 --- a/AquaNet/src/libs/sdk.ts +++ b/AquaNet/src/libs/sdk.ts @@ -266,6 +266,8 @@ export const USERBOX = { get('/api/v2/game/chu3/user-box', {}), setUserBox: (d: { field: string, value: number | string }) => post(`/api/v2/game/chu3/user-detail-set`, d), + getUserProfile: (username: string): Promise => + get(`/api/v2/game/chu3/user-detail`, {username}) } export const CARD = { diff --git a/AquaNet/src/libs/userbox/userbox.ts b/AquaNet/src/libs/userbox/userbox.ts index 2b3e7343..bed119aa 100644 --- a/AquaNet/src/libs/userbox/userbox.ts +++ b/AquaNet/src/libs/userbox/userbox.ts @@ -174,6 +174,7 @@ export async function userboxFileProcess(folder: FileSystemEntry, progressUpdate if (dataFolder) await scanOptionFolder(dataFolder, progressUpdate); useLocalStorage("userboxNew", false).value = true; + useLocalStorage("userboxNewProfile", false).value = true; location.reload(); return null diff --git a/AquaNet/src/pages/UserHome.svelte b/AquaNet/src/pages/UserHome.svelte index ab506021..7e5a00f4 100644 --- a/AquaNet/src/pages/UserHome.svelte +++ b/AquaNet/src/pages/UserHome.svelte @@ -105,6 +105,41 @@ d!.user.rival = isAdd }).catch(e => error = e.message).finally(() => isLoading = false) } + + /* Aquabox */ + + import { userboxFileProcess, ddsDB, initializeDb } from "../libs/userbox/userbox" + import ChuniPenguinComponent from "../components/settings/userbox/ChuniPenguin.svelte" + import ChuniUserplateComponent from "../components/settings/userbox/ChuniUserplate.svelte"; + import { + type UserBox, + type UserItem, + } from "../libs/generalTypes"; + import { USERBOX } from "../libs/sdk"; + + let USERBOX_ACTIVE = useLocalStorage("userboxNewProfile", false); + let USERBOX_INSTALLED = false; + + let userbox: UserBox; + let allItems: Record> = {}; + + if (game == "chu3" && USERBOX_ACTIVE.value) { + indexedDB.databases().then(async (dbi) => { + let databaseExists = dbi.some(db => db.name == "userboxChusanDDS"); + if (databaseExists) { + await initializeDb(); + const profile = await USERBOX.getUserProfile(username).catch(_ => null) + if (!profile) return; + userbox = profile; + console.log(userbox); + + allItems = await DATA.allItems('chu3').catch(_ => { + error = t("userbox.error.nodata") + }) as typeof allItems + USERBOX_INSTALLED = databaseExists; + } + }) + }
@@ -132,6 +167,18 @@
+ {#if USERBOX_ACTIVE.value && USERBOX_INSTALLED && game == "chu3"} +
+ +
+ +
+
+ {/if} +

{titleText} {t('UserHome.Statistics')}

@@ -576,4 +623,18 @@ &:before content: "+" color: vars.$c-good + +.chuni-userbox-container + display: flex + align-items: center + justify-content: center + + .chuni-penguin-container + height: 256px + aspect-ratio: 1 + position: relative + +@media (max-width: 1000px) + .chuni-userbox-container + flex-wrap: wrap