mirror of
https://github.com/jiojciojsioe3/a3cjroijsiojiorj.git
synced 2024-11-15 15:31:51 +08:00
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:
parent
fd114d9f69
commit
1db4eb6710
@ -1,5 +1,8 @@
|
|||||||
class About{
|
class About{
|
||||||
constructor(touchEnabled){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(touchEnabled){
|
||||||
this.touchEnabled = touchEnabled
|
this.touchEnabled = touchEnabled
|
||||||
loader.changePage("about", true)
|
loader.changePage("about", true)
|
||||||
cancelTouch = false
|
cancelTouch = false
|
||||||
|
@ -20,7 +20,10 @@ function filePermission(file){
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
class RemoteFile{
|
class RemoteFile{
|
||||||
constructor(url){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(url){
|
||||||
this.url = url
|
this.url = url
|
||||||
try{
|
try{
|
||||||
this.path = new URL(url).pathname
|
this.path = new URL(url).pathname
|
||||||
@ -53,7 +56,10 @@ class RemoteFile{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class LocalFile{
|
class LocalFile{
|
||||||
constructor(file, path){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(file, path){
|
||||||
this.file = file
|
this.file = file
|
||||||
this.path = path || file.webkitRelativePath
|
this.path = path || file.webkitRelativePath
|
||||||
this.url = this.path
|
this.url = this.path
|
||||||
@ -70,7 +76,10 @@ class LocalFile{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class FilesystemFile{
|
class FilesystemFile{
|
||||||
constructor(file, path){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(file, path){
|
||||||
this.file = file
|
this.file = file
|
||||||
this.path = path
|
this.path = path
|
||||||
this.url = this.path
|
this.url = this.path
|
||||||
@ -87,7 +96,10 @@ class FilesystemFile{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class GdriveFile{
|
class GdriveFile{
|
||||||
constructor(fileObj){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(fileObj){
|
||||||
this.path = fileObj.path
|
this.path = fileObj.path
|
||||||
this.name = fileObj.name
|
this.name = fileObj.name
|
||||||
this.id = fileObj.id
|
this.id = fileObj.id
|
||||||
@ -108,7 +120,10 @@ class GdriveFile{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class CachedFile{
|
class CachedFile{
|
||||||
constructor(contents, oldFile){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(contents, oldFile){
|
||||||
this.contents = contents
|
this.contents = contents
|
||||||
this.oldFile = oldFile
|
this.oldFile = oldFile
|
||||||
this.path = oldFile.path
|
this.path = oldFile.path
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Account{
|
class Account{
|
||||||
constructor(touchEnabled){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(touchEnabled){
|
||||||
this.touchEnabled = touchEnabled
|
this.touchEnabled = touchEnabled
|
||||||
cancelTouch = false
|
cancelTouch = false
|
||||||
this.locked = false
|
this.locked = false
|
||||||
|
@ -36,7 +36,8 @@ var assets = {
|
|||||||
"lyrics.js",
|
"lyrics.js",
|
||||||
"customsongs.js",
|
"customsongs.js",
|
||||||
"abstractfile.js",
|
"abstractfile.js",
|
||||||
"idb.js"
|
"idb.js",
|
||||||
|
"plugins.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"main.css",
|
"main.css",
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class AutoScore {
|
class AutoScore {
|
||||||
constructor(difficulty, level, scoremode, circles) {
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(difficulty, level, scoremode, circles) {
|
||||||
this.scoremode = scoremode;
|
this.scoremode = scoremode;
|
||||||
this.circles = circles;
|
this.circles = circles;
|
||||||
this.basic_max_score_list = {
|
this.basic_max_score_list = {
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class CanvasAsset{
|
class CanvasAsset{
|
||||||
constructor(view, layer, position){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(view, layer, position){
|
||||||
this.ctx = view.ctx
|
this.ctx = view.ctx
|
||||||
this.view = view
|
this.view = view
|
||||||
this.position = position
|
this.position = position
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class CanvasCache{
|
class CanvasCache{
|
||||||
constructor(noSmoothing, w, h, scale){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(noSmoothing, w, h, scale){
|
||||||
this.noSmoothing = noSmoothing
|
this.noSmoothing = noSmoothing
|
||||||
if(w){
|
if(w){
|
||||||
this.resize(w, h, scale)
|
this.resize(w, h, scale)
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class CanvasDraw{
|
class CanvasDraw{
|
||||||
constructor(noSmoothing){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(noSmoothing){
|
||||||
this.diffStarPath = new Path2D(vectors.diffStar)
|
this.diffStarPath = new Path2D(vectors.diffStar)
|
||||||
this.longVowelMark = new Path2D(vectors.longVowelMark)
|
this.longVowelMark = new Path2D(vectors.longVowelMark)
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class CanvasTest{
|
class CanvasTest{
|
||||||
constructor(){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
this.canvas = document.createElement("canvas")
|
this.canvas = document.createElement("canvas")
|
||||||
var pixelRatio = window.devicePixelRatio || 1
|
var pixelRatio = window.devicePixelRatio || 1
|
||||||
var width = innerWidth * pixelRatio
|
var width = innerWidth * pixelRatio
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Circle{
|
class Circle{
|
||||||
constructor(config){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(config){
|
||||||
this.id = config.id
|
this.id = config.id
|
||||||
this.ms = config.start
|
this.ms = config.start
|
||||||
this.originalMS = this.ms
|
this.originalMS = this.ms
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Controller{
|
class Controller{
|
||||||
constructor(selectedSong, songData, autoPlayEnabled, multiplayer, touchEnabled){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(selectedSong, songData, autoPlayEnabled, multiplayer, touchEnabled){
|
||||||
this.selectedSong = selectedSong
|
this.selectedSong = selectedSong
|
||||||
this.songData = songData
|
this.songData = songData
|
||||||
this.autoPlayEnabled = autoPlayEnabled
|
this.autoPlayEnabled = autoPlayEnabled
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class CustomSongs{
|
class CustomSongs{
|
||||||
constructor(touchEnabled, noPage){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(touchEnabled, noPage){
|
||||||
this.loaderDiv = document.createElement("div")
|
this.loaderDiv = document.createElement("div")
|
||||||
this.loaderDiv.innerHTML = assets.pages["loadsong"]
|
this.loaderDiv.innerHTML = assets.pages["loadsong"]
|
||||||
var loadingText = this.loaderDiv.querySelector("#loading-text")
|
var loadingText = this.loaderDiv.querySelector("#loading-text")
|
||||||
@ -151,8 +154,10 @@ class CustomSongs{
|
|||||||
this.changeSelected(this.linkLocalFolder)
|
this.changeSelected(this.linkLocalFolder)
|
||||||
if(typeof showDirectoryPicker === "function"){
|
if(typeof showDirectoryPicker === "function"){
|
||||||
return showDirectoryPicker().then(file => {
|
return showDirectoryPicker().then(file => {
|
||||||
this.walkFilesystem(file).then(files => this.importLocal(files)).then(e => {
|
this.walkFilesystem(file).then(files => this.importLocal(files)).then(input => {
|
||||||
|
if(input){
|
||||||
db.setItem("customFolder", [file])
|
db.setItem("customFolder", [file])
|
||||||
|
}
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
if(e !== "cancel"){
|
if(e !== "cancel"){
|
||||||
return Promise.reject(e)
|
return Promise.reject(e)
|
||||||
@ -217,8 +222,8 @@ class CustomSongs{
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Promise.all(dropPromises).then(() => this.importLocal(allFiles)).then(() => {
|
Promise.all(dropPromises).then(() => this.importLocal(allFiles)).then(input => {
|
||||||
if(dbItems.length){
|
if(input && dbItems.length){
|
||||||
db.setItem("customFolder", dbItems)
|
db.setItem("customFolder", dbItems)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -265,6 +270,7 @@ class CustomSongs{
|
|||||||
}else if(e !== "cancel"){
|
}else if(e !== "cancel"){
|
||||||
return Promise.reject(e)
|
return Promise.reject(e)
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
gdriveFolder(event){
|
gdriveFolder(event){
|
||||||
@ -387,6 +393,7 @@ class CustomSongs{
|
|||||||
new SongSelect("customSongs", false, this.touchEnabled)
|
new SongSelect("customSongs", false, this.touchEnabled)
|
||||||
pageEvents.send("import-songs", length)
|
pageEvents.send("import-songs", length)
|
||||||
}, 500)
|
}, 500)
|
||||||
|
return songs && songs.length
|
||||||
}
|
}
|
||||||
keyPressed(pressed, name){
|
keyPressed(pressed, name){
|
||||||
if(!pressed || this.locked){
|
if(!pressed || this.locked){
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Debug{
|
class Debug{
|
||||||
constructor(){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
if(!assets.pages["debug"]){
|
if(!assets.pages["debug"]){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -329,7 +332,10 @@ class Debug{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class InputSlider{
|
class InputSlider{
|
||||||
constructor(sliderDiv, min, max, fixedPoint){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(sliderDiv, min, max, fixedPoint){
|
||||||
this.fixedPoint = fixedPoint
|
this.fixedPoint = fixedPoint
|
||||||
this.mul = Math.pow(10, fixedPoint)
|
this.mul = Math.pow(10, fixedPoint)
|
||||||
this.min = min * this.mul
|
this.min = min * this.mul
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Game{
|
class Game{
|
||||||
constructor(controller, selectedSong, songData){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(controller, selectedSong, songData){
|
||||||
this.controller = controller
|
this.controller = controller
|
||||||
this.selectedSong = selectedSong
|
this.selectedSong = selectedSong
|
||||||
this.songData = songData
|
this.songData = songData
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class GameInput{
|
class GameInput{
|
||||||
constructor(controller){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(controller){
|
||||||
this.controller = controller
|
this.controller = controller
|
||||||
this.game = this.controller.game
|
this.game = this.controller.game
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Gamepad{
|
class Gamepad{
|
||||||
constructor(bindings, callback){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(bindings, callback){
|
||||||
this.bindings = bindings
|
this.bindings = bindings
|
||||||
this.callback = !!callback
|
this.callback = !!callback
|
||||||
this.b = {
|
this.b = {
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class GameRules{
|
class GameRules{
|
||||||
constructor(game){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(game){
|
||||||
this.difficulty = game.controller.selectedSong.difficulty
|
this.difficulty = game.controller.selectedSong.difficulty
|
||||||
var frame = 1000 / 60
|
var frame = 1000 / 60
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Gpicker{
|
class Gpicker{
|
||||||
constructor(){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
this.apiKey = gameConfig.google_credentials.api_key
|
this.apiKey = gameConfig.google_credentials.api_key
|
||||||
this.oauthClientId = gameConfig.google_credentials.oauth_client_id
|
this.oauthClientId = gameConfig.google_credentials.oauth_client_id
|
||||||
this.projectNumber = gameConfig.google_credentials.project_number
|
this.projectNumber = gameConfig.google_credentials.project_number
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
class IDB{
|
class IDB{
|
||||||
constructor(name, store){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(name, store){
|
||||||
this.name = name
|
this.name = name
|
||||||
this.store = store
|
this.store = store
|
||||||
}
|
}
|
||||||
init(){
|
start(){
|
||||||
if(this.db){
|
if(this.db){
|
||||||
return Promise.resolve(this.db)
|
return Promise.resolve(this.db)
|
||||||
}
|
}
|
||||||
@ -31,7 +34,7 @@ class IDB{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
transaction(method, ...args){
|
transaction(method, ...args){
|
||||||
return this.init().then(db =>
|
return this.start().then(db =>
|
||||||
db.transaction(this.store, "readwrite").objectStore(this.store)[method](...args)
|
db.transaction(this.store, "readwrite").objectStore(this.store)[method](...args)
|
||||||
).then(this.promise.bind(this))
|
).then(this.promise.bind(this))
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
class ImportSongs{
|
class ImportSongs{
|
||||||
constructor(limited, otherFiles){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(limited, otherFiles, noPlugins, pluginAmount){
|
||||||
this.limited = limited
|
this.limited = limited
|
||||||
this.tjaFiles = []
|
this.tjaFiles = []
|
||||||
this.osuFiles = []
|
this.osuFiles = []
|
||||||
this.assetFiles = {}
|
this.assetFiles = {}
|
||||||
|
this.pluginFiles = []
|
||||||
this.otherFiles = otherFiles || {}
|
this.otherFiles = otherFiles || {}
|
||||||
|
this.noPlugins = noPlugins
|
||||||
|
this.pluginAmount = pluginAmount
|
||||||
this.songs = []
|
this.songs = []
|
||||||
this.stylesheet = []
|
this.stylesheet = []
|
||||||
|
this.plugins = []
|
||||||
this.songTitle = this.otherFiles.songTitle || {}
|
this.songTitle = this.otherFiles.songTitle || {}
|
||||||
this.uraRegex = /\s*[\((]裏[\))]$/
|
this.uraRegex = /\s*[\((]裏[\))]$/
|
||||||
this.courseTypes = {
|
this.courseTypes = {
|
||||||
@ -77,11 +84,48 @@
|
|||||||
if(!(name in this.assetFiles)){
|
if(!(name in this.assetFiles)){
|
||||||
this.assetFiles[name] = file
|
this.assetFiles[name] = file
|
||||||
}
|
}
|
||||||
|
}else if(name.endsWith(".taikoweb.js")){
|
||||||
|
this.pluginFiles.push({
|
||||||
|
file: file,
|
||||||
|
index: i
|
||||||
|
})
|
||||||
}else{
|
}else{
|
||||||
this.otherFiles[path] = file
|
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 = []
|
var metaPromises = []
|
||||||
metaFiles.forEach(fileObj => {
|
metaFiles.forEach(fileObj => {
|
||||||
metaPromises.push(this.addMeta(fileObj))
|
metaPromises.push(this.addMeta(fileObj))
|
||||||
@ -468,6 +512,18 @@
|
|||||||
return name.slice(0, name.lastIndexOf("."))
|
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){
|
getCategory(file, exclude){
|
||||||
var path = file.path.toLowerCase().split("/")
|
var path = file.path.toLowerCase().split("/")
|
||||||
for(var i = path.length - 2; i >= 0; i--){
|
for(var i = path.length - 2; i >= 0; i--){
|
||||||
@ -543,11 +599,13 @@
|
|||||||
assets.otherFiles.songTitle = this.songTitle
|
assets.otherFiles.songTitle = this.songTitle
|
||||||
}
|
}
|
||||||
return Promise.resolve(this.songs)
|
return Promise.resolve(this.songs)
|
||||||
}else if(Object.keys(this.assetFiles).length){
|
}else{
|
||||||
|
if(this.noPlugins && this.pluginAmount || Object.keys(this.assetFiles).length){
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}else{
|
}else{
|
||||||
return Promise.reject("nosongs")
|
return Promise.reject("nosongs")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.clean()
|
this.clean()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Keyboard{
|
class Keyboard{
|
||||||
constructor(bindings, callback){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(bindings, callback){
|
||||||
this.bindings = bindings
|
this.bindings = bindings
|
||||||
this.callback = callback
|
this.callback = callback
|
||||||
this.wildcard = false
|
this.wildcard = false
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Loader{
|
class Loader{
|
||||||
constructor(callback){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(callback){
|
||||||
this.callback = callback
|
this.callback = callback
|
||||||
this.loadedAssets = 0
|
this.loadedAssets = 0
|
||||||
this.assetsDiv = document.getElementById("assets")
|
this.assetsDiv = document.getElementById("assets")
|
||||||
@ -253,6 +256,7 @@ class Loader{
|
|||||||
pageEvents.setKbd()
|
pageEvents.setKbd()
|
||||||
scoreStorage = new ScoreStorage()
|
scoreStorage = new ScoreStorage()
|
||||||
db = new IDB("taiko", "store")
|
db = new IDB("taiko", "store")
|
||||||
|
plugins = new Plugins()
|
||||||
|
|
||||||
Promise.all(this.promises).then(() => {
|
Promise.all(this.promises).then(() => {
|
||||||
if(this.error){
|
if(this.error){
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class LoadSong{
|
class LoadSong{
|
||||||
constructor(selectedSong, autoPlayEnabled, multiplayer, touchEnabled){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(selectedSong, autoPlayEnabled, multiplayer, touchEnabled){
|
||||||
this.selectedSong = selectedSong
|
this.selectedSong = selectedSong
|
||||||
this.autoPlayEnabled = autoPlayEnabled
|
this.autoPlayEnabled = autoPlayEnabled
|
||||||
this.multiplayer = multiplayer
|
this.multiplayer = multiplayer
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Logo{
|
class Logo{
|
||||||
constructor(){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
this.canvas = document.getElementById("logo")
|
this.canvas = document.getElementById("logo")
|
||||||
this.ctx = this.canvas.getContext("2d")
|
this.ctx = this.canvas.getContext("2d")
|
||||||
this.pathSvg = failedTests.indexOf("Path2D SVG") === -1 && vectors.logo1
|
this.pathSvg = failedTests.indexOf("Path2D SVG") === -1 && vectors.logo1
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Lyrics{
|
class Lyrics{
|
||||||
constructor(file, songOffset, div, parsed){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(file, songOffset, div, parsed){
|
||||||
this.div = div
|
this.div = div
|
||||||
this.stroke = document.createElement("div")
|
this.stroke = document.createElement("div")
|
||||||
this.stroke.classList.add("stroke")
|
this.stroke.classList.add("stroke")
|
||||||
|
@ -91,6 +91,7 @@ var scoreStorage
|
|||||||
var account = {}
|
var account = {}
|
||||||
var gpicker
|
var gpicker
|
||||||
var db
|
var db
|
||||||
|
var plugins
|
||||||
|
|
||||||
pageEvents.add(root, ["touchstart", "touchmove", "touchend"], event => {
|
pageEvents.add(root, ["touchstart", "touchmove", "touchend"], event => {
|
||||||
if(event.cancelable && cancelTouch && event.target.tagName !== "SELECT"){
|
if(event.cancelable && cancelTouch && event.target.tagName !== "SELECT"){
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Mekadon{
|
class Mekadon{
|
||||||
constructor(controller, game){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(controller, game){
|
||||||
this.controller = controller
|
this.controller = controller
|
||||||
this.game = game
|
this.game = game
|
||||||
this.lr = false
|
this.lr = false
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class P2Connection{
|
class P2Connection{
|
||||||
constructor(){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
this.closed = true
|
this.closed = true
|
||||||
this.lastMessages = {}
|
this.lastMessages = {}
|
||||||
this.otherConnected = false
|
this.otherConnected = false
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class PageEvents{
|
class PageEvents{
|
||||||
constructor(){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
this.allEvents = new Map()
|
this.allEvents = new Map()
|
||||||
this.keyListeners = new Map()
|
this.keyListeners = new Map()
|
||||||
this.mouseListeners = new Map()
|
this.mouseListeners = new Map()
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class ParseOsu{
|
class ParseOsu{
|
||||||
constructor(fileContent, difficulty, stars, offset, metaOnly){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(fileContent, difficulty, stars, offset, metaOnly){
|
||||||
this.osu = {
|
this.osu = {
|
||||||
OFFSET: 0,
|
OFFSET: 0,
|
||||||
MSPERBEAT: 1,
|
MSPERBEAT: 1,
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class ParseTja{
|
class ParseTja{
|
||||||
constructor(file, difficulty, stars, offset, metaOnly){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(file, difficulty, stars, offset, metaOnly){
|
||||||
this.data = []
|
this.data = []
|
||||||
for(let line of file){
|
for(let line of file){
|
||||||
var indexComment = line.indexOf("//")
|
var indexComment = line.indexOf("//")
|
||||||
|
342
public/src/js/plugins.js
Normal file
342
public/src/js/plugins.js
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
class Plugins{
|
||||||
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
|
this.imported = []
|
||||||
|
this.allPlugins = []
|
||||||
|
this.pluginMap = {}
|
||||||
|
this.hashes = []
|
||||||
|
}
|
||||||
|
add(script, name){
|
||||||
|
var hash = md5.base64(script.toString())
|
||||||
|
if(this.hashes.indexOf(hash) !== -1){
|
||||||
|
console.warn("Skip adding an already addded plugin: " + name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
name = name || "plugin"
|
||||||
|
var baseName = name
|
||||||
|
for(var i = 2; name in this.allPlugins; i++){
|
||||||
|
name = baseName + i.toString()
|
||||||
|
}
|
||||||
|
var plugin = new PluginLoader(script, name, hash)
|
||||||
|
this.allPlugins.push({
|
||||||
|
name: name,
|
||||||
|
plugin: plugin
|
||||||
|
})
|
||||||
|
this.pluginMap[name] = plugin
|
||||||
|
this.hashes.push(hash)
|
||||||
|
return plugin
|
||||||
|
}
|
||||||
|
remove(name){
|
||||||
|
var hash = this.pluginMap[name].hash
|
||||||
|
if(hash){
|
||||||
|
var index = this.hashes.indexOf(hash)
|
||||||
|
if(index !== -1){
|
||||||
|
this.hashes.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.unload(name)
|
||||||
|
var index = this.imported.findIndex(obj => obj.name === name)
|
||||||
|
if(index !== -1){
|
||||||
|
this.imported.splice(index, 1)
|
||||||
|
}
|
||||||
|
var index = this.allPlugins.findIndex(obj => obj.name === name)
|
||||||
|
if(index !== -1){
|
||||||
|
this.allPlugins.splice(index, 1)
|
||||||
|
}
|
||||||
|
delete this.pluginMap[name]
|
||||||
|
}
|
||||||
|
load(name){
|
||||||
|
this.pluginMap[name].load()
|
||||||
|
}
|
||||||
|
loadAll(){
|
||||||
|
for(var i = 0; i < this.allPlugins.length; i++){
|
||||||
|
this.allPlugins[i].plugin.load()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
start(name){
|
||||||
|
this.pluginMap[name].start()
|
||||||
|
}
|
||||||
|
startAll(){
|
||||||
|
for(var i = 0; i < this.allPlugins.length; i++){
|
||||||
|
this.allPlugins[i].plugin.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stop(name){
|
||||||
|
this.pluginMap[name].stop()
|
||||||
|
}
|
||||||
|
stopAll(){
|
||||||
|
for(var i = this.allPlugins.length; i--;){
|
||||||
|
this.allPlugins[i].plugin.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unload(name){
|
||||||
|
this.pluginMap[name].unload()
|
||||||
|
}
|
||||||
|
unloadAll(){
|
||||||
|
for(var i = this.allPlugins.length; i--;){
|
||||||
|
this.allPlugins[i].plugin.unload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unloadImported(){
|
||||||
|
for(var i = this.imported.length; i--;){
|
||||||
|
this.imported[i].plugin.unload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strFromFunc(func){
|
||||||
|
var output = func.toString()
|
||||||
|
return output.slice(output.indexOf("{") + 1, output.lastIndexOf("}"))
|
||||||
|
}
|
||||||
|
argsFromFunc(func){
|
||||||
|
var output = func.toString()
|
||||||
|
output = output.slice(0, output.indexOf("{"))
|
||||||
|
output = output.slice(output.indexOf("(") + 1, output.lastIndexOf(")"))
|
||||||
|
return output.split(",").map(str => str.trim()).filter(Boolean)
|
||||||
|
}
|
||||||
|
insertBefore(input, insertedText, searchString){
|
||||||
|
var index = input.indexOf(searchString)
|
||||||
|
if(index === -1){
|
||||||
|
throw new Error("searchString not found: " + searchString)
|
||||||
|
}
|
||||||
|
return input.slice(0, index) + insertedText + input.slice(index)
|
||||||
|
}
|
||||||
|
insertAfter(input, searchString, insertedText){
|
||||||
|
var index = input.indexOf(searchString)
|
||||||
|
if(index === -1){
|
||||||
|
throw new Error("searchString not found: " + searchString)
|
||||||
|
}
|
||||||
|
var length = searchString.length
|
||||||
|
return input.slice(0, index + length) + insertedText + input.slice(index + length)
|
||||||
|
}
|
||||||
|
strReplace(input, searchString, insertedText){
|
||||||
|
var index = input.indexOf(searchString)
|
||||||
|
if(index === -1){
|
||||||
|
throw new Error("searchString not found: " + searchString)
|
||||||
|
}
|
||||||
|
return input.slice(0, index) + insertedText + input.slice(index + searchString.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
getSettings(){
|
||||||
|
var items = {}
|
||||||
|
for(var i = 0; i < this.allPlugins.length; i++){
|
||||||
|
var obj = this.allPlugins[i]
|
||||||
|
var plugin = obj.plugin
|
||||||
|
items[obj.name] = {
|
||||||
|
name: plugin.module.name || obj.name,
|
||||||
|
type: "toggle",
|
||||||
|
default: true,
|
||||||
|
getItem: () => plugin.started,
|
||||||
|
setItem: value => {
|
||||||
|
if(plugin.started && !value){
|
||||||
|
plugin.stop()
|
||||||
|
}else if(!plugin.started && value){
|
||||||
|
plugin.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PluginLoader{
|
||||||
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(script, name, hash){
|
||||||
|
this.name = name
|
||||||
|
this.hash = hash
|
||||||
|
if(typeof script === "string"){
|
||||||
|
this.url = URL.createObjectURL(new Blob([script], {
|
||||||
|
type: "application/javascript"
|
||||||
|
}))
|
||||||
|
}else{
|
||||||
|
this.class = script
|
||||||
|
}
|
||||||
|
}
|
||||||
|
load(){
|
||||||
|
if(this.loaded || !this.url && !this.class){
|
||||||
|
return Promise.resolve()
|
||||||
|
}else{
|
||||||
|
return (this.url ? import(this.url) : Promise.resolve({
|
||||||
|
default: this.class
|
||||||
|
})).then(module => {
|
||||||
|
if(this.url){
|
||||||
|
URL.revokeObjectURL(this.url)
|
||||||
|
delete this.url
|
||||||
|
}else{
|
||||||
|
delete this.class
|
||||||
|
}
|
||||||
|
this.loaded = true
|
||||||
|
try{
|
||||||
|
this.module = new module.default()
|
||||||
|
}catch(e){
|
||||||
|
console.error(e)
|
||||||
|
this.error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
if(this.module.beforeLoad){
|
||||||
|
this.module.beforeLoad(this)
|
||||||
|
}
|
||||||
|
if(this.module.load){
|
||||||
|
this.module.load(this)
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.error(e)
|
||||||
|
this.error()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
start(){
|
||||||
|
return this.load().then(() => {
|
||||||
|
if(!this.started && this.module){
|
||||||
|
this.started = true
|
||||||
|
try{
|
||||||
|
if(this.module.beforeStart){
|
||||||
|
this.module.beforeStart()
|
||||||
|
}
|
||||||
|
if(this.module.start){
|
||||||
|
this.module.start()
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.error(e)
|
||||||
|
this.error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
stop(error){
|
||||||
|
if(this.loaded && this.started){
|
||||||
|
this.started = false
|
||||||
|
try{
|
||||||
|
if(this.module.beforeStop){
|
||||||
|
this.module.beforeStop()
|
||||||
|
}
|
||||||
|
if(this.module.stop){
|
||||||
|
this.module.stop()
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.error(e)
|
||||||
|
if(!error){
|
||||||
|
this.error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unload(error){
|
||||||
|
if(this.loaded){
|
||||||
|
if(this.started){
|
||||||
|
this.stop(error)
|
||||||
|
}
|
||||||
|
this.loaded = false
|
||||||
|
plugins.remove(this.name)
|
||||||
|
if(this.module){
|
||||||
|
try{
|
||||||
|
if(this.module.beforeUnload){
|
||||||
|
this.module.beforeUnload()
|
||||||
|
}
|
||||||
|
if(this.module.unload){
|
||||||
|
this.module.unload()
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
delete this.module
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error(){
|
||||||
|
if(this.module && this.module.error){
|
||||||
|
try{
|
||||||
|
this.module.error()
|
||||||
|
}catch(e){
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.unload(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditValue{
|
||||||
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(parent, name){
|
||||||
|
if(name){
|
||||||
|
this.original = parent[name]
|
||||||
|
this.name = [parent, name]
|
||||||
|
this.delete = !(name in parent)
|
||||||
|
}else{
|
||||||
|
this.original = parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
load(callback){
|
||||||
|
var output = callback(this.original)
|
||||||
|
if(typeof output === "undefined"){
|
||||||
|
throw new Error("A value is expected to be returned")
|
||||||
|
}
|
||||||
|
this.edited = output
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
start(){
|
||||||
|
if(this.name){
|
||||||
|
this.name[0][this.name[1]] = this.edited
|
||||||
|
}
|
||||||
|
return this.edited
|
||||||
|
}
|
||||||
|
stop(){
|
||||||
|
if(this.name){
|
||||||
|
if(this.delete){
|
||||||
|
delete this.name[0][this.name[1]]
|
||||||
|
}else{
|
||||||
|
this.name[0][this.name[1]] = this.original
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.original
|
||||||
|
}
|
||||||
|
unload(){
|
||||||
|
delete this.name
|
||||||
|
delete this.edited
|
||||||
|
delete this.original
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditFunction extends EditValue{
|
||||||
|
load(callback){
|
||||||
|
var output = callback(plugins.strFromFunc(this.original))
|
||||||
|
if(typeof output === "undefined"){
|
||||||
|
throw new Error("A value is expected to be returned")
|
||||||
|
}
|
||||||
|
var args = plugins.argsFromFunc(this.original)
|
||||||
|
this.edited = Function(...args, output)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Patch{
|
||||||
|
edits = []
|
||||||
|
addEdits(...args){
|
||||||
|
args.forEach(arg => this.edits.push(arg))
|
||||||
|
}
|
||||||
|
beforeStart(){
|
||||||
|
this.edits.forEach(edit => edit.start())
|
||||||
|
}
|
||||||
|
beforeStop(){
|
||||||
|
this.edits.forEach(edit => edit.stop())
|
||||||
|
}
|
||||||
|
beforeUnload(){
|
||||||
|
this.edits.forEach(edit => edit.unload())
|
||||||
|
}
|
||||||
|
log(message){
|
||||||
|
var name = this.name || "Plugin"
|
||||||
|
console.log(
|
||||||
|
"%c[" + name + "]%c " + message,
|
||||||
|
"font-weight: bold;",
|
||||||
|
""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
class Scoresheet{
|
class Scoresheet{
|
||||||
constructor(controller, results, multiplayer, touchEnabled){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(controller, results, multiplayer, touchEnabled){
|
||||||
this.controller = controller
|
this.controller = controller
|
||||||
this.resultsObj = results
|
this.resultsObj = results
|
||||||
this.player = [multiplayer ? (p2.player === 1 ? 0 : 1) : 0]
|
this.player = [multiplayer ? (p2.player === 1 ? 0 : 1) : 0]
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class ScoreStorage{
|
class ScoreStorage{
|
||||||
constructor(){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
this.scores = {}
|
this.scores = {}
|
||||||
this.scoresP2 = {}
|
this.scoresP2 = {}
|
||||||
this.requestP2 = new Set()
|
this.requestP2 = new Set()
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Session{
|
class Session{
|
||||||
constructor(touchEnabled){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(touchEnabled){
|
||||||
this.touchEnabled = touchEnabled
|
this.touchEnabled = touchEnabled
|
||||||
loader.changePage("session", true)
|
loader.changePage("session", true)
|
||||||
this.endButton = this.getElement("view-end-button")
|
this.endButton = this.getElement("view-end-button")
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Settings{
|
class Settings{
|
||||||
constructor(){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
var ios = /iPhone|iPad/.test(navigator.userAgent)
|
var ios = /iPhone|iPad/.test(navigator.userAgent)
|
||||||
var phone = /Android|iPhone|iPad/.test(navigator.userAgent)
|
var phone = /Android|iPhone|iPad/.test(navigator.userAgent)
|
||||||
this.allLanguages = []
|
this.allLanguages = []
|
||||||
@ -151,6 +154,7 @@ class Settings{
|
|||||||
loader.screen.style.fontFamily = strings.font
|
loader.screen.style.fontFamily = strings.font
|
||||||
loader.screen.style.fontWeight = boldFonts ? "bold" : ""
|
loader.screen.style.fontWeight = boldFonts ? "bold" : ""
|
||||||
loader.screen.classList[boldFonts ? "add" : "remove"]("bold-fonts")
|
loader.screen.classList[boldFonts ? "add" : "remove"]("bold-fonts")
|
||||||
|
strings.plural = new Intl.PluralRules(lang.intl)
|
||||||
if(!noEvent){
|
if(!noEvent){
|
||||||
pageEvents.send("language-change", lang.id)
|
pageEvents.send("language-change", lang.id)
|
||||||
}
|
}
|
||||||
@ -158,10 +162,15 @@ class Settings{
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SettingsView{
|
class SettingsView{
|
||||||
constructor(touchEnabled, tutorial, songId, toSetting){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(touchEnabled, tutorial, songId, toSetting, settingsItems){
|
||||||
this.touchEnabled = touchEnabled
|
this.touchEnabled = touchEnabled
|
||||||
this.tutorial = tutorial
|
this.tutorial = tutorial
|
||||||
this.songId = songId
|
this.songId = songId
|
||||||
|
this.customSettings = !!settingsItems
|
||||||
|
this.settingsItems = settingsItems || settings.items
|
||||||
|
|
||||||
loader.changePage("settings", tutorial)
|
loader.changePage("settings", tutorial)
|
||||||
assets.sounds["bgm_settings"].playLoop(0.1, false, 0, 1.392, 26.992)
|
assets.sounds["bgm_settings"].playLoop(0.1, false, 0, 1.392, 26.992)
|
||||||
@ -233,8 +242,8 @@ class SettingsView{
|
|||||||
var content = this.getElement("view-content")
|
var content = this.getElement("view-content")
|
||||||
this.items = []
|
this.items = []
|
||||||
this.selected = 0
|
this.selected = 0
|
||||||
for(let i in settings.items){
|
for(let i in this.settingsItems){
|
||||||
var current = settings.items[i]
|
var current = this.settingsItems[i]
|
||||||
if(
|
if(
|
||||||
!touchEnabled && current.touch === true ||
|
!touchEnabled && current.touch === true ||
|
||||||
touchEnabled && current.touch === false ||
|
touchEnabled && current.touch === false ||
|
||||||
@ -246,7 +255,7 @@ class SettingsView{
|
|||||||
settingBox.classList.add("setting-box")
|
settingBox.classList.add("setting-box")
|
||||||
var nameDiv = document.createElement("div")
|
var nameDiv = document.createElement("div")
|
||||||
nameDiv.classList.add("setting-name", "stroke-sub")
|
nameDiv.classList.add("setting-name", "stroke-sub")
|
||||||
var name = strings.settings[i].name
|
var name = current.name || strings.settings[i].name
|
||||||
this.setAltText(nameDiv, name)
|
this.setAltText(nameDiv, name)
|
||||||
settingBox.appendChild(nameDiv)
|
settingBox.appendChild(nameDiv)
|
||||||
var valueDiv = document.createElement("div")
|
var valueDiv = document.createElement("div")
|
||||||
@ -277,6 +286,7 @@ class SettingsView{
|
|||||||
})
|
})
|
||||||
this.addTouch(this.endButton, this.onEnd.bind(this))
|
this.addTouch(this.endButton, this.onEnd.bind(this))
|
||||||
|
|
||||||
|
if(!this.customSettings){
|
||||||
this.gamepadSettings = document.getElementById("settings-gamepad")
|
this.gamepadSettings = document.getElementById("settings-gamepad")
|
||||||
this.addTouch(this.gamepadSettings, event => {
|
this.addTouch(this.gamepadSettings, event => {
|
||||||
if(event.target === event.currentTarget){
|
if(event.target === event.currentTarget){
|
||||||
@ -372,6 +382,7 @@ class SettingsView{
|
|||||||
settingBox: this.latencyEndButton
|
settingBox: this.latencyEndButton
|
||||||
})
|
})
|
||||||
this.addTouch(this.latencyEndButton, event => this.latencyBack(true))
|
this.addTouch(this.latencyEndButton, event => this.latencyBack(true))
|
||||||
|
}
|
||||||
|
|
||||||
this.setStrings()
|
this.setStrings()
|
||||||
|
|
||||||
@ -432,8 +443,12 @@ class SettingsView{
|
|||||||
pageEvents.remove(element, ["mousedown", "touchend"])
|
pageEvents.remove(element, ["mousedown", "touchend"])
|
||||||
}
|
}
|
||||||
getValue(name, valueDiv){
|
getValue(name, valueDiv){
|
||||||
var current = settings.items[name]
|
var current = this.settingsItems[name]
|
||||||
|
if(current.getItem){
|
||||||
|
var value = current.getItem()
|
||||||
|
}else{
|
||||||
var value = settings.getItem(name)
|
var value = settings.getItem(name)
|
||||||
|
}
|
||||||
if(current.type === "language"){
|
if(current.type === "language"){
|
||||||
value = allStrings[value].name + " (" + value + ")"
|
value = allStrings[value].name + " (" + value + ")"
|
||||||
}else if(current.type === "select" || current.type === "gamepad"){
|
}else if(current.type === "select" || current.type === "gamepad"){
|
||||||
@ -471,8 +486,13 @@ class SettingsView{
|
|||||||
valueDiv.innerText = value
|
valueDiv.innerText = value
|
||||||
}
|
}
|
||||||
setValue(name){
|
setValue(name){
|
||||||
var current = settings.items[name]
|
var promise
|
||||||
|
var current = this.settingsItems[name]
|
||||||
|
if(current.getItem){
|
||||||
|
var value = current.getItem()
|
||||||
|
}else{
|
||||||
var value = settings.getItem(name)
|
var value = settings.getItem(name)
|
||||||
|
}
|
||||||
var selectedIndex = this.items.findIndex(item => item.id === name)
|
var selectedIndex = this.items.findIndex(item => item.id === name)
|
||||||
var selected = this.items[selectedIndex]
|
var selected = this.items[selectedIndex]
|
||||||
if(this.mode !== "settings"){
|
if(this.mode !== "settings"){
|
||||||
@ -511,12 +531,18 @@ class SettingsView{
|
|||||||
this.playSound("se_don")
|
this.playSound("se_don")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if(current.setItem){
|
||||||
|
promise = current.setItem(value)
|
||||||
|
}else{
|
||||||
settings.setItem(name, value)
|
settings.setItem(name, value)
|
||||||
|
}
|
||||||
|
(promise || Promise.resolve()).then(() => {
|
||||||
this.getValue(name, this.items[this.selected].valueDiv)
|
this.getValue(name, this.items[this.selected].valueDiv)
|
||||||
this.playSound("se_ka")
|
this.playSound("se_ka")
|
||||||
if(current.type === "language"){
|
if(current.type === "language"){
|
||||||
this.setLang(allStrings[value])
|
this.setLang(allStrings[value])
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
keyPressed(pressed, name, event, repeat){
|
keyPressed(pressed, name, event, repeat){
|
||||||
if(pressed){
|
if(pressed){
|
||||||
@ -627,7 +653,7 @@ class SettingsView{
|
|||||||
}
|
}
|
||||||
keyboardSet(){
|
keyboardSet(){
|
||||||
var selected = this.items[this.selected]
|
var selected = this.items[this.selected]
|
||||||
var current = settings.items[selected.id]
|
var current = this.settingsItems[selected.id]
|
||||||
selected.valueDiv.innerHTML = ""
|
selected.valueDiv.innerHTML = ""
|
||||||
for(var i in current.default){
|
for(var i in current.default){
|
||||||
var keyDiv = document.createElement("div")
|
var keyDiv = document.createElement("div")
|
||||||
@ -665,7 +691,7 @@ class SettingsView{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var selected = this.items[this.selected]
|
var selected = this.items[this.selected]
|
||||||
var current = settings.items[selected.id]
|
var current = this.settingsItems[selected.id]
|
||||||
if(diff){
|
if(diff){
|
||||||
this.gamepadSelected = this.mod(current.options.length, this.gamepadSelected + diff)
|
this.gamepadSelected = this.mod(current.options.length, this.gamepadSelected + diff)
|
||||||
this.playSound("se_ka")
|
this.playSound("se_ka")
|
||||||
@ -681,7 +707,7 @@ class SettingsView{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var selected = this.items[this.selected]
|
var selected = this.items[this.selected]
|
||||||
var current = settings.items[selected.id]
|
var current = this.settingsItems[selected.id]
|
||||||
settings.setItem(selected.id, current.options[this.gamepadSelected])
|
settings.setItem(selected.id, current.options[this.gamepadSelected])
|
||||||
this.getValue(selected.id, selected.valueDiv)
|
this.getValue(selected.id, selected.valueDiv)
|
||||||
this.playSound(confirm ? "se_don" : "se_cancel")
|
this.playSound(confirm ? "se_don" : "se_cancel")
|
||||||
@ -693,7 +719,7 @@ class SettingsView{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var selected = this.items[this.selected]
|
var selected = this.items[this.selected]
|
||||||
var current = settings.items[selected.id]
|
var current = this.settingsItems[selected.id]
|
||||||
this.latencySettings.style.display = "flex"
|
this.latencySettings.style.display = "flex"
|
||||||
}
|
}
|
||||||
latencyGetValue(name, valueText){
|
latencyGetValue(name, valueText){
|
||||||
@ -801,7 +827,7 @@ class SettingsView{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var selected = this.items[this.selected]
|
var selected = this.items[this.selected]
|
||||||
var current = settings.items[selected.id]
|
var current = this.settingsItems[selected.id]
|
||||||
this.getValue(selected.id, selected.valueDiv)
|
this.getValue(selected.id, selected.valueDiv)
|
||||||
this.playSound(confirm ? "se_don" : "se_cancel")
|
this.playSound(confirm ? "se_don" : "se_cancel")
|
||||||
this.latencySettings.style.display = ""
|
this.latencySettings.style.display = ""
|
||||||
@ -821,10 +847,14 @@ class SettingsView{
|
|||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
defaultSettings(){
|
defaultSettings(){
|
||||||
|
if(this.customSettings){
|
||||||
|
plugins.unloadImported()
|
||||||
|
return this.onEnd()
|
||||||
|
}
|
||||||
if(this.mode === "keyboard"){
|
if(this.mode === "keyboard"){
|
||||||
this.keyboardBack(this.items[this.selected])
|
this.keyboardBack(this.items[this.selected])
|
||||||
}
|
}
|
||||||
for(var i in settings.items){
|
for(var i in this.settingsItems){
|
||||||
settings.setItem(i, null)
|
settings.setItem(i, null)
|
||||||
}
|
}
|
||||||
this.setLang(allStrings[settings.getItem("language")])
|
this.setLang(allStrings[settings.getItem("language")])
|
||||||
@ -848,7 +878,7 @@ class SettingsView{
|
|||||||
try{
|
try{
|
||||||
localStorage.setItem("tutorial", "true")
|
localStorage.setItem("tutorial", "true")
|
||||||
}catch(e){}
|
}catch(e){}
|
||||||
new SongSelect(this.tutorial ? false : "settings", false, this.touched, this.songId)
|
new SongSelect(this.tutorial ? false : this.customSettings ? "plugins" : "settings", false, this.touched, this.songId)
|
||||||
}
|
}
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
@ -877,14 +907,16 @@ class SettingsView{
|
|||||||
this.setStrings()
|
this.setStrings()
|
||||||
}
|
}
|
||||||
setStrings(){
|
setStrings(){
|
||||||
this.setAltText(this.viewTitle, strings.gameSettings)
|
this.setAltText(this.viewTitle, this.customSettings ? strings.plugins.title : strings.gameSettings)
|
||||||
this.setAltText(this.endButton, strings.settings.ok)
|
this.setAltText(this.endButton, strings.settings.ok)
|
||||||
|
if(!this.customSettings){
|
||||||
this.setAltText(this.gamepadTitle, strings.settings.gamepadLayout.name)
|
this.setAltText(this.gamepadTitle, strings.settings.gamepadLayout.name)
|
||||||
this.setAltText(this.gamepadEndButton, strings.settings.ok)
|
this.setAltText(this.gamepadEndButton, strings.settings.ok)
|
||||||
this.setAltText(this.latencyTitle, strings.settings.latency.name)
|
this.setAltText(this.latencyTitle, strings.settings.latency.name)
|
||||||
this.setAltText(this.latencyDefaultButton, strings.settings.default)
|
this.setAltText(this.latencyDefaultButton, strings.settings.default)
|
||||||
this.setAltText(this.latencyEndButton, strings.settings.ok)
|
this.setAltText(this.latencyEndButton, strings.settings.ok)
|
||||||
this.setAltText(this.defaultButton, strings.settings.default)
|
}
|
||||||
|
this.setAltText(this.defaultButton, this.customSettings ? strings.plugins.unloadAll : strings.settings.default)
|
||||||
}
|
}
|
||||||
setAltText(element, text){
|
setAltText(element, text){
|
||||||
element.innerText = text
|
element.innerText = text
|
||||||
@ -941,12 +973,14 @@ class SettingsView{
|
|||||||
if(this.defaultButton){
|
if(this.defaultButton){
|
||||||
delete this.defaultButton
|
delete this.defaultButton
|
||||||
}
|
}
|
||||||
|
if(!this.customSettings){
|
||||||
this.removeTouch(this.gamepadSettings)
|
this.removeTouch(this.gamepadSettings)
|
||||||
this.removeTouch(this.gamepadEndButton)
|
this.removeTouch(this.gamepadEndButton)
|
||||||
this.removeTouch(this.gamepadBox)
|
this.removeTouch(this.gamepadBox)
|
||||||
this.removeTouch(this.latencySettings)
|
this.removeTouch(this.latencySettings)
|
||||||
this.removeTouch(this.latencyDefaultButton)
|
this.removeTouch(this.latencyDefaultButton)
|
||||||
this.removeTouch(this.latencyEndButton)
|
this.removeTouch(this.latencyEndButton)
|
||||||
|
}
|
||||||
delete this.windowSymbol
|
delete this.windowSymbol
|
||||||
delete this.touchMove
|
delete this.touchMove
|
||||||
delete this.viewOuter
|
delete this.viewOuter
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class SongSelect{
|
class SongSelect{
|
||||||
constructor(fromTutorial, fadeIn, touchEnabled, songId, showWarning){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(fromTutorial, fadeIn, touchEnabled, songId, showWarning){
|
||||||
this.touchEnabled = touchEnabled
|
this.touchEnabled = touchEnabled
|
||||||
|
|
||||||
loader.changePage("songselect", false)
|
loader.changePage("songselect", false)
|
||||||
@ -55,6 +58,12 @@ class SongSelect{
|
|||||||
border: ["#ffe7ef", "#d36aa2"],
|
border: ["#ffe7ef", "#d36aa2"],
|
||||||
outline: "#d36aa2"
|
outline: "#d36aa2"
|
||||||
},
|
},
|
||||||
|
"plugins": {
|
||||||
|
sort: 0,
|
||||||
|
background: "#f6bba1",
|
||||||
|
border: ["#fde9df", "#ce7553"],
|
||||||
|
outline: "#ce7553"
|
||||||
|
},
|
||||||
"default": {
|
"default": {
|
||||||
sort: null,
|
sort: null,
|
||||||
background: "#ececec",
|
background: "#ececec",
|
||||||
@ -150,6 +159,14 @@ class SongSelect{
|
|||||||
category: strings.random
|
category: strings.random
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if(plugins.allPlugins.length){
|
||||||
|
this.songs.push({
|
||||||
|
title: strings.plugins.title,
|
||||||
|
skin: this.songSkin.plugins,
|
||||||
|
action: "plugins",
|
||||||
|
category: strings.random
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
this.songs.push({
|
this.songs.push({
|
||||||
title: strings.back,
|
title: strings.back,
|
||||||
@ -218,8 +235,12 @@ class SongSelect{
|
|||||||
this.playedSounds = {}
|
this.playedSounds = {}
|
||||||
|
|
||||||
var songIdIndex = -1
|
var songIdIndex = -1
|
||||||
|
var newSelected = -1
|
||||||
if(fromTutorial){
|
if(fromTutorial){
|
||||||
this.selectedSong = this.songs.findIndex(song => song.action === fromTutorial)
|
newSelected = this.songs.findIndex(song => song.action === fromTutorial)
|
||||||
|
}
|
||||||
|
if(newSelected !== -1){
|
||||||
|
this.selectedSong = newSelected
|
||||||
this.playBgm(true)
|
this.playBgm(true)
|
||||||
}else{
|
}else{
|
||||||
if(songId){
|
if(songId){
|
||||||
@ -481,18 +502,6 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
touchEnd(event){
|
touchEnd(event){
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if(this.state.screen === "song" && this.redrawRunning){
|
|
||||||
var currentSong = this.songs[this.selectedSong]
|
|
||||||
if(currentSong.action === "customSongs"){
|
|
||||||
var x = event.changedTouches[0].pageX - this.canvas.offsetLeft
|
|
||||||
var y = event.changedTouches[0].pageY - this.canvas.offsetTop
|
|
||||||
var mouse = this.mouseOffset(x, y)
|
|
||||||
var moveBy = this.songSelMouse(mouse.x, mouse.y)
|
|
||||||
if(moveBy === 0){
|
|
||||||
this.toCustomSongs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mouseMove(event){
|
mouseMove(event){
|
||||||
var mouse = this.mouseOffset(event.offsetX, event.offsetY)
|
var mouse = this.mouseOffset(event.offsetX, event.offsetY)
|
||||||
@ -565,8 +574,8 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
diffSelMouse(x, y){
|
diffSelMouse(x, y){
|
||||||
if(this.state.locked === 0){
|
if(this.state.locked === 0){
|
||||||
if(223 < x && x < 367 && 132 < y && y < 436){
|
if(223 < x && x < 223 + 72 * this.diffOptions.length && 132 < y && y < 436){
|
||||||
return Math.floor((x - 223) / ((367 - 223) / 2))
|
return Math.floor((x - 223) / 72)
|
||||||
}else if(this.songs[this.selectedSong].maker && this.songs[this.selectedSong].maker.id > 0 && this.songs[this.selectedSong].maker.url && x > 230 && x < 485 && y > 446 && y < 533) {
|
}else if(this.songs[this.selectedSong].maker && this.songs[this.selectedSong].maker.id > 0 && this.songs[this.selectedSong].maker.url && x > 230 && x < 485 && y > 446 && y < 533) {
|
||||||
return "maker"
|
return "maker"
|
||||||
}else if(550 < x && x < 1050 && 109 < y && y < 538){
|
}else if(550 < x && x < 1050 && 109 < y && y < 538){
|
||||||
@ -706,6 +715,8 @@ class SongSelect{
|
|||||||
this.toSettings()
|
this.toSettings()
|
||||||
}else if(currentSong.action === "customSongs"){
|
}else if(currentSong.action === "customSongs"){
|
||||||
this.toCustomSongs()
|
this.toCustomSongs()
|
||||||
|
}else if(currentSong.action === "plugins"){
|
||||||
|
this.toPlugins()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.pointer(false)
|
this.pointer(false)
|
||||||
@ -864,6 +875,13 @@ class SongSelect{
|
|||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
toPlugins(){
|
||||||
|
this.playSound("se_don")
|
||||||
|
this.clean()
|
||||||
|
setTimeout(() => {
|
||||||
|
new SettingsView(this.touchEnabled, false, undefined, undefined, plugins.getSettings())
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
redraw(){
|
redraw(){
|
||||||
if(!this.redrawRunning){
|
if(!this.redrawRunning){
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class SoundBuffer{
|
class SoundBuffer{
|
||||||
constructor(){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(){
|
||||||
var AudioContext = window.AudioContext || window.webkitAudioContext
|
var AudioContext = window.AudioContext || window.webkitAudioContext
|
||||||
this.context = new AudioContext()
|
this.context = new AudioContext()
|
||||||
this.audioDecoder = this.context.decodeAudioData.bind(this.context)
|
this.audioDecoder = this.context.decodeAudioData.bind(this.context)
|
||||||
|
@ -21,6 +21,13 @@ var translations = {
|
|||||||
tw: "Microsoft YaHei, sans-serif",
|
tw: "Microsoft YaHei, sans-serif",
|
||||||
ko: "Microsoft YaHei, sans-serif"
|
ko: "Microsoft YaHei, sans-serif"
|
||||||
},
|
},
|
||||||
|
intl: {
|
||||||
|
ja: "ja",
|
||||||
|
en: "en-GB",
|
||||||
|
cn: "zh-Hans",
|
||||||
|
tw: "zh-Hant",
|
||||||
|
ko: "ko"
|
||||||
|
},
|
||||||
|
|
||||||
taikoWeb: {
|
taikoWeb: {
|
||||||
ja: "たいこウェブ",
|
ja: "たいこウェブ",
|
||||||
@ -1278,6 +1285,27 @@ var translations = {
|
|||||||
en: "This function requires third party cookies.",
|
en: "This function requires third party cookies.",
|
||||||
tw: "此功能需要第三方 cookies。"
|
tw: "此功能需要第三方 cookies。"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
title: {
|
||||||
|
ja: null,
|
||||||
|
en: "Plugins"
|
||||||
|
},
|
||||||
|
unloadAll: {
|
||||||
|
ja: null,
|
||||||
|
en: "Unload All"
|
||||||
|
},
|
||||||
|
warning: {
|
||||||
|
ja: null,
|
||||||
|
en: "You are about to load %s. Plugins should only be loaded if you trust them. Continue?"
|
||||||
|
},
|
||||||
|
plugin: {
|
||||||
|
ja: null,
|
||||||
|
en: {
|
||||||
|
one: "%s plugin",
|
||||||
|
other: "%s plugins"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var allStrings = {}
|
var allStrings = {}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Titlescreen{
|
class Titlescreen{
|
||||||
constructor(songId){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(songId){
|
||||||
this.songId = songId
|
this.songId = songId
|
||||||
db.getItem("customFolder").then(folder => this.customFolder = folder)
|
db.getItem("customFolder").then(folder => this.customFolder = folder)
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class Tutorial{
|
class Tutorial{
|
||||||
constructor(fromSongSel, songId){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(fromSongSel, songId){
|
||||||
this.fromSongSel = fromSongSel
|
this.fromSongSel = fromSongSel
|
||||||
this.songId = songId
|
this.songId = songId
|
||||||
loader.changePage("tutorial", true)
|
loader.changePage("tutorial", true)
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class View{
|
class View{
|
||||||
constructor(controller){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(controller){
|
||||||
this.controller = controller
|
this.controller = controller
|
||||||
|
|
||||||
this.canvas = document.getElementById("canvas")
|
this.canvas = document.getElementById("canvas")
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class ViewAssets{
|
class ViewAssets{
|
||||||
constructor(view){
|
constructor(...args){
|
||||||
|
this.init(...args)
|
||||||
|
}
|
||||||
|
init(view){
|
||||||
this.view = view
|
this.view = view
|
||||||
this.controller = this.view.controller
|
this.controller = this.view.controller
|
||||||
this.allAssets = []
|
this.allAssets = []
|
||||||
|
Loading…
Reference in New Issue
Block a user