diff --git a/api/crazyAuth.js b/api/crazyAuth.js index 0ba0361..ad34d8e 100644 --- a/api/crazyAuth.js +++ b/api/crazyAuth.js @@ -60,15 +60,15 @@ export default async function handler(req, res) { const newUser = new User({ crazyGamesId: userId, username: finalUsername, secret }); await newUser.save(); - try { - if (process.env.DISCORD_WEBHOOK) { - const hook = new Webhook(process.env.DISCORD_WEBHOOK); - hook.setUsername("WorldGuessr"); - hook.send(`🎮 **${finalUsername}** has joined WorldGuessr from CrazyGames!`); - } - } catch (error) { - console.error('Error sending discord webhook', error); - } + // try { + // if (process.env.DISCORD_WEBHOOK) { + // const hook = new Webhook(process.env.DISCORD_WEBHOOK); + // hook.setUsername("WorldGuessr"); + // hook.send(`🎮 **${finalUsername}** has joined WorldGuessr from CrazyGames!`); + // } + // } catch (error) { + // console.error('Error sending discord webhook', error); + // } return res.status(200).json({ secret: newUser.secret, username: newUser.username }); } diff --git a/api/eloRank.js b/api/eloRank.js index 351d059..e611056 100644 --- a/api/eloRank.js +++ b/api/eloRank.js @@ -26,11 +26,9 @@ export default async function handler(req, res) { return res.status(404).json({ message: 'User not found' }); } - console.time('get user rank', user.username); const rank = (await User.countDocuments({ elo: { $gt: user.elo }, banned: false }).cache(2000)) + 1; - console.timeEnd('get user rank', user.username); // Return the user's elo and rank return res.status(200).json({ elo: user.elo, rank, league: getLeague(user.elo), @@ -48,7 +46,6 @@ export async function setElo(accountId, newElo, gameData) { // gamedata -> {draw:true|false, winner: true|false} try { - console.log('Setting elo', accountId, newElo, 'old elo', gameData.oldElo, 'gameData', gameData); await User.updateOne({ _id: accountId }, { elo: newElo, $inc: { duels_played: 1, duels_wins: gameData.winner ? 1 : 0, duels_losses: gameData.winner ? 0 : 1, duels_tied: gameData.draw ? 1 : 0, diff --git a/api/googleAuth.js b/api/googleAuth.js index 1f45f17..86235b1 100644 --- a/api/googleAuth.js +++ b/api/googleAuth.js @@ -18,11 +18,9 @@ export default async function handler(req, res) { return res.status(400).json({ error: 'Invalid' }); } - console.time('findUser'); const userDb = await User.findOne({ secret, }).select("secret username email staff canMakeClues supporter").cache(120); - console.timeEnd('findUser'); if (userDb) { output = { secret: userDb.secret, username: userDb.username, email: userDb.email, staff: userDb.staff, canMakeClues: userDb.canMakeClues, supporter: userDb.supporter }; return res.status(200).json(output); @@ -58,7 +56,6 @@ export default async function handler(req, res) { const existingUser = await User.findOne({ email }); let secret = null; if (!existingUser) { - console.log("User does not exist, creating a new user", email); secret = createUUID(); const newUser = new User({ email, secret }); await newUser.save(); diff --git a/api/leaderboard.js b/api/leaderboard.js index e84d981..b4332c1 100644 --- a/api/leaderboard.js +++ b/api/leaderboard.js @@ -28,7 +28,6 @@ export default async function handler(req, res) { } const xp = req.query.mode === 'xp'; - console.log('leaderboard', myUsername, pastDay, xp); if(xp) { try { diff --git a/api/map/mapHome.js b/api/map/mapHome.js index b4b4866..69eccc9 100644 --- a/api/map/mapHome.js +++ b/api/map/mapHome.js @@ -33,9 +33,7 @@ export default async function handler(req, res) { let user; if(secret) { - console.time('findUser'); user = await User.findOne({ secret: secret }); - console.timeEnd('findUser'); if(typeof secret !== 'string') { return res.status(400).json({ message: 'Invalid input' }); } @@ -83,7 +81,6 @@ export default async function handler(req, res) { // find maps made by user if(user) { // created_at, slug, name, hearts,plays, description_short, map_creator_name, _id, in_review, official, accepted, reject_reason, resubmittable, locationsCnt - console.time('findMyMaps'); let myMaps = await Map.find({ created_by: user._id.toString() }).select({ created_at: 1, slug: 1, @@ -111,7 +108,6 @@ export default async function handler(req, res) { if(!map.map_creator_name) { owner = await User.findById(map.created_by); // save map creator name - console.log('updating map creator name', map._id, owner.username, map.name); map.map_creator_name = owner.username; await map.save(); @@ -122,7 +118,6 @@ export default async function handler(req, res) { })); likedMapsSendable.sort((a,b) => b.created_at - a.created_at); if(likedMapsSendable.length > 0) response.likedMaps = likedMapsSendable; - console.timeEnd('findMyMaps'); } response.countryMaps = Object.values(officialCountryMaps).map((map) => ({ @@ -152,11 +147,8 @@ export default async function handler(req, res) { // retrieve from db let maps = []; if(method === "recent") { - console.time('findRecentMaps'); maps = await Map.find({ accepted: true }).sort({ created_at: -1 }).limit(100); - console.timeEnd('findRecentMaps'); } else if(method === "popular") { - console.time('findPopularMaps'); maps = await Map.find({ accepted: true }) .select({ locationsCnt: { $size: "$data" }, created_at: 1, @@ -176,10 +168,8 @@ export default async function handler(req, res) { // sort and limit to 100 maps = maps.sort((a,b) => b.hearts - a.hearts).slice(0,100); - console.timeEnd('findPopularMaps'); } else if(method === "spotlight") { maps = await Map.find({ accepted: true, spotlight: true }).limit(100).allowDiskUse(true); - console.log('spotlight maps', maps.length); } let sendableMaps = await Promise.all(maps.map(async (map) => { @@ -187,7 +177,6 @@ export default async function handler(req, res) { if(!map.map_creator_name && map.data) { owner = await User.findById(map.created_by); // save map creator name - console.log('updating map creator name', map._id, owner.username, map.name); map.map_creator_name = owner.username; await map.save(); } else { diff --git a/api/map/publicData.js b/api/map/publicData.js index 9300292..67dbc71 100644 --- a/api/map/publicData.js +++ b/api/map/publicData.js @@ -6,7 +6,6 @@ import msToTime from "../../components/msToTime.js"; export default async function handler(req, res) { const slug = req.query.slug; - console.log("Getting map data for", slug); const secret = await getServerSecret(req); const session = {}; if(secret) { diff --git a/api/map/searchMap.js b/api/map/searchMap.js index a1b4bb9..7fcc91a 100644 --- a/api/map/searchMap.js +++ b/api/map/searchMap.js @@ -25,7 +25,6 @@ export default async function searchMaps(req, res) { } let hearted_maps = user ? user.hearted_maps : null; - console.log('searching maps for query:', query); // Validate the search query if (!query || query.length < 3) { @@ -36,7 +35,6 @@ export default async function searchMaps(req, res) { query = query.replace(/[^a-zA-Z0-9\s]/g, ''); try { - console.time('searchMaps'); // Find maps that match the search query in either name, short description, or author name let maps = await Map.find({ accepted: true, @@ -58,7 +56,6 @@ export default async function searchMaps(req, res) { owner = null; } // save map creator name - console.log('updating map creator name', map._id, owner.username, map.name); map.map_creator_name = owner.username; await map.save(); } else{ @@ -67,7 +64,6 @@ export default async function searchMaps(req, res) { return sendableMap(map, owner, hearted_maps?hearted_maps.has(map._id.toString()):false, user?.staff, map.created_by === user?._id.toString()); })); - console.timeEnd('searchMaps'); res.status(200).json(sendableMaps); } catch (error) { diff --git a/api/publicAccount.js b/api/publicAccount.js index 7550a24..5938a68 100644 --- a/api/publicAccount.js +++ b/api/publicAccount.js @@ -22,9 +22,7 @@ export default async function handler(req, res) { try { // Find user by the provided token - console.time('findUser'); const user = id ? await User.findById(id).cache(120) : await User.findOne({ secret }).cache(120); - console.timeEnd('findUser'); if (!user) { return res.status(404).json({ message: 'User not found' }); } diff --git a/api/setName.js b/api/setName.js index 372de53..11ebdab 100644 --- a/api/setName.js +++ b/api/setName.js @@ -46,15 +46,15 @@ export default async function handler(req, res) { user.username = username; await user.save(); - try { - if(process.env.DISCORD_WEBHOOK) { - const hook = new Webhook(process.env.DISCORD_WEBHOOK); - hook.setUsername("WorldGuessr"); - hook.send(`🎉 **${username}** has joined WorldGuessr!`); - } - } catch (error) { - console.error('Discord webhook failed', error); - } + // try { + // if(process.env.DISCORD_WEBHOOK) { + // const hook = new Webhook(process.env.DISCORD_WEBHOOK); + // hook.setUsername("WorldGuessr"); + // hook.send(`🎉 **${username}** has joined WorldGuessr!`); + // } + // } catch (error) { + // console.error('Discord webhook failed', error); + // } res.status(200).json({ success: true }); } catch (error) { diff --git a/components/home.js b/components/home.js index b2049a2..c1d7983 100644 --- a/components/home.js +++ b/components/home.js @@ -1977,7 +1977,7 @@ setTimeout(() => { setFriendsModal(true)} loginQueued={loginQueued} setLoginQueued={setLoginQueued} inGame={multiplayerState?.inGame || screen === "singleplayer"} openAccountModal={() => setAccountModalOpen(true)} session={session} reloadBtnPressed={reloadBtnPressed} backBtnPressed={backBtnPressed} setGameOptionsModalShown={setGameOptionsModalShown} onNavbarPress={() => onNavbarLogoPress()} gameOptions={gameOptions} screen={screen} multiplayerState={multiplayerState} shown={!multiplayerState?.gameData?.public && !leagueModal} /> {/* ELO/League button */} -{screen === "home" && !mapModal && session && session?.token?.secret && !inCrazyGames && !session?.token?.supporter && ( +{screen === "home" && !mapModal && session && session?.token?.secret && ( diff --git a/cron.js b/cron.js index 9804c2c..662b3c4 100644 --- a/cron.js +++ b/cron.js @@ -13,73 +13,24 @@ import cityGen from './serverUtils/cityGen.js'; configDotenv(); -let dbEnabled = false; -if (!process.env.MONGODB) { - console.log("[MISSING-ENV WARN] MONGODB env variable not set".yellow); - dbEnabled = false; -} else { - // Connect to MongoDB - if (mongoose.connection.readyState !== 1) { - try { - await mongoose.connect(process.env.MONGODB); - console.log('[INFO] Database Connected'); - dbEnabled = true; - } catch (error) { - console.error('[ERROR] Database connection failed!'.red, error.message); - console.log(error); - dbEnabled = false; - } - } -} - -async function calculateRanks() { - if (!dbEnabled) return; - console.log('Calculating ranks'); - console.time('Updated ranks'); - - const users = await User.find({ banned: false }).select('elo lastEloHistoryUpdate').sort({ elo: -1 }); - - // Prepare bulk operations - const bulkOps = []; - - for (let i = 0; i < users.length; i++) { - const user = users[i]; - - // Prepare the update operation for the current user - if((Date.now() - user.lastEloHistoryUpdate > 24 * 60 * 60 * 1000)) { - bulkOps.push({ - updateOne: { - filter: { _id: user._id }, - update: { - - $push: { elo_history: { elo: user.elo, time: Date.now() } }, - $set: { lastEloHistoryUpdate: Date.now() }, - $set: { elo_today: 0 }, - - }, - }, - }); - } - } - - // Execute bulk operations - if (bulkOps.length > 0) { - await User.bulkWrite(bulkOps); - } - - console.timeEnd('Updated ranks'); - console.log('bulkOps', bulkOps.length); -} - -// Calculate ranks every 12 hours -// setInterval(calculateRanks, 60 * 60 * 1000 * 3); -function recursiveCalculateRanks() { - calculateRanks().then(() => { - setTimeout(recursiveCalculateRanks, 12 * 60 * 60 * 1000); - }); -} -recursiveCalculateRanks(); - +// let dbEnabled = false; +// if (!process.env.MONGODB) { +// console.log("[MISSING-ENV WARN] MONGODB env variable not set".yellow); +// dbEnabled = false; +// } else { +// // Connect to MongoDB +// if (mongoose.connection.readyState !== 1) { +// try { +// await mongoose.connect(process.env.MONGODB); +// console.log('[INFO] Database Connected'); +// dbEnabled = true; +// } catch (error) { +// console.error('[ERROR] Database connection failed!'.red, error.message); +// console.log(error); +// dbEnabled = false; +// } +// } +// } let countryLocations = {}; @@ -134,9 +85,6 @@ const generateBalancedLocations = async () => { } - // log average number of locatiosn per country - const total = Object.values(countryLocations).reduce((acc, val) => acc + val.length, 0); - console.log('Average locations per country:', total / countries.length); } catch (error) { console.error('Error generating locations', error); diff --git a/pages/leaderboard/index.js b/pages/leaderboard/index.js index 0acde0a..6e0bfab 100644 --- a/pages/leaderboard/index.js +++ b/pages/leaderboard/index.js @@ -343,6 +343,15 @@ const Leaderboard = ({ }) => {
)} + + {/* elo past day doesnt work, display message */} + {pastDay && useElo && ( +

+ ELO past day leaderboard is not working at the moment. + We are working on fixing it. +
+

+ )}
diff --git a/server.js b/server.js index 0a3f1b0..68b47d3 100644 --- a/server.js +++ b/server.js @@ -42,6 +42,7 @@ var app = express(); import cors from 'cors'; import cityGen from './serverUtils/cityGen.js'; import User from './models/User.js'; +import { currentDate } from './ws/ws.js'; app.use(cors()); app.use(bodyParser.json({limit: '5mb'})); @@ -117,7 +118,6 @@ async function updateRecentPlays() { const map = await MapModel.findOne({ slug: mapSlug }); if(map && map.accepted) { map.plays += recentPlays[mapSlug]; - console.log('Updating plays for', mapSlug, 'by', recentPlays[mapSlug]); await map.save(); } } @@ -148,7 +148,6 @@ const generateClueLocations = async () => { // shuffle uniqueLatLongs = new Set([...uniqueLatLongs].sort(() => Math.random() - 0.5)); - console.log('Generating clue locations', uniqueLatLongs.size); // populate clueLocations // ex format: {"lat":17.90240017665545,"long":102.7868538747363,"country":"TH"} clueLocations = []; @@ -198,7 +197,6 @@ app.get('/allCountries.json', (req, res) => { // Fetch this from cron localhost:3003/allCountries.json if(Date.now() - lastAllCountriesCacheUpdate < 60 * 1000 && allCountriesCache.length > 0) { res.json({ ready: true, locations: allCountriesCache }); - console.log('Serving allCountries.json from cache'); } else { fetch('http://localhost:3003/allCountries.json') @@ -211,7 +209,7 @@ app.get('/allCountries.json', (req, res) => { res.json(data); }) .catch(error => { - console.error('Error fetching allCountries.json', error); + console.error('Error fetching allCountries.json', error, currentDate()); res.status(500).json({ ready: false, message: 'Error fetching allCountries.json' }); }); } @@ -232,7 +230,6 @@ app.get('/countryLocations/:country', (req, res) => { } if(countryLocations[req.params.country].cacheUpdate && Date.now() - countryLocations[req.params.country].cacheUpdate < 60 * 1000) { - console.log('Serving countryLocations from cache'); return res.json({ ready: countryLocations[req.params.country].locations.length>0, locations: countryLocations[req.params.country].locations }); } else { @@ -247,7 +244,7 @@ fetch('http://localhost:3003/countryLocations/'+req.params.country) res.json(data); }) .catch(error => { - console.error('Error fetching countryLocations', error); + console.error('Error fetching countryLocations', error, currentDate()); res.status(500).json({ ready: false, message: 'Error fetching countryLocations' }); }); } @@ -255,9 +252,7 @@ fetch('http://localhost:3003/countryLocations/'+req.params.country) app.get('/mapLocations/:slug', async (req, res) => { const slug = req.params.slug; - console.time('mapLocations '+slug); const map = await MapModel.findOne({ slug }).cache(10000) - console.timeEnd('mapLocations '+slug); if (!map) { return res.status(404).json({ message: 'Map not found' }); } diff --git a/ws/classes/Game.js b/ws/classes/Game.js index 4f8575b..844dfe0 100644 --- a/ws/classes/Game.js +++ b/ws/classes/Game.js @@ -365,7 +365,6 @@ export default class Game { // get n random from the list let locs = map.data; if(locs.length < this.rounds) { - console.error('Not enough locations in map', this.location); // send error to all players this.sendAllPlayers({ type: 'toast', diff --git a/ws/classes/Player.js b/ws/classes/Player.js index cf6922a..e6d1c2b 100644 --- a/ws/classes/Player.js +++ b/ws/classes/Player.js @@ -29,7 +29,6 @@ export default class Player { setElo(newElo, gameData) { if(!this.accountId) return; - console.log('Setting elo', this.id, this.username, newElo, 'old elo', this.elo); this.elo = newElo; setElo(this.accountId, newElo, gameData); @@ -166,7 +165,6 @@ export default class Player { message: 'Failed to login', failedToLogin: true }); - console.log('Failed to verify user', this.id); this.ws.close(); } } diff --git a/ws/ws.js b/ws/ws.js index fb99c3e..8769672 100644 --- a/ws/ws.js +++ b/ws/ws.js @@ -37,6 +37,11 @@ const playersInQueue = new Map(); let maintenanceMode = false; let dbEnabled = true; +//get current date &time in cst +export function currentDate() { + return new Date().toLocaleString("en-US", { timeZone: "America/Chicago" }); +} + // location generator let allLocations = []; const generateMainLocations = async () => { @@ -45,13 +50,13 @@ const generateMainLocations = async () => { const data = await res.json(); allLocations = data.locations??[]; }).catch((e) => { - console.log('Failed to load locations', e); + console.error('Failed to load locations', e, currentDate()); }); }; -generateMainLocations(); +setTimeout(generateMainLocations, 2000); setInterval(generateMainLocations, 1000 * 10); // helpers @@ -91,11 +96,11 @@ function log(...args) { console.log(new Date().toLocaleString("en-US", { timeZone: "America/Chicago" }), ...args); // if(!dev) { - if(process.env.DISCORD_WEBHOOK_WS) { - const hook = new Webhook(process.env.DISCORD_WEBHOOK_WS); - hook.setUsername("Logs"+(dev ? ' - Dev' : '')); - hook.send(args.join(' ')); - } + // if(process.env.DISCORD_WEBHOOK_WS) { + // const hook = new Webhook(process.env.DISCORD_WEBHOOK_WS); + // hook.setUsername("Logs"+(dev ? ' - Dev' : '')); + // hook.send(args.join(' ')); + // } // } } @@ -139,10 +144,10 @@ function log(...args) { blockedAt((time, stack) => { - if(time > 1000) console.log(`Blocked for ${time}ms, operation started here:`, JSON.stringify(stack, null, 2)); + if(time > 1000) console.log(`Blocked for ${time}ms, operation started here:`, JSON.stringify(stack, null, 2), currentDate()); }) function stop(reason) { - console.error('Stopping server', reason); + console.error('Stopping server', reason, currentDate()); } process.on('SIGTERM', () => { @@ -157,13 +162,13 @@ process.on('SIGINT', () => { process.on('uncaughtException', (err) => { - console.error('Uncaught exception', err); + console.error('Uncaught exception', err, currentDate()); stop('uncaughtException'); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { - console.error('Unhandled rejection', reason, promise); + console.error('Unhandled rejection', reason, promise, currentDate()); stop('unhandledRejection'); }); // uWebSockets.js @@ -260,7 +265,7 @@ if (process.env.MAINTENANCE_SECRET) { setCorsHeaders(res); res.writeHeader('Content-Type', 'text/htmk'); res.end('kick count: ' + cnt+'
banned ip: '+ip+'
all ips: '+[...bannedIps].join('
')); - console.log('Banned ip', ip); + console.log('Banned ip', ip, 'kicked', cnt, currentDate()); }); app.get(`/unbanIp/${maintenanceSecret}/:ip`, (res, req) => { const ip = req.getParameter(0); @@ -269,7 +274,7 @@ if (process.env.MAINTENANCE_SECRET) { setCorsHeaders(res); res.writeHeader('Content-Type', 'text/plain'); res.end('ok'); - console.log('Unbanned ip', ip); + console.log('Unbanned ip', ip, currentDate()); }); app.get(`/getIpCounts/${maintenanceSecret}`, (res) => { const ipCounts = [...ipConnectionCount.entries()].map(([ip, cnt]) => ({ ip, cnt })); @@ -301,7 +306,7 @@ app.ws('/wg', { } if([...bannedIps].some((bannedIp) => ip.includes(bannedIp)) || ipConnectionCount.get(ip) && ipConnectionCount.get(ip) > 100) { - console.log('Banned ip tried to connect', ip); + console.log('Banned ip tried to connect', ip, currentDate()); res.writeStatus('403 Forbidden'); res.end(); return; @@ -319,7 +324,6 @@ app.ws('/wg', { const player = new Player(ws, id, ip); if(ip !== 'unknown') ipConnectionCount.set(ip, (ipConnectionCount.get(ip) || 0) + 1); - console.log('New connection', id, ip); player.send({ type: 't', @@ -372,7 +376,6 @@ app.ws('/wg', { } if ((json.type === 'publicDuel') && !player.gameId) { - console.log('public duel requested by', player.username, player.ip); if(player.banned) { player.send({ type: 'toast', @@ -442,7 +445,6 @@ app.ws('/wg', { if (json.type === 'leaveQueue' && player.inQueue) { player.inQueue = false; - console.log('public duel leave by', player.username); playersInQueue.delete(player.id); } @@ -645,7 +647,6 @@ app.ws('/wg', { // if(!npz) npz = false; // if(!showRoadName) showRoadName = false; - console.log("Creating game", gameId); const game = new Game(gameId, false); // game.timePerRound = timePerRound * 1000; @@ -676,7 +677,6 @@ app.ws('/wg', { // make sure player is host if(game.players[player.id].host) { let { rounds, timePerRound, location, nm, npz, showRoadName, displayLocation } = json; - console.log("setPrivateGameOptions", rounds, timePerRound, location, nm, npz, showRoadName); rounds = Number(rounds); // maxDist no longer required-> can be pulled from community map @@ -1228,11 +1228,11 @@ app.ws('/wg', { } - // remaining players in queue check if wait was longer than 30 seconds, in that case set their elo range to infinity + // remaining players in queue check if wait was longer than 10 seconds, in that case set their elo range to infinity for(const playerId of playersInQueue) { const player = players.get(playerId[0]); const queueData = playerId[1]; - if(!queueData.guest && Date.now() - queueData.queueTime > 30000) { + if(!queueData.guest && Date.now() - queueData.queueTime > 10000) { playersInQueue.set(playerId[0], { ...queueData, min: 0, max: 10000, queueTime: Date.now() }); player.send({