bukkit-openhab-client
Version:
Client for the Minecraft bukkit-openhab-plugin
266 lines (265 loc) • 10.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Websocket = require("ws");
const events_1 = require("events");
const url_1 = require("url");
var MessageType;
(function (MessageType) {
MessageType[MessageType["PLAYER_MESSAGE"] = 1] = "PLAYER_MESSAGE";
MessageType[MessageType["SERVER_MESSAGE"] = 2] = "SERVER_MESSAGE";
MessageType[MessageType["PLAYER_COMMANDS_MESSAGE"] = 3] = "PLAYER_COMMANDS_MESSAGE";
MessageType[MessageType["SIGN_MESSAGE"] = 4] = "SIGN_MESSAGE";
MessageType[MessageType["SIGN_COMMANDS_MESSAGE"] = 5] = "SIGN_COMMANDS_MESSAGE";
})(MessageType || (MessageType = {}));
var CommandType;
(function (CommandType) {
CommandType["PLAYER_HEALTH"] = "PLAYER_HEALTH";
CommandType["PLAYER_WALKSPEED"] = "PLAYER_WALK_SPEED";
CommandType["PLAYER_LEVEL"] = "PLAYER_LEVEL";
CommandType["PLAYER_GAMEMODE"] = "PLAYER_GAME_MODE";
CommandType["PLAYER_LOCATION"] = "PLAYER_LOCATION";
CommandType["SIGN_STATE"] = "COMMAND_SIGN_ACTIVE";
})(CommandType = exports.CommandType || (exports.CommandType = {}));
var websocketState;
(function (websocketState) {
websocketState[websocketState["CONNECTING"] = 0] = "CONNECTING";
websocketState[websocketState["OPEN"] = 1] = "OPEN";
websocketState[websocketState["CLOSING"] = 2] = "CLOSING";
websocketState[websocketState["CLOSED"] = 3] = "CLOSED";
})(websocketState || (websocketState = {}));
var websocketCloseStatus;
(function (websocketCloseStatus) {
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_SUCCESS_CLOSE_STATUS"] = 1000] = "WEB_SOCKET_SUCCESS_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_ENDPOINT_UNAVAILABLE_CLOSE_STATUS"] = 1001] = "WEB_SOCKET_ENDPOINT_UNAVAILABLE_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_PROTOCOL_ERROR_CLOSE_STATUS"] = 1002] = "WEB_SOCKET_PROTOCOL_ERROR_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_INVALID_DATA_TYPE_CLOSE_STATUS"] = 1003] = "WEB_SOCKET_INVALID_DATA_TYPE_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_EMPTY_CLOSE_STATUS"] = 1005] = "WEB_SOCKET_EMPTY_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_ABORTED_CLOSE_STATUS"] = 1006] = "WEB_SOCKET_ABORTED_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_INVALID_PAYLOAD_CLOSE_STATUS"] = 1007] = "WEB_SOCKET_INVALID_PAYLOAD_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_POLICY_VIOLATION_CLOSE_STATUS"] = 1008] = "WEB_SOCKET_POLICY_VIOLATION_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_MESSAGE_TOO_BIG_CLOSE_STATUS"] = 1009] = "WEB_SOCKET_MESSAGE_TOO_BIG_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_UNSUPPORTED_EXTENSIONS_CLOSE_STATUS"] = 1010] = "WEB_SOCKET_UNSUPPORTED_EXTENSIONS_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_SERVER_ERROR_CLOSE_STATUS"] = 1011] = "WEB_SOCKET_SERVER_ERROR_CLOSE_STATUS";
websocketCloseStatus[websocketCloseStatus["WEB_SOCKET_SECURE_HANDSHAKE_ERROR_CLOSE_STATUS"] = 1015] = "WEB_SOCKET_SECURE_HANDSHAKE_ERROR_CLOSE_STATUS";
})(websocketCloseStatus || (websocketCloseStatus = {}));
const commandType = new Map([
[CommandType.PLAYER_HEALTH, 'PLAYER_HEALTH'],
[CommandType.PLAYER_WALKSPEED, 'PLAYER_WALKSPEED'],
[CommandType.PLAYER_LEVEL, 'PLAYER_LEVEL'],
[CommandType.PLAYER_GAMEMODE, 'PLAYER_GAMEMODE'],
[CommandType.PLAYER_LOCATION, 'PLAYER_LOCATION'],
[CommandType.SIGN_STATE, 'SIGN_STATE']
]);
const DEFAULT_PORT = 10692;
const DEFAULT_PATH = 'stream';
class Client extends events_1.EventEmitter {
constructor(host, options) {
super();
this.reconnectCount = 0;
options = options || {};
options.port = options.port || DEFAULT_PORT;
options.reconnect = options.reconnect !== false;
options.reconnectInterval = options.reconnectInterval || 6000;
this.options = options;
let wsURL;
try {
wsURL = new url_1.URL(DEFAULT_PATH, host);
}
catch (_a) {
wsURL = new url_1.URL(DEFAULT_PATH, `ws://${host}`);
}
wsURL.protocol = 'ws';
//@ts-ignore
wsURL.port = wsURL.port ? wsURL.port : this.options.port.toString();
this.url = wsURL;
this.connect();
}
connect() {
let ws = new Websocket(this.url.href);
this.ws = ws;
ws.on('error', err => {
return;
});
ws.on('open', () => {
this.emit('connect');
});
ws.on('close', (code, reason) => {
this.emit('close', code);
if (code === websocketCloseStatus.WEB_SOCKET_SUCCESS_CLOSE_STATUS)
return;
if (this.options.reconnect)
this.reconnect(this.options.reconnectInterval);
});
ws.on('message', msg => {
this.onMessage(JSON.parse(msg.toString()));
});
}
close() {
this.ws.close(websocketCloseStatus.WEB_SOCKET_SUCCESS_CLOSE_STATUS);
}
reconnect(timeout) {
if (this.options.maxReconnects === this.reconnectCount) {
this.close();
return;
}
const reconnect = () => {
this.emit('reconnect');
this.connect();
this.reconnectCount++;
};
if (timeout) {
setTimeout(reconnect, timeout);
}
else {
reconnect();
}
}
onMessage(data) {
switch (data.messageType) {
case MessageType.PLAYER_MESSAGE:
this.onPlayerMessage(data.message);
break;
case MessageType.SERVER_MESSAGE:
this.onServerMessage(data.message);
break;
case MessageType.SIGN_MESSAGE:
this.onSignMessage(data.message);
break;
default:
console.log(`unknown message type: ${data}`);
}
this.emit('message', data);
}
onPlayerMessage(message) {
this.emit('player', message);
}
onServerMessage(message) {
this.emit('server', message);
}
onSignMessage(message) {
this.emit('sign', message);
}
send(command, commandArgs) {
const invalidArgsError = `invalid arguments for commandType: ${commandType.get(command)}`;
switch (command) {
case CommandType.PLAYER_HEALTH:
if (isPlayerHealthCommand(commandArgs)) {
const { playerName, health } = commandArgs;
this.sendCommand(MessageType.PLAYER_COMMANDS_MESSAGE, {
type: command,
playerName,
value: health
});
}
else {
this.emit('error', invalidArgsError);
}
break;
case CommandType.PLAYER_WALKSPEED:
if (isPlayerWalkSpeedCommand(commandArgs)) {
const { playerName, walkSpeed } = commandArgs;
this.sendCommand(MessageType.PLAYER_COMMANDS_MESSAGE, {
type: command,
playerName,
value: walkSpeed
});
}
else {
this.emit('error', invalidArgsError);
}
break;
case CommandType.PLAYER_LEVEL:
if (isPlayerLevelCommand(commandArgs)) {
const { playerName, level } = commandArgs;
this.sendCommand(MessageType.PLAYER_COMMANDS_MESSAGE, {
type: command,
playerName,
value: level
});
}
else {
this.emit('error', invalidArgsError);
}
break;
case CommandType.PLAYER_GAMEMODE:
if (isPlayerGameModeCommand(commandArgs)) {
const { playerName, gameMode } = commandArgs;
this.sendCommand(MessageType.PLAYER_COMMANDS_MESSAGE, {
type: command,
playerName,
value: gameMode
});
}
else {
this.emit('error', invalidArgsError);
}
break;
case CommandType.PLAYER_LOCATION:
if (isPlayerLocationCommand(commandArgs)) {
const { playerName, location } = commandArgs;
this.sendCommand(MessageType.PLAYER_COMMANDS_MESSAGE, {
type: command,
playerName,
value: location
});
}
else {
this.emit('error', invalidArgsError);
}
break;
case CommandType.SIGN_STATE:
if (isSignStateCommand(commandArgs)) {
const { signName, state } = commandArgs;
this.sendCommand(MessageType.SIGN_COMMANDS_MESSAGE, {
type: command,
signName,
value: state
});
}
else {
this.emit('error', invalidArgsError);
}
break;
default:
this.emit('error', `unknown command type: ${command}`);
}
}
sendCommand(messageType, message) {
this.ws.send(JSON.stringify({ messageType, message }));
}
}
exports.Client = Client;
function connect(host, options) {
const client = new Client(host, options);
return client;
}
exports.connect = connect;
function isPlayerCommand(command) {
return command.playerName !== undefined;
}
function isSignCommand(command) {
return command.signName !== undefined;
}
function isPlayerHealthCommand(command) {
return (isPlayerCommand(command) &&
command.health !== undefined);
}
function isPlayerWalkSpeedCommand(command) {
return (isPlayerCommand(command) &&
command.walkSpeed !== undefined);
}
function isPlayerLevelCommand(command) {
return (isPlayerCommand(command) &&
command.level !== undefined);
}
function isPlayerGameModeCommand(command) {
return (isPlayerCommand(command) &&
command.gameMode !== undefined);
}
function isPlayerLocationCommand(command) {
return (isPlayerCommand(command) &&
command.location !== undefined);
}
function isSignStateCommand(command) {
return (isSignCommand(command) && command.state !== undefined);
}