Add TeleportTo command and map region lookup by name

This commit is contained in:
Casper Warden
2017-12-16 06:42:41 +00:00
parent f4c0f82760
commit d278bc359b
21 changed files with 362 additions and 60 deletions

View File

@@ -1,7 +1,6 @@
import {MapInfoReply} from '../../events/MapInfoReply';
import {Packet} from '../Packet';
import * as Long from 'long';
import {RegionHandleRequestMessage} from '../messages/RegionHandleRequest';
import {MapItemReplyMessage} from '../messages/MapItemReply';
import {Message} from '../../enums/Message';
import {MapBlockReplyMessage} from '../messages/MapBlockReply';
@@ -11,42 +10,78 @@ import {MapItemRequestMessage} from '../messages/MapItemRequest';
import {Utils} from '../Utils';
import {PacketFlags} from '../../enums/PacketFlags';
import {GridItemType} from '../../enums/GridItemType';
import {RegionIDAndHandleReplyMessage} from '../messages/RegionIDAndHandleReply';
import {CommandsBase} from './CommandsBase';
import {AvatarPickerRequestMessage} from '../messages/AvatarPickerRequest';
import {AvatarPickerReplyMessage} from '../messages/AvatarPickerReply';
import {FilterResponse} from '../../enums/FilterResponse';
import {MapNameRequestMessage} from '../messages/MapNameRequest';
import {GridLayerType} from '../../enums/GridLayerType';
import {RegionInfoReply} from '../../events/RegionInfoReply';
export class GridCommands extends CommandsBase
{
getRegionHandle(regionID: UUID): Promise<Long>
getRegionByName(regionName: string)
{
return new Promise<Long>((resolve, reject) =>
return new Promise<RegionInfoReply>((resolve, reject) =>
{
const circuit = this.currentRegion.circuit;
const msg: RegionHandleRequestMessage = new RegionHandleRequestMessage();
msg.RequestBlock = {
RegionID: regionID,
const response = new MapInfoReply();
const msg: MapNameRequestMessage = new MapNameRequestMessage();
msg.AgentData = {
AgentID: this.agent.agentID,
SessionID: circuit.sessionID,
Flags: GridLayerType.Objects,
EstateID: 0,
Godlike: false
};
msg.NameData = {
Name: Utils.StringToBuffer(regionName)
};
circuit.sendMessage(msg, PacketFlags.Reliable);
circuit.waitForMessage(Message.RegionIDAndHandleReply, 10000, (packet: Packet): FilterResponse =>
circuit.waitForMessage(Message.MapBlockReply, 10000, (packet: Packet): FilterResponse =>
{
const filterMsg = packet.message as RegionIDAndHandleReplyMessage;
if (filterMsg.ReplyBlock.RegionID.toString() === regionID.toString())
const filterMsg = packet.message as MapBlockReplyMessage;
let found = false;
filterMsg.Data.forEach((region) =>
{
const name = Utils.BufferToStringSimple(region.Name);
if (name.trim().toLowerCase() === regionName.trim().toLowerCase())
{
found = true;
}
});
if (found)
{
return FilterResponse.Finish;
}
else
{
return FilterResponse.NoMatch;
}
return FilterResponse.NoMatch;
}).then((packet: Packet) =>
{
const responseMsg = packet.message as RegionIDAndHandleReplyMessage;
resolve(responseMsg.ReplyBlock.RegionHandle);
const responseMsg = packet.message as MapBlockReplyMessage;
responseMsg.Data.forEach((region) =>
{
const name = Utils.BufferToStringSimple(region.Name);
if (name.trim().toLowerCase() === regionName.trim().toLowerCase() && !(region.X === 0 && region.Y === 0))
{
const reply = new RegionInfoReply();
reply.access = region.Access;
reply.X = region.X;
reply.Y = region.Y;
reply.name = name;
reply.regionFlags = region.RegionFlags;
reply.waterHeight = region.WaterHeight;
reply.agents = region.Agents;
reply.mapImageID = region.MapImageID;
reply.handle = Utils.RegionCoordinatesToHandle(region.X * 256, region.Y * 256);
resolve(reply);
}
});
}).catch((err) =>
{
reject(err);
});
});
}
getRegionMapInfo(gridX: number, gridY: number): Promise<MapInfoReply>
{
return new Promise<MapInfoReply>((resolve, reject) =>
@@ -59,7 +94,7 @@ export class GridCommands extends CommandsBase
SessionID: circuit.sessionID,
Flags: 65536,
EstateID: 0,
Godlike: true
Godlike: false
};
msg.PositionData = {
MinX: (gridX / 256),

View File

@@ -1,6 +1,41 @@
import {CommandsBase} from './CommandsBase';
import {UUID} from '../UUID';
import {Packet} from '../Packet';
import * as Long from 'long';
import {PacketFlags} from '../../enums/PacketFlags';
import {RegionHandleRequestMessage} from '../messages/RegionHandleRequest';
import {Message} from '../../enums/Message';
import {FilterResponse} from '../../enums/FilterResponse';
import {RegionIDAndHandleReplyMessage} from '../messages/RegionIDAndHandleReply';
export class RegionCommands extends CommandsBase
{
getRegionHandle(regionID: UUID): Promise<Long>
{
return new Promise<Long>((resolve, reject) =>
{
const circuit = this.currentRegion.circuit;
const msg: RegionHandleRequestMessage = new RegionHandleRequestMessage();
msg.RequestBlock = {
RegionID: regionID,
};
circuit.sendMessage(msg, PacketFlags.Reliable);
circuit.waitForMessage(Message.RegionIDAndHandleReply, 10000, (packet: Packet): FilterResponse =>
{
const filterMsg = packet.message as RegionIDAndHandleReplyMessage;
if (filterMsg.ReplyBlock.RegionID.toString() === regionID.toString())
{
return FilterResponse.Finish;
}
else
{
return FilterResponse.NoMatch;
}
}).then((packet: Packet) =>
{
const responseMsg = packet.message as RegionIDAndHandleReplyMessage;
resolve(responseMsg.ReplyBlock.RegionHandle);
});
});
}
}

View File

@@ -6,22 +6,17 @@ import {TeleportEvent} from '../../events/TeleportEvent';
import {PacketFlags} from '../../enums/PacketFlags';
import {TeleportLureRequestMessage} from '../messages/TeleportLureRequest';
import {TeleportFlags} from '../../enums/TeleportFlags';
import {Vector3} from '../Vector3';
import {RegionInfoReply} from '../../events/RegionInfoReply';
import {TeleportLocationRequestMessage} from '../messages/TeleportLocationRequest';
import * as Long from 'long';
export class TeleportCommands extends CommandsBase
{
acceptTeleport(lure: LureEvent): Promise<TeleportEvent>
private awaitTeleportEvent(): Promise<TeleportEvent>
{
return new Promise<TeleportEvent>((resolve, reject) =>
{
const circuit = this.currentRegion.circuit;
const tlr = new TeleportLureRequestMessage();
tlr.Info = {
AgentID: this.agent.agentID,
SessionID: circuit.sessionID,
LureID: lure.lureID,
TeleportFlags: TeleportFlags.ViaLure
};
circuit.sendMessage(tlr, PacketFlags.Reliable);
if (this.currentRegion.caps.eventQueueClient)
{
if (this.bot.clientEvents === null)
@@ -77,6 +72,78 @@ export class TeleportCommands extends CommandsBase
}
});
}
else
{
reject(new Error('EventQueue not ready'));
}
});
}
acceptTeleport(lure: LureEvent): Promise<TeleportEvent>
{
return new Promise<TeleportEvent>((resolve, reject) =>
{
const circuit = this.currentRegion.circuit;
const tlr = new TeleportLureRequestMessage();
tlr.Info = {
AgentID: this.agent.agentID,
SessionID: circuit.sessionID,
LureID: lure.lureID,
TeleportFlags: TeleportFlags.ViaLure
};
circuit.sendMessage(tlr, PacketFlags.Reliable);
this.awaitTeleportEvent().then((event: TeleportEvent) =>
{
resolve(event);
}).catch((err) =>
{
reject(err);
});
});
}
teleportToHandle(handle: Long, position: Vector3, lookAt: Vector3)
{
return new Promise<TeleportEvent>((resolve, reject) =>
{
const rtm = new TeleportLocationRequestMessage();
rtm.AgentData = {
AgentID: this.agent.agentID,
SessionID: this.circuit.sessionID
};
rtm.Info = {
LookAt: lookAt,
Position: position,
RegionHandle: handle
};
this.circuit.sendMessage(rtm, PacketFlags.Reliable);
this.awaitTeleportEvent().then((event: TeleportEvent) =>
{
resolve(event);
}).catch((err) =>
{
reject(err);
});
});
}
teleportTo(regionName: string, position: Vector3, lookAt: Vector3)
{
return new Promise<TeleportEvent>((resolve, reject) =>
{
this.bot.clientCommands.grid.getRegionByName(regionName).then((region: RegionInfoReply) =>
{
this.teleportToHandle(region.handle, position, lookAt).then((event: TeleportEvent) =>
{
resolve(event);
}).catch((err) =>
{
reject(err);
})
}).catch((err) =>
{
reject(err);
});
});
}
}