ImportSongs: Add plugin support

- Files with filenames that end with .taikoweb.js can be imported and run to add custom functionality to the game
- The plugin file is a javascript module script that should have a class in the default export
- Currently supported methods in the class: name (string), load, start, stop, unload (functions)
- The class can be extended from the Patch class to add automatic patching of variables and functions
- Here are some of the plugins I made: https://github.com/KatieFrogs/taiko-web-plugins
This commit is contained in:
KatieFrogs
2022-02-11 17:28:22 +03:00
parent fd114d9f69
commit 1db4eb6710
43 changed files with 803 additions and 193 deletions

View File

@@ -1,12 +1,19 @@
class ImportSongs{
constructor(limited, otherFiles){
constructor(...args){
this.init(...args)
}
init(limited, otherFiles, noPlugins, pluginAmount){
this.limited = limited
this.tjaFiles = []
this.osuFiles = []
this.assetFiles = {}
this.pluginFiles = []
this.otherFiles = otherFiles || {}
this.noPlugins = noPlugins
this.pluginAmount = pluginAmount
this.songs = []
this.stylesheet = []
this.plugins = []
this.songTitle = this.otherFiles.songTitle || {}
this.uraRegex = /\s*[\(]裏[\)]$/
this.courseTypes = {
@@ -77,11 +84,48 @@
if(!(name in this.assetFiles)){
this.assetFiles[name] = file
}
}else if(name.endsWith(".taikoweb.js")){
this.pluginFiles.push({
file: file,
index: i
})
}else{
this.otherFiles[path] = file
}
}
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 => {
var plugin = plugins.add(obj.data, obj.name)
if(plugin){
pluginAmount++
plugins.imported.push({
name: plugin.name,
plugin: plugin
})
startPromises.push(plugin.start())
}
})
}
return Promise.all(startPromises).then(() => {
var importSongs = new ImportSongs(this.limited, this.otherFiles, true, pluginAmount)
return importSongs.load(files)
})
})
}
var metaPromises = []
metaFiles.forEach(fileObj => {
metaPromises.push(this.addMeta(fileObj))
@@ -468,6 +512,18 @@
return name.slice(0, name.lastIndexOf("."))
}
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
})
})
}
getCategory(file, exclude){
var path = file.path.toLowerCase().split("/")
for(var i = path.length - 2; i >= 0; i--){
@@ -543,10 +599,12 @@
assets.otherFiles.songTitle = this.songTitle
}
return Promise.resolve(this.songs)
}else if(Object.keys(this.assetFiles).length){
return Promise.resolve()
}else{
return Promise.reject("nosongs")
if(this.noPlugins && this.pluginAmount || Object.keys(this.assetFiles).length){
return Promise.resolve()
}else{
return Promise.reject("nosongs")
}
}
this.clean()
}