- Add a waitForEventQueue promise, to get rid of the 5 second fudge from testBot.js - Async'ify testBot.js - Complete plumbing for Hint's ScriptDialog support (see changes to ScriptDialogEvent.ts and Comms.ts - Fix: The EventQueue was pausing for 5 seconds every 30 seconds
268 lines
13 KiB
JavaScript
268 lines
13 KiB
JavaScript
"use strict";
|
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const LoginHandler_1 = require("./LoginHandler");
|
|
const PacketFlags_1 = require("./enums/PacketFlags");
|
|
const UseCircuitCode_1 = require("./classes/messages/UseCircuitCode");
|
|
const CompleteAgentMovement_1 = require("./classes/messages/CompleteAgentMovement");
|
|
const Message_1 = require("./enums/Message");
|
|
const LogoutRequest_1 = require("./classes/messages/LogoutRequest");
|
|
const Utils_1 = require("./classes/Utils");
|
|
const RegionHandshakeReply_1 = require("./classes/messages/RegionHandshakeReply");
|
|
const RegionProtocolFlags_1 = require("./enums/RegionProtocolFlags");
|
|
const AgentDataUpdateRequest_1 = require("./classes/messages/AgentDataUpdateRequest");
|
|
const TeleportEvent_1 = require("./events/TeleportEvent");
|
|
const ClientEvents_1 = require("./classes/ClientEvents");
|
|
const TeleportEventType_1 = require("./enums/TeleportEventType");
|
|
const ClientCommands_1 = require("./classes/ClientCommands");
|
|
const DisconnectEvent_1 = require("./events/DisconnectEvent");
|
|
const StartPingCheck_1 = require("./classes/messages/StartPingCheck");
|
|
const FilterResponse_1 = require("./enums/FilterResponse");
|
|
const UUID_1 = require("./classes/UUID");
|
|
class Bot {
|
|
constructor(login, options) {
|
|
this.ping = null;
|
|
this.pingNumber = 0;
|
|
this.lastSuccessfulPing = 0;
|
|
this.circuitSubscription = null;
|
|
this.eventQueueRunning = false;
|
|
this.eventQueueWaits = {};
|
|
this.clientEvents = new ClientEvents_1.ClientEvents();
|
|
this.loginParams = login;
|
|
this.options = options;
|
|
this.clientEvents.onEventQueueStateChange.subscribe((evt) => {
|
|
this.eventQueueRunning = evt.active;
|
|
for (const waitID of Object.keys(this.eventQueueWaits)) {
|
|
try {
|
|
clearTimeout(this.eventQueueWaits[waitID].timer);
|
|
this.eventQueueWaits[waitID].resolve();
|
|
delete this.eventQueueWaits[waitID];
|
|
}
|
|
catch (ignore) { }
|
|
}
|
|
});
|
|
}
|
|
login() {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const loginHandler = new LoginHandler_1.LoginHandler(this.clientEvents, this.options);
|
|
const response = yield loginHandler.Login(this.loginParams);
|
|
this.currentRegion = response.region;
|
|
this.agent = response.agent;
|
|
this.clientCommands = new ClientCommands_1.ClientCommands(response.region, response.agent, this);
|
|
return response;
|
|
});
|
|
}
|
|
changeRegion(region) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
this.currentRegion = region;
|
|
this.clientCommands = new ClientCommands_1.ClientCommands(this.currentRegion, this.agent, this);
|
|
if (this.ping !== null) {
|
|
clearInterval(this.ping);
|
|
this.ping = null;
|
|
}
|
|
yield this.connectToSim();
|
|
});
|
|
}
|
|
waitForEventQueue(timeout = 1000) {
|
|
return new Promise((resolve, reject) => {
|
|
if (this.eventQueueRunning) {
|
|
resolve();
|
|
}
|
|
else {
|
|
const waitID = UUID_1.UUID.random().toString();
|
|
const newWait = {
|
|
'resolve': resolve
|
|
};
|
|
newWait.timer = setTimeout(() => {
|
|
delete this.eventQueueWaits[waitID];
|
|
reject(new Error('Timeout'));
|
|
}, timeout);
|
|
this.eventQueueWaits[waitID] = newWait;
|
|
}
|
|
});
|
|
}
|
|
closeCircuit() {
|
|
this.agent.shutdown();
|
|
this.currentRegion.shutdown();
|
|
if (this.circuitSubscription !== null) {
|
|
this.circuitSubscription.unsubscribe();
|
|
this.circuitSubscription = null;
|
|
}
|
|
delete this.currentRegion;
|
|
delete this.agent;
|
|
delete this.clientCommands;
|
|
if (this.ping !== null) {
|
|
clearInterval(this.ping);
|
|
this.ping = null;
|
|
}
|
|
}
|
|
kicked(message) {
|
|
this.closeCircuit();
|
|
this.disconnected(false, message);
|
|
}
|
|
disconnected(requested, message) {
|
|
const disconnectEvent = new DisconnectEvent_1.DisconnectEvent();
|
|
disconnectEvent.requested = requested;
|
|
disconnectEvent.message = message;
|
|
if (this.clientEvents) {
|
|
this.clientEvents.onDisconnected.next(disconnectEvent);
|
|
}
|
|
}
|
|
close() {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const circuit = this.currentRegion.circuit;
|
|
const msg = new LogoutRequest_1.LogoutRequestMessage();
|
|
msg.AgentData = {
|
|
AgentID: this.agent.agentID,
|
|
SessionID: circuit.sessionID
|
|
};
|
|
circuit.sendMessage(msg, PacketFlags_1.PacketFlags.Reliable);
|
|
yield circuit.waitForMessage(Message_1.Message.LogoutReply, 5000);
|
|
this.closeCircuit();
|
|
this.disconnected(true, 'Logout completed');
|
|
});
|
|
}
|
|
connectToSim() {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
const circuit = this.currentRegion.circuit;
|
|
circuit.init();
|
|
const msg = new UseCircuitCode_1.UseCircuitCodeMessage();
|
|
msg.CircuitCode = {
|
|
SessionID: circuit.sessionID,
|
|
ID: this.agent.agentID,
|
|
Code: circuit.circuitCode
|
|
};
|
|
yield circuit.waitForAck(circuit.sendMessage(msg, PacketFlags_1.PacketFlags.Reliable), 1000);
|
|
const agentMovement = new CompleteAgentMovement_1.CompleteAgentMovementMessage();
|
|
agentMovement.AgentData = {
|
|
AgentID: this.agent.agentID,
|
|
SessionID: circuit.sessionID,
|
|
CircuitCode: circuit.circuitCode
|
|
};
|
|
circuit.sendMessage(agentMovement, PacketFlags_1.PacketFlags.Reliable);
|
|
yield circuit.waitForMessage(Message_1.Message.RegionHandshake, 10000);
|
|
const handshakeReply = new RegionHandshakeReply_1.RegionHandshakeReplyMessage();
|
|
handshakeReply.AgentData = {
|
|
AgentID: this.agent.agentID,
|
|
SessionID: circuit.sessionID
|
|
};
|
|
handshakeReply.RegionInfo = {
|
|
Flags: RegionProtocolFlags_1.RegionProtocolFlags.SelfAppearanceSupport | RegionProtocolFlags_1.RegionProtocolFlags.AgentAppearanceService
|
|
};
|
|
yield circuit.waitForAck(circuit.sendMessage(handshakeReply, PacketFlags_1.PacketFlags.Reliable), 10000);
|
|
if (this.clientCommands !== null) {
|
|
this.clientCommands.network.setBandwidth(1536000);
|
|
}
|
|
const agentRequest = new AgentDataUpdateRequest_1.AgentDataUpdateRequestMessage();
|
|
agentRequest.AgentData = {
|
|
AgentID: this.agent.agentID,
|
|
SessionID: circuit.sessionID
|
|
};
|
|
circuit.sendMessage(agentRequest, PacketFlags_1.PacketFlags.Reliable);
|
|
this.agent.setInitialAppearance();
|
|
this.agent.circuitActive();
|
|
this.lastSuccessfulPing = new Date().getTime();
|
|
this.ping = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
this.pingNumber++;
|
|
if (this.pingNumber > 255) {
|
|
this.pingNumber = 0;
|
|
}
|
|
const ping = new StartPingCheck_1.StartPingCheckMessage();
|
|
ping.PingID = {
|
|
PingID: this.pingNumber,
|
|
OldestUnacked: this.currentRegion.circuit.getOldestUnacked()
|
|
};
|
|
circuit.sendMessage(ping, PacketFlags_1.PacketFlags.Reliable);
|
|
circuit.waitForMessage(Message_1.Message.CompletePingCheck, 10000, ((pingData, cpc) => {
|
|
if (cpc.PingID.PingID === pingData.pingID) {
|
|
this.lastSuccessfulPing = new Date().getTime();
|
|
const pingTime = this.lastSuccessfulPing - pingData.timeSent;
|
|
if (this.clientEvents !== null) {
|
|
this.clientEvents.onCircuitLatency.next(pingTime);
|
|
}
|
|
return FilterResponse_1.FilterResponse.Finish;
|
|
}
|
|
return FilterResponse_1.FilterResponse.NoMatch;
|
|
}).bind(this, {
|
|
pingID: this.pingNumber,
|
|
timeSent: new Date().getTime()
|
|
}));
|
|
if ((new Date().getTime() - this.lastSuccessfulPing) > 60000) {
|
|
this.kicked('Circuit Timeout');
|
|
}
|
|
}), 5000);
|
|
this.circuitSubscription = circuit.subscribeToMessages([
|
|
Message_1.Message.TeleportFailed,
|
|
Message_1.Message.TeleportFinish,
|
|
Message_1.Message.TeleportLocal,
|
|
Message_1.Message.TeleportStart,
|
|
Message_1.Message.TeleportProgress,
|
|
Message_1.Message.TeleportCancel,
|
|
Message_1.Message.KickUser
|
|
], (packet) => {
|
|
switch (packet.message.id) {
|
|
case Message_1.Message.TeleportLocal:
|
|
{
|
|
const tpEvent = new TeleportEvent_1.TeleportEvent();
|
|
tpEvent.message = '';
|
|
tpEvent.eventType = TeleportEventType_1.TeleportEventType.TeleportCompleted;
|
|
tpEvent.simIP = 'local';
|
|
tpEvent.simPort = 0;
|
|
tpEvent.seedCapability = '';
|
|
if (this.clientEvents === null) {
|
|
this.kicked('ClientEvents is null');
|
|
}
|
|
this.clientEvents.onTeleportEvent.next(tpEvent);
|
|
break;
|
|
}
|
|
case Message_1.Message.TeleportStart:
|
|
{
|
|
const teleportStart = packet.message;
|
|
const tpEvent = new TeleportEvent_1.TeleportEvent();
|
|
tpEvent.message = '';
|
|
tpEvent.eventType = TeleportEventType_1.TeleportEventType.TeleportStarted;
|
|
tpEvent.simIP = '';
|
|
tpEvent.simPort = 0;
|
|
tpEvent.seedCapability = '';
|
|
if (this.clientEvents === null) {
|
|
this.kicked('ClientEvents is null');
|
|
}
|
|
this.clientEvents.onTeleportEvent.next(tpEvent);
|
|
break;
|
|
}
|
|
case Message_1.Message.TeleportProgress:
|
|
{
|
|
const teleportProgress = packet.message;
|
|
const message = Utils_1.Utils.BufferToStringSimple(teleportProgress.Info.Message);
|
|
const tpEvent = new TeleportEvent_1.TeleportEvent();
|
|
tpEvent.message = message;
|
|
tpEvent.eventType = TeleportEventType_1.TeleportEventType.TeleportProgress;
|
|
tpEvent.simIP = '';
|
|
tpEvent.simPort = 0;
|
|
tpEvent.seedCapability = '';
|
|
if (this.clientEvents === null) {
|
|
this.kicked('ClientEvents is null');
|
|
}
|
|
this.clientEvents.onTeleportEvent.next(tpEvent);
|
|
break;
|
|
}
|
|
case Message_1.Message.KickUser:
|
|
{
|
|
const kickUser = packet.message;
|
|
this.kicked(Utils_1.Utils.BufferToStringSimple(kickUser.UserInfo.Reason));
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
exports.Bot = Bot;
|
|
//# sourceMappingURL=Bot.js.map
|