Skip to content

Commit

Permalink
fix: Make sACN interface configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
schw4rzlicht committed Jun 12, 2020
1 parent b91630f commit 48eafa0
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 26 deletions.
10 changes: 6 additions & 4 deletions __tests__/Config.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Config, MaConfig, TwitchConfig, Command, Parameter, SACNConfig} from "../src/lib/Config";
import {Config, MaConfig, TwitchConfig, Command, Parameter, SACNLock} from "../src/lib/Config";

import Fs = require("fs");

Expand All @@ -8,7 +8,6 @@ test("Constructor", () => {
let config = new Config(rawConfig);

expect(config.timeout).toBe(rawConfig.timeout);
expect(config.lockMessage).toBe(rawConfig.lockMessage);

expect(config.ma).toBeInstanceOf(MaConfig);
expect(config.ma.host).toBe(rawConfig.ma.host);
Expand All @@ -20,6 +19,9 @@ test("Constructor", () => {
expect(config.twitch.accessToken).toBe(rawConfig.twitch.accessToken);
expect(config.twitch.channel).toBe(rawConfig.twitch.channel);

expect(config.sacn.lockMessage).toBe(rawConfig.sacn.lockMessage);
expect(config.sacn.interface).toBe(rawConfig.sacn.interface);

expect(config.commands).toBeInstanceOf(Array);
expect(config.commands.length).toBeGreaterThan(0);

Expand All @@ -38,7 +40,7 @@ test("Constructor", () => {
expect(command.help).toBe(rawConfig.commands[index].help);

if(command.sacn) {
expect(command.sacn).toBeInstanceOf(SACNConfig);
expect(command.sacn).toBeInstanceOf(SACNLock);
expect(command.sacn.universe).toBe(rawConfig.commands[index].sacn.universe);
expect(command.sacn.channel).toBe(rawConfig.commands[index].sacn.channel);
}
Expand All @@ -60,7 +62,7 @@ test("Constructor", () => {
expect(parameter.message).toBe(rawConfig.commands[index].parameters[pIndex].message);

if(parameter.sacn) {
expect(parameter.sacn).toBeInstanceOf(SACNConfig);
expect(parameter.sacn).toBeInstanceOf(SACNLock);
expect(parameter.sacn.universe).toBe(rawConfig.commands[index].parameters[pIndex].sacn.universe);
expect(parameter.sacn.channel).toBe(rawConfig.commands[index].parameters[pIndex].sacn.channel);
}
Expand Down
5 changes: 4 additions & 1 deletion config.json.sample
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"timeout": 20,
"lockMessage": "{command} is currently locked! Please wait!",
"sacn": {
"lockMessage": "{command} is currently locked! Please wait!",
"interface": "127.0.0.1"
},
"ma": {
"host": "192.168.0.20",
"user": "administrator",
Expand Down
4 changes: 3 additions & 1 deletion config.yml.sample
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
timeout: 20
lockMessage: "{command} is currently locked! Please wait!"
sacn:
lockMessage: "{command} is currently locked! Please wait!"
interface: "127.0.0.1"
ma:
host: "192.168.0.20"
user: "administrator"
Expand Down
3 changes: 2 additions & 1 deletion docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ Find an example `config.json` [here](../config.json.sample) and an example `conf
| Property | Type | Required | Description | Default |
|:-----------------------------------|:-------|:---------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------|
| `timeout` | int | yes | The cooldown time in seconds between the execution of any command (prevents flooding/spamming). Does not apply to moderators and channel owners. | |
| `lockMessage` | string | no | The message to be sent when viewers try to execute a command that is currently locked. `{command}` is replaced by the attempted command and parameter. | `{command}` is currently locked! Please wait! |
| `ma.host` | string | yes | The IP address of the desk to connect to. | |
| `ma.user` | string | no | The GrandMA 2 user to log in with. | administrator |
| `ma.password` | string | no | The password for the user defined in `ma.user`. | admin |
| `twitch.clientId` | string | yes | The client ID obtained by Twitch. | |
| `twitch.accessToken` | string | yes | The access token obtained by Twitch. | |
| `twitch.channel` | string | yes | The Twitch channel the bot connects to. | |
| `sacn.lockMessage` | string | no | The message to be sent when viewers try to execute a command that is currently locked. `{command}` is replaced by the attempted command and parameter. | `{command}` is currently locked! Please wait! |
| `sacn.interface` | string | no | The IP address of the interface `twitch2ma` is listening on. | All interfaces |
| `commands` | array | yes | An array of commands the bot reacts to. | |
| `command.chatCommand` | string | yes | The command viewers need to use in chat without `!`. The command `lights` is reserved for viewer help. | |
| `command.consoleCommand` | string | no | The command that gets executed on the desk. | |
Expand Down
48 changes: 37 additions & 11 deletions src/lib/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import _ = require("lodash");
export class Config {

public readonly timeout: number;
public readonly lockMessage: string;
public readonly ma: MaConfig;
public readonly twitch: TwitchConfig;
public readonly sacn: SACNConfig;
public readonly commands: Array<Command>;
public readonly availableCommands: string;

Expand All @@ -26,17 +26,17 @@ export class Config {
}

this.timeout = config.timeout;
this.lockMessage = config.lockMessage;
this.ma = new MaConfig(config.ma);
this.twitch = new TwitchConfig(config.twitch);
this.sacn = config.sacn ? config.sacn : null;
this.commands = new Array<Command>();

for (const command of config.commands) {
this.commands.push(new Command(command));
}

this.availableCommands = _.map(this.commands, command => `!${command.chatCommand}`).join(", ");
this.commandMap = _.zipObject(_.map(this.commands, command => command.chatCommand), this.commands); // TODO debug
this.commandMap = _.zipObject(_.map(this.commands, command => command.chatCommand), this.commands);
}

getCommand(chatCommand: string): Command {
Expand Down Expand Up @@ -70,13 +70,20 @@ export class TwitchConfig {
}
}

export class Command {
export interface Instructions {
getChatCommand(): string;
readonly consoleCommand: string;
readonly message: string;
readonly sacn: SACNLock;
}

export class Command implements Instructions {

public readonly chatCommand: string;
public readonly consoleCommand: string;
public readonly message: string;
public readonly help: string;
public readonly sacn: SACNConfig;
public readonly sacn: SACNLock;
public readonly parameters: Array<Parameter>;
public readonly availableParameters: string;

Expand All @@ -89,7 +96,7 @@ export class Command {
this.help = command.help;

if(command.sacn) {
this.sacn = new SACNConfig(command.sacn);
this.sacn = new SACNLock(command.sacn);
}

this.parameters = new Array<Parameter>();
Expand All @@ -98,37 +105,45 @@ export class Command {
for (const parameter of command.parameters) {
this.parameters.push(new Parameter(parameter));
}
this.parameterMap = _.zipObject(_.map(this.parameters, parameter => parameter.parameter), this.parameters); // TODO debug
this.parameterMap = _.zipObject(_.map(this.parameters, parameter => parameter.parameter), this.parameters);
this.availableParameters = _.map(this.parameters, parameter => parameter.parameter).join(", ");
} else {
this.parameterMap = {};
}
}

getChatCommand(): string {
return this.chatCommand;
}

getParameter(parameter: string): Parameter {
return _.get(this.parameterMap, parameter);
}
}

export class Parameter {
export class Parameter implements Instructions {

public readonly parameter: string;
public readonly consoleCommand: string;
public readonly message: string;
public readonly sacn: SACNConfig;
public readonly sacn: SACNLock;

constructor(parameter: any) {
this.parameter = parameter.parameter;
this.consoleCommand = parameter.consoleCommand;
this.message = parameter.message;

if(parameter.sacn) {
this.sacn = new SACNConfig(parameter.sacn);
this.sacn = new SACNLock(parameter.sacn);
}
}

getChatCommand(): string {
return this.parameter;
}
}

export class SACNConfig {
export class SACNLock {

public readonly universe: number;
public readonly channel: number;
Expand All @@ -138,3 +153,14 @@ export class SACNConfig {
this.channel = sacn.channel;
}
}

export class SACNConfig {

public readonly lockMessage: string;
public readonly interface: string;

constructor(sacn: any) {
this.lockMessage = sacn.lockMessage;
this.interface = sacn.interface;
}
}
13 changes: 10 additions & 3 deletions src/lib/permissions/SACNPermission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,17 @@ export default class SACNPermission implements PermissionInstance {
}

if (this.universeData.size > 0) {
this.sACNReceiver = new Receiver({

let receiverOptions = {
universes: Array.from(this.universeData.keys()),
reuseAddr: true
});
};

if(_.isString(config.sacn.interface)) {
_.set(receiverOptions, "iface", config.sacn.interface);
}

this.sACNReceiver = new Receiver(receiverOptions);

this.sACNReceiver.on("packet", (packet: Packet) => {

Expand All @@ -54,7 +61,7 @@ export default class SACNPermission implements PermissionInstance {
let universeData = this.universeData.get(sacn.universe);
if (_.isInteger(universeData[sacn.channel - 1]) && universeData[sacn.channel - 1] < 255) {
permissionCollector.denyPermission("sacn",
`@${runtimeInformation.userName}, ${runtimeInformation.config.lockMessage}`);
`@${runtimeInformation.userName}, ${runtimeInformation.config.sacn.lockMessage}`);
}
}
}
Expand Down
22 changes: 17 additions & 5 deletions src/resources/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@
"type": "integer",
"minimum": 0
},
"lockMessage": {
"description": "The message to be sent when viewers try to execute a command that is currently locked. '{command}' is replaced by the attempted command and parameter.",
"type": "string",
"default": "{command} is currently locked! Please wait!"
},
"ma": {
"description": "GrandMA 2 telnet configuration",
"type": "object",
Expand Down Expand Up @@ -93,6 +88,23 @@
"channel"
]
},
"sacn": {
"description": "sACN specific configuration used for sACN locks.",
"type": "object",
"properties": {
"lockMessage": {
"description": "The message to be sent when viewers try to execute a command that is currently locked. '{command}' is replaced by the attempted command and parameter.",
"type": "string",
"default": "{command} is currently locked! Please wait!"
},
"interface": {
"description": "The IP address of the interface twitch2ma is listening on.",
"type": "string",
"format": "ipv4"
}
},
"additionalProperties": false
},
"commands": {
"description": "An array of commands the bot reacts to.",
"type": "array",
Expand Down

0 comments on commit 48eafa0

Please sign in to comment.