first commit

This commit is contained in:
polaris 2024-01-17 01:12:50 -05:00
commit 827f1fd9d4
7 changed files with 3478 additions and 0 deletions

135
.gitignore vendored Executable file
View File

@ -0,0 +1,135 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
/.vscode/
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.development
.env.production
.env.test.local
.env.production.local
.env.local
production.env
development.env
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

17
app.js Executable file
View File

@ -0,0 +1,17 @@
const express = require('express');
const app = express();
const cors = require("cors");
const sunGetRoutes = require('./chunithm/13/getRoutes');
const sunPostRoutes = require('./chunithm/13/postRoutes');
app.use(express.json());
app.use(cors({ credentials: true, origin: '*' }));
app.use('/SDHD', sunGetRoutes);
app.use('/SDHD', sunPostRoutes);
// Starting the server
const PORT = 4000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});

666
chunithm/13/getRoutes.js Executable file
View File

@ -0,0 +1,666 @@
const express = require('express');
const router = express.Router();
const pool1 = require('../../db');
const { zonedTimeToUtc, format } = require("date-fns-tz");
router.get('/access-code', getAccessCodeHandler);
router.get('/items', getItemsHandler);
router.get('/chuni-avatar-items', getChuniAvatarItems);
router.get('/profile-data', getProfileDataHandler);
router.get('/chuni-score-playlog', getChuniScorePlaylogHandler);
router.get('/chuni-best-and-top', getChuniBestAndTopHandler);
router.get('/chuni-player-team', getChuniPlayerTeamHandler);
router.get('/chuni-duel-items', getChuniDuelItems);
router.get('/chuni-nameplate-items', getChuniNamePlateItems);
router.get('/chuni-map-items', getChuniMapItems);
router.get("/listFriends", listFriendsHandler);
router.get("/listRivals", listRivalsHandler);
router.get("/chuni-static-music", getChuniStaticMusic);
router.get("/get-trophies", getTrophiesHandler);
router.get("/list-favorite-songs", listFavoriteSongsHandler);
router.get("/chuni-recent", getChuniRecentHandler);
function getAccessCodeHandler(req, res) {
const userId = req.query.user;
const version = req.query.version; // Get version from URL parameter
if (!userId || !version) {
return res.status(400).json({ error: "User and version parameters are required" });
}
// Retrieve the access code for the given user ID and version
pool1.query(
`
SELECT ac.access_code
FROM aime_card ac
JOIN chuni_profile_data pd ON ac.user = pd.user
WHERE ac.user = ? AND pd.version = ?
`,
[userId, version],
(error, results) => {
if (error) {
console.error("Error retrieving access code:", error);
return res.status(500).json({ error: "Error retrieving access code" });
}
// Ensure that the access code is found
if (results.length === 0 || !results[0].access_code) {
return res.status(404).json({
error: "Access code not found for the given user and version",
});
}
const accessCode = results[0].access_code;
// Send the access code in the response
res.json({ accessCode });
}
);
}
function getItemsHandler(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
WITH UserAimeId AS (
SELECT aime_user.id AS aimeUserId
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?
)
SELECT i.*
FROM chuni_item_item i
JOIN UserAimeId uai ON i.user = uai.aimeUserId
JOIN chuni_profile_data pd ON uai.aimeUserId = pd.user
WHERE pd.version = ?
`,
[user, version],
(error, results, fields) => {
if (error) {
console.error("Error retrieving items:", error);
return res.status(500).json({ error: "Error retrieving items" });
}
res.json(results);
}
);
}
function getProfileDataHandler(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
WITH UserAimeId AS (
SELECT aime_user.id AS aimeUserId
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?
),
UserProfile AS (
SELECT p.*, t.teamName, cnst.str as trophyname
FROM chuni_profile_data p
LEFT JOIN chuni_profile_team t ON p.teamId = t.id
LEFT JOIN cozynet_chuni_static_trophies cnst ON p.trophyId = cnst.id
JOIN UserAimeId ON p.user = UserAimeId.aimeUserId
)
SELECT *
FROM UserProfile
WHERE version = ?
`,
[user, version],
(error, results, fields) => {
if (error) {
console.error("Error retrieving profile data:", error);
return res.status(500).json({ error: "Error retrieving profile data" });
}
results.forEach((row) => {
let lastPlayDateUTC = zonedTimeToUtc(row.lastPlayDate, "Asia/Tokyo");
row.lastPlayDate = format(lastPlayDateUTC, "yyyy-MM-dd");
});
res.json(results);
}
);
}
function getChuniScorePlaylogHandler(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
WITH RankedScores AS (
SELECT
csp.maxCombo,
csp.isFullCombo,
csp.userPlayDate,
csp.playerRating,
csp.isAllJustice,
csp.score,
csp.judgeHeaven,
csp.judgeGuilty,
csp.judgeJustice,
csp.judgeAttack,
csp.judgeCritical,
csp.isClear,
csp.skillId,
csp.isNewRecord,
csm.chartId,
csm.title,
csm.level,
csm.genre,
csm.jacketPath,
csm.artist,
IF(csp.score > LAG(csp.score, 1) OVER (ORDER BY csp.userPlayDate), 'Increase',
IF(csp.score < LAG(csp.score, 1) OVER (ORDER BY csp.userPlayDate), 'Decrease', 'Same')) AS score_change,
IF(csp.playerRating > LAG(csp.playerRating, 1) OVER (ORDER BY csp.userPlayDate), 'Increase',
IF(csp.playerRating < LAG(csp.playerRating, 1) OVER (ORDER BY csp.userPlayDate), 'Decrease', 'Same')) AS rating_change
FROM
chuni_score_playlog csp
JOIN chuni_profile_data d ON csp.user = d.user
JOIN chuni_static_music csm ON csp.musicId = csm.songId AND csp.level = csm.chartId AND csm.version = d.version
JOIN aime_card a ON d.user = a.user
WHERE
a.user = ? AND d.version = ? -- Use the version parameter here
)
SELECT
maxCombo,
isFullCombo,
userPlayDate,
playerRating,
isAllJustice,
score,
judgeHeaven,
judgeGuilty,
judgeJustice,
judgeAttack,
judgeCritical,
isClear,
skillId,
isNewRecord,
chartId,
title,
level,
genre,
jacketPath,
artist,
score_change,
rating_change,
CASE
WHEN score >= 1009000 THEN CAST(level AS DECIMAL(10,2)) * 100 + 215
WHEN score >= 1007500 THEN CAST(level AS DECIMAL(10,2)) * 100 + 200 + (score - 1007500) / 100
WHEN score >= 1005000 THEN CAST(level AS DECIMAL(10,2)) * 100 + 150 + (score - 1005000) / 50
WHEN score >= 1000000 THEN CAST(level AS DECIMAL(10,2)) * 100 + 100 + (score - 1000000) / 100
WHEN score >= 975000 THEN CAST(level AS DECIMAL(10,2)) * 100 + (score - 975000) / 250
WHEN score >= 925000 THEN CAST(level AS DECIMAL(10,2)) * 100 - 300 + (score - 925000) * 3 / 500
WHEN score >= 900000 THEN CAST(level AS DECIMAL(10,2)) * 100 - 500 + (score - 900000) * 4 / 500
WHEN score >= 800000 THEN ((CAST(level AS DECIMAL(10,2)) * 100 - 500) / 2 + (score - 800000) * ((CAST(level AS DECIMAL(10,2)) - 500) / 2) / 100000)
ELSE 0
END AS rating
FROM
RankedScores
ORDER BY
userPlayDate DESC;
`,
[user, version], // Pass version as a parameter
(error, results, fields) => {
if (error) throw error;
results.forEach((row) => {
let userPlayDateUTC = zonedTimeToUtc(row.userPlayDate, "Asia/Tokyo");
row.userPlayDate = format(userPlayDateUTC, "yyyy-MM-dd ");
});
res.json(results);
}
);
}
function getChuniRecentHandler(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
SELECT
jt.score,
jt.musicId,
jt.difficultId,
jt.romVersionCode,
sm.title,
sm.level,
sm.jacketPath,
CASE
WHEN jt.score >= 1009000 THEN CAST(sm.level AS DECIMAL(10,2)) * 100 + 215
WHEN jt.score >= 1007500 THEN CAST(sm.level AS DECIMAL(10,2)) * 100 + 200 + (jt.score - 1007500) / 100
WHEN jt.score >= 1005000 THEN CAST(sm.level AS DECIMAL(10,2)) * 100 + 150 + (jt.score - 1005000) / 50
WHEN jt.score >= 1000000 THEN CAST(sm.level AS DECIMAL(10,2)) * 100 + 100 + (jt.score - 1000000) / 100
WHEN jt.score >= 975000 THEN CAST(sm.level AS DECIMAL(10,2)) * 100 + (jt.score - 975000) / 250
WHEN jt.score >= 925000 THEN CAST(sm.level AS DECIMAL(10,2)) * 100 - 300 + (jt.score - 925000) * 3 / 500
WHEN jt.score >= 900000 THEN CAST(sm.level AS DECIMAL(10,2)) * 100 - 500 + (jt.score - 900000) * 4 / 500
WHEN jt.score >= 800000 THEN ((CAST(sm.level AS DECIMAL(10,2)) * 100 - 500) / 2 + (jt.score - 800000) * ((CAST(sm.level AS DECIMAL(10,2)) - 500) / 2) / 100000)
END AS rating
FROM
chuni_profile_recent_rating
JOIN
JSON_TABLE(recentRating, '$[*]' COLUMNS (
score VARCHAR(255) PATH '$.score',
musicId VARCHAR(255) PATH '$.musicId',
difficultId VARCHAR(255) PATH '$.difficultId',
romVersionCode VARCHAR(255) PATH '$.romVersionCode'
)) AS jt
JOIN
chuni_static_music sm ON jt.musicId = sm.songId AND jt.difficultId = sm.chartId
WHERE
user = ? AND sm.version = ?
ORDER BY
rating DESC;
`,
[user, version], // Pass version as a parameter
(error, results, fields) => {
if (error) throw error;
res.json(results);
}
);
}
function getProfileDataHandler(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
WITH UserAimeId AS (
SELECT aime_user.id AS aimeUserId
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?
),
UserProfile AS (
SELECT p.*, t.teamName, cnst.str as trophyname
FROM chuni_profile_data p
LEFT JOIN chuni_profile_team t ON p.teamId = t.id
LEFT JOIN cozynet_chuni_static_trophies cnst ON p.trophyId = cnst.id
JOIN UserAimeId ON p.user = UserAimeId.aimeUserId
)
SELECT *
FROM UserProfile
WHERE version = ?
`,
[user, version],
(error, results, fields) => {
if (error) {
console.error("Error retrieving profile data:", error);
return res.status(500).json({ error: "Error retrieving profile data" });
}
results.forEach((row) => {
let lastPlayDateUTC = zonedTimeToUtc(row.lastPlayDate, "Asia/Tokyo");
row.lastPlayDate = format(lastPlayDateUTC, "yyyy-MM-dd");
});
res.json(results);
}
);
}
function getChuniStaticMusic(req, res) {
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
SELECT DISTINCT csm.songId, csm.title, csm.artist, csm.jacketPath
FROM chuni_static_music csm
WHERE csm.version = ?
`,
[version], // Pass version as a parameter
(error, results, fields) => {
if (error) {
console.error("Error retrieving static music:", error);
return res.status(500).json({ error: "Error retrieving best and top data" });
}
res.json(results);
}
);
}
function getChuniBestAndTopHandler(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
SELECT
csp.maxCombo,
csp.isFullCombo,
csp.userPlayDate,
csp.playerRating,
csp.isAllJustice,
csp.score,
csp.isNewRecord,
csp.judgeHeaven,
csp.judgeGuilty,
csp.judgeJustice,
csp.judgeAttack,
csp.judgeCritical,
csp.isClear,
csp.skillId,
csp.isNewRecord,
csm.chartId,
csm.title,
csm.level,
csm.genre,
csm.jacketPath,
csm.artist,
CASE
WHEN csp.score > LAG(csp.score, 1) OVER (ORDER BY csp.userPlayDate) THEN 'Increase'
WHEN csp.score < LAG(csp.score, 1) OVER (ORDER BY csp.userPlayDate) THEN 'Decrease'
ELSE 'Same'
END AS score_change,
CASE
WHEN csp.playerRating > LAG(csp.playerRating, 1) OVER (ORDER BY csp.userPlayDate) THEN 'Increase'
WHEN csp.playerRating < LAG(csp.playerRating, 1) OVER (ORDER BY csp.userPlayDate) THEN 'Decrease'
ELSE 'Same'
END AS rating_change,
CASE
WHEN csp.score >= 1009000 THEN CAST(csm.level AS DECIMAL(10,2)) * 100 + 215
WHEN csp.score >= 1007500 THEN CAST(csm.level AS DECIMAL(10,2)) * 100 + 200 + (csp.score - 1007500) / 100
WHEN csp.score >= 1005000 THEN CAST(csm.level AS DECIMAL(10,2)) * 100 + 150 + (csp.score - 1005000) / 50
WHEN csp.score >= 1000000 THEN CAST(csm.level AS DECIMAL(10,2)) * 100 + 100 + (csp.score - 1000000) / 100
WHEN csp.score >= 975000 THEN CAST(csm.level AS DECIMAL(10,2)) * 100 + (csp.score - 975000) / 250
WHEN csp.score >= 925000 THEN CAST(csm.level AS DECIMAL(10,2)) * 100 - 300 + (csp.score - 925000) * 3 / 500
WHEN csp.score >= 900000 THEN CAST(csm.level AS DECIMAL(10,2)) * 100 - 500 + (csp.score - 900000) * 4 / 500
WHEN csp.score >= 800000 THEN ((CAST(csm.level AS DECIMAL(10,2)) * 100 - 500) / 2 + (csp.score - 800000) * ((CAST(csm.level AS DECIMAL(10,2)) - 500) / 2) / 100000)
ELSE 0
END AS rating
FROM
chuni_score_playlog csp
JOIN
chuni_static_music csm ON csp.musicId = csm.songId AND csp.level = csm.chartId
JOIN
chuni_profile_data d ON csp.user = d.user
JOIN
aime_card a ON d.user = a.user
WHERE
a.user = ? AND csm.version = ?
ORDER BY
csp.userPlayDate DESC
`,
[user, version],
(error, results, fields) => {
if (error) {
console.error("Error retrieving best and top data:", error);
return res.status(500).json({ error: "Error retrieving best and top data" });
}
res.json(results);
}
);
}
function getChuniPlayerTeamHandler(req, res) {
const user = req.query.user;
pool1.query(
`SELECT *
FROM chuni_profile_team
`,
[user],
(error, results, fields) => {
if (error) throw error;
res.json(results);
}
);
}
function getChuniAvatarItems(req, res) {
const user = req.query.user;
pool1.query(
`
SELECT chuni_item_item.itemId as item_id, cozynet_chuni_static_accessory.category, cozynet_chuni_static_accessory.str, cozynet_chuni_static_accessory.sortName
FROM chuni_item_item
LEFT JOIN cozynet_chuni_static_accessory ON chuni_item_item.itemId = cozynet_chuni_static_accessory.id
WHERE chuni_item_item.user = ? AND chuni_item_item.itemKind = 11
`,
[user],
(error, results, fields) => {
if (error) throw error;
res.json(results);
}
);
}
function getChuniNamePlateItems(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
SELECT
chuni_item_item.itemId AS nameplateId,
cozynet_chuni_static_nameplate.str,
cozynet_chuni_static_nameplate.imagePath,
cozynet_chuni_static_nameplate.sortName
FROM
chuni_item_item
LEFT JOIN
cozynet_chuni_static_nameplate ON chuni_item_item.itemId = cozynet_chuni_static_nameplate.id
JOIN
chuni_profile_data ON chuni_profile_data.user = chuni_item_item.user
WHERE
chuni_item_item.user = ?
AND chuni_item_item.itemKind = 1
AND chuni_profile_data.version = ?
AND cozynet_chuni_static_nameplate.str IS NOT NULL
ORDER BY
chuni_item_item.id ASC;
`,
[user, version],
(error, results, fields) => {
if (error) throw error;
res.json(results);
}
);
}
function getChuniMapItems(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
SELECT
chuni_item_item.itemId AS itemId,
cozynet_chuni_static_mapicon.str,
cozynet_chuni_static_mapicon.sortName
FROM
chuni_item_item
LEFT JOIN
cozynet_chuni_static_mapicon ON chuni_item_item.itemId = cozynet_chuni_static_mapicon.id
JOIN
chuni_profile_data ON chuni_profile_data.user = chuni_item_item.user
WHERE
chuni_profile_data.user = ?
AND chuni_item_item.itemKind = 8
AND chuni_profile_data.version = ?
`,
[user, version],
(error, results, fields) => {
if (error) throw error;
res.json(results);
}
);
}
function getChuniDuelItems(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
` SELECT
chuni_item_item.itemId AS duelId,
cozynet_chuni_static_systemvoice.str AS str
FROM
chuni_item_item
LEFT JOIN
cozynet_chuni_static_systemvoice ON chuni_item_item.itemId = cozynet_chuni_static_systemvoice.id
JOIN
chuni_profile_data ON chuni_profile_data.user = chuni_item_item.user
WHERE
chuni_profile_data.user = ?
AND chuni_item_item.itemKind = 9
AND chuni_profile_data.version = ?
`,
[user, version],
(error, results, fields) => {
if (error) throw error;
res.json(results);
}
);
}
function listRivalsHandler(req, res) {
const user1 = req.query.user;
const version = req.query.version; // Get version from URL parameter
if (!user1 || !version) {
return res.status(400).json({ error: "User and version parameters are required" });
}
pool1.query(
`
SELECT cf.favId AS favId, au.username AS username
FROM chuni_item_favorite cf
JOIN aime_user au ON cf.favId = au.id
JOIN chuni_profile_data pd ON au.id = pd.user
WHERE cf.user = ? AND pd.version = ?
`,
[user1, version],
(error, results) => {
if (error) {
console.error("Error retrieving rivals:", error);
return res.status(500).json({ error: "Error retrieving rivals" });
}
res.json(results);
}
);
}
function listFavoriteSongsHandler(req, res) {
const user1 = req.query.user;
const version = req.query.version; // Get version from URL parameter
if (!user1 || !version) {
return res.status(400).json({ error: "User and version parameters are required" });
}
pool1.query(
`
SELECT DISTINCT
cf.favId AS songId,
cf.favKind,
cf.version,
sm.jacketPath,
sm.title
FROM
chuni_item_favorite cf
JOIN
chuni_static_music sm ON cf.favId = sm.songId
WHERE
cf.user = ?
AND cf.version = ?
`,
[user1, version],
(error, results) => {
if (error) {
console.error("Error retrieving rivals:", error);
return res.status(500).json({ error: "Error retrieving rivals" });
}
res.json(results);
}
);
}
function listFriendsHandler(req, res) {
const user1 = req.query.user;
const version = req.query.version; // Get version from URL parameter
if (!user1 || !version) {
return res.status(400).json({ error: "User and version parameters are required" });
}
pool1.query(
`
SELECT cf.favId AS favId, au.username AS username
FROM chuni_item_favorite cf
JOIN aime_user au ON cf.favId = au.id
JOIN chuni_profile_data pd ON au.id = pd.user
WHERE cf.user = ? AND pd.version = ?
`,
[user1, version],
(error, results) => {
if (error) {
console.error("Error retrieving rivals:", error);
return res.status(500).json({ error: "Error retrieving rivals" });
}
res.json(results);
}
);
}
function getTrophiesHandler(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
pool1.query(
`
SELECT
cst.str AS name, cst.id AS trophyId, cst.rareType
FROM
cozynet_chuni_static_trophies cst
`,
[user, version],
(error, results, fields) => {
if (error) {
console.error("Error retrieving items:", error);
return res.status(500).json({ error: "Error retrieving items" });
}
res.json(results);
}
);
}
module.exports = router;

829
chunithm/13/postRoutes.js Executable file
View File

@ -0,0 +1,829 @@
// postRoutes.js
const express = require('express');
const router = express.Router();
const pool1 = require('../../db');
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
function generateToken(userId, version, rivalCode) {
const payload = { userId, version, rivalCode }; // Include rivalCode in the payload
const secret = process.env.JWT_SECRET;
const options = { expiresIn: "12h" };
const token = jwt.sign(payload, secret, options);
return token;
}
router.post("/registerUser", registerUserHandler);
router.post("/verifyUser", verifyUserHandler);
router.post("/updateAccessCode", updateAccessCodeHandler);
router.post("/update_chuni_player_team", updateChuniPlayerTeamHandler);
router.post("/create_keychip", createKeychipHandler);
router.post("/update_chuni_profile_player_team",updateChuniProfilePlayerTeamHandler);
router.post("/update_chuni_item_duel", updateChuniItemDuelHandler);
router.post("/update_chuni_item_mapchar", updateChuniItemMapcharHandler);
router.post("/update_trophyid", updateTrophyIdHandler);
router.post("/update_nameplateId", updateNameplateIdHandler);
router.post("/updateAvatarCustomization", updateAvatarCustomizationHandler);
router.post("/update_chuni_player_rivals", updateChuniPlayerRivalsHandler);
router.post("/update_friendlist", updateChuniFriendList);
router.post("/update_chuni_favorite_music", updateChuniFavoriteMusic);
function registerUserHandler(req, res) {
const { accessCode, username, password, email } = req.body;
pool1.query(
`SELECT aime_user.id, aime_user.username, aime_user.email, aime_user.password, aime_card.user
FROM aime_user
LEFT JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.access_code = ?`,
[accessCode],
(err, rows) => {
if (err) {
console.error("Error finding user:", err);
return res.status(500).json({ error: "Failed to find user" });
}
if (rows.length === 0) {
return res.status(404).json({
error:
"Please play at least one credit before signing in to the web ui",
});
}
const existingUser = rows[0];
if (existingUser.username || existingUser.email) {
return res.status(409).json({
error: "Cannot change username, email, or password during sign-up.",
});
}
const saltRounds = 10;
bcrypt.hash(password, saltRounds, function (err, hashedPassword) {
if (err) {
console.error("Error hashing password:", err);
return res.status(500).json({
error: "Failed to hash password",
});
}
registerUser(existingUser.id, username, hashedPassword, email, res);
});
}
);
}function registerUser(userId, username, password, email, res) {
const query = "UPDATE aime_user SET username = ?, password = ?, email = ? WHERE id = ?";
pool1.query(query, [username, password, email, userId], (err, result) => {
if (err) {
console.error("Error registering user:", err);
return res.status(500).json({
error: "Username or email is already in use by another player",
});
}
if (result.affectedRows === 0) {
return res.status(404).json({ error: "User not found" });
}
// Fetch the version from chuni_profile_data
pool1.query(
"SELECT version FROM chuni_profile_data WHERE user = ? ORDER BY version DESC LIMIT 1",
[userId],
(versionError, versionResults) => {
if (versionError) {
console.error("Error fetching version:", versionError);
return res.status(500).json({ error: "Error fetching version" });
}
if (versionResults.length === 0) {
return res.status(500).json({ error: "No version found for the user" });
}
const version = versionResults[0].version;
// Check if the user already has a rival code
pool1.query(
"SELECT rival_code FROM cozynet_rival_codes WHERE id = ?",
[userId],
(rivalCodeError, rivalCodeResults) => {
if (rivalCodeError) {
console.error("Error checking for existing rival code:", rivalCodeError);
return res.status(500).json({ error: "Error checking for existing rival code" });
}
let rivalCode;
if (rivalCodeResults.length > 0) {
// Use the existing rival code
rivalCode = rivalCodeResults[0].rival_code;
} else {
// Generate a new rival code
rivalCode = generateRandomCode();
// Insert into cozynet_rival_codes table
const rivalCodeQuery = "INSERT INTO cozynet_rival_codes (id, rival_code) VALUES (?, ?)";
pool1.query(rivalCodeQuery, [userId, rivalCode], (insertError) => {
if (insertError) {
console.error("Error inserting into cozynet_rival_codes:", insertError);
return res.status(500).json({ error: "Error inserting into cozynet_rival_codes" });
}
// Generate a token with the rival code included
const token = generateToken(userId, version, rivalCode);
res.json({ message: "User registered successfully", userId, token, rivalCode });
});
}
}
);
}
);
});
}
function generateRandomCode() {
// Generate a random 8-digit code
return Math.floor(10000000 + Math.random() * 90000000);
}
function verifyUserHandler(req, res) {
const { username, password } = req.body;
pool1.query(
`SELECT aime_user.id, aime_user.password, aime_card.access_code
FROM aime_user
LEFT JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_user.username = ?`,
[username],
(err, rows) => {
if (err) {
console.error("Error verifying user:", err);
return res.status(500).json({ error: "Failed to verify user" });
}
if (rows.length === 0) {
return res.status(404).json({ error: "Invalid username" });
}
bcrypt.compare(password, rows[0].password, function (err, result) {
if (err) {
console.error("Error comparing password:", err);
return res.status(500).json({ error: "Failed to compare password" });
}
if (result) {
// Fetch the version from chuni_profile_data
pool1.query(
"SELECT version FROM chuni_profile_data WHERE user = ? ORDER BY version DESC LIMIT 1",
[rows[0].id],
(versionError, versionResults) => {
if (versionError) {
console.error("Error fetching version:", versionError);
return res.status(500).json({ error: "Error fetching version" });
}
if (versionResults.length === 0) {
return res.status(500).json({ error: "No version found for the user" });
}
const version = versionResults[0].version;
// Check if the user already has a rival code
pool1.query(
"SELECT rival_code FROM cozynet_rival_codes WHERE id = ?",
[rows[0].id],
(rivalCodeError, rivalCodeResults) => {
if (rivalCodeError) {
console.error("Error checking for existing rival code:", rivalCodeError);
return res.status(500).json({ error: "Error checking for existing rival code" });
}
let rivalCode;
if (rivalCodeResults.length > 0) {
// Use the existing rival code
rivalCode = rivalCodeResults[0].rival_code;
} else {
// Generate a new rival code
rivalCode = generateRandomCode();
// Insert into cozynet_rival_codes table
const rivalCodeQuery = "INSERT INTO cozynet_rival_codes (id, rival_code) VALUES (?, ?)";
pool1.query(rivalCodeQuery, [rows[0].id, rivalCode], (insertError) => {
if (insertError) {
console.error("Error inserting into cozynet_rival_codes:", insertError);
return res.status(500).json({ error: "Error inserting into cozynet_rival_codes" });
}
});
}
const token = generateToken(rows[0].id, version, rivalCode);
res.json({
message: "User verified successfully",
userId: rows[0].id,
accessCode: rows[0].access_code,
token,
rivalCode,
});
}
);
}
);
} else {
return res.status(404).json({ error: "Invalid password" });
}
});
})
}
// Assume you are using Express
function updateChuniPlayerTeamHandler(req, res) {
const { teamName } = req.body;
const insertQuery = `
INSERT INTO chuni_profile_team (teamName)
VALUES (?)
`;
pool1.query(insertQuery, [teamName], (error, results) => {
if (error) {
console.error("Error inserting team name:", error);
return res.status(500).send("Error inserting team name");
}
// Fetch the updated list of teams from the database
const selectQuery = `
SELECT id, teamName FROM chuni_profile_team
`;
pool1.query(selectQuery, (selectError, selectResults) => {
if (selectError) {
console.error("Error fetching team names:", selectError);
return res.status(500).send("Error fetching team names");
}
// Send the updated list of teams to the frontend
res.json({
success: true,
message: "Team name inserted successfully",
teams: selectResults,
});
});
});
}
function createKeychipHandler(req, res) {
const { arcade_nickname, name, game, namcopcbid, serial, user } = req.body;
const sqlValidateAccessCode = `
SELECT aime_user.id
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?`;
pool1.query(sqlValidateAccessCode, [user], (error, results) => {
if (error) {
console.error("SQL error during access code validation:", error);
return res.status(500).send("Error validating access code");
}
if (results.length === 0) {
return res.status(400).send("Invalid access code");
}
const userId = results[0].id;
const sqlInsertArcade = "INSERT INTO arcade (name, nickname) VALUES (?, ?)";
console.log(
"Creating new arcade entry with name:",
name,
"and nickname:",
arcade_nickname
);
pool1.query(sqlInsertArcade, [name, arcade_nickname], (error, results) => {
if (error) {
console.error("SQL error during arcade creation:", error);
return res.status(500).send("Error creating arcade");
}
const sqlFetchArcadeId = "SELECT LAST_INSERT_ID() as id";
console.log("Fetching new arcade ID...");
pool1.query(sqlFetchArcadeId, (error, results) => {
if (error) {
console.error("SQL error during fetching new arcade ID:", error);
return res.status(500).send("Error fetching new arcade ID");
}
const newArcadeId = results[0].id;
const sqlAssignMachine =
"INSERT INTO arcade_owner (user, arcade, permissions) VALUES (?, ?, ?)";
console.log("Assigning arcade", newArcadeId, "to user", userId);
pool1.query(
sqlAssignMachine,
[userId, newArcadeId, 1],
(error, results) => {
if (error) {
console.error(
"SQL error during assigning machine to user:",
error
);
return res.status(500).send("Error assigning machine to user");
}
const serialId = game === "SDEW" ? namcopcbid : serial;
const sqlCreateMachine =
"INSERT INTO machine (arcade, serial, game) VALUES (?, ?, ?)";
console.log(
"Creating machine with arcade ID:",
newArcadeId,
", serial ID:",
serialId,
"and game:",
game
);
pool1.query(
sqlCreateMachine,
[newArcadeId, serialId, game],
(error, results) => {
if (error) {
console.error("SQL error during machine creation:", error);
return res.status(500).send("Error creating machine");
}
console.log(
"Machine created successfully. Arcade and machine created successfully."
);
res.json({
success: true,
message: "Arcade and machine created successfully",
});
}
);
}
);
});
});
});
}
function updateChuniProfilePlayerTeamHandler(req, res) {
const user = req.query.user;
const { teamId } = req.body;
const updateQuery = `
UPDATE chuni_profile_data
SET
teamId = ?
WHERE user = (
SELECT aime_user.id
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?
)`;
pool1.query(updateQuery, [teamId, user], (error, results) => {
if (error) {
res.status(500).send("Error updating avatar customization");
throw error;
}
res.json({
success: true,
message: "Avatar customization updated successfully",
});
});
}
function updateChuniItemDuelHandler(req, res) {
const user = req.query.user;
const { voiceId } = req.body;
const updateQuery = `
UPDATE chuni_profile_data
SET
voiceId = ?
WHERE user = (
SELECT aime_user.id
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?
)`;
pool1.query(updateQuery, [voiceId, user], (error, results) => {
if (error) {
res.status(500).send("Error updating avatar customization");
throw error;
}
res.json({
success: true,
message: "Avatar customization updated successfully",
});
});
}
function updateChuniItemMapcharHandler(req, res) {
const user = req.query.user;
const { mapIconId } = req.body;
const updateQuery = `
UPDATE chuni_profile_data
SET
mapIconId = ?
WHERE user = (
SELECT aime_user.id
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?
)`;
pool1.query(updateQuery, [mapIconId, user], (error, results) => {
if (error) {
res.status(500).send("Error updating avatar customization");
throw error;
}
res.json({
success: true,
message: "Avatar customization updated successfully",
});
});
}
function updateTrophyIdHandler(req, res) {
const user = req.query.user;
const { trophyId } = req.body;
const updateQuery = `
UPDATE chuni_profile_data
SET
trophyId = ?
WHERE user = (
SELECT aime_user.id
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?
)`;
pool1.query(updateQuery, [trophyId, user], (error, results) => {
if (error) {
console.error("Error updating trophyId:", error);
return res.status(500).json({
success: false,
message: "Error updating trophyId",
});
}
res.json({
success: true,
message: "TrophyId updated successfully",
});
});
}
function updateNameplateIdHandler(req, res) {
const user = req.query.user;
const { nameplateId } = req.body;
const updateQuery = `
UPDATE chuni_profile_data
SET
nameplateId = ?
WHERE user = (
SELECT aime_user.id
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?
)`;
pool1.query(updateQuery, [nameplateId, user], (error, results) => {
if (error) {
res.status(500).send("Error updating avatar customization");
throw error;
}
res.json({
success: true,
message: "Avatar customization updated successfully",
});
});
}
function updateAvatarCustomizationHandler(req, res) {
const user = req.query.user;
const { avatarItem, avatarBack, avatarFace, avatarWear, avatarHead } =
req.body;
const updateQuery = `
UPDATE chuni_profile_data
SET
avatarItem = ?,
avatarBack = ?,
avatarFace = ?,
avatarWear = ?,
avatarHead = ?
WHERE user = (
SELECT aime_user.id
FROM aime_user
JOIN aime_card ON aime_user.id = aime_card.user
WHERE aime_card.user = ?
)`;
pool1.query(
updateQuery,
[avatarItem, avatarBack, avatarFace, avatarWear, avatarHead, user],
(error, results) => {
if (error) {
res.status(500).send("Error updating avatar customization");
throw error;
}
res.json({
success: true,
message: "Avatar customization updated successfully",
});
}
);
}
function updateChuniFavoriteMusic(req, res) {
// Assuming you have middleware to verify and decode the JWT and store user ID in req.user
const { user: user1, version } = req.query;
const songId = req.body.songId;
// Check if the user has already added the specified musicId as a favorite
const checkExistingFavoriteQuery = `
SELECT COUNT(*) as existingCount
FROM chuni_item_favorite
WHERE user = ? AND version = ? AND favId = ? AND favKind = 1
`;
pool1.query(checkExistingFavoriteQuery, [user1, version, songId], (existingCountError, existingCountResults) => {
if (existingCountError) {
console.error("Error checking existing favorite for user:", existingCountError);
return res.status(500).send("Error checking existing favorite");
}
const existingFavoriteCount = existingCountResults[0].existingCount;
// If the user has already added the specified musicId as a favorite, return an error
if (existingFavoriteCount > 0) {
return res.status(400).json({
success: false,
message: "User has already added this songId as a favorite.",
});
}
// Check the current count of favorites for user1
const checkCountQuery = `
SELECT COUNT(*) as favCount
FROM chuni_item_favorite
WHERE user = ? AND version = ? AND favKind = 1
`;
pool1.query(checkCountQuery, [user1, version], (countError, countResults) => {
if (countError) {
console.error("Error checking favorite count for user:", countError);
return res.status(500).send("Error checking favorite count");
}
const currentFavoriteCount = countResults[0].favCount;
// Check if the user1 has reached the limit (e.g., 20)
if (currentFavoriteCount >= 20) {
return res.status(400).json({
success: false,
message: "User has reached the maximum limit of favorites (20). Cannot add more.",
});
}
// If the limit is not reached and the musicId is not already a favorite, proceed with inserting favorite relation
const insertQuery1 = `
INSERT INTO chuni_item_favorite (user, version, favId, favKind)
VALUES (?, ?, ?, 1)
`;
console.log("Inserting favorites. user1:", user1, "songId:", songId);
pool1.query(insertQuery1, [user1, version, songId], (insertError1, results1) => {
if (insertError1) {
console.error("Error inserting favorite for user:", insertError1);
return res.status(500).send("Error inserting favorite");
}
res.json({
success: true,
message: "Favorites inserted successfully",
});
});
});
});
}
function updateChuniPlayerRivalsHandler(req, res) {
// Assuming you have middleware to verify and decode the JWT and store user ID in req.user
const { user1, version, rivalCode } = req.body;
// Check if user1 already has four rivals
const countQuery1 = `
SELECT COUNT(*) as rivalCount FROM chuni_item_favorite
WHERE user = ? AND favKind = 2
`;
pool1.query(countQuery1, [user1], (countError1, countResults1) => {
if (countError1) {
console.error("Error counting rivals for user1:", countError1);
return res.status(500).send("Error counting rivals");
}
const rivalCount1 = countResults1[0].rivalCount;
if (rivalCount1 >= 4) {
return res.status(400).json({
success: false,
message: "You already have four rivals. Unable to add more.",
});
}
// Get user2's ID based on rivalCode
const getUserIdByRivalCodeQuery = `
SELECT id FROM cozynet_rival_codes
WHERE rival_code = ?;
`;
pool1.query(getUserIdByRivalCodeQuery, [rivalCode], (error, results) => {
if (error) {
console.error("Error retrieving user id by rival code:", error);
return res.status(500).send("Error retrieving user id by rival code");
}
if (!results || results.length === 0) {
return res.status(404).json({
success: false,
message: "Rival code not found",
});
}
const user2 = results[0].id;
// Check if user2 already has four rivals
const countQuery2 = `
SELECT COUNT(*) as rivalCount FROM chuni_item_favorite
WHERE user = ? AND favKind = 2
`;
pool1.query(countQuery2, [user2], (countError2, countResults2) => {
if (countError2) {
console.error("Error counting rivals for user2:", countError2);
return res.status(500).send("Error counting rivals");
}
const rivalCount2 = countResults2[0].rivalCount;
if (rivalCount2 >= 4) {
return res.status(400).json({
success: false,
message: "The selected user already has four rivals. Unable to add more.",
});
}
// If both users have fewer than four rivals, proceed with inserting rival relations
const insertQuery1 = `
INSERT INTO chuni_item_favorite (user, version, favId, favKind)
VALUES (?, ?, ?, 2)
`;
const insertQuery2 = `
INSERT INTO chuni_item_favorite (user, version, favId, favKind)
VALUES (?, ?, ?, 2)
`;
console.log("Inserting favorites. user1:", user1, "user2:", user2);
pool1.query(insertQuery1, [user1, version, user2], (insertError1, results1) => {
if (insertError1) {
console.error("Error inserting favorite for user1:", insertError1);
return res.status(500).send("Error inserting favorite");
}
pool1.query(insertQuery2, [user2, version, user1], (insertError2, results2) => {
if (insertError2) {
console.error("Error inserting favorite for user2:", insertError2);
return res.status(500).send("Error inserting favorite");
}
res.json({
success: true,
message: "Favorites inserted successfully",
});
});
});
});
});
});
}
function updateChuniFriendList(req, res) {
// Assuming you have middleware to verify and decode the JWT and store user ID in req.user
const { user1, version, rivalCode } = req.body;
// Get user2's ID based on rivalCode
const getUserIdByRivalCodeQuery = `
SELECT id FROM cozynet_rival_codes
WHERE rival_code = ?;
`;
pool1.query(getUserIdByRivalCodeQuery, [rivalCode], (error, results) => {
if (error) {
console.error("Error retrieving user id by rival code:", error);
return res.status(500).send("Error retrieving user id by rival code");
}
if (!results || results.length === 0) {
return res.status(404).json({
success: false,
message: "Rival code not found",
});
}
const user2 = results[0].id;
// If both users have no limit on rivals, proceed with inserting rival relations
const insertQuery1 = `
INSERT INTO chuni_item_favorite (user, version, favId, favKind)
VALUES (?, ?, ?, 3)
`;
const insertQuery2 = `
INSERT INTO chuni_item_favorite (user, version, favId, favKind)
VALUES (?, ?, ?, 3)
`;
console.log("Inserting favorites. user1:", user1, "user2:", user2);
pool1.query(insertQuery1, [user1, version, user2], (insertError1, results1) => {
if (insertError1) {
console.error("Error inserting favorite for user1:", insertError1);
return res.status(500).send("Error inserting favorite");
}
pool1.query(insertQuery2, [user2, version, user1], (insertError2, results2) => {
if (insertError2) {
console.error("Error inserting favorite for user2:", insertError2);
return res.status(500).send("Error inserting favorite");
}
res.json({
success: true,
message: "Favorites inserted successfully",
});
});
});
});
}
function updateAccessCodeHandler(req, res) {
const user = req.query.user;
const version = req.query.version; // Get version from URL parameter
const { access_code } = req.body;
if (!user || !version) {
return res.status(400).json({ error: "User and version parameters are required" });
}
const updateQuery = `
UPDATE aime_card ac
JOIN chuni_profile_data pd ON ac.user = pd.user
SET ac.access_code = ?
WHERE ac.user = ? AND pd.version = ?;
`;
pool1.query(updateQuery, [access_code, user, version], (error, results) => {
if (error) {
console.error("Error updating access code:", error);
return res.status(500).json({
success: false,
message: "Error updating access code",
error: error.message,
});
}
// Check if any rows were affected
if (results.affectedRows === 0) {
return res.status(404).json({
success: false,
message: "User not found with the specified user ID and version",
});
}
res.json({
success: true,
message: "Access code updated successfully",
});
});
}
module.exports = router;

14
db.js Executable file
View File

@ -0,0 +1,14 @@
const mysql = require("mysql2");
const dbUsername = process.env.user;
const dbPassword = process.env.password;
const dbHost = process.env.host;
const dbDatabase = process.env.database;
const pool = mysql.createPool({
host: dbHost,
user: dbUsername,
password: dbPassword,
database: dbDatabase,
port: process.env.port,
});
module.exports = pool;

1787
package-lock.json generated Executable file

File diff suppressed because it is too large Load Diff

30
package.json Executable file
View File

@ -0,0 +1,30 @@
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start:dev": "nodemon --env-file=.env.development app.js",
"start:prod": "nodemon --env-file=.env.production app.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"date-fns": "^2.30.0",
"date-fns-tz": "^2.0.0",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-jwt": "^8.4.1",
"express-session": "^1.17.3",
"find-config": "^1.0.0",
"fs": "^0.0.1-security",
"jsonwebtoken": "^9.0.2",
"mysql2": "^3.6.3",
"promisify": "^0.0.3",
"util": "^0.12.5"
}
}