diff --git a/d2m/actions/create-room.js b/d2m/actions/create-room.js index c8f0661..3be2429 100644 --- a/d2m/actions/create-room.js +++ b/d2m/actions/create-room.js @@ -2,7 +2,6 @@ const assert = require("assert").strict const DiscordTypes = require("discord-api-types/v10") -const reg = require("../../matrix/read-registration") const passthrough = require("../../passthrough") const { discord, sync, db } = passthrough @@ -62,16 +61,11 @@ async function channelToKState(channel, guild) { const spaceID = db.prepare("SELECT space_id FROM guild_space WHERE guild_id = ?").pluck().get(guild.id) assert.ok(typeof spaceID === "string") - const row = db.prepare("SELECT nick, custom_avatar FROM channel_room WHERE channel_id = ?").get(channel.id) - assert(row) - const customName = row.nick - const customAvatar = row.custom_avatar + const customName = db.prepare("SELECT nick FROM channel_room WHERE channel_id = ?").pluck().get(channel.id) const [convertedName, convertedTopic] = convertNameAndTopic(channel, guild, customName) const avatarEventContent = {} - if (customAvatar) { - avatarEventContent.url = customAvatar - } else if (guild.icon) { + if (guild.icon) { avatarEventContent.discord_path = file.guildIcon(guild) avatarEventContent.url = await file.uploadDiscordFileToMxc(avatarEventContent.discord_path) // TODO: somehow represent future values in kstate (callbacks?), while still allowing for diffing, so test cases don't need to touch the media API } @@ -86,7 +80,7 @@ async function channelToKState(channel, guild) { "m.room.guest_access/": {guest_access: "can_join"}, "m.room.history_visibility/": {history_visibility}, [`m.space.parent/${spaceID}`]: { - via: [reg.ooye.server_name], + via: ["cadence.moe"], // TODO: put the proper server here canonical: true }, "m.room.join_rules/": { @@ -189,8 +183,6 @@ async function _syncRoom(channelID, shouldActuallySync) { return creation // Naturally, the newly created room is already up to date, so we can always skip syncing here. } - const roomID = existing.room_id - if (!shouldActuallySync) { return existing.room_id // only need to ensure room exists, and it does. return the room ID } @@ -200,16 +192,15 @@ async function _syncRoom(channelID, shouldActuallySync) { const {spaceID, channelKState} = await channelToKState(channel, guild) // sync channel state to room - const roomKState = await roomToKState(roomID) + const roomKState = await roomToKState(existing.room_id) const roomDiff = ks.diffKState(roomKState, channelKState) - const roomApply = applyKStateDiffToRoom(roomID, roomDiff) - db.prepare("UPDATE channel_room SET name = ? WHERE room_id = ?").run(channel.name, roomID) + const roomApply = applyKStateDiffToRoom(existing.room_id, roomDiff) // sync room as space member - const spaceApply = _syncSpaceMember(channel, spaceID, roomID) + const spaceApply = _syncSpaceMember(channel, spaceID, existing.room_id) await Promise.all([roomApply, spaceApply]) - return roomID + return existing.room_id } async function _unbridgeRoom(channelID) { @@ -253,7 +244,7 @@ async function _syncSpaceMember(channel, spaceID, roomID) { && !channel["thread_metadata"]?.archived // archived threads do not belong in the space (don't offer people conversations that are no longer relevant) ) { spaceEventContent = { - via: [reg.ooye.server_name] + via: ["cadence.moe"] // TODO: use the proper server } } const spaceDiff = ks.diffKState(spaceKState, { @@ -288,7 +279,5 @@ module.exports.ensureRoom = ensureRoom module.exports.syncRoom = syncRoom module.exports.createAllForGuild = createAllForGuild module.exports.channelToKState = channelToKState -module.exports.roomToKState = roomToKState -module.exports.applyKStateDiffToRoom = applyKStateDiffToRoom module.exports._convertNameAndTopic = convertNameAndTopic module.exports._unbridgeRoom = _unbridgeRoom diff --git a/d2m/actions/create-space.js b/d2m/actions/create-space.js index 34aa25f..1f00312 100644 --- a/d2m/actions/create-space.js +++ b/d2m/actions/create-space.js @@ -4,15 +4,13 @@ const assert = require("assert") const DiscordTypes = require("discord-api-types/v10") const passthrough = require("../../passthrough") -const { discord, sync, db } = passthrough +const { sync, db } = passthrough /** @type {import("../../matrix/api")} */ const api = sync.require("../../matrix/api") /** @type {import("../../matrix/file")} */ const file = sync.require("../../matrix/file") /** @type {import("./create-room")} */ const createRoom = sync.require("./create-room") -/** @type {import("../../matrix/kstate")} */ -const ks = sync.require("../../matrix/kstate") /** * @param {import("discord-api-types/v10").RESTGetAPIGuildResult} guild @@ -60,7 +58,7 @@ async function guildToKState(guild) { "m.room.name/": {name: guild.name}, "m.room.avatar/": avatarEventContent, "m.room.guest_access/": {guest_access: "can_join"}, // guests can join space if other conditions are met - "m.room.history_visibility/": {history_visibility: "invited"} // any events sent after user was invited are visible + "m.room.history_visibility": {history_visibility: "invited"} // any events sent after user was invited are visible } return guildKState @@ -71,26 +69,17 @@ async function syncSpace(guildID) { const guild = discord.guilds.get(guildID) assert.ok(guild) - /** @type {string?} */ - const spaceID = db.prepare("SELECT space_id from guild_space WHERE guild_id = ?").pluck().get(guildID) + /** @type {{room_id: string, thread_parent: string?}} */ + const existing = db.prepare("SELECT space_id from guild_space WHERE guild_id = ?").get(guildID) const guildKState = await guildToKState(guild) - if (!spaceID) { + if (!existing) { const spaceID = await createSpace(guild, guildKState) - return spaceID // Naturally, the newly created space is already up to date, so we can always skip syncing here. + return spaceID } - console.log(`[space sync] to matrix: ${guild.name}`) - // sync channel state to room - const spaceKState = await createRoom.roomToKState(spaceID) - const spaceDiff = ks.diffKState(spaceKState, guildKState) - await createRoom.applyKStateDiffToRoom(spaceID, spaceDiff) - return spaceID -} module.exports.createSpace = createSpace -module.exports.syncSpace = syncSpace -module.exports.guildToKState = guildToKState diff --git a/d2m/actions/register-user.js b/d2m/actions/register-user.js index 00a985c..a33cecc 100644 --- a/d2m/actions/register-user.js +++ b/d2m/actions/register-user.js @@ -21,7 +21,7 @@ async function createSim(user) { // Choose sim name const simName = userToMxid.userToSimName(user) const localpart = reg.ooye.namespace_prefix + simName - const mxid = `@${localpart}:${reg.ooye.server_name}` + const mxid = "@" + localpart + ":cadence.moe" // Save chosen name in the database forever // Making this database change right away so that in a concurrent registration, the 2nd registration will already have generated a different localpart because it can see this row when it generates diff --git a/d2m/discord-packets.js b/d2m/discord-packets.js index 6ece8ca..a1a4505 100644 --- a/d2m/discord-packets.js +++ b/d2m/discord-packets.js @@ -82,10 +82,7 @@ const utils = { // Event dispatcher for OOYE bridge operations try { - if (message.t === "GUILD_UPDATE") { - await eventDispatcher.onGuildUpdate(client, message.d) - - } else if (message.t === "CHANNEL_UPDATE") { + if (message.t === "CHANNEL_UPDATE") { await eventDispatcher.onChannelOrThreadUpdate(client, message.d, false) } else if (message.t === "THREAD_CREATE") { diff --git a/d2m/event-dispatcher.js b/d2m/event-dispatcher.js index 9bb07c0..c871ff1 100644 --- a/d2m/event-dispatcher.js +++ b/d2m/event-dispatcher.js @@ -14,8 +14,6 @@ const addReaction = sync.require("./actions/add-reaction") const announceThread = sync.require("./actions/announce-thread") /** @type {import("./actions/create-room")}) */ const createRoom = sync.require("./actions/create-room") -/** @type {import("./actions/create-space")}) */ -const createSpace = sync.require("./actions/create-space") /** @type {import("../matrix/api")}) */ const api = sync.require("../matrix/api") @@ -118,16 +116,6 @@ module.exports = { await announceThread.announceThread(parentRoomID, threadRoomID, thread) }, - /** - * @param {import("./discord-client")} client - * @param {import("discord-api-types/v10").GatewayGuildUpdateDispatchData} guild - */ - async onGuildUpdate(client, guild) { - const spaceID = db.prepare("SELECT space_id FROM guild_space WHERE guild_id = ?").pluck().get(guild.id) - if (!spaceID) return - await createSpace.syncSpace(guild.id) - }, - /** * @param {import("./discord-client")} client * @param {import("discord-api-types/v10").GatewayChannelUpdateDispatchData} channelOrThread diff --git a/m2d/converters/utils.js b/m2d/converters/utils.js index 7b9c504..108da1f 100644 --- a/m2d/converters/utils.js +++ b/m2d/converters/utils.js @@ -11,7 +11,6 @@ function eventSenderIsFromDiscord(sender) { // If it's from a user in the bridge's namespace, then it originated from discord // This includes messages sent by the appservice's bot user, because that is what's used for webhooks // TODO: It would be nice if bridge system messages wouldn't trigger this check and could be bridged from matrix to discord, while webhook reflections would remain ignored... - // TODO that only applies to the above todo: But you'd have to watch out for the /icon command, where the bridge bot would set the room avatar, and that shouldn't be reflected into the room a second time. if (userRegex.some(x => sender.match(x))) { return true } diff --git a/m2d/event-dispatcher.js b/m2d/event-dispatcher.js index c62d805..44eba85 100644 --- a/m2d/event-dispatcher.js +++ b/m2d/event-dispatcher.js @@ -6,7 +6,7 @@ const util = require("util") const Ty = require("../types") -const {db, sync, as} = require("../passthrough") +const {sync, as} = require("../passthrough") /** @type {import("./actions/send-event")} */ const sendEvent = sync.require("./actions/send-event") @@ -69,14 +69,3 @@ async event => { if (utils.eventSenderIsFromDiscord(event.sender)) return await addReaction.addReaction(event) })) - -sync.addTemporaryListener(as, "type:m.room.avatar", guard("m.room.avatar", -/** - * @param {Ty.Event.StateOuter} event - */ -async event => { - if (event.state_key !== "") return - if (utils.eventSenderIsFromDiscord(event.sender)) return - const url = event.content.url || null - db.prepare("UPDATE channel_room SET custom_avatar = ? WHERE room_id = ?").run(url, event.room_id) -})) diff --git a/matrix/api.js b/matrix/api.js index 9eff6c7..b382631 100644 --- a/matrix/api.js +++ b/matrix/api.js @@ -167,8 +167,6 @@ async function profileSetAvatarUrl(mxid, avatar_url) { * @param {number} power */ async function setUserPower(roomID, mxid, power) { - assert(roomID[0] === "!") - assert(mxid[0] === "@") // Yes it's this hard https://github.com/matrix-org/matrix-appservice-bridge/blob/2334b0bae28a285a767fe7244dad59f5a5963037/src/components/intent.ts#L352 const powerLevels = await getStateEvent(roomID, "m.room.power_levels", "") const users = powerLevels.users || {} diff --git a/matrix/kstate.js b/matrix/kstate.js index 1b2ca14..398b1b6 100644 --- a/matrix/kstate.js +++ b/matrix/kstate.js @@ -42,7 +42,6 @@ function diffKState(actual, target) { const diff = {} // go through each key that it should have for (const key of Object.keys(target)) { - if (!key.includes("/")) throw new Error(`target kstate's key "${key}" does not contain a slash separator; if a blank state_key was intended, add a trailing slash to the kstate key.`) if (key in actual) { // diff try { diff --git a/types.d.ts b/types.d.ts index 2ba8d1d..b9f7ed6 100644 --- a/types.d.ts +++ b/types.d.ts @@ -19,7 +19,6 @@ export type AppServiceRegistrationConfig = { ooye: { namespace_prefix: string max_file_size: number - server_name: string } } @@ -28,7 +27,7 @@ export type WebhookCreds = { token: string } -export namespace Event { +namespace Event { export type Outer = { type: string room_id: string @@ -39,10 +38,6 @@ export namespace Event { event_id: string } - export type StateOuter = Outer & { - state_key: string - } - export type ReplacementContent = T & { "m.new_content": T "m.relates_to": { @@ -79,11 +74,6 @@ export namespace Event { avatar_url?: string } - export type M_Room_Avatar = { - discord_path?: string - url?: string - } - export type M_Reaction = { "m.relates_to": { rel_type: "m.annotation" @@ -93,7 +83,7 @@ export namespace Event { } } -export namespace R { +namespace R { export type RoomCreated = { room_id: string }