1
0
mirror of https://dev.s-ul.net/Galexion/MaiMaiDXNet.git synced 2024-11-27 22:20:48 +01:00

Merge branch 'artemisdevsupport' into 'master'

Artemis Support

See merge request Galexion/MaiMaiDXNet!1
This commit is contained in:
Galexion 2023-07-17 03:03:03 +00:00
commit 319ae958cc
12 changed files with 735 additions and 289 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@ config.json
public/images
public/assets
node_modules
todo

306
dbhandler.js Normal file
View File

@ -0,0 +1,306 @@
const { serverType, ArtConnSettings, DXMemorialImageDirectory } = require('./config.json');
const sqlite3 = require('sqlite3').verbose();
var db = undefined;
if (serverType === 0) {
db = new sqlite3.Database(DXMemorialImageDirectory + '\\db.sqlite');
}
const mysql = require('mysql');
var con = mysql.createConnection(ArtConnSettings)
if (serverType === 1) {
con.connect((err) => {
if (err) {
console.error('Error connecting to MySQL database:', err);
process.exit()
return;
}
console.log('Connected to MySQL database.');
});
}
// index.js route '/'
async function getUserCount() {
if (serverType === 0) {
return new Promise((resolve, reject) => {
db.all('SELECT * FROM sega_card', (err, rows) => {
if (err) {
console.error(err);
res.render('error', { error: err });
reject(err)
} else {
resolve(rows.length)
}
});
});
} else {
return new Promise((resolve, reject) => {
con.query("SELECT * FROM aime.mai2_profile_detail", function (err, result, fields) {
if (err) {
reject(err)
throw err
};
resolve(JSON.parse(JSON.stringify(result)).length);
});
});
}
}
// index.js & api.js /getUserData/
async function getUserData(req) {
if (serverType === 0) {
return new Promise((resolve, reject) => {
const cookies = req.cookies
db.all('SELECT * FROM maimai2_user_detail', (err, rows) => {
if (err) {
console.error(err);
// Return a Failed Message.
reject(err)
} else {
// Make the Request easier to get to.
var mUser = undefined // Leave the Matched User undefined until the user is found.
for (user of rows) { // For Each User in Rows
if (cookies.aime_card_id === user.aime_card_id.toString()) { // If the Access Code for the card is in the system,
mUser = user; // set the Matched User Variable to the User, and break the for Loop.
break;
}
}
if (mUser) {
// Return a Response with the whole identifiable user data. the EXT_ID will be used later to identify images and other things and match them to the user's profile.
resolve(mUser);
} else {
reject(new Error('User not found'));
}
}
});
}); // function is required to obtain the User Data, and create the user profile. I'm going to bed.
} else { // 07-23 oh god im going to have to recreate this function again aren't i
return new Promise((resolve, reject) => {
con.query("SELECT * FROM aime.mai2_profile_detail", function (err, result, fields) {
if (err) {
reject(err)
throw err
};
// Make the Request easier to get to.
const cookies = req.cookies
var mUser = undefined // Leave the Matched User undefined until the user is found.
for (user of result) { // For Each User in Rows
console.log(user.user)
if (cookies.aime_card_id === user.user.toString()) { // If the Access Code for the card is in the system,
mUser = user; // set the Matched User Variable to the User, and break the for Loop.
break;
}
}
if (mUser) {
// Return a Response with the whole identifiable user data. the EXT_ID will be used later to identify images and other things and match them to the user's profile.
resolve(mUser);
} else {
reject(new Error('User not found'));
}
})
});
};
}
// api.js /getExtId/
async function getExtId(req) {
if (serverType === 0) {
return new Promise((resolve, reject) => {
db.all('SELECT * FROM sega_card', (err, rows) => {
if (err) {
console.error(err);
// Return a Failed Message.
reject(err)
} else {
// Make the Request easier to get to.
var request = req.body;
var mUser = undefined // Leave the Matched User undefined until the user is found.
for (user of rows) { // For Each User in Rows
if (request.input === user.luid) { // If the Access Code for the card is in the system,
mUser = user; // set the Matched User Variable to the User, and break the for Loop.
break
}
}
// Return a Response with the whole identifiable user data. the EXT_ID will be used later to identify images and other things and match them to the user's profile.
resolve(mUser)
}
});
});
} else {
return new Promise((resolve, reject) => {
con.query("SELECT * FROM aime.aime_card", function (err, result, fields) {
if (err) {
reject(err)
throw err
};
// Make the Request easier to get to.
var request = req.body;
var mUser = undefined // Leave the Matched User undefined until the user is found.
for (user of result) { // For Each User in Rows
if (request.input === user.access_code) { // If the Access Code for the card is in the system,
mUser = user; // set the Matched User Variable to the User, and break the for Loop.
break;
}
}
if (mUser) {
// Return a Response with the whole identifiable user data. the EXT_ID will be used later to identify images and other things and match them to the user's profile.
resolve(mUser);
} else {
reject(new Error('User not found'));
}
})
});
}
}
// api /getUserScores/
async function getUserScores(req) {
if (serverType === 0) {
return new Promise((resolve, reject) => {
db.all('SELECT * FROM maimai2_user_playlog', (err, rows) => {
if (err) {
console.error(err);
reject(err)
// Return a Failed Message.
} 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.
resolve(mUser)
}
});
});
} else {
return new Promise((resolve, reject) => {
con.query("SELECT * FROM aime.mai2_playlog", function (err, result, fields) {
if (err) {
reject(err)
throw err
};
// Make the Request easier to get to.
const cookies = req.cookies
var mUser = undefined // Leave the Matched User undefined until the user is found.
// 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 result) { // For Each Score in Rows
console.log(request.input)
if (request.input == score.user) { // 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.
resolve(mUser)
})
});
}
}
// api /getUserArea/
async function getUserArea(req) {
if (serverType === 0) {
return new Promise((resolve, reject) => {
db.all('SELECT * FROM maimai2_user_map', (err, rows) => {
if (err) {
console.error(err);
// Return a Failed Message.
reject(err)
} else {
// Make the Request easier to get to.
var request = req.body;
var mUser = new Array(); // Leave the Matched User's Areas undefined until the user is found.
for (map of rows) { // For Each Area in Rows
if (request.input == map.user_id) { // If the inputed User ID and Score's User ID Matches,
mUser.push(map) // add that Area into the array.
}
}
// Return a Response with all the Areas listed under that user.
resolve(mUser)
}
});
});
} else {
return new Promise((resolve, reject) => {
con.query("SELECT * FROM aime.mai2_item_map", function (err, result, fields) {
if (err) {
reject(err)
throw err
};
// Make the Request easier to get to.
const cookies = req.cookies
var mUser = undefined // Leave the Matched User undefined until the user is found.
// 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 result) { // For Each Score in Rows
console.log(request.input)
if (request.input == score.user) { // 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.
resolve(mUser)
})
});
}
}
/* side note: User Banned & User Unbanned should be tied into 1 commnand that toggles it but maybe not, i dont really know */
// api /getUserBanned/
async function getUserBanned(req) {
if (serverType === 0) {
return new Promise((resolve, reject) => {
var request = req.body;
if (request.input === undefined) {
return reject('Failed to update user ban state, insufficent paramaters')
return
}
db.run('UPDATE maimai2_user_detail SET ban_state = ? WHERE id = ?', [2, request.input], function (err) {
if (err) {
console.error(err.message);
reject({ "status": "failure", "message": "Unable to ban user, see reason", "reason": err });
} else {
resolve({ "status": "Success", "message": `User ${request.input} banned.` })
}
});
});
} else {
}
}
// api /getUserUnbanned/
async function getUserUnbanned(req) {
if (serverType === 0) {
return new Promise((resolve, reject) => {
var request = req.body;
if (request.input === undefined) {
return reject('Failed to update user ban state, insufficent paramaters')
return
}
db.run('UPDATE maimai2_user_detail SET ban_state = ? WHERE id = ?', [0, request.input], function (err) {
if (err) {
console.error(err.message);
reject({ "status": "failure", "message": "Unable to ban user, see reason", "reason": err });
} else {
resolve({ "status": "Success", "message": `User ${request.input} banned.` })
}
});
});
} else {
}
}
module.exports = { getUserCount, getUserData, getUserScores, getUserArea, getUserBanned, getUserUnbanned, getExtId };

View File

@ -9,11 +9,12 @@ var indexRouter = require('./routes/index');
var apiRouter = require('./routes/api');
var config = require("./config.json");
const watcher = chokidar.watch(config.DXMemorialImageDirectory, {
if (config.serverType === 0) { // Only run the image Importer when Aqua is active
const watcher = chokidar.watch(config.DXMemorialImageDirectory, {
persistent: true
});
watcher
watcher
.on('add', (filePath) => {
const isImage = /\.(jpe?g|png|gif)$/i.test(filePath);
if (isImage) {
@ -33,16 +34,15 @@ watcher
.on('error', (error) => {
console.error(`Watcher error: ${error}`);
});
}
// readFileSync function must use __dirname get current directory
// readFileSync function must use __dirname get current directory
// require use ./ refer to current directory.
const options = {
};
const options = {};
var app = express()
// Create HTTPs server.
// Create HTTPs server.
//var httpsServer = https.createServer(options, app);
@ -55,19 +55,19 @@ app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.json({ extended: false }));
// define routes
app.use('/', indexRouter);
app.use('/api/', apiRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
app.use(function (req, res, next) {
next(createError(404));
});
var PORT = process.env.PORT || 8000
// error handler
app.use(function(err, req, res, next) {
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
@ -77,6 +77,6 @@ app.use(function(err, req, res, next) {
res.render('error');
});
app.listen(PORT, () => console.log(`Server is running in port ${PORT}`));
app.listen(PORT, () => console.log(`Server is running in port ${PORT}, Server type ${config.serverType}`));
module.exports = app;

174
package-lock.json generated
View File

@ -17,6 +17,7 @@
"fs": "^0.0.1-security",
"http-errors": "^2.0.0",
"morgan": "^1.10.0",
"mysql": "^2.18.1",
"path": "^0.12.7",
"sqlite3": "^5.1.4"
}
@ -269,6 +270,14 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/bignumber.js": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
"integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
"engines": {
"node": "*"
}
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -505,6 +514,11 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"node_modules/cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
@ -1114,6 +1128,11 @@
"node": ">=0.12.0"
}
},
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -1163,9 +1182,9 @@
}
},
"node_modules/make-dir/node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"bin": {
"semver": "bin/semver.js"
}
@ -1389,6 +1408,47 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/mysql": {
"version": "2.18.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
"integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
"dependencies": {
"bignumber.js": "9.0.0",
"readable-stream": "2.3.7",
"safe-buffer": "5.1.2",
"sqlstring": "2.3.1"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mysql/node_modules/readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/mysql/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/mysql/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@ -1632,6 +1692,11 @@
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"node_modules/promise-inflight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@ -1771,9 +1836,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dependencies": {
"lru-cache": "^6.0.0"
},
@ -1916,9 +1981,9 @@
"optional": true
},
"node_modules/sqlite3": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.4.tgz",
"integrity": "sha512-i0UlWAzPlzX3B5XP2cYuhWQJsTtlMD6obOa1PgeEQ4DHEXUuyJkgv50I3isqZAP5oFc2T8OFvakmDh2W6I+YpA==",
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz",
"integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==",
"hasInstallScript": true,
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.0",
@ -1937,6 +2002,14 @@
}
}
},
"node_modules/sqlstring": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
"integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ssri": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
@ -2359,6 +2432,11 @@
}
}
},
"bignumber.js": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
"integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -2535,6 +2613,11 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
@ -3018,6 +3101,11 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -3052,9 +3140,9 @@
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
@ -3220,6 +3308,46 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"mysql": {
"version": "2.18.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
"integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
"requires": {
"bignumber.js": "9.0.0",
"readable-stream": "2.3.7",
"safe-buffer": "5.1.2",
"sqlstring": "2.3.1"
},
"dependencies": {
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@ -3394,6 +3522,11 @@
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"promise-inflight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@ -3486,9 +3619,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"requires": {
"lru-cache": "^6.0.0"
}
@ -3601,9 +3734,9 @@
}
},
"sqlite3": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.4.tgz",
"integrity": "sha512-i0UlWAzPlzX3B5XP2cYuhWQJsTtlMD6obOa1PgeEQ4DHEXUuyJkgv50I3isqZAP5oFc2T8OFvakmDh2W6I+YpA==",
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz",
"integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==",
"requires": {
"@mapbox/node-pre-gyp": "^1.0.0",
"node-addon-api": "^4.2.0",
@ -3611,6 +3744,11 @@
"tar": "^6.1.11"
}
},
"sqlstring": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
"integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ=="
},
"ssri": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",

View File

@ -17,6 +17,7 @@
"fs": "^0.0.1-security",
"http-errors": "^2.0.0",
"morgan": "^1.10.0",
"mysql": "^2.18.1",
"path": "^0.12.7",
"sqlite3": "^5.1.4"
}

View File

@ -1,12 +1,12 @@
// Get the cookie string
const cookieString = document.cookie;
// Get the cookie string
const cookieString = document.cookie;
// Parse the cookie string and extract the values
const cookies = cookieString.split(';');
let ext_id, luid;
// Parse the cookie string and extract the values
const cookies = cookieString.split(';');
let ext_id, luid;
for (let i = 0; i < cookies.length; i++) {
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
const cookieParts = cookie.split('=');
@ -17,19 +17,19 @@
if (cookieParts[0] === 'luid') {
luid = cookieParts[1];
}
}
}
// Sends user to User Page if already signed in
if (ext_id && luid) {
// Sends user to User Page if already signed in
if (ext_id && luid) {
console.log(`User Data Detected, sending to user page.`);
window.location = "/user";
} else {
} else {
console.log('User Data Not Detected! Please Sign In.');
}
}
const form = document.getElementById("myForm");
form.addEventListener("submit", function(event) {
const form = document.getElementById("myForm");
form.addEventListener("submit", function (event) {
event.preventDefault(); // Prevent the default form submission behavior
const input = document.getElementsByName("myInput")[0].value;
@ -48,24 +48,27 @@
.then(response => response.json())
.then(data => {
console.log(data)
let releventData = {
luid: data.data.luid,
luid: data.data.luid || data.data.access_code,
ext_id: data.data.ext_id
}
console.log(releventData)
// Set the cookie expiration to 7 days from now
const expirationDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
// Set the ext_id cookie
document.cookie = `ext_id=${data.data.ext_id}; expires=${expirationDate.toUTCString()}`;
document.cookie = `ext_id=${releventData.ext_id}; expires=${expirationDate.toUTCString()}`;
// Set the luid cookie
document.cookie = `luid=${data.data.luid}; expires=${expirationDate.toUTCString()}`;
document.cookie = `luid=${releventData.luid}; expires=${expirationDate.toUTCString()}`;
console.log(data.data.id)
// Set the aime_card_id cookie
if (window.serverType === 0) {
document.cookie = `aime_card_id=${data.data.id.toString()}; expires=${expirationDate.toUTCString()}`;
} else {
document.cookie = `aime_card_id=${data.data.user.toString()}; expires=${expirationDate.toUTCString()}`;
}
// Set the cookie
window.location = "/user";
})
.catch(error => console.error(error));
});
});

View File

@ -104,7 +104,7 @@ async function getReleventInformationMap(mapData, mapid) {
// Ban Check lmao
if (userdata.ban_state !== 0) {
if (userdata.ban_state === 2 ||userdata.banState === 2) {
//nice
const parent = document.getElementById("User");
const wrapperDiv = document.createElement("div");
@ -135,7 +135,7 @@ if (userdata.ban_state !== 0) {
// Check if the user image element exists
if (userdata.icon_id === 10) {
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')) {
@ -201,6 +201,7 @@ async function userPlayLogFormatter(div, loadMoreButton) {
}
// 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();
@ -209,7 +210,7 @@ async function userPlayLogFormatter(div, loadMoreButton) {
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) // get song data
let song = await getReleventInformation(musicData, score.music_id || score.musicId) // get song data
if (song === null) {
continue
}
@ -217,7 +218,7 @@ async function userPlayLogFormatter(div, loadMoreButton) {
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)
console.log(score.music_id || score.musicId)
console.log("Song or title is undefined");
errorIncrement++
continue;
@ -225,7 +226,7 @@ async function userPlayLogFormatter(div, loadMoreButton) {
scoreDiv.innerHTML = `
<div class="score-title">
<h4>${song.name.str} || ${new Date(score.user_play_date)}</h4>
<h4>${song.name.str} || ${new Date(score.user_play_date||score.userPlayDate)}</h4>
</div>
`;
/* Score Jacket Image */
@ -236,7 +237,7 @@ async function userPlayLogFormatter(div, loadMoreButton) {
});
scoreJacketDiv.classList.add('score-jacket');
jacket.classList.add('score-jacket');
jacket.src = "assets/jacket/UI_Jacket_" + padNumber(Number(score.music_id), 6) + '.png';
jacket.src = "assets/jacket/UI_Jacket_" + padNumber(Number(score.music_id||score.musicId), 6) + '.png';
scoreJacketDiv.append(jacket)
scoreDiv.append(scoreJacketDiv)
@ -255,7 +256,7 @@ async function userPlayLogFormatter(div, loadMoreButton) {
const scoreGradeDiv = document.createElement('div');
scoreGradeDiv.classList.add('score-grade');
let scoreGrade = document.createElement('h4');
scoreGrade.textContent = `${scoreGrades[score.score_rank]}`;
scoreGrade.textContent = `${scoreGrades[score.score_rank||score.scoreRank]}`;
scoreGradeDiv.append(scoreGrade);
scoreDiv.append(scoreGradeDiv);
@ -295,9 +296,6 @@ async function userPlayLogFormatter(div, loadMoreButton) {
}
// If there are no more scores to load, hide the "Load More" button.
if (startIndex + scoreIncrement >= UserPlayLogData.length) {
loadMoreButton.style.display = "none";
}
}
/* User Area Status Renderer */
@ -309,7 +307,7 @@ async function userAreaStatusFormatter(div) {
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); // get the relevent Map Information
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

View File

@ -4,7 +4,13 @@ This is a Open Source MaiMaiDX.Net Interface.
### This Interface Requires a Server Database.
Currently, I only have access to AQUA, but ARTEMiS could be supported once AQUA support is finished.
Artemis & Aqua are Supported, see the `How To Use` Section for more details.
### Features
Functional MaiMaiDX Profile Playlog, Memorial Photo (Aqua Only), and Area Tracker.
Coming Soon: Addable & Viewable Friends Profiles, Song Records, viewable Collections, Server Ranking?
# How to use:
@ -34,11 +40,53 @@ Create a `config.json` file and paste this in, with paths to your instance.
```json
{
"DXMemorialImageDirectory": "A:\\path\\to\\aqua\\data",
"serverType": 0,
"aquaSrvDir": "A:\\path\\to\\aqua\\data",
"ArtConnSettings": {
"host":"192.168.smt.hng",
"user":"MaiDXNet",
"password":"aSecurePassword"
},
"imageFolder": "N:\\MaiMaiDXNet\\public\\images"
}
```
`serverType` selects between Aqua (0), and Artemis (1).
Note: you want to enter into the `data` folder in `aquaSrvDir`.
Note: `imageFolder` leads to the `/public/images` folder of the directory.
## Artemis
### WARNING: Artemis currently does not have support for Memorial Photos, and none will be imported when attempting to use Artemis.
Create a `config.json` file and paste this in, with paths to your instance.
```json
{
"serverType": 1,
"aquaSrvDir": "A:\\path\\to\\aqua\\data",
"ArtConnSettings": {
"host":"192.168.smt.hng",
"user":"MaiDXNet",
"pass":"aSecurePassword"
},
"imageFolder": "N:\\MaiMaiDXNet\\public\\images"
}
```
`serverType` selects between Aqua (0), and Artemis (1).
Edit `ArtConnSettings` to be configured for your server.
Modify and use this command string in your terminal to create and set up permissions for The MaiDXNet account.
```sql
CREATE USER 'MaiDXNet'@'%' IDENTIFIED BY 'aSecurePassword';
GRANT Alter,Create,Delete,Drop,Index,Insert,References,Select,Update ON aime.* TO 'MaiDXNet'@'%';
```
# Project Progress
Goal for Milestone 1:

View File

@ -1,126 +1,80 @@
var express = require('express');
var router = express.Router();
var fetch = require('cross-fetch');
const sqlite3 = require('sqlite3').verbose();
const fs = require('fs')
var config = require('../config.json');
let db = new sqlite3.Database(config.DXMemorialImageDirectory + '\\db.sqlite');
var {getExtId,getUserArea,getUserScores,getUserUnbanned,getUserBanned, getUserData} = require("../dbhandler.js");
router.post('/getExtId/', function (req, res, next) {
db.all('SELECT * FROM sega_card', (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 = undefined // Leave the Matched User undefined until the user is found.
for (user of rows) { // For Each User in Rows
if (request.input === user.luid) { // If the Access Code for the card is in the system,
mUser = user; // set the Matched User Variable to the User, and break the for Loop.
break
}
}
// Return a Response with the whole identifiable user data. the EXT_ID will be used later to identify images and other things and match them to the user's profile.
getExtId(req).then(
(mUser) => {
res.status(200).json({ data: mUser, status: "Complete" });
}
});
},
(reason) => {
res.status(500).json({ error: reason, status: "Failed" });
console.error(reason); // Error!
},
);
});
router.post('/getUserData/', function (req,res,next) {
db.all('SELECT * FROM maimai2_user_detail', (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 = undefined // Leave the Matched User undefined until the user is found.
for (user of rows) { // For Each User in Rows
if (request.input === user.aime_card_id) { // If the Access Code for the card is in the system,
mUser = user; // set the Matched User Variable to the User, and break the for Loop.
break
}
}
// Return a Response with the whole identifiable user data. the EXT_ID will be used later to identify images and other things and match them to the user's profile.
getUserData(req).then(
(mUser) => {
res.status(200).json({ data: mUser, status: "Complete" });
}
});
},
(reason) => {
res.status(500).json({ error: reason, status: "Failed" });
console.error(reason); // Error!
},
);
})
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.
getUserScores(req).then(
(mUser) => {
res.status(200).json({ data: mUser, status: "Complete" });
}
});
},
(reason) => {
res.status(500).json({ error: err.message, status: "Failed" });
console.error(reason); // Error!
},
);
});
router.post('/getUserArea/', function (req,res,next) {
db.all('SELECT * FROM maimai2_user_map', (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 Areas undefined until the user is found.
for (map of rows) { // For Each Area in Rows
if (request.input == map.user_id) { // If the inputed User ID and Score's User ID Matches,
mUser.push(map) // add that Area into the array.
}
}
// Return a Response with all the Areas listed under that user.
getUserArea(req).then(
(mUser) => {
res.status(200).json({ data: mUser, status: "Complete" });
}
});
},
(reason) => {
res.status(500).json({ error: err.message, status: "Failed" });
console.error(reason); // Error!
},
);
});
router.post('/getuserbanned/', function (req,res,next) {
var request = req.body;
if (request.input === undefined) {
return res.status(500).send('Failed to update user ban state, insufficent paramaters');
}
db.run('UPDATE maimai2_user_detail SET ban_state = ? WHERE id = ?', [2, request.input], function(err) {
if (err) {
console.error(err.message);
res.status(500).send('Failed to update user ban state');
} else {
res.send({"status": "Success", "message": `User ${request.input} banned.`});
}
});
getUserBanned(req).then(
(result) => {
res.send(result);
},
(reason) => {
res.status(500).send(reason);
console.error(reason); // Error!
},
);
});
router.post('/getuserunbanned/', function (req,res,next) {
var request = req.body;
if (request.input === undefined) {
return res.status(500).send('Failed to update user ban state, insufficent paramaters');
}
db.run('UPDATE maimai2_user_detail SET ban_state = ? WHERE id = ?', [0, request.input], function(err) {
if (err) {
console.error(err.message);
res.status(500).send('Failed to update user ban state');
} else {
res.send({"status": "Success", "message": `User ${request.input} unbanned.`});
}
});
getUserUnbanned(req).then(
(result) => {
res.send(result);
},
(reason) => {
res.status(500).send(reason);
console.error(reason); // Error!
},
);
});
router.get('/getmemorialimagelist/', function (req,res,next) {

View File

@ -1,29 +1,30 @@
var express = require('express');
var router = express.Router();
var fetch = require('cross-fetch');
const sqlite3 = require('sqlite3').verbose();
var config = require('../config.json');
let db = new sqlite3.Database(config.DXMemorialImageDirectory + '\\db.sqlite');
var { getUserCount, getUserData } = require("../dbhandler.js");
/* GET home page. */
var title = 'Webapp Mission Test'
router.get('/', function (req, res, next) {
db.all('SELECT * FROM sega_card', (err, rows) => {
if (err) {
console.error(err);
res.render('error', { error: err });
} else {
console.log(rows);
console.log(`There are Currently ${rows.length} Users Registered.`); // this check could probably be changed into an API
var title = 'MaiDXNet';
router.get('/', async function (req, res, next) {
await getUserCount().then(
(userCount) => {
var params = {
totalUsers: rows.length
}
totalUsers: userCount, // ToDo: Change this to use the internal dbhandler api
serverType: config.serverType
};
console.log(`Recived User Count:`+userCount);
res.render('index', { title: title, params: params });
}
});
},
(reason) => {
res.render('error', { title: title, error: reason });
console.error(reason); // Error!
},
);
});
router.get('/user', async function (req, res, next) {
try{
try {
const cookies = req.cookies
console.log(cookies)
if (cookies.aime_card_id === undefined) {
@ -35,36 +36,4 @@ 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
db.all('SELECT * FROM maimai2_user_detail', (err, rows) => {
if (err) {
console.error(err);
// Return a Failed Message.
reject(err)
} else {
// Make the Request easier to get to.
var mUser = undefined // Leave the Matched User undefined until the user is found.
for (user of rows) { // For Each User in Rows
if (cookies.aime_card_id === user.aime_card_id.toString()) { // If the Access Code for the card is in the system,
mUser = user; // set the Matched User Variable to the User, and break the for Loop.
break;
}
}
if (mUser) {
// Return a Response with the whole identifiable user data. the EXT_ID will be used later to identify images and other things and match them to the user's profile.
resolve(mUser);
} else {
reject(new Error('User not found'));
}
}
});
});
} // function is required to obtain the User Data, and create the user profile. I'm going to bed.
module.exports = router;

View File

@ -1,9 +1,18 @@
<% var rootPath='../' ; %>
<%- include(rootPath + 'templates/header.ejs' ); %>
<% if (params.serverType===0) { %>
<script>
window.serverType = 0;
</script>
<% } else { %>
<script>
window.serverType = 1;
</script>
<% } %>
<div id="loginContent">
<h1>MaiGateDX</h1>
<h5>Total Users Registered: <%= params.totalUsers %></h5>
<h1>MaiDXNet</h1>
<h5>Total Users Registered: <%= params.totalUsers %>
</h5>
<h4>Please Input your 20 Digit Access Code.</h4>
<form id="myForm">
<input type="text" name="myInput" minlength="20" maxlength="20" placeholder="0000011111222223333344444" required>
@ -17,7 +26,9 @@
</h4>
<h5>
- Site Is Not Complete<br>
- Unfortunatly Some Song Jackets Cannot be found, which will lead certain lisenced and original songs to load without their jackets when checking your play log.
- Unfortunatly Some Song Jackets Cannot be found, which will lead certain lisenced and original songs to
load without their jackets when checking your play log. <br>
- Artemis does not Support Memorial Photos, though that is coming.
</h5>
</div>
</body>

View File

@ -3,8 +3,25 @@
<% function normalizeText(text) { return text .normalize('NFD') .replace(/[\u0300-\u036f]/g, ''
).replace(/[\uFF01-\uFF5E]/g, function(ch) { return String.fromCharCode(ch.charCodeAt(0) - 0xFEE0); }); } %>
<link href="/stylesheets/user.css" rel="stylesheet" type="text/css">
<%
// set parameters correctly for either aqua format or Artemis format
var user = {};
if(userdata.user_name !== undefined) {
user = {
user_name: userdata.user_name,
music_rating: userdata.music_rating,
total_awake: userdata.total_awake
}
} else {
user = {
user_name: userdata.userName,
music_rating: userdata.musicRating,
total_awake: userdata.totalAwake
}
}
%>
<div id="User">
<h1>Yo! Welcome Back <%= normalizeText(userdata.user_name) %>!</h1>
<h1>Yo! Welcome Back <%= normalizeText(user.user_name) %>!</h1>
<div id="wrapper">
<!-- Calm before the storm -->
@ -26,14 +43,14 @@
<h4 id="user-title-text"></h4>
</div>
<div class="user-name">
<h4><%= normalizeText(userdata.user_name) %></h4>
<h4><%= normalizeText(user.user_name) %></h4>
</div>
<div class="dx-rating">
<h4><%= userdata.music_rating%></h4>
<h4><%= user.music_rating%></h4>
</div>
<div class="user-class"></div>
<div class="awakens">
<h4>★ ☓<%= userdata.total_awake%></h4>
<h4>★ ☓<%= user.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">