PK: Fix mentions/replies using UUID
This commit is contained in:
		
							parent
							
								
									3d87bd9da5
								
							
						
					
					
						commit
						f48c1f3f31
					
				
					 9 changed files with 81 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -122,10 +122,14 @@ async function memberToStateContent(pkMessage, author) {
 | 
			
		|||
 * 4. If the state content has changed, send it to Matrix and update it in the database for next time
 | 
			
		||||
 * @param {WebhookAuthor} author
 | 
			
		||||
 * @param {Ty.PkMessage} pkMessage
 | 
			
		||||
 * @param {string} roomID
 | 
			
		||||
 * @returns {Promise<string>} mxid of the updated sim
 | 
			
		||||
 */
 | 
			
		||||
async function syncUser(author, pkMessage, roomID) {
 | 
			
		||||
	const mxid = await ensureSimJoined(pkMessage, roomID)
 | 
			
		||||
	// Update the sim_proxy table, so mentions can look up the original sender later
 | 
			
		||||
	db.prepare("INSERT OR IGNORE INTO sim_proxy (user_id, proxy_owner_id) VALUES (?, ?)").run(pkMessage.member.id, pkMessage.sender)
 | 
			
		||||
	// Sync the member state
 | 
			
		||||
	const content = await memberToStateContent(pkMessage, author)
 | 
			
		||||
	const currentHash = registerUser._hashProfileContent(content)
 | 
			
		||||
	const existingHash = select("sim_member", "hashed_profile_content", {room_id: roomID, mxid}).safeIntegers().pluck().get()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								db/migrations/0010-add-sim-proxy.sql
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								db/migrations/0010-add-sim-proxy.sql
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
CREATE TABLE IF NOT EXISTS sim_proxy (
 | 
			
		||||
	user_id TEXT NOT NULL,
 | 
			
		||||
	proxy_owner_id TEXT NOT NULL,
 | 
			
		||||
	PRIMARY KEY(user_id)
 | 
			
		||||
) WITHOUT ROWID;
 | 
			
		||||
							
								
								
									
										6
									
								
								db/orm-defs.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								db/orm-defs.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -63,6 +63,11 @@ export type Models = {
 | 
			
		|||
		hashed_profile_content: number
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sim_proxy: {
 | 
			
		||||
		user_id: string
 | 
			
		||||
		proxy_owner_id: string
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	webhook: {
 | 
			
		||||
		channel_id: string
 | 
			
		||||
		webhook_id: string
 | 
			
		||||
| 
						 | 
				
			
			@ -100,3 +105,4 @@ export type Prepared<Row> = {
 | 
			
		|||
export type AllKeys<U> = U extends any ? keyof U : never
 | 
			
		||||
export type PickTypeOf<T, K extends AllKeys<T>> = T extends { [k in K]?: any } ? T[K] : never
 | 
			
		||||
export type Merge<U> = {[x in AllKeys<U>]: PickTypeOf<U, x>}
 | 
			
		||||
export type Nullable<T> = {[k in keyof T]: T[k] | null}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,8 @@ class From {
 | 
			
		|||
		/** @private @type {Table[]} */
 | 
			
		||||
		this.tables = [table]
 | 
			
		||||
		/** @private */
 | 
			
		||||
		this.directions = []
 | 
			
		||||
		/** @private */
 | 
			
		||||
		this.sql = ""
 | 
			
		||||
		/** @private */
 | 
			
		||||
		this.cols = []
 | 
			
		||||
| 
						 | 
				
			
			@ -53,12 +55,14 @@ class From {
 | 
			
		|||
	 * @template {keyof U.Models} Table2
 | 
			
		||||
	 * @param {Table2} table
 | 
			
		||||
	 * @param {Col & (keyof U.Models[Table2])} col
 | 
			
		||||
	 * @param {"inner" | "left"} [direction]
 | 
			
		||||
	 */
 | 
			
		||||
	join(table, col) {
 | 
			
		||||
	join(table, col, direction = "inner") {
 | 
			
		||||
		/** @type {From<Table | Table2, keyof U.Merge<U.Models[Table | Table2]>>} */
 | 
			
		||||
		// @ts-ignore
 | 
			
		||||
		const r = this
 | 
			
		||||
		r.tables.push(table)
 | 
			
		||||
		r.directions.push(direction.toUpperCase())
 | 
			
		||||
		r.using.push(col)
 | 
			
		||||
		return r
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +116,8 @@ class From {
 | 
			
		|||
		for (let i = 1; i < this.tables.length; i++) {
 | 
			
		||||
			const table = this.tables[i]
 | 
			
		||||
			const col = this.using[i-1]
 | 
			
		||||
			sql += `INNER JOIN ${table} USING (${col}) `
 | 
			
		||||
			const direction = this.directions[i-1]
 | 
			
		||||
			sql += `${direction} JOIN ${table} USING (${col}) `
 | 
			
		||||
		}
 | 
			
		||||
		sql += this.sql
 | 
			
		||||
		/** @type {U.Prepared<Pick<U.Merge<U.Models[Table]>, Col>>} */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,3 +44,12 @@ test("orm: from: where and pluck works", t => {
 | 
			
		|||
	const subtypes = from("event_message").where({message_id: "1141501302736695316"}).pluck("event_subtype").all()
 | 
			
		||||
	t.deepEqual(subtypes.sort(), ["m.image", "m.text"])
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("orm: from: join direction works", t => {
 | 
			
		||||
	const hasOwner = from("sim").join("sim_proxy", "user_id", "left").select("user_id", "proxy_owner_id").where({sim_name: "_pk_zoego"}).get()
 | 
			
		||||
	t.deepEqual(hasOwner, {user_id: "43d378d5-1183-47dc-ab3c-d14e21c3fe58", proxy_owner_id: "196188877885538304"})
 | 
			
		||||
	const hasNoOwner = from("sim").join("sim_proxy", "user_id", "left").select("user_id", "proxy_owner_id").where({sim_name: "crunch_god"}).get()
 | 
			
		||||
	t.deepEqual(hasNoOwner, {user_id: "820865262526005258", proxy_owner_id: null})
 | 
			
		||||
	const hasNoOwnerInner = from("sim").join("sim_proxy", "user_id", "inner").select("user_id", "proxy_owner_id").where({sim_name: "crunch_god"}).get()
 | 
			
		||||
	t.deepEqual(hasNoOwnerInner, null)
 | 
			
		||||
})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -238,6 +238,16 @@ function splitDisplayName(displayName) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert a Matrix user ID into a Discord user ID for mentioning, where if the user is a PK proxy, it will mention the proxy owner.
 | 
			
		||||
 * @param {string} mxid
 | 
			
		||||
 */
 | 
			
		||||
function getUserOrProxyOwnerID(mxid) {
 | 
			
		||||
	const row = from("sim").join("sim_proxy", "user_id", "left").select("user_id", "proxy_owner_id").where({mxid}).get()
 | 
			
		||||
	if (!row) return null
 | 
			
		||||
	return row.proxy_owner_id || row.user_id
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * At the time of this executing, we know what the end of message emojis are, and we know that at least one of them is unknown.
 | 
			
		||||
 * This function will strip them from the content and generate the correct pending file of the sprite sheet.
 | 
			
		||||
| 
						 | 
				
			
			@ -444,11 +454,11 @@ async function eventToMessage(event, guild, di) {
 | 
			
		|||
				replyLine += `https://discord.com/channels/${guild.id}/${row.channel_id}/${row.message_id} `
 | 
			
		||||
			}
 | 
			
		||||
			const sender = repliedToEvent.sender
 | 
			
		||||
			const authorID = select("sim", "user_id", {mxid: repliedToEvent.sender}).pluck().get()
 | 
			
		||||
			const authorID = getUserOrProxyOwnerID(sender)
 | 
			
		||||
			if (authorID) {
 | 
			
		||||
				replyLine += `<@${authorID}>`
 | 
			
		||||
			} else {
 | 
			
		||||
				let senderName = select("member_cache", "displayname", {mxid: repliedToEvent.sender}).pluck().get()
 | 
			
		||||
				let senderName = select("member_cache", "displayname", {mxid: sender}).pluck().get()
 | 
			
		||||
				if (!senderName) {
 | 
			
		||||
					const match = sender.match(/@([^:]*)/)
 | 
			
		||||
					assert(match)
 | 
			
		||||
| 
						 | 
				
			
			@ -497,7 +507,7 @@ async function eventToMessage(event, guild, di) {
 | 
			
		|||
				mxid = decodeURIComponent(mxid)
 | 
			
		||||
				if (mxUtils.eventSenderIsFromDiscord(mxid)) {
 | 
			
		||||
					// Handle mention of an OOYE sim user by their mxid
 | 
			
		||||
					const userID = select("sim", "user_id", {mxid: mxid}).pluck().get()
 | 
			
		||||
					const userID = getUserOrProxyOwnerID(mxid)
 | 
			
		||||
					if (!userID) return whole
 | 
			
		||||
					return `${attributeValue} data-user-id="${userID}">`
 | 
			
		||||
				} else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1869,7 +1869,6 @@ test("event2message: mentioning discord users works", async t => {
 | 
			
		|||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
test("event2message: mentioning discord users works when URL encoded", async t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		await eventToMessage({
 | 
			
		||||
| 
						 | 
				
			
			@ -1901,6 +1900,37 @@ test("event2message: mentioning discord users works when URL encoded", async t =
 | 
			
		|||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("event2message: mentioning PK discord users works", async t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		await eventToMessage({
 | 
			
		||||
			content: {
 | 
			
		||||
				msgtype: "m.text",
 | 
			
		||||
				body: "wrong body",
 | 
			
		||||
				format: "org.matrix.custom.html",
 | 
			
		||||
				formatted_body: `I'm just <a href="https://matrix.to/#/@_ooye__pk_zoego:cadence.moe">Azalea</a> testing mentions`
 | 
			
		||||
			},
 | 
			
		||||
			event_id: "$g07oYSZFWBkxohNEfywldwgcWj1hbhDzQ1sBAKvqOOU",
 | 
			
		||||
			origin_server_ts: 1688301929913,
 | 
			
		||||
			room_id: "!kLRqKKUQXcibIMtOpl:cadence.moe",
 | 
			
		||||
			sender: "@cadence:cadence.moe",
 | 
			
		||||
			type: "m.room.message",
 | 
			
		||||
			unsigned: {
 | 
			
		||||
				age: 405299
 | 
			
		||||
			}
 | 
			
		||||
		}),
 | 
			
		||||
		{
 | 
			
		||||
			ensureJoined: [],
 | 
			
		||||
			messagesToDelete: [],
 | 
			
		||||
			messagesToEdit: [],
 | 
			
		||||
			messagesToSend: [{
 | 
			
		||||
				username: "cadence [they]",
 | 
			
		||||
				content: "I'm just <@196188877885538304> testing mentions",
 | 
			
		||||
				avatar_url: undefined
 | 
			
		||||
			}]
 | 
			
		||||
		}
 | 
			
		||||
	)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test("event2message: mentioning matrix users works", async t => {
 | 
			
		||||
	t.deepEqual(
 | 
			
		||||
		await eventToMessage({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,11 @@ INSERT INTO sim (user_id, sim_name, localpart, mxid) VALUES
 | 
			
		|||
('112890272819507200', '.wing.', '_ooye_.wing.', '@_ooye_.wing.:cadence.moe'),
 | 
			
		||||
('114147806469554185', 'extremity', '_ooye_extremity', '@_ooye_extremity:cadence.moe'),
 | 
			
		||||
('111604486476181504', 'kyuugryphon', '_ooye_kyuugryphon', '@_ooye_kyuugryphon:cadence.moe'),
 | 
			
		||||
('1109360903096369153', 'amanda', '_ooye_amanda', '@_ooye_amanda:cadence.moe');
 | 
			
		||||
('1109360903096369153', 'amanda', '_ooye_amanda', '@_ooye_amanda:cadence.moe'),
 | 
			
		||||
('43d378d5-1183-47dc-ab3c-d14e21c3fe58', '_pk_zoego', '_ooye__pk_zoego', '@_ooye__pk_zoego:cadence.moe');
 | 
			
		||||
 | 
			
		||||
INSERT INTO sim_proxy (user_id, proxy_owner_id) VALUES
 | 
			
		||||
('43d378d5-1183-47dc-ab3c-d14e21c3fe58', '196188877885538304');
 | 
			
		||||
 | 
			
		||||
INSERT INTO sim_member (mxid, room_id, hashed_profile_content) VALUES
 | 
			
		||||
('@_ooye_bojack_horseman:cadence.moe', '!hYnGGlPHlbujVVfktC:cadence.moe', NULL);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								types.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -70,6 +70,7 @@ export type PkMember = {
 | 
			
		|||
export type PkMessage = {
 | 
			
		||||
	system: PkSystem
 | 
			
		||||
	member: PkMember
 | 
			
		||||
	sender: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export namespace Event {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue