From 98a096e18fb7ae915a948c5ce43c22dcc96978bf Mon Sep 17 00:00:00 2001 From: emerson Date: Sun, 5 Dec 2021 20:22:28 -0500 Subject: [PATCH] set up initial member, topic, and pl sync --- src/Channel.ts | 33 +++++++++++++++++++++++++++++---- src/IRCUser.ts | 28 +++++++++++++++++++++++----- src/Server.ts | 21 +++++++++++++++++++++ 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/Channel.ts b/src/Channel.ts index 28118e9..156de8b 100644 --- a/src/Channel.ts +++ b/src/Channel.ts @@ -4,28 +4,53 @@ import { IRCUser } from "./IRCUser.js"; import { IRCMessage } from "./Message.js"; export class Channel { + private server: Server public name: string private matrixUsers: Map private ircUsers: Map private nickToMXid: Map private powerLevels: Map private topic: Map; - private memberCount: number; private modes: Map private messages: Map; private tsToEventId: Map; - constructor(public roomId: string, private server: Server, initialIRCUser: IRCUser) { + constructor(public roomId: string, initialIRCUser: IRCUser) { + this.server = initialIRCUser.server this.name = roomId; this.matrixUsers = new Map(); this.ircUsers = new Map(); this.ircUsers.set(initialIRCUser.nick, initialIRCUser); this.nickToMXid = new Map(); this.powerLevels = new Map(); - this.topic = new Map(); - this.memberCount = 0; + this.topic = new Map([['text', ''], ['timestamp', '0']]); this.modes = new Map(); this.modes.set('n', ''); this.messages = new Map(); this.tsToEventId = new Map(); } + + handleMatrixEvent(event: any) { + if (!event["type"]) + return; + + if (event["type"] === "m.room.member") { + const thisMatrixUser = this.server.getOrCreateMatrixUser(event["sender"]); + this.matrixUsers.set(thisMatrixUser.nick, thisMatrixUser); + } + else if (event["type"] === "m.room.topic") { + this.topic.set("text", event["content"]["topic"]); + this.topic.set("timestamp", event["origin_server_ts"].toString()) + } + else if (event["type"] === "m.room.power_levels") { + 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)); + } + } + else { + console.log(event); + } + } } \ No newline at end of file diff --git a/src/IRCUser.ts b/src/IRCUser.ts index 8c999a8..4922446 100644 --- a/src/IRCUser.ts +++ b/src/IRCUser.ts @@ -1,25 +1,23 @@ +import axios from "axios"; import { Channel } from "./Channel.js"; import { Client } from "./Client.js"; -import { MatrixUser } from "./MatrixUser.js"; -import { IRCMessage } from "./Message.js"; import { Server } from "./Server.js"; export class IRCUser { private clients: Set private channels: Map - private server: Server - private matrixUser: MatrixUser|null + public server: Server public nick: string private ident: string private hostname: string public accountName: string public isAuthed: boolean private txnIdStore: Set + private nextBatch: string constructor(private initialClient: Client, public mxid: string, private accessToken: string) { this.clients = new Set([initialClient]); this.channels = new Map(); this.server = initialClient.server; - this.matrixUser = null; const mxidSplit = mxid.split(':') this.nick = mxidSplit[0].substr(1); this.ident = this.nick; @@ -27,6 +25,8 @@ export class IRCUser { this.accountName = mxid.slice(1); this.isAuthed = false; this.txnIdStore = new Set(); + this.nextBatch = ""; + this.doSync(); } verifyCredentials(accessToken: string): boolean { @@ -36,4 +36,22 @@ export class IRCUser { getMask(): string { return `${this.nick}!${this.ident}@${this.hostname}`; } + + doSync(): void { + let endpoint = `https://matrix.org/_matrix/client/v3/sync?access_token=${this.accessToken}`; + if (this.nextBatch !== "") + endpoint = `${endpoint}&since=${this.nextBatch}`; + + axios.get(endpoint).then(response => { + const data = response.data; + this.nextBatch = data.next_batch; + const rooms = data.rooms; + if (rooms['join']) { + for (const roomId of Object.keys(rooms.join)) { + const targetChannel = this.server.matrixRooms.get(roomId) || new Channel(roomId, this); + rooms.join[roomId].state.events.forEach((nextEvent: any) => targetChannel.handleMatrixEvent(nextEvent)); + } + } + }) + } } \ No newline at end of file diff --git a/src/Server.ts b/src/Server.ts index ec41ebe..a2b9278 100644 --- a/src/Server.ts +++ b/src/Server.ts @@ -21,4 +21,25 @@ export class Server { this.ircUsers = new Map(); this.nickToMxid = new Map(); } + + getOrCreateMatrixUser(mxid: string): MatrixUser { + let maybeMatrixUser = this.matrixUsers.get(mxid); + if (maybeMatrixUser) { + return maybeMatrixUser; + } + let potentialNick = mxid.split(":")[0].substr(1); + if (!this.nickToMxid.has(potentialNick)) { + const newMatrixUser = new MatrixUser(mxid, potentialNick); + this.matrixUsers.set(mxid, newMatrixUser); + this.nickToMxid.set(potentialNick, mxid); + return newMatrixUser; + } + const homeserverArray = mxid.split(":")[1].split('.'); + const baseDomainNum = homeserverArray.length - 2; + potentialNick = `${potentialNick}-${homeserverArray[baseDomainNum]}`; + const newMatrixUser = new MatrixUser(mxid, potentialNick); + this.matrixUsers.set(mxid, newMatrixUser); + this.nickToMxid.set(potentialNick, mxid); + return newMatrixUser; + } } \ No newline at end of file