Added new kick/ban screen.
This commit is contained in:
parent
dd2fd189dc
commit
123b21f8cb
7 changed files with 181 additions and 74 deletions
67
src/mami.css/baka.css
Normal file
67
src/mami.css/baka.css
Normal file
|
@ -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);
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
@include views.css;
|
@include views.css;
|
||||||
|
|
||||||
|
@include baka.css;
|
||||||
@include chat.css;
|
@include chat.css;
|
||||||
@include eeprom.css;
|
@include eeprom.css;
|
||||||
@include emote.css;
|
@include emote.css;
|
||||||
|
|
|
@ -25,6 +25,7 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } };
|
||||||
#include sound/context.js
|
#include sound/context.js
|
||||||
#include sound/osukeys.js
|
#include sound/osukeys.js
|
||||||
#include sound/umisound.js
|
#include sound/umisound.js
|
||||||
|
#include ui/baka.jsx
|
||||||
#include ui/chat-layout.js
|
#include ui/chat-layout.js
|
||||||
#include ui/hooks.js
|
#include ui/hooks.js
|
||||||
#include ui/emotes.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.',
|
'_1013': 'You cannot connect to the server right now, try again later.',
|
||||||
'_1015': 'Your client and the server could not establish a secure connection.',
|
'_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;
|
let dumpEvents = false;
|
||||||
settings.watch('dumpEvents', value => dumpEvents = value);
|
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 => {
|
Umi.Server.watch('session:start', start => {
|
||||||
if(dumpEvents) console.log('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(dumpEvents) console.log('session:fail', fail);
|
||||||
|
|
||||||
if(fail.baka !== undefined) {
|
if(fail.baka !== undefined) {
|
||||||
displayBanMessage(fail.baka);
|
new MamiForceDisconnectNotice(fail.baka).pushOn(views);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const message = (reason => {
|
getLoadingOverlay(
|
||||||
if(reason === 'authfail')
|
'cross', 'Failed!',
|
||||||
return 'Authentication failed.';
|
sessFailReasons[fail.session.reason] ?? `Unknown reason: ${fail.session.reason}`
|
||||||
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);
|
|
||||||
|
|
||||||
if(fail.session.needsAuth)
|
if(fail.session.needsAuth)
|
||||||
setTimeout(() => location.assign(futami.get('login')), 1000);
|
setTimeout(() => location.assign(futami.get('login')), 1000);
|
||||||
|
@ -721,7 +661,7 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } };
|
||||||
Umi.Server.watch('session:term', term => {
|
Umi.Server.watch('session:term', term => {
|
||||||
if(dumpEvents) console.log('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 => {
|
Umi.Server.watch('user:add', add => {
|
||||||
|
|
1
src/mami.js/sleep.js
Normal file
1
src/mami.js/sleep.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
const MamiSleep = durationMs => new Promise(resolve => { setTimeout(resolve, durationMs); });
|
82
src/mami.js/ui/baka.jsx
Normal file
82
src/mami.js/ui/baka.jsx
Normal file
|
@ -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 = <div class="baka">
|
||||||
|
<div class="baka-container">
|
||||||
|
<div class="baka-duration">
|
||||||
|
<div class="baka-duration-inner">{message}</div>
|
||||||
|
</div>
|
||||||
|
{marqueeElem = <div class="baka-marquee"></div>}
|
||||||
|
</div>
|
||||||
|
<div class="baka-bottom"/>
|
||||||
|
</div>;
|
||||||
|
|
||||||
|
const marqueeString = banInfo.type === 'kick' ? 'Kicked' : 'Banned';
|
||||||
|
for(let i = 0; i < 10; ++i)
|
||||||
|
marqueeElem.append(<div class="baka-marquee-text">{marqueeString}</div>);
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
|
@ -1,12 +1,14 @@
|
||||||
#include animate.js
|
#include animate.js
|
||||||
#include common.js
|
#include common.js
|
||||||
#include emotes.js
|
#include emotes.js
|
||||||
|
#include sleep.js
|
||||||
#include utility.js
|
#include utility.js
|
||||||
#include youare.jsx
|
|
||||||
#include settings/backup.js
|
#include settings/backup.js
|
||||||
|
#include ui/baka.jsx
|
||||||
#include ui/emotes.js
|
#include ui/emotes.js
|
||||||
#include ui/menus.js
|
#include ui/menus.js
|
||||||
#include ui/view.js
|
#include ui/view.js
|
||||||
|
#include ui/youare.jsx
|
||||||
|
|
||||||
Umi.UI.Settings = (function() {
|
Umi.UI.Settings = (function() {
|
||||||
const items = [
|
const items = [
|
||||||
|
@ -384,6 +386,20 @@ Umi.UI.Settings = (function() {
|
||||||
title: 'Disable Old Theme System',
|
title: 'Disable Old Theme System',
|
||||||
type: 'checkbox',
|
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!',
|
title: 'You are an idiot!',
|
||||||
type: 'button',
|
type: 'button',
|
||||||
|
|
Loading…
Reference in a new issue