/**
* OpenSpace WebSocket related communication method
* @constructor openspace
* @param {object} setting The configuration object
* @property {object} config The configuration object stored from the parameter
* @property {library} robot The robotjs library
* @property {library} ws The WebSocket use to connect OpenSpace backend
*/
class openspace {
constructor(setting) {
var port = setting['port']
this.config = setting['config']
this.robot = require("robotjs");
this.init()
const net = require('net');
const WebSocket = require('ws');
this.ws = new WebSocket('ws://' + 'localhost' + ':' + port);
this.ws.on('open', (connection) => {
console.log('Connected to local OpenSpace server');
});
}
/**
* Function to initial mouse control related (robotjs) variable
* @property {array-number} mouse The user's mouse x and y position
* @property {array-number} altY How many y pixels should mouse increase/decrease while holding right key (zoom in/zoom out)
* @property {array-number} latY How many y pixels should mouse increase/decrease while holding left key (rotate up/rotate down)
* @property {array-number} latX How many x pixels should mouse increase/decrease while holding left key (rotate left/rotate right)
*/
init() {
this.mouse = this.robot.getMousePos();
this.altY = 0;
this.latY = 0;
this.latX = 0;
}
/**
* Function to clear mouse control
* @param {string} type 'alt' / 'lat' / 'all'
*/
clear(type) {
var x = this.mouse.x,
y = this.mouse.y;
if(type=='alt' || type=='all') {
this.robot.mouseToggle("up","right");
this.altY = 0;
if(this.latY>0)
y = this.latY + y;
if(this.latX>0)
x = this.latX + x;
this.robot.moveMouse(x, y);
}
if(type=='lat' || type=='all') {
this.robot.mouseToggle("up","left");
this.latX = 0;
this.latY = 0;
if(this.altY>0)
y = this.altY + y;
this.robot.moveMouse(x, y);
}
}
/**
* Function to move altitude (zoom in or zoom out)
* @param {string} type -1 (zoom out) / 1 (zoom in)
* @param {string} value How many pixels should be moved
*/
moveAltitude(type,value) {
value = value*20
if(value>200) value = 200;
if(value<-200) value = -200;
var x = this.mouse.x,
y = this.mouse.y;
this.config.OpenSpaceLog['Altitude'] && console.log(value)
this.altY = value;
y = y+value + this.latY;
x = x + this.latX;
this.robot.mouseToggle("down","right");
var mouse = this.robot.getMousePos();
if(mouse.y !=y)
this.robot.dragMouse(x, y);
}
/**
* Function to move latitude and longitude (rotation)
* @param {array-number} msg A array includes {angle,distance}
* @property {object} msg.angle What is angle triggered on joystick.
* @property {library} msg.distance What is distance triggered on joystick.
*/
moveGeo(msg) {
var speed,type,multi,type2,multi2;
if(msg.angle>=0 && msg.angle<=90) {
this.config.OpenSpaceLog['Geography'] && console.log('message: latitude- N:' + msg.angle/90 + '- E:' + (90-msg.angle)/90);
speed = msg.distance;
type = 'N';
multi = msg.angle/90;
type2 = 'E';
multi2 = (90-msg.angle)/90;
} else if (msg.angle>=270) {
this.config.OpenSpaceLog['Geography'] && console.log('message: latitude- E:' + (msg.angle - 270)/90 + '- S:' + (360 - msg.angle)/90);
speed = msg.distance;
type = 'E';
multi = (msg.angle - 270)/90;
type2 = 'S';
multi2 = (360 - msg.angle)/90;
} else if (msg.angle>=180 && msg.angle<=270) {
this.config.OpenSpaceLog['Geography'] && console.log('message: latitude- S:' + (msg.angle - 180)/90 + '- W:' + (270 - msg.angle)/90);
speed = msg.distance;
type = 'S';
multi = (msg.angle - 180)/90;
type2 = 'W';
multi2 = (270 - msg.angle)/90;
} else if (msg.angle>=90 && msg.angle<=180) {
this.config.OpenSpaceLog['Geography'] && console.log('message: latitude- W:' + (msg.angle - 90)/90 + '- N:' + (180 - msg.angle)/90);
speed = msg.distance;
type = 'W';
multi = (msg.angle - 90)/90;
type2 = 'N';
multi2 = (180 - msg.angle)/90;
}
this.config.OpenSpaceLog['Geography'] && console.log('message: latitude- ' + msg.distance);
var x = this.mouse.x,
y = this.mouse.y,
base = 20;
multi = multi * 10;
multi2 = multi2 * 10;
if(type=='N') {
y = y + base*multi
} else if(type=='S') {
y = y - base*multi
} else if(type=='E') {
x = x - base*multi
} else if(type=='W') {
x = x + base*multi
}
if(type2=='N') {
y = y + base*multi2
} else if(type2=='S') {
y = y - base*multi2
} else if(type2=='E') {
x = x - base*multi2
} else if(type2=='W') {
x = x + base*multi2
}
this.latY = y - this.mouse.y
this.latX = x - this.mouse.x
y = y+this.altY;
this.robot.mouseToggle("down","left");
var mouse = this.robot.getMousePos();
if(mouse.x !=x || mouse.y !=y)
this.robot.dragMouse(x, y);
}
/**
* Function to screenshot OpenSpace, then send the screenshot to client's device
* @param {object} setting The configuration object
*/
screenshot(setting) {
var path = setting['OpenSpacePath']
var socket = setting['socketObj']
this.trigger('RenderEngine.TakeScreenshot')
const fs = require('fs');
var screenshotPath = path,
dir,
imgName,
imgTime = 500;
let latestStats = false,
latestIndex;
// Finding the latest folder
fs.readdir(screenshotPath,function(err, list){
list.forEach(function(file,index){
var stats = new Date(fs.statSync(screenshotPath+"/"+file).mtime);
this.config.OpenSpaceLog['Screenshot'] && console.log(index);
if(!latestStats) {
latestStats = stats;
latestIndex = index;
} else if(latestStats < stats) {
latestStats = stats;
latestIndex = index;
}
})
})
// Generating the image
setTimeout(
function() {
fs.readdir(screenshotPath,function(err, list){
// console.log(latestIndex)
// dir = list[list.length-1]
dir = list[latestIndex]
this.config.OpenSpaceLog['Screenshot'] && console.log(screenshotPath+"/"+dir);
fs.readdir(screenshotPath+"/"+dir,function(err, list){
imgName = list[list.length-1]
this.config.OpenSpaceLog['Screenshot'] && console.log(list[list.length-1]);
// https://stackoverflow.com/questions/26331787/socket-io-node-js-simple-example-to-send-image-files-from-server-to-client
fs.readFile(screenshotPath+"/"+dir+"/"+imgName , function(err, buf){
// it's possible to embed binary data
// within arbitrarily-complex objects
socket.emit('image', { image: true, buffer: buf.toString('base64') });
});
})
})
},imgTime)
}
/**
* Function to change OpenSpace current focus planet
* @param {string} planet The number of planet
*/
changePlanet(planet) {
this.set('NavigationHandler.OrbitalNavigator.Anchor',planet)
this.trigger('NavigationHandler.OrbitalNavigator.RetargetAnchor')
}
/**
* Function to trigger the api script
* @param {object} event The api event
*/
trigger(event) {
this.ws.send(JSON.stringify(
{
topic: 0,
type: 'trigger',
payload: {
property: event
}
}
));
}
/**
* Function to set the api value
* @param {object} event The api event
*/
set(event,result) {
this.ws.send(JSON.stringify(
{
topic: 0,
type: 'set',
payload: {
property: event, value: result
}
}
));
}
/**
* Function to run lua script
* @param {object} script The lua script
*/
lua(script) {
this.ws.send(JSON.stringify(
{
topic: 0,
type: 'luascript',
payload: {
script
}
}
));
}
}
module.exports = function(setting) {
return new openspace(setting);
}