mirror of
https://dev.s-ul.net/Galexion/MaiMaiDXNet.git
synced 2024-11-24 02:40:11 +01:00
Play Log Partically Complete 1 / 3
This commit is contained in:
parent
93a9e0ee64
commit
29ffa2adf1
@ -30,7 +30,7 @@ const cookieString = document.cookie;
|
||||
|
||||
// Parse the cookie string and extract the values
|
||||
const cookies = cookieString.split(';');
|
||||
let ext_id, luid;
|
||||
let ext_id, luid, aime_card_id;
|
||||
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookie = cookies[i].trim();
|
||||
@ -43,6 +43,10 @@ for (let i = 0; i < cookies.length; i++) {
|
||||
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.
|
||||
@ -55,8 +59,49 @@ if (ext_id && luid) {
|
||||
}
|
||||
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 getSongInformation(id) {
|
||||
const musicData = await musicMetadata();
|
||||
const songMatch = musicData[id];
|
||||
if (!songMatch) {
|
||||
return null;
|
||||
}
|
||||
return songMatch;
|
||||
}
|
||||
|
||||
|
||||
// Ban Check lmao
|
||||
|
||||
if (userdata.ban_state !== 0) {
|
||||
//nice
|
||||
const parent = document.getElementById("User");
|
||||
const wrapperDiv = document.createElement("div");
|
||||
wrapperDiv.id = 'wrapper';
|
||||
const newDiv = document.createElement("div");
|
||||
newDiv.classList.add('error')
|
||||
newDiv.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 newDiv.innerHTML = "<p>This is some HTML content</p>;
|
||||
parent.insertBefore(wrapperDiv, parent.firstChild);
|
||||
wrapperDiv.appendChild(newDiv);
|
||||
}
|
||||
|
||||
|
||||
// Check if the user image element exists
|
||||
if(userdata.icon_id === 10) {
|
||||
if (userdata.icon_id === 10) {
|
||||
const userImage = document.getElementById('user-image');
|
||||
userImage.src = "images/" + ext_id + '-up.jpg';
|
||||
} else if (document.currentScript.getAttribute('data-userdata')) {
|
||||
@ -64,13 +109,6 @@ if(userdata.icon_id === 10) {
|
||||
const UI_Icon = userdata.icon_id;
|
||||
|
||||
// Pad the number because game weird
|
||||
function padNumber(num, size) {
|
||||
let s = num + "";
|
||||
while (s.length < size) {
|
||||
s = "0" + s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
// Set the user image source
|
||||
userImage.src = "assets/icon/UI_Icon_" + padNumber(Number(UI_Icon), 6) + '.png';
|
||||
@ -80,26 +118,147 @@ if(userdata.icon_id === 10) {
|
||||
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.titleId) {
|
||||
userTitleText = title.name
|
||||
break
|
||||
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.titleId) {
|
||||
userTitleText = title.name
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
continue
|
||||
userTitle.textContent = userTitleText
|
||||
} else {
|
||||
// handle the error
|
||||
}
|
||||
userTitle.textContent = userTitleText
|
||||
} else {
|
||||
// handle the error
|
||||
}
|
||||
};
|
||||
|
||||
request.onerror = function() {
|
||||
// handle the error
|
||||
request.onerror = function () {
|
||||
// handle the error
|
||||
};
|
||||
|
||||
request.send();
|
||||
|
||||
// User Play Log
|
||||
|
||||
async function userPlayLogFormatter(div) {
|
||||
const UserPlayLogData = await UserPlayLog(aime_card_id);
|
||||
const musicIds = UserPlayLogData.map(score => score.music_id);
|
||||
const songs = await Promise.all(musicIds.map(getSongInformation));
|
||||
|
||||
let myDiv = document.getElementById("scoreWrapper");
|
||||
if (myDiv === null) {
|
||||
const scoresWrapperDiv = document.createElement('div');
|
||||
scoresWrapperDiv.id = "scoreWrapper";
|
||||
|
||||
for (let i = UserPlayLogData.length - 1; i >= 0; i--) {
|
||||
const newDiv = document.createElement('div');
|
||||
let score = JSON.parse(JSON.stringify(UserPlayLogData[i]));
|
||||
let song = JSON.parse(JSON.stringify(songs[i]));
|
||||
|
||||
if (!song || !song.name) {
|
||||
console.log(song)
|
||||
console.log(score.music_id)
|
||||
console.log("Song or title is undefined");
|
||||
continue;
|
||||
}
|
||||
|
||||
newDiv.innerHTML = `
|
||||
<h4>${song.name.str || ""} || </h4>
|
||||
`;
|
||||
|
||||
let jacket = document.createElement('img');
|
||||
jacket.addEventListener("error", function () {
|
||||
this.src = "assets/icon/UI_Icon_000000.png";
|
||||
});
|
||||
jacket.classList.add('score-jacket');
|
||||
jacket.src = "assets/jacket/UI_Jacket_" + padNumber(Number(score.music_id), 6) + '.png';
|
||||
newDiv.append(jacket)
|
||||
|
||||
newDiv.setAttribute("id", "score-grid");
|
||||
newDiv.setAttribute("class", "item");
|
||||
|
||||
scoresWrapperDiv.appendChild(newDiv);
|
||||
}
|
||||
|
||||
div.appendChild(scoresWrapperDiv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// 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)
|
||||
}
|
||||
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: aime_card_id
|
||||
})
|
||||
})
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -28,22 +28,24 @@
|
||||
"profile-image user-class awakens";
|
||||
gap: 10px;
|
||||
border: 2px solid black;
|
||||
border-radius: 10px;
|
||||
border-radius: 15px;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
width: fit-content;
|
||||
margin: 0 auto;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
#user-profile-wrapper {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
border: 2px solid black;
|
||||
border-radius: 10px;
|
||||
border-radius: 15px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5em;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +75,7 @@
|
||||
grid-area: awakens;
|
||||
}
|
||||
|
||||
h4 {
|
||||
h4.profile {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
@ -83,8 +85,110 @@ h4 {
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
.error {
|
||||
display: inline-block;
|
||||
margin: 1em;
|
||||
border: 2px dashed red;
|
||||
border-radius: 10px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
margin-bottom: 2em;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"1a 2b 3c 4d"
|
||||
"5e 6f 7g 8h";
|
||||
grid-gap: 10px;
|
||||
}
|
||||
|
||||
.btn1 {
|
||||
grid-area: "1a";
|
||||
}
|
||||
|
||||
.btn2 {
|
||||
grid-area: "2b";
|
||||
}
|
||||
|
||||
.btn3 {
|
||||
grid-area: "3c";
|
||||
}
|
||||
|
||||
.btn4 {
|
||||
grid-area: "4d";
|
||||
}
|
||||
|
||||
.btn5 {
|
||||
grid-area: "5e";
|
||||
}
|
||||
|
||||
.btn6 {
|
||||
grid-area: "6f";
|
||||
}
|
||||
|
||||
.btn7 {
|
||||
grid-area: "7g";
|
||||
}
|
||||
|
||||
.btn8 {
|
||||
grid-area: "8h";
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
/* Jacket Grid */
|
||||
|
||||
.score-grid {
|
||||
display: grid;
|
||||
|
||||
grid-template-rows: 1fr 1fr 1fr;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
|
||||
grid-template-areas:
|
||||
'label0 label0 label0 label0'
|
||||
'label1 label1 label2 label3'
|
||||
'label1 label1 label4 label4';
|
||||
|
||||
gap: 0px;
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
|
||||
.score-title {
|
||||
|
||||
background-color: #D5BBCA;
|
||||
grid-area: label0;
|
||||
|
||||
}
|
||||
.score-jacket {
|
||||
|
||||
background-color: #9EF6B5;
|
||||
grid-area: label1;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 25%;
|
||||
width: 25%;
|
||||
|
||||
}
|
||||
.score-achivement {
|
||||
|
||||
background-color: #ED69FD;
|
||||
grid-area: label2;
|
||||
|
||||
}
|
||||
.score-grade {
|
||||
|
||||
background-color: #9B5999;
|
||||
grid-area: label3;
|
||||
|
||||
}
|
||||
.score-info {
|
||||
|
||||
background-color: #58B669;
|
||||
grid-area: label4;
|
||||
|
||||
}
|
@ -37,6 +37,10 @@ Create a `config.json` file and paste this in, with paths to your instance.
|
||||
|
||||
ToDo:
|
||||
- Create Play Data Tab
|
||||
- Get User Playlog Data (Done)
|
||||
- Sort From Most Recent (Done)
|
||||
- Assign Song Names to Each Score (done)
|
||||
- Create Detailed Look Into Score
|
||||
- Create Photos Tab
|
||||
- Create Area Tab
|
||||
- Create Collection Tab
|
||||
@ -46,5 +50,5 @@ ToDo:
|
||||
|
||||
Complete:
|
||||
- Sign In Page
|
||||
- Make User Profile on User Page (almost done)
|
||||
- Make User Profile on User Page (done)
|
||||
- Fuck you css go kill yourself
|
@ -49,6 +49,26 @@ let db = new sqlite3.Database('A:\\db.sqlite');
|
||||
});
|
||||
})
|
||||
|
||||
router.post('/getUserScores/', function (req,res,next) {
|
||||
db.all('SELECT * FROM maimai2_user_playlog', (err, rows) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
// Return a Failed Message.
|
||||
res.status(500).json({ error: err.message, status: "Failed" });
|
||||
} else {
|
||||
// Make the Request easier to get to.
|
||||
var request = req.body;
|
||||
var mUser = new Array(); // Leave the Matched User's Scores undefined until the user is found.
|
||||
for (score of rows) { // For Each Score in Rows
|
||||
if (request.input == score.user_id) { // If the inputed User ID and Score's User ID Matches,
|
||||
mUser.push(score) // add that score into the array.
|
||||
}
|
||||
}
|
||||
// Return a Response with all the Scores listed under that user.
|
||||
res.status(200).json({ data: mUser, status: "Complete" });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
module.exports = router;
|
@ -35,6 +35,10 @@ router.get('/user', async function (req, res, next) {
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/error/test/db', function (req,res,next) {
|
||||
res.render('error', { error: "Error: SQLITE_BUSY: database is locked"})
|
||||
})
|
||||
|
||||
async function getUserData(req) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const cookies = req.cookies
|
||||
|
@ -1,6 +1,33 @@
|
||||
<% var rootPath='../' ; %>
|
||||
<%- include(rootPath + 'templates/header.ejs' ); %>
|
||||
<h1>Fuck. Something Went Wrong or you got 404'd.</h1>
|
||||
<%=error%>
|
||||
</body>
|
||||
<div class="wrapper">
|
||||
<div class="error">
|
||||
<% if(error == "Error: SQLITE_BUSY: database is locked") {
|
||||
%>
|
||||
<h1 style="word-wrap: break-word; max-width:800px;">It appears that the database is currently unavailable. Please try again later.</h1>
|
||||
<p style="word-wrap: break-word; max-width:800px;">If you accidentally disconnect from the server, this error typically resolves itself. However, if you continue to encounter the error, try restarting the server. If you're playing on a Private Server with other users, you should ask a Network Admin to restart it for you.</p>
|
||||
<%} else {%>
|
||||
|
||||
<h1>Fuck. Something Went Wrong or you got 404'd.</h1>
|
||||
<%}%>
|
||||
<%=error%>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.error {
|
||||
display: inline-block;
|
||||
margin: 1em;
|
||||
border: 2px dashed red;
|
||||
border-radius: 10px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -5,24 +5,44 @@
|
||||
<link href="/stylesheets/user.css" rel="stylesheet" type="text/css">
|
||||
<div id="User">
|
||||
<h1>Yo! Welcome Back <%= normalizeText(userdata.user_name) %>!</h1>
|
||||
|
||||
<div id="wrapper">
|
||||
<div id="user-profile-wrapper">
|
||||
<div class="profile-image"><img id="user-image" src="" alt="User Image" onerror="this.src='assets/icon/UI_Icon_000000.png'"></div>
|
||||
<div class="user-title">
|
||||
<h4 id="user-title-text"></h4>
|
||||
</div>
|
||||
<div class="user-name">
|
||||
<h4><%= normalizeText(userdata.user_name) %></h4>
|
||||
</div>
|
||||
<div class="dx-rating">
|
||||
<h4><%= userdata.music_rating%></h4>
|
||||
</div>
|
||||
<div class="user-class"></div>
|
||||
<div class="awakens">
|
||||
<h4>★ ☓<%= userdata.total_awake%></h4>
|
||||
<!-- Calm before the storm -->
|
||||
<div class="buttons">
|
||||
<button class="btn1" onclick="showContent(1)">Home</button>
|
||||
<button class="btn2" onclick="showContent(2)">Play Data</button>
|
||||
<button class="btn3" onclick="showContent(3)">Friends</button>
|
||||
<button class="btn4" onclick="showContent(4)">Photos</button>
|
||||
<button class="btn5" onclick="showContent(5)">Records</button>
|
||||
<button class="btn6" onclick="showContent(6)">Area</button>
|
||||
<button class="btn7" onclick="showContent(7)">Collection</button>
|
||||
<button class="btn8" onclick="showContent(8)">Ranking</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="wrapper">
|
||||
<div data-content="content-1" id="user-profile-wrapper">
|
||||
<div class="profile-image"><img id="user-image" src="" alt="User Image" onerror="this.src='assets/icon/UI_Icon_000000.png'"></div>
|
||||
<div class="user-title">
|
||||
<h4 id="user-title-text"></h4>
|
||||
</div>
|
||||
<div class="user-name">
|
||||
<h4><%= normalizeText(userdata.user_name) %></h4>
|
||||
</div>
|
||||
<div class="dx-rating">
|
||||
<h4><%= userdata.music_rating%></h4>
|
||||
</div>
|
||||
<div class="user-class"></div>
|
||||
<div class="awakens">
|
||||
<h4>★ ☓<%= userdata.total_awake%></h4>
|
||||
</div>
|
||||
</div><!-- This is just one nested div, Trmazi it's going to get a lot worse from here on. -->
|
||||
<div data-content="content-2" id="user-play-data" class="hidden"> <!-- User Play-Log is generated at run time when the user clicks the button, so they get up to date data. -->
|
||||
<h4>Please Wait, Obtaining Scores...</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Developer Only Information</summary>
|
||||
For Development purposes only, send statistics found in this menu when encontering UI
|
||||
|
Loading…
Reference in New Issue
Block a user