mirror of
https://github.com/ibratabian17/OpenParty.git
synced 2026-01-15 14:22:54 -03:00
Improve User Assigning Profile and Fix Leaderboard Causing recap freezes
This commit is contained in:
@@ -2,12 +2,14 @@ var { main } = require('./var')
|
||||
var { resolvePath } = require('./helper')
|
||||
var { modules } = require('../settings.json')
|
||||
var fs = require("fs"); // require https module
|
||||
var requestIp = require('./lib/ipResolver.js')
|
||||
|
||||
|
||||
function init(app, express) {
|
||||
const bodyParser = require("body-parser");
|
||||
app.use(express.json());
|
||||
app.use(bodyParser.raw());
|
||||
app.use(requestIp.mw())
|
||||
app.use((err, req, res, next) => {
|
||||
// shareLog('ERROR', `${err}`)
|
||||
res.status(500).send('Internal Server Error');
|
||||
|
||||
206
core/lib/ipResolver.js
Normal file
206
core/lib/ipResolver.js
Normal file
@@ -0,0 +1,206 @@
|
||||
const is = require('./is');
|
||||
//taken from https://github.com/pbojinov/request-ip
|
||||
|
||||
/**
|
||||
* Parse x-forwarded-for headers.
|
||||
*
|
||||
* @param {string} value - The value to be parsed.
|
||||
* @return {string|null} First known IP address, if any.
|
||||
*/
|
||||
function getClientIpFromXForwardedFor(value) {
|
||||
if (!is.existy(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is.not.string(value)) {
|
||||
throw new TypeError(`Expected a string, got "${typeof value}"`);
|
||||
}
|
||||
|
||||
// x-forwarded-for may return multiple IP addresses in the format:
|
||||
// "client IP, proxy 1 IP, proxy 2 IP"
|
||||
// Therefore, the right-most IP address is the IP address of the most recent proxy
|
||||
// and the left-most IP address is the IP address of the originating client.
|
||||
// source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
|
||||
// Azure Web App's also adds a port for some reason, so we'll only use the first part (the IP)
|
||||
const forwardedIps = value.split(',').map((e) => {
|
||||
const ip = e.trim();
|
||||
if (ip.includes(':')) {
|
||||
const splitted = ip.split(':');
|
||||
// make sure we only use this if it's ipv4 (ip:port)
|
||||
if (splitted.length === 2) {
|
||||
return splitted[0];
|
||||
}
|
||||
}
|
||||
return ip;
|
||||
});
|
||||
|
||||
// Sometimes IP addresses in this header can be 'unknown' (http://stackoverflow.com/a/11285650).
|
||||
// Therefore taking the right-most IP address that is not unknown
|
||||
// A Squid configuration directive can also set the value to "unknown" (http://www.squid-cache.org/Doc/config/forwarded_for/)
|
||||
for (let i = 0; i < forwardedIps.length; i++) {
|
||||
if (is.ip(forwardedIps[i])) {
|
||||
return forwardedIps[i];
|
||||
}
|
||||
}
|
||||
|
||||
// If no value in the split list is an ip, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine client IP address.
|
||||
*
|
||||
* @param req
|
||||
* @returns {string} ip - The IP address if known, defaulting to empty string if unknown.
|
||||
*/
|
||||
function getClientIp(req) {
|
||||
// Server is probably behind a proxy.
|
||||
if (req.headers) {
|
||||
// Standard headers used by Amazon EC2, Heroku, and others.
|
||||
if (is.ip(req.headers['x-client-ip'])) {
|
||||
return req.headers['x-client-ip'];
|
||||
}
|
||||
|
||||
// Load-balancers (AWS ELB) or proxies.
|
||||
const xForwardedFor = getClientIpFromXForwardedFor(
|
||||
req.headers['x-forwarded-for'],
|
||||
);
|
||||
if (is.ip(xForwardedFor)) {
|
||||
return xForwardedFor;
|
||||
}
|
||||
|
||||
// Cloudflare.
|
||||
// @see https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-
|
||||
// CF-Connecting-IP - applied to every request to the origin.
|
||||
if (is.ip(req.headers['cf-connecting-ip'])) {
|
||||
return req.headers['cf-connecting-ip'];
|
||||
}
|
||||
|
||||
// DigitalOcean.
|
||||
// @see https://www.digitalocean.com/community/questions/app-platform-client-ip
|
||||
// DO-Connecting-IP - applied to app platform servers behind a proxy.
|
||||
if (is.ip(req.headers['do-connecting-ip'])) {
|
||||
return req.headers['do-connecting-ip'];
|
||||
}
|
||||
|
||||
// Fastly and Firebase hosting header (When forwared to cloud function)
|
||||
if (is.ip(req.headers['fastly-client-ip'])) {
|
||||
return req.headers['fastly-client-ip'];
|
||||
}
|
||||
|
||||
// Akamai and Cloudflare: True-Client-IP.
|
||||
if (is.ip(req.headers['true-client-ip'])) {
|
||||
return req.headers['true-client-ip'];
|
||||
}
|
||||
|
||||
// Default nginx proxy/fcgi; alternative to x-forwarded-for, used by some proxies.
|
||||
if (is.ip(req.headers['x-real-ip'])) {
|
||||
return req.headers['x-real-ip'];
|
||||
}
|
||||
|
||||
// (Rackspace LB and Riverbed's Stingray)
|
||||
// http://www.rackspace.com/knowledge_center/article/controlling-access-to-linux-cloud-sites-based-on-the-client-ip-address
|
||||
// https://splash.riverbed.com/docs/DOC-1926
|
||||
if (is.ip(req.headers['x-cluster-client-ip'])) {
|
||||
return req.headers['x-cluster-client-ip'];
|
||||
}
|
||||
|
||||
if (is.ip(req.headers['x-forwarded'])) {
|
||||
return req.headers['x-forwarded'];
|
||||
}
|
||||
|
||||
if (is.ip(req.headers['forwarded-for'])) {
|
||||
return req.headers['forwarded-for'];
|
||||
}
|
||||
|
||||
if (is.ip(req.headers.forwarded)) {
|
||||
return req.headers.forwarded;
|
||||
}
|
||||
|
||||
// Google Cloud App Engine
|
||||
// https://cloud.google.com/appengine/docs/standard/go/reference/request-response-headers
|
||||
|
||||
if (is.ip(req.headers['x-appengine-user-ip'])) {
|
||||
return req.headers['x-appengine-user-ip'];
|
||||
}
|
||||
}
|
||||
|
||||
// Remote address checks.
|
||||
// Deprecated
|
||||
if (is.existy(req.connection)) {
|
||||
if (is.ip(req.connection.remoteAddress)) {
|
||||
return req.connection.remoteAddress;
|
||||
}
|
||||
if (
|
||||
is.existy(req.connection.socket) &&
|
||||
is.ip(req.connection.socket.remoteAddress)
|
||||
) {
|
||||
return req.connection.socket.remoteAddress;
|
||||
}
|
||||
}
|
||||
|
||||
if (is.existy(req.socket) && is.ip(req.socket.remoteAddress)) {
|
||||
return req.socket.remoteAddress;
|
||||
}
|
||||
|
||||
if (is.existy(req.info) && is.ip(req.info.remoteAddress)) {
|
||||
return req.info.remoteAddress;
|
||||
}
|
||||
|
||||
// AWS Api Gateway + Lambda
|
||||
if (
|
||||
is.existy(req.requestContext) &&
|
||||
is.existy(req.requestContext.identity) &&
|
||||
is.ip(req.requestContext.identity.sourceIp)
|
||||
) {
|
||||
return req.requestContext.identity.sourceIp;
|
||||
}
|
||||
|
||||
// Cloudflare fallback
|
||||
// https://blog.cloudflare.com/eliminating-the-last-reasons-to-not-enable-ipv6/#introducingpseudoipv4
|
||||
if (req.headers) {
|
||||
if (is.ip(req.headers['Cf-Pseudo-IPv4'])) {
|
||||
return req.headers['Cf-Pseudo-IPv4'];
|
||||
}
|
||||
}
|
||||
|
||||
// Fastify https://www.fastify.io/docs/latest/Reference/Request/
|
||||
if (is.existy(req.raw)) {
|
||||
return getClientIp(req.raw);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose request IP as a middleware.
|
||||
*
|
||||
* @param {object} [options] - Configuration.
|
||||
* @param {string} [options.attributeName] - Name of attribute to augment request object with.
|
||||
* @return {*}
|
||||
*/
|
||||
function mw(options) {
|
||||
// Defaults.
|
||||
const configuration = is.not.existy(options) ? {} : options;
|
||||
|
||||
// Validation.
|
||||
if (is.not.object(configuration)) {
|
||||
throw new TypeError('Options must be an object!');
|
||||
}
|
||||
|
||||
const attributeName = configuration.attributeName || 'clientIp';
|
||||
return (req, res, next) => {
|
||||
const ip = getClientIp(req);
|
||||
Object.defineProperty(req, attributeName, {
|
||||
get: () => ip,
|
||||
configurable: true,
|
||||
});
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getClientIpFromXForwardedFor,
|
||||
getClientIp,
|
||||
mw,
|
||||
};
|
||||
72
core/lib/is.js
Normal file
72
core/lib/is.js
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Inspired by and credit to is_js [https://github.com/arasatasaygin/is.js]
|
||||
*/
|
||||
|
||||
const regexes = {
|
||||
ipv4: /^(?:(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/,
|
||||
ipv6: /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i,
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function which reverses the sense of predicate result
|
||||
* @param {*} func
|
||||
* @returns
|
||||
*/
|
||||
function not(func) {
|
||||
return function () {
|
||||
return !func.apply(null, Array.prototype.slice.call(arguments));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces is.existy from is_js.
|
||||
* @param {*} value - The value to test
|
||||
* @returns {boolean} True if the value is defined, otherwise false
|
||||
*/
|
||||
function existy(value) {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces is.ip from is_js.
|
||||
* @param {*} value - The value to test
|
||||
* @returns {boolean} True if the value is an IP address, otherwise false
|
||||
*/
|
||||
function ip(value) {
|
||||
return (
|
||||
(existy(value) && regexes.ipv4.test(value)) || regexes.ipv6.test(value)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces is.object from is_js.
|
||||
* @param {*} value - The value to test
|
||||
* @returns {boolean} True if the value is an object, otherwise false
|
||||
*/
|
||||
function object(value) {
|
||||
return Object(value) === value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces is,.string from is_js.
|
||||
* @param {*} value - The value to test
|
||||
* @returns True if the value is a string, otherwise false
|
||||
*/
|
||||
function string(value) {
|
||||
return Object.prototype.toString.call(value) === '[object String]';
|
||||
}
|
||||
|
||||
const is = {
|
||||
existy: existy,
|
||||
ip: ip,
|
||||
object: object,
|
||||
string: string,
|
||||
not: {
|
||||
existy: not(existy),
|
||||
ip: not(ip),
|
||||
object: not(object),
|
||||
string: not(string),
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = is;
|
||||
@@ -29,15 +29,16 @@ exports.initroute = (app) => {
|
||||
console.log('[ACC] Is the key correct? are the files corrupted?')
|
||||
console.log('[ACC] Ignore this message if this first run')
|
||||
console.log('[ACC] Resetting All User Data...')
|
||||
console.log(err)
|
||||
}
|
||||
|
||||
// Map over profileIds to retrieve corresponding user profiles or create default profiles
|
||||
const responseProfiles = profilesid.map(profileId => {
|
||||
const userProfile = decryptedData[profileId]; // Get user profile based on profileId
|
||||
if (userProfile) {
|
||||
return { ...userProfile, ip: req.ip, ticket: ticket }; // Add IP to userProfile but not in the response
|
||||
return { ...userProfile, ip: req.clientIp, ticket: ticket }; // Add IP to userProfile but not in the response
|
||||
} else {
|
||||
const defaultProfile = { ip: req.ip, ticket: ticket }; // Create a default profile with IP address
|
||||
const defaultProfile = { ip: req.clientIp, ticket: ticket }; // Create a default profile with IP address
|
||||
decryptedData[profileId] = defaultProfile; // Add default profile to decrypted data
|
||||
return {}; // Return an empty object (don't include defaultProfile in response)
|
||||
}
|
||||
@@ -64,6 +65,7 @@ exports.initroute = (app) => {
|
||||
console.log('[ACC] Is the key correct? are the files corrupted?')
|
||||
console.log('[ACC] Ignore this message if this first run')
|
||||
console.log('[ACC] Resetting All User Data...')
|
||||
console.log(err)
|
||||
}
|
||||
|
||||
// Find a matching profile based on name or IP address (only one profile)
|
||||
@@ -75,7 +77,7 @@ exports.initroute = (app) => {
|
||||
}
|
||||
const matchedProfileId = Object.keys(decryptedData).find(profileId => {
|
||||
const userProfile = decryptedData[profileId]; // Get user profile based on profileId
|
||||
return userProfile.name === content.name || userProfile.ticket === ticket || userProfile.ip === req.ip; // Check for name or IP match
|
||||
return userProfile.name === content.name || userProfile.ticket === ticket || userProfile.ip === req.clientIp; // Check for name or IP match
|
||||
});
|
||||
|
||||
if (matchedProfileId) {
|
||||
|
||||
@@ -9,6 +9,11 @@ const core = {
|
||||
generateCarousel: require('../carousel/carousel').generateCarousel, generateSweatCarousel: require('../carousel/carousel').generateSweatCarousel, generateCoopCarousel: require('../carousel/carousel').generateCoopCarousel, updateMostPlayed: require('../carousel/carousel').updateMostPlayed
|
||||
}
|
||||
const DOTW_PATH = path.join(core.getSavefilePath(), 'leaderboard/dotw/');
|
||||
const { getSavefilePath } = require('../helper');
|
||||
const { encrypt, decrypt } = require('../lib/encryptor')
|
||||
|
||||
const secretKey = require('../../database/encryption.json').encrpytion.userEncrypt;
|
||||
decryptedData = {};
|
||||
|
||||
function generateToolNickname() {
|
||||
const prefixes = ["Wordkeeper", "Special", "Krakenbite", "DinosaurFan", "Definehub", "Termtracker", "Lexiconet", "Vocabvault", "Lingolink", "Glossarygenius", "Thesaurustech", "Synonymster", "Definitionary", "Jargonjot", "Idiomizer", "Phraseforge", "Meaningmaker", "Languageledger", "Etymologyengine", "Grammarguard", "Syntaxsense", "Semanticsearch", "Orthographix", "Phraseology", "Vernacularvault", "Dictionet", "Slangscroll", "Lingualist", "Grammargrid", "Lingoledge", "Termtoolbox", "Wordware", "Lexigizmo", "Synosearch", "Thesaurustech", "Phrasefinder", "Vocabvortex", "Meaningmatrix", "Languageledger", "Etymologist", "Grammargate", "Syntaxsphere", "Semanticsearch", "Orthographix", "Phraseplay", "Vernacularvault", "Dictionator", "Slangstack", "Lingolink", "Grammarguide", "Lingopedia", "Termtracker", "Wordwizard", "Lexilist", "Synomate", "Thesaurustool", "Definitizer", "Jargonjunction", "Idiomgenius", "Phrasemaker", "Meaningmate", "Duolingo", "Languagelink", "Etymoengine", "Grammarguru", "Syntaxsage", "Semanticsuite", "Orthography", "Phrasefinder", "Vocabverse", "Lexipedia", "Synoscribe", "Thesaurusware", "Definitionary", "Jargonscribe", "Idiomster", "Phrasetech", "Meaningmax", "Flop", "Slayguy", "Languagelex", "Etymoedge", "Grammargenie", "Syntaxsync", "Semanticsearch", "Orthography", "Phraseforge", "Vernacularex", "Dictionmaster", "Slangster", "Lingoware", "Grammargraph", "Lingomate", "Termmate", "Wordwork", "Lexixpert", "Synostar", "Thesaurusmax", "OculusVision", "FlowerPower", "RustySilver", "Underfire", "Shakeawake", "Truthhand", "Kittywake", "Definize", "Jargonize", "Idiomify", "Phrasemaster", "Meaningmark", "Lingualine", "Etymogenius", "Grammarguard", "Syntaxsmart", "Semanticsearch", "Orthography", "Phrasedex", "Vocabmax", "Lexilock", "Synomind", "Thesaurusmart", "Definify", "Jargonmatrix", "Idiomnet", "Phraseplay", "Meaningmate", "Lingolink", "Etymoexpert", "Grammargetter", "Syntaxsage", "Semanticsearch", "Orthography", "Phrasepad", "Vernacularvibe", "Dictiondom", "Slangster", "Lingolytics", "Grammargenie", "Lingotutor", "Termtracker", "Wordwarp", "Lexisync", "Synomind", "Thesaurusmate", "Definizer", "Jargonify", "Idiomster", "Phraselab", "Meaningmark", "Languageleaf", "Etymoedge", "Grammargrid", "Syntaxsync", "Semanticsuite", "Orthographix", "Phraseforge", "Vernacularvibe", "Dictiondom", "Slangster", "Lingolytics", "Grammargenie", "Lingotutor", "Termtracker", "Wordwarp", "Lexisync", "Synomind", "Thesaurusmate", "Definizer", "Jargonify", "Idiomster", "Phraselab", "Meaningmark", "Languageleaf", "Etymoedge", "Grammargrid", "Syntaxsync", "Semanticsuite", "Orthographix"];
|
||||
@@ -27,38 +32,37 @@ function generateToolNickname() {
|
||||
|
||||
}
|
||||
|
||||
const getProfileData = async (req) => {
|
||||
function getProfileData(ticket, content, clientIp) {
|
||||
const dataFilePath = path.join(getSavefilePath(), '/account/profiles/user.json');
|
||||
try {
|
||||
const ticket = req.header("Authorization");
|
||||
const sku = req.header('X-SkuId');
|
||||
const prodwsurl = "https://prod.just-dance.com/";
|
||||
|
||||
const response = await axios({
|
||||
method: req.method,
|
||||
url: prodwsurl + req.url,
|
||||
headers: {
|
||||
"X-SkuId": sku,
|
||||
"Authorization": ticket,
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
data: req.body
|
||||
});
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
throw new Error(`HTTP status ${error.response.status}`);
|
||||
} else if (error.request) {
|
||||
throw new Error('Network error');
|
||||
} else {
|
||||
throw new Error(error.message);
|
||||
if (Object.keys(decryptedData).length === 0) {
|
||||
const encryptedData = fs.readFileSync(dataFilePath, 'utf8');
|
||||
decryptedData = JSON.parse(decrypt(encryptedData, secretKey));
|
||||
}
|
||||
} catch (err) {
|
||||
decryptedData = {};
|
||||
console.log('[ACC] Unable to read user.json');
|
||||
console.log('[ACC] Is the key correct? are the files corrupted?');
|
||||
console.log('[ACC] Ignore this message if this first run');
|
||||
console.log('[ACC] Resetting All User Data...');
|
||||
console.log(err);
|
||||
}
|
||||
};
|
||||
|
||||
const matchedProfileId = Object.keys(decryptedData).find(profileId => {
|
||||
const userProfile = decryptedData[profileId];
|
||||
return userProfile.ticket === ticket || userProfile.ip === clientIp;
|
||||
});
|
||||
|
||||
if (matchedProfileId) {
|
||||
return decryptedData[matchedProfileId];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const getGameVersion = (req) => {
|
||||
const sku = req.header('X-SkuId');
|
||||
return sku.substring(0, 6);
|
||||
const sku = req.header('X-SkuId') || "jd2019-pc-ww";
|
||||
return sku.substring(0, 6) || "jd2019";
|
||||
};
|
||||
|
||||
const initroute = (app) => {
|
||||
@@ -102,62 +106,6 @@ const initroute = (app) => {
|
||||
|
||||
try {
|
||||
leaderboardData.entries.push(
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
"score": Math.floor(Math.random() * 1333) + 12000,
|
||||
"name": generateToolNickname(),
|
||||
"avatar": Math.floor(Math.random() * 100),
|
||||
"country": Math.floor(Math.random() * 20),
|
||||
"platformId": "e3",
|
||||
"alias": 0,
|
||||
"aliasGender": 0,
|
||||
"jdPoints": 0,
|
||||
"portraitBorder": 0,
|
||||
"mapName": mapName
|
||||
},
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
"score": Math.floor(Math.random() * 1333) + 12000,
|
||||
"name": generateToolNickname(),
|
||||
"avatar": Math.floor(Math.random() * 100),
|
||||
"country": Math.floor(Math.random() * 20),
|
||||
"platformId": "e3",
|
||||
"alias": 0,
|
||||
"aliasGender": 0,
|
||||
"jdPoints": 0,
|
||||
"portraitBorder": 0,
|
||||
"mapName": mapName
|
||||
},
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
"score": Math.floor(Math.random() * 1333) + 12000,
|
||||
"name": generateToolNickname(),
|
||||
"avatar": Math.floor(Math.random() * 100),
|
||||
"country": Math.floor(Math.random() * 20),
|
||||
"platformId": "e3",
|
||||
"alias": 0,
|
||||
"aliasGender": 0,
|
||||
"jdPoints": 0,
|
||||
"portraitBorder": 0,
|
||||
"mapName": mapName
|
||||
},
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
"score": Math.floor(Math.random() * 1333) + 12000,
|
||||
"name": generateToolNickname(),
|
||||
"avatar": Math.floor(Math.random() * 100),
|
||||
"country": Math.floor(Math.random() * 20),
|
||||
"platformId": "e3",
|
||||
"alias": 0,
|
||||
"aliasGender": 0,
|
||||
"jdPoints": 0,
|
||||
"portraitBorder": 0,
|
||||
"mapName": mapName
|
||||
},
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
@@ -189,62 +137,6 @@ const initroute = (app) => {
|
||||
|
||||
try {
|
||||
leaderboardData.entries.push(
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
"score": Math.floor(Math.random() * 1333) + 12000,
|
||||
"name": generateToolNickname(),
|
||||
"avatar": Math.floor(Math.random() * 100),
|
||||
"country": Math.floor(Math.random() * 20),
|
||||
"platformId": "e3",
|
||||
"alias": 0,
|
||||
"aliasGender": 0,
|
||||
"jdPoints": 0,
|
||||
"portraitBorder": 0,
|
||||
"mapName": mapName
|
||||
},
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
"score": Math.floor(Math.random() * 1333) + 12000,
|
||||
"name": generateToolNickname(),
|
||||
"avatar": Math.floor(Math.random() * 100),
|
||||
"country": Math.floor(Math.random() * 20),
|
||||
"platformId": "e3",
|
||||
"alias": 0,
|
||||
"aliasGender": 0,
|
||||
"jdPoints": 0,
|
||||
"portraitBorder": 0,
|
||||
"mapName": mapName
|
||||
},
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
"score": Math.floor(Math.random() * 1333) + 12000,
|
||||
"name": generateToolNickname(),
|
||||
"avatar": Math.floor(Math.random() * 100),
|
||||
"country": Math.floor(Math.random() * 20),
|
||||
"platformId": "e3",
|
||||
"alias": 0,
|
||||
"aliasGender": 0,
|
||||
"jdPoints": 0,
|
||||
"portraitBorder": 0,
|
||||
"mapName": mapName
|
||||
},
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
"score": Math.floor(Math.random() * 1333) + 12000,
|
||||
"name": generateToolNickname(),
|
||||
"avatar": Math.floor(Math.random() * 100),
|
||||
"country": Math.floor(Math.random() * 20),
|
||||
"platformId": "e3",
|
||||
"alias": 0,
|
||||
"aliasGender": 0,
|
||||
"jdPoints": 0,
|
||||
"portraitBorder": 0,
|
||||
"mapName": mapName
|
||||
},
|
||||
{
|
||||
"__class": "LeaderboardEntry_Online",
|
||||
"profileId": "00000000-0000-0000-0000-000000000000",
|
||||
@@ -267,11 +159,12 @@ const initroute = (app) => {
|
||||
});
|
||||
|
||||
app.post("/profile/v2/map-ended", async (req, res) => {
|
||||
const codename = req.body;
|
||||
|
||||
const ticket = req.header("Authorization");
|
||||
const clientIp = req.ip;
|
||||
try {
|
||||
for (let song of codename) {
|
||||
core.updateMostPlayed(song);
|
||||
const mapList = req.body;
|
||||
for (let song of mapList) {
|
||||
core.updateMostPlayed(song.mapName);
|
||||
|
||||
const dotwFilePath = path.join(DOTW_PATH, `${song.mapName}.json`);
|
||||
if (fs.existsSync(dotwFilePath)) {
|
||||
@@ -281,9 +174,9 @@ const initroute = (app) => {
|
||||
return res.send('1');
|
||||
}
|
||||
} else {
|
||||
const profiljson1 = await getProfileData(req);
|
||||
const profiljson1 = await getProfileData(ticket, song, clientIp);
|
||||
if (!profiljson1) {
|
||||
return res.status(500).send('Error fetching profile data');
|
||||
return res.send('1')
|
||||
}
|
||||
|
||||
const jsontodancerweek = {
|
||||
@@ -304,12 +197,12 @@ const initroute = (app) => {
|
||||
|
||||
fs.writeFileSync(dotwFilePath, JSON.stringify(jsontodancerweek, null, 2));
|
||||
console.log(`DOTW file for ${song.mapName} created!`);
|
||||
res.send(profiljson1);
|
||||
res.send('');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send('Internal Server Error');
|
||||
console.log(error)
|
||||
res.status(200).send(''); //keep send
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user