Add TeleportTo command and map region lookup by name
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user