🎨 🚨 Replace TSLint by ESLint

parent 0653ef2d
module.exports = {
root: true,
extends: [
"osufrlive",
],
};
......@@ -3,18 +3,23 @@
{
"address": "127.0.0.1",
"port": 4445,
"password": "test"
"password": "tft2019"
},
{
"address": "127.0.0.1",
"port": 4446,
"password": "test"
"address": "192.168.1.38",
"port": 4444,
"password": "tft2019"
},
{
"address": "192.168.1.39",
"port": 4444,
"password": "tft2019"
}
],
"server": {
"address": "127.0.0.1",
"port": 4444,
"password": "test"
"password": "tft2019"
},
"stopTimeout": 5
}
\ No newline at end of file
}
This diff is collapsed.
......@@ -7,16 +7,23 @@
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"lint": "tslint -c tslint.json src/**/*.ts",
"lint": "eslint . --ext .js,.ts",
"start": "node build/index.js"
},
"devDependencies": {
"@types/node": "^12.0.3",
"@types/ws": "^6.0.1",
"@typescript-eslint/eslint-plugin": "^2.14.0",
"eslint": "^6.8.0",
"eslint-config-osufrlive": "https://git.cartooncraft.fr/osufrlive/eslint/-/jobs/artifacts/v0.0.1/raw/eslint-config-osufrlive-0.0.1.tgz?job=pack",
"eslint-config-standard-with-typescript": "^11.0.1",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-node": "^9.2.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"ts-node": "^8.2.0",
"ts-node-dev": "^1.0.0-pre.39",
"tslint": "^5.16.0",
"typescript": "^3.4.5"
"typescript": "^3.7.4"
},
"dependencies": {
"node-config-ts": "^2.2.4",
......
import { config } from "node-config-ts";
import * as events from "./events";
import * as OBSWebSocket from "obs-websocket-js";
import { Logger } from "osufrlive-common";
import { promisify } from "util";
import * as Websocket from "ws";
import * as events from "./events";
import { config } from "node-config-ts";
import { Logger } from "osufrlive-common";
import { OBSWSClient } from "./OBSWSClient";
import { promisify } from "util";
export class App {
private static readonly logger = new Logger("App");
......@@ -13,10 +13,10 @@ export class App {
public currentScene: string;
private wss: Websocket.Server;
private clients: OBSWSClient[] = [];
private readonly clients: OBSWSClient[] = [];
public async start() {
for(const configId in config.obsInstances)
public start(): void {
for(const configId of Object.keys(config.obsInstances))
this.handleObsInstance(Number(configId), true);
this.wss = new Websocket.Server({
......@@ -37,20 +37,20 @@ export class App {
App.logger.info(`WebSocket server listening on ${config.server.address}:${config.server.port}`);
}
public async stop() {
public async stop(): Promise<void> {
await promisify(this.wss.close.bind(this.wss))();
}
public broadcastEvent(updateType: string, data: object) {
public broadcastEvent(updateType: string, data: object): void {
return this.broadcast({ ...data, "update-type": updateType });
}
private broadcast(data: object) {
private broadcast(data: object): void {
for(const client of this.clients)
client.ws.send(JSON.stringify(data));
}
private handleObsInstance(instanceId: number, exitOnConnectionFailure: boolean) {
private handleObsInstance(instanceId: number, exitOnConnectionFailure: boolean): void {
const conf = config.obsInstances[instanceId];
const obs = new OBSWebSocket();
for(const name of Object.keys(events))
......@@ -67,7 +67,8 @@ export class App {
obs.on("ConnectionOpened", () => {
App.logger.info(`OBS Connection #${instanceId} opened!`);
if(this.currentScene)
obs.send("SetCurrentScene", { "scene-name": this.currentScene });
obs.send("SetCurrentScene", { "scene-name": this.currentScene })
.catch((err) => App.logger.error(`Failed to set current scene ${this.currentScene} to new client #${instanceId}!`, err));
});
obs.on("ConnectionClosed", () => {
......@@ -77,8 +78,7 @@ export class App {
});
}
public get primaryOBSInstance() {
public get primaryOBSInstance(): OBSWebSocket | undefined {
return this.obsInstances[0];
}
}
import * as Websocket from "ws";
import { App } from "./App";
import * as authenticatedHandlers from "./requests/authenticated";
import * as unauthenticatedHandlers from "./requests/unauthenticated";
import * as Websocket from "ws";
import { App } from "./App";
import { Logger } from "osufrlive-common";
export class OBSWSClient {
public salt: string;
public challenge: string;
public authenticated: boolean = false;
private static readonly logger = new Logger("OBSWSClient");
public constructor(public readonly app: App, public readonly ws: Websocket) {
ws.on("message", async (str) => {
ws.on("message", (str) => {
const data = JSON.parse(str.toString());
const handlers = this.authenticated ? authenticatedHandlers : unauthenticatedHandlers;
const handler = Object.keys(handlers).find((handlerName) => data["request-type"] === handlerName) ? handlers[data["request-type"]] : null;
const handler: ((client: OBSWSClient, data: object) => Promise<object>) | null = Object.keys(handlers).find((handlerName) => data["request-type"] === handlerName) ? handlers[data["request-type"]] : null;
if(handler) {
const response = await handler(this, data) || {};
ws.send(JSON.stringify({ "status": "success", ...response, "message-id": data["message-id"] }));
}
if(handler)
handler(this, data)
.then((res = {}) => ws.send(JSON.stringify({ status: "success", ...res, "message-id": data["message-id"] })))
.catch((err) => OBSWSClient.logger.error("Failed to handle request", err));
});
}
}
import * as OBSWebSocket from "obs-websocket-js";
import { App } from "../App";
import { Logger } from "osufrlive-common";
export function SwitchScenes(socket: OBSWebSocket, app: App, data: { "scene-name": string, "sources": OBSWebSocket.Source[] }) {
if(app.currentScene !== data["scene-name"]) {
app.currentScene = data["scene-name"];
app.broadcastEvent("SwitchScenes", { "scene-name": data["scene-name"], "sources": data.sources });
for(const obs of app.obsInstances)
obs.send("SetCurrentScene", { "scene-name": data["scene-name"] });
const SwitchScenesLogger = new Logger("SwitchScenes");
export function SwitchScenes(socket: OBSWebSocket, app: App, { "scene-name": sceneName, sources }: { "scene-name": string; sources: OBSWebSocket.Source[] }): void {
if(app.currentScene !== sceneName) {
app.currentScene = sceneName;
app.broadcastEvent("SwitchScenes", { "scene-name": sceneName, sources });
for(const [id, obs] of Object.entries(app.obsInstances))
obs.send("SetCurrentScene", { "scene-name": sceneName })
.catch((err) => SwitchScenesLogger.error(`Failed to set current scene to ${sceneName} on instance #${id}!`, err));
}
}
import { App } from "./App";
import { config } from "node-config-ts";
import { Logger } from "osufrlive-common";
import { App } from "./App";
export const app = new App();
process.on("SIGINT", async () => {
process.on("SIGINT", () => {
Logger.info("Shutting down app...");
(async () => {
setTimeout(() => {
Logger.error(`Stop timeout (${config.stopTimeout} seconds) exceeded - forcing shutdown!`);
process.exit(2);
}, config.stopTimeout * 1000);
setTimeout(() => {
Logger.error(`Stop timeout (${config.stopTimeout} seconds) exceeded - forcing shutdown!`);
process.exit(2);
}, config.stopTimeout * 1000);
try {
await app.stop();
} catch(err) {
Logger.error("An error occured while shutting down!", { err });
process.nextTick(() => process.exit(1));
}
Logger.info("App successfully shut down!");
process.nextTick(() => process.exit(0));
try {
await app.stop();
} catch (err) {
Logger.error("An error occured while shutting down!", { err });
process.nextTick(() => process.exit(1));
}
Logger.info("App successfully shut down!");
process.nextTick(() => process.exit(0));
})().catch((err) => Logger.error("An error occured while shutting down!", err));
});
Logger.info("Starting app...");
app.start()
.then(() => Logger.info("App started!"))
.catch((err) => {
Logger.error("An error occured while starting!", { err });
process.exit(1);
});
try {
app.start();
} catch (err) {
Logger.error("An error occured while starting!", { err });
process.exit(1);
}
import { Logger } from "osufrlive-common";
import { OBSWSClient } from "../../OBSWSClient";
export async function SetCurrentScene(client: OBSWSClient, data: { "scene-name": string }) {
try {
await Promise.all(client.app.obsInstances.map((obs) => obs.send("SetCurrentScene", { "scene-name": data["scene-name"] })));
// const eventData = await client.app.primaryOBSInstance.send("GetCurrentScene");
// client.app.broadcastEvent("SwitchScenes", { "scene-name": eventData.name, "sources": eventData.sources });
} catch(err) {
return err;
}
const SetCurrentSceneLogger = new Logger("SetCurrentScene");
export async function SetCurrentScene(client: OBSWSClient, { "scene-name": sceneName }: { "scene-name": string }): Promise<void> {
await Promise.all(Object.entries(client.app.obsInstances).map(async ([id, obs]) =>
obs.send("SetCurrentScene", { "scene-name": sceneName })
.catch((err) => SetCurrentSceneLogger.error(`Failed to set current scene to ${sceneName} on instance #${id}!`, err)),
));
}
......@@ -2,7 +2,8 @@ import { createHash, randomBytes } from "crypto";
import { config } from "node-config-ts";
import { OBSWSClient } from "../../OBSWSClient";
export function GetAuthRequired(client: OBSWSClient) {
// eslint-disable-next-line @typescript-eslint/require-await
export async function GetAuthRequired(client: OBSWSClient): Promise<{ authRequired: false } | { authRequired: true; challenge: string; salt: string }> {
if(!config.server.password) {
client.authenticated = true;
return { authRequired: false };
......@@ -12,7 +13,8 @@ export function GetAuthRequired(client: OBSWSClient) {
return { authRequired: true, challenge: client.challenge, salt: client.salt };
}
export function Authenticate(client: OBSWSClient, data: { auth: string }) {
// eslint-disable-next-line @typescript-eslint/require-await
export async function Authenticate(client: OBSWSClient, data: { auth: string }): Promise<{ status?: string }> {
if(!config.server.password || !client.salt || !client.challenge || client.authenticated)
return { status: "error" };
......@@ -20,7 +22,7 @@ export function Authenticate(client: OBSWSClient, data: { auth: string }) {
const authResponse = createHash("sha256").update(secret + client.challenge).digest("base64");
if(data.auth === authResponse) {
client.authenticated = true;
return;
return {};
} else
return { status: "error" };
}
const OBSWebSocket = require("obs-websocket-js");
(async () => {
try {
const obs = new OBSWebSocket();
obs.on("SwitchScenes", (data) => console.log("SwitchScenes OK", data["scene-name"]));
console.log("connecting");
await obs.connect({ address: "localhost:4444", "password": "test" });
console.log("connected");
await obs.send("SetCurrentScene", { "scene-name": "Scene 2" });
} catch(err) {
console.error("err", err);
}
})();
......@@ -8,7 +8,8 @@
"lib": [
"es2018"
],
"noUnusedLocals": true
"noUnusedLocals": true,
"strictNullChecks": true
},
"files": [
"src/index.ts"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment