diff --git a/src/mami.css/baka.css b/src/mami.css/baka.css new file mode 100644 index 0000000..dd3007d --- /dev/null +++ b/src/mami.css/baka.css @@ -0,0 +1,67 @@ +@keyframes baka-marquee-anim { + from { transform: translateX(0); } + to { transform: translateX(-100%); } +} + +.baka { + color: #000; + background: repeating-linear-gradient(-45deg, #ff3d3d, #ff3d3d 20px, #f00 20px, #f00 40px); + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 16px; + line-height: 25px; + color: #fff; + display: flex; + flex-direction: column; +} + +.baka-container { + flex-shrink: 1; + flex-grow: 1; + background: #0008; + display: flex; + flex-direction: column; + justify-content: flex-end; +} + +.baka-bottom { + flex-grow: 0; + flex-shrink: 0; + height: 6em; +} + +.baka-spacing { + flex-grow: 1; + flex-shrink: 1; +} + +.baka-marquee { + flex-grow: 0; + flex-shrink: 0; + display: flex; + width: 100%; + height: 6em; + overflow: hidden; + white-space: nowrap; + background: #0005; + backdrop-filter: blur(4px); +} +.baka-marquee-text { + font-size: 5rem; + line-height: 1.2em; + font-weight: 700; + padding: 0 .25em; + text-transform: uppercase; + animation: baka-marquee-anim 2.33s infinite linear; +} + +.baka-duration { + flex-grow: 0; + flex-shrink: 0; + margin: 5px; +} +.baka-duration-inner { + padding: 5px 10px; + background: #0002; + display: inline-block; + backdrop-filter: blur(4px); +} diff --git a/src/mami.css/main.css b/src/mami.css/main.css index f238110..82fbac6 100644 --- a/src/mami.css/main.css +++ b/src/mami.css/main.css @@ -3,6 +3,7 @@ @include views.css; +@include baka.css; @include chat.css; @include eeprom.css; @include emote.css; diff --git a/src/mami.js/main.js b/src/mami.js/main.js index 1226aee..8f2a77b 100644 --- a/src/mami.js/main.js +++ b/src/mami.js/main.js @@ -25,6 +25,7 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; #include sound/context.js #include sound/osukeys.js #include sound/umisound.js +#include ui/baka.jsx #include ui/chat-layout.js #include ui/hooks.js #include ui/emotes.js @@ -564,6 +565,12 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; '_1013': 'You cannot connect to the server right now, try again later.', '_1015': 'Your client and the server could not establish a secure connection.', }; + const sessFailReasons = { + 'authfail': 'Authentication failed.', + 'sockfail': 'Too many active connections.', + 'userfail': 'Name in use.', + 'joinfail': 'You are banned.', + }; let dumpEvents = false; settings.watch('dumpEvents', value => dumpEvents = value); @@ -606,64 +613,6 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; }); - const playBannedSfx = async () => { - await soundCtx.library.play('touhou:pichuun'); - }; - const playBannedBgm = async preload => { - const name = 'touhou:th10score'; - - if(preload) { - await soundCtx.library.loadBuffer(name); - return; - } - - const source = await soundCtx.library.loadSource(name); - source.setLoop(true, 10.512, 38.074); - await source.play(); - }; - const displayBanMessage = baka => { - let message; - if(baka.perma) - message = 'You have been banned till the end of time, please try again in a different dimension.'; - else if(baka.until) - message = `You were banned until ${baka.until.toLocaleString()}!`; - else - message = 'You were kicked, refresh to log back in!'; - - const icon = baka.type === 'kick' ? 'bomb' : 'hammer'; - const header = baka.type === 'kick' ? 'Kicked!' : 'Banned!'; - - const currentView = views.current(); - - if(currentView === undefined || 'setIcon' in currentView) { - playBannedBgm(); - getLoadingOverlay(icon, header, message); - } else { - const currentViewElem = views.currentElement(); - - MamiAnimate({ - duration: 550, - easing: 'outExpo', - start: () => { - playBannedBgm(true); - playBannedSfx(); - }, - update: t => { - currentViewElem.style.transform = `scale(${(1 - .5 * t)}, ${(1 - 1 * t)})`; - }, - end: () => { - getLoadingOverlay(icon, header, message).then(() => { - playBannedBgm(); - - // there's currently no way to reconnect after a kick/ban so just dispose of the ui entirely - if(views.count() > 1) - views.shift(); - }); - }, - }); - } - }; - Umi.Server.watch('session:start', start => { if(dumpEvents) console.log('session:start', start); @@ -697,23 +646,14 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; if(dumpEvents) console.log('session:fail', fail); if(fail.baka !== undefined) { - displayBanMessage(fail.baka); + new MamiForceDisconnectNotice(fail.baka).pushOn(views); return; } - const message = (reason => { - if(reason === 'authfail') - return 'Authentication failed.'; - if(reason === 'sockfail') - return 'Too many active connections.'; - if(reason === 'userfail') - return 'Name in use.'; - if(reason === 'joinfail') - return 'You are banned.'; - return `Unknown reason: ${reason}`; - })(fail.session.reason); - - getLoadingOverlay('cross', 'Failed!', message); + getLoadingOverlay( + 'cross', 'Failed!', + sessFailReasons[fail.session.reason] ?? `Unknown reason: ${fail.session.reason}` + ); if(fail.session.needsAuth) setTimeout(() => location.assign(futami.get('login')), 1000); @@ -721,7 +661,7 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; Umi.Server.watch('session:term', term => { if(dumpEvents) console.log('session:term', term); - displayBanMessage(term.baka); + new MamiForceDisconnectNotice(term.baka).pushOn(views); }); Umi.Server.watch('user:add', add => { diff --git a/src/mami.js/sleep.js b/src/mami.js/sleep.js new file mode 100644 index 0000000..4122f14 --- /dev/null +++ b/src/mami.js/sleep.js @@ -0,0 +1 @@ +const MamiSleep = durationMs => new Promise(resolve => { setTimeout(resolve, durationMs); }); diff --git a/src/mami.js/ui/baka.jsx b/src/mami.js/ui/baka.jsx new file mode 100644 index 0000000..daee726 --- /dev/null +++ b/src/mami.js/ui/baka.jsx @@ -0,0 +1,82 @@ +#include animate.js +#include easings.js +#include rng.js + +const MamiForceDisconnectNotice = function(banInfo) { + const message = (() => { + if(banInfo.perma) + return 'You have been banned till the end of time, please try again in a different dimension'; + if(banInfo.until) + return `You were banned until ${banInfo.until.toLocaleString()}`; + return 'You were kicked, refresh to log back in'; + })(); + + let marqueeElem; + const html =