diff --git a/db/data-for-test.sql b/db/data-for-test.sql index 4a406c9..ec9f9ec 100644 --- a/db/data-for-test.sql +++ b/db/data-for-test.sql @@ -34,6 +34,7 @@ CREATE TABLE IF NOT EXISTS "channel_room" ( "name" TEXT, "nick" TEXT, "thread_parent" TEXT, + "custom_avatar" TEXT, PRIMARY KEY("channel_id") ); CREATE TABLE IF NOT EXISTS "event_message" ( @@ -55,11 +56,11 @@ BEGIN TRANSACTION; INSERT INTO guild_space (guild_id, space_id) VALUES ('112760669178241024', '!jjWAGMeQdNrVZSSfvz:cadence.moe'); -INSERT INTO channel_room (channel_id, room_id, name, nick, thread_parent) VALUES -('112760669178241024', '!kLRqKKUQXcibIMtOpl:cadence.moe', 'heave', 'main', NULL), -('497161350934560778', '!edUxjVdzgUvXDUIQCK:cadence.moe', 'amanda-spam', NULL, NULL), -('160197704226439168', '!uCtjHhfGlYbVnPVlkG:cadence.moe', 'the-stanley-parable-channel', 'bots', NULL), -('1100319550446252084', '!PnyBKvUBOhjuCucEfk:cadence.moe', 'worm-farm', NULL, NULL); +INSERT INTO channel_room (channel_id, room_id, name, nick, thread_parent, custom_avatar) VALUES +('112760669178241024', '!kLRqKKUQXcibIMtOpl:cadence.moe', 'heave', 'main', NULL, NULL), +('497161350934560778', '!edUxjVdzgUvXDUIQCK:cadence.moe', 'amanda-spam', NULL, NULL, NULL), +('160197704226439168', '!uCtjHhfGlYbVnPVlkG:cadence.moe', 'the-stanley-parable-channel', 'bots', NULL, NULL), +('1100319550446252084', '!PnyBKvUBOhjuCucEfk:cadence.moe', 'worm-farm', NULL, NULL, NULL); INSERT INTO sim (discord_id, sim_name, localpart, mxid) VALUES ('0', 'bot', '_ooye_bot', '@_ooye_bot:cadence.moe'), diff --git a/matrix/api.js b/matrix/api.js index 9eff6c7..2e0763e 100644 --- a/matrix/api.js +++ b/matrix/api.js @@ -169,7 +169,7 @@ async function profileSetAvatarUrl(mxid, avatar_url) { 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 + // Yes there's no shortcut 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 || {} if (power != null) { diff --git a/matrix/kstate.js b/matrix/kstate.js index 1b2ca14..469ec91 100644 --- a/matrix/kstate.js +++ b/matrix/kstate.js @@ -1,6 +1,7 @@ // @ts-check -const assert = require("assert") +const assert = require("assert").strict +const mixin = require("mixin-deep") /** Mutates the input. */ function kstateStripConditionals(kstate) { @@ -43,18 +44,34 @@ function diffKState(actual, target) { // 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) { + + if (key === "m.room.power_levels/") { + // Special handling for power levels, we want to deep merge the actual and target into the final state. + console.log(actual[key]) + const temp = mixin({}, actual[key], target[key]) + console.log(actual[key]) + console.log(temp) + try { + assert.deepEqual(actual[key], temp) + } catch (e) { + // they differ. use the newly prepared object as the diff. + diff[key] = temp + } + + } else if (key in actual) { // diff try { assert.deepEqual(actual[key], target[key]) } catch (e) { - // they differ. reassign the target + // they differ. use the target as the diff. diff[key] = target[key] } + } else { // not present, needs to be added diff[key] = target[key] } + // keys that are missing in "actual" will not be deleted on "target" (no action) } return diff diff --git a/matrix/kstate.test.js b/matrix/kstate.test.js index 1541898..11d5131 100644 --- a/matrix/kstate.test.js +++ b/matrix/kstate.test.js @@ -92,3 +92,57 @@ test("diffKState: detects new properties", t => { } ) }) + +test("diffKState: power levels are mixed together", t => { + const original = { + "m.room.power_levels/": { + "ban": 50, + "events": { + "m.room.name": 100, + "m.room.power_levels": 100 + }, + "events_default": 0, + "invite": 50, + "kick": 50, + "notifications": { + "room": 20 + }, + "redact": 50, + "state_default": 50, + "users": { + "@example:localhost": 100 + }, + "users_default": 0 + } + } + const result = diffKState(original, { + "m.room.power_levels/": { + "events": { + "m.room.avatar": 0 + } + } + }) + t.deepEqual(result, { + "m.room.power_levels/": { + "ban": 50, + "events": { + "m.room.name": 100, + "m.room.power_levels": 100, + "m.room.avatar": 0 + }, + "events_default": 0, + "invite": 50, + "kick": 50, + "notifications": { + "room": 20 + }, + "redact": 50, + "state_default": 50, + "users": { + "@example:localhost": 100 + }, + "users_default": 0 + } + }) + t.notDeepEqual(original, result) +}) diff --git a/package-lock.json b/package-lock.json index 875e329..e808e1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "js-yaml": "^4.1.0", "matrix-appservice": "^2.0.0", "matrix-js-sdk": "^24.1.0", - "mixin-deep": "^2.0.1", + "mixin-deep": "github:cloudrac3r/mixin-deep#v3.0.0", "node-fetch": "^2.6.7", "prettier-bytes": "^1.0.4", "snowtransfer": "^0.8.0", @@ -2111,9 +2111,9 @@ } }, "node_modules/mixin-deep": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-2.0.1.tgz", - "integrity": "sha512-imbHQNRglyaplMmjBLL3V5R6Bfq5oM+ivds3SKgc6oRtzErEnBUUc5No11Z2pilkUvl42gJvi285xTNswcKCMA==", + "version": "3.0.0", + "resolved": "git+ssh://git@github.com/cloudrac3r/mixin-deep.git#2dd70d6b8644263f7ed2c1620506c9eb3f11d32a", + "license": "MIT", "engines": { "node": ">=6" } diff --git a/package.json b/package.json index bc0a0db..67aeade 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "js-yaml": "^4.1.0", "matrix-appservice": "^2.0.0", "matrix-js-sdk": "^24.1.0", - "mixin-deep": "^2.0.1", + "mixin-deep": "github:cloudrac3r/mixin-deep#v3.0.0", "node-fetch": "^2.6.7", "prettier-bytes": "^1.0.4", "snowtransfer": "^0.8.0", diff --git a/stdin.js b/stdin.js index 61a2a08..ce612f5 100644 --- a/stdin.js +++ b/stdin.js @@ -14,6 +14,7 @@ const mreq = sync.require("./matrix/mreq") const api = sync.require("./matrix/api") const sendEvent = sync.require("./m2d/actions/send-event") const eventDispatcher = sync.require("./d2m/event-dispatcher") +const ks = sync.require("./matrix/kstate") const guildID = "112760669178241024" const extraContext = {}