mirror of
https://github.com/yuukiwww/taiko-web.git
synced 2024-10-22 17:05:49 +02:00
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:
parent
c5ce5104f1
commit
180ec58adb
@ -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(", "))
|
||||
}
|
||||
|
@ -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]))
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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(() => {
|
||||
|
@ -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()
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -308,8 +308,8 @@
|
||||
w: _w, h: _h,
|
||||
radius: 11
|
||||
})
|
||||
ctx.fill()
|
||||
|
||||
ctx.fill()
|
||||
|
||||
this.draw.layeredText({
|
||||
ctx: ctx,
|
||||
text: selectedSong.category,
|
||||
|
Loading…
Reference in New Issue
Block a user