2019-01-05 08:44:28 +01:00
|
|
|
|
class ImportSongs{
|
2022-02-11 15:28:22 +01:00
|
|
|
|
constructor(...args){
|
|
|
|
|
this.init(...args)
|
|
|
|
|
}
|
|
|
|
|
init(limited, otherFiles, noPlugins, pluginAmount){
|
2020-10-29 06:07:56 +01:00
|
|
|
|
this.limited = limited
|
2019-01-05 08:44:28 +01:00
|
|
|
|
this.tjaFiles = []
|
|
|
|
|
this.osuFiles = []
|
2019-02-03 13:04:25 +01:00
|
|
|
|
this.assetFiles = {}
|
2022-02-11 15:28:22 +01:00
|
|
|
|
this.pluginFiles = []
|
2020-10-29 06:07:56 +01:00
|
|
|
|
this.otherFiles = otherFiles || {}
|
2022-02-11 15:28:22 +01:00
|
|
|
|
this.noPlugins = noPlugins
|
|
|
|
|
this.pluginAmount = pluginAmount
|
2019-01-05 08:44:28 +01:00
|
|
|
|
this.songs = []
|
2019-02-03 13:04:25 +01:00
|
|
|
|
this.stylesheet = []
|
2022-02-11 15:28:22 +01:00
|
|
|
|
this.plugins = []
|
2020-10-31 12:47:42 +01:00
|
|
|
|
this.songTitle = this.otherFiles.songTitle || {}
|
2019-04-04 22:40:11 +02:00
|
|
|
|
this.uraRegex = /\s*[\((]裏[\))]$/
|
2019-01-05 08:44:28 +01:00
|
|
|
|
this.courseTypes = {
|
|
|
|
|
"easy": 0,
|
|
|
|
|
"normal": 1,
|
|
|
|
|
"hard": 2,
|
|
|
|
|
"oni": 3,
|
|
|
|
|
"ura": 4
|
|
|
|
|
}
|
2020-04-26 22:56:31 +02:00
|
|
|
|
this.categoryAliases = {}
|
|
|
|
|
assets.categories.forEach(cat => {
|
2020-04-27 17:47:55 +02:00
|
|
|
|
this.categoryAliases[cat.title.toLowerCase()] = cat.id
|
|
|
|
|
if(cat.aliases){
|
2020-04-26 22:56:31 +02:00
|
|
|
|
cat.aliases.forEach(alias => {
|
2020-04-27 17:47:55 +02:00
|
|
|
|
this.categoryAliases[alias.toLowerCase()] = cat.id
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
if(cat.title_lang){
|
|
|
|
|
for(var i in cat.title_lang){
|
|
|
|
|
this.categoryAliases[cat.title_lang[i].toLowerCase()] = cat.id
|
|
|
|
|
}
|
2019-01-25 02:42:05 +01:00
|
|
|
|
}
|
2020-04-27 17:47:55 +02:00
|
|
|
|
})
|
2022-07-15 16:00:43 +02:00
|
|
|
|
this.assetSelectors = {}
|
|
|
|
|
for(var selector in assets.cssBackground){
|
|
|
|
|
var filename = assets.cssBackground[selector]
|
|
|
|
|
var index = filename.lastIndexOf(".")
|
|
|
|
|
if(index !== -1){
|
|
|
|
|
filename = filename.slice(0, index)
|
|
|
|
|
}
|
|
|
|
|
this.assetSelectors[filename] = selector
|
2019-02-03 13:04:25 +01:00
|
|
|
|
}
|
2020-10-31 12:47:42 +01:00
|
|
|
|
this.comboVoices = ["v_combo_50"].concat(Array.from(Array(50), (d, i) => "v_combo_" + ((i + 1) * 100)))
|
2020-10-29 06:07:56 +01:00
|
|
|
|
}
|
|
|
|
|
load(files){
|
|
|
|
|
var extensionRegex = /\.[^\/]+$/
|
|
|
|
|
files.sort((a, b) => {
|
|
|
|
|
var path1 = a.path.replace(extensionRegex, "")
|
|
|
|
|
var path2 = b.path.replace(extensionRegex, "")
|
|
|
|
|
return path1 > path2 ? 1 : -1
|
|
|
|
|
})
|
2019-01-05 08:44:28 +01:00
|
|
|
|
|
2020-10-29 06:07:56 +01:00
|
|
|
|
var metaFiles = []
|
2019-01-05 08:44:28 +01:00
|
|
|
|
for(var i = 0; i < files.length; i++){
|
|
|
|
|
var file = files[i]
|
|
|
|
|
var name = file.name.toLowerCase()
|
2020-10-29 06:07:56 +01:00
|
|
|
|
var path = file.path.toLowerCase()
|
2022-07-15 16:00:43 +02:00
|
|
|
|
if(name.endsWith(".tja") || name.endsWith(".tjf")){
|
2019-01-05 08:44:28 +01:00
|
|
|
|
this.tjaFiles.push({
|
|
|
|
|
file: file,
|
|
|
|
|
index: i
|
|
|
|
|
})
|
|
|
|
|
}else if(name.endsWith(".osu")){
|
|
|
|
|
this.osuFiles.push({
|
|
|
|
|
file: file,
|
|
|
|
|
index: i
|
|
|
|
|
})
|
2020-10-31 12:47:42 +01:00
|
|
|
|
}else if(!this.limited && (name === "genre.ini" || name === "box.def") || name === "songtitle.txt"){
|
2020-10-29 06:07:56 +01:00
|
|
|
|
var level = (file.path.match(/\//g) || []).length
|
2019-01-05 08:44:28 +01:00
|
|
|
|
metaFiles.push({
|
|
|
|
|
file: file,
|
|
|
|
|
level: (level * 2) + (name === "genre.ini" ? 1 : 0)
|
|
|
|
|
})
|
2020-10-31 12:47:42 +01:00
|
|
|
|
}else if(!this.limited && (path.indexOf("/taiko-web assets/") !== -1 || path.indexOf("taiko-web assets/") === 0)){
|
2019-02-03 13:04:25 +01:00
|
|
|
|
if(!(name in this.assetFiles)){
|
|
|
|
|
this.assetFiles[name] = file
|
|
|
|
|
}
|
2022-02-11 15:28:22 +01:00
|
|
|
|
}else if(name.endsWith(".taikoweb.js")){
|
|
|
|
|
this.pluginFiles.push({
|
|
|
|
|
file: file,
|
|
|
|
|
index: i
|
|
|
|
|
})
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}else{
|
2019-02-03 13:04:25 +01:00
|
|
|
|
this.otherFiles[path] = file
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-11 15:28:22 +01:00
|
|
|
|
if(!this.noPlugins && this.pluginFiles.length){
|
|
|
|
|
var pluginPromises = []
|
|
|
|
|
this.pluginFiles.forEach(fileObj => {
|
|
|
|
|
pluginPromises.push(this.addPlugin(fileObj).catch(e => console.warn(e)))
|
|
|
|
|
})
|
|
|
|
|
return Promise.all(pluginPromises).then(() => {
|
|
|
|
|
var startPromises = []
|
|
|
|
|
var pluginAmount = 0
|
|
|
|
|
if(this.plugins.length && confirm(strings.plugins.warning.replace("%s",
|
|
|
|
|
strings.plugins.plugin[strings.plural.select(this.plugins.length)].replace("%s",
|
|
|
|
|
this.plugins.length.toString()
|
|
|
|
|
)
|
|
|
|
|
))){
|
|
|
|
|
this.plugins.forEach(obj => {
|
2022-02-22 14:23:01 +01:00
|
|
|
|
var plugin = plugins.add(obj.data, {
|
|
|
|
|
name: obj.name,
|
|
|
|
|
raw: true
|
|
|
|
|
})
|
2022-02-11 15:28:22 +01:00
|
|
|
|
if(plugin){
|
|
|
|
|
pluginAmount++
|
2022-02-17 21:50:07 +01:00
|
|
|
|
plugin.imported = true
|
2022-02-11 15:28:22 +01:00
|
|
|
|
startPromises.push(plugin.start())
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
return Promise.all(startPromises).then(() => {
|
|
|
|
|
var importSongs = new ImportSongs(this.limited, this.otherFiles, true, pluginAmount)
|
|
|
|
|
return importSongs.load(files)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-05 08:44:28 +01:00
|
|
|
|
var metaPromises = []
|
|
|
|
|
metaFiles.forEach(fileObj => {
|
|
|
|
|
metaPromises.push(this.addMeta(fileObj))
|
|
|
|
|
})
|
|
|
|
|
|
2020-10-29 06:07:56 +01:00
|
|
|
|
return Promise.all(metaPromises).then(() => {
|
2019-01-05 08:44:28 +01:00
|
|
|
|
var songPromises = []
|
|
|
|
|
|
|
|
|
|
this.tjaFiles.forEach(fileObj => {
|
2020-10-29 06:07:56 +01:00
|
|
|
|
songPromises.push(this.addTja(fileObj).catch(e => console.warn(e)))
|
2019-01-05 08:44:28 +01:00
|
|
|
|
})
|
|
|
|
|
this.osuFiles.forEach(fileObj => {
|
2020-10-29 06:07:56 +01:00
|
|
|
|
songPromises.push(this.addOsu(fileObj).catch(e => console.warn(e)))
|
2019-01-05 08:44:28 +01:00
|
|
|
|
})
|
2019-02-03 13:04:25 +01:00
|
|
|
|
songPromises.push(this.addAssets())
|
2020-10-29 06:07:56 +01:00
|
|
|
|
return Promise.all(songPromises)
|
|
|
|
|
}).then(this.loaded.bind(this))
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addMeta(fileObj){
|
|
|
|
|
var file = fileObj.file
|
|
|
|
|
var level = fileObj.level
|
|
|
|
|
var name = file.name.toLowerCase()
|
2024-03-20 16:16:44 +01:00
|
|
|
|
return file.read(name === "songtitle.txt" ? undefined : "utf-8").then(data => {
|
2020-10-29 06:07:56 +01:00
|
|
|
|
var data = data.replace(/\0/g, "").split("\n")
|
2019-01-05 08:44:28 +01:00
|
|
|
|
var category
|
|
|
|
|
if(name === "genre.ini"){
|
|
|
|
|
var key
|
|
|
|
|
for(var i = 0; i < data.length; i++){
|
|
|
|
|
var line = data[i].trim().toLowerCase()
|
|
|
|
|
if(line.startsWith("[") && line.endsWith("]")){
|
|
|
|
|
key = line.slice(1, -1)
|
|
|
|
|
}else if(key === "genre"){
|
|
|
|
|
var equalsPos = line.indexOf("=")
|
|
|
|
|
if(equalsPos !== -1 && line.slice(0, equalsPos).trim() === "genrename"){
|
|
|
|
|
var value = line.slice(equalsPos + 1).trim()
|
2020-04-27 17:47:55 +02:00
|
|
|
|
if(value.toLowerCase() in this.categoryAliases){
|
|
|
|
|
category = value
|
|
|
|
|
}else{
|
|
|
|
|
category = data[i].trim().slice(equalsPos + 1).trim()
|
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}else if(name === "box.def"){
|
|
|
|
|
for(var i = 0; i < data.length; i++){
|
|
|
|
|
var line = data[i].trim().toLowerCase()
|
|
|
|
|
if(line.startsWith("#title:")){
|
|
|
|
|
var value = line.slice(7).trim()
|
2020-04-27 17:47:55 +02:00
|
|
|
|
if(value.toLowerCase() in this.categoryAliases){
|
|
|
|
|
category = value
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
}else if(line.startsWith("#genre:")){
|
|
|
|
|
var value = line.slice(7).trim()
|
2020-04-27 17:47:55 +02:00
|
|
|
|
if(value.toLowerCase() in this.categoryAliases){
|
|
|
|
|
category = value
|
|
|
|
|
}else{
|
|
|
|
|
category = data[i].trim().slice(7).trim()
|
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-04 22:40:11 +02:00
|
|
|
|
}else if(name === "songtitle.txt"){
|
|
|
|
|
var lastTitle
|
|
|
|
|
for(var i = 0; i < data.length; i++){
|
|
|
|
|
var line = data[i].trim()
|
|
|
|
|
if(line){
|
|
|
|
|
var lang = line.slice(0, 2)
|
|
|
|
|
if(line.charAt(2) !== " " || !(lang in allStrings)){
|
|
|
|
|
this.songTitle[line] = {}
|
|
|
|
|
lastTitle = line
|
|
|
|
|
}else if(lastTitle){
|
|
|
|
|
this.songTitle[lastTitle][lang] = line.slice(3).trim()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
if(category){
|
2020-10-29 06:07:56 +01:00
|
|
|
|
var metaPath = file.path.toLowerCase().slice(0, file.name.length * -1)
|
2019-01-05 13:24:09 +01:00
|
|
|
|
var filesLoop = fileObj => {
|
2020-10-29 06:07:56 +01:00
|
|
|
|
var tjaPath = fileObj.file.path.toLowerCase().slice(0, fileObj.file.name.length * -1)
|
2019-01-05 08:44:28 +01:00
|
|
|
|
if(tjaPath.startsWith(metaPath) && (!("categoryLevel" in fileObj) || fileObj.categoryLevel < level)){
|
2020-04-27 17:47:55 +02:00
|
|
|
|
if(category.toLowerCase() in this.categoryAliases){
|
|
|
|
|
fileObj.category_id = this.categoryAliases[category.toLowerCase()]
|
|
|
|
|
}else{
|
|
|
|
|
fileObj.category = category
|
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
fileObj.categoryLevel = level
|
|
|
|
|
}
|
2019-01-05 13:24:09 +01:00
|
|
|
|
}
|
|
|
|
|
this.tjaFiles.forEach(filesLoop)
|
|
|
|
|
this.osuFiles.forEach(filesLoop)
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
}).catch(e => {
|
|
|
|
|
console.warn(e)
|
|
|
|
|
})
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addTja(fileObj){
|
|
|
|
|
var file = fileObj.file
|
|
|
|
|
var index = fileObj.index
|
|
|
|
|
var category = fileObj.category
|
2020-04-27 17:47:55 +02:00
|
|
|
|
var category_id = fileObj.category_id
|
2020-10-29 06:07:56 +01:00
|
|
|
|
if(!this.limited){
|
2024-04-04 18:01:45 +02:00
|
|
|
|
var filePromise = file.read("sjis") // utf-8にしたい
|
2020-10-29 06:07:56 +01:00
|
|
|
|
}else{
|
|
|
|
|
var filePromise = Promise.resolve()
|
|
|
|
|
}
|
|
|
|
|
return filePromise.then(dataRaw => {
|
|
|
|
|
var data = dataRaw ? dataRaw.replace(/\0/g, "").split("\n") : []
|
2019-11-04 15:20:44 +01:00
|
|
|
|
var tja = new ParseTja(data, "oni", 0, 0, true)
|
2019-01-05 08:44:28 +01:00
|
|
|
|
var songObj = {
|
|
|
|
|
id: index + 1,
|
2020-03-13 03:34:54 +01:00
|
|
|
|
order: index + 1,
|
2020-10-29 06:07:56 +01:00
|
|
|
|
title: file.name.slice(0, file.name.lastIndexOf(".")),
|
2019-01-05 08:44:28 +01:00
|
|
|
|
type: "tja",
|
2019-03-15 22:34:48 +01:00
|
|
|
|
chart: file,
|
2020-03-14 10:44:29 +01:00
|
|
|
|
courses: {},
|
2020-10-29 06:07:56 +01:00
|
|
|
|
music: "muted",
|
|
|
|
|
custom: true
|
|
|
|
|
}
|
|
|
|
|
if(this.limited){
|
|
|
|
|
songObj.unloaded = true
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
2020-03-13 03:34:54 +01:00
|
|
|
|
var coursesAdded = false
|
2019-03-05 22:48:30 +01:00
|
|
|
|
var titleLang = {}
|
2020-03-13 03:34:54 +01:00
|
|
|
|
var titleLangAdded = false
|
|
|
|
|
var subtitleLangAdded = false
|
2019-03-05 22:48:30 +01:00
|
|
|
|
var subtitleLang = {}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
var dir = file.path.toLowerCase()
|
2019-01-05 08:44:28 +01:00
|
|
|
|
dir = dir.slice(0, dir.lastIndexOf("/") + 1)
|
|
|
|
|
for(var diff in tja.metadata){
|
|
|
|
|
var meta = tja.metadata[diff]
|
2019-03-05 22:48:30 +01:00
|
|
|
|
songObj.title = meta.title || file.name.slice(0, file.name.lastIndexOf("."))
|
2019-01-05 08:44:28 +01:00
|
|
|
|
var subtitle = meta.subtitle || ""
|
2019-03-05 22:48:30 +01:00
|
|
|
|
if(subtitle.startsWith("--") || subtitle.startsWith("++")){
|
|
|
|
|
subtitle = subtitle.slice(2).trim()
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
2019-03-05 22:48:30 +01:00
|
|
|
|
songObj.subtitle = subtitle
|
2019-02-20 23:42:18 +01:00
|
|
|
|
songObj.preview = meta.demostart || 0
|
2020-03-13 03:34:54 +01:00
|
|
|
|
songObj.courses[diff] = {
|
|
|
|
|
stars: meta.level || 0,
|
|
|
|
|
branch: !!meta.branch
|
|
|
|
|
}
|
|
|
|
|
coursesAdded = true
|
2019-01-05 08:44:28 +01:00
|
|
|
|
if(meta.wave){
|
2019-03-05 22:48:30 +01:00
|
|
|
|
songObj.music = this.otherFiles[dir + meta.wave.toLowerCase()] || songObj.music
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
2019-01-05 13:24:09 +01:00
|
|
|
|
if(meta.genre){
|
2020-04-27 17:47:55 +02:00
|
|
|
|
if(meta.genre.toLowerCase() in this.categoryAliases){
|
|
|
|
|
songObj.category_id = this.categoryAliases[meta.genre.toLowerCase()]
|
|
|
|
|
}else{
|
|
|
|
|
songObj.category = meta.genre
|
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
2019-02-03 13:04:25 +01:00
|
|
|
|
if(meta.taikowebskin){
|
|
|
|
|
songObj.song_skin = this.getSkin(dir, meta.taikowebskin)
|
|
|
|
|
}
|
2019-11-25 02:04:59 +01:00
|
|
|
|
if(meta.maker){
|
2020-03-12 05:59:28 +01:00
|
|
|
|
var maker = meta.maker
|
|
|
|
|
var url = null
|
|
|
|
|
var gt = maker.lastIndexOf(">")
|
|
|
|
|
if(gt === maker.length - 1){
|
|
|
|
|
var lt = maker.lastIndexOf("<")
|
|
|
|
|
if(lt !== -1 && lt !== gt - 2){
|
2022-07-15 16:00:43 +02:00
|
|
|
|
url = maker.slice(lt + 1, gt).trim()
|
2020-03-12 05:59:28 +01:00
|
|
|
|
if(url.startsWith("http://") || url.startsWith("https://")){
|
2022-07-15 16:00:43 +02:00
|
|
|
|
maker = maker.slice(0, lt)
|
2020-03-12 05:59:28 +01:00
|
|
|
|
}else{
|
|
|
|
|
url = null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
songObj.maker = {
|
|
|
|
|
name: maker,
|
|
|
|
|
url: url,
|
|
|
|
|
id: 1
|
|
|
|
|
}
|
2019-11-25 02:04:59 +01:00
|
|
|
|
}
|
2020-03-31 14:50:27 +02:00
|
|
|
|
if(meta.lyrics){
|
|
|
|
|
var lyricsFile = this.normPath(this.joinPath(dir, meta.lyrics))
|
|
|
|
|
if(lyricsFile in this.otherFiles){
|
|
|
|
|
songObj.lyrics = true
|
|
|
|
|
songObj.lyricsFile = this.otherFiles[lyricsFile]
|
|
|
|
|
}
|
|
|
|
|
}else if(meta.inlineLyrics){
|
|
|
|
|
songObj.lyrics = true
|
|
|
|
|
}
|
2019-03-05 22:48:30 +01:00
|
|
|
|
for(var id in allStrings){
|
2019-04-04 22:40:11 +02:00
|
|
|
|
var songTitle = songObj.title
|
|
|
|
|
var ura = ""
|
|
|
|
|
if(songTitle){
|
|
|
|
|
var uraPos = songTitle.search(this.uraRegex)
|
|
|
|
|
if(uraPos !== -1){
|
|
|
|
|
ura = songTitle.slice(uraPos)
|
|
|
|
|
songTitle = songTitle.slice(0, uraPos)
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-03-05 22:48:30 +01:00
|
|
|
|
if(meta["title" + id]){
|
|
|
|
|
titleLang[id] = meta["title" + id]
|
2020-03-13 03:34:54 +01:00
|
|
|
|
titleLangAdded = true
|
2019-04-04 22:40:11 +02:00
|
|
|
|
}else if(songTitle in this.songTitle && this.songTitle[songTitle][id]){
|
|
|
|
|
titleLang[id] = this.songTitle[songTitle][id] + ura
|
2020-03-13 03:34:54 +01:00
|
|
|
|
titleLangAdded = true
|
2019-03-05 22:48:30 +01:00
|
|
|
|
}
|
|
|
|
|
if(meta["subtitle" + id]){
|
|
|
|
|
subtitleLang[id] = meta["subtitle" + id]
|
2020-03-13 03:34:54 +01:00
|
|
|
|
subtitleLangAdded = true
|
2019-03-05 22:48:30 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-13 03:34:54 +01:00
|
|
|
|
if(titleLangAdded){
|
|
|
|
|
songObj.title_lang = titleLang
|
2019-03-05 22:48:30 +01:00
|
|
|
|
}
|
2020-03-13 03:34:54 +01:00
|
|
|
|
if(subtitleLangAdded){
|
|
|
|
|
songObj.subtitle_lang = subtitleLang
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
2020-04-27 17:47:55 +02:00
|
|
|
|
if(!songObj.category_id && !songObj.category){
|
|
|
|
|
if(!category && category_id === undefined){
|
|
|
|
|
songObj.category_id = this.getCategory(file, [songTitle || songObj.title, file.name.slice(0, file.name.lastIndexOf("."))])
|
|
|
|
|
}else if(category){
|
|
|
|
|
songObj.category = category
|
|
|
|
|
songObj.orginalCategory = category
|
|
|
|
|
}else{
|
|
|
|
|
songObj.category_id = category_id
|
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
if(coursesAdded || songObj.unloaded){
|
2019-01-05 08:44:28 +01:00
|
|
|
|
this.songs[index] = songObj
|
|
|
|
|
}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
if(!this.limited){
|
|
|
|
|
var hash = md5.base64(dataRaw).slice(0, -2)
|
|
|
|
|
songObj.hash = hash
|
|
|
|
|
scoreStorage.songTitles[songObj.title] = hash
|
|
|
|
|
var score = scoreStorage.get(hash, false, true)
|
|
|
|
|
if(score){
|
|
|
|
|
score.title = songObj.title
|
|
|
|
|
}
|
2020-03-07 02:48:30 +01:00
|
|
|
|
}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
})
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addOsu(fileObj){
|
|
|
|
|
var file = fileObj.file
|
|
|
|
|
var index = fileObj.index
|
|
|
|
|
var category = fileObj.category
|
2020-04-27 17:47:55 +02:00
|
|
|
|
var category_id = fileObj.category_id
|
2020-10-29 06:07:56 +01:00
|
|
|
|
if(!this.limited){
|
|
|
|
|
var filePromise = file.read()
|
|
|
|
|
}else{
|
|
|
|
|
var filePromise = Promise.resolve()
|
|
|
|
|
}
|
|
|
|
|
return filePromise.then(dataRaw => {
|
|
|
|
|
var data = dataRaw ? dataRaw.replace(/\0/g, "").split("\n") : []
|
|
|
|
|
var osu = new ParseOsu(data, "oni", 0, 0, true)
|
|
|
|
|
var dir = file.path.toLowerCase()
|
2019-01-05 08:44:28 +01:00
|
|
|
|
dir = dir.slice(0, dir.lastIndexOf("/") + 1)
|
|
|
|
|
var songObj = {
|
|
|
|
|
id: index + 1,
|
2020-03-13 03:34:54 +01:00
|
|
|
|
order: index + 1,
|
2019-01-05 08:44:28 +01:00
|
|
|
|
type: "osu",
|
2019-03-15 22:34:48 +01:00
|
|
|
|
chart: file,
|
2019-01-05 08:44:28 +01:00
|
|
|
|
subtitle: osu.metadata.ArtistUnicode || osu.metadata.Artist,
|
2020-03-13 03:34:54 +01:00
|
|
|
|
subtitle_lang: {
|
|
|
|
|
en: osu.metadata.Artist || osu.metadata.ArtistUnicode
|
|
|
|
|
},
|
2020-10-29 06:07:56 +01:00
|
|
|
|
preview: osu.generalInfo.PreviewTime ? osu.generalInfo.PreviewTime / 1000 : 0,
|
|
|
|
|
courses: {},
|
|
|
|
|
music: (osu.generalInfo.AudioFilename ? this.otherFiles[dir + osu.generalInfo.AudioFilename.toLowerCase()] : "") || "muted"
|
|
|
|
|
}
|
|
|
|
|
if(!this.limited){
|
|
|
|
|
songObj.courses.oni = {
|
|
|
|
|
stars: parseInt(osu.difficulty.overallDifficulty) || 0,
|
|
|
|
|
branch: false
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
songObj.unloaded = true
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
var filename = file.name.slice(0, file.name.lastIndexOf("."))
|
2020-03-09 13:36:57 +01:00
|
|
|
|
var title = osu.metadata.TitleUnicode || osu.metadata.Title || file.name.slice(0, file.name.lastIndexOf("."))
|
2019-01-05 08:44:28 +01:00
|
|
|
|
if(title){
|
|
|
|
|
var suffix = ""
|
|
|
|
|
var matches = filename.match(/\[.+?\]$/)
|
|
|
|
|
if(matches){
|
|
|
|
|
suffix = " " + matches[0]
|
|
|
|
|
}
|
|
|
|
|
songObj.title = title + suffix
|
2020-03-13 03:34:54 +01:00
|
|
|
|
songObj.title_lang = {
|
2020-10-29 06:07:56 +01:00
|
|
|
|
en: (osu.metadata.Title || osu.metadata.TitleUnicode || title) + suffix
|
2020-03-13 03:34:54 +01:00
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}else{
|
|
|
|
|
songObj.title = filename
|
|
|
|
|
}
|
2019-03-05 22:48:30 +01:00
|
|
|
|
this.songs[index] = songObj
|
2020-04-27 17:47:55 +02:00
|
|
|
|
if(!category && category_id === undefined){
|
|
|
|
|
songObj.category_id = this.getCategory(file, [osu.metadata.TitleUnicode, osu.metadata.Title, file.name.slice(0, file.name.lastIndexOf("."))])
|
|
|
|
|
}else if(category){
|
|
|
|
|
songObj.category = category
|
|
|
|
|
songObj.orginalCategory = category
|
|
|
|
|
}else{
|
|
|
|
|
songObj.category_id = category_id
|
|
|
|
|
}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
if(!this.limited){
|
|
|
|
|
var hash = md5.base64(dataRaw).slice(0, -2)
|
|
|
|
|
songObj.hash = hash
|
|
|
|
|
scoreStorage.songTitles[songObj.title] = hash
|
|
|
|
|
var score = scoreStorage.get(hash, false, true)
|
|
|
|
|
if(score){
|
|
|
|
|
score.title = songObj.title
|
|
|
|
|
}
|
2020-03-07 08:13:50 +01:00
|
|
|
|
}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
})
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-03 13:04:25 +01:00
|
|
|
|
addAssets(){
|
2020-10-29 06:07:56 +01:00
|
|
|
|
var promises = []
|
|
|
|
|
for(let name in this.assetFiles){
|
|
|
|
|
let id = this.getFilename(name)
|
|
|
|
|
var file = this.assetFiles[name]
|
2020-10-31 12:47:42 +01:00
|
|
|
|
var index = name.lastIndexOf(".")
|
2020-10-29 06:07:56 +01:00
|
|
|
|
if(name === "vectors.json"){
|
2020-10-31 12:47:42 +01:00
|
|
|
|
promises.push(file.read().then(response => {
|
2020-10-29 06:07:56 +01:00
|
|
|
|
vectors = JSON.parse(response)
|
|
|
|
|
}))
|
2019-02-03 13:04:25 +01:00
|
|
|
|
}
|
2022-07-15 16:00:43 +02:00
|
|
|
|
if(name.endsWith(".png") || name.endsWith(".gif")){
|
2020-10-29 06:07:56 +01:00
|
|
|
|
let image = document.createElement("img")
|
|
|
|
|
promises.push(pageEvents.load(image).then(() => {
|
|
|
|
|
if(id in this.assetSelectors){
|
|
|
|
|
var selector = this.assetSelectors[id]
|
2022-07-15 16:00:43 +02:00
|
|
|
|
var gradient = ""
|
|
|
|
|
if(selector === "#song-search"){
|
|
|
|
|
gradient = loader.songSearchGradient
|
|
|
|
|
}
|
|
|
|
|
this.stylesheet.push(loader.cssRuleset({
|
|
|
|
|
[selector]: {
|
|
|
|
|
"background-image": gradient + "url(\"" + image.src + "\")"
|
|
|
|
|
}
|
|
|
|
|
}))
|
2020-10-29 06:07:56 +01:00
|
|
|
|
}
|
|
|
|
|
}))
|
|
|
|
|
image.id = name
|
2020-11-04 01:12:46 +01:00
|
|
|
|
promises.push(file.blob().then(blob => {
|
|
|
|
|
image.src = URL.createObjectURL(blob)
|
|
|
|
|
}))
|
2020-10-29 06:07:56 +01:00
|
|
|
|
loader.assetsDiv.appendChild(image)
|
2020-10-31 12:47:42 +01:00
|
|
|
|
var oldImage = assets.image[id]
|
|
|
|
|
if(oldImage && oldImage.parentNode){
|
2020-11-04 01:12:46 +01:00
|
|
|
|
URL.revokeObjectURL(oldImage.src)
|
2020-10-31 12:47:42 +01:00
|
|
|
|
oldImage.parentNode.removeChild(oldImage)
|
|
|
|
|
}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
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))
|
|
|
|
|
}
|
2020-10-31 12:47:42 +01:00
|
|
|
|
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)
|
|
|
|
|
}))
|
|
|
|
|
}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
}
|
|
|
|
|
return Promise.all(promises)
|
2019-02-03 13:04:25 +01:00
|
|
|
|
}
|
|
|
|
|
loadSound(file, name, gain){
|
|
|
|
|
var id = this.getFilename(name)
|
2020-10-29 06:07:56 +01:00
|
|
|
|
return gain.load(file).then(sound => {
|
2019-02-03 13:04:25 +01:00
|
|
|
|
assets.sounds[id] = sound
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
getFilename(name){
|
|
|
|
|
return name.slice(0, name.lastIndexOf("."))
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-11 15:28:22 +01:00
|
|
|
|
addPlugin(fileObj){
|
|
|
|
|
var file = fileObj.file
|
|
|
|
|
var filePromise = file.read()
|
|
|
|
|
return filePromise.then(dataRaw => {
|
|
|
|
|
var name = file.name.slice(0, file.name.lastIndexOf(".taikoweb.js"))
|
|
|
|
|
this.plugins.push({
|
|
|
|
|
name: name,
|
|
|
|
|
data: dataRaw
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-09 13:36:57 +01:00
|
|
|
|
getCategory(file, exclude){
|
2020-10-29 06:07:56 +01:00
|
|
|
|
var path = file.path.toLowerCase().split("/")
|
2019-01-05 08:44:28 +01:00
|
|
|
|
for(var i = path.length - 2; i >= 0; i--){
|
2020-03-09 13:36:57 +01:00
|
|
|
|
var hasTitle = false
|
|
|
|
|
for(var j in exclude){
|
2020-03-25 22:56:49 +01:00
|
|
|
|
if(exclude[j] && path[i].indexOf(exclude[j].toLowerCase()) !== -1){
|
2020-03-09 13:36:57 +01:00
|
|
|
|
hasTitle = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!hasTitle){
|
2020-04-26 22:56:31 +02:00
|
|
|
|
for(var cat in this.categoryAliases){
|
2020-03-09 13:36:57 +01:00
|
|
|
|
if(path[i].indexOf(cat) !== -1){
|
2020-04-26 22:56:31 +02:00
|
|
|
|
return this.categoryAliases[cat]
|
2020-03-09 13:36:57 +01:00
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-03 13:04:25 +01:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-05 08:44:28 +01:00
|
|
|
|
loaded(){
|
|
|
|
|
this.songs = this.songs.filter(song => typeof song !== "undefined")
|
2019-02-03 13:04:25 +01:00
|
|
|
|
if(this.stylesheet.length){
|
|
|
|
|
var style = document.createElement("style")
|
|
|
|
|
style.appendChild(document.createTextNode(this.stylesheet.join("\n")))
|
|
|
|
|
document.head.appendChild(style)
|
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
if(this.songs.length){
|
2020-10-29 06:07:56 +01:00
|
|
|
|
if(this.limited){
|
|
|
|
|
assets.otherFiles = this.otherFiles
|
2020-10-31 12:47:42 +01:00
|
|
|
|
assets.otherFiles.songTitle = this.songTitle
|
2020-10-29 06:07:56 +01:00
|
|
|
|
}
|
|
|
|
|
return Promise.resolve(this.songs)
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}else{
|
2022-02-11 15:28:22 +01:00
|
|
|
|
if(this.noPlugins && this.pluginAmount || Object.keys(this.assetFiles).length){
|
|
|
|
|
return Promise.resolve()
|
|
|
|
|
}else{
|
|
|
|
|
return Promise.reject("nosongs")
|
|
|
|
|
}
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
2020-10-29 06:07:56 +01:00
|
|
|
|
this.clean()
|
2019-01-05 08:44:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-03 13:04:25 +01:00
|
|
|
|
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("/")
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-05 08:44:28 +01:00
|
|
|
|
clean(){
|
|
|
|
|
delete this.songs
|
|
|
|
|
delete this.tjaFiles
|
|
|
|
|
delete this.osuFiles
|
2020-10-31 12:47:42 +01:00
|
|
|
|
delete this.assetFiles
|
2019-01-05 08:44:28 +01:00
|
|
|
|
delete this.otherFiles
|
|
|
|
|
}
|
|
|
|
|
}
|