diff --git a/libsecondlife/AgentManager.cs b/libsecondlife/AgentManager.cs
index 5236d292..18950b30 100644
--- a/libsecondlife/AgentManager.cs
+++ b/libsecondlife/AgentManager.cs
@@ -674,6 +674,13 @@ namespace libsecondlife
public delegate void MeanCollisionCallback(MeanCollisionType type, LLUUID perp, LLUUID victim,
float magnitude, DateTime time);
+ ///
+ /// Triggered when the agent physically moves in to a neighboring region
+ ///
+ /// Simulator agent was previously occupying
+ /// Simulator agent is now currently occupying
+ public delegate void RegionCrossedCallback(Simulator oldSim, Simulator newSim);
+
/// Callback for incoming chat packets
public event ChatCallback OnChat;
/// Callback for pop-up dialogs from scripts
@@ -696,6 +703,8 @@ namespace libsecondlife
/// Callback for an object or avatar forcefully colliding
/// with the agent
public event MeanCollisionCallback OnMeanCollision;
+ /// Callback for the agent moving in to a neighboring sim
+ public event RegionCrossedCallback OnRegionCrossed;
#endregion
@@ -920,7 +929,8 @@ namespace libsecondlife
Client.Network.RegisterCallback(PacketType.AvatarAnimation, new NetworkManager.PacketCallback(AvatarAnimationHandler));
// Object colliding into our agent callback
Client.Network.RegisterCallback(PacketType.MeanCollisionAlert, new NetworkManager.PacketCallback(MeanCollisionAlertHandler));
-
+ // Region Crossing
+ Client.Network.RegisterCallback(PacketType.CrossedRegion, new NetworkManager.PacketCallback(CrossedRegionHandler));
// CAPS callbacks
Client.Network.RegisterEventCallback("EstablishAgentCommunication", new Caps.EventQueueCallback(EstablishAgentCommunicationEventHandler));
@@ -2417,6 +2427,40 @@ namespace libsecondlife
fullName = null;
}
+ ///
+ /// Allows agent to cross over (walk, fly, vehicle) in to neighboring
+ /// simulators
+ ///
+ private void CrossedRegionHandler(Packet packet, Simulator sim)
+ {
+ CrossedRegionPacket crossing = (CrossedRegionPacket)packet;
+ string seedCap = Helpers.FieldToUTF8String(crossing.RegionData.SeedCapability);
+ IPEndPoint endPoint = new IPEndPoint(crossing.RegionData.SimIP, crossing.RegionData.SimPort);
+
+ Client.DebugLog("Crossed in to new region area, attempting to connect to " + endPoint.ToString());
+
+ Simulator oldSim = Client.Network.CurrentSim;
+ Simulator newSim = Client.Network.Connect(endPoint, crossing.RegionData.RegionHandle, true, seedCap);
+
+ if (newSim != null)
+ {
+ Client.Log("Finished crossing over in to region " + newSim.ToString(), Helpers.LogLevel.Info);
+
+ if (OnRegionCrossed != null)
+ {
+ try { OnRegionCrossed(oldSim, newSim); }
+ catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
+ }
+ }
+ else
+ {
+ // The old simulator will (poorly) handle our movement still, so the connection isn't
+ // completely shot yet
+ Client.Log("Failed to connect to new region " + endPoint.ToString() + " after crossing over",
+ Helpers.LogLevel.Warning);
+ }
+ }
+
#endregion Packet Handlers
}
}
diff --git a/libsecondlife/NetworkManager.cs b/libsecondlife/NetworkManager.cs
index 81531e5f..0d255b9f 100644
--- a/libsecondlife/NetworkManager.cs
+++ b/libsecondlife/NetworkManager.cs
@@ -345,6 +345,22 @@ namespace libsecondlife
public Simulator Connect(IPAddress ip, ushort port, ulong handle, bool setDefault, string seedcaps)
{
IPEndPoint endPoint = new IPEndPoint(ip, (int)port);
+ return Connect(endPoint, handle, setDefault, seedcaps);
+ }
+
+ ///
+ /// Connect to a simulator
+ ///
+ /// IP address and port to connect to
+ /// Handle for this simulator, to identify its
+ /// location in the grid
+ /// Whether to set CurrentSim to this new
+ /// connection, use this if the avatar is moving in to this simulator
+ /// URL of the capabilities server to use for
+ /// this sim connection
+ /// A Simulator object on success, otherwise null
+ public Simulator Connect(IPEndPoint endPoint, ulong handle, bool setDefault, string seedcaps)
+ {
Simulator simulator = FindSimulator(endPoint);
if (simulator == null)