send sim messages to the proper rooms
This commit is contained in:
		
							parent
							
								
									7526d63690
								
							
						
					
					
						commit
						da6603d258
					
				
					 10 changed files with 38 additions and 10 deletions
				
			
		| 
						 | 
					@ -24,10 +24,18 @@ async function createSim(user) {
 | 
				
			||||||
	const mxid = "@" + localpart + ":cadence.moe"
 | 
						const mxid = "@" + localpart + ":cadence.moe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Save chosen name in the database forever
 | 
						// 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
 | 
				
			||||||
	db.prepare("INSERT INTO sim (discord_id, sim_name, localpart, mxid) VALUES (?, ?, ?, ?)").run(user.id, simName, localpart, mxid)
 | 
						db.prepare("INSERT INTO sim (discord_id, sim_name, localpart, mxid) VALUES (?, ?, ?, ?)").run(user.id, simName, localpart, mxid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Register matrix user with that name
 | 
						// Register matrix user with that name
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
		await api.register(localpart)
 | 
							await api.register(localpart)
 | 
				
			||||||
 | 
						} catch (e) {
 | 
				
			||||||
 | 
							// If user creation fails, manually undo the database change. Still isn't perfect, but should help.
 | 
				
			||||||
 | 
							// (A transaction would be preferable, but I don't think it's safe to leave transaction open across event loop ticks.)
 | 
				
			||||||
 | 
							db.prepare("DELETE FROM sim WHERE discord_id = ?").run(user.id)
 | 
				
			||||||
 | 
							throw e
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return mxid
 | 
						return mxid
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,7 @@ function* generateLocalpartAlternatives(preferences) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Whole process for checking the database and generating the right sim name.
 | 
					 * Whole process for checking the database and generating the right sim name.
 | 
				
			||||||
 | 
					 * It is very important this is not an async function: once the name has been chosen, the calling function should be able to immediately claim that name into the database in the same event loop tick.
 | 
				
			||||||
 * @param {import("discord-api-types/v10").APIUser} user
 | 
					 * @param {import("discord-api-types/v10").APIUser} user
 | 
				
			||||||
 * @returns {string}
 | 
					 * @returns {string}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,3 +31,7 @@ test("user2name: adds number suffix if name is unavailable (new username format)
 | 
				
			||||||
test("user2name: uses ID if name becomes too short", t => {
 | 
					test("user2name: uses ID if name becomes too short", t => {
 | 
				
			||||||
   t.equal(userToSimName({username: "f***", discriminator: "0001", id: "9"}), "9")
 | 
					   t.equal(userToSimName({username: "f***", discriminator: "0001", id: "9"}), "9")
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("user2name: uses ID when name has only disallowed characters", t => {
 | 
				
			||||||
 | 
					   t.equal(userToSimName({username: "!@#$%^&*", discriminator: "0001", id: "9"}), "9")
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
| 
						 | 
					@ -6,15 +6,16 @@ const DiscordTypes = require("discord-api-types/v10")
 | 
				
			||||||
const passthrough = require("../passthrough")
 | 
					const passthrough = require("../passthrough")
 | 
				
			||||||
const { sync } = passthrough
 | 
					const { sync } = passthrough
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @type {typeof import("./event-dispatcher")} */
 | 
					 | 
				
			||||||
const eventDispatcher = sync.require("./event-dispatcher")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const utils = {
 | 
					const utils = {
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @param {import("./discord-client")} client
 | 
						 * @param {import("./discord-client")} client
 | 
				
			||||||
	 * @param {import("cloudstorm").IGatewayMessage} message
 | 
						 * @param {import("cloudstorm").IGatewayMessage} message
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	onPacket(client, message) {
 | 
						onPacket(client, message) {
 | 
				
			||||||
 | 
							// requiring this later so that the client is already constructed by the time event-dispatcher is loaded
 | 
				
			||||||
 | 
							/** @type {typeof import("./event-dispatcher")} */
 | 
				
			||||||
 | 
							const eventDispatcher = sync.require("./event-dispatcher")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (message.t === "READY") {
 | 
							if (message.t === "READY") {
 | 
				
			||||||
			if (client.ready) return
 | 
								if (client.ready) return
 | 
				
			||||||
			client.ready = true
 | 
								client.ready = true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const {sync} = require("../passthrough")
 | 
					const {sync} = require("../passthrough")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @type {import("./actions/create-space")}) */
 | 
					 | 
				
			||||||
const createSpace = sync.require("./actions/create-space")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** @type {import("./actions/send-message")}) */
 | 
					/** @type {import("./actions/send-message")}) */
 | 
				
			||||||
const sendMessage = sync.require("./actions/send-message")
 | 
					const sendMessage = sync.require("./actions/send-message")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,7 @@ function path(p, mxid) {
 | 
				
			||||||
 * @returns {Promise<import("../types").R.Registered>}
 | 
					 * @returns {Promise<import("../types").R.Registered>}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function register(username) {
 | 
					function register(username) {
 | 
				
			||||||
 | 
					   console.log(`[api] register: ${username}`)
 | 
				
			||||||
   return mreq.mreq("POST", "/client/v3/register", {
 | 
					   return mreq.mreq("POST", "/client/v3/register", {
 | 
				
			||||||
      type: "m.login.application_service",
 | 
					      type: "m.login.application_service",
 | 
				
			||||||
      username
 | 
					      username
 | 
				
			||||||
| 
						 | 
					@ -38,6 +39,7 @@ function register(username) {
 | 
				
			||||||
 * @returns {Promise<string>} room ID
 | 
					 * @returns {Promise<string>} room ID
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function createRoom(content) {
 | 
					async function createRoom(content) {
 | 
				
			||||||
 | 
					   console.log(`[api] create room:`, content)
 | 
				
			||||||
   /** @type {import("../types").R.RoomCreated} */
 | 
					   /** @type {import("../types").R.RoomCreated} */
 | 
				
			||||||
   const root = await mreq.mreq("POST", "/client/v3/createRoom", content)
 | 
					   const root = await mreq.mreq("POST", "/client/v3/createRoom", content)
 | 
				
			||||||
   return root.room_id
 | 
					   return root.room_id
 | 
				
			||||||
| 
						 | 
					@ -74,6 +76,7 @@ function getAllState(roomID) {
 | 
				
			||||||
 * @returns {Promise<string>} event ID
 | 
					 * @returns {Promise<string>} event ID
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function sendState(roomID, type, stateKey, content, mxid) {
 | 
					async function sendState(roomID, type, stateKey, content, mxid) {
 | 
				
			||||||
 | 
					   console.log(`[api] state: ${roomID}: ${type}/${stateKey}`)
 | 
				
			||||||
   assert.ok(type)
 | 
					   assert.ok(type)
 | 
				
			||||||
   assert.ok(stateKey)
 | 
					   assert.ok(stateKey)
 | 
				
			||||||
   /** @type {import("../types").R.EventSent} */
 | 
					   /** @type {import("../types").R.EventSent} */
 | 
				
			||||||
| 
						 | 
					@ -82,6 +85,7 @@ async function sendState(roomID, type, stateKey, content, mxid) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function sendEvent(roomID, type, content, mxid) {
 | 
					async function sendEvent(roomID, type, content, mxid) {
 | 
				
			||||||
 | 
					   console.log(`[api] event to ${roomID} as ${mxid || "default sim"}`)
 | 
				
			||||||
   /** @type {import("../types").R.EventSent} */
 | 
					   /** @type {import("../types").R.EventSent} */
 | 
				
			||||||
   const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/send/${type}/${makeTxnId.makeTxnId()}`, mxid), content)
 | 
					   const root = await mreq.mreq("PUT", path(`/client/v3/rooms/${roomID}/send/${type}/${makeTxnId.makeTxnId()}`, mxid), content)
 | 
				
			||||||
   return root.event_id
 | 
					   return root.event_id
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,11 +11,12 @@ const reg = sync.require("./read-registration.js")
 | 
				
			||||||
const baseUrl = "https://matrix.cadence.moe/_matrix"
 | 
					const baseUrl = "https://matrix.cadence.moe/_matrix"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MatrixServerError extends Error {
 | 
					class MatrixServerError extends Error {
 | 
				
			||||||
	constructor(data) {
 | 
						constructor(data, opts) {
 | 
				
			||||||
		super(data.error || data.errcode)
 | 
							super(data.error || data.errcode)
 | 
				
			||||||
		this.data = data
 | 
							this.data = data
 | 
				
			||||||
		/** @type {string} */
 | 
							/** @type {string} */
 | 
				
			||||||
		this.errcode = data.errcode
 | 
							this.errcode = data.errcode
 | 
				
			||||||
 | 
							this.opts = opts
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +39,7 @@ async function mreq(method, url, body, extra = {}) {
 | 
				
			||||||
	const res = await fetch(baseUrl + url, opts)
 | 
						const res = await fetch(baseUrl + url, opts)
 | 
				
			||||||
	const root = await res.json()
 | 
						const root = await res.json()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!res.ok || root.errcode) throw new MatrixServerError(root)
 | 
						if (!res.ok || root.errcode) throw new MatrixServerError(root, opts)
 | 
				
			||||||
	return root
 | 
						return root
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								matrix/read-registration.test.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								matrix/read-registration.test.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					const {test} = require("supertape")
 | 
				
			||||||
 | 
					const assert = require("assert")
 | 
				
			||||||
 | 
					const reg = require("./read-registration")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("reg: has necessary parameters", t => {
 | 
				
			||||||
 | 
					   const propertiesToCheck = ["sender_localpart", "id", "as_token", "namespace_prefix"]
 | 
				
			||||||
 | 
					   t.deepEqual(
 | 
				
			||||||
 | 
					      propertiesToCheck.filter(p => p in reg),
 | 
				
			||||||
 | 
					      propertiesToCheck
 | 
				
			||||||
 | 
					   )
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@ const sync = new HeatSync({watchFS: false})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Object.assign(passthrough, { config, sync, db })
 | 
					Object.assign(passthrough, { config, sync, db })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require("../matrix/read-registration.test")
 | 
				
			||||||
require("../d2m/actions/create-room.test")
 | 
					require("../d2m/actions/create-room.test")
 | 
				
			||||||
require("../d2m/converters/user-to-mxid.test")
 | 
					require("../d2m/converters/user-to-mxid.test")
 | 
				
			||||||
require("../matrix/api.test")
 | 
					require("../matrix/api.test")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue