mirror of
https://github.com/PhaseII-eAmusement-Network/PhaseWeb3-Vue.git
synced 2026-09-08 17:25:16 -05:00
This commit is contained in:
5110
public/data-sources/sdvx/akaname/6.json
Normal file
5110
public/data-sources/sdvx/akaname/6.json
Normal file
File diff suppressed because it is too large
Load Diff
136
src/components/Cards/AkanameCardBox.vue
Normal file
136
src/components/Cards/AkanameCardBox.vue
Normal file
@@ -0,0 +1,136 @@
|
||||
<script setup>
|
||||
import axios from "axios";
|
||||
import { watch, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { mdiLoading } from "@mdi/js";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import CardBox from "@/components/CardBox.vue";
|
||||
import FormField from "@/components/FormField.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import PillTag from "@/components/PillTag.vue";
|
||||
|
||||
import { GameConstants } from "@/constants";
|
||||
import { APIUpdateProfile } from "@/stores/api/profile";
|
||||
|
||||
const props = defineProps({
|
||||
profile: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
version: {
|
||||
type: Number,
|
||||
default: 6,
|
||||
},
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
const userProfile = ref(JSON.parse(JSON.stringify(props.profile)));
|
||||
const version = ref(props.version);
|
||||
const AkanameKey = ref(0);
|
||||
|
||||
const newAkaname = ref(userProfile.value?.akaname ?? 0);
|
||||
const AkanameSettings = ref([]);
|
||||
const isModified = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
watch(
|
||||
() => props.version,
|
||||
() => {
|
||||
userProfile.value = JSON.parse(JSON.stringify(props.profile));
|
||||
loadAkanameSettings();
|
||||
newAkaname.value = userProfile.value?.akaname;
|
||||
isModified.value = false;
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.version,
|
||||
() => {
|
||||
version.value = props.version;
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
newAkaname,
|
||||
() => {
|
||||
AkanameKey.value++;
|
||||
isModified.value = !akanameEquals(newAkaname.value, props.profile.akaname);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
loadAkanameSettings();
|
||||
function loadAkanameSettings() {
|
||||
axios
|
||||
.get(`/data-sources/sdvx/akaname/${version.value}.json`)
|
||||
.then((r) => {
|
||||
if (r.data) {
|
||||
AkanameSettings.value = r.data;
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error.message);
|
||||
});
|
||||
}
|
||||
|
||||
function akanameEquals(akaname1, akaname2) {
|
||||
return JSON.stringify({ akaname1 }) === JSON.stringify({ akaname2 });
|
||||
}
|
||||
|
||||
async function updateProfile() {
|
||||
loading.value = true;
|
||||
var newProfile = JSON.parse(JSON.stringify(props.profile));
|
||||
|
||||
newProfile.akaname = newAkaname.value;
|
||||
const profileStatus = await APIUpdateProfile(
|
||||
GameConstants.SDVX,
|
||||
props.version,
|
||||
{ akaname: newAkaname.value }
|
||||
);
|
||||
if (profileStatus.status != "error") {
|
||||
router.go();
|
||||
}
|
||||
}
|
||||
|
||||
function revert() {
|
||||
newAkaname.value = userProfile.value?.akaname ?? 0;
|
||||
isModified.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CardBox class="mt-6">
|
||||
<PillTag color="info" label="Akaname" class="mb-2" />
|
||||
<div class="grid md:grid-cols-2 space-y-6 align-center">
|
||||
<form>
|
||||
<FormField label="Akaname" help="Sets your profile's subtitle">
|
||||
<FormControl v-model="newAkaname" :options="AkanameSettings" />
|
||||
</FormField>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="space-x-2 pb-4">
|
||||
<BaseButton
|
||||
v-if="isModified"
|
||||
color="success"
|
||||
label="Save"
|
||||
@click="updateProfile()"
|
||||
/>
|
||||
<BaseButton
|
||||
v-if="isModified"
|
||||
color="danger"
|
||||
label="Revert"
|
||||
@click="revert()"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-if="loading"
|
||||
:path="mdiLoading"
|
||||
color="text-yellow-500"
|
||||
class="animate animate-spin"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</CardBox>
|
||||
</template>
|
||||
@@ -1,12 +1,14 @@
|
||||
<script setup>
|
||||
import axios from "axios";
|
||||
import {
|
||||
mdiCog,
|
||||
mdiAccountDetails,
|
||||
mdiPlaylistMusicOutline,
|
||||
mdiFormatListText,
|
||||
} from "@mdi/js";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { dashCode } from "@/constants/userData";
|
||||
import { getGameInfo } from "@/constants";
|
||||
import { GameConstants, getGameInfo } from "@/constants";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import UserEmblem from "@/components/UserEmblem.vue";
|
||||
import UserQpro from "@/components/UserQpro.vue";
|
||||
@@ -40,6 +42,32 @@ function colorText() {
|
||||
}
|
||||
|
||||
const thisGame = getGameInfo(props.game);
|
||||
const version = ref(props.version);
|
||||
const AkanameSettings = ref([]);
|
||||
const fullyLoaded = ref(false);
|
||||
|
||||
async function loadAkanameSettings() {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`/data-sources/sdvx/akaname/${version.value}.json`
|
||||
);
|
||||
if (response.data) {
|
||||
AkanameSettings.value = response.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading Akaname settings:", error.message);
|
||||
} finally {
|
||||
fullyLoaded.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (thisGame.id === GameConstants.SDVX) {
|
||||
await loadAkanameSettings();
|
||||
} else {
|
||||
fullyLoaded.value = true;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -70,6 +98,16 @@ const thisGame = getGameInfo(props.game);
|
||||
<h1 :class="colorText()" class="text-4xl md:text-5xl font-bold">
|
||||
{{ profile.username }}
|
||||
</h1>
|
||||
<template v-if="fullyLoaded">
|
||||
<p
|
||||
v-if="profile.akaname"
|
||||
class="text-2xl tracking-widest font-light my-1"
|
||||
>
|
||||
{{
|
||||
AkanameSettings.find((item) => item.id === profile.akaname)?.label
|
||||
}}
|
||||
</p>
|
||||
</template>
|
||||
<p class="text-xl font-mono">{{ dashCode(profile.extid) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,7 @@ import FormCheckRadio from "@/components/FormCheckRadio.vue";
|
||||
import FormControl from "@/components/FormControl.vue";
|
||||
import EmblemCardBox from "@/components/Cards/EmblemCardBox.vue";
|
||||
import QproCardBox from "@/components/Cards/QproCardBox.vue";
|
||||
import AkanameCardBox from "@/components/Cards/AkanameCardBox.vue";
|
||||
import PillTag from "@/components/PillTag.vue";
|
||||
|
||||
import { APIGetProfile, APIUpdateProfile } from "@/stores/api/profile";
|
||||
@@ -275,6 +276,11 @@ async function updateProfile() {
|
||||
:profile="myProfile"
|
||||
:version="versionForm.currentVersion"
|
||||
/>
|
||||
<AkanameCardBox
|
||||
v-if="gameID == 'sdvx' && versionForm.currentVersion >= 5"
|
||||
:profile="myProfile"
|
||||
:version="versionForm.currentVersion"
|
||||
/>
|
||||
</div>
|
||||
</SectionMain>
|
||||
</LayoutAuthenticated>
|
||||
|
||||
52
tools/akaname_parser.py
Normal file
52
tools/akaname_parser.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
args = sys.argv
|
||||
if len(args) != 2:
|
||||
print('<akaname_parser> <akaname_parts.xml path>\nWrites a resulting JSON file to the same path.')
|
||||
sys.exit()
|
||||
|
||||
inFilePath = args[1]
|
||||
if not os.path.exists(inFilePath):
|
||||
print(f'The path {inFilePath} does not exist!')
|
||||
sys.exit()
|
||||
|
||||
if not inFilePath.endswith('.xml'):
|
||||
print('You must supply an XML file.')
|
||||
sys.exit()
|
||||
|
||||
def parseXML(xmlFile: str) -> list[dict]:
|
||||
root = ET.fromstring(xmlFile)
|
||||
parts = []
|
||||
for part in root.findall('part'):
|
||||
partId = part.attrib.get('id', None)
|
||||
if not partId:
|
||||
continue
|
||||
|
||||
wordFormat = part.find('word')
|
||||
if wordFormat.text == None:
|
||||
continue
|
||||
|
||||
parsedData = {}
|
||||
if wordFormat.text.startswith('['):
|
||||
pattern = re.findall(r"\[([a-z]+):([^\]]+)\]", wordFormat.text)
|
||||
parsedData = {key: value.split(',') if ',' in value else value for key, value in pattern}
|
||||
contentMatch = re.search(r"\[c:[^\]]+\](.*?)\[/c\]", wordFormat.text)
|
||||
parsedData['label'] = contentMatch.group(1) if contentMatch else ""
|
||||
else:
|
||||
parsedData['label'] = wordFormat.text
|
||||
parsedData['id'] = int(partId)
|
||||
parts.append(parsedData)
|
||||
return parts
|
||||
|
||||
akanameData = []
|
||||
with open(inFilePath, 'r', encoding='shift-jis') as inFile:
|
||||
akanameData = parseXML(inFile.read())
|
||||
|
||||
with open(inFilePath.replace('.xml', '.json'), 'w', encoding='utf-8') as outFile:
|
||||
outFile.write(json.dumps(akanameData, indent=4))
|
||||
|
||||
print(f'Converted {len(akanameData)} akaname parts\nyippie!')
|
||||
Reference in New Issue
Block a user