326 lines
16 KiB
JavaScript
326 lines
16 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");
|
|
const Vector3_1 = require("./classes/Vector3");
|
|
class Bot {
|
|
constructor(login, options) {
|
|
this.ping = null;
|
|
this.pingNumber = 0;
|
|
this.lastSuccessfulPing = 0;
|
|
this.circuitSubscription = null;
|
|
this.eventQueueRunning = false;
|
|
this.eventQueueWaits = {};
|
|
this.stay = false;
|
|
this.stayRegion = '';
|
|
this.stayPosition = new Vector3_1.Vector3();
|
|
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) { }
|
|
}
|
|
});
|
|
}
|
|
stayPut(stay, regionName, position) {
|
|
this.stay = stay;
|
|
if (regionName !== undefined && position !== undefined) {
|
|
this.stayRegion = regionName;
|
|
this.stayPosition = position;
|
|
}
|
|
}
|
|
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, requested) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
this.closeCircuit();
|
|
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(requested);
|
|
});
|
|
}
|
|
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.currentRegion.shutdown();
|
|
if (this.circuitSubscription !== null) {
|
|
this.circuitSubscription.unsubscribe();
|
|
this.circuitSubscription = null;
|
|
}
|
|
delete this.currentRegion;
|
|
this.clientCommands.shutdown();
|
|
delete this.clientCommands;
|
|
if (this.ping !== null) {
|
|
clearInterval(this.ping);
|
|
this.ping = null;
|
|
}
|
|
}
|
|
kicked(message) {
|
|
this.closeCircuit();
|
|
this.agent.shutdown();
|
|
delete this.agent;
|
|
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.stayRegion = '';
|
|
this.stayPosition = new Vector3_1.Vector3();
|
|
this.closeCircuit();
|
|
this.agent.shutdown();
|
|
delete this.agent;
|
|
this.disconnected(true, 'Logout completed');
|
|
});
|
|
}
|
|
agentID() {
|
|
return this.agent.agentID;
|
|
}
|
|
connectToSim(requested) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
this.agent.setCurrentRegion(this.currentRegion);
|
|
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);
|
|
let agentPosition = null;
|
|
let regionName = null;
|
|
circuit.waitForMessage(Message_1.Message.AgentMovementComplete, 10000).then((agentMovementMsg) => {
|
|
agentPosition = agentMovementMsg.Data.Position;
|
|
if (regionName !== null) {
|
|
if (this.stayRegion === '' || requested) {
|
|
this.stayPut(this.stay, regionName, agentPosition);
|
|
}
|
|
}
|
|
}).catch(() => {
|
|
console.error('Timed out waiting for AgentMovementComplete');
|
|
});
|
|
const handshakeMessage = 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);
|
|
this.currentRegion.handshake(handshakeMessage).then(() => {
|
|
regionName = this.currentRegion.regionName;
|
|
console.log('Arrived in region: ' + regionName);
|
|
if (agentPosition !== null) {
|
|
if (this.stayRegion === '' || requested) {
|
|
this.stayPut(this.stay, regionName, agentPosition);
|
|
}
|
|
}
|
|
}).catch((error) => {
|
|
console.error('Timed out getting handshake');
|
|
console.error(error);
|
|
});
|
|
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 % 12 === 0 && this.stay) {
|
|
if (this.currentRegion.regionName !== this.stayRegion) {
|
|
console.log('Stay Put: Attempting to teleport to ' + this.stayRegion);
|
|
this.clientCommands.teleport.teleportTo(this.stayRegion, this.stayPosition, this.stayPosition).then(() => {
|
|
console.log('I found my way home.');
|
|
}).catch(() => {
|
|
console.log('Cannot teleport home right now.');
|
|
});
|
|
}
|
|
}
|
|
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()
|
|
})).then(() => {
|
|
}).catch(() => {
|
|
console.error('Timeout waiting for ping from the simulator - possible disconnection');
|
|
});
|
|
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
|