mami/src/proto.js/sockchat/authed.js
flash cf71bab92d Rewrote connection handling.
This has been in the works for over a month and might break things because it's a very radical change.
If it causes you to be unable to join chat, report it on the forum or try joining using the legacy chat on https://sockchat.flashii.net.
2024-04-17 15:42:50 +00:00

323 lines
8.9 KiB
JavaScript

#include sockchat/utils.js
const SockChatS2CPong = ctx => {
const lastPong = Date.now();
const lastPing = ctx.lastPing;
ctx.lastPing = undefined;
if(lastPing === undefined)
throw 'unexpected pong received??';
ctx.pingPromise?.resolve({
ping: lastPing,
pong: lastPong,
diff: lastPong - lastPing,
});
};
const SockChatS2CBanKick = (ctx, type, expiresTime) => {
ctx.wasKicked = true;
const bakaInfo = {
session: { success: false },
baka: {
type: type === '0' ? 'kick' : 'ban',
},
};
if(bakaInfo.baka.type === 'ban') {
bakaInfo.baka.perma = expiresTime === '-1';
bakaInfo.baka.until = expiresTime === '-1' ? undefined : new Date(parseInt(expiresTime) * 1000);
}
ctx.dispatch('session:term', bakaInfo);
};
const SockChatS2CContextClear = (ctx, mode) => {
if(mode === '0' || mode === '3' || mode === '4')
ctx.dispatch('msg:clear');
if(mode === '1' || mode === '3' || mode === '4')
ctx.dispatch('user:clear');
if(mode === '2' || mode === '4')
ctx.dispatch('chan:clear');
};
const SockChatS2CChannelPopulate = (ctx, count, ...args) => {
count = parseInt(count);
ctx.dispatch('chan:clear');
for(let i = 0; i < count; ++i) {
const offset = 3 * i;
ctx.dispatch('chan:add', {
channel: {
name: args[offset],
hasPassword: args[offset + 1] !== '0',
isTemporary: args[offset + 2] !== '0',
isCurrent: args[offset] === ctx.channelName,
},
});
}
ctx.dispatch('chan:focus', {
channel: { name: ctx.channelName },
});
};
const SockChatS2CChannelAdd = (ctx, name, hasPass, isTemp) => {
ctx.dispatch('chan:add', {
channel: {
name: name,
hasPassword: hasPass !== '0',
isTemporary: isTemp !== '0',
},
});
};
const SockChatS2CChannelUpdate = (ctx, prevName, name, hasPass, isTemp) => {
ctx.dispatch('chan:update', {
channel: {
previousName: prevName,
name: name,
hasPassword: hasPass !== '0',
isTemporary: isTemp !== '0',
},
});
};
const SockChatS2CChannelRemove = (ctx, name) => {
ctx.dispatch('chan:remove', {
channel: { name: name },
});
};
const SockChatS2CUserPopulate = (ctx, count, ...args) => {
count = parseInt(count);
ctx.dispatch('user:clear');
for(let i = 0; i < count; ++i) {
const offset = 5 * i;
const statusInfo = SockChatParseStatusInfo(args[offset + 1]);
ctx.dispatch('user:add', {
user: {
id: args[offset],
self: args[offset] === ctx.userId,
name: statusInfo.name,
status: statusInfo.status,
colour: SockChatParseUserColour(args[offset + 2]),
perms: SockChatParseUserPerms(args[offset + 3]),
hidden: args[offset + 4] !== '0',
},
});
}
};
const SockChatS2CUserAdd = (ctx, timeStamp, userId, userName, userColour, userPerms, msgId) => {
const statusInfo = SockChatParseStatusInfo(userName);
ctx.dispatch('user:add', {
msg: {
id: msgId,
time: new Date(parseInt(timeStamp) * 1000),
channel: ctx.channelName,
botInfo: {
type: 'join',
args: [statusInfo.name],
},
},
user: {
id: userId,
self: userId === ctx.userId,
name: statusInfo.name,
status: statusInfo.status,
colour: SockChatParseUserColour(userColour),
perms: SockChatParseUserPerms(userPerms),
},
});
};
const SockChatS2CUserUpdate = (ctx, userId, userName, userColour, userPerms) => {
const statusInfo = SockChatParseStatusInfo(userName);
ctx.dispatch('user:update', {
user: {
id: userId,
self: userId === ctx.userId,
name: statusInfo.name,
status: statusInfo.status,
colour: SockChatParseUserColour(userColour),
perms: SockChatParseUserPerms(userPerms),
},
});
};
const SockChatS2CUserRemove = (ctx, userId, userName, reason, timeStamp, msgId) => {
const statusInfo = SockChatParseStatusInfo(userName);
ctx.dispatch('user:remove', {
leave: { type: reason },
msg: {
id: msgId,
time: new Date(parseInt(timeStamp) * 1000),
channel: ctx.channelName,
botInfo: {
type: reason,
args: [statusInfo.name],
},
},
user: {
id: userId,
self: userId === ctx.userId,
name: statusInfo.name,
status: statusInfo.status,
},
});
};
const SockChatS2CUserChannelJoin = (ctx, userId, userName, userColour, userPerms, msgId) => {
const statusInfo = SockChatParseStatusInfo(userName);
ctx.dispatch('chan:join', {
user: {
id: userId,
self: userId === ctx.userId,
name: statusInfo.name,
status: statusInfo.status,
colour: SockChatParseUserColour(userColour),
perms: SockChatParseUserPerms(userPerms),
},
msg: {
id: msgId,
channel: ctx.channelName,
botInfo: {
type: 'jchan',
args: [statusInfo.name],
},
},
});
};
const SockChatS2CUserChannelLeave = (ctx, userId, msgId) => {
ctx.dispatch('chan:leave', {
user: {
id: userId,
self: userId === ctx.userId,
},
msg: {
id: msgId,
channel: ctx.channelName,
botInfo: {
type: 'lchan',
args: [userId],
},
},
});
};
const SockChatS2CUserChannelFocus = (ctx, name) => {
ctx.channelName = name;
ctx.dispatch('chan:focus', {
channel: { name: ctx.channelName },
});
};
const SockChatS2CMessagePopulate = (ctx, timeStamp, userId, userName, userColour, userPerms, msgText, msgId, msgNotify, msgFlags) => {
const mFlags = SockChatParseMsgFlags(msgFlags);
const statusInfo = SockChatParseStatusInfo(userName);
const info = {
msg: {
id: msgId,
time: new Date(parseInt(timeStamp) * 1000),
channel: ctx.channelName,
sender: {
id: userId,
self: userId === ctx.userId,
name: statusInfo.name,
status: statusInfo.status,
colour: SockChatParseUserColour(userColour),
perms: SockChatParseUserColour(userPerms),
},
isBot: userId === '-1',
silent: msgNotify === '0',
flags: mFlags,
flagsRaw: msgFlags,
text: SockChatUnfuckText(msgText, mFlags.isAction),
},
};
const msgIdFirst = info.msg.id.charCodeAt(0);
if(msgIdFirst < 48 || msgIdFirst > 57)
info.msg.id = (Math.round(Number.MIN_SAFE_INTEGER * Math.random())).toString();
if(info.msg.isBot) {
const botParts = msgText.split("\f");
info.msg.botInfo = {
isError: botParts[0] === '1',
type: botParts[1],
args: botParts.slice(2),
};
// i think this is more Inaccurate Behaviour on the server side
if(info.msg.botInfo.type === 'say')
info.msg.botInfo.args[0] = SockChatUnfuckText(info.msg.botInfo.args[0]);
}
ctx.dispatch('msg:add', info);
};
const SockChatS2CMessageAdd = (ctx, timeStamp, userId, msgText, msgId, msgFlags) => {
const mFlags = SockChatParseMsgFlags(msgFlags);
let mText = SockChatUnfuckText(msgText, mFlags.isAction);
let mChannelName = ctx.channelName;
if(msgFlags[4] !== '0') {
if(userId === ctx.userId) {
const mTextParts = mText.split(' ');
mChannelName = `@${mTextParts.shift()}`;
mText = mTextParts.join(' ');
} else {
mChannelName = `@~${userId}`;
}
}
const msgInfo = {
msg: {
id: msgId,
time: new Date(parseInt(timeStamp) * 1000),
channel: mChannelName,
sender: {
id: userId,
self: userId === ctx.userId,
},
flags: mFlags,
flagsRaw: msgFlags,
isBot: userId === '-1',
text: mText,
},
};
if(msgInfo.msg.isBot) {
const botParts = msgText.split("\f");
msgInfo.msg.botInfo = {
isError: botParts[0] === '1',
type: botParts[1],
args: botParts.slice(2),
};
}
ctx.dispatch('msg:add', msgInfo);
};
const SockChatS2CMessageRemove = (ctx, msgId) => {
ctx.dispatch('msg:remove', {
msg: {
id: msgId,
channel: ctx.channelName,
},
});
};