diff --git a/server/api/ApiManager.ts b/server/api/ApiManager.ts index a7ca3bd..e695a61 100644 --- a/server/api/ApiManager.ts +++ b/server/api/ApiManager.ts @@ -32,6 +32,10 @@ export default class ApiManager { static addEventListener(name: string, func: EventCallbackFunction) { this.event_listeners[name] = func } + static clients: { [key: string]: string[] } = {} + static checkUserIsOnline(userId: string, deviceId: string) { + return this.clients[userId].includes(deviceId) + } static initEvents() { const io = this.socketIoServer @@ -42,10 +46,22 @@ export default class ApiManager { const deviceId = socket.handshake.auth.device_id as string + const clientInfo = { + userId: '', + deviceId, + ip + } + socket.on('disconnect', (_reason) => { - console.log(chalk.yellow('[斷]') + ` ${ip} disconnected`) + if (clientInfo.userId == '') + console.log(chalk.yellow('[斷]') + ` ${ip} disconnected`) + else { + console.log(chalk.green('[斷]') + ` ${ip} disconnected`) + const ls = this.clients[clientInfo.userId] + ls.splice(ls.indexOf(deviceId)) + } }) - console.log(chalk.green('[連]') + ` ${ip} connected`) + console.log(chalk.yellow('[連]') + ` ${ip} connected`) socket.on("The_White_Silk", (name: string, args: { [key: string]: unknown }, callback_: (ret: ApiCallbackMessage) => void) => { function callback(ret: ApiCallbackMessage) { @@ -59,9 +75,7 @@ export default class ApiManager { }) console.log(chalk.red('[收]') + ` ${ip} -> ${chalk.yellow(name)} `) - return callback(this.event_listeners[name]?.(args, { - deviceId - }) || { + return callback(this.event_listeners[name]?.(args, clientInfo) || { code: 501, msg: "Not implmented", }) diff --git a/server/api/EventBean.ts b/server/api/EventBean.ts new file mode 100644 index 0000000..43d68af --- /dev/null +++ b/server/api/EventBean.ts @@ -0,0 +1,4 @@ +export default class EventBean { + declare event_name: string + declare data: unknown +} \ No newline at end of file diff --git a/server/api/EventStorer.ts b/server/api/EventStorer.ts new file mode 100644 index 0000000..535ee8f --- /dev/null +++ b/server/api/EventStorer.ts @@ -0,0 +1,53 @@ +import { DatabaseSync } from "node:sqlite" +import path from 'node:path' + +import config from "../config.ts" +import User from "../data/User.ts"; +import EventBean from "./EventBean.ts"; + +export default class EventStorer { + static database: DatabaseSync = this.init() + + private static init(): DatabaseSync { + const db: DatabaseSync = new DatabaseSync(path.join(config.data_path, 'Events.db')) + return db + } + + static getInstanceForUser(user: User) { + return new EventStorer(user) + } + + declare user: User + constructor(user: User) { + this.user = user + + EventStorer.database.exec(` + CREATE TABLE IF NOT EXISTS ${this.getTableName()} ( + /* 序号 */ count INTEGER PRIMARY KEY AUTOINCREMENT, + /* 事件 */ event_name TEXT NOT NULL, + /* 數據 */ data TEXT NOT NULL, + ); + `) + } + protected getTableName() { + return `events_${this.user.bean.id}` + } + addEvent(eventName: string, data: unknown) { + EventStorer.database.prepare(`INSERT INTO ${this.getTableName()} ( + event_name, + data + ) VALUES (?, ?);`).run( + eventName, + JSON.stringify(data) + ) + } + getEvents() { + return EventStorer.database.prepare(`SELECT * FROM ${this.getTableName()};`).all().map((v: any) => ({ + ...v, + data: JSON.parse(v.data) + })) as unknown as EventBean[] + } + clearEvents() { + EventStorer.database.prepare(`DELETE FROM ${this.getTableName()};`).run() + } +}