2017-11-30 04:11:59 +00:00
|
|
|
import {Caps} from './Caps';
|
2017-12-20 17:07:10 +00:00
|
|
|
import * as LLSD from '@caspertech/llsd';
|
2017-11-30 04:11:59 +00:00
|
|
|
import * as request from 'request';
|
|
|
|
|
import * as Long from 'long';
|
|
|
|
|
import {IPAddress} from './IPAddress';
|
|
|
|
|
import {ClientEvents} from './ClientEvents';
|
|
|
|
|
import {TeleportEventType} from '../enums/TeleportEventType';
|
2017-12-14 18:22:41 +00:00
|
|
|
import {UUID} from './UUID';
|
2017-12-15 19:13:45 +00:00
|
|
|
import {Agent} from './Agent';
|
2018-10-07 17:06:54 +01:00
|
|
|
import {
|
|
|
|
|
EventQueueStateChangeEvent,
|
|
|
|
|
GroupChatEvent,
|
|
|
|
|
GroupChatSessionAgentListEvent,
|
|
|
|
|
GroupChatSessionJoinEvent,
|
|
|
|
|
TeleportEvent
|
|
|
|
|
} from '..';
|
2017-11-30 04:11:59 +00:00
|
|
|
|
|
|
|
|
export class EventQueueClient
|
|
|
|
|
{
|
|
|
|
|
caps: Caps;
|
|
|
|
|
ack?: number;
|
|
|
|
|
done = false;
|
|
|
|
|
currentRequest: request.Request | null = null;
|
|
|
|
|
private clientEvents: ClientEvents;
|
2017-12-15 19:13:45 +00:00
|
|
|
private agent: Agent;
|
2017-11-30 04:11:59 +00:00
|
|
|
|
2017-12-15 19:13:45 +00:00
|
|
|
constructor(agent: Agent, caps: Caps, clientEvents: ClientEvents)
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2017-12-15 19:13:45 +00:00
|
|
|
this.agent = agent;
|
2017-11-30 04:11:59 +00:00
|
|
|
this.clientEvents = clientEvents;
|
|
|
|
|
this.caps = caps;
|
|
|
|
|
this.Get();
|
2018-10-07 17:06:54 +01:00
|
|
|
const state = new EventQueueStateChangeEvent();
|
|
|
|
|
state.active = true;
|
|
|
|
|
this.clientEvents.onEventQueueStateChange.next(state);
|
2017-11-30 04:11:59 +00:00
|
|
|
}
|
|
|
|
|
shutdown()
|
|
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
// We must ACK any outstanding events
|
|
|
|
|
this.done = true;
|
2017-11-30 04:11:59 +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 EventQueueStateChangeEvent();
|
|
|
|
|
state.active = false;
|
|
|
|
|
this.clientEvents.onEventQueueStateChange.next(state);
|
|
|
|
|
});
|
2017-11-30 04:11:59 +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-11-30 04:11:59 +00:00
|
|
|
this.capsRequestXML('EventQueueGet', req).then((data) =>
|
|
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
if (data['id'])
|
|
|
|
|
{
|
|
|
|
|
this.ack = data['id'];
|
|
|
|
|
}
|
|
|
|
|
else
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
this.ack = undefined;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (data['events'])
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
data['events'].forEach((event: any) =>
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
try
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
if (event['message'])
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
// noinspection TsLint
|
|
|
|
|
switch (event['message'])
|
|
|
|
|
{
|
|
|
|
|
case 'EnableSimulator':
|
2017-11-30 04:11:59 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
/*
|
|
|
|
|
{
|
|
|
|
|
"body": {
|
|
|
|
|
"SimulatorInfo": [
|
|
|
|
|
{
|
|
|
|
|
"Handle": "AALoAAAECwA=",
|
|
|
|
|
"IP": "2FIqRA==",
|
|
|
|
|
"Port": 13029
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
"message": "EnableSimulator"
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 'ParcelProperties':
|
|
|
|
|
/*
|
|
|
|
|
{
|
|
|
|
|
"body": {
|
|
|
|
|
"AgeVerificationBlock": [
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
|
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
"RegionDenyAgeUnverified": true
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"MediaData": [
|
|
|
|
|
{
|
|
|
|
|
"MediaDesc": "",
|
|
|
|
|
"MediaHeight": 0,
|
|
|
|
|
"MediaLoop": 0,
|
|
|
|
|
"MediaType": "text/html",
|
|
|
|
|
"MediaWidth": 0,
|
|
|
|
|
"ObscureMedia": 0,
|
|
|
|
|
"ObscureMusic": 0
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"ParcelData": [
|
|
|
|
|
{
|
|
|
|
|
"AABBMax": [
|
|
|
|
|
256,
|
|
|
|
|
256,
|
|
|
|
|
50
|
|
|
|
|
],
|
|
|
|
|
"AABBMin": [
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0
|
|
|
|
|
],
|
|
|
|
|
"AnyAVSounds": true,
|
|
|
|
|
"Area": 65536,
|
|
|
|
|
"AuctionID": "AAAAAA==",
|
|
|
|
|
"AuthBuyerID": "00000000-0000-0000-0000-000000000000",
|
|
|
|
|
"Bitmap": "/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8=",
|
|
|
|
|
"Category": 0,
|
|
|
|
|
"ClaimDate": 1333505995,
|
|
|
|
|
"ClaimPrice": 0,
|
|
|
|
|
"Desc": "adoption parent furry parent teen twin cub neko pets adult elf vamp toddleedoo baby child panel brother sister numbers meshmerized gacha adoptions adopt family mesh skin shape camp ngi youthspot foster kids mall zoo train kid primbay\ndupli
|
|
|
|
|
city onlinker",
|
|
|
|
|
"GroupAVSounds": true,
|
|
|
|
|
"GroupID": "f2b75b49-8ebc-2a9c-f345-aa2f91adc908",
|
|
|
|
|
"GroupPrims": 18677,
|
|
|
|
|
"IsGroupOwned": true,
|
|
|
|
|
"LandingType": 2,
|
|
|
|
|
"LocalID": 15,
|
|
|
|
|
"MaxPrims": 30000,
|
|
|
|
|
"MediaAutoScale": 1,
|
|
|
|
|
"MediaID": "6bd35c06-2b24-a83e-03f6-f547c65c8556",
|
|
|
|
|
"MediaURL": "",
|
|
|
|
|
"MusicURL": "http://142.4.209.63:8071",
|
|
|
|
|
"Name": "Next Gen Inc. Adoption Agency on the :::: KiD GRiD :::",
|
|
|
|
|
"OtherCleanTime": 0,
|
|
|
|
|
"OtherCount": 4096,
|
|
|
|
|
"OtherPrims": 312,
|
|
|
|
|
"OwnerID": "f2b75b49-8ebc-2a9c-f345-aa2f91adc908",
|
|
|
|
|
"OwnerPrims": 3,
|
|
|
|
|
"ParcelFlags": "NiAUSw==",
|
|
|
|
|
"ParcelPrimBonus": 1,
|
|
|
|
|
"PassHours": 10,
|
|
|
|
|
"PassPrice": 10,
|
|
|
|
|
"PublicCount": 0,
|
|
|
|
|
"RegionDenyAnonymous": true,
|
|
|
|
|
"RegionDenyIdentified": true,
|
|
|
|
|
"RegionDenyTransacted": true,
|
|
|
|
|
"RegionPushOverride": true,
|
|
|
|
|
"RentPrice": 0,
|
|
|
|
|
"RequestResult": 0,
|
|
|
|
|
"SalePrice": 1,
|
|
|
|
|
"SeeAVs": true,
|
|
|
|
|
"SelectedPrims": 1,
|
|
|
|
|
"SelfCount": 0,
|
|
|
|
|
"SequenceID": 0,
|
|
|
|
|
"SimWideMaxPrims": 30000,
|
|
|
|
|
"SimWideTotalPrims": 18993,
|
|
|
|
|
"SnapSelection": true,
|
|
|
|
|
"SnapshotID": "09c4101a-9406-2501-b9b7-dbb60260fd7a",
|
|
|
|
|
"Status": 0,
|
|
|
|
|
"TotalPrims": 18993,
|
|
|
|
|
"UserLocation": [
|
|
|
|
|
131.48399353027344,
|
|
|
|
|
171.41600036621094,
|
|
|
|
|
21.544700622558594
|
|
|
|
|
],
|
|
|
|
|
"UserLookAt": [
|
|
|
|
|
0.0325143001973629,
|
|
|
|
|
-0.9994710087776184,
|
|
|
|
|
0
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"RegionAllowAccessBlock": [
|
|
|
|
|
{
|
|
|
|
|
"RegionAllowAccessOverride": true
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
"message": "ParcelProperties"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
break;
|
|
|
|
|
case 'AgentGroupDataUpdate':
|
|
|
|
|
/*
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
|
|
|
|
"body": {
|
2018-10-09 20:03:28 +01:00
|
|
|
"AgentData": [
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
"AgentID": "49cc9041-5c53-4c1c-8490-e6bb84cdbacd"
|
2017-11-30 04:11:59 +00:00
|
|
|
}
|
|
|
|
|
],
|
2018-10-09 20:03:28 +01:00
|
|
|
"GroupData": [
|
|
|
|
|
{
|
|
|
|
|
"AcceptNotices": true,
|
|
|
|
|
"Contribution": 0,
|
|
|
|
|
"GroupID": "06459c46-069f-4de1-c297-c966bd55ab91",
|
|
|
|
|
"GroupInsigniaID": "8dacb5c9-80bc-aae4-6a12-d792b6eb7dc4",
|
|
|
|
|
"GroupName": "Jez Ember Estates",
|
|
|
|
|
"GroupPowers": "AAAgAAQAAAA="
|
|
|
|
|
},
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
"AcceptNotices": true,
|
|
|
|
|
"Contribution": 0,
|
|
|
|
|
"GroupID": "539b5be0-bb18-d0ef-6c07-3326e0130aaf",
|
|
|
|
|
"GroupInsigniaID": "7d7d0b4a-bf5b-dc51-3869-5e0eaa6ad41d",
|
|
|
|
|
"GroupName": "**BOY BEARS MALL**",
|
|
|
|
|
"GroupPowers": "AAAIABgBAAA="
|
2017-11-30 04:11:59 +00:00
|
|
|
}
|
|
|
|
|
],
|
2018-10-09 20:03:28 +01:00
|
|
|
"NewGroupData": [
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
"ListInProfile": true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"ListInProfile": true
|
2017-11-30 04:11:59 +00:00
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
2018-10-09 20:03:28 +01:00
|
|
|
"message": "AgentGroupDataUpdate"
|
2017-11-30 04:11:59 +00:00
|
|
|
}
|
|
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
*/
|
|
|
|
|
break;
|
|
|
|
|
case 'AgentStateUpdate':
|
|
|
|
|
/*
|
2017-11-30 04:11:59 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
{
|
|
|
|
|
"body": {
|
|
|
|
|
"can_modify_navmesh": true,
|
|
|
|
|
"has_modified_navmesh": true,
|
|
|
|
|
"preferences": {
|
|
|
|
|
"access_prefs": {
|
|
|
|
|
"max": "PG"
|
|
|
|
|
},
|
|
|
|
|
"default_object_perm_masks": {
|
|
|
|
|
"Everyone": 0,
|
|
|
|
|
"Group": 0,
|
|
|
|
|
"NextOwner": 532480
|
|
|
|
|
},
|
|
|
|
|
"god_level": 0,
|
|
|
|
|
"hover_height": 0,
|
|
|
|
|
"language": "",
|
|
|
|
|
"language_is_public": true
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
"message": "AgentStateUpdate"
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
break;
|
|
|
|
|
case 'TeleportFailed':
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
const tpEvent = new TeleportEvent();
|
|
|
|
|
tpEvent.message = event['body']['Info'][0]['Reason'];
|
|
|
|
|
tpEvent.eventType = TeleportEventType.TeleportFailed;
|
|
|
|
|
tpEvent.simIP = '';
|
|
|
|
|
tpEvent.simPort = 0;
|
|
|
|
|
tpEvent.seedCapability = '';
|
2017-11-30 04:11:59 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
this.clientEvents.onTeleportEvent.next(tpEvent);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "ChatterBoxSessionStartReply":
|
2017-12-15 19:13:45 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
if (event['body'])
|
2017-12-15 19:13:45 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
const gcsje = new GroupChatSessionJoinEvent();
|
|
|
|
|
gcsje.sessionID = new UUID(event['body']['session_id'].toString());
|
|
|
|
|
gcsje.success = event['body']['success'];
|
|
|
|
|
if (gcsje.success)
|
|
|
|
|
{
|
|
|
|
|
this.agent.addChatSession(gcsje.sessionID);
|
|
|
|
|
}
|
|
|
|
|
this.clientEvents.onGroupChatSessionJoin.next(gcsje);
|
2017-12-15 19:13:45 +00:00
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
break;
|
2017-12-15 19:13:45 +00:00
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
case 'ChatterBoxInvitation':
|
2017-12-14 18:22:41 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
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'];
|
2017-12-15 21:28:45 +00:00
|
|
|
|
2017-12-14 18:22:41 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
const groupChatEvent = new GroupChatEvent();
|
|
|
|
|
groupChatEvent.from = new UUID(messageParams['from_id'].toString());
|
|
|
|
|
groupChatEvent.fromName = messageParams['from_name'];
|
|
|
|
|
groupChatEvent.groupID = new UUID(messageParams['id'].toString());
|
|
|
|
|
groupChatEvent.message = messageParams['message'];
|
2017-12-14 18:22:41 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
const requestedFolders = {
|
|
|
|
|
'method': 'accept invitation',
|
|
|
|
|
'session-id': imSessionID
|
|
|
|
|
};
|
|
|
|
|
this.caps.capsRequestXML('ChatSessionRequest', requestedFolders).then((ignore: any) =>
|
|
|
|
|
{
|
|
|
|
|
this.agent.addChatSession(groupChatEvent.groupID);
|
2017-12-15 19:13:45 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
const gcsje = new GroupChatSessionJoinEvent();
|
|
|
|
|
gcsje.sessionID = groupChatEvent.groupID;
|
|
|
|
|
gcsje.success = true;
|
|
|
|
|
this.clientEvents.onGroupChatSessionJoin.next(gcsje);
|
|
|
|
|
this.clientEvents.onGroupChat.next(groupChatEvent);
|
|
|
|
|
}).catch((err) =>
|
|
|
|
|
{
|
|
|
|
|
console.error(err);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-12-14 18:22:41 +00:00
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
case 'ChatterBoxSessionAgentListUpdates':
|
2017-12-19 17:58:25 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
if (event['body'])
|
2017-12-19 17:58:25 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
if (event['body']['agent_updates'])
|
2017-12-19 17:58:25 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
Object.keys(event['body']['agent_updates']).forEach((agentUpdate) =>
|
2017-12-19 17:58:25 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
const updObj = event['body']['agent_updates'][agentUpdate];
|
|
|
|
|
const gcsale = new GroupChatSessionAgentListEvent();
|
|
|
|
|
gcsale.agentID = new UUID(agentUpdate);
|
|
|
|
|
gcsale.groupID = new 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);
|
|
|
|
|
});
|
|
|
|
|
}
|
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 'TeleportFinish':
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
const info = event['body']['Info'][0];
|
|
|
|
|
if (info['LocationID'])
|
|
|
|
|
{
|
|
|
|
|
info['LocationID'] = Buffer.from(info['LocationID'].toArray()).readUInt32LE(0);
|
2017-11-30 04:11:59 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
const regionHandleBuf = Buffer.from(info['RegionHandle'].toArray());
|
|
|
|
|
info['RegionHandle'] = new Long(regionHandleBuf.readUInt32LE(0), regionHandleBuf.readUInt32LE(4), true);
|
2017-11-30 04:11:59 +00:00
|
|
|
|
|
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
info['SimIP'] = new IPAddress(Buffer.from(info['SimIP'].toArray()), 0).toString();
|
2017-11-30 04:11:59 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
info['TeleportFlags'] = Buffer.from(info['TeleportFlags'].toArray()).readUInt32LE(0);
|
2017-11-30 04:11:59 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
const tpEvent = new TeleportEvent();
|
|
|
|
|
tpEvent.message = '';
|
|
|
|
|
tpEvent.eventType = TeleportEventType.TeleportCompleted;
|
|
|
|
|
tpEvent.simIP = info['SimIP'];
|
|
|
|
|
tpEvent.simPort = info['SimPort'];
|
|
|
|
|
tpEvent.seedCapability = info['SeedCapability'];
|
2017-11-30 04:11:59 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
this.clientEvents.onTeleportEvent.next(tpEvent);
|
|
|
|
|
}
|
2017-11-30 04:11:59 +00:00
|
|
|
|
2018-10-09 20:03:28 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
console.log('Unhandled event:');
|
|
|
|
|
console.log(JSON.stringify(event, null, 4));
|
2017-11-30 04:11:59 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
catch (erro)
|
|
|
|
|
{
|
|
|
|
|
console.error('Error handling cap');
|
|
|
|
|
console.error(erro);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2017-11-30 04:11:59 +00:00
|
|
|
}
|
2018-10-09 20:03:28 +01:00
|
|
|
catch (error)
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
console.error(error);
|
2017-11-30 04:11:59 +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-11-30 04:11:59 +00:00
|
|
|
{
|
2018-10-07 17:06:54 +01:00
|
|
|
// This is the normal request timeout, so reconnect immediately
|
2017-11-30 04:11:59 +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)
|
2018-10-07 17:06:54 +01:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
console.error('Event queue aborted after ' + time + 'ms. Reconnecting in 5 seconds');
|
|
|
|
|
|
|
|
|
|
// Wait 5 seconds before retrying
|
|
|
|
|
setTimeout(() =>
|
2018-10-07 17:06:54 +01:00
|
|
|
{
|
2018-10-09 20:03:28 +01:00
|
|
|
if (!this.done)
|
|
|
|
|
{
|
|
|
|
|
this.Get();
|
|
|
|
|
}
|
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
2018-10-07 17:06:54 +01:00
|
|
|
}
|
2017-11-30 04:11:59 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
request(url: string, data: string, contentType: string): Promise<string>
|
|
|
|
|
{
|
|
|
|
|
return new Promise<string>((resolve, reject) =>
|
|
|
|
|
{
|
|
|
|
|
this.currentRequest = request({
|
|
|
|
|
'headers': {
|
|
|
|
|
'Content-Length': data.length,
|
|
|
|
|
'Content-Type': contentType
|
|
|
|
|
},
|
|
|
|
|
'uri': url,
|
|
|
|
|
'body': data,
|
|
|
|
|
'rejectUnauthorized': false,
|
|
|
|
|
'method': 'POST',
|
|
|
|
|
'timeout': 1800000 // Super long timeout
|
|
|
|
|
}, (err, res, body) =>
|
|
|
|
|
{
|
|
|
|
|
this.currentRequest = null;
|
|
|
|
|
if (err)
|
|
|
|
|
{
|
|
|
|
|
reject(err);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
resolve(body);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-07 17:06:54 +01:00
|
|
|
capsRequestXML(capability: string, data: any, attempt: number = 0): Promise<any>
|
2017-11-30 04:11:59 +00:00
|
|
|
{
|
|
|
|
|
return new Promise<any>((resolve, reject) =>
|
|
|
|
|
{
|
|
|
|
|
this.caps.getCapability(capability).then((url) =>
|
|
|
|
|
{
|
|
|
|
|
const serializedData = LLSD.LLSD.formatXML(data);
|
|
|
|
|
this.request(url, serializedData, 'application/llsd+xml').then((body: string) =>
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (body.indexOf('<llsd>') !== -1)
|
|
|
|
|
{
|
|
|
|
|
const parsed = LLSD.LLSD.parseXML(body);
|
|
|
|
|
resolve(parsed);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-10-07 17:06:54 +01:00
|
|
|
// Retry caps request three times before giving up
|
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-11-30 04:11:59 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (error)
|
|
|
|
|
{
|
|
|
|
|
reject(error);
|
|
|
|
|
}
|
|
|
|
|
}).catch((err) =>
|
|
|
|
|
{
|
|
|
|
|
reject(err);
|
|
|
|
|
});
|
|
|
|
|
}).catch((err) =>
|
|
|
|
|
{
|
|
|
|
|
reject(err);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
2018-10-07 17:06:54 +01:00
|
|
|
}
|