mirror of
https://github.com/jiojciojsioe3/a3cjroijsiojiorj.git
synced 2024-12-23 01:36:14 +08:00
Multiplayer improvements and reupload score on error
- In multiplayer you will play at the bottom if you joined second - Add a dialog to song select that score has not been saved - Uploads the score when logged in again - Translate error messages from the server
This commit is contained in:
parent
ad62ac800c
commit
7f1bb9d357
28
app.py
28
app.py
@ -190,15 +190,15 @@ def route_api_config():
|
||||
|
||||
@app.route('/api/register', methods=['POST'])
|
||||
def route_api_register():
|
||||
if session.get('username'):
|
||||
return api_error('already_logged_in')
|
||||
|
||||
data = request.get_json()
|
||||
if not schema.validate(data, schema.register):
|
||||
return abort(400)
|
||||
|
||||
if session.get('username'):
|
||||
session.clear()
|
||||
|
||||
username = data.get('username', '')
|
||||
if len(username) > 20 or not re.match('^[a-zA-Z0-9_]{1,20}$', username):
|
||||
if len(username) < 3 or len(username) > 20 or not re.match('^[a-zA-Z0-9_]{3,20}$', username):
|
||||
return api_error('invalid_username')
|
||||
|
||||
if db.users.find_one({'username_lower': username.lower()}):
|
||||
@ -226,13 +226,13 @@ def route_api_register():
|
||||
|
||||
@app.route('/api/login', methods=['POST'])
|
||||
def route_api_login():
|
||||
if session.get('username'):
|
||||
return api_error('already_logged_in')
|
||||
|
||||
data = request.get_json()
|
||||
if not schema.validate(data, schema.login):
|
||||
return abort(400)
|
||||
|
||||
if session.get('username'):
|
||||
session.clear()
|
||||
|
||||
username = data.get('username', '')
|
||||
result = db.users.find_one({'username_lower': username.lower()})
|
||||
if not result:
|
||||
@ -263,15 +263,17 @@ def route_api_account_display_name():
|
||||
if not schema.validate(data, schema.update_display_name):
|
||||
return abort(400)
|
||||
|
||||
display_name = data.get('display_name', '')
|
||||
if not display_name or len(display_name) > 20:
|
||||
display_name = data.get('display_name', '').strip()
|
||||
if not display_name:
|
||||
display_name = session.get('username')
|
||||
elif len(display_name) > 25:
|
||||
return api_error('invalid_display_name')
|
||||
|
||||
db.users.update_one({'username': session.get('username')}, {
|
||||
'$set': {'display_name': display_name}
|
||||
})
|
||||
|
||||
return jsonify({'status': 'ok'})
|
||||
return jsonify({'status': 'ok', 'display_name': display_name})
|
||||
|
||||
|
||||
@app.route('/api/account/password', methods=['POST'])
|
||||
@ -287,8 +289,8 @@ def route_api_account_password():
|
||||
return api_error('current_password_invalid')
|
||||
|
||||
new_password = data.get('new_password', '').encode('utf-8')
|
||||
if not 8 <= len(new_password) <= 5000:
|
||||
return api_error('invalid_password')
|
||||
if not 6 <= len(new_password) <= 5000:
|
||||
return api_error('invalid_new_password')
|
||||
|
||||
salt = bcrypt.gensalt()
|
||||
hashed = bcrypt.hashpw(new_password, salt)
|
||||
@ -310,7 +312,7 @@ def route_api_account_remove():
|
||||
user = db.users.find_one({'username': session.get('username')})
|
||||
password = data.get('password', '').encode('utf-8')
|
||||
if not bcrypt.checkpw(password, user['password']):
|
||||
return api_error('current_password_invalid')
|
||||
return api_error('verify_password_invalid')
|
||||
|
||||
db.scores.delete_many({'username': session.get('username')})
|
||||
db.users.delete_one({'username': session.get('username')})
|
||||
|
@ -2,5 +2,5 @@
|
||||
"songs_baseurl": "",
|
||||
"assets_baseurl": "",
|
||||
"email": "",
|
||||
"_accounts": true
|
||||
"accounts": true
|
||||
}
|
||||
|
@ -368,3 +368,11 @@ kbd{
|
||||
.accountdel-form{
|
||||
margin: 0.3em auto;
|
||||
}
|
||||
.view-content .error-div{
|
||||
display: none;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
padding: 0.5em;
|
||||
font-size: 1.1em;
|
||||
color: #d00;
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ class Account{
|
||||
this.inputForms = []
|
||||
this.shownDiv = ""
|
||||
|
||||
this.errorDiv = this.getElement("error-div")
|
||||
this.getElement("displayname-hint").innerText = strings.account.displayName
|
||||
this.displayname = this.getElement("displayname")
|
||||
this.displayname.placeholder = strings.account.displayName
|
||||
@ -116,6 +117,8 @@ class Account{
|
||||
this.mode = register ? "register" : "login"
|
||||
|
||||
this.setAltText(this.getElement("view-title"), strings.account[this.mode])
|
||||
|
||||
this.errorDiv = this.getElement("error-div")
|
||||
this.items = []
|
||||
this.form = this.getElement("login-form")
|
||||
this.getElement("username-hint").innerText = strings.account.username
|
||||
@ -239,14 +242,14 @@ class Account{
|
||||
password: this.form.password.value
|
||||
}
|
||||
if(!obj.username || !obj.password){
|
||||
alert(strings.account.cannotBeEmpty.replace("%s", strings.account[!obj.username ? "username" : "password"]))
|
||||
this.error(strings.account.cannotBeEmpty.replace("%s", strings.account[!obj.username ? "username" : "password"]))
|
||||
return
|
||||
}
|
||||
if(this.mode === "login"){
|
||||
obj.remember = this.form.remember.checked
|
||||
}else{
|
||||
if(obj.password !== this.form.password2.value){
|
||||
alert(strings.account.passwordsDoNotMatch)
|
||||
this.error(strings.account.passwordsDoNotMatch)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -260,7 +263,7 @@ class Account{
|
||||
pageEvents.send("login", account.username)
|
||||
}
|
||||
if(this.mode === "login"){
|
||||
this.request("scores/get").then(response => {
|
||||
this.request("scores/get", false, true).then(response => {
|
||||
loadScores(response.scores)
|
||||
}, () => {
|
||||
loadScores({})
|
||||
@ -273,9 +276,13 @@ class Account{
|
||||
}
|
||||
}, response => {
|
||||
if(response && response.status === "error" && response.message){
|
||||
alert(response.message)
|
||||
if(response.message in strings.serverError){
|
||||
this.error(strings.serverError[response.message])
|
||||
}else{
|
||||
this.error(response.message)
|
||||
}
|
||||
}else{
|
||||
alert(strings.account.error)
|
||||
this.error(strings.account.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -293,17 +300,12 @@ class Account{
|
||||
account.loggedIn = false
|
||||
delete account.username
|
||||
delete account.displayName
|
||||
var loadScores = scores => {
|
||||
Cookies.remove("session")
|
||||
var loadScores = () => {
|
||||
scoreStorage.load()
|
||||
this.onEnd(false, true)
|
||||
pageEvents.send("logout")
|
||||
}
|
||||
this.request("logout").then(response => {
|
||||
loadScores()
|
||||
}, () => {
|
||||
loadScores()
|
||||
})
|
||||
this.request("logout").then(loadScores, loadScores)
|
||||
}
|
||||
onSave(event){
|
||||
if(event){
|
||||
@ -316,6 +318,7 @@ class Account{
|
||||
if(this.locked){
|
||||
return
|
||||
}
|
||||
this.clearError()
|
||||
var promises = []
|
||||
var noNameChange = false
|
||||
if(this.shownDiv === "pass"){
|
||||
@ -329,7 +332,7 @@ class Account{
|
||||
new_password: passwords[1]
|
||||
}))
|
||||
}else{
|
||||
alert(strings.account.passwordsDoNotMatch)
|
||||
this.error(strings.account.newPasswordsDoNotMatch)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -341,7 +344,6 @@ class Account{
|
||||
account.loggedIn = false
|
||||
delete account.username
|
||||
delete account.displayName
|
||||
Cookies.remove("session")
|
||||
scoreStorage.load()
|
||||
pageEvents.send("logout")
|
||||
return Promise.resolve
|
||||
@ -351,8 +353,8 @@ class Account{
|
||||
if(!noNameChange && newName !== account.displayName){
|
||||
promises.push(this.request("account/display_name", {
|
||||
display_name: newName
|
||||
}).then(() => {
|
||||
account.displayName = newName
|
||||
}).then(response => {
|
||||
account.displayName = response.display_name
|
||||
}))
|
||||
}
|
||||
var error = false
|
||||
@ -361,9 +363,13 @@ class Account{
|
||||
return
|
||||
}
|
||||
if(response && response.message){
|
||||
alert(response.message)
|
||||
if(response.message in strings.serverError){
|
||||
this.error(strings.serverError[response.message])
|
||||
}else{
|
||||
this.error(response.message)
|
||||
}
|
||||
}else{
|
||||
alert(strings.account.error)
|
||||
this.error(strings.account.error)
|
||||
}
|
||||
}
|
||||
Promise.all(promises).then(() => {
|
||||
@ -389,11 +395,11 @@ class Account{
|
||||
new SongSelect(false, false, touched)
|
||||
}, 500)
|
||||
}
|
||||
request(url, obj){
|
||||
request(url, obj, get){
|
||||
this.lock(true)
|
||||
return new Promise((resolve, reject) => {
|
||||
var request = new XMLHttpRequest()
|
||||
request.open("POST", "api/" + url)
|
||||
request.open(get ? "GET" : "POST", "api/" + url)
|
||||
pageEvents.load(request).then(() => {
|
||||
this.lock(false)
|
||||
if(request.status !== 200){
|
||||
@ -435,6 +441,14 @@ class Account{
|
||||
}
|
||||
}
|
||||
}
|
||||
error(text){
|
||||
this.errorDiv.innerText = text
|
||||
this.errorDiv.style.display = "block"
|
||||
}
|
||||
clearError(){
|
||||
this.errorDiv.innerText = ""
|
||||
this.errorDiv.style.display = ""
|
||||
}
|
||||
clean(eventsOnly, noReset){
|
||||
if(!eventsOnly){
|
||||
cancelTouch = true
|
||||
@ -442,6 +456,10 @@ class Account{
|
||||
this.gamepad.clean()
|
||||
}
|
||||
if(this.mode === "account"){
|
||||
if(!noReset){
|
||||
this.accountPass.reset()
|
||||
this.accountDel.reset()
|
||||
}
|
||||
pageEvents.remove(this.accounPassButton, ["click", "touchstart"])
|
||||
pageEvents.remove(this.accountDelButton, ["click", "touchstart"])
|
||||
pageEvents.remove(this.logoutButton, ["mousedown", "touchstart"])
|
||||
@ -449,10 +467,7 @@ class Account{
|
||||
for(var i = 0; i < this.inputForms.length; i++){
|
||||
pageEvents.remove(this.inputForms[i], ["keydown", "keyup", "keypress"])
|
||||
}
|
||||
if(!noReset){
|
||||
this.accountPass.reset()
|
||||
this.accountDel.reset()
|
||||
}
|
||||
delete this.errorDiv
|
||||
delete this.displayname
|
||||
delete this.accountPassButton
|
||||
delete this.accountPass
|
||||
@ -473,6 +488,7 @@ class Account{
|
||||
for(var i = 0; i < this.form.length; i++){
|
||||
pageEvents.remove(this.registerButton, ["keydown", "keyup", "keypress"])
|
||||
}
|
||||
delete this.errorDiv
|
||||
delete this.form
|
||||
delete this.password2
|
||||
delete this.remember
|
||||
|
@ -1,7 +1,6 @@
|
||||
var assets = {
|
||||
"js": [
|
||||
"lib/md5.min.js",
|
||||
"lib/js.cookie.min.js",
|
||||
"loadsong.js",
|
||||
"parseosu.js",
|
||||
"titlescreen.js",
|
||||
|
@ -155,10 +155,16 @@ class Controller{
|
||||
if(this.mainLoopRunning){
|
||||
if(this.multiplayer !== 2){
|
||||
requestAnimationFrame(() => {
|
||||
this.viewLoop()
|
||||
var player = this.multiplayer ? p2.player : 1
|
||||
if(player === 1){
|
||||
this.viewLoop()
|
||||
}
|
||||
if(this.multiplayer === 1){
|
||||
this.syncWith.viewLoop()
|
||||
}
|
||||
if(player === 2){
|
||||
this.viewLoop()
|
||||
}
|
||||
if(this.scoresheet){
|
||||
if(this.view.ctx){
|
||||
this.view.ctx.save()
|
||||
@ -197,14 +203,14 @@ class Controller{
|
||||
displayScore(score, notPlayed, bigNote){
|
||||
this.view.displayScore(score, notPlayed, bigNote)
|
||||
}
|
||||
songSelection(fadeIn){
|
||||
songSelection(fadeIn, scoreSaveFailed){
|
||||
if(!fadeIn){
|
||||
this.clean()
|
||||
}
|
||||
if(this.calibrationMode){
|
||||
new SettingsView(this.touchEnabled, false, null, "latency")
|
||||
}else{
|
||||
new SongSelect(false, fadeIn, this.touchEnabled)
|
||||
new SongSelect(false, fadeIn, this.touchEnabled, null, scoreSaveFailed)
|
||||
}
|
||||
}
|
||||
restartSong(){
|
||||
|
@ -506,7 +506,7 @@ class Game{
|
||||
if(this.musicFadeOut === 0){
|
||||
if(this.controller.multiplayer === 1){
|
||||
var obj = this.getGlobalScore()
|
||||
obj.name = account.loggedIn ? account.displayName : strings.defaultName
|
||||
obj.name = account.loggedIn ? account.displayName : null
|
||||
p2.send("gameresults", obj)
|
||||
}
|
||||
this.musicFadeOut++
|
||||
|
2
public/src/js/lib/js.cookie.min.js
vendored
2
public/src/js/lib/js.cookie.min.js
vendored
@ -1,2 +0,0 @@
|
||||
/*! js-cookie v3.0.0-rc.0 | MIT */
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self,function(){var r=e.Cookies,n=e.Cookies=t();n.noConflict=function(){return e.Cookies=r,n}}())}(this,function(){"use strict";function e(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)e[n]=r[n]}return e}var t={read:function(e){return e.replace(/%3B/g,";")},write:function(e){return e.replace(/;/g,"%3B")}};return function r(n,i){function o(r,o,u){if("undefined"!=typeof document){"number"==typeof(u=e({},i,u)).expires&&(u.expires=new Date(Date.now()+864e5*u.expires)),u.expires&&(u.expires=u.expires.toUTCString()),r=t.write(r).replace(/=/g,"%3D"),o=n.write(String(o),r);var c="";for(var f in u)u[f]&&(c+="; "+f,!0!==u[f]&&(c+="="+u[f].split(";")[0]));return document.cookie=r+"="+o+c}}return Object.create({set:o,get:function(e){if("undefined"!=typeof document&&(!arguments.length||e)){for(var r=document.cookie?document.cookie.split("; "):[],i={},o=0;o<r.length;o++){var u=r[o].split("="),c=u.slice(1).join("="),f=t.read(u[0]).replace(/%3D/g,"=");if(i[f]=n.read(c,f),e===f)break}return e?i[e]:i}},remove:function(t,r){o(t,"",e({},r,{expires:-1}))},withAttributes:function(t){return r(this.converter,e({},this.attributes,t))},withConverter:function(t){return r(e({},this.converter,t),this.attributes)}},{attributes:{value:Object.freeze(i)},converter:{value:Object.freeze(n)}})}(t,{path:"/"})});
|
@ -109,7 +109,7 @@ class Loader{
|
||||
assets.audioMusic.length +
|
||||
assets.audioSfxLR.length +
|
||||
assets.audioSfxLoud.length +
|
||||
(gameConfig._accounts ? 1 : 0)
|
||||
(gameConfig.accounts ? 1 : 0)
|
||||
|
||||
Promise.all(this.promises).then(() => {
|
||||
|
||||
@ -156,22 +156,17 @@ class Loader{
|
||||
}
|
||||
}))
|
||||
|
||||
if(gameConfig._accounts){
|
||||
var token = Cookies.get("session")
|
||||
if(token){
|
||||
this.addPromise(this.ajax("/api/scores/get").then(response => {
|
||||
response = JSON.parse(response)
|
||||
if(response.status === "ok"){
|
||||
account.loggedIn = true
|
||||
account.username = response.username
|
||||
account.displayName = response.display_name
|
||||
scoreStorage.load(response.scores)
|
||||
pageEvents.send("login", account.username)
|
||||
}
|
||||
}))
|
||||
}else{
|
||||
this.assetLoaded()
|
||||
}
|
||||
if(gameConfig.accounts){
|
||||
this.addPromise(this.ajax("/api/scores/get").then(response => {
|
||||
response = JSON.parse(response)
|
||||
if(response.status === "ok"){
|
||||
account.loggedIn = true
|
||||
account.username = response.username
|
||||
account.displayName = response.display_name
|
||||
scoreStorage.load(response.scores)
|
||||
pageEvents.send("login", account.username)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
settings = new Settings()
|
||||
|
@ -264,14 +264,14 @@ class LoadSong{
|
||||
if(event.type === "gameload"){
|
||||
this.cancelButton.style.display = ""
|
||||
|
||||
if(event.value === song.difficulty){
|
||||
if(event.value.diff === song.difficulty){
|
||||
this.startMultiplayer()
|
||||
}else{
|
||||
this.selectedSong2 = {}
|
||||
for(var i in this.selectedSong){
|
||||
this.selectedSong2[i] = this.selectedSong[i]
|
||||
}
|
||||
this.selectedSong2.difficulty = event.value
|
||||
this.selectedSong2.difficulty = event.value.diff
|
||||
if(song.type === "tja"){
|
||||
this.startMultiplayer()
|
||||
}else{
|
||||
|
@ -4,6 +4,7 @@ class P2Connection{
|
||||
this.lastMessages = {}
|
||||
this.otherConnected = false
|
||||
this.name = null
|
||||
this.player = 1
|
||||
this.allEvents = new Map()
|
||||
this.addEventListener("message", this.message.bind(this))
|
||||
this.currentHash = ""
|
||||
@ -103,6 +104,10 @@ class P2Connection{
|
||||
}
|
||||
message(response){
|
||||
switch(response.type){
|
||||
case "gameload":
|
||||
if("player" in response.value){
|
||||
this.player = response.value.player === 2 ? 2 : 1
|
||||
}
|
||||
case "gamestart":
|
||||
this.otherConnected = true
|
||||
this.notes = []
|
||||
@ -129,7 +134,7 @@ class P2Connection{
|
||||
case "gameresults":
|
||||
this.results = {}
|
||||
for(var i in response.value){
|
||||
this.results[i] = response.value[i].toString()
|
||||
this.results[i] = response.value[i] === null ? null : response.value[i].toString()
|
||||
}
|
||||
break
|
||||
case "note":
|
||||
@ -152,9 +157,12 @@ class P2Connection{
|
||||
this.clearMessage("users")
|
||||
this.otherConnected = true
|
||||
this.session = true
|
||||
if("player" in response.value){
|
||||
this.player = response.value.player === 2 ? 2 : 1
|
||||
}
|
||||
break
|
||||
case "name":
|
||||
this.name = (response.value || "").toString() || null
|
||||
this.name = response.value ? response.value.toString() : response.value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ class PageEvents{
|
||||
})
|
||||
}
|
||||
keyEvent(event){
|
||||
if(!("key" in event)){
|
||||
if(!("key" in event) || event.ctrlKey && (event.key === "c" || event.key === "x" || event.key === "v")){
|
||||
return
|
||||
}
|
||||
if(this.kbd.indexOf(event.key.toLowerCase()) !== -1){
|
||||
|
@ -2,9 +2,19 @@ class Scoresheet{
|
||||
constructor(controller, results, multiplayer, touchEnabled){
|
||||
this.controller = controller
|
||||
this.resultsObj = results
|
||||
this.results = {}
|
||||
this.player = [multiplayer ? (p2.player === 1 ? 0 : 1) : 0]
|
||||
var player0 = this.player[0]
|
||||
this.results = []
|
||||
this.results[player0] = {}
|
||||
this.rules = []
|
||||
this.rules[player0] = this.controller.game.rules
|
||||
if(multiplayer){
|
||||
this.player.push(p2.player === 2 ? 0 : 1)
|
||||
this.results[this.player[1]] = p2.results
|
||||
this.rules[this.player[1]] = this.controller.syncWith.game.rules
|
||||
}
|
||||
for(var i in results){
|
||||
this.results[i] = results[i].toString()
|
||||
this.results[player0][i] = results[i] === null ? null : results[i].toString()
|
||||
}
|
||||
this.multiplayer = multiplayer
|
||||
this.touchEnabled = touchEnabled
|
||||
@ -248,7 +258,7 @@ class Scoresheet{
|
||||
var frameTop = winH / 2 - 720 / 2
|
||||
var frameLeft = winW / 2 - 1280 / 2
|
||||
|
||||
var players = this.multiplayer && p2.results ? 2 : 1
|
||||
var players = this.multiplayer ? 2 : 1
|
||||
var p2Offset = 298
|
||||
|
||||
var bgOffset = 0
|
||||
@ -331,28 +341,21 @@ class Scoresheet{
|
||||
}
|
||||
|
||||
var rules = this.controller.game.rules
|
||||
var gaugePercent = rules.gaugePercent(this.results.gauge)
|
||||
var gaugeClear = [rules.gaugeClear]
|
||||
if(players === 2){
|
||||
gaugeClear.push(this.controller.syncWith.game.rules.gaugeClear)
|
||||
}
|
||||
var failedOffset = gaugePercent >= gaugeClear[0] ? 0 : -2000
|
||||
if(players === 2){
|
||||
var gauge2 = this.controller.syncWith.game.rules.gaugePercent(p2.results.gauge)
|
||||
if(gauge2 > gaugePercent && failedOffset !== 0 && gauge2 >= gaugeClear[1]){
|
||||
var failedOffset = rules.clearReached(this.results[this.player[0]].gauge) ? 0 : -2000
|
||||
if(players === 2 && failedOffset !== 0){
|
||||
var p2results = this.results[this.player[1]]
|
||||
if(p2results && this.controller.syncWith.game.rules.clearReached(p2results.gauge)){
|
||||
failedOffset = 0
|
||||
}
|
||||
}
|
||||
if(elapsed >= 3100 + failedOffset){
|
||||
for(var p = 0; p < players; p++){
|
||||
ctx.save()
|
||||
var results = this.results
|
||||
if(p === 1){
|
||||
results = p2.results
|
||||
var results = this.results[p]
|
||||
if(!results){
|
||||
continue
|
||||
}
|
||||
var playerRules = p === 0 ? rules : this.controller.syncWith.game.rules
|
||||
var resultGauge = playerRules.gaugePercent(results.gauge)
|
||||
var clear = resultGauge >= gaugeClear[p]
|
||||
var clear = this.rules[p].clearReached(results.gauge)
|
||||
if(p === 1 || !this.multiplayer && clear){
|
||||
ctx.translate(0, 290)
|
||||
}
|
||||
@ -415,7 +418,7 @@ class Scoresheet{
|
||||
|
||||
this.draw.layeredText({
|
||||
ctx: ctx,
|
||||
text: this.results.title,
|
||||
text: this.results[this.player[0]].title,
|
||||
fontSize: 40,
|
||||
fontFamily: this.font,
|
||||
x: 1257,
|
||||
@ -431,9 +434,11 @@ class Scoresheet{
|
||||
|
||||
ctx.save()
|
||||
for(var p = 0; p < players; p++){
|
||||
var results = this.results
|
||||
var results = this.results[p]
|
||||
if(!results){
|
||||
continue
|
||||
}
|
||||
if(p === 1){
|
||||
results = p2.results
|
||||
ctx.translate(0, p2Offset)
|
||||
}
|
||||
|
||||
@ -455,10 +460,11 @@ class Scoresheet{
|
||||
ctx.fillText(text, 395, 308)
|
||||
ctx.miterLimit = 10
|
||||
|
||||
if(p === 0){
|
||||
var name = account.loggedIn ? account.displayName : strings.defaultName
|
||||
var defaultName = p === 0 ? strings.defaultName : strings.default2PName
|
||||
if(p === this.player[0]){
|
||||
var name = account.loggedIn ? account.displayName : defaultName
|
||||
}else{
|
||||
var name = results.name
|
||||
var name = results.name || defaultName
|
||||
}
|
||||
this.nameplateCache.get({
|
||||
ctx: ctx,
|
||||
@ -466,7 +472,7 @@ class Scoresheet{
|
||||
y: 92,
|
||||
w: 273,
|
||||
h: 66,
|
||||
id: p.toString() + "p",
|
||||
id: p.toString() + "p" + name,
|
||||
}, ctx => {
|
||||
this.draw.nameplate({
|
||||
ctx: ctx,
|
||||
@ -609,7 +615,7 @@ class Scoresheet{
|
||||
if(this.tetsuoHanaClass){
|
||||
this.tetsuoHana.classList.remove(this.tetsuoHanaClass)
|
||||
}
|
||||
this.tetsuoHanaClass = rules.clearReached(this.results.gauge) ? "dance" : "failed"
|
||||
this.tetsuoHanaClass = this.rules[this.player[0]].clearReached(this.results[this.player[0]].gauge) ? "dance" : "failed"
|
||||
this.tetsuoHana.classList.add(this.tetsuoHanaClass)
|
||||
}
|
||||
}
|
||||
@ -623,32 +629,32 @@ class Scoresheet{
|
||||
ctx.translate(frameLeft, frameTop)
|
||||
|
||||
for(var p = 0; p < players; p++){
|
||||
var results = this.results
|
||||
var results = this.results[p]
|
||||
if(!results){
|
||||
continue
|
||||
}
|
||||
if(p === 1){
|
||||
results = p2.results
|
||||
ctx.translate(0, p2Offset)
|
||||
}
|
||||
var gaugePercent = rules.gaugePercent(results.gauge)
|
||||
var w = 712
|
||||
this.draw.gauge({
|
||||
ctx: ctx,
|
||||
x: 558 + w,
|
||||
y: p === 1 ? 124 : 116,
|
||||
clear: gaugeClear[p],
|
||||
percentage: gaugePercent,
|
||||
clear: this.rules[p].gaugeClear,
|
||||
percentage: this.rules[p].gaugePercent(results.gauge),
|
||||
font: this.font,
|
||||
scale: w / 788,
|
||||
scoresheet: true,
|
||||
blue: p === 1,
|
||||
multiplayer: p === 1
|
||||
})
|
||||
var playerRules = p === 0 ? rules : this.controller.syncWith.game.rules
|
||||
this.draw.soul({
|
||||
ctx: ctx,
|
||||
x: 1215,
|
||||
y: 144,
|
||||
scale: 36 / 42,
|
||||
cleared: playerRules.clearReached(results.gauge)
|
||||
cleared: this.rules[p].clearReached(results.gauge)
|
||||
})
|
||||
}
|
||||
})
|
||||
@ -661,13 +667,12 @@ class Scoresheet{
|
||||
var noCrownResultWait = -2000;
|
||||
|
||||
for(var p = 0; p < players; p++){
|
||||
var results = this.results
|
||||
if(p === 1){
|
||||
results = p2.results
|
||||
var results = this.results[p]
|
||||
if(!results){
|
||||
continue
|
||||
}
|
||||
var crownType = null
|
||||
var playerRules = p === 0 ? rules : this.controller.syncWith.game.rules
|
||||
if(playerRules.clearReached(results.gauge)){
|
||||
if(this.rules[p].clearReached(results.gauge)){
|
||||
crownType = results.bad === "0" ? "gold" : "silver"
|
||||
}
|
||||
if(crownType !== null){
|
||||
@ -730,7 +735,10 @@ class Scoresheet{
|
||||
var times = {}
|
||||
var lastTime = 0
|
||||
for(var p = 0; p < players; p++){
|
||||
var results = p === 0 ? this.results : p2.results
|
||||
var results = this.results[p]
|
||||
if(!results){
|
||||
continue
|
||||
}
|
||||
var currentTime = 3100 + noCrownResultWait + results.points.length * 30 * this.frame
|
||||
if(currentTime > lastTime){
|
||||
lastTime = currentTime
|
||||
@ -739,7 +747,10 @@ class Scoresheet{
|
||||
for(var i in printNumbers){
|
||||
var largestTime = 0
|
||||
for(var p = 0; p < players; p++){
|
||||
var results = p === 0 ? this.results : p2.results
|
||||
var results = this.results[p]
|
||||
if(!results){
|
||||
continue
|
||||
}
|
||||
times[printNumbers[i]] = lastTime + 500
|
||||
var currentTime = lastTime + 500 + results[printNumbers[i]].length * 30 * this.frame
|
||||
if(currentTime > largestTime){
|
||||
@ -755,9 +766,11 @@ class Scoresheet{
|
||||
}
|
||||
|
||||
for(var p = 0; p < players; p++){
|
||||
var results = this.results
|
||||
var results = this.results[p]
|
||||
if(!results){
|
||||
continue
|
||||
}
|
||||
if(p === 1){
|
||||
results = p2.results
|
||||
ctx.translate(0, p2Offset)
|
||||
}
|
||||
ctx.save()
|
||||
@ -851,7 +864,7 @@ class Scoresheet{
|
||||
|
||||
if(elapsed >= 1000){
|
||||
this.clean()
|
||||
this.controller.songSelection(true)
|
||||
this.controller.songSelection(true, this.scoreSaveFailed)
|
||||
}
|
||||
}
|
||||
|
||||
@ -918,10 +931,14 @@ class Scoresheet{
|
||||
delete this.resultsObj.title
|
||||
delete this.resultsObj.difficulty
|
||||
delete this.resultsObj.gauge
|
||||
scoreStorage.add(hash, difficulty, this.resultsObj, true, title)
|
||||
scoreStorage.add(hash, difficulty, this.resultsObj, true, title).catch(() => {
|
||||
this.scoreSaveFailed = true
|
||||
})
|
||||
}else if(oldScore && (crown === "gold" && oldScore.crown !== "gold" || crown && !oldScore.crown)){
|
||||
oldScore.crown = crown
|
||||
scoreStorage.add(hash, difficulty, oldScore, true, title)
|
||||
scoreStorage.add(hash, difficulty, oldScore, true, title).catch(() => {
|
||||
this.scoreSaveFailed = true
|
||||
})
|
||||
}
|
||||
}
|
||||
this.scoreSaved = true
|
||||
@ -936,7 +953,7 @@ class Scoresheet{
|
||||
snd.buffer.loadSettings()
|
||||
this.redrawRunning = false
|
||||
pageEvents.remove(this.canvas, ["mousedown", "touchstart"])
|
||||
if(this.multiplayer !== 2 && this.touchEnabled){
|
||||
if(this.touchEnabled){
|
||||
pageEvents.remove(document.getElementById("touch-full-btn"), "touchend")
|
||||
}
|
||||
if(this.session){
|
||||
@ -948,5 +965,7 @@ class Scoresheet{
|
||||
delete this.ctx
|
||||
delete this.canvas
|
||||
delete this.fadeScreen
|
||||
delete this.results
|
||||
delete this.rules
|
||||
}
|
||||
}
|
||||
|
@ -6,23 +6,30 @@ class ScoreStorage{
|
||||
this.scoreKeys = ["points", "good", "ok", "bad", "maxCombo", "drumroll"]
|
||||
this.crownValue = ["", "silver", "gold"]
|
||||
}
|
||||
load(strings){
|
||||
this.scores = {}
|
||||
if(strings){
|
||||
this.scoreStrings = this.prepareStrings(strings)
|
||||
load(strings, loadFailed){
|
||||
var scores = {}
|
||||
var scoreStrings = {}
|
||||
if(loadFailed){
|
||||
try{
|
||||
var localScores = localStorage.getItem("saveFailed")
|
||||
if(localScores){
|
||||
scoreStrings = JSON.parse(localScores)
|
||||
}
|
||||
}catch(e){}
|
||||
}else if(strings){
|
||||
scoreStrings = this.prepareStrings(strings)
|
||||
}else if(account.loggedIn){
|
||||
return
|
||||
}else{
|
||||
this.scoreStrings = {}
|
||||
try{
|
||||
var localScores = localStorage.getItem("scoreStorage")
|
||||
if(localScores){
|
||||
this.scoreStrings = JSON.parse(localScores)
|
||||
scoreStrings = JSON.parse(localScores)
|
||||
}
|
||||
}catch(e){}
|
||||
}
|
||||
for(var hash in this.scoreStrings){
|
||||
var scoreString = this.scoreStrings[hash]
|
||||
for(var hash in scoreStrings){
|
||||
var scoreString = scoreStrings[hash]
|
||||
var songAdded = false
|
||||
if(typeof scoreString === "string" && scoreString){
|
||||
var diffArray = scoreString.split(";")
|
||||
@ -42,14 +49,32 @@ class ScoreStorage{
|
||||
score[name] = value
|
||||
}
|
||||
if(!songAdded){
|
||||
this.scores[hash] = {title: null}
|
||||
scores[hash] = {title: null}
|
||||
songAdded = true
|
||||
}
|
||||
this.scores[hash][this.difficulty[i]] = score
|
||||
scores[hash][this.difficulty[i]] = score
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(loadFailed){
|
||||
for(var hash in scores){
|
||||
for(var i in this.difficulty){
|
||||
var diff = this.difficulty[i]
|
||||
if(scores[hash][diff]){
|
||||
this.add(hash, diff, scores[hash][diff], true, this.songTitles[hash] || null).then(() => {
|
||||
localStorage.removeItem("saveFailed")
|
||||
}, () => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
this.scores = scores
|
||||
this.scoreStrings = scoreStrings
|
||||
}
|
||||
if(strings){
|
||||
this.load(false, true)
|
||||
}
|
||||
}
|
||||
prepareScores(scores){
|
||||
var output = []
|
||||
@ -126,7 +151,7 @@ class ScoreStorage{
|
||||
}
|
||||
}
|
||||
}
|
||||
add(song, difficulty, scoreObject, isHash, setTitle){
|
||||
add(song, difficulty, scoreObject, isHash, setTitle, saveFailed){
|
||||
var hash = isHash ? song : this.titleHash(song)
|
||||
if(!(hash in this.scores)){
|
||||
this.scores[hash] = {}
|
||||
@ -137,11 +162,29 @@ class ScoreStorage{
|
||||
this.scores[hash][difficulty] = scoreObject
|
||||
this.writeString(hash)
|
||||
this.write()
|
||||
var obj = {}
|
||||
obj[hash] = this.scoreStrings[hash]
|
||||
this.sendToServer({
|
||||
scores: this.prepareScores(obj)
|
||||
}).catch(() => this.add.apply(this, arguments))
|
||||
if(saveFailed){
|
||||
var failedScores = {}
|
||||
try{
|
||||
var localScores = localStorage.getItem("saveFailed")
|
||||
if(localScores){
|
||||
failedScores = JSON.parse(localScores)
|
||||
}
|
||||
}catch(e){}
|
||||
if(!(hash in failedScores)){
|
||||
failedScores[hash] = {}
|
||||
}
|
||||
failedScores[hash] = this.scoreStrings[hash]
|
||||
try{
|
||||
localStorage.setItem("saveFailed", JSON.stringify(failedScores))
|
||||
}catch(e){}
|
||||
return Promise.reject()
|
||||
}else{
|
||||
var obj = {}
|
||||
obj[hash] = this.scoreStrings[hash]
|
||||
return this.sendToServer({
|
||||
scores: this.prepareScores(obj)
|
||||
}).catch(() => this.add(song, difficulty, scoreObject, isHash, setTitle, true))
|
||||
}
|
||||
}
|
||||
template(){
|
||||
var template = {crown: ""}
|
||||
@ -192,10 +235,10 @@ class ScoreStorage{
|
||||
}
|
||||
}).catch(() => {
|
||||
if(retry){
|
||||
this.scoreSaveFailed = true
|
||||
account.loggedIn = false
|
||||
delete account.username
|
||||
delete account.displayName
|
||||
Cookies.remove("session")
|
||||
this.load()
|
||||
pageEvents.send("logout")
|
||||
return Promise.reject()
|
||||
|
@ -1,5 +1,5 @@
|
||||
class SongSelect{
|
||||
constructor(fromTutorial, fadeIn, touchEnabled, songId){
|
||||
constructor(fromTutorial, fadeIn, touchEnabled, songId, scoreSaveFailed){
|
||||
this.touchEnabled = touchEnabled
|
||||
|
||||
loader.changePage("songselect", false)
|
||||
@ -167,6 +167,9 @@ class SongSelect{
|
||||
category: strings.random
|
||||
})
|
||||
}
|
||||
if(scoreSaveFailed){
|
||||
scoreStorage.scoreSaveFailed = true
|
||||
}
|
||||
this.songs.push({
|
||||
title: strings.aboutSimulator,
|
||||
skin: this.songSkin.about,
|
||||
@ -379,7 +382,12 @@ class SongSelect{
|
||||
return
|
||||
}
|
||||
var shift = event ? event.shiftKey : this.pressedKeys["shift"]
|
||||
if(this.state.screen === "song"){
|
||||
if(this.state.scoreSaveFailed){
|
||||
if(name === "confirm"){
|
||||
this.playSound("se_don")
|
||||
this.state.scoreSaveFailed = false
|
||||
}
|
||||
}else if(this.state.screen === "song"){
|
||||
if(name === "confirm"){
|
||||
this.toSelectDifficulty()
|
||||
}else if(name === "back"){
|
||||
@ -453,10 +461,15 @@ class SongSelect{
|
||||
var ctrl = false
|
||||
var touch = true
|
||||
}
|
||||
if(this.state.screen === "song"){
|
||||
if(this.state.scoreSaveFailed){
|
||||
if(408 < mouse.x && mouse.x < 872 && 470 < mouse.y && mouse.y < 550){
|
||||
this.playSound("se_don")
|
||||
this.state.scoreSaveFailed = false
|
||||
}
|
||||
}else if(this.state.screen === "song"){
|
||||
if(20 < mouse.y && mouse.y < 90 && 410 < mouse.x && mouse.x < 880 && (mouse.x < 540 || mouse.x > 750)){
|
||||
this.categoryJump(mouse.x < 640 ? -1 : 1)
|
||||
}else if(!p2.session && 60 < mouse.x && mouse.x < 332 && 640 < mouse.y && mouse.y < 706 && gameConfig._accounts){
|
||||
}else if(!p2.session && 60 < mouse.x && mouse.x < 332 && 640 < mouse.y && mouse.y < 706 && gameConfig.accounts){
|
||||
this.toAccount()
|
||||
}else if(p2.session && 438 < mouse.x && mouse.x < 834 && mouse.y > 603){
|
||||
this.toSession()
|
||||
@ -508,10 +521,14 @@ class SongSelect{
|
||||
mouseMove(event){
|
||||
var mouse = this.mouseOffset(event.offsetX, event.offsetY)
|
||||
var moveTo = null
|
||||
if(this.state.screen === "song"){
|
||||
if(this.state.scoreSaveFailed){
|
||||
if(408 < mouse.x && mouse.x < 872 && 470 < mouse.y && mouse.y < 550){
|
||||
moveTo = "scoreSaveFailed"
|
||||
}
|
||||
}else if(this.state.screen === "song"){
|
||||
if(20 < mouse.y && mouse.y < 90 && 410 < mouse.x && mouse.x < 880 && (mouse.x < 540 || mouse.x > 750)){
|
||||
moveTo = mouse.x < 640 ? "categoryPrev" : "categoryNext"
|
||||
}else if(!p2.session && 60 < mouse.x && mouse.x < 332 && 640 < mouse.y && mouse.y < 706 && gameConfig._accounts){
|
||||
}else if(!p2.session && 60 < mouse.x && mouse.x < 332 && 640 < mouse.y && mouse.y < 706 && gameConfig.accounts){
|
||||
moveTo = "account"
|
||||
}else if(p2.session && 438 < mouse.x && mouse.x < 834 && mouse.y > 603){
|
||||
moveTo = "session"
|
||||
@ -831,6 +848,7 @@ class SongSelect{
|
||||
}
|
||||
if(p2.session){
|
||||
p2.send("gameend")
|
||||
this.state.moveHover = null
|
||||
}else{
|
||||
localStorage["selectedSong"] = this.selectedSong
|
||||
|
||||
@ -992,12 +1010,22 @@ class SongSelect{
|
||||
}else{
|
||||
this.state.moveMS = ms - this.songSelecting.speed * this.songSelecting.resize + (ms - this.state.screenMS - 1000)
|
||||
}
|
||||
if(ms > this.state.screenMS + 500){
|
||||
if(screen === "titleFadeIn" && ms > this.state.screenMS + 500){
|
||||
this.state.screen = "title"
|
||||
screen = "title"
|
||||
}
|
||||
}
|
||||
|
||||
if(screen === "song" && scoreStorage.scoreSaveFailed && !p2.session){
|
||||
if(this.bgmEnabled){
|
||||
this.playBgm(false)
|
||||
}
|
||||
scoreStorage.scoreSaveFailed = false
|
||||
this.state.scoreSaveFailed = true
|
||||
this.state.locked = true
|
||||
this.playSound("se_pause")
|
||||
}
|
||||
|
||||
if(screen === "song"){
|
||||
if(this.songs[this.selectedSong].courses){
|
||||
selectedWidth = this.songAsset.selectedWidth
|
||||
@ -1441,7 +1469,8 @@ class SongSelect{
|
||||
ctx: ctx,
|
||||
font: this.font,
|
||||
x: _x,
|
||||
y: _y - 45
|
||||
y: _y - 45,
|
||||
two: p2.session && p2.player === 2
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1579,15 +1608,15 @@ class SongSelect{
|
||||
if(this.selectedDiff === 4 + this.diffOptions.length){
|
||||
currentDiff = 3
|
||||
}
|
||||
if(i === currentSong.p2Cursor && p2.socket.readyState === 1){
|
||||
if(songSel && i === currentSong.p2Cursor && p2.socket.readyState === 1){
|
||||
this.draw.diffCursor({
|
||||
ctx: ctx,
|
||||
font: this.font,
|
||||
x: _x,
|
||||
y: _y - (songSel ? 45 : 65),
|
||||
two: true,
|
||||
side: songSel ? false : (currentSong.p2Cursor === currentDiff),
|
||||
scale: songSel ? 0.7 : 1
|
||||
y: _y - 45,
|
||||
two: !p2.session || p2.player === 1,
|
||||
side: false,
|
||||
scale: 0.7
|
||||
})
|
||||
}
|
||||
if(!songSel){
|
||||
@ -1603,7 +1632,8 @@ class SongSelect{
|
||||
font: this.font,
|
||||
x: _x,
|
||||
y: _y - 65,
|
||||
side: currentSong.p2Cursor === currentDiff && p2.socket.readyState === 1
|
||||
side: currentSong.p2Cursor === currentDiff && p2.socket.readyState === 1,
|
||||
two: p2.session && p2.player === 2
|
||||
})
|
||||
}
|
||||
if(highlight){
|
||||
@ -1644,6 +1674,22 @@ class SongSelect{
|
||||
drawDifficulty(ctx, i, currentUra)
|
||||
}
|
||||
}
|
||||
for(var i = 0; currentSong.courses && i < 4; i++){
|
||||
if(!songSel && i === currentSong.p2Cursor && p2.socket.readyState === 1){
|
||||
var _x = x + 402 + i * 100
|
||||
var _y = y + 87
|
||||
var currentDiff = this.selectedDiff - this.diffOptions.length
|
||||
this.draw.diffCursor({
|
||||
ctx: ctx,
|
||||
font: this.font,
|
||||
x: _x,
|
||||
y: _y - 65,
|
||||
two: !p2.session || p2.player === 1,
|
||||
side: currentSong.p2Cursor === currentDiff,
|
||||
scale: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var borders = (this.songAsset.border + this.songAsset.innerBorder) * 2
|
||||
var textW = this.songAsset.width - borders
|
||||
@ -1900,20 +1946,27 @@ class SongSelect{
|
||||
ctx.lineTo(x + w - 4, y + 4)
|
||||
ctx.fill()
|
||||
|
||||
if(!p2.session || p2.player === 1){
|
||||
var name = account.loggedIn ? account.displayName : strings.defaultName
|
||||
var rank = account.loggedIn || !gameConfig.accounts || p2.session ? false : strings.notLoggedIn
|
||||
}else{
|
||||
var name = p2.name || strings.defaultName
|
||||
var rank = false
|
||||
}
|
||||
this.nameplateCache.get({
|
||||
ctx: ctx,
|
||||
x: frameLeft + 60,
|
||||
y: frameTop + 640,
|
||||
w: 273,
|
||||
h: 66,
|
||||
id: "1p",
|
||||
id: "1p" + name + "\n" + rank,
|
||||
}, ctx => {
|
||||
this.draw.nameplate({
|
||||
ctx: ctx,
|
||||
x: 3,
|
||||
y: 3,
|
||||
name: account.loggedIn ? account.displayName : strings.defaultName,
|
||||
rank: account.loggedIn || !gameConfig._accounts || p2.session ? false : strings.notLoggedIn,
|
||||
name: name,
|
||||
rank: rank,
|
||||
font: this.font
|
||||
})
|
||||
})
|
||||
@ -2049,25 +2102,131 @@ class SongSelect{
|
||||
}
|
||||
}
|
||||
if(p2.session){
|
||||
if(p2.player === 1){
|
||||
var name = p2.name || strings.default2PName
|
||||
}else{
|
||||
var name = account.loggedIn ? account.displayName : strings.default2PName
|
||||
}
|
||||
this.nameplateCache.get({
|
||||
ctx: ctx,
|
||||
x: frameLeft + 949,
|
||||
y: frameTop + 640,
|
||||
w: 273,
|
||||
h: 66,
|
||||
id: "2p",
|
||||
id: "2p" + name,
|
||||
}, ctx => {
|
||||
this.draw.nameplate({
|
||||
ctx: ctx,
|
||||
x: 3,
|
||||
y: 3,
|
||||
name: p2.name,
|
||||
name: name,
|
||||
font: this.font,
|
||||
blue: true
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if(this.state.scoreSaveFailed){
|
||||
if(this.preview){
|
||||
this.endPreview()
|
||||
}
|
||||
ctx.fillStyle = "rgba(0, 0, 0, 0.5)"
|
||||
ctx.fillRect(0, 0, winW, winH)
|
||||
|
||||
ctx.save()
|
||||
ctx.translate(frameLeft, frameTop)
|
||||
|
||||
var pauseRect = (ctx, mul) => {
|
||||
this.draw.roundedRect({
|
||||
ctx: ctx,
|
||||
x: 269 * mul,
|
||||
y: 93 * mul,
|
||||
w: 742 * mul,
|
||||
h: 494 * mul,
|
||||
radius: 17 * mul
|
||||
})
|
||||
}
|
||||
pauseRect(ctx, 1)
|
||||
ctx.strokeStyle = "#fff"
|
||||
ctx.lineWidth = 24
|
||||
ctx.stroke()
|
||||
ctx.strokeStyle = "#000"
|
||||
ctx.lineWidth = 12
|
||||
ctx.stroke()
|
||||
this.draw.pattern({
|
||||
ctx: ctx,
|
||||
img: assets.image["bg_pause"],
|
||||
shape: pauseRect,
|
||||
dx: 68,
|
||||
dy: 11
|
||||
})
|
||||
this.draw.wrappingText({
|
||||
ctx: ctx,
|
||||
text: strings.scoreSaveFailed,
|
||||
fontSize: 30,
|
||||
fontFamily: this.font,
|
||||
x: 300,
|
||||
y: 130,
|
||||
width: 680,
|
||||
height: 300,
|
||||
lineHeight: 35,
|
||||
fill: "#000",
|
||||
verticalAlign: "middle",
|
||||
textAlign: "center",
|
||||
})
|
||||
|
||||
var _x = 640
|
||||
var _y = 470
|
||||
var _w = 464
|
||||
var _h = 80
|
||||
ctx.fillStyle = "#ffb447"
|
||||
this.draw.roundedRect({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2,
|
||||
y: _y,
|
||||
w: _w,
|
||||
h: _h,
|
||||
radius: 30
|
||||
})
|
||||
ctx.fill()
|
||||
var layers = [
|
||||
{outline: "#000", letterBorder: 10},
|
||||
{fill: "#fff"}
|
||||
]
|
||||
this.draw.layeredText({
|
||||
ctx: ctx,
|
||||
text: strings.ok,
|
||||
x: _x,
|
||||
y: _y + 18,
|
||||
width: _w,
|
||||
height: _h - 54,
|
||||
fontSize: 40,
|
||||
fontFamily: this.font,
|
||||
letterSpacing: -1,
|
||||
align: "center"
|
||||
}, layers)
|
||||
|
||||
var highlight = 1
|
||||
if(this.state.moveHover === "scoreSaveFailed"){
|
||||
highlight = 2
|
||||
}
|
||||
if(highlight){
|
||||
this.draw.highlight({
|
||||
ctx: ctx,
|
||||
x: _x - _w / 2 - 3.5,
|
||||
y: _y - 3.5,
|
||||
w: _w + 7,
|
||||
h: _h + 7,
|
||||
animate: highlight === 1,
|
||||
animateMS: this.state.moveMS,
|
||||
opacity: highlight === 2 ? 0.8 : 1,
|
||||
radius: 30
|
||||
})
|
||||
}
|
||||
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
if(screen === "titleFadeIn"){
|
||||
ctx.save()
|
||||
|
||||
@ -2120,7 +2279,7 @@ class SongSelect{
|
||||
})
|
||||
}
|
||||
this.draw.songFrame(config)
|
||||
if(config.song.p2Cursor && p2.socket.readyState === 1){
|
||||
if(config.song.p2Cursor !== null && p2.socket.readyState === 1){
|
||||
this.draw.diffCursor({
|
||||
ctx: ctx,
|
||||
font: this.font,
|
||||
@ -2167,6 +2326,9 @@ class SongSelect{
|
||||
}
|
||||
|
||||
startPreview(loadOnly){
|
||||
if(!loadOnly && this.state && this.state.scoreSaveFailed){
|
||||
return
|
||||
}
|
||||
var currentSong = this.songs[this.selectedSong]
|
||||
var id = currentSong.id
|
||||
var prvTime = currentSong.preview
|
||||
@ -2242,6 +2404,9 @@ class SongSelect{
|
||||
}
|
||||
}
|
||||
playBgm(enabled){
|
||||
if(enabled && this.state && this.state.scoreSaveFailed){
|
||||
return
|
||||
}
|
||||
if(enabled && !this.bgmEnabled){
|
||||
this.bgmEnabled = true
|
||||
snd.musicGain.fadeIn(0.4)
|
||||
|
@ -37,6 +37,7 @@
|
||||
this.oni = "おに"
|
||||
this.songBranch = "譜面分岐あり"
|
||||
this.defaultName = "どんちゃん"
|
||||
this.default2PName = "かっちゃん"
|
||||
this.notLoggedIn = "ログインしていない"
|
||||
this.sessionStart = "オンラインセッションを開始する!"
|
||||
this.sessionEnd = "オンラインセッションを終了する"
|
||||
@ -197,6 +198,7 @@
|
||||
register: "登録",
|
||||
registerAccount: "アカウントを登録",
|
||||
passwordsDoNotMatch: "パスワードが一致しません",
|
||||
newPasswordsDoNotMatch: "New passwords do not match",
|
||||
cannotBeEmpty: "%sは空にできません",
|
||||
error: "リクエストの処理中にエラーが発生しました",
|
||||
logout: "ログアウト",
|
||||
@ -213,6 +215,17 @@
|
||||
deleteAccount: "Delete Account",
|
||||
verifyPassword: "Verify password to delete this account"
|
||||
}
|
||||
this.serverError = {
|
||||
not_logged_in: "Not logged in",
|
||||
invalid_username: "Invalid username, a username can only contain letters, numbers, and underscores, and must be between 3 and 20 characters long",
|
||||
username_in_use: "A user already exists with that username",
|
||||
invalid_password: "Cannot use this password, please check that your password is at least 6 characters long",
|
||||
invalid_username_password: "Invalid Username or Password",
|
||||
invalid_display_name: "Cannot use this name, please check that your new name is at most 25 characters long",
|
||||
current_password_invalid: "Current password does not match",
|
||||
invalid_new_password: "Cannot use this password, please check that your new password is at least 6 characters long",
|
||||
verify_password_invalid: "Verification password does not match"
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "サポートされていないブラウザを実行しています (%s)",
|
||||
details: "詳しく",
|
||||
@ -263,9 +276,11 @@ function StringsEn(){
|
||||
this.oni = "Extreme"
|
||||
this.songBranch = "Diverge Notes"
|
||||
this.defaultName = "Don-chan"
|
||||
this.default2PName = "Katsu-chan"
|
||||
this.notLoggedIn = "Not logged in"
|
||||
this.sessionStart = "Begin an Online Session!"
|
||||
this.sessionEnd = "End Online Session"
|
||||
this.scoreSaveFailed = "Could not connect to the server, your score has not been saved.\n\nPlease log in or refresh the page to try saving the score again."
|
||||
this.loading = "Loading..."
|
||||
this.waitingForP2 = "Waiting for Another Player..."
|
||||
this.cancel = "Cancel"
|
||||
@ -423,6 +438,7 @@ function StringsEn(){
|
||||
register: "Register",
|
||||
registerAccount: "Register account",
|
||||
passwordsDoNotMatch: "Passwords do not match",
|
||||
newPasswordsDoNotMatch: "New passwords do not match",
|
||||
cannotBeEmpty: "%s cannot be empty",
|
||||
error: "An error occurred while processing your request",
|
||||
logout: "Log Out",
|
||||
@ -439,6 +455,17 @@ function StringsEn(){
|
||||
deleteAccount: "Delete Account",
|
||||
verifyPassword: "Verify password to delete this account"
|
||||
}
|
||||
this.serverError = {
|
||||
not_logged_in: "Not logged in",
|
||||
invalid_username: "Invalid username, a username can only contain letters, numbers, and underscores, and must be between 3 and 20 characters long",
|
||||
username_in_use: "A user already exists with that username",
|
||||
invalid_password: "Cannot use this password, please check that your password is at least 6 characters long",
|
||||
invalid_username_password: "Invalid Username or Password",
|
||||
invalid_display_name: "Cannot use this name, please check that your new name is at most 25 characters long",
|
||||
current_password_invalid: "Current password does not match",
|
||||
invalid_new_password: "Cannot use this password, please check that your new password is at least 6 characters long",
|
||||
verify_password_invalid: "Verification password does not match"
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "You are running an unsupported browser (%s)",
|
||||
details: "Details...",
|
||||
@ -489,6 +516,7 @@ function StringsCn(){
|
||||
this.oni = "魔王"
|
||||
this.songBranch = "有谱面分歧"
|
||||
this.defaultName = "小咚"
|
||||
this.default2PName = "小咔"
|
||||
this.notLoggedIn = "未登录"
|
||||
this.sessionStart = "开始在线会话!"
|
||||
this.sessionEnd = "结束在线会话"
|
||||
@ -649,6 +677,7 @@ function StringsCn(){
|
||||
register: "注册",
|
||||
registerAccount: "注册帐号",
|
||||
passwordsDoNotMatch: "密码不匹配",
|
||||
newPasswordsDoNotMatch: "New passwords do not match",
|
||||
cannotBeEmpty: "%s不能为空",
|
||||
error: "处理您的请求时发生错误",
|
||||
logout: "登出",
|
||||
@ -665,6 +694,17 @@ function StringsCn(){
|
||||
deleteAccount: "Delete Account",
|
||||
verifyPassword: "Verify password to delete this account"
|
||||
}
|
||||
this.serverError = {
|
||||
not_logged_in: "Not logged in",
|
||||
invalid_username: "Invalid username, a username can only contain letters, numbers, and underscores, and must be between 3 and 20 characters long",
|
||||
username_in_use: "A user already exists with that username",
|
||||
invalid_password: "Cannot use this password, please check that your password is at least 6 characters long",
|
||||
invalid_username_password: "Invalid Username or Password",
|
||||
invalid_display_name: "Cannot use this name, please check that your new name is at most 25 characters long",
|
||||
current_password_invalid: "Current password does not match",
|
||||
invalid_new_password: "Cannot use this password, please check that your new password is at least 6 characters long",
|
||||
verify_password_invalid: "Verification password does not match"
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "You are running an unsupported browser (%s)",
|
||||
details: "Details...",
|
||||
@ -715,6 +755,7 @@ function StringsTw(){
|
||||
this.oni = "魔王"
|
||||
this.songBranch = "有譜面分歧"
|
||||
this.defaultName = "小咚"
|
||||
this.default2PName = "小咔"
|
||||
this.notLoggedIn = "未登錄"
|
||||
this.sessionStart = "開始多人模式!"
|
||||
this.sessionEnd = "結束多人模式"
|
||||
@ -875,6 +916,7 @@ function StringsTw(){
|
||||
register: "註冊",
|
||||
registerAccount: "註冊帳號",
|
||||
passwordsDoNotMatch: "密碼不匹配",
|
||||
newPasswordsDoNotMatch: "New passwords do not match",
|
||||
cannotBeEmpty: "%s不能為空",
|
||||
error: "處理您的請求時發生錯誤",
|
||||
logout: "登出",
|
||||
@ -891,6 +933,17 @@ function StringsTw(){
|
||||
deleteAccount: "Delete Account",
|
||||
verifyPassword: "Verify password to delete this account"
|
||||
}
|
||||
this.serverError = {
|
||||
not_logged_in: "Not logged in",
|
||||
invalid_username: "Invalid username, a username can only contain letters, numbers, and underscores, and must be between 3 and 20 characters long",
|
||||
username_in_use: "A user already exists with that username",
|
||||
invalid_password: "Cannot use this password, please check that your password is at least 6 characters long",
|
||||
invalid_username_password: "Invalid Username or Password",
|
||||
invalid_display_name: "Cannot use this name, please check that your new name is at most 25 characters long",
|
||||
current_password_invalid: "Current password does not match",
|
||||
invalid_new_password: "Cannot use this password, please check that your new password is at least 6 characters long",
|
||||
verify_password_invalid: "Verification password does not match"
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "You are running an unsupported browser (%s)",
|
||||
details: "Details...",
|
||||
@ -941,6 +994,7 @@ function StringsKo(){
|
||||
this.oni = "귀신"
|
||||
this.songBranch = "악보 분기 있습니다"
|
||||
this.defaultName = "동이"
|
||||
this.default2PName = "딱이"
|
||||
this.notLoggedIn = "로그인하지 않았습니다"
|
||||
this.sessionStart = "온라인 세션 시작!"
|
||||
this.sessionEnd = "온라인 세션 끝내기"
|
||||
@ -1101,6 +1155,7 @@ function StringsKo(){
|
||||
register: "가입하기",
|
||||
registerAccount: "계정 등록",
|
||||
passwordsDoNotMatch: "비밀번호가 일치하지 않습니다",
|
||||
newPasswordsDoNotMatch: "New passwords do not match",
|
||||
cannotBeEmpty: "%s 비어 있을 수 없습니다",
|
||||
error: "요청을 처리하는 동안 오류가 발생했습니다",
|
||||
logout: "로그 아웃",
|
||||
@ -1117,6 +1172,17 @@ function StringsKo(){
|
||||
deleteAccount: "Delete Account",
|
||||
verifyPassword: "Verify password to delete this account"
|
||||
}
|
||||
this.serverError = {
|
||||
not_logged_in: "Not logged in",
|
||||
invalid_username: "Invalid username, a username can only contain letters, numbers, and underscores, and must be between 3 and 20 characters long",
|
||||
username_in_use: "A user already exists with that username",
|
||||
invalid_password: "Cannot use this password, please check that your password is at least 6 characters long",
|
||||
invalid_username_password: "Invalid Username or Password",
|
||||
invalid_display_name: "Cannot use this name, please check that your new name is at most 25 characters long",
|
||||
current_password_invalid: "Current password does not match",
|
||||
invalid_new_password: "Cannot use this password, please check that your new password is at least 6 characters long",
|
||||
verify_password_invalid: "Verification password does not match"
|
||||
}
|
||||
this.browserSupport = {
|
||||
browserWarning: "You are running an unsupported browser (%s)",
|
||||
details: "Details...",
|
||||
|
@ -129,6 +129,11 @@
|
||||
this.nameplateCache = new CanvasCache(noSmoothing)
|
||||
|
||||
this.multiplayer = this.controller.multiplayer
|
||||
if(this.multiplayer === 2){
|
||||
this.player = p2.player === 2 ? 1 : 2
|
||||
}else{
|
||||
this.player = this.controller.multiplayer ? p2.player : 1
|
||||
}
|
||||
|
||||
this.touchEnabled = this.controller.touchEnabled
|
||||
this.touch = -Infinity
|
||||
@ -224,13 +229,12 @@
|
||||
this.winH = winH
|
||||
this.ratio = ratio
|
||||
|
||||
if(this.multiplayer !== 2){
|
||||
if(this.player !== 2){
|
||||
this.canvas.width = winW
|
||||
this.canvas.height = winH
|
||||
ctx.scale(ratio, ratio)
|
||||
this.canvas.style.width = (winW / this.pixelRatio) + "px"
|
||||
this.canvas.style.height = (winH / this.pixelRatio) + "px"
|
||||
|
||||
this.titleCache.resize(640, 90, ratio)
|
||||
}
|
||||
if(!this.multiplayer){
|
||||
@ -246,7 +250,7 @@
|
||||
resized = true
|
||||
}else if(this.controller.game.paused && !document.hasFocus()){
|
||||
return
|
||||
}else if(this.multiplayer !== 2){
|
||||
}else if(this.player !== 2){
|
||||
ctx.clearRect(0, 0, winW / ratio, winH / ratio)
|
||||
}
|
||||
winW /= ratio
|
||||
@ -263,8 +267,8 @@
|
||||
var frameTop = winH / 2 - 720 / 2
|
||||
var frameLeft = winW / 2 - 1280 / 2
|
||||
}
|
||||
if(this.multiplayer === 2){
|
||||
frameTop += this.multiplayer === 2 ? 165 : 176
|
||||
if(this.player === 2){
|
||||
frameTop += 165
|
||||
}
|
||||
if(touchMultiplayer){
|
||||
if(!this.touchp2Class){
|
||||
@ -284,11 +288,11 @@
|
||||
|
||||
this.drawGogoTime()
|
||||
|
||||
if(!touchMultiplayer || this.multiplayer === 1 && frameTop >= 0){
|
||||
if(!touchMultiplayer || this.player === 1 && frameTop >= 0){
|
||||
this.assets.drawAssets("background")
|
||||
}
|
||||
|
||||
if(this.multiplayer !== 2){
|
||||
if(this.player !== 2){
|
||||
this.titleCache.get({
|
||||
ctx: ctx,
|
||||
x: winW - (touchMultiplayer && fullScreenSupported ? 750 : 650),
|
||||
@ -356,7 +360,7 @@
|
||||
var score = this.controller.getGlobalScore()
|
||||
var gaugePercent = this.rules.gaugePercent(score.gauge)
|
||||
|
||||
if(this.multiplayer === 2){
|
||||
if(this.player === 2){
|
||||
var scoreImg = "bg_score_p2"
|
||||
var scoreFill = "#6bbec0"
|
||||
}else{
|
||||
@ -379,17 +383,17 @@
|
||||
size: 100,
|
||||
paddingLeft: 0
|
||||
}
|
||||
this.scorePos = {x: 363, y: frameTop + (this.multiplayer === 2 ? 520 : 227)}
|
||||
this.scorePos = {x: 363, y: frameTop + (this.player === 2 ? 520 : 227)}
|
||||
|
||||
var animPos = {
|
||||
x1: this.slotPos.x + 13,
|
||||
y1: this.slotPos.y + (this.multiplayer === 2 ? 27 : -27),
|
||||
y1: this.slotPos.y + (this.player === 2 ? 27 : -27),
|
||||
x2: winW - 38,
|
||||
y2: frameTop + (this.multiplayer === 2 ? 484 : 293)
|
||||
y2: frameTop + (this.player === 2 ? 484 : 293)
|
||||
}
|
||||
var taikoPos = {
|
||||
x: 19,
|
||||
y: frameTop + (this.multiplayer === 2 ? 464 : 184),
|
||||
y: frameTop + (this.player === 2 ? 464 : 184),
|
||||
w: 111,
|
||||
h: 130
|
||||
}
|
||||
@ -397,15 +401,16 @@
|
||||
this.nameplateCache.get({
|
||||
ctx: ctx,
|
||||
x: 167,
|
||||
y: this.multiplayer === 2 ? 565 : 160,
|
||||
y: this.player === 2 ? 565 : 160,
|
||||
w: 219,
|
||||
h: 53,
|
||||
id: "1p",
|
||||
}, ctx => {
|
||||
var defaultName = this.player === 1 ? strings.defaultName : strings.default2PName
|
||||
if(this.multiplayer === 2){
|
||||
var name = p2.name || strings.defaultName
|
||||
var name = p2.name || defaultName
|
||||
}else{
|
||||
var name = account.loggedIn ? account.displayName : strings.defaultName
|
||||
var name = account.loggedIn ? account.displayName : defaultName
|
||||
}
|
||||
this.draw.nameplate({
|
||||
ctx: ctx,
|
||||
@ -414,19 +419,19 @@
|
||||
scale: 0.8,
|
||||
name: name,
|
||||
font: this.font,
|
||||
blue: this.multiplayer === 2
|
||||
blue: this.player === 2
|
||||
})
|
||||
})
|
||||
|
||||
ctx.fillStyle = "#000"
|
||||
ctx.fillRect(
|
||||
0,
|
||||
this.multiplayer === 2 ? 306 : 288,
|
||||
this.player === 2 ? 306 : 288,
|
||||
winW,
|
||||
this.multiplayer === 1 ? 184 : 183
|
||||
this.player === 1 ? 184 : 183
|
||||
)
|
||||
ctx.beginPath()
|
||||
if(this.multiplayer === 2){
|
||||
if(this.player === 2){
|
||||
ctx.moveTo(0, 467)
|
||||
ctx.lineTo(384, 467)
|
||||
ctx.lineTo(384, 512)
|
||||
@ -445,7 +450,7 @@
|
||||
ctx.fillStyle = scoreFill
|
||||
var leftSide = (ctx, mul) => {
|
||||
ctx.beginPath()
|
||||
if(this.multiplayer === 2){
|
||||
if(this.player === 2){
|
||||
ctx.moveTo(0, 468 * mul)
|
||||
ctx.lineTo(380 * mul, 468 * mul)
|
||||
ctx.lineTo(380 * mul, 512 * mul)
|
||||
@ -475,7 +480,7 @@
|
||||
// Score background
|
||||
ctx.fillStyle = "#000"
|
||||
ctx.beginPath()
|
||||
if(this.multiplayer === 2){
|
||||
if(this.player === 2){
|
||||
this.draw.roundedCorner(ctx, 184, 512, 20, 0)
|
||||
ctx.lineTo(384, 512)
|
||||
this.draw.roundedCorner(ctx, 384, 560, 12, 2)
|
||||
@ -493,16 +498,16 @@
|
||||
ctx.drawImage(assets.image["difficulty"],
|
||||
0, 144 * this.difficulty[this.controller.selectedSong.difficulty],
|
||||
168, 143,
|
||||
126, this.multiplayer === 2 ? 497 : 228,
|
||||
126, this.player === 2 ? 497 : 228,
|
||||
62, 53
|
||||
)
|
||||
}
|
||||
|
||||
// Badges
|
||||
if(this.controller.autoPlayEnabled && !this.controller.multiplayer){
|
||||
if(this.controller.autoPlayEnabled && !this.multiplayer){
|
||||
this.ctx.drawImage(assets.image["badge_auto"],
|
||||
183,
|
||||
this.multiplayer === 2 ? 490 : 265,
|
||||
this.player === 2 ? 490 : 265,
|
||||
23,
|
||||
23
|
||||
)
|
||||
@ -512,7 +517,7 @@
|
||||
ctx.fillStyle = "#000"
|
||||
ctx.beginPath()
|
||||
var gaugeX = winW - 788 * 0.7 - 32
|
||||
if(this.multiplayer === 2){
|
||||
if(this.player === 2){
|
||||
ctx.moveTo(gaugeX, 464)
|
||||
ctx.lineTo(winW, 464)
|
||||
ctx.lineTo(winW, 489)
|
||||
@ -527,18 +532,18 @@
|
||||
this.draw.gauge({
|
||||
ctx: ctx,
|
||||
x: winW,
|
||||
y: this.multiplayer === 2 ? 468 : 273,
|
||||
y: this.player === 2 ? 468 : 273,
|
||||
clear: this.rules.gaugeClear,
|
||||
percentage: gaugePercent,
|
||||
font: this.font,
|
||||
scale: 0.7,
|
||||
multiplayer: this.multiplayer === 2,
|
||||
blue: this.multiplayer === 2
|
||||
multiplayer: this.player === 2,
|
||||
blue: this.player === 2
|
||||
})
|
||||
this.draw.soul({
|
||||
ctx: ctx,
|
||||
x: winW - 40,
|
||||
y: this.multiplayer === 2 ? 484 : 293,
|
||||
y: this.player === 2 ? 484 : 293,
|
||||
scale: 0.75,
|
||||
cleared: this.rules.clearReached(score.gauge)
|
||||
})
|
||||
@ -566,29 +571,30 @@
|
||||
}
|
||||
this.scorePos = {
|
||||
x: 155,
|
||||
y: frameTop + (this.multiplayer === 2 ? 318 : 193)
|
||||
y: frameTop + (this.player === 2 ? 318 : 193)
|
||||
}
|
||||
|
||||
var animPos = {
|
||||
x1: this.slotPos.x + 14,
|
||||
y1: this.slotPos.y + (this.multiplayer === 2 ? 29 : -29),
|
||||
y1: this.slotPos.y + (this.player === 2 ? 29 : -29),
|
||||
x2: winW - 55,
|
||||
y2: frameTop + (this.multiplayer === 2 ? 378 : 165)
|
||||
y2: frameTop + (this.player === 2 ? 378 : 165)
|
||||
}
|
||||
var taikoPos = {x: 179, y: frameTop + 190, w: 138, h: 162}
|
||||
|
||||
this.nameplateCache.get({
|
||||
ctx: ctx,
|
||||
x: 320,
|
||||
y: this.multiplayer === 2 ? 460 : 20,
|
||||
y: this.player === 2 ? 460 : 20,
|
||||
w: 273,
|
||||
h: 66,
|
||||
id: "1p",
|
||||
}, ctx => {
|
||||
var defaultName = this.player === 1 ? strings.defaultName : strings.default2PName
|
||||
if(this.multiplayer === 2){
|
||||
var name = p2.name || strings.defaultName
|
||||
var name = p2.name || defaultName
|
||||
}else{
|
||||
var name = account.loggedIn ? account.displayName : strings.defaultName
|
||||
var name = account.loggedIn ? account.displayName : defaultName
|
||||
}
|
||||
this.draw.nameplate({
|
||||
ctx: ctx,
|
||||
@ -596,7 +602,7 @@
|
||||
y: 3,
|
||||
name: name,
|
||||
font: this.font,
|
||||
blue: this.multiplayer === 2
|
||||
blue: this.player === 2
|
||||
})
|
||||
})
|
||||
|
||||
@ -605,10 +611,10 @@
|
||||
0,
|
||||
184,
|
||||
winW,
|
||||
this.multiplayer === 1 ? 177 : 176
|
||||
this.multiplayer && this.player === 1 ? 177 : 176
|
||||
)
|
||||
ctx.beginPath()
|
||||
if(this.multiplayer === 2){
|
||||
if(this.player === 2){
|
||||
ctx.moveTo(328, 351)
|
||||
ctx.lineTo(winW, 351)
|
||||
ctx.lineTo(winW, 385)
|
||||
@ -625,17 +631,17 @@
|
||||
this.draw.gauge({
|
||||
ctx: ctx,
|
||||
x: winW,
|
||||
y: this.multiplayer === 2 ? 357 : 135,
|
||||
y: this.player === 2 ? 357 : 135,
|
||||
clear: this.rules.gaugeClear,
|
||||
percentage: gaugePercent,
|
||||
font: this.font,
|
||||
multiplayer: this.multiplayer === 2,
|
||||
blue: this.multiplayer === 2
|
||||
multiplayer: this.player === 2,
|
||||
blue: this.player === 2
|
||||
})
|
||||
this.draw.soul({
|
||||
ctx: ctx,
|
||||
x: winW - 57,
|
||||
y: this.multiplayer === 2 ? 378 : 165,
|
||||
y: this.player === 2 ? 378 : 165,
|
||||
cleared: this.rules.clearReached(score.gauge)
|
||||
})
|
||||
|
||||
@ -667,7 +673,7 @@
|
||||
ctx.drawImage(assets.image["difficulty"],
|
||||
0, 144 * this.difficulty[this.controller.selectedSong.difficulty],
|
||||
168, 143,
|
||||
16, this.multiplayer === 2 ? 194 : 232,
|
||||
16, this.player === 2 ? 194 : 232,
|
||||
141, 120
|
||||
)
|
||||
var diff = this.controller.selectedSong.difficulty
|
||||
@ -679,13 +685,13 @@
|
||||
ctx.fillStyle = "#fff"
|
||||
ctx.lineWidth = 7
|
||||
ctx.miterLimit = 1
|
||||
ctx.strokeText(text, 87, this.multiplayer === 2 ? 310 : 348)
|
||||
ctx.fillText(text, 87, this.multiplayer === 2 ? 310 : 348)
|
||||
ctx.strokeText(text, 87, this.player === 2 ? 310 : 348)
|
||||
ctx.fillText(text, 87, this.player === 2 ? 310 : 348)
|
||||
ctx.miterLimit = 10
|
||||
}
|
||||
|
||||
// Badges
|
||||
if(this.controller.autoPlayEnabled && !this.controller.multiplayer){
|
||||
if(this.controller.autoPlayEnabled && !this.multiplayer){
|
||||
this.ctx.drawImage(assets.image["badge_auto"],
|
||||
125, 235, 34, 34
|
||||
)
|
||||
@ -694,7 +700,7 @@
|
||||
// Score background
|
||||
ctx.fillStyle = "#000"
|
||||
ctx.beginPath()
|
||||
if(this.multiplayer === 2){
|
||||
if(this.player === 2){
|
||||
ctx.moveTo(0, 312)
|
||||
this.draw.roundedCorner(ctx, 176, 312, 20, 1)
|
||||
ctx.lineTo(176, 353)
|
||||
@ -719,11 +725,11 @@
|
||||
}, {
|
||||
// 560, 10
|
||||
x: animPos.x1 + animPos.w / 6,
|
||||
y: animPos.y1 - animPos.h * (this.multiplayer === 2 ? 2.5 : 3.5)
|
||||
y: animPos.y1 - animPos.h * (this.player === 2 ? 2.5 : 3.5)
|
||||
}, {
|
||||
// 940, -150
|
||||
x: animPos.x2 - animPos.w / 3,
|
||||
y: animPos.y2 - animPos.h * (this.multiplayer === 2 ? 3.5 : 5)
|
||||
y: animPos.y2 - animPos.h * (this.player === 2 ? 3.5 : 5)
|
||||
}, {
|
||||
// 1225, 165
|
||||
x: animPos.x2,
|
||||
@ -1443,12 +1449,12 @@
|
||||
var selectedSong = this.controller.selectedSong
|
||||
var songSkinName = selectedSong.songSkin.name
|
||||
var donLayers = []
|
||||
var filename = !selectedSong.songSkin.don && this.multiplayer === 2 ? "bg_don2_" : "bg_don_"
|
||||
var filename = !selectedSong.songSkin.don && this.player === 2 ? "bg_don2_" : "bg_don_"
|
||||
var prefix = ""
|
||||
|
||||
this.donBg = document.createElement("div")
|
||||
this.donBg.classList.add("donbg")
|
||||
if(this.multiplayer === 2){
|
||||
if(this.player === 2){
|
||||
this.donBg.classList.add("donbg-bottom")
|
||||
}
|
||||
for(var layer = 1; layer <= 3; layer++){
|
||||
|
@ -18,7 +18,7 @@ class ViewAssets{
|
||||
sw: imgw,
|
||||
sh: imgh - 1,
|
||||
x: view.portrait ? -60 : 0,
|
||||
y: view.portrait ? (view.multiplayer === 2 ? 560 : 35) : (view.multiplayer === 2 ? 360 : 2),
|
||||
y: view.portrait ? (view.player === 2 ? 560 : 35) : (view.player === 2 ? 360 : 2),
|
||||
w: w,
|
||||
h: h - 1
|
||||
}
|
||||
|
@ -2,9 +2,10 @@
|
||||
<div class="view account-view">
|
||||
<div class="view-title stroke-sub"></div>
|
||||
<div class="view-content">
|
||||
<div class="error-div"></div>
|
||||
<div class="displayname-div">
|
||||
<div class="displayname-hint"></div>
|
||||
<input type="text" class="displayname">
|
||||
<input type="text" class="displayname" maxlength="25">
|
||||
</div>
|
||||
<form class="accountpass-form">
|
||||
<div>
|
||||
|
@ -2,9 +2,10 @@
|
||||
<div class="view">
|
||||
<div class="view-title stroke-sub"></div>
|
||||
<div class="view-content">
|
||||
<div class="error-div"></div>
|
||||
<form class="login-form">
|
||||
<div class="username-hint"></div>
|
||||
<input type="text" name="username" required>
|
||||
<input type="text" name="username" maxlength="20" required>
|
||||
<div class="password-hint"></div>
|
||||
<input type="password" name="password" required>
|
||||
<div class="password2-div"></div>
|
||||
|
13
server.py
13
server.py
@ -103,8 +103,8 @@ async def connection(ws, path):
|
||||
user["other_user"]["action"] = "loading"
|
||||
user["other_user"]["other_user"] = user
|
||||
await asyncio.wait([
|
||||
ws.send(msgobj("gameload", waiting_diff)),
|
||||
user["other_user"]["ws"].send(msgobj("gameload", diff)),
|
||||
ws.send(msgobj("gameload", {"diff": waiting_diff, "player": 2})),
|
||||
user["other_user"]["ws"].send(msgobj("gameload", {"diff": diff, "player": 1})),
|
||||
ws.send(msgobj("name", user["other_user"]["name"])),
|
||||
user["other_user"]["ws"].send(msgobj("name", user["name"]))
|
||||
])
|
||||
@ -138,10 +138,9 @@ async def connection(ws, path):
|
||||
user["other_user"]["other_user"] = user
|
||||
user["action"] = "invite"
|
||||
user["session"] = value["id"]
|
||||
sent_msg = msgobj("session")
|
||||
await asyncio.wait([
|
||||
ws.send(sent_msg),
|
||||
user["other_user"]["ws"].send(sent_msg),
|
||||
ws.send(msgobj("session", {"player": 2})),
|
||||
user["other_user"]["ws"].send(msgobj("session", {"player": 1})),
|
||||
ws.send(msgobj("invite")),
|
||||
ws.send(msgobj("name", user["other_user"]["name"])),
|
||||
user["other_user"]["ws"].send(msgobj("name", user["name"]))
|
||||
@ -291,8 +290,8 @@ async def connection(ws, path):
|
||||
user["action"] = "loading"
|
||||
user["other_user"]["action"] = "loading"
|
||||
await asyncio.wait([
|
||||
ws.send(msgobj("gameload", user["other_user"]["gamediff"])),
|
||||
user["other_user"]["ws"].send(msgobj("gameload", diff))
|
||||
ws.send(msgobj("gameload", {"diff": user["other_user"]["gamediff"]})),
|
||||
user["other_user"]["ws"].send(msgobj("gameload", {"diff": diff}))
|
||||
])
|
||||
else:
|
||||
user["action"] = "waiting"
|
||||
|
Loading…
Reference in New Issue
Block a user