From 123b21f8cbd1510415e44dc94fb6c4d94c596f69 Mon Sep 17 00:00:00 2001 From: flashwave Date: Sat, 24 Feb 2024 20:26:40 +0000 Subject: [PATCH] Added new kick/ban screen. --- src/mami.css/baka.css | 67 +++++++++++++++++++++++++ src/mami.css/main.css | 1 + src/mami.js/main.js | 86 +++++---------------------------- src/mami.js/sleep.js | 1 + src/mami.js/ui/baka.jsx | 82 +++++++++++++++++++++++++++++++ src/mami.js/ui/settings.jsx | 18 ++++++- src/mami.js/{ => ui}/youare.jsx | 0 7 files changed, 181 insertions(+), 74 deletions(-) create mode 100644 src/mami.css/baka.css create mode 100644 src/mami.js/sleep.js create mode 100644 src/mami.js/ui/baka.jsx rename src/mami.js/{ => ui}/youare.jsx (100%) 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 =
+
+
+
{message}
+
+ {marqueeElem =
} +
+
+
; + + const marqueeString = banInfo.type === 'kick' ? 'Kicked' : 'Banned'; + for(let i = 0; i < 10; ++i) + marqueeElem.append(
{marqueeString}
); + + const rng = new MamiRNG; + let sfxBuf, sfxSrc, bgmSrc; + + const pub = { + getElement: () => html, + onViewPush: async () => { + try { + sfxBuf = await mami.sound.library.loadBuffer('touhou:pichuun'); + sfxSrc = mami.sound.audio.createSource(sfxBuf); + } catch(ex) { + sfxBuf = sfxSrc = undefined; + } + + try { + bgmSrc = await mami.sound.library.loadSource('touhou:th10score'); + bgmSrc.setLoop(true, 10.512, 38.074); + } catch(ex) { + bgmSrc = undefined; + } + }, + onViewPop: async () => { + bgmSrc?.stop(); + bgmSrc = sfxBuf = sfxSrc = undefined; + }, + pushOn: async views => { + const rotate = rng.next(-20, 20); + + await views.push(pub, ctx => MamiAnimate({ + async: true, + duration: (sfxBuf?.duration ?? 1.4) * 1000, + start: () => { + sfxSrc?.play(); + ctx.toElem.style.top = '-100%'; + }, + update: t => { + const tOutBounce = MamiEasings.outBounce(t); + ctx.toElem.style.top = `${-100 + (tOutBounce * 100)}%`; + + const tOutExpo = MamiEasings.outExpo(t); + ctx.fromElem.style.transform = `scale(${1 - (1 * tOutExpo)}) rotate(${rotate * tOutExpo}deg)`; + ctx.fromElem.style.filter = `grayscale(${tOutExpo * 100}%)`; + }, + end: () => { + bgmSrc?.play(); + ctx.toElem.style.top = null; + ctx.fromElem.style.transform = null; + ctx.fromElem.style.filter = null; + }, + })); + }, + }; + + return pub; +}; diff --git a/src/mami.js/ui/settings.jsx b/src/mami.js/ui/settings.jsx index 1417ff0..f32cf0d 100644 --- a/src/mami.js/ui/settings.jsx +++ b/src/mami.js/ui/settings.jsx @@ -1,12 +1,14 @@ #include animate.js #include common.js #include emotes.js +#include sleep.js #include utility.js -#include youare.jsx #include settings/backup.js +#include ui/baka.jsx #include ui/emotes.js #include ui/menus.js #include ui/view.js +#include ui/youare.jsx Umi.UI.Settings = (function() { const items = [ @@ -384,6 +386,20 @@ Umi.UI.Settings = (function() { title: 'Disable Old Theme System', type: 'checkbox', }, + { + title: 'Test kick/ban notice', + type: 'button', + invoke: async button => { + button.disabled = true; + await (new MamiForceDisconnectNotice({ + perma: true, + type: 'ban', + })).pushOn(mami.views); + await MamiSleep(5000); + await mami.views.pop(); + button.disabled = false; + }, + }, { title: 'You are an idiot!', type: 'button', diff --git a/src/mami.js/youare.jsx b/src/mami.js/ui/youare.jsx similarity index 100% rename from src/mami.js/youare.jsx rename to src/mami.js/ui/youare.jsx