mirror of
https://github.com/yuukiwww/taiko-web.git
synced 2024-10-22 17:05:49 +02:00
ImportSongs: Custom assets
This commit is contained in:
parent
7b9de52d06
commit
da40fd58ff
1
app.py
1
app.py
@ -6,7 +6,6 @@ import json
|
||||
import sqlite3
|
||||
import re
|
||||
import os
|
||||
import urlparse
|
||||
from flask import Flask, g, jsonify, render_template, request, abort, redirect
|
||||
from ffmpy import FFmpeg
|
||||
|
||||
|
@ -288,6 +288,7 @@
|
||||
|
||||
var string = inputText.split("")
|
||||
var drawn = []
|
||||
var quoteOpened = false
|
||||
|
||||
for(var i = 0; i < string.length; i++){
|
||||
let symbol = string[i]
|
||||
@ -314,7 +315,12 @@
|
||||
}else if(symbol === "…"){
|
||||
drawn.push({text: symbol, x: bold ? 9 : 0, y: 5, h: 25, rotate: true})
|
||||
}else if(symbol === '"'){
|
||||
drawn.push({text: symbol, x: 0, y: 5, h: 20, rotate: true})
|
||||
if(quoteOpened){
|
||||
drawn.push({realText: symbol, text: "“", x: -25, y: 10, h: 20})
|
||||
}else{
|
||||
drawn.push({realText: symbol, text: "”", x: 12, y: 15, h: 20})
|
||||
}
|
||||
quoteOpened = !quoteOpened
|
||||
}else if(r.comma.test(symbol)){
|
||||
// Comma, full stop
|
||||
if(bold){
|
||||
@ -440,14 +446,17 @@
|
||||
}
|
||||
|
||||
var scaling = 1
|
||||
var strokeScaling = 1
|
||||
var height = config.height - (ura ? 52 * mul : 0)
|
||||
if(height && drawnHeight > height){
|
||||
scaling = height / drawnHeight
|
||||
if(config.align === "bottom"){
|
||||
strokeScaling = Math.max(0.6, height / drawnHeight)
|
||||
ctx.translate(40 * mul, 0)
|
||||
ctx.scale(Math.max(0.6, height / drawnHeight), scaling)
|
||||
ctx.scale(strokeScaling, scaling)
|
||||
ctx.translate(-40 * mul, 0)
|
||||
}else{
|
||||
strokeScaling = scaling
|
||||
ctx.scale(1, scaling)
|
||||
}
|
||||
if(config.selectable){
|
||||
@ -482,7 +491,7 @@
|
||||
ctx.strokeStyle = config.outline
|
||||
ctx.lineWidth = config.outlineSize * mul
|
||||
if(config.align === "bottom"){
|
||||
ctx.lineWidth /= scaling
|
||||
ctx.lineWidth /= strokeScaling
|
||||
}
|
||||
ctx.lineJoin = "round"
|
||||
ctx.miterLimit = 1
|
||||
@ -632,6 +641,9 @@
|
||||
}else{
|
||||
drawn.push({text: symbol, x: -3, y: 13, w: 13, scale: [1.2, 0.7]})
|
||||
}
|
||||
}else if(r.tilde.test(symbol)){
|
||||
// Hyphen, tilde
|
||||
drawn.push({text: symbol === "~" ? "~" : symbol, x: 0, y: 0, w: 39})
|
||||
}else if(r.en.test(symbol)){
|
||||
// n-width
|
||||
drawn.push({text: symbol, x: 0, y: 0, w: 28})
|
||||
|
@ -75,7 +75,9 @@ class Controller{
|
||||
}
|
||||
var ms = this.game.elapsedTime
|
||||
|
||||
this.keyboard.checkMenuKeys()
|
||||
if(this.game.musicFadeOut < 3){
|
||||
this.keyboard.checkMenuKeys()
|
||||
}
|
||||
if(!this.game.isPaused()){
|
||||
this.keyboard.checkGameKeys()
|
||||
|
||||
|
@ -20,7 +20,7 @@ class Debug{
|
||||
|
||||
this.moving = false
|
||||
pageEvents.add(window, ["mousedown", "mouseup", "blur"], this.stopMove.bind(this))
|
||||
pageEvents.add(window, "mousemove", this.onMove.bind(this))
|
||||
pageEvents.mouseAdd(this, this.onMove.bind(this))
|
||||
pageEvents.add(this.titleDiv, "mousedown", this.startMove.bind(this))
|
||||
pageEvents.add(this.minimiseDiv, "click", this.minimise.bind(this))
|
||||
pageEvents.add(this.restartBtn, "click", this.restartSong.bind(this))
|
||||
@ -173,7 +173,8 @@ class Debug{
|
||||
clean(){
|
||||
this.offsetSlider.clean()
|
||||
|
||||
pageEvents.remove(window, ["mousedown", "mouseup", "mousemove", "blur"])
|
||||
pageEvents.remove(window, ["mousedown", "mouseup", "blur"])
|
||||
pageEvents.mouseRemove(this)
|
||||
pageEvents.remove(this.title, "mousedown")
|
||||
pageEvents.remove(this.minimiseDiv, "click")
|
||||
pageEvents.remove(this.restartBtn, "click")
|
||||
|
@ -24,9 +24,11 @@
|
||||
|
||||
this.tjaFiles = []
|
||||
this.osuFiles = []
|
||||
this.assetFiles = {}
|
||||
var metaFiles = []
|
||||
this.otherFiles = {}
|
||||
this.songs = []
|
||||
this.stylesheet = []
|
||||
this.courseTypes = {
|
||||
"easy": 0,
|
||||
"normal": 1,
|
||||
@ -53,6 +55,18 @@
|
||||
this.categories[allStrings[i].categories[ja].toLowerCase()] = ja
|
||||
}
|
||||
}
|
||||
this.assetSelectors = {
|
||||
"bg-pattern-1": ".pattern-bg",
|
||||
"bg_genre_0": "#song-select",
|
||||
"title-screen": "#title-screen",
|
||||
"dancing-don": "#loading-don",
|
||||
"touch_drum": "#touch-drum-img",
|
||||
"touch_fullscreen": "#touch-full-btn",
|
||||
"touch_pause": "#touch-pause-btn",
|
||||
"bg_stage_1": ".song-stage-1",
|
||||
"bg_stage_2": ".song-stage-2",
|
||||
"bg_stage_3": ".song-stage-3"
|
||||
}
|
||||
|
||||
for(var i = 0; i < files.length; i++){
|
||||
var file = files[i]
|
||||
@ -74,8 +88,12 @@
|
||||
file: file,
|
||||
level: (level * 2) + (name === "genre.ini" ? 1 : 0)
|
||||
})
|
||||
}else if(path.indexOf("/taiko-web assets/") !== -1){
|
||||
if(!(name in this.assetFiles)){
|
||||
this.assetFiles[name] = file
|
||||
}
|
||||
}else{
|
||||
this.otherFiles[file.webkitRelativePath.toLowerCase()] = file
|
||||
this.otherFiles[path] = file
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,6 +112,7 @@
|
||||
this.osuFiles.forEach(fileObj => {
|
||||
songPromises.push(this.addOsu(fileObj))
|
||||
})
|
||||
songPromises.push(this.addAssets())
|
||||
Promise.all(songPromises).then(this.loaded.bind(this))
|
||||
})
|
||||
}
|
||||
@ -188,6 +207,9 @@
|
||||
if(meta.genre){
|
||||
songObj.category = this.categories[meta.genre.toLowerCase()] || meta.genre
|
||||
}
|
||||
if(meta.taikowebskin){
|
||||
songObj.song_skin = this.getSkin(dir, meta.taikowebskin)
|
||||
}
|
||||
}
|
||||
if(!songObj.category){
|
||||
songObj.category = category || this.getCategory(file)
|
||||
@ -242,6 +264,67 @@
|
||||
return promise
|
||||
}
|
||||
|
||||
addAssets(){
|
||||
return new Promise((resolve, reject) => {
|
||||
var promises = []
|
||||
for(let name in this.assetFiles){
|
||||
let id = this.getFilename(name)
|
||||
var file = this.assetFiles[name]
|
||||
if(name === "vectors.json"){
|
||||
var reader = new FileReader()
|
||||
promises.push(pageEvents.load(reader).then(() => response => {
|
||||
vectors = JSON.parse(response)
|
||||
}))
|
||||
reader.readAsText(file)
|
||||
}
|
||||
if(assets.img.indexOf(name) !== -1){
|
||||
let image = document.createElement("img")
|
||||
promises.push(pageEvents.load(image).then(() => {
|
||||
if(id in this.assetSelectors){
|
||||
var selector = this.assetSelectors[id]
|
||||
this.stylesheet.push(selector + '{background-image:url("' + image.src + '")}')
|
||||
}
|
||||
}))
|
||||
image.id = name
|
||||
image.src = URL.createObjectURL(file)
|
||||
loader.assetsDiv.appendChild(image)
|
||||
assets.image[id].parentNode.removeChild(assets.image[id])
|
||||
assets.image[id] = image
|
||||
}
|
||||
if(assets.audioSfx.indexOf(name) !== -1){
|
||||
assets.sounds[id].clean()
|
||||
promises.push(this.loadSound(file, name, snd.sfxGain))
|
||||
}
|
||||
if(assets.audioMusic.indexOf(name) !== -1){
|
||||
assets.sounds[id].clean()
|
||||
promises.push(this.loadSound(file, name, snd.musicGain))
|
||||
}
|
||||
if(assets.audioSfxLR.indexOf(name) !== -1){
|
||||
assets.sounds[id + "_p1"].clean()
|
||||
assets.sounds[id + "_p2"].clean()
|
||||
promises.push(this.loadSound(file, name, snd.sfxGain).then(sound => {
|
||||
assets.sounds[id + "_p1"] = assets.sounds[id].copy(snd.sfxGainL)
|
||||
assets.sounds[id + "_p2"] = assets.sounds[id].copy(snd.sfxGainR)
|
||||
}))
|
||||
}
|
||||
if(assets.audioSfxLoud.indexOf(name) !== -1){
|
||||
assets.sounds[id].clean()
|
||||
promises.push(this.loadSound(file, name, snd.sfxLoudGain))
|
||||
}
|
||||
}
|
||||
Promise.all(promises).then(resolve, reject)
|
||||
})
|
||||
}
|
||||
loadSound(file, name, gain){
|
||||
var id = this.getFilename(name)
|
||||
return gain.load(file, true).then(sound => {
|
||||
assets.sounds[id] = sound
|
||||
})
|
||||
}
|
||||
getFilename(name){
|
||||
return name.slice(0, name.lastIndexOf("."))
|
||||
}
|
||||
|
||||
getCategory(file){
|
||||
var path = file.webkitRelativePath.toLowerCase().split("/")
|
||||
for(var i = path.length - 2; i >= 0; i--){
|
||||
@ -253,8 +336,55 @@
|
||||
}
|
||||
}
|
||||
|
||||
getSkin(dir, config){
|
||||
var configArray = config.toLowerCase().split(",")
|
||||
var configObj = {}
|
||||
for(var i in configArray){
|
||||
var string = configArray[i].trim()
|
||||
var space = string.indexOf(" ")
|
||||
if(space !== -1){
|
||||
configObj[string.slice(0, space).trim()] = string.slice(space + 1).trim()
|
||||
}
|
||||
}
|
||||
if(!configObj.dir){
|
||||
configObj.dir = ""
|
||||
}
|
||||
configObj.prefix = "custom "
|
||||
var skinnable = ["song", "stage", "don"]
|
||||
for(var i in skinnable){
|
||||
var skinName = skinnable[i]
|
||||
var skinValue = configObj[skinName]
|
||||
if(skinValue && skinValue !== "none"){
|
||||
var fileName = "bg_" + skinName + "_" + configObj.name
|
||||
var skinPath = this.joinPath(dir, configObj.dir, fileName)
|
||||
for(var j = 0; j < 2; j++){
|
||||
if(skinValue !== "static"){
|
||||
var suffix = (j === 0 ? "_a" : "_b") + ".png"
|
||||
}else{
|
||||
var suffix = ".png"
|
||||
}
|
||||
var skinFull = this.normPath(skinPath + suffix)
|
||||
if(skinFull in this.otherFiles){
|
||||
configObj[fileName + suffix] = this.otherFiles[skinFull]
|
||||
}else{
|
||||
configObj[skinName] = null
|
||||
}
|
||||
if(skinValue === "static"){
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return configObj
|
||||
}
|
||||
|
||||
loaded(){
|
||||
this.songs = this.songs.filter(song => typeof song !== "undefined")
|
||||
if(this.stylesheet.length){
|
||||
var style = document.createElement("style")
|
||||
style.appendChild(document.createTextNode(this.stylesheet.join("\n")))
|
||||
document.head.appendChild(style)
|
||||
}
|
||||
if(this.songs.length){
|
||||
assets.songs = this.songs
|
||||
assets.customSongs = true
|
||||
@ -274,6 +404,40 @@
|
||||
}
|
||||
}
|
||||
|
||||
joinPath(){
|
||||
var resultPath = arguments[0]
|
||||
for(var i = 1; i < arguments.length; i++){
|
||||
var pPath = arguments[i]
|
||||
if(pPath && (pPath[0] === "/" || pPath[0] === "\\")){
|
||||
resultPath = pPath
|
||||
}else{
|
||||
var lastChar = resultPath.slice(-1)
|
||||
if(resultPath && (lastChar !== "/" || lastChar !== "\\")){
|
||||
resultPath = resultPath + "/"
|
||||
}
|
||||
resultPath = resultPath + pPath
|
||||
}
|
||||
}
|
||||
return resultPath
|
||||
}
|
||||
normPath(path){
|
||||
path = path.replace(/\\/g, "/").toLowerCase()
|
||||
while(path[0] === "/"){
|
||||
path = path.slice(1)
|
||||
}
|
||||
var comps = path.split("/")
|
||||
for(var i = 0; i < comps.length; i++){
|
||||
if(comps[i] === "." || comps[i] === ""){
|
||||
comps.splice(i, 1)
|
||||
i--
|
||||
}else if(i !== 0 && comps[i] === ".." && comps[i - 1] !== ".."){
|
||||
comps.splice(i - 1, 2)
|
||||
i -= 2
|
||||
}
|
||||
}
|
||||
return comps.join("/")
|
||||
}
|
||||
|
||||
clean(){
|
||||
delete this.loaderDiv
|
||||
delete this.songs
|
||||
|
@ -243,7 +243,6 @@ class Loader{
|
||||
clean(){
|
||||
var fontDetectDiv = document.getElementById("fontdetectHelper")
|
||||
fontDetectDiv.parentNode.removeChild(fontDetectDiv)
|
||||
delete this.assetsDiv
|
||||
delete this.loaderPercentage
|
||||
delete this.loaderProgress
|
||||
delete this.promises
|
||||
|
@ -26,11 +26,13 @@ class LoadSong{
|
||||
song.songStage = this.randInt(1, 3)
|
||||
song.donBg = this.randInt(1, 6)
|
||||
|
||||
var songObj = assets.songs.find(song => song.id === id)
|
||||
|
||||
if(song.songSkin && song.songSkin.name){
|
||||
var imgLoad = []
|
||||
for(var type in song.songSkin){
|
||||
var value = song.songSkin[type]
|
||||
if(type !== "name" && value && value !== "none"){
|
||||
if(["song", "stage", "don"].indexOf(type) !== -1 && value && value !== "none"){
|
||||
var filename = "bg_" + type + "_" + song.songSkin.name
|
||||
if(value === "static"){
|
||||
imgLoad.push({
|
||||
@ -57,28 +59,34 @@ class LoadSong{
|
||||
}
|
||||
var skinBase = gameConfig.assets_baseurl + "song_skins/"
|
||||
for(var i = 0; i < imgLoad.length; i++){
|
||||
let filename = imgLoad[i].filename
|
||||
let prefix = song.songSkin.prefix || ""
|
||||
if((prefix + filename) in assets.image){
|
||||
continue
|
||||
}
|
||||
let img = document.createElement("img")
|
||||
if(this.touchEnabled && imgLoad[i].type === "song"){
|
||||
if(!songObj.music && this.touchEnabled && imgLoad[i].type === "song"){
|
||||
img.crossOrigin = "Anonymous"
|
||||
}
|
||||
let filename = imgLoad[i].filename
|
||||
let promise = pageEvents.load(img)
|
||||
if(imgLoad[i].type === "song"){
|
||||
promises.push(promise.then(() => {
|
||||
return this.scaleImg(img, filename)
|
||||
return this.scaleImg(img, filename, prefix)
|
||||
}))
|
||||
}else{
|
||||
promises.push(promise.then(() => {
|
||||
assets.image[filename] = img
|
||||
assets.image[prefix + filename] = img
|
||||
}))
|
||||
}
|
||||
img.src = skinBase + filename + ".png"
|
||||
if(songObj.music){
|
||||
img.src = URL.createObjectURL(song.songSkin[filename + ".png"])
|
||||
}else{
|
||||
img.src = skinBase + filename + ".png"
|
||||
}
|
||||
}
|
||||
}
|
||||
promises.push(this.loadSongBg(id))
|
||||
|
||||
var songObj = assets.songs.find(song => song.id === id)
|
||||
|
||||
promises.push(new Promise((resolve, reject) => {
|
||||
if(songObj.sound){
|
||||
songObj.sound.gain = snd.musicGain
|
||||
@ -136,7 +144,7 @@ class LoadSong{
|
||||
img.crossOrigin = "Anonymous"
|
||||
}
|
||||
promises.push(pageEvents.load(img).then(() => {
|
||||
return this.scaleImg(img, filenameAb)
|
||||
return this.scaleImg(img, filenameAb, "")
|
||||
}))
|
||||
}else{
|
||||
promises.push(pageEvents.load(img).then(() => {
|
||||
@ -150,7 +158,7 @@ class LoadSong{
|
||||
Promise.all(promises).then(resolve, reject)
|
||||
})
|
||||
}
|
||||
scaleImg(img, filename){
|
||||
scaleImg(img, filename, prefix){
|
||||
return new Promise((resolve, reject) => {
|
||||
if(this.touchEnabled){
|
||||
var canvas = document.createElement("canvas")
|
||||
@ -163,7 +171,7 @@ class LoadSong{
|
||||
var saveScaled = url => {
|
||||
let img2 = document.createElement("img")
|
||||
pageEvents.load(img2).then(() => {
|
||||
assets.image[filename] = img2
|
||||
assets.image[prefix + filename] = img2
|
||||
resolve()
|
||||
}, reject)
|
||||
img2.src = url
|
||||
@ -176,7 +184,7 @@ class LoadSong{
|
||||
saveScaled(canvas.toDataURL())
|
||||
}
|
||||
}else{
|
||||
assets.image[filename] = img
|
||||
assets.image[prefix + filename] = img
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
|
@ -999,6 +999,7 @@
|
||||
var songSkinName = selectedSong.songSkin.name
|
||||
var supportsBlend = "mixBlendMode" in this.songBg.style
|
||||
var songLayers = [document.getElementById("layer1"), document.getElementById("layer2")]
|
||||
var prefix = selectedSong.songSkin.prefix || ""
|
||||
|
||||
if(selectedSong.category in this.categories){
|
||||
var catId = this.categories[selectedSong.category].sort
|
||||
@ -1009,19 +1010,19 @@
|
||||
if(!selectedSong.songSkin.song){
|
||||
var id = selectedSong.songBg
|
||||
this.songBg.classList.add("songbg-" + id)
|
||||
this.setLayers(songLayers, "bg_song_" + id + (supportsBlend ? "" : "a"), supportsBlend)
|
||||
this.setLayers(songLayers, prefix + "bg_song_" + id + (supportsBlend ? "" : "a"), supportsBlend)
|
||||
}else if(selectedSong.songSkin.song !== "none"){
|
||||
var notStatic = selectedSong.songSkin.song !== "static"
|
||||
if(notStatic){
|
||||
this.songBg.classList.add("songbg-" + selectedSong.songSkin.song)
|
||||
}
|
||||
this.setLayers(songLayers, "bg_song_" + songSkinName + (notStatic ? "_" : ""), notStatic)
|
||||
this.setLayers(songLayers, prefix + "bg_song_" + songSkinName + (notStatic ? "_" : ""), notStatic)
|
||||
}
|
||||
|
||||
if(!selectedSong.songSkin.stage){
|
||||
this.songStage.classList.add("song-stage-" + selectedSong.songStage)
|
||||
}else if(selectedSong.songSkin.stage !== "none"){
|
||||
this.setBgImage(this.songStage, assets.image["bg_stage_" + songSkinName].src)
|
||||
this.setBgImage(this.songStage, assets.image[prefix + "bg_stage_" + songSkinName].src)
|
||||
}
|
||||
}
|
||||
setDonBg(){
|
||||
@ -1029,6 +1030,7 @@
|
||||
var songSkinName = selectedSong.songSkin.name
|
||||
var donLayers = []
|
||||
var filename = !selectedSong.songSkin.don && this.multiplayer === 2 ? "bg_don2_" : "bg_don_"
|
||||
var prefix = selectedSong.songSkin.prefix || ""
|
||||
|
||||
this.donBg = document.createElement("div")
|
||||
this.donBg.classList.add("donbg")
|
||||
@ -1047,7 +1049,7 @@
|
||||
var asset1, asset2
|
||||
if(!selectedSong.songSkin.don){
|
||||
this.donBg.classList.add("donbg-" + selectedSong.donBg)
|
||||
this.setLayers(donLayers, filename + selectedSong.donBg, true)
|
||||
this.setLayers(donLayers, prefix + filename + selectedSong.donBg, true)
|
||||
asset1 = filename + selectedSong.donBg + "a"
|
||||
asset2 = filename + selectedSong.donBg + "b"
|
||||
}else if(selectedSong.songSkin.don !== "none"){
|
||||
@ -1060,15 +1062,17 @@
|
||||
asset1 = filename + songSkinName
|
||||
asset2 = filename + songSkinName
|
||||
}
|
||||
this.setLayers(donLayers, filename + songSkinName + (notStatic ? "_" : ""), notStatic)
|
||||
this.setLayers(donLayers, prefix + filename + songSkinName + (notStatic ? "_" : ""), notStatic)
|
||||
}else{
|
||||
return
|
||||
}
|
||||
var w1 = assets.image[asset1].width
|
||||
var w2 = assets.image[asset2].width
|
||||
var w1 = assets.image[prefix + asset1].width
|
||||
var w2 = assets.image[prefix + asset2].width
|
||||
this.donBg.style.setProperty("--sw", w1 > w2 ? w1 : w2)
|
||||
this.donBg.style.setProperty("--sw1", w1)
|
||||
this.donBg.style.setProperty("--sw2", w2)
|
||||
this.donBg.style.setProperty("--sh1", assets.image[asset1].height)
|
||||
this.donBg.style.setProperty("--sh2", assets.image[asset2].height)
|
||||
this.donBg.style.setProperty("--sh1", assets.image[prefix + asset1].height)
|
||||
this.donBg.style.setProperty("--sh2", assets.image[prefix + asset2].height)
|
||||
}
|
||||
setDonBgHeight(){
|
||||
this.donBg.style.setProperty("--h", getComputedStyle(this.donBg).height)
|
||||
|
Loading…
Reference in New Issue
Block a user