Clément Wolf 1 vuosi sitten
vanhempi
commit
14cffffc56
7 muutettua tiedostoa jossa 74 lisäystä ja 6 poistoa
  1. 2 0
      api.js
  2. 20 2
      collection.js
  3. 6 1
      glicko.js
  4. 25 1
      map_scanner.js
  5. 9 1
      ranked.js
  6. 5 0
      user.js
  7. 7 1
      website.js

+ 2 - 0
api.js

@@ -52,6 +52,8 @@ async function osu_fetch(url, options) {
     oauth_token = null;
     await promisify(setTimeout)(1000);
     return await osu_fetch(url, options);
+  } else if (res.status == 404) {
+    throw new Error('Not found');
   } else {
     const json = await res.json();
     return json;

+ 20 - 2
collection.js

@@ -26,11 +26,29 @@ async function select_next_map() {
   }
 
   let new_map = null;
+  let tries = 0;
   do {
+    tries++;
+
     const mapset = random_from(this.data.collection.beatmapsets);
     const map_id = random_from(mapset.beatmaps).id;
-    new_map = await get_map_info(map_id);
-  } while (this.recently_played.includes(new_map.id));
+
+    try {
+      new_map = await get_map_info(map_id);
+    } catch (err) {
+      if (err.message == 'Invalid map ID') {
+        continue;
+      } else {
+        catch_sentry_exception(err);
+        continue;
+      }
+    }
+  } while (this.recently_played.includes(new_map.id) && tries < 25);
+
+  if (tries == 25) {
+    await this.send('Couldn\'t select any map. Is the collection too small?');
+    return;
+  }
 
   const flavor = `${MAP_TYPES[new_map.ranked]} ${new_map.stars.toFixed(2)}*, ${Math.round(new_map.overall_pp)}pp`;
   const map_name = `[https://osu.ppy.sh/beatmaps/${new_map.id} ${new_map.name}]`;

+ 6 - 1
glicko.js

@@ -11,6 +11,7 @@ import {update_division} from './discord_updates.js';
 import Config from './util/config.js';
 import {get_user_by_id} from './user.js';
 import {capture_sentry_exception} from './util/helpers.js';
+import {get_map_info} form './glicko.js';
 
 
 const RANK_DIVISIONS = [
@@ -160,11 +161,15 @@ async function save_game_and_update_rating(lobby, game) {
   const rating_columns = ['osu_rating', 'taiko_rating', 'catch_rating', 'mania_rating'];
 
   try {
+    // Make sure we have the map in the database
+    const map_id = game.beatmap.id || lobby.beatmap_id;
+    await get_map_info(map_id, null);
+
     db.prepare(`INSERT INTO game (
       game_id, match_id, start_time, end_time, beatmap_id,
       play_mode, scoring_type, team_type, mods
     ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(
-        game.id, lobby.id, Date.parse(game.start_time).valueOf(), tms, game.beatmap.id,
+        game.id, lobby.id, Date.parse(game.start_time).valueOf(), tms, map_id,
         game.mode_int, game.scoring_type, game.team_type, JSON.stringify(game.mods),
     );
   } catch (err) {

+ 25 - 1
map_scanner.js

@@ -7,8 +7,32 @@ import {osu_fetch} from './api.js';
 import db from './database.js';
 
 
+// Promise queue to make sure we're only scanning one map at a time (eliminating race conditions)
+const queue = [];
+async function run_queue_loop() {
+  while (queue.length > 0) {
+    try {
+      const res = await _get_map_info(queue[0].map_id, queue[0].api_res);
+      queue[0].resolve(res);
+    } catch (err) {
+      queue[0].reject(err);
+    }
+
+    queue.shift();
+  }
+}
+
+function get_map_info(map_id, api_res) {
+  return new Promise((resolve, reject) => {
+    queue.push({map_id, api_res, resolve, reject});
+
+    // First item in the queue: init queue loop
+    if (queue.length == 1) run_queue_loop();
+  });
+}
+
 // Get metadata and pp from map ID (downloads it if not already downloaded)
-async function get_map_info(map_id, api_res) {
+async function _get_map_info(map_id, api_res) {
   const map = db.prepare(`SELECT * FROM map WHERE map_id = ?`).get(map_id);
   if (map) {
     return map;

+ 9 - 1
ranked.js

@@ -95,6 +95,8 @@ async function select_next_map() {
   let new_map = null;
   for (let i = 0; i < 10; i++) {
     new_map = select_map();
+    if (!new_map) break;
+
     if (!this.data.recent_maps.includes(new_map.map_id)) {
       break;
     }
@@ -243,7 +245,13 @@ async function init_lobby(lobby) {
           return;
         }
       } catch (err) {
-        capture_sentry_exception(err);
+        if (err.name == 'SyntaxError') {
+          await lobby.send('osu!api is having issues, scores ignored. More info: https://status.ppy.sh/');
+        } else {
+          capture_sentry_exception(err);
+        }
+
+        return;
       }
 
       lobby.data.last_game_id = game.id;

+ 5 - 0
user.js

@@ -11,6 +11,11 @@ async function init_user(user_id, user_data) {
     user_data = res.users[0];
   }
 
+  if (!user_data) {
+    console.error('Invalid user ID', user_id, '- WTF?');
+    throw new Error('Invalid user ID');
+  }
+
   // Migrate old profiles
   let discord_user_id = null;
   const old_profile = db.prepare(`SELECT discord_id FROM old_discord_user WHERE osu_id = ?`).get(user_id);

+ 7 - 1
website.js

@@ -45,6 +45,7 @@ async function listen() {
     }
 
     res.clearCookie('token');
+    res.set('X-Osu-ID', '0');
     next();
   });
 
@@ -256,8 +257,13 @@ async function listen() {
   app.get('/u/:userId', async (req, http_res) => {
     if (req.get('User-Agent').indexOf('Discordbot') != -1) {
       const user = await get_user_by_id(req.params.userId, false);
+      if (!user) {
+        http_res.status(404).send('');
+        return;
+      }
+
       const info = get_user_ranks(user.user_id);
-      if (!user || !info) {
+      if (!info) {
         http_res.status(404).send('');
         return;
       }