ScoreStorage: Use hashes instead of song titles

This commit is contained in:
LoveEevee 2020-03-07 04:48:30 +03:00
parent 0221c977c8
commit 1759772831
8 changed files with 150 additions and 84 deletions

42
app.py
View File

@ -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)

View File

@ -1,6 +1,7 @@
var assets = {
"js": [
"lib/fontdetect.min.js",
"lib/md5.min.js",
"loadsong.js",
"parseosu.js",
"titlescreen.js",

View File

@ -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

10
public/src/js/lib/md5.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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

View File

@ -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){
if(difficulty){
return this.scores[song][difficulty]
}else{
return this.scores[song]
var hash = isHash ? song : this.titleHash(song)
if(difficulty){
if(hash in this.scores){
return this.scores[hash][difficulty]
}
}else{
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()
}

View File

@ -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