2021-12-05 18:33:49 -05:00
|
|
|
import { Server } from "./Server.js";
|
|
|
|
import { MatrixUser } from "./MatrixUser.js";
|
|
|
|
import { IRCUser } from "./IRCUser.js";
|
|
|
|
import { IRCMessage } from "./Message.js";
|
2021-12-06 10:23:29 -05:00
|
|
|
import { Client } from "./Client.js";
|
|
|
|
import numerics from "./numerics.js";
|
2021-12-05 18:33:49 -05:00
|
|
|
|
|
|
|
export class Channel {
|
|
|
|
public name: string
|
|
|
|
private matrixUsers: Map<string, MatrixUser>
|
|
|
|
private ircUsers: Map<string, IRCUser>
|
|
|
|
private nickToMXid: Map<string, string>
|
|
|
|
private powerLevels: Map<string, number>
|
|
|
|
private topic: Map<string, string>;
|
|
|
|
private modes: Map<string, string>
|
|
|
|
private messages: Map<string, IRCMessage>;
|
|
|
|
private tsToEventId: Map<number, string>;
|
2021-12-06 10:23:29 -05:00
|
|
|
constructor(public roomId: string, private server: Server) {
|
2021-12-05 18:33:49 -05:00
|
|
|
this.name = roomId;
|
|
|
|
this.matrixUsers = new Map();
|
|
|
|
this.ircUsers = new Map();
|
|
|
|
this.nickToMXid = new Map();
|
|
|
|
this.powerLevels = new Map();
|
2021-12-06 10:23:29 -05:00
|
|
|
this.topic = new Map([['text', ''], ['timestamp', '0'], ['setter', 'matrix']]);
|
2021-12-05 18:33:49 -05:00
|
|
|
this.modes = new Map();
|
|
|
|
this.modes.set('n', '');
|
|
|
|
this.messages = new Map();
|
|
|
|
this.tsToEventId = new Map();
|
|
|
|
}
|
2021-12-05 20:22:28 -05:00
|
|
|
|
2021-12-06 10:23:29 -05:00
|
|
|
getNickPowerLevelMapping(nick: string): string {
|
|
|
|
let opStatus = '';
|
|
|
|
const pl = this.powerLevels.get(nick) || 0;
|
|
|
|
if (pl > 99) {
|
|
|
|
opStatus = '@';
|
|
|
|
}
|
|
|
|
else if (pl > 49) {
|
|
|
|
opStatus = '%';
|
|
|
|
}
|
|
|
|
else if (pl > 0) {
|
|
|
|
opStatus = '+';
|
|
|
|
}
|
|
|
|
return opStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
joinNewIRCClient(client: Client, passedTags: Map<string, string>) {
|
|
|
|
console.log('joining channel')
|
|
|
|
if (!client.user)
|
2021-12-05 20:22:28 -05:00
|
|
|
return;
|
2021-12-06 10:23:29 -05:00
|
|
|
if (client.enabledCaps.has('extended-join')) {
|
|
|
|
client.sendMessage(client.user.getMask(), "JOIN", [this.name, client.user.accountName, client.user.mxid], new Map([['account', client.user.realname]]));
|
|
|
|
} else {
|
|
|
|
client.sendMessage(client.user.getMask(), "JOIN", [this.name], new Map([['account', client.user.realname]]));
|
2021-12-05 20:22:28 -05:00
|
|
|
}
|
2021-12-06 10:23:29 -05:00
|
|
|
this.sendNames(client, passedTags);
|
|
|
|
this.sendTopic(client, passedTags);
|
|
|
|
}
|
|
|
|
|
|
|
|
sendNames(client: Client, passedTags: Map<string, string>) {
|
|
|
|
if (!client.user)
|
|
|
|
return;
|
|
|
|
let namesList: string[] = [];
|
|
|
|
for (const matrixUser of this.matrixUsers.values()) {
|
|
|
|
const opStatus = this.getNickPowerLevelMapping(matrixUser.nick);
|
|
|
|
namesList.push(`${opStatus}${matrixUser.nick}`);
|
2021-12-05 20:22:28 -05:00
|
|
|
}
|
2021-12-06 10:23:29 -05:00
|
|
|
let singleNamesList: string[] = []
|
|
|
|
namesList.forEach((singleName, index) => {
|
|
|
|
if (index === 0 || index % 20 !== 0) {
|
|
|
|
singleNamesList.push(singleName);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!client.user)
|
|
|
|
return;
|
|
|
|
client.sendMessage(client.server.name, "353", numerics["353"](client.user.nick, "=", this.name, singleNamesList), passedTags);
|
|
|
|
singleNamesList = [];
|
2021-12-05 20:22:28 -05:00
|
|
|
}
|
2021-12-06 10:23:29 -05:00
|
|
|
})
|
|
|
|
if (singleNamesList.length !== 0) {
|
|
|
|
client.sendMessage(client.server.name, "353", numerics["353"](client.user.nick, "=", this.name, singleNamesList), passedTags);
|
|
|
|
}
|
|
|
|
client.sendMessage(client.server.name, "366", numerics["366"](client.user.nick, this.name), passedTags);
|
|
|
|
}
|
|
|
|
|
|
|
|
sendMode(client: Client, passedTags: Map<string, string>) {
|
|
|
|
if (!client.user)
|
|
|
|
return;
|
|
|
|
const chanModes = [];
|
|
|
|
for (let m of this.modes.keys()) {
|
|
|
|
chanModes.push(m);
|
2021-12-05 20:22:28 -05:00
|
|
|
}
|
2021-12-06 10:23:29 -05:00
|
|
|
client.sendMessage(client.server.name, "324", numerics["324"](client.user.nick, this.name, `+${chanModes.join("")}`), passedTags);
|
|
|
|
}
|
|
|
|
|
|
|
|
sendTopic(client: Client, passedTags: Map<string, string>) {
|
|
|
|
if (!client.user)
|
|
|
|
return;
|
|
|
|
const topicText = this.topic.get('text') || '';
|
|
|
|
const topicSetter = this.topic.get('setter') || 'matrix';
|
|
|
|
const topicTimestamp = this.topic.get('timestamp') || '0';
|
|
|
|
if (topicText === '') {
|
|
|
|
client.sendMessage(client.server.name, '331', [client.user.nick, this.name, 'No topic is set'], passedTags);
|
|
|
|
return;
|
2021-12-05 20:22:28 -05:00
|
|
|
}
|
2021-12-06 10:23:29 -05:00
|
|
|
client.sendMessage(client.server.name, '332', [client.user.nick, this.name, topicText], passedTags);
|
|
|
|
client.sendMessage(client.server.name, '333', [client.user.nick, this.name, topicSetter, topicTimestamp], passedTags);
|
|
|
|
}
|
|
|
|
|
|
|
|
sendWho(client: Client, passedTags: Map<string, string>) {
|
|
|
|
if (!client.user)
|
|
|
|
return;
|
|
|
|
for (const matrixUser of this.matrixUsers.values()) {
|
|
|
|
const opStatus = this.getNickPowerLevelMapping(matrixUser.nick);
|
|
|
|
const userParams = [
|
|
|
|
client.user.nick,
|
|
|
|
this.name,
|
|
|
|
matrixUser.ident,
|
|
|
|
matrixUser.hostname,
|
|
|
|
client.server.name,
|
|
|
|
matrixUser.nick,
|
|
|
|
`H${opStatus}`,
|
|
|
|
`0 ${matrixUser.realname}`
|
|
|
|
]
|
|
|
|
client.sendMessage(client.server.name, '352', userParams, passedTags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
routeMatrixEvent(event: any) {
|
|
|
|
if (!event["type"])
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (event["type"]) {
|
|
|
|
case 'm.room.member':
|
|
|
|
this.handleMatrixMember(event);
|
|
|
|
break;
|
|
|
|
case 'm.room.power_levels':
|
|
|
|
this.handleMatrixPL(event);
|
|
|
|
break;
|
|
|
|
case 'm.room.topic':
|
|
|
|
this.handleMatrixTopic(event);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.log(event["type"]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handleMatrixMember(event: any) {
|
|
|
|
const thisMatrixUser = this.server.getOrCreateMatrixUser(event["sender"]);
|
|
|
|
this.matrixUsers.set(thisMatrixUser.nick, thisMatrixUser);
|
|
|
|
this.nickToMXid.set(thisMatrixUser.nick, thisMatrixUser.mxid);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleMatrixPL(event: any) {
|
|
|
|
const allUsers = event["content"]["users"];
|
|
|
|
for (const [mxid, pl] of Object.entries(allUsers)) {
|
|
|
|
const thisMatrixUser = this.server.getOrCreateMatrixUser(event["sender"]);
|
|
|
|
this.matrixUsers.set(thisMatrixUser.nick, thisMatrixUser);
|
|
|
|
this.powerLevels.set(thisMatrixUser.nick, Number(pl));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handleMatrixTopic(event: any) {
|
|
|
|
this.topic.set("text", event["content"]["topic"]);
|
|
|
|
this.topic.set("timestamp", event["origin_server_ts"].toString())
|
2021-12-05 20:22:28 -05:00
|
|
|
}
|
2021-12-05 18:33:49 -05:00
|
|
|
}
|