twitch2ma
Version:
Twitch chat bot that runs commands on the MA GrandMA2 using Telnet.
140 lines (109 loc) • 3.95 kB
text/typescript
import {RuntimeInformation} from "./RuntimeInformation";
import {Config} from "./Config";
export interface PermissionInstance {
check(permissionCollector: PermissionCollector,
runtimeInformation: RuntimeInformation,
additionalRuntimeInformation: Map<String, any>): void;
start(): void;
stop(): Promise<void>;
reloadConfig(config: Config): Promise<void>;
}
export class PermissionError extends Error {
readonly permissionCollector: PermissionCollector;
constructor(permissionCollector: PermissionCollector) {
super();
this.permissionCollector = permissionCollector;
Object.setPrototypeOf(this, PermissionError.prototype);
this.name = PermissionError.name;
}
}
export class Reason {
public readonly name: string;
public readonly viewerMessage: string;
constructor(name: string, viewerMessage: string) {
this.name = name;
this.viewerMessage = viewerMessage;
}
}
export class PermissionController {
private readonly permissionInstances: Array<PermissionInstance>;
private readonly additionalRuntimeInformation: Map<String, any>;
constructor() {
this.permissionInstances = [];
this.additionalRuntimeInformation = new Map();
}
withPermissionInstance(instance: PermissionInstance): PermissionController {
this.permissionInstances.push(instance);
return this;
}
async checkPermissions(runtimeInformation: RuntimeInformation) {
let permissionCollector = new PermissionCollector();
for (const permissionInstance of this.permissionInstances) {
permissionInstance.check(permissionCollector, runtimeInformation, this.additionalRuntimeInformation);
}
if (permissionCollector.permissionDenied) {
throw new PermissionError(permissionCollector);
}
return permissionCollector;
}
setAdditionalRuntimeInformation(name: string, value: any) {
this.additionalRuntimeInformation.set(name, value);
}
start() {
let startChain = Promise.resolve();
for (const permissionInstance of this.permissionInstances) {
startChain = startChain
.then(() => permissionInstance.start());
}
return startChain;
}
stop() {
let stopChain = Promise.resolve();
for (const permissionInstance of this.permissionInstances) {
stopChain = stopChain
.then(() => permissionInstance.stop());
}
return stopChain;
}
reloadConfig(config: Config) {
let reloadChain = Promise.resolve();
for (const permissionInstance of this.permissionInstances) {
reloadChain
.then(() => permissionInstance.reloadConfig(config));
}
return reloadChain;
}
}
export class PermissionCollector {
private _permissionDenied: boolean;
private _godMode: boolean;
private readonly _godModeReasons: Array<String>;
private readonly _permissionDeniedReasons: Array<Reason>;
constructor() {
this._permissionDenied = false;
this._godMode = false;
this._godModeReasons = [];
this._permissionDeniedReasons = [];
}
denyPermission(reason: string, message: string) {
this._permissionDenied = !this._godMode;
this._permissionDeniedReasons.push(new Reason(reason, message));
}
enableGodMode(reason: string) {
this._permissionDenied = false;
this._godMode = true;
this._godModeReasons.push(reason);
}
get permissionDenied(): boolean {
return this._permissionDenied;
}
get permissionDeniedReasons(): Array<Reason> {
return this._permissionDeniedReasons;
}
get godMode(): boolean {
return this._godMode;
}
get godModeReasons(): Array<String> {
return this._godModeReasons;
}
}