Changed look of song loading, fix custom game assets and song skins, fix auth error

- Change the way a selected song appears while it is loading the metadata
- Fix custom taikowebskin
- Fix importing custom game assets (local only)
- Get the oauth token again on auth error
This commit is contained in:
LoveEevee 2020-10-31 14:47:42 +03:00
parent c5ce5104f1
commit 180ec58adb
10 changed files with 103 additions and 59 deletions

View File

@ -138,7 +138,7 @@
if(gamepads[i]){
var gamepadDiag = []
gamepadDiag.push(gamepads[i].id)
gamepadDiag.push("buttons: " + gamepads[i].buttons.length)
gamepadDiag.push("buttons: " + gamepads[i].buttons.length)
gamepadDiag.push("axes: " + gamepads[i].axes.length)
diag.push("Gamepad #" + (i + 1) + ": " + gamepadDiag.join(", "))
}

View File

@ -1,3 +1,9 @@
function readFile(file, arrayBuffer, encoding){
var reader = new FileReader()
var promise = pageEvents.load(reader).then(event => event.target.result)
reader[arrayBuffer ? "readAsArrayBuffer" : "readAsText"](file, encoding)
return promise
}
class RemoteFile{
constructor(url){
this.url = url
@ -22,13 +28,14 @@ class RemoteFile{
}
read(encoding){
if(encoding){
return this.arrayBuffer().then(response =>
new TextDecoder(encoding).decode(response)
)
return this.blob().then(blob => readFile(blob, false, encoding))
}else{
return loader.ajax(this.url)
}
}
blob(){
return this.arrayBuffer().then(response => new Blob([response]))
}
}
class LocalFile{
constructor(file){
@ -38,16 +45,13 @@ class LocalFile{
this.name = file.name
}
arrayBuffer(){
var reader = new FileReader()
var promise = pageEvents.load(reader).then(event => event.target.result)
reader.readAsArrayBuffer(this.file)
return promise
return readFile(this.file, true)
}
read(encoding){
var reader = new FileReader()
var promise = pageEvents.load(reader).then(event => event.target.result)
reader.readAsText(this.file, encoding)
return promise
return readFile(this.file, false, encoding)
}
blob(){
return Promise.resolve(this.file)
}
}
class GdriveFile{
@ -62,16 +66,14 @@ class GdriveFile{
}
read(encoding){
if(encoding){
return this.arrayBuffer().then(response => {
var reader = new FileReader()
var promise = pageEvents.load(reader).then(event => event.target.result)
reader.readAsText(new Blob([response]), encoding)
return promise
})
return this.blob().then(blob => readFile(blob, false, encoding))
}else{
return gpicker.downloadFile(this.id)
}
}
blob(){
return this.arrayBuffer().then(response => new Blob([response]))
}
}
class CachedFile{
constructor(contents, oldFile){
@ -87,4 +89,7 @@ class CachedFile{
read(encoding){
return this.arrayBuffer()
}
blob(){
return this.arrayBuffer().then(response => new Blob([response]))
}
}

View File

@ -40,12 +40,12 @@ class Controller{
this.parsedSongData = new ParseOsu(songData, selectedSong.difficulty, selectedSong.stars, selectedSong.offset)
}
this.offset = this.parsedSongData.soundOffset
var maxCombo = this.parsedSongData.circles.filter(circle => ["don", "ka", "daiDon", "daiKa"].indexOf(circle.type) > -1 && (!circle.branch || circle.branch.name == "master")).length
if (maxCombo >= 50) {
var comboVoices = ["v_combo_50"].concat([...Array(Math.floor(maxCombo/100)).keys()].map(i => "v_combo_" + (i + 1)*100))
var comboVoices = ["v_combo_50"].concat(Array.from(Array(Math.min(50, Math.floor(maxCombo / 100))), (d, i) => "v_combo_" + ((i + 1) * 100)))
var promises = []
comboVoices.forEach(name => {
if (!assets.sounds[name + "_p1"]) {
promises.push(loader.loadSound(name + ".wav", snd.sfxGain).then(sound => {
@ -54,7 +54,7 @@ class Controller{
}))
}
})
Promise.all(promises)
}

View File

@ -136,10 +136,12 @@ class CustomSongs{
}
}
songsLoaded(songs){
var length = songs.length
assets.songs = songs
assets.customSongs = true
assets.customSelected = 0
if(songs){
var length = songs.length
assets.songs = songs
assets.customSongs = true
assets.customSelected = 0
}
assets.sounds["se_don"].play()
this.clean()
setTimeout(() => {

View File

@ -84,7 +84,7 @@ class Gpicker{
gapi.client.load("drive", "v3").then(resolve, reject)
))
}
getToken(lockedCallback){
getToken(lockedCallback=()=>{}){
if(this.oauthToken){
return Promise.resolve()
}
@ -156,13 +156,31 @@ class Gpicker{
.build()
.setVisible(true)
}
downloadFile(id, arrayBuffer){
return this.queue().then(() =>
loader.ajax(this.filesUrl + id + "?alt=media", request => {
downloadFile(id, arrayBuffer, retry){
var url = this.filesUrl + id + "?alt=media"
return this.queue().then(this.getToken.bind(this)).then(() =>
loader.ajax(url, request => {
if(arrayBuffer){
request.responseType = "arraybuffer"
}
request.setRequestHeader("Authorization", "Bearer " + this.oauthToken)
}, true).then(event => {
var request = event.target
var reject = () => Promise.reject(`${url} (${request.status})`)
if(request.status === 200){
return request.response
}else if(request.status === 401 && !retry){
return new Response(request.response).json().then(response => {
var e = response.error
if(e && e.errors[0].reason === "authError"){
delete this.oauthToken
return this.downloadFile(id, arrayBuffer, true)
}else{
return reject()
}
}, reject)
}
return reject()
})
)
}

View File

@ -7,7 +7,7 @@
this.otherFiles = otherFiles || {}
this.songs = []
this.stylesheet = []
this.songTitle = {}
this.songTitle = this.otherFiles.songTitle || {}
this.uraRegex = /\s*[\(]裏[\)]$/
this.courseTypes = {
"easy": 0,
@ -42,6 +42,7 @@
"bg_stage_2": ".song-stage-2",
"bg_stage_3": ".song-stage-3"
}
this.comboVoices = ["v_combo_50"].concat(Array.from(Array(50), (d, i) => "v_combo_" + ((i + 1) * 100)))
}
load(files){
var extensionRegex = /\.[^\/]+$/
@ -66,13 +67,13 @@
file: file,
index: i
})
}else if(!this.limited && (name === "genre.ini" || name === "box.def" || name === "songtitle.txt")){
}else if(!this.limited && (name === "genre.ini" || name === "box.def") || name === "songtitle.txt"){
var level = (file.path.match(/\//g) || []).length
metaFiles.push({
file: file,
level: (level * 2) + (name === "genre.ini" ? 1 : 0)
})
}else if(!this.limited && path.indexOf("/taiko-web assets/") !== -1){
}else if(!this.limited && (path.indexOf("/taiko-web assets/") !== -1 || path.indexOf("taiko-web assets/") === 0)){
if(!(name in this.assetFiles)){
this.assetFiles[name] = file
}
@ -401,12 +402,13 @@
for(let name in this.assetFiles){
let id = this.getFilename(name)
var file = this.assetFiles[name]
var index = name.lastIndexOf(".")
if(name === "vectors.json"){
promises.push(file.read().then(() => response => {
promises.push(file.read().then(response => {
vectors = JSON.parse(response)
}))
}
if(assets.img.indexOf(name) !== -1){
if(name.endsWith(".png")){
let image = document.createElement("img")
promises.push(pageEvents.load(image).then(() => {
if(id in this.assetSelectors){
@ -415,9 +417,12 @@
}
}))
image.id = name
image.src = URL.createObjectURL(file)
image.src = URL.createObjectURL(file.blob())
loader.assetsDiv.appendChild(image)
assets.image[id].parentNode.removeChild(assets.image[id])
var oldImage = assets.image[id]
if(oldImage && oldImage.parentNode){
oldImage.parentNode.removeChild(oldImage)
}
assets.image[id] = image
}
if(assets.audioSfx.indexOf(name) !== -1){
@ -440,6 +445,13 @@
assets.sounds[id].clean()
promises.push(this.loadSound(file, name, snd.sfxLoudGain))
}
if(this.comboVoices.indexOf(id) !== -1){
promises.push(snd.sfxGain.load(file).then(sound => {
assets.sounds[id] = sound
assets.sounds[id + "_p1"] = assets.sounds[id].copy(snd.sfxGainL)
assets.sounds[id + "_p2"] = assets.sounds[id].copy(snd.sfxGainR)
}))
}
}
return Promise.all(promises)
}
@ -525,8 +537,11 @@
if(this.songs.length){
if(this.limited){
assets.otherFiles = this.otherFiles
assets.otherFiles.songTitle = this.songTitle
}
return Promise.resolve(this.songs)
}else if(Object.keys(this.assetFiles).length){
return Promise.resolve()
}else{
return Promise.reject("cancel")
}
@ -571,6 +586,7 @@
delete this.songs
delete this.tjaFiles
delete this.osuFiles
delete this.assetFiles
delete this.otherFiles
}
}

View File

@ -433,16 +433,19 @@ class Loader{
this.screen.innerHTML = assets.pages[name]
this.screen.classList[patternBg ? "add" : "remove"]("pattern-bg")
}
ajax(url, customRequest){
ajax(url, customRequest, customResponse){
var request = new XMLHttpRequest()
request.open("GET", url)
var promise = pageEvents.load(request).then(() => {
if(request.status === 200){
return request.response
}else{
return Promise.reject(`${url} (${request.status})`)
}
})
var promise = pageEvents.load(request)
if(!customResponse){
promise = promise.then(() => {
if(request.status === 200){
return request.response
}else{
return Promise.reject(`${url} (${request.status})`)
}
})
}
if(customRequest){
customRequest(request)
}

View File

@ -108,7 +108,9 @@ class LoadSong{
return this.scaleImg(img, filename, prefix, force)
}), songObj.custom ? filename + ".png" : skinBase + filename + ".png")
if(songObj.custom){
img.src = URL.createObjectURL(song.songSkin[filename + ".png"])
this.addPromise(song.songSkin[filename + ".png"].blob().then(blob => {
img.src = URL.createObjectURL(blob)
}))
}else{
img.src = skinBase + filename + ".png"
}

View File

@ -1090,7 +1090,7 @@ class SongSelect{
}
if(screen === "song"){
if(this.songs[this.selectedSong].courses){
if(this.songs[this.selectedSong].courses && !this.songs[this.selectedSong].unloaded){
selectedWidth = this.songAsset.selectedWidth
}
@ -1101,11 +1101,11 @@ class SongSelect{
var resize2 = changeSpeed - resize
var scroll = resize2 - resize - scrollDelay * 2
var elapsed = ms - this.state.moveMS
if(this.state.catJump || (this.state.move && ms > this.state.moveMS + resize2 - scrollDelay)){
var isJump = this.state.catJump
var previousSelectedSong = this.selectedSong
if(!isJump){
this.playSound("se_ka", 0, this.lastMoveBy)
this.selectedSong = this.mod(this.songs.length, this.selectedSong + this.state.move)
@ -1165,7 +1165,7 @@ class SongSelect{
if(this.songs[this.selectedSong].action !== "back"){
var cat = this.songs[this.selectedSong].originalCategory
this.drawBackground(cat)
this.drawBackground(cat)
}
}
if(this.state.moveMS && ms < this.state.moveMS + changeSpeed){
@ -1291,7 +1291,7 @@ class SongSelect{
highlight = 1
}
var selectedSkin = this.songSkin.selected
if(screen === "title" || screen === "titleFadeIn" || this.state.locked === 3){
if(screen === "title" || screen === "titleFadeIn" || this.state.locked === 3 || currentSong.unloaded){
selectedSkin = currentSong.skin
highlight = 2
}else if(songSelMoving){
@ -2278,7 +2278,7 @@ class SongSelect{
}else{
this.songSelect.style.backgroundImage = "url('" + assets.image["bg_genre_def"].src + "')"
}
}
}
drawClosedSong(config){
var ctx = config.ctx
@ -2476,20 +2476,18 @@ class SongSelect{
currentSong.chart = new CachedFile(data, file)
return importSongs[currentSong.type === "tja" ? "addTja" : "addOsu"]({
file: currentSong.chart,
index: 0
index: currentSong.id
})
}).then(() => {
var imported = importSongs.songs[0]
var imported = importSongs.songs[currentSong.id]
importSongs.clean()
imported.id = currentSong.id
imported.order = currentSong.order
delete imported.song_skin
songObj.preview_time = imported.preview
var index = assets.songs.findIndex(song => song.id === currentSong.id)
if(index !== -1){
assets.songs[index] = imported
}
this.songs[selectedSong] = this.addSong(imported)
this.state.moveMS = this.getMS() - this.songSelecting.speed * this.songSelecting.resize
if(imported.music && currentId === this.previewId){
return snd.previewGain.load(imported.music).then(sound => {
imported.sound = sound

View File

@ -308,8 +308,8 @@
w: _w, h: _h,
radius: 11
})
ctx.fill()
ctx.fill()
this.draw.layeredText({
ctx: ctx,
text: selectedSong.category,