2017-12-13 15:23:50 +00:00
|
|
|
"use strict";
|
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
2017-12-20 17:07:10 +00:00
|
|
|
const LLSD = require("@caspertech/llsd");
|
2017-12-13 15:23:50 +00:00
|
|
|
const request = require("request");
|
|
|
|
|
const Long = require("long");
|
|
|
|
|
const IPAddress_1 = require("./IPAddress");
|
|
|
|
|
const TeleportEventType_1 = require("../enums/TeleportEventType");
|
2017-12-14 18:22:41 +00:00
|
|
|
const UUID_1 = require("./UUID");
|
2018-10-07 17:06:54 +01:00
|
|
|
const __1 = require("..");
|
2017-12-13 15:23:50 +00:00
|
|
|
class EventQueueClient {
|
2017-12-15 19:13:45 +00:00
|
|
|
constructor(agent, caps, clientEvents) {
|
2017-12-13 15:23:50 +00:00
|
|
|
this.done = false;
|
|
|
|
|
this.currentRequest = null;
|
2017-12-15 19:13:45 +00:00
|
|
|
this.agent = agent;
|
2017-12-13 15:23:50 +00:00
|
|
|
this.clientEvents = clientEvents;
|
|
|
|
|
this.caps = caps;
|
|
|
|
|
this.Get();
|
2018-10-07 17:06:54 +01:00
|
|
|
const state = new __1.EventQueueStateChangeEvent();
|
|
|
|
|
state.active = true;
|
|
|
|
|
this.clientEvents.onEventQueueStateChange.next(state);
|
2017-12-13 15:23:50 +00:00
|
|
|
}
|
|
|
|
|
shutdown() {
|
2018-10-09 20:03:28 +01:00
|
|
|
this.done = true;
|
2017-12-13 15:23:50 +00:00
|
|
|
if (this.currentRequest !== null) {
|
|
|
|
|
this.currentRequest.abort();
|
|
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
const req = {
|
|
|
|
|
'ack': this.ack,
|
|
|
|
|
'done': true
|
|
|
|
|
};
|
|
|
|
|
this.capsRequestXML('EventQueueGet', req).then((data) => {
|
|
|
|
|
const state = new __1.EventQueueStateChangeEvent();
|
|
|
|
|
state.active = false;
|
|
|
|
|
this.clientEvents.onEventQueueStateChange.next(state);
|
|
|
|
|
});
|
2017-12-13 15:23:50 +00:00
|
|
|
}
|
|
|
|
|
Get() {
|
|
|
|
|
const req = {
|
|
|
|
|
'ack': this.ack,
|
|
|
|
|
'done': this.done
|
|
|
|
|
};
|
2018-10-07 17:06:54 +01:00
|
|
|
const startTime = new Date().getTime();
|
2017-12-13 15:23:50 +00:00
|
|
|
this.capsRequestXML('EventQueueGet', req).then((data) => {
|
2018-10-09 20:03:28 +01:00
|
|
|
if (data['id']) {
|
|
|
|
|
this.ack = data['id'];
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
this.ack = undefined;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
if (data['events']) {
|
|
|
|
|
data['events'].forEach((event) => {
|
|
|
|
|
try {
|
|
|
|
|
if (event['message']) {
|
|
|
|
|
switch (event['message']) {
|
|
|
|
|
case 'EnableSimulator':
|
2017-12-13 15:23:50 +00:00
|
|
|
break;
|
2018-10-09 20:03:28 +01:00
|
|
|
case 'ParcelProperties':
|
2017-12-15 19:13:45 +00:00
|
|
|
break;
|
2018-10-09 20:03:28 +01:00
|
|
|
case 'AgentGroupDataUpdate':
|
|
|
|
|
break;
|
|
|
|
|
case 'AgentStateUpdate':
|
|
|
|
|
break;
|
|
|
|
|
case 'TeleportFailed':
|
|
|
|
|
{
|
|
|
|
|
const tpEvent = new __1.TeleportEvent();
|
|
|
|
|
tpEvent.message = event['body']['Info'][0]['Reason'];
|
|
|
|
|
tpEvent.eventType = TeleportEventType_1.TeleportEventType.TeleportFailed;
|
|
|
|
|
tpEvent.simIP = '';
|
|
|
|
|
tpEvent.simPort = 0;
|
|
|
|
|
tpEvent.seedCapability = '';
|
|
|
|
|
this.clientEvents.onTeleportEvent.next(tpEvent);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "ChatterBoxSessionStartReply":
|
|
|
|
|
{
|
|
|
|
|
if (event['body']) {
|
2018-10-07 17:06:54 +01:00
|
|
|
const gcsje = new __1.GroupChatSessionJoinEvent();
|
2018-10-09 20:03:28 +01:00
|
|
|
gcsje.sessionID = new UUID_1.UUID(event['body']['session_id'].toString());
|
|
|
|
|
gcsje.success = event['body']['success'];
|
|
|
|
|
if (gcsje.success) {
|
|
|
|
|
this.agent.addChatSession(gcsje.sessionID);
|
|
|
|
|
}
|
2017-12-15 19:13:45 +00:00
|
|
|
this.clientEvents.onGroupChatSessionJoin.next(gcsje);
|
2018-10-09 20:03:28 +01:00
|
|
|
}
|
|
|
|
|
break;
|
2017-12-14 18:22:41 +00:00
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
case 'ChatterBoxInvitation':
|
|
|
|
|
{
|
|
|
|
|
if (event['body'] && event['body']['instantmessage'] && event['body']['instantmessage']['message_params'] && event['body']['instantmessage']['message_params']['id']) {
|
|
|
|
|
const messageParams = event['body']['instantmessage']['message_params'];
|
|
|
|
|
const imSessionID = messageParams['id'];
|
|
|
|
|
const groupChatEvent = new __1.GroupChatEvent();
|
|
|
|
|
groupChatEvent.from = new UUID_1.UUID(messageParams['from_id'].toString());
|
|
|
|
|
groupChatEvent.fromName = messageParams['from_name'];
|
|
|
|
|
groupChatEvent.groupID = new UUID_1.UUID(messageParams['id'].toString());
|
|
|
|
|
groupChatEvent.message = messageParams['message'];
|
|
|
|
|
const requestedFolders = {
|
|
|
|
|
'method': 'accept invitation',
|
|
|
|
|
'session-id': imSessionID
|
|
|
|
|
};
|
|
|
|
|
this.caps.capsRequestXML('ChatSessionRequest', requestedFolders).then((ignore) => {
|
|
|
|
|
this.agent.addChatSession(groupChatEvent.groupID);
|
|
|
|
|
const gcsje = new __1.GroupChatSessionJoinEvent();
|
|
|
|
|
gcsje.sessionID = groupChatEvent.groupID;
|
|
|
|
|
gcsje.success = true;
|
|
|
|
|
this.clientEvents.onGroupChatSessionJoin.next(gcsje);
|
|
|
|
|
this.clientEvents.onGroupChat.next(groupChatEvent);
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
console.error(err);
|
2017-12-19 17:58:25 +00:00
|
|
|
});
|
|
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
break;
|
2017-12-19 17:58:25 +00:00
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
case 'ChatterBoxSessionAgentListUpdates':
|
|
|
|
|
{
|
|
|
|
|
if (event['body']) {
|
|
|
|
|
if (event['body']['agent_updates']) {
|
|
|
|
|
Object.keys(event['body']['agent_updates']).forEach((agentUpdate) => {
|
|
|
|
|
const updObj = event['body']['agent_updates'][agentUpdate];
|
|
|
|
|
const gcsale = new __1.GroupChatSessionAgentListEvent();
|
|
|
|
|
gcsale.agentID = new UUID_1.UUID(agentUpdate);
|
|
|
|
|
gcsale.groupID = new UUID_1.UUID(event['body']['session_id'].toString());
|
|
|
|
|
gcsale.canVoiceChat = false;
|
|
|
|
|
gcsale.isModerator = false;
|
|
|
|
|
gcsale.entered = (updObj['transition'] === 'ENTER');
|
|
|
|
|
if (updObj['can_voice_chat'] === true) {
|
|
|
|
|
gcsale.canVoiceChat = true;
|
|
|
|
|
}
|
|
|
|
|
if (updObj['is_moderator'] === true) {
|
|
|
|
|
gcsale.isModerator = true;
|
|
|
|
|
}
|
|
|
|
|
this.clientEvents.onGroupChatAgentListUpdate.next(gcsale);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-12-13 15:23:50 +00:00
|
|
|
}
|
2018-10-19 16:30:09 +01:00
|
|
|
case 'ObjectPhysicsProperties':
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
case 'TeleportFinish':
|
|
|
|
|
{
|
|
|
|
|
const info = event['body']['Info'][0];
|
|
|
|
|
if (info['LocationID']) {
|
|
|
|
|
info['LocationID'] = Buffer.from(info['LocationID'].toArray()).readUInt32LE(0);
|
|
|
|
|
const regionHandleBuf = Buffer.from(info['RegionHandle'].toArray());
|
|
|
|
|
info['RegionHandle'] = new Long(regionHandleBuf.readUInt32LE(0), regionHandleBuf.readUInt32LE(4), true);
|
|
|
|
|
info['SimIP'] = new IPAddress_1.IPAddress(Buffer.from(info['SimIP'].toArray()), 0).toString();
|
|
|
|
|
info['TeleportFlags'] = Buffer.from(info['TeleportFlags'].toArray()).readUInt32LE(0);
|
|
|
|
|
const tpEvent = new __1.TeleportEvent();
|
|
|
|
|
tpEvent.message = '';
|
|
|
|
|
tpEvent.eventType = TeleportEventType_1.TeleportEventType.TeleportCompleted;
|
|
|
|
|
tpEvent.simIP = info['SimIP'];
|
|
|
|
|
tpEvent.simPort = info['SimPort'];
|
|
|
|
|
tpEvent.seedCapability = info['SeedCapability'];
|
|
|
|
|
this.clientEvents.onTeleportEvent.next(tpEvent);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
console.log('Unhandled event:');
|
|
|
|
|
console.log(JSON.stringify(event, null, 4));
|
|
|
|
|
}
|
2017-12-13 15:23:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
catch (erro) {
|
|
|
|
|
console.error('Error handling cap');
|
|
|
|
|
console.error(erro);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2017-12-13 15:23:50 +00:00
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
catch (error) {
|
|
|
|
|
console.error(error);
|
2017-12-13 15:23:50 +00:00
|
|
|
}
|
|
|
|
|
if (!this.done) {
|
|
|
|
|
this.Get();
|
|
|
|
|
}
|
|
|
|
|
}).catch((err) => {
|
2018-10-07 17:06:54 +01:00
|
|
|
const time = (new Date().getTime()) - startTime;
|
|
|
|
|
if (time > 30000) {
|
2017-12-13 15:23:50 +00:00
|
|
|
if (!this.done) {
|
|
|
|
|
this.Get();
|
|
|
|
|
}
|
2018-10-07 17:06:54 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2018-10-09 20:03:28 +01:00
|
|
|
if (!this.done) {
|
|
|
|
|
console.error('Event queue aborted after ' + time + 'ms. Reconnecting in 5 seconds');
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
if (!this.done) {
|
|
|
|
|
this.Get();
|
|
|
|
|
}
|
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
2018-10-07 17:06:54 +01:00
|
|
|
}
|
2017-12-13 15:23:50 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
request(url, data, contentType) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
this.currentRequest = request({
|
|
|
|
|
'headers': {
|
|
|
|
|
'Content-Length': data.length,
|
|
|
|
|
'Content-Type': contentType
|
|
|
|
|
},
|
|
|
|
|
'uri': url,
|
|
|
|
|
'body': data,
|
|
|
|
|
'rejectUnauthorized': false,
|
|
|
|
|
'method': 'POST',
|
|
|
|
|
'timeout': 1800000
|
|
|
|
|
}, (err, res, body) => {
|
|
|
|
|
this.currentRequest = null;
|
|
|
|
|
if (err) {
|
|
|
|
|
reject(err);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
resolve(body);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
2018-10-07 17:06:54 +01:00
|
|
|
capsRequestXML(capability, data, attempt = 0) {
|
2017-12-13 15:23:50 +00:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
this.caps.getCapability(capability).then((url) => {
|
|
|
|
|
const serializedData = LLSD.LLSD.formatXML(data);
|
|
|
|
|
this.request(url, serializedData, 'application/llsd+xml').then((body) => {
|
|
|
|
|
try {
|
|
|
|
|
if (body.indexOf('<llsd>') !== -1) {
|
|
|
|
|
const parsed = LLSD.LLSD.parseXML(body);
|
|
|
|
|
resolve(parsed);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2018-10-09 20:03:28 +01:00
|
|
|
if (attempt < 3 && capability !== 'EventQueueGet') {
|
2018-10-07 17:06:54 +01:00
|
|
|
return this.capsRequestXML(capability, data, ++attempt);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
reject(new Error('Not an LLSD response, capability: ' + capability));
|
|
|
|
|
}
|
2017-12-13 15:23:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (error) {
|
|
|
|
|
reject(error);
|
|
|
|
|
}
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
reject(err);
|
|
|
|
|
});
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
reject(err);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
exports.EventQueueClient = EventQueueClient;
|
|
|
|
|
//# sourceMappingURL=EventQueueClient.js.map
|