-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.js
111 lines (85 loc) · 2.51 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
var os = require('os');
const GameCommunicator = require("./gameclient.js").GameCommunicator;
const child_process = require('child_process');
const readline = require('readline');
class CLICreator {
constructor(config) {
this._events = {
"client.new": []
};
this.config = config;
}
createClients() {
for (let cliConfig of this.config["engines"]) {
if (cliConfig["enabled"] !== true) {
continue;
}
let cligc = new CLIGameCommunicator(cliConfig);
this.doEvent("client.new", { communicator: cligc, position: parseInt(cliConfig["position"]) });
}
}
on(eventName, eventHandler) {
let handlers = this._events[eventName];
if (handlers === undefined) {
throw new Error("unknown event name:" + eventName);
}
handlers.push(eventHandler);
}
doEvent(eventName, data) {
let handlers = this._events[eventName];
if (handlers === undefined) {
throw new Error("unknown event name:" + eventName);
}
for (let handler of handlers) {
handler(data);
}
}
}
class CLIGameCommunicator extends GameCommunicator {
constructor(cliConfig) {
super();
this.isClosing = false;
this.child = child_process.exec(cliConfig["command"], {
cwd: cliConfig["cwd"],
encoding: "utf8"
}, (error, stdout, stderr) => {
//nothing to do
});
this.child.stderr.on('data', data => {
console.log(`[cli client] reported an error: ${data}`);
});
this.child.on('close', (code) => {
console.log(`[cli client] process exited with code ${code}`);
this.close(code, "process exited");
});
this.rl = readline.createInterface({
input: this.child.stdout,
output: this.child.stdin
});
this.rl.on('line', (line) => {
this.doEvent("receivedMessage", line.trim());
});
this.drop_move_prefix = cliConfig["drop_move_prefix"];
}
sendMessage(message) {
if (message.startsWith("move") && this.drop_move_prefix) {
message = message.substring(5);
}
try {
this.child.stdin.write(message + os.EOL);
} catch(e) {
console.log("[cli client] error writing to stdin.");
console.log("[cli client]", e);
this.close(-1, "error writing to stdin");
}
}
close(code, reason) {
if (this.isClosing) {
return;
}
this.isClosing = true;
this.sendMessage("quit");
this.doEvent("close", { code: code, reason: "" });
}
}
module.exports = CLICreator;