From 1759772831e8a7269b5e7e8aa19d8ae96ad9da3a Mon Sep 17 00:00:00 2001 From: LoveEevee Date: Sat, 7 Mar 2020 04:48:30 +0300 Subject: [PATCH] ScoreStorage: Use hashes instead of song titles --- app.py | 42 +++++++++--------- public/src/js/assets.js | 1 + public/src/js/importsongs.js | 10 ++++- public/src/js/lib/md5.min.js | 10 +++++ public/src/js/loader.js | 14 +++++- public/src/js/scoresheet.js | 5 ++- public/src/js/scorestorage.js | 72 +++++++++++++++++++------------ public/src/js/songselect.js | 80 +++++++++++++++++++++-------------- 8 files changed, 150 insertions(+), 84 deletions(-) create mode 100644 public/src/js/lib/md5.min.js diff --git a/app.py b/app.py index d288d98..d1ecbe3 100644 --- a/app.py +++ b/app.py @@ -25,6 +25,7 @@ def get_db(): db = getattr(g, '_database', None) if db is None: db = g._database = sqlite3.connect(DATABASE) + db.row_factory = sqlite3.Row return db @@ -96,8 +97,8 @@ def route_api_preview(): if not song_row: abort(400) - song_type = song_row[0][12] - prev_path = make_preview(song_id, song_type, song_row[0][15]) + song_type = song_row[0]['type'] + prev_path = make_preview(song_id, song_type, song_row[0]['preview']) if not prev_path: return redirect(get_config()['songs_baseurl'] + '%s/main.mp3' % song_id) @@ -112,43 +113,44 @@ def route_api_songs(): raw_categories = query_db('select * from categories') categories = {} for cat in raw_categories: - categories[cat[0]] = cat[1] + categories[cat['id']] = cat['title'] raw_song_skins = query_db('select * from song_skins') song_skins = {} for skin in raw_song_skins: - song_skins[skin[0]] = {'name': skin[1], 'song': skin[2], 'stage': skin[3], 'don': skin[4]} + song_skins[skin[0]] = {'name': skin['name'], 'song': skin['song'], 'stage': skin['stage'], 'don': skin['don']} songs_out = [] for song in songs: - song_id = song[0] - song_type = song[12] - preview = song[15] + song_id = song['id'] + song_type = song['type'] + preview = song['preview'] - category_out = categories[song[11]] if song[11] in categories else "" - song_skin_out = song_skins[song[14]] if song[14] in song_skins else None + category_out = categories[song['category']] if song['category'] in categories else '' + song_skin_out = song_skins[song['skin_id']] if song['skin_id'] in song_skins else None maker = None - if song[17] == 0: + if song['maker_id'] == 0: maker = 0 - elif song[17] and song[17] > 0: - maker = {'name': song[18], 'url': song[19], 'id': song[17]} + elif song['maker_id'] and song['maker_id'] > 0: + maker = {'name': song['name'], 'url': song['url'], 'id': song['maker_id']} songs_out.append({ 'id': song_id, - 'title': song[1], - 'title_lang': song[2], - 'subtitle': song[3], - 'subtitle_lang': song[4], + 'title': song['title'], + 'title_lang': song['title_lang'], + 'subtitle': song['subtitle'], + 'subtitle_lang': song['subtitle_lang'], 'stars': [ - song[5], song[6], song[7], song[8], song[9] + song['easy'], song['normal'], song['hard'], song['oni'], song['ura'] ], 'preview': preview, 'category': category_out, 'type': song_type, - 'offset': song[13], + 'offset': song['offset'], 'song_skin': song_skin_out, - 'volume': song[16], - 'maker': maker + 'volume': song['volume'], + 'maker': maker, + 'hash': song['hash'] }) return jsonify(songs_out) diff --git a/public/src/js/assets.js b/public/src/js/assets.js index 45c5e93..b202a13 100644 --- a/public/src/js/assets.js +++ b/public/src/js/assets.js @@ -1,6 +1,7 @@ var assets = { "js": [ "lib/fontdetect.min.js", + "lib/md5.min.js", "loadsong.js", "parseosu.js", "titlescreen.js", diff --git a/public/src/js/importsongs.js b/public/src/js/importsongs.js index 6fb7ea1..d9dba60 100644 --- a/public/src/js/importsongs.js +++ b/public/src/js/importsongs.js @@ -274,6 +274,13 @@ if(songObj.stars.length !== 0){ this.songs[index] = songObj } + var hash = md5.base64(event.target.result).slice(0, -2) + songObj.hash = hash + scoreStorage.songTitles[songObj.title] = hash + var score = scoreStorage.get(hash) + if(score){ + score.title = songObj.title + } }).catch(() => {}) reader.readAsText(file, "sjis") return promise @@ -297,7 +304,8 @@ subtitle_lang: osu.metadata.Artist || osu.metadata.ArtistUnicode, preview: osu.generalInfo.PreviewTime / 1000, stars: [null, null, null, parseInt(osu.difficulty.overallDifficulty) || 1], - music: this.otherFiles[dir + osu.generalInfo.AudioFilename.toLowerCase()] || "muted" + music: this.otherFiles[dir + osu.generalInfo.AudioFilename.toLowerCase()] || "muted", + hash: md5.base64(event.target.result).slice(0, -2) } var filename = file.name.slice(0, file.name.lastIndexOf(".")) var title = osu.metadata.TitleUnicode || osu.metadata.Title diff --git a/public/src/js/lib/md5.min.js b/public/src/js/lib/md5.min.js new file mode 100644 index 0000000..7418ff8 --- /dev/null +++ b/public/src/js/lib/md5.min.js @@ -0,0 +1,10 @@ +/** + * [js-md5]{@link https://github.com/emn178/js-md5} + * + * @namespace md5 + * @version 0.7.3 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2014-2017 + * @license MIT + */ +!function(){"use strict";function t(t){if(t)d[0]=d[16]=d[1]=d[2]=d[3]=d[4]=d[5]=d[6]=d[7]=d[8]=d[9]=d[10]=d[11]=d[12]=d[13]=d[14]=d[15]=0,this.blocks=d,this.buffer8=l;else if(a){var r=new ArrayBuffer(68);this.buffer8=new Uint8Array(r),this.blocks=new Uint32Array(r)}else this.blocks=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.h0=this.h1=this.h2=this.h3=this.start=this.bytes=this.hBytes=0,this.finalized=this.hashed=!1,this.first=!0}var r="input is invalid type",e="object"==typeof window,i=e?window:{};i.JS_MD5_NO_WINDOW&&(e=!1);var s=!e&&"object"==typeof self,h=!i.JS_MD5_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;h?i=global:s&&(i=self);var f=!i.JS_MD5_NO_COMMON_JS&&"object"==typeof module&&module.exports,o="function"==typeof define&&define.amd,a=!i.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,n="0123456789abcdef".split(""),u=[128,32768,8388608,-2147483648],y=[0,8,16,24],c=["hex","array","digest","buffer","arrayBuffer","base64"],p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),d=[],l;if(a){var A=new ArrayBuffer(68);l=new Uint8Array(A),d=new Uint32Array(A)}!i.JS_MD5_NO_NODE_JS&&Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),!a||!i.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&ArrayBuffer.isView||(ArrayBuffer.isView=function(t){return"object"==typeof t&&t.buffer&&t.buffer.constructor===ArrayBuffer});var b=function(r){return function(e){return new t(!0).update(e)[r]()}},v=function(){var r=b("hex");h&&(r=w(r)),r.create=function(){return new t},r.update=function(t){return r.create().update(t)};for(var e=0;e>2]|=t[f]<>6,u[h++]=128|63&s):s<55296||s>=57344?(u[h++]=224|s>>12,u[h++]=128|s>>6&63,u[h++]=128|63&s):(s=65536+((1023&s)<<10|1023&t.charCodeAt(++f)),u[h++]=240|s>>18,u[h++]=128|s>>12&63,u[h++]=128|s>>6&63,u[h++]=128|63&s);else for(h=this.start;f>2]|=s<>2]|=(192|s>>6)<>2]|=(128|63&s)<=57344?(n[h>>2]|=(224|s>>12)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<>2]|=(240|s>>18)<>2]|=(128|s>>12&63)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<=64?(this.start=h-64,this.hash(),this.hashed=!0):this.start=h}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296<<0,this.bytes=this.bytes%4294967296),this}},t.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var t=this.blocks,r=this.lastByteIndex;t[r>>2]|=u[3&r],r>=56&&(this.hashed||this.hash(),t[0]=t[16],t[16]=t[1]=t[2]=t[3]=t[4]=t[5]=t[6]=t[7]=t[8]=t[9]=t[10]=t[11]=t[12]=t[13]=t[14]=t[15]=0),t[14]=this.bytes<<3,t[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},t.prototype.hash=function(){var t,r,e,i,s,h,f=this.blocks;this.first?r=((r=((t=((t=f[0]-680876937)<<7|t>>>25)-271733879<<0)^(e=((e=(-271733879^(i=((i=(-1732584194^2004318071&t)+f[1]-117830708)<<12|i>>>20)+t<<0)&(-271733879^t))+f[2]-1126478375)<<17|e>>>15)+i<<0)&(i^t))+f[3]-1316259209)<<22|r>>>10)+e<<0:(t=this.h0,r=this.h1,e=this.h2,r=((r+=((t=((t+=((i=this.h3)^r&(e^i))+f[0]-680876936)<<7|t>>>25)+r<<0)^(e=((e+=(r^(i=((i+=(e^t&(r^e))+f[1]-389564586)<<12|i>>>20)+t<<0)&(t^r))+f[2]+606105819)<<17|e>>>15)+i<<0)&(i^t))+f[3]-1044525330)<<22|r>>>10)+e<<0),r=((r+=((t=((t+=(i^r&(e^i))+f[4]-176418897)<<7|t>>>25)+r<<0)^(e=((e+=(r^(i=((i+=(e^t&(r^e))+f[5]+1200080426)<<12|i>>>20)+t<<0)&(t^r))+f[6]-1473231341)<<17|e>>>15)+i<<0)&(i^t))+f[7]-45705983)<<22|r>>>10)+e<<0,r=((r+=((t=((t+=(i^r&(e^i))+f[8]+1770035416)<<7|t>>>25)+r<<0)^(e=((e+=(r^(i=((i+=(e^t&(r^e))+f[9]-1958414417)<<12|i>>>20)+t<<0)&(t^r))+f[10]-42063)<<17|e>>>15)+i<<0)&(i^t))+f[11]-1990404162)<<22|r>>>10)+e<<0,r=((r+=((t=((t+=(i^r&(e^i))+f[12]+1804603682)<<7|t>>>25)+r<<0)^(e=((e+=(r^(i=((i+=(e^t&(r^e))+f[13]-40341101)<<12|i>>>20)+t<<0)&(t^r))+f[14]-1502002290)<<17|e>>>15)+i<<0)&(i^t))+f[15]+1236535329)<<22|r>>>10)+e<<0,r=((r+=((i=((i+=(r^e&((t=((t+=(e^i&(r^e))+f[1]-165796510)<<5|t>>>27)+r<<0)^r))+f[6]-1069501632)<<9|i>>>23)+t<<0)^t&((e=((e+=(t^r&(i^t))+f[11]+643717713)<<14|e>>>18)+i<<0)^i))+f[0]-373897302)<<20|r>>>12)+e<<0,r=((r+=((i=((i+=(r^e&((t=((t+=(e^i&(r^e))+f[5]-701558691)<<5|t>>>27)+r<<0)^r))+f[10]+38016083)<<9|i>>>23)+t<<0)^t&((e=((e+=(t^r&(i^t))+f[15]-660478335)<<14|e>>>18)+i<<0)^i))+f[4]-405537848)<<20|r>>>12)+e<<0,r=((r+=((i=((i+=(r^e&((t=((t+=(e^i&(r^e))+f[9]+568446438)<<5|t>>>27)+r<<0)^r))+f[14]-1019803690)<<9|i>>>23)+t<<0)^t&((e=((e+=(t^r&(i^t))+f[3]-187363961)<<14|e>>>18)+i<<0)^i))+f[8]+1163531501)<<20|r>>>12)+e<<0,r=((r+=((i=((i+=(r^e&((t=((t+=(e^i&(r^e))+f[13]-1444681467)<<5|t>>>27)+r<<0)^r))+f[2]-51403784)<<9|i>>>23)+t<<0)^t&((e=((e+=(t^r&(i^t))+f[7]+1735328473)<<14|e>>>18)+i<<0)^i))+f[12]-1926607734)<<20|r>>>12)+e<<0,r=((r+=((h=(i=((i+=((s=r^e)^(t=((t+=(s^i)+f[5]-378558)<<4|t>>>28)+r<<0))+f[8]-2022574463)<<11|i>>>21)+t<<0)^t)^(e=((e+=(h^r)+f[11]+1839030562)<<16|e>>>16)+i<<0))+f[14]-35309556)<<23|r>>>9)+e<<0,r=((r+=((h=(i=((i+=((s=r^e)^(t=((t+=(s^i)+f[1]-1530992060)<<4|t>>>28)+r<<0))+f[4]+1272893353)<<11|i>>>21)+t<<0)^t)^(e=((e+=(h^r)+f[7]-155497632)<<16|e>>>16)+i<<0))+f[10]-1094730640)<<23|r>>>9)+e<<0,r=((r+=((h=(i=((i+=((s=r^e)^(t=((t+=(s^i)+f[13]+681279174)<<4|t>>>28)+r<<0))+f[0]-358537222)<<11|i>>>21)+t<<0)^t)^(e=((e+=(h^r)+f[3]-722521979)<<16|e>>>16)+i<<0))+f[6]+76029189)<<23|r>>>9)+e<<0,r=((r+=((h=(i=((i+=((s=r^e)^(t=((t+=(s^i)+f[9]-640364487)<<4|t>>>28)+r<<0))+f[12]-421815835)<<11|i>>>21)+t<<0)^t)^(e=((e+=(h^r)+f[15]+530742520)<<16|e>>>16)+i<<0))+f[2]-995338651)<<23|r>>>9)+e<<0,r=((r+=((i=((i+=(r^((t=((t+=(e^(r|~i))+f[0]-198630844)<<6|t>>>26)+r<<0)|~e))+f[7]+1126891415)<<10|i>>>22)+t<<0)^((e=((e+=(t^(i|~r))+f[14]-1416354905)<<15|e>>>17)+i<<0)|~t))+f[5]-57434055)<<21|r>>>11)+e<<0,r=((r+=((i=((i+=(r^((t=((t+=(e^(r|~i))+f[12]+1700485571)<<6|t>>>26)+r<<0)|~e))+f[3]-1894986606)<<10|i>>>22)+t<<0)^((e=((e+=(t^(i|~r))+f[10]-1051523)<<15|e>>>17)+i<<0)|~t))+f[1]-2054922799)<<21|r>>>11)+e<<0,r=((r+=((i=((i+=(r^((t=((t+=(e^(r|~i))+f[8]+1873313359)<<6|t>>>26)+r<<0)|~e))+f[15]-30611744)<<10|i>>>22)+t<<0)^((e=((e+=(t^(i|~r))+f[6]-1560198380)<<15|e>>>17)+i<<0)|~t))+f[13]+1309151649)<<21|r>>>11)+e<<0,r=((r+=((i=((i+=(r^((t=((t+=(e^(r|~i))+f[4]-145523070)<<6|t>>>26)+r<<0)|~e))+f[11]-1120210379)<<10|i>>>22)+t<<0)^((e=((e+=(t^(i|~r))+f[2]+718787259)<<15|e>>>17)+i<<0)|~t))+f[9]-343485551)<<21|r>>>11)+e<<0,this.first?(this.h0=t+1732584193<<0,this.h1=r-271733879<<0,this.h2=e-1732584194<<0,this.h3=i+271733878<<0,this.first=!1):(this.h0=this.h0+t<<0,this.h1=this.h1+r<<0,this.h2=this.h2+e<<0,this.h3=this.h3+i<<0)},t.prototype.hex=function(){this.finalize();var t=this.h0,r=this.h1,e=this.h2,i=this.h3;return n[t>>4&15]+n[15&t]+n[t>>12&15]+n[t>>8&15]+n[t>>20&15]+n[t>>16&15]+n[t>>28&15]+n[t>>24&15]+n[r>>4&15]+n[15&r]+n[r>>12&15]+n[r>>8&15]+n[r>>20&15]+n[r>>16&15]+n[r>>28&15]+n[r>>24&15]+n[e>>4&15]+n[15&e]+n[e>>12&15]+n[e>>8&15]+n[e>>20&15]+n[e>>16&15]+n[e>>28&15]+n[e>>24&15]+n[i>>4&15]+n[15&i]+n[i>>12&15]+n[i>>8&15]+n[i>>20&15]+n[i>>16&15]+n[i>>28&15]+n[i>>24&15]},t.prototype.toString=t.prototype.hex,t.prototype.digest=function(){this.finalize();var t=this.h0,r=this.h1,e=this.h2,i=this.h3;return[255&t,t>>8&255,t>>16&255,t>>24&255,255&r,r>>8&255,r>>16&255,r>>24&255,255&e,e>>8&255,e>>16&255,e>>24&255,255&i,i>>8&255,i>>16&255,i>>24&255]},t.prototype.array=t.prototype.digest,t.prototype.arrayBuffer=function(){this.finalize();var t=new ArrayBuffer(16),r=new Uint32Array(t);return r[0]=this.h0,r[1]=this.h1,r[2]=this.h2,r[3]=this.h3,t},t.prototype.buffer=t.prototype.arrayBuffer,t.prototype.base64=function(){for(var t,r,e,i="",s=this.array(),h=0;h<15;)t=s[h++],r=s[h++],e=s[h++],i+=p[t>>>2]+p[63&(t<<4|r>>>4)]+p[63&(r<<2|e>>>6)]+p[63&e];return t=s[h],i+=p[t>>>2]+p[t<<4&63]+"=="};var _=v();f?module.exports=_:(i.md5=_,o&&define(function(){return _}))}(); \ No newline at end of file diff --git a/public/src/js/loader.js b/public/src/js/loader.js index ec19352..3a5cd75 100644 --- a/public/src/js/loader.js +++ b/public/src/js/loader.js @@ -204,9 +204,21 @@ class Loader{ } settings = new Settings() - scoreStorage = new ScoreStorage() pageEvents.setKbd() + scoreStorage = new ScoreStorage() + for(var i in assets.songsDefault){ + var song = assets.songsDefault[i] + if(!song.hash){ + song.hash = song.title + } + scoreStorage.songTitles[song.title] = song.hash + var score = scoreStorage.get(song.hash) + if(score){ + score.title = song.title + } + } + Promise.all(this.promises).then(() => { this.canvasTest.drawAllImages().then(result => { perf.allImg = result diff --git a/public/src/js/scoresheet.js b/public/src/js/scoresheet.js index 3e62440..cf9887b 100644 --- a/public/src/js/scoresheet.js +++ b/public/src/js/scoresheet.js @@ -863,8 +863,9 @@ class Scoresheet{ saveScore(){ if(!this.controller.autoPlayEnabled && this.resultsObj.points > 0){ var title = this.controller.selectedSong.originalTitle + var hash = this.controller.selectedSong.hash var difficulty = this.resultsObj.difficulty - var oldScore = scoreStorage.get(title, difficulty) + var oldScore = scoreStorage.get(hash, difficulty, true) if(!oldScore || oldScore.points <= this.resultsObj.points){ var crown = "" if(this.controller.game.rules.clearReached(this.resultsObj.gauge)){ @@ -877,7 +878,7 @@ class Scoresheet{ delete this.resultsObj.title delete this.resultsObj.difficulty delete this.resultsObj.gauge - scoreStorage.add(title, difficulty, this.resultsObj) + scoreStorage.add(hash, difficulty, this.resultsObj, true, title) } } this.scoreSaved = true diff --git a/public/src/js/scorestorage.js b/public/src/js/scorestorage.js index f06e729..87820f5 100644 --- a/public/src/js/scorestorage.js +++ b/public/src/js/scorestorage.js @@ -1,6 +1,7 @@ class ScoreStorage{ constructor(){ this.scores = {} + this.songTitles = {} this.difficulty = ["oni", "ura", "hard", "normal", "easy"] this.scoreKeys = ["points", "good", "ok", "bad", "maxCombo", "drumroll"] this.crownValue = ["", "silver", "gold"] @@ -15,8 +16,8 @@ class ScoreStorage{ this.scoreStrings = JSON.parse(localScores) } }catch(e){} - for(var song in this.scoreStrings){ - var scoreString = this.scoreStrings[song] + for(var hash in this.scoreStrings){ + var scoreString = this.scoreStrings[hash] var songAdded = false if(typeof scoreString === "string" && scoreString){ var diffArray = scoreString.split(";") @@ -36,18 +37,18 @@ class ScoreStorage{ score[name] = value } if(!songAdded){ - this.scores[song] = [] + this.scores[hash] = {title: null} songAdded = true } - this.scores[song][this.difficulty[i]] = score + this.scores[hash][this.difficulty[i]] = score } } } } } save(){ - for(var song in this.scores){ - this.writeString(song) + for(var hash in this.scores){ + this.writeString(hash) } this.write() } @@ -56,8 +57,8 @@ class ScoreStorage{ localStorage.setItem("scoreStorage", JSON.stringify(this.scoreStrings)) }catch(e){} } - writeString(song){ - var score = this.scores[song] + writeString(hash){ + var score = this.scores[hash] var diffArray = [] var notEmpty = false for(var i = this.difficulty.length; i--;){ @@ -77,25 +78,39 @@ class ScoreStorage{ diffArray.unshift("") } } - this.scoreStrings[song] = diffArray.join(";") + this.scoreStrings[hash] = diffArray.join(";") } - get(song, difficulty){ + titleHash(song){ + if(song in this.songTitles){ + return this.songTitles[song] + }else{ + return song + } + } + get(song, difficulty, isHash){ if(!song){ return this.scores - }else if(song in this.scores){ + }else{ + var hash = isHash ? song : this.titleHash(song) if(difficulty){ - return this.scores[song][difficulty] + if(hash in this.scores){ + return this.scores[hash][difficulty] + } }else{ - return this.scores[song] + return this.scores[hash] } } } - add(song, difficulty, scoreObject){ - if(!(song in this.scores)){ - this.scores[song] = {} + add(song, difficulty, scoreObject, isHash, setTitle){ + var hash = isHash ? song : this.titleHash(song) + if(!(hash in this.scores)){ + this.scores[hash] = {} } - this.scores[song][difficulty] = scoreObject - this.writeString(song) + if(setTitle){ + this.scores[hash].title = setTitle + } + this.scores[hash][difficulty] = scoreObject + this.writeString(hash) this.write() } template(){ @@ -106,28 +121,29 @@ class ScoreStorage{ } return template } - remove(song, difficulty){ - if(song in this.scores){ + remove(song, difficulty, isHash){ + var hash = isHash ? song : this.titleHash(song) + if(hash in this.scores){ if(difficulty){ - if(difficulty in this.scores[song]){ - delete this.scores[song][difficulty] + if(difficulty in this.scores[hash]){ + delete this.scores[hash][difficulty] var noDiff = true for(var i in this.difficulty){ - if(this.scores[song][this.difficulty[i]]){ + if(this.scores[hash][this.difficulty[i]]){ noDiff = false break } } if(noDiff){ - delete this.scores[song] - delete this.scoreStrings[song] + delete this.scores[hash] + delete this.scoreStrings[hash] }else{ - this.writeString(song) + this.writeString(hash) } } }else{ - delete this.scores[song] - delete this.scoreStrings[song] + delete this.scores[hash] + delete this.scoreStrings[hash] } this.write() } diff --git a/public/src/js/songselect.js b/public/src/js/songselect.js index cb320da..6bc9d16 100644 --- a/public/src/js/songselect.js +++ b/public/src/js/songselect.js @@ -125,7 +125,8 @@ class SongSelect{ music: song.music, volume: song.volume, maker: song.maker, - canJump: true + canJump: true, + hash: song.hash || song.title }) } this.songs.sort((a, b) => { @@ -746,7 +747,8 @@ class SongSelect{ "type": selectedSong.type, "offset": selectedSong.offset, "songSkin": selectedSong.songSkin, - "stars": selectedSong.stars[difficulty] + "stars": selectedSong.stars[difficulty], + "hash": selectedSong.hash }, autoplay, multiplayer, touch) } toOptions(moveBy){ @@ -1256,6 +1258,15 @@ class SongSelect{ this.currentSongCache.clear() } + if(selectedWidth === this.songAsset.width){ + this.drawSongCrown({ + ctx: ctx, + song: currentSong, + x: winW / 2 - selectedWidth / 2 + xOffset, + y: songTop + this.songAsset.height - selectedHeight + }) + } + this.draw.songFrame({ ctx: ctx, x: winW / 2 - selectedWidth / 2 + xOffset, @@ -1387,7 +1398,7 @@ class SongSelect{ } var drawDifficulty = (ctx, i, currentUra) => { if(currentSong.stars[i] || currentUra){ - var score = scoreStorage.get(currentSong.originalTitle) + var score = scoreStorage.get(currentSong.hash) var crownDiff = currentUra ? "ura" : this.difficultyId[i] var crownType = "" if(score && score[crownDiff]){ @@ -1926,35 +1937,7 @@ class SongSelect{ drawClosedSong(config){ var ctx = config.ctx - if(!config.song.action && config.song.originalTitle){ - var score = scoreStorage.get(config.song.originalTitle) - for(var i = this.difficultyId.length; i--;){ - var diff = this.difficultyId[i] - if(!score){ - break - } - if(config.song.stars[i] && score[diff] && score[diff].crown){ - this.draw.crown({ - ctx: ctx, - type: score[diff].crown, - x: config.x + this.songAsset.width / 2, - y: config.y - 13, - scale: 0.3, - ratio: this.ratio / this.pixelRatio - }) - this.draw.diffIcon({ - ctx: ctx, - diff: i, - x: config.x + this.songAsset.width / 2 + 8, - y: config.y - 8, - scale: diff === "hard" || diff === "normal" ? 0.45 : 0.5, - border: 6.5, - small: true - }) - break - } - } - } + this.drawSongCrown(config) config.width = this.songAsset.width config.height = this.songAsset.height config.border = this.songAsset.border @@ -2004,6 +1987,39 @@ class SongSelect{ } } + drawSongCrown(config){ + if(!config.song.action && config.song.hash){ + var ctx = config.ctx + var score = scoreStorage.get(config.song.hash) + for(var i = this.difficultyId.length; i--;){ + var diff = this.difficultyId[i] + if(!score){ + break + } + if(config.song.stars[i] && score[diff] && score[diff].crown){ + this.draw.crown({ + ctx: ctx, + type: score[diff].crown, + x: config.x + this.songAsset.width / 2, + y: config.y - 13, + scale: 0.3, + ratio: this.ratio / this.pixelRatio + }) + this.draw.diffIcon({ + ctx: ctx, + diff: i, + x: config.x + this.songAsset.width / 2 + 8, + y: config.y - 8, + scale: diff === "hard" || diff === "normal" ? 0.45 : 0.5, + border: 6.5, + small: true + }) + break + } + } + } + } + startPreview(loadOnly){ var currentSong = this.songs[this.selectedSong] var id = currentSong.id