mirror of
https://dev.s-ul.net/Galexion/MaiMaiDXNet.git
synced 2024-11-28 03:10:49 +01:00
557 lines
20 KiB
JavaScript
557 lines
20 KiB
JavaScript
// Get the clear storage button element
|
|
const clearStorageBtn = document.getElementById('clear-storage-btn');
|
|
|
|
// Add a click event listener to the clear storage button
|
|
clearStorageBtn.addEventListener('click', () => {
|
|
// Remove the cookies
|
|
function removeCookies() {
|
|
// Set the expiration date to a date in the past
|
|
const expirationDate = new Date(0).toUTCString();
|
|
|
|
// Set the ext_id cookie to expire
|
|
document.cookie = `ext_id=; expires=${expirationDate}`;
|
|
|
|
// Set the luid cookie to expire
|
|
document.cookie = `luid=; expires=${expirationDate}`;
|
|
|
|
// Set the aime_card_id cookie to expire
|
|
document.cookie = `aime_card_id=; expires=${expirationDate}`;
|
|
}
|
|
|
|
// Example usage
|
|
removeCookies();
|
|
window.location = "/";
|
|
});
|
|
|
|
function startBanBtnEventListener(status) {
|
|
// Get the Ban Button Element
|
|
const banBtn = document.getElementById('banButton');
|
|
|
|
// Add a click Event Listener to the Ban button.
|
|
banBtn.addEventListener('click', () => {
|
|
if (status === 0) {
|
|
getuserbanned(aime_card_id)
|
|
} else {
|
|
getuserunbanned(aime_card_id)
|
|
}
|
|
});
|
|
}
|
|
// Get the cookie string
|
|
const cookieString = document.cookie;
|
|
|
|
// Parse the cookie string and extract the values
|
|
const cookies = cookieString.split(';');
|
|
let ext_id, luid, aime_card_id;
|
|
|
|
for (let i = 0; i < cookies.length; i++) {
|
|
const cookie = cookies[i].trim();
|
|
const cookieParts = cookie.split('=');
|
|
|
|
if (cookieParts[0] === 'ext_id') {
|
|
ext_id = cookieParts[1];
|
|
}
|
|
|
|
if (cookieParts[0] === 'luid') {
|
|
luid = cookieParts[1];
|
|
}
|
|
|
|
if (cookieParts[0] === 'aime_card_id') {
|
|
aime_card_id = cookieParts[1];
|
|
}
|
|
}
|
|
|
|
// Send the user to the sign in page if they aren't already signed in to the website.
|
|
if (ext_id && luid) {
|
|
|
|
} else {
|
|
console.log('User Data Not Detected! Please Sign In.');
|
|
window.location = "/";
|
|
}
|
|
const userdata = JSON.parse(document.currentScript.getAttribute('data-userdata'));
|
|
|
|
//=====================================================================
|
|
// Now Exiting: Cookie Data ///////////////// Now Entering: User Data
|
|
//=====================================================================
|
|
|
|
// general functions
|
|
|
|
function padNumber(num, size) {
|
|
let s = num + "";
|
|
while (s.length < size) {
|
|
s = "0" + s;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
async function getReleventInformation(musicData, id) {
|
|
const songMatch = musicData[id];
|
|
if (!songMatch) {
|
|
return null;
|
|
}
|
|
return songMatch;
|
|
}
|
|
|
|
async function getReleventInformationMap(mapData, mapid) {
|
|
let mapMatch = undefined;
|
|
for(map of mapData) {
|
|
if (map.mapInfomation.colorId.id == mapid) {
|
|
mapMatch = map
|
|
} else continue
|
|
|
|
}
|
|
return mapMatch
|
|
}
|
|
|
|
// Ban Check lmao
|
|
|
|
if (userdata.ban_state === 2 ||userdata.banState === 2) {
|
|
//nice
|
|
const parent = document.getElementById("User");
|
|
const wrapperDiv = document.createElement("div");
|
|
wrapperDiv.id = 'wrapper';
|
|
const scoreDiv = document.createElement("div");
|
|
scoreDiv.classList.add('error')
|
|
scoreDiv.innerHTML = `<h3 style='
|
|
word-wrap: break-word;
|
|
max-width:800px;'>Heya! It looks like you've been banned from playing on this profile, but don't worry - you can still enjoy the game in guest mode and view this profile. However, your account won't be able to play on it anymore. If you have any questions about your ban, please contact your Network Administrator.</h3>`; // or set the HTML content with scoreDiv.innerHTML = "<p>This is some HTML content</p>;
|
|
parent.insertBefore(wrapperDiv, parent.firstChild);
|
|
wrapperDiv.appendChild(scoreDiv);
|
|
document.getElementById('BanUserArea').innerHTML = `Welcome back, developer! You found it! This is the unban button, available for self-banned users and Network admins. Click this button to reverse the ban, stop testing the features needed to be tested while banned, and get back to having fun.`;
|
|
let banButton = document.createElement('button');
|
|
banButton.id = "banButton";
|
|
banButton.innerHTML = "let me in... LET ME INnNnNnNnNnNnNnNnN";
|
|
|
|
document.getElementById('BanUserArea').append(banButton);
|
|
startBanBtnEventListener(1) // unban user
|
|
} else {
|
|
document.getElementById('BanUserArea').innerHTML = `Caution! Pressing this button will result in self-ban. Please use with care or take a break without resorting to self-banning. Remember, you can always reverse the action through the web UI.`;
|
|
let banButton = document.createElement('button');
|
|
banButton.id = "banButton";
|
|
banButton.innerHTML = "I Quit.";
|
|
|
|
document.getElementById('BanUserArea').append(banButton);
|
|
startBanBtnEventListener(0) // ban user
|
|
}
|
|
|
|
|
|
// Check if the user image element exists
|
|
if (userdata.icon_id === 10 || userdata.iconId === 10) {
|
|
const userImage = document.getElementById('user-image');
|
|
userImage.src = "images/" + ext_id + '-up.jpg';
|
|
} else if (document.currentScript.getAttribute('data-userdata')) {
|
|
const userImage = document.getElementById('user-image');
|
|
const UI_Icon = userdata.icon_id;
|
|
|
|
// Pad the number because game weird
|
|
|
|
// Set the user image source
|
|
userImage.src = "assets/icon/UI_Icon_" + padNumber(Number(UI_Icon), 6) + '.png';
|
|
}
|
|
|
|
// title getting
|
|
const request = new XMLHttpRequest();
|
|
request.open('GET', '/assets/metadata/titleMetadata.json', true);
|
|
|
|
request.onload = function () {
|
|
if (this.status >= 200 && this.status < 400) {
|
|
const data = JSON.parse(this.response);
|
|
const userTitle = document.getElementById('user-title-text');
|
|
var userTitleText = ""
|
|
for (title of data) {
|
|
if (userdata.title_id === title.InGameID) {
|
|
userTitleText = title.name
|
|
break
|
|
}
|
|
continue
|
|
}
|
|
userTitle.textContent = userTitleText
|
|
} else {
|
|
// handle the error
|
|
}
|
|
};
|
|
|
|
request.onerror = function () {
|
|
// handle the error
|
|
};
|
|
|
|
request.send();
|
|
|
|
// User Play Log
|
|
|
|
let scoreIncrement = 0;
|
|
let errorIncrement = 0;
|
|
let displayedScoreCount = 20;
|
|
|
|
/* welcome to hell */
|
|
async function userPlayLogFormatter(div, loadMoreButton) {
|
|
const UserPlayLogData = await UserPlayLog(aime_card_id);
|
|
let scoresWrapperDiv = document.getElementById("scoreWrapper");
|
|
document.getElementById('RawUserPlayLog').innerHTML = JSON.stringify(UserPlayLogData, null, 2);
|
|
// If the scores wrapper div doesn't exist, create it.
|
|
if (scoresWrapperDiv === null) {
|
|
scoresWrapperDiv = document.createElement('div');
|
|
scoresWrapperDiv.id = "scoreWrapper";
|
|
div.appendChild(scoresWrapperDiv);
|
|
}
|
|
|
|
const startIndex = scoresWrapperDiv.children.length;
|
|
if (startIndex > 0) {
|
|
// If the scores wrapper div already has children, don't do anything.
|
|
return;
|
|
}
|
|
|
|
// Get the user's play log data and music IDs.
|
|
console.log(UserPlayLogData)
|
|
const musicIds = UserPlayLogData.map(score => score.music_id);
|
|
const musicData = await musicMetadata();
|
|
|
|
let errorIncrement = 0;
|
|
let scoreIncrement = 0;
|
|
for (let i = UserPlayLogData.length - 1; i >= 0; i--) {
|
|
const scoreDiv = document.createElement('div'); // Create a Div
|
|
let score = JSON.parse(JSON.stringify(UserPlayLogData[i])); // get score data
|
|
let song = await getReleventInformation(musicData, score.music_id || score.musicId) // get song data
|
|
if (song === null) {
|
|
continue
|
|
}
|
|
let diffucultyData = song.difficultys.Notes[score.level] // get difficulty information
|
|
|
|
if (!song || !song.name) { // if a song can't be found, skip it and increment the error counter by 1.
|
|
console.log(song)
|
|
console.log(score.music_id || score.musicId)
|
|
console.log("Song or title is undefined");
|
|
errorIncrement++
|
|
continue;
|
|
}
|
|
console.log(song)
|
|
|
|
scoreDiv.innerHTML = `
|
|
<div class="score-title">
|
|
<h4>${song.name.str} || ${new Date(score.user_play_date||score.userPlayDate)}</h4>
|
|
</div>
|
|
`;
|
|
/* Score Jacket Image */
|
|
const scoreJacketDiv = document.createElement('div');
|
|
let jacket = document.createElement('img');
|
|
jacket.addEventListener("error", function () {
|
|
this.src = "assets/icon/UI_Icon_000000.png";
|
|
});
|
|
scoreJacketDiv.classList.add('score-jacket');
|
|
jacket.classList.add('score-jacket');
|
|
jacket.src = "assets/jacket/UI_Jacket_" + padNumber(Number(song.InGameID), 6) + '.png';
|
|
scoreJacketDiv.append(jacket)
|
|
scoreDiv.append(scoreJacketDiv)
|
|
|
|
/* Achivement Box */
|
|
const scoreAchivementDiv = document.createElement('div');
|
|
scoreAchivementDiv.classList.add('score-achivement');
|
|
scoreAchivementDiv.innerHTML = `<h4>ACHIVEMENT</h5>`;
|
|
let achivementPercentage = document.createElement('h5');
|
|
let achivementNumber = padNumber(Number(score.achievement), 7)
|
|
achivementPercentage.textContent = `${achivementNumber / 10000}%`;
|
|
scoreAchivementDiv.append(achivementPercentage)
|
|
scoreDiv.append(scoreAchivementDiv)
|
|
|
|
/* Score Grade */
|
|
let scoreGrades = ["D", "C", "B", "BB", "BBB", "A", "AA", "AAA", "S", "S+", "SS", "SS+", "SSS", "SSS+"]
|
|
const scoreGradeDiv = document.createElement('div');
|
|
scoreGradeDiv.classList.add('score-grade');
|
|
let scoreGrade = document.createElement('h4');
|
|
scoreGrade.textContent = `${scoreGrades[score.score_rank||score.scoreRank]}`;
|
|
scoreGradeDiv.append(scoreGrade);
|
|
scoreDiv.append(scoreGradeDiv);
|
|
|
|
/* DX Score, Full Combo, Full Sync, and Multi-Placement */
|
|
|
|
const scoreInfoDiv = document.createElement('div');
|
|
scoreInfoDiv.classList.add('score-info');
|
|
const scoreInfoGridDiv = document.createElement('div');
|
|
scoreInfoDiv.classList.add('score-info-grid');
|
|
// please i dont want to make a fucking nested grid
|
|
/* DX Score */
|
|
const scoreDXScoreDiv = document.createElement('div');
|
|
scoreDXScoreDiv.classList.add('DX-Score');
|
|
scoreDXScoreDiv.innerHTML = `<h6>DX Score: ${score.deluxscore}/${diffucultyData.maxNotes * 3}</h6>`;
|
|
scoreInfoGridDiv.append(scoreDXScoreDiv);
|
|
scoreInfoDiv.append(scoreInfoGridDiv);
|
|
scoreDiv.append(scoreInfoDiv);
|
|
/* Full Combo */
|
|
/* Full Sync */
|
|
/* Player Placement */
|
|
|
|
/* Side note: Can't Do Any of this without the Image Assets / Information, So Moving on for now */
|
|
/* setting stuff up */
|
|
scoreDiv.setAttribute("class", "score-grid");
|
|
scoreIncrement++
|
|
|
|
scoresWrapperDiv.appendChild(scoreDiv);
|
|
}
|
|
|
|
|
|
|
|
// Edit the Score Info Header with the relevant information.
|
|
const header = document.querySelector('#score-info-header');
|
|
header.textContent = `Showing ${startIndex + scoreIncrement - errorIncrement} out of ${scoreIncrement} scores.`;
|
|
if (errorIncrement > 0) {
|
|
header.insertAdjacentHTML('afterend', `<p>${errorIncrement} Songs Failed to load properly, most likely due to missing information.</p>`);
|
|
}
|
|
|
|
// If there are no more scores to load, hide the "Load More" button.
|
|
}
|
|
|
|
/* User Area Status Renderer */
|
|
|
|
async function userAreaStatusFormatter(div) {
|
|
const UserAreaData = await userAreaInfomation(aime_card_id);
|
|
document.getElementById('RawUserArea').innerHTML = JSON.stringify(UserAreaData, null, 2);
|
|
const mapMetadata = await mapsMetadata()
|
|
let areaWrapper = document.createElement('div'); // create the Wrapper Div
|
|
for (let i = UserAreaData.length - 1; i >= 0; i--) {
|
|
const area = UserAreaData[i]; // get the area
|
|
const mapInfo = await getReleventInformationMap(mapMetadata, area.map_id||area.mapId); // get the relevent Map Information
|
|
console.log(mapInfo)
|
|
if(!mapInfo) continue // continue if mapInfo cant be found for a map
|
|
const areaGrid = document.createElement('div'); // create the Grid for the area inforrmation to go
|
|
areaGrid.classList.add('areaGrid'); // add the appropriate class
|
|
/* Area Title */
|
|
let areaTitle = document.createElement('div');
|
|
areaTitle.classList.add('areaTitle');
|
|
areaTitle.innerHTML = `<h4>${mapInfo.name}</h4>`
|
|
areaGrid.append(areaTitle)
|
|
/* Kilometers */
|
|
let areaKilometers = document.createElement('div');
|
|
areaKilometers.classList.add('areaKilometers');
|
|
areaKilometers.innerHTML = `${area.distance} KM Traveled!`;
|
|
if (area.is_complete === 1) { // If the Area is complete, denote that in the areaKilometers.
|
|
areaKilometers.innerHTML = areaKilometers.innerHTML + ` Area Complete!`;
|
|
} else { // else check if unlock rewards exist, and then calculate the diffrence between the next reward and the current distance traveled.
|
|
if (mapInfo.mapInfomation.unlockRewards !== undefined) {
|
|
for (unlock of mapInfo.mapInfomation.unlockRewards) {
|
|
if (area.distance > unlock.Distance) {
|
|
continue
|
|
} else if (area.distance !== 0) {
|
|
let diffrence = unlock.Distance - area.distance
|
|
if (diffrence === 0) {
|
|
console.log(unlock)
|
|
areaKilometers.innerHTML = areaKilometers.innerHTML + ` Task Track!<br>Clear ${unlock.TreasureId.str} to continue!`;
|
|
} else {
|
|
areaKilometers.innerHTML = areaKilometers.innerHTML + ` ${diffrence} KM until Next Reward.`;
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
areaGrid.append(areaKilometers)
|
|
// Append to AreaGrid
|
|
areaWrapper.append(areaGrid);
|
|
/* Details Button */
|
|
let areaDetails = document.createElement('div');
|
|
areaDetails.classList.add('areaDetails');
|
|
let areaDetailsButton = document.createElement('button');
|
|
areaDetailsButton.appendChild(document.createTextNode("Details"));
|
|
areaDetails.append(areaDetailsButton)
|
|
areaGrid.append(areaDetails)
|
|
}
|
|
// Place everything done here Inside the parent Div
|
|
div.appendChild(areaWrapper)
|
|
}
|
|
|
|
/* Memorial Image Renderer */
|
|
async function userImageFormatter(div) {
|
|
let memorialImageList = await imageList(); // get image list
|
|
let imageInfoDiv = document.getElementById("image-info-header-div");
|
|
imageInfoDiv.innerHTML = "";
|
|
console.log("Attempting to search list with EXT_ID " + ext_id.toString())
|
|
for (var i = 0; i < memorialImageList.length; i++) { // for each name in the array
|
|
let imageName = memorialImageList[i]
|
|
console.log(imageName)
|
|
if (imageName.startsWith(ext_id.toString())) { // Check if the External ID matches the ID within the photo at the beginning
|
|
let memorialImage = document.createElement('img');
|
|
memorialImage.classList.add('memorialImage');
|
|
memorialImage.addEventListener("error", function () {
|
|
this.src = "assets/icon/UI_Icon_000000.png";
|
|
});
|
|
if(window.serverType === 0) {
|
|
memorialImage.src = "images/" + imageName + '.jpg';
|
|
} else {
|
|
memorialImage.src = "images/" + imageName + '.jpeg';
|
|
}
|
|
imageInfoDiv.append(memorialImage)
|
|
}
|
|
}
|
|
if(imageInfoDiv.innerHTML == "") {
|
|
let error = document.createElement('h3');
|
|
error.innerText = "No Images Memorialised."
|
|
imageInfoDiv.append(error)
|
|
}
|
|
}
|
|
|
|
//=====================================================================
|
|
// Now Exiting: User Data ////////////// Now Entering: Nested Div Hell
|
|
//=====================================================================
|
|
|
|
const showContent = (contentNumber) => {
|
|
// Select the content div with the data-content attribute equal to the contentNumber
|
|
const contentDiv = document.querySelector(`[data-content="content-${contentNumber}"]`);
|
|
|
|
// Hide all content divs except the selected one
|
|
const contentDivs = document.querySelectorAll('[data-content]');
|
|
contentDivs.forEach((div) => {
|
|
if (div === contentDiv) {
|
|
if (contentNumber === 2) { // If the ContentNumber is set to the PlayLog, Go to the userPlayLogFormatter Function
|
|
userPlayLogFormatter(div)
|
|
} else if (contentNumber === 4) {
|
|
userImageFormatter(div)
|
|
} else if (contentNumber === 6) {
|
|
userAreaStatusFormatter(div)
|
|
}
|
|
div.classList.remove('hidden');
|
|
} else {
|
|
div.classList.add('hidden');
|
|
}
|
|
});
|
|
};
|
|
|
|
//=====================================================================
|
|
// Now Exiting: Nested Div Hell ///////////// Now Entering: Fetch Land
|
|
//=====================================================================
|
|
|
|
function UserPlayLog(aime_card_id) {
|
|
const input = aime_card_id;
|
|
const url = "/api/getUserScores/";
|
|
|
|
// Return the fetch promise so that it can be handled within userPlayLogFormatter
|
|
return fetch(url, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
body: JSON.stringify({
|
|
input: input
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => data.data)
|
|
.catch(error => console.error(error));
|
|
}
|
|
|
|
function getuserbanned(aime_card_id) {
|
|
const input = aime_card_id;
|
|
const url = "/api/getuserbanned/";
|
|
|
|
// Return the fetch promise so that it can be handled within userPlayLogFormatter
|
|
return fetch(url, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
body: JSON.stringify({
|
|
input: input
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => window.location.reload())
|
|
.catch(error => console.error(error));
|
|
}
|
|
|
|
function getuserunbanned(aime_card_id) {
|
|
const input = aime_card_id;
|
|
const url = "/api/getuserunbanned/";
|
|
|
|
// Return the fetch promise so that it can be handled within userPlayLogFormatter
|
|
return fetch(url, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
body: JSON.stringify({
|
|
input: input
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => window.location.reload())
|
|
.catch(error => console.error(error));
|
|
}
|
|
|
|
function userAreaInfomation(aime_card_id) {
|
|
const input = aime_card_id;
|
|
const url = "/api/getUserArea/";
|
|
|
|
// Return the fetch promise so that it can be handled within userPlayLogFormatter
|
|
return fetch(url, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
body: JSON.stringify({
|
|
input: input
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => data.data)
|
|
.catch(error => console.error(error));
|
|
}
|
|
|
|
async function musicMetadata() {
|
|
const url = "/assets/metadata/musicMetadata.json";
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
const mapping = {};
|
|
data.forEach((song) => {
|
|
mapping[song.name.id] = song;
|
|
});
|
|
|
|
return mapping;
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
}
|
|
|
|
async function mapsMetadata() {
|
|
const url = "/assets/metadata/mapMetadata.json";
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
}
|
|
|
|
async function imageList() {
|
|
const url = "/api/getmemorialimagelist";
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
|
|
const data = await response.json();
|
|
return data
|
|
} catch (error) {
|
|
console.error(error);
|
|
}
|
|
}
|
|
|