update lib meta and cleanup
This commit is contained in:
parent
608690c748
commit
59b768f1b1
46 changed files with 773 additions and 591 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
<AssemblyName>LibreMetaverse.StructuredData</AssemblyName>
|
<AssemblyName>LibreMetaverse.StructuredData</AssemblyName>
|
||||||
<Description>LibreMetaverse structured data library</Description>
|
<Description>LibreMetaverse structured data library</Description>
|
||||||
<PackageId>LibreMetaverse.StructuredData</PackageId>
|
<PackageId>LibreMetaverse.StructuredData</PackageId>
|
||||||
<TargetFrameworks>net48;netstandard2.1;net6.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net7.0</TargetFrameworks>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RootNamespace>LibreMetaverse.StructuredData</RootNamespace>
|
<RootNamespace>LibreMetaverse.StructuredData</RootNamespace>
|
||||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<AssemblyName>LibreMetaverse.Types</AssemblyName>
|
<AssemblyName>LibreMetaverse.Types</AssemblyName>
|
||||||
<PackageId>LibreMetaverse.Types</PackageId>
|
<PackageId>LibreMetaverse.Types</PackageId>
|
||||||
<Description>LibreMetaverse type library</Description>
|
<Description>LibreMetaverse type library</Description>
|
||||||
<TargetFrameworks>net48;netstandard2.1;net6.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net7.0</TargetFrameworks>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RootNamespace>LibreMetaverse</RootNamespace>
|
<RootNamespace>LibreMetaverse</RootNamespace>
|
||||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ namespace OpenMetaverse
|
||||||
public static string MD5(string str)
|
public static string MD5(string str)
|
||||||
{
|
{
|
||||||
StringBuilder digest = new StringBuilder(32);
|
StringBuilder digest = new StringBuilder(32);
|
||||||
byte[] hash = MD5(Encoding.Default.GetBytes(str));
|
byte[] hash = MD5(Encoding.UTF8.GetBytes(str));
|
||||||
|
|
||||||
// Convert the hash to a hex string
|
// Convert the hash to a hex string
|
||||||
foreach (byte b in hash)
|
foreach (byte b in hash)
|
||||||
|
|
@ -399,7 +399,7 @@ namespace OpenMetaverse
|
||||||
/// <returns>The PBKDF2 hash of the supplied string</returns>
|
/// <returns>The PBKDF2 hash of the supplied string</returns>
|
||||||
public static string PBKDF2(string str)
|
public static string PBKDF2(string str)
|
||||||
{
|
{
|
||||||
var derivebytes = new Rfc2898DeriveBytes(str, 32) {IterationCount = 10000};
|
var derivebytes = new Rfc2898DeriveBytes(str, 32, 10000, HashAlgorithmName.SHA1);
|
||||||
byte[] hash = derivebytes.GetBytes(20);
|
byte[] hash = derivebytes.GetBytes(20);
|
||||||
byte[] salt = derivebytes.Salt;
|
byte[] salt = derivebytes.Salt;
|
||||||
return Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash);
|
return Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash);
|
||||||
|
|
|
||||||
|
|
@ -910,7 +910,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
private readonly object m_InstantMessageLock = new object();
|
private readonly object m_InstantMessageLock = new object();
|
||||||
/// <summary>Raised when an ImprovedInstantMessage packet is recieved from the simulator, this is used for everything from
|
/// <summary>Raised when an ImprovedInstantMessage packet is received from the simulator, this is used for everything from
|
||||||
/// private messaging to friendship offers. The Dialog field defines what type of message has arrived</summary>
|
/// private messaging to friendship offers. The Dialog field defines what type of message has arrived</summary>
|
||||||
public event EventHandler<InstantMessageEventArgs> IM
|
public event EventHandler<InstantMessageEventArgs> IM
|
||||||
{
|
{
|
||||||
|
|
@ -1104,8 +1104,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnCameraConstraint(CameraConstraintEventArgs e)
|
protected virtual void OnCameraConstraint(CameraConstraintEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<CameraConstraintEventArgs> handler = m_CameraConstraint;
|
EventHandler<CameraConstraintEventArgs> handler = m_CameraConstraint;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -1128,8 +1127,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnScriptSensorReply(ScriptSensorReplyEventArgs e)
|
protected virtual void OnScriptSensorReply(ScriptSensorReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<ScriptSensorReplyEventArgs> handler = m_ScriptSensorReply;
|
EventHandler<ScriptSensorReplyEventArgs> handler = m_ScriptSensorReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -1151,8 +1149,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnAvatarSitResponse(AvatarSitResponseEventArgs e)
|
protected virtual void OnAvatarSitResponse(AvatarSitResponseEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<AvatarSitResponseEventArgs> handler = m_AvatarSitResponse;
|
EventHandler<AvatarSitResponseEventArgs> handler = m_AvatarSitResponse;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -1478,7 +1475,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
private HomeInfo home;
|
private HomeInfo home;
|
||||||
private string fullName;
|
private string fullName;
|
||||||
private TeleportStatus teleportStat = TeleportStatus.None;
|
private TeleportStatus teleportStatus = TeleportStatus.None;
|
||||||
private ManualResetEvent teleportEvent = new ManualResetEvent(false);
|
private ManualResetEvent teleportEvent = new ManualResetEvent(false);
|
||||||
private uint heightWidthGenCounter;
|
private uint heightWidthGenCounter;
|
||||||
private Dictionary<UUID, AssetGesture> gestureCache = new Dictionary<UUID, AssetGesture>();
|
private Dictionary<UUID, AssetGesture> gestureCache = new Dictionary<UUID, AssetGesture>();
|
||||||
|
|
@ -2966,7 +2963,13 @@ namespace OpenMetaverse
|
||||||
/// <returns>true on success, false on failure</returns>
|
/// <returns>true on success, false on failure</returns>
|
||||||
public bool Teleport(UUID landmark)
|
public bool Teleport(UUID landmark)
|
||||||
{
|
{
|
||||||
teleportStat = TeleportStatus.None;
|
if (teleportStatus == TeleportStatus.Progress)
|
||||||
|
{
|
||||||
|
Logger.Log("Teleport already in progress while attempting to teleport.", Helpers.LogLevel.Info, Client);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
teleportStatus = TeleportStatus.None;
|
||||||
teleportEvent.Reset();
|
teleportEvent.Reset();
|
||||||
TeleportLandmarkRequestPacket p = new TeleportLandmarkRequestPacket
|
TeleportLandmarkRequestPacket p = new TeleportLandmarkRequestPacket
|
||||||
{
|
{
|
||||||
|
|
@ -2981,15 +2984,15 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
teleportEvent.WaitOne(Client.Settings.TELEPORT_TIMEOUT, false);
|
teleportEvent.WaitOne(Client.Settings.TELEPORT_TIMEOUT, false);
|
||||||
|
|
||||||
if (teleportStat == TeleportStatus.None ||
|
if (teleportStatus == TeleportStatus.None ||
|
||||||
teleportStat == TeleportStatus.Start ||
|
teleportStatus == TeleportStatus.Start ||
|
||||||
teleportStat == TeleportStatus.Progress)
|
teleportStatus == TeleportStatus.Progress)
|
||||||
{
|
{
|
||||||
TeleportMessage = "Teleport timed out.";
|
TeleportMessage = "Teleport timed out.";
|
||||||
teleportStat = TeleportStatus.Failed;
|
teleportStatus = TeleportStatus.Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (teleportStat == TeleportStatus.Finished);
|
return (teleportStatus == TeleportStatus.Finished);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -3018,7 +3021,14 @@ namespace OpenMetaverse
|
||||||
{
|
{
|
||||||
if (Client.Network.CurrentSim == null) { return false; }
|
if (Client.Network.CurrentSim == null) { return false; }
|
||||||
|
|
||||||
teleportStat = TeleportStatus.None;
|
if (teleportStatus == TeleportStatus.Progress)
|
||||||
|
{
|
||||||
|
Logger.Log($"Teleport already in progress while attempting to teleport to {simName}.",
|
||||||
|
Helpers.LogLevel.Info, Client);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
teleportStatus = TeleportStatus.None;
|
||||||
|
|
||||||
if (simName != Client.Network.CurrentSim.Name)
|
if (simName != Client.Network.CurrentSim.Name)
|
||||||
{
|
{
|
||||||
|
|
@ -3030,7 +3040,7 @@ namespace OpenMetaverse
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TeleportMessage = $"Unable to resolve simulator named: {simName}";
|
TeleportMessage = $"Unable to resolve simulator named: {simName}";
|
||||||
teleportStat = TeleportStatus.Failed;
|
teleportStatus = TeleportStatus.Failed;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3063,40 +3073,46 @@ namespace OpenMetaverse
|
||||||
/// <remarks>This call is blocking</remarks>
|
/// <remarks>This call is blocking</remarks>
|
||||||
public bool Teleport(ulong regionHandle, Vector3 position, Vector3 lookAt)
|
public bool Teleport(ulong regionHandle, Vector3 position, Vector3 lookAt)
|
||||||
{
|
{
|
||||||
|
if (teleportStatus == TeleportStatus.Progress)
|
||||||
|
{
|
||||||
|
Logger.Log("Teleport already in progress while attempting to teleport.",
|
||||||
|
Helpers.LogLevel.Info, Client);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Client.Network.CurrentSim == null ||
|
if (Client.Network.CurrentSim == null ||
|
||||||
Client.Network.CurrentSim.Caps == null ||
|
Client.Network.CurrentSim.Caps == null ||
|
||||||
!Client.Network.CurrentSim.Caps.IsEventQueueRunning)
|
!Client.Network.CurrentSim.Caps.IsEventQueueRunning)
|
||||||
{
|
{
|
||||||
// Wait a bit to see if the event queue comes online
|
// Wait a bit to see if the event queue comes online
|
||||||
AutoResetEvent queueEvent = new AutoResetEvent(false);
|
AutoResetEvent queueEvent = new AutoResetEvent(false);
|
||||||
EventHandler<EventQueueRunningEventArgs> queueCallback =
|
|
||||||
delegate(object sender, EventQueueRunningEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Simulator == Client.Network.CurrentSim)
|
|
||||||
queueEvent.Set();
|
|
||||||
};
|
|
||||||
|
|
||||||
Client.Network.EventQueueRunning += queueCallback;
|
void QueueCallback(object sender, EventQueueRunningEventArgs e)
|
||||||
queueEvent.WaitOne(10 * 1000, false);
|
{
|
||||||
Client.Network.EventQueueRunning -= queueCallback;
|
if (e.Simulator == Client.Network.CurrentSim) { queueEvent.Set(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
teleportStat = TeleportStatus.None;
|
Client.Network.EventQueueRunning += QueueCallback;
|
||||||
|
queueEvent.WaitOne(10 * 1000, false);
|
||||||
|
Client.Network.EventQueueRunning -= QueueCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
teleportStatus = TeleportStatus.None;
|
||||||
teleportEvent.Reset();
|
teleportEvent.Reset();
|
||||||
|
|
||||||
RequestTeleport(regionHandle, position, lookAt);
|
RequestTeleport(regionHandle, position, lookAt);
|
||||||
|
|
||||||
teleportEvent.WaitOne(Client.Settings.TELEPORT_TIMEOUT, false);
|
teleportEvent.WaitOne(Client.Settings.TELEPORT_TIMEOUT, false);
|
||||||
|
|
||||||
if (teleportStat == TeleportStatus.None ||
|
if (teleportStatus == TeleportStatus.None ||
|
||||||
teleportStat == TeleportStatus.Start ||
|
teleportStatus == TeleportStatus.Start ||
|
||||||
teleportStat == TeleportStatus.Progress)
|
teleportStatus == TeleportStatus.Progress)
|
||||||
{
|
{
|
||||||
TeleportMessage = "Teleport timed out.";
|
TeleportMessage = "Teleport timed out.";
|
||||||
teleportStat = TeleportStatus.Failed;
|
teleportStatus = TeleportStatus.Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (teleportStat == TeleportStatus.Finished);
|
return (teleportStatus == TeleportStatus.Finished);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -3117,8 +3133,7 @@ namespace OpenMetaverse
|
||||||
/// <param name="lookAt"><seealso cref="Vector3"/> direction in destination sim agent will look at</param>
|
/// <param name="lookAt"><seealso cref="Vector3"/> direction in destination sim agent will look at</param>
|
||||||
public void RequestTeleport(ulong regionHandle, Vector3 position, Vector3 lookAt)
|
public void RequestTeleport(ulong regionHandle, Vector3 position, Vector3 lookAt)
|
||||||
{
|
{
|
||||||
if (Client.Network.CurrentSim != null &&
|
if (Client.Network?.CurrentSim?.Caps != null &&
|
||||||
Client.Network.CurrentSim.Caps != null &&
|
|
||||||
Client.Network.CurrentSim.Caps.IsEventQueueRunning)
|
Client.Network.CurrentSim.Caps.IsEventQueueRunning)
|
||||||
{
|
{
|
||||||
TeleportLocationRequestPacket teleport = new TeleportLocationRequestPacket
|
TeleportLocationRequestPacket teleport = new TeleportLocationRequestPacket
|
||||||
|
|
@ -3144,7 +3159,7 @@ namespace OpenMetaverse
|
||||||
{
|
{
|
||||||
TeleportMessage = "CAPS event queue is not running";
|
TeleportMessage = "CAPS event queue is not running";
|
||||||
teleportEvent.Set();
|
teleportEvent.Set();
|
||||||
teleportStat = TeleportStatus.Failed;
|
teleportStatus = TeleportStatus.Failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3251,7 +3266,7 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
public void SendTeleportLureRequest(UUID targetID)
|
public void SendTeleportLureRequest(UUID targetID)
|
||||||
{
|
{
|
||||||
SendTeleportLureRequest(targetID, "Hi there I would like to teleport to you");
|
SendTeleportLureRequest(targetID, "Let me join you in your location");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Teleporting
|
#endregion Teleporting
|
||||||
|
|
@ -4302,7 +4317,9 @@ namespace OpenMetaverse
|
||||||
SimAccess = (byte) msg.SimAccess,
|
SimAccess = (byte) msg.SimAccess,
|
||||||
SimIP = Utils.IPToUInt(msg.IP),
|
SimIP = Utils.IPToUInt(msg.IP),
|
||||||
SimPort = (ushort) msg.Port,
|
SimPort = (ushort) msg.Port,
|
||||||
TeleportFlags = (uint) msg.Flags
|
TeleportFlags = (uint) msg.Flags,
|
||||||
|
RegionSizeX = msg.RegionSizeX,
|
||||||
|
RegionSizeY = msg.RegionSizeY
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// FIXME: Check This
|
// FIXME: Check This
|
||||||
|
|
@ -4328,7 +4345,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
TeleportMessage = "Teleport started";
|
TeleportMessage = "Teleport started";
|
||||||
flags = (TeleportFlags)start.Info.TeleportFlags;
|
flags = (TeleportFlags)start.Info.TeleportFlags;
|
||||||
teleportStat = TeleportStatus.Start;
|
teleportStatus = TeleportStatus.Start;
|
||||||
|
|
||||||
Logger.DebugLog($"TeleportStart received, Flags: {flags}", Client);
|
Logger.DebugLog($"TeleportStart received, Flags: {flags}", Client);
|
||||||
}
|
}
|
||||||
|
|
@ -4338,7 +4355,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
TeleportMessage = Utils.BytesToString(progress.Info.Message);
|
TeleportMessage = Utils.BytesToString(progress.Info.Message);
|
||||||
flags = (TeleportFlags)progress.Info.TeleportFlags;
|
flags = (TeleportFlags)progress.Info.TeleportFlags;
|
||||||
teleportStat = TeleportStatus.Progress;
|
teleportStatus = TeleportStatus.Progress;
|
||||||
|
|
||||||
Logger.DebugLog($"TeleportProgress received, Message: {TeleportMessage}, Flags: {flags}", Client);
|
Logger.DebugLog($"TeleportProgress received, Message: {TeleportMessage}, Flags: {flags}", Client);
|
||||||
}
|
}
|
||||||
|
|
@ -4347,7 +4364,7 @@ namespace OpenMetaverse
|
||||||
TeleportFailedPacket failed = (TeleportFailedPacket)packet;
|
TeleportFailedPacket failed = (TeleportFailedPacket)packet;
|
||||||
|
|
||||||
TeleportMessage = Utils.BytesToString(failed.Info.Reason);
|
TeleportMessage = Utils.BytesToString(failed.Info.Reason);
|
||||||
teleportStat = TeleportStatus.Failed;
|
teleportStatus = TeleportStatus.Failed;
|
||||||
finished = true;
|
finished = true;
|
||||||
|
|
||||||
Logger.DebugLog($"TeleportFailed received, Reason: {TeleportMessage}", Client);
|
Logger.DebugLog($"TeleportFailed received, Reason: {TeleportMessage}", Client);
|
||||||
|
|
@ -4365,19 +4382,20 @@ namespace OpenMetaverse
|
||||||
// Connect to the new sim
|
// Connect to the new sim
|
||||||
Client.Network.CurrentSim.AgentMovementComplete = false; // we're not there anymore
|
Client.Network.CurrentSim.AgentMovementComplete = false; // we're not there anymore
|
||||||
Simulator newSimulator = Client.Network.Connect(new IPAddress(finish.Info.SimIP),
|
Simulator newSimulator = Client.Network.Connect(new IPAddress(finish.Info.SimIP),
|
||||||
finish.Info.SimPort, finish.Info.RegionHandle, true, seedcaps);
|
finish.Info.SimPort, finish.Info.RegionHandle, true, seedcaps,
|
||||||
|
finish.Info.RegionSizeX, finish.Info.RegionSizeY);
|
||||||
|
|
||||||
if (newSimulator != null)
|
if (newSimulator != null)
|
||||||
{
|
{
|
||||||
TeleportMessage = "Teleport finished";
|
TeleportMessage = "Teleport finished";
|
||||||
teleportStat = TeleportStatus.Finished;
|
teleportStatus = TeleportStatus.Finished;
|
||||||
|
|
||||||
Logger.Log($"Moved to new sim {newSimulator}", Helpers.LogLevel.Info, Client);
|
Logger.Log($"Moved to {newSimulator}", Helpers.LogLevel.Info, Client);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TeleportMessage = "Failed to connect to the new sim after a teleport";
|
TeleportMessage = $"Failed to connect to {newSimulator} after teleport";
|
||||||
teleportStat = TeleportStatus.Failed;
|
teleportStatus = TeleportStatus.Failed;
|
||||||
|
|
||||||
// We're going to get disconnected now
|
// We're going to get disconnected now
|
||||||
Logger.Log(TeleportMessage, Helpers.LogLevel.Error, Client);
|
Logger.Log(TeleportMessage, Helpers.LogLevel.Error, Client);
|
||||||
|
|
@ -4388,7 +4406,7 @@ namespace OpenMetaverse
|
||||||
//TeleportCancelPacket cancel = (TeleportCancelPacket)packet;
|
//TeleportCancelPacket cancel = (TeleportCancelPacket)packet;
|
||||||
|
|
||||||
TeleportMessage = "Cancelled";
|
TeleportMessage = "Cancelled";
|
||||||
teleportStat = TeleportStatus.Cancelled;
|
teleportStatus = TeleportStatus.Cancelled;
|
||||||
finished = true;
|
finished = true;
|
||||||
|
|
||||||
Logger.DebugLog($"TeleportCancel received from {simulator}", Client);
|
Logger.DebugLog($"TeleportCancel received from {simulator}", Client);
|
||||||
|
|
@ -4399,7 +4417,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
TeleportMessage = "Teleport finished";
|
TeleportMessage = "Teleport finished";
|
||||||
flags = (TeleportFlags)local.Info.TeleportFlags;
|
flags = (TeleportFlags)local.Info.TeleportFlags;
|
||||||
teleportStat = TeleportStatus.Finished;
|
teleportStatus = TeleportStatus.Finished;
|
||||||
relativePosition = local.Info.Position;
|
relativePosition = local.Info.Position;
|
||||||
Movement.Camera.LookDirection(local.Info.LookAt);
|
Movement.Camera.LookDirection(local.Info.LookAt);
|
||||||
// This field is apparently not used for anything
|
// This field is apparently not used for anything
|
||||||
|
|
@ -4411,7 +4429,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
if (m_Teleport != null)
|
if (m_Teleport != null)
|
||||||
{
|
{
|
||||||
OnTeleport(new TeleportEventArgs(TeleportMessage, teleportStat, flags));
|
OnTeleport(new TeleportEventArgs(TeleportMessage, teleportStatus, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finished) { teleportEvent.Set(); }
|
if (finished) { teleportEvent.Set(); }
|
||||||
|
|
@ -4541,7 +4559,8 @@ namespace OpenMetaverse
|
||||||
Logger.DebugLog($"Crossed in to new region area, attempting to connect to {endPoint}", Client);
|
Logger.DebugLog($"Crossed in to new region area, attempting to connect to {endPoint}", Client);
|
||||||
|
|
||||||
Simulator oldSim = Client.Network.CurrentSim;
|
Simulator oldSim = Client.Network.CurrentSim;
|
||||||
Simulator newSim = Client.Network.Connect(endPoint, crossed.RegionHandle, true, crossed.SeedCapability);
|
Simulator newSim = Client.Network.Connect(endPoint, crossed.RegionHandle, true, crossed.SeedCapability,
|
||||||
|
crossed.RegionSizeX, crossed.RegionSizeY);
|
||||||
|
|
||||||
if (newSim != null)
|
if (newSim != null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -393,18 +393,12 @@ namespace OpenMetaverse
|
||||||
{
|
{
|
||||||
if (value > 0)
|
if (value > 0)
|
||||||
{
|
{
|
||||||
if (updateTimer != null)
|
updateTimer?.Change(value, value);
|
||||||
{
|
|
||||||
updateTimer.Change(value, value);
|
|
||||||
}
|
|
||||||
updateInterval = value;
|
updateInterval = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (updateTimer != null)
|
updateTimer?.Change(Timeout.Infinite, Timeout.Infinite);
|
||||||
{
|
|
||||||
updateTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
|
||||||
}
|
|
||||||
updateInterval = 0;
|
updateInterval = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ namespace OpenMetaverse
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="assetID">UUID of the asset</param>
|
/// <param name="assetID">UUID of the asset</param>
|
||||||
/// <param name="assetData">Raw bytes the asset consists of</param>
|
/// <param name="assetData">Raw bytes the asset consists of</param>
|
||||||
/// <returns>Weather the operation was successfull</returns>
|
/// <returns>Whether the operation was successful</returns>
|
||||||
public bool SaveAssetToCache(UUID assetID, byte[] assetData)
|
public bool SaveAssetToCache(UUID assetID, byte[] assetData)
|
||||||
{
|
{
|
||||||
if (!Operational())
|
if (!Operational())
|
||||||
|
|
|
||||||
|
|
@ -319,8 +319,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnXferReceived(XferReceivedEventArgs e)
|
protected virtual void OnXferReceived(XferReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<XferReceivedEventArgs> handler = m_XferReceivedEvent;
|
EventHandler<XferReceivedEventArgs> handler = m_XferReceivedEvent;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -344,8 +343,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnAssetUploaded(AssetUploadEventArgs e)
|
protected virtual void OnAssetUploaded(AssetUploadEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<AssetUploadEventArgs> handler = m_AssetUploadedEvent;
|
EventHandler<AssetUploadEventArgs> handler = m_AssetUploadedEvent;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -369,8 +367,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnUploadProgress(AssetUploadEventArgs e)
|
protected virtual void OnUploadProgress(AssetUploadEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<AssetUploadEventArgs> handler = m_UploadProgressEvent;
|
EventHandler<AssetUploadEventArgs> handler = m_UploadProgressEvent;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -394,8 +391,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnInitiateDownload(InitiateDownloadEventArgs e)
|
protected virtual void OnInitiateDownload(InitiateDownloadEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<InitiateDownloadEventArgs> handler = m_InitiateDownloadEvent;
|
EventHandler<InitiateDownloadEventArgs> handler = m_InitiateDownloadEvent;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -419,8 +415,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnImageReceiveProgress(ImageReceiveProgressEventArgs e)
|
protected virtual void OnImageReceiveProgress(ImageReceiveProgressEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<ImageReceiveProgressEventArgs> handler = m_ImageReceiveProgressEvent;
|
EventHandler<ImageReceiveProgressEventArgs> handler = m_ImageReceiveProgressEvent;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -640,8 +635,7 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
|
|
||||||
// If ViewerAsset capability exists, use that, if not, fallback to UDP (which is obsoleted on Second Life.)
|
// If ViewerAsset capability exists, use that, if not, fallback to UDP (which is obsoleted on Second Life.)
|
||||||
if (Client.Network.CurrentSim.Caps != null
|
if (Client.Network.CurrentSim?.Caps?.CapabilityURI("ViewerAsset") != null)
|
||||||
&& Client.Network.CurrentSim.Caps.CapabilityURI("ViewerAsset") != null)
|
|
||||||
{
|
{
|
||||||
RequestAssetHTTP(assetID, transfer, callback);
|
RequestAssetHTTP(assetID, transfer, callback);
|
||||||
}
|
}
|
||||||
|
|
@ -827,10 +821,20 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
|
|
||||||
// If ViewerAsset capability exists, use that, if not, fallback to UDP
|
// If ViewerAsset capability exists, use that, if not, fallback to UDP
|
||||||
if (Client.Network.CurrentSim.Caps != null
|
if (Client.Network.CurrentSim?.Caps?.CapabilityURI("ViewerAsset") != null)
|
||||||
&& Client.Network.CurrentSim.Caps.CapabilityURI("ViewerAsset") != null)
|
|
||||||
{
|
{
|
||||||
RequestInventoryAssetHTTP(assetID, transfer, callback);
|
RequestInventoryAssetHTTP(assetID, transfer,
|
||||||
|
(AssetDownload transferResult, Asset assetResult) =>
|
||||||
|
{
|
||||||
|
if (transferResult.Success == false)
|
||||||
|
{
|
||||||
|
Logger.Log($"HTTP transfer has failed trying UDP", Helpers.LogLevel.Warning, Client);
|
||||||
|
RequestInventoryAssetUDP(assetID, itemID, taskID, ownerID, transfer, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback(transferResult, assetResult);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -849,6 +853,7 @@ namespace OpenMetaverse
|
||||||
/// <param name="callback"></param>
|
/// <param name="callback"></param>
|
||||||
private void RequestInventoryAssetHTTP(UUID assetID, AssetDownload transfer, AssetReceivedCallback callback)
|
private void RequestInventoryAssetHTTP(UUID assetID, AssetDownload transfer, AssetReceivedCallback callback)
|
||||||
{
|
{
|
||||||
|
int attempts = 0;
|
||||||
DownloadRequest req = new DownloadRequest(
|
DownloadRequest req = new DownloadRequest(
|
||||||
BuildFetchRequestUri(transfer.AssetType, assetID),
|
BuildFetchRequestUri(transfer.AssetType, assetID),
|
||||||
null,
|
null,
|
||||||
|
|
@ -873,6 +878,7 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
else // download failed
|
else // download failed
|
||||||
{
|
{
|
||||||
|
attempts++;
|
||||||
Logger.Log($"Failed to fetch asset {assetID}: {((error == null) ? "" : error.Message)}",
|
Logger.Log($"Failed to fetch asset {assetID}: {((error == null) ? "" : error.Message)}",
|
||||||
Helpers.LogLevel.Warning, Client);
|
Helpers.LogLevel.Warning, Client);
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
|
|
@ -880,6 +886,10 @@ namespace OpenMetaverse
|
||||||
transfer.Success = false;
|
transfer.Success = false;
|
||||||
transfer.Status = StatusCode.Error;
|
transfer.Status = StatusCode.Error;
|
||||||
}
|
}
|
||||||
|
if (attempts == 5)
|
||||||
|
{
|
||||||
|
callback(transfer, null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1213,8 +1223,7 @@ namespace OpenMetaverse
|
||||||
if (meshID == UUID.Zero || callback == null)
|
if (meshID == UUID.Zero || callback == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Client.Network.CurrentSim.Caps != null &&
|
if (Client.Network.CurrentSim?.Caps?.GetMeshCapURI() != null)
|
||||||
Client.Network.CurrentSim.Caps.GetMeshCapURI() != null)
|
|
||||||
{
|
{
|
||||||
// Do we have this mesh asset in the cache?
|
// Do we have this mesh asset in the cache?
|
||||||
if (Client.Assets.Cache.HasAsset(meshID))
|
if (Client.Assets.Cache.HasAsset(meshID))
|
||||||
|
|
@ -1329,8 +1338,7 @@ namespace OpenMetaverse
|
||||||
uint packetStart, TextureDownloadCallback callback, bool progress)
|
uint packetStart, TextureDownloadCallback callback, bool progress)
|
||||||
{
|
{
|
||||||
if (Client.Settings.USE_HTTP_TEXTURES
|
if (Client.Settings.USE_HTTP_TEXTURES
|
||||||
&& Client.Network.CurrentSim.Caps != null
|
&& Client.Network.CurrentSim?.Caps?.GetTextureCapURI() != null)
|
||||||
&& Client.Network.CurrentSim.Caps.GetTextureCapURI() != null)
|
|
||||||
{
|
{
|
||||||
HttpRequestTexture(textureID, imageType, priority, discardLevel, packetStart, callback, progress);
|
HttpRequestTexture(textureID, imageType, priority, discardLevel, packetStart, callback, progress);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ namespace OpenMetaverse.Assets
|
||||||
|
|
||||||
private static bool LoadTerrain(string filePath, byte[] data, TerrainLoadedCallback terrainCallback, long bytesRead, long totalBytes)
|
private static bool LoadTerrain(string filePath, byte[] data, TerrainLoadedCallback terrainCallback, long bytesRead, long totalBytes)
|
||||||
{
|
{
|
||||||
|
// TODO: This needs to be re-written to read data from a saved varregion (sizeX != 256)
|
||||||
float[,] terrain = new float[256, 256];
|
float[,] terrain = new float[256, 256];
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
|
|
||||||
|
|
@ -350,10 +351,10 @@ namespace OpenMetaverse.Assets
|
||||||
BinaryWriter bs = new BinaryWriter(s);
|
BinaryWriter bs = new BinaryWriter(s);
|
||||||
|
|
||||||
int y;
|
int y;
|
||||||
for (y = 0; y < 256; y++)
|
for (y = 0; y < sim.SizeY; y++)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
for (x = 0; x < 256; x++)
|
for (x = 0; x < sim.SizeX; x++)
|
||||||
{
|
{
|
||||||
float height;
|
float height;
|
||||||
sim.TerrainHeightAtPoint(x, y, out height);
|
sim.TerrainHeightAtPoint(x, y, out height);
|
||||||
|
|
|
||||||
|
|
@ -689,9 +689,7 @@ namespace OpenMetaverse
|
||||||
/// <returns>True if Display name functionality is available</returns>
|
/// <returns>True if Display name functionality is available</returns>
|
||||||
public bool DisplayNamesAvailable()
|
public bool DisplayNamesAvailable()
|
||||||
{
|
{
|
||||||
return (Client.Network.CurrentSim != null
|
return Client.Network.CurrentSim?.Caps?.CapabilityURI("GetDisplayNames") != null;
|
||||||
&& Client.Network.CurrentSim.Caps != null)
|
|
||||||
&& Client.Network.CurrentSim.Caps.CapabilityURI("GetDisplayNames") != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -296,8 +296,7 @@ namespace OpenMetaverse.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire the download progress callback for each chunk of received data
|
// Fire the download progress callback for each chunk of received data
|
||||||
if (state.DownloadProgressCallback != null)
|
state.DownloadProgressCallback?.Invoke(state.Request, response, totalBytesRead, totalSize);
|
||||||
state.DownloadProgressCallback(state.Request, response, totalBytesRead, totalSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nolength)
|
if (nolength)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2016, openmetaverse.co
|
* Copyright (c) 2006-2016, openmetaverse.co
|
||||||
* Copyright (c) 2022, Sjofn LLC.
|
* Copyright (c) 2022-2023, Sjofn LLC.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* - Redistribution and use in source and binary forms, with or without
|
* - Redistribution and use in source and binary forms, with or without
|
||||||
|
|
@ -38,9 +38,9 @@ namespace OpenMetaverse.Http
|
||||||
public class EventQueueClient
|
public class EventQueueClient
|
||||||
{
|
{
|
||||||
/// <summary>For exponential backoff on error.</summary>
|
/// <summary>For exponential backoff on error.</summary>
|
||||||
public const int REQUEST_BACKOFF_SECONDS = 15 * 1000; // 15 seconds start
|
private const int REQUEST_BACKOFF_SECONDS = 15 * 1000; // 15 seconds start
|
||||||
public const int REQUEST_BACKOFF_SECONDS_INC = 5 * 1000; // 5 seconds increase
|
private const int REQUEST_BACKOFF_SECONDS_INC = 5 * 1000; // 5 seconds increase
|
||||||
public const int REQUEST_BACKOFF_SECONDS_MAX = 5 * 60 * 1000; // 5 minutes
|
private const int REQUEST_BACKOFF_SECONDS_MAX = 5 * 60 * 1000; // 5 minutes
|
||||||
|
|
||||||
public delegate void ConnectedCallback();
|
public delegate void ConnectedCallback();
|
||||||
public delegate void EventCallback(string eventName, OSDMap body);
|
public delegate void EventCallback(string eventName, OSDMap body);
|
||||||
|
|
@ -48,13 +48,14 @@ namespace OpenMetaverse.Http
|
||||||
public ConnectedCallback OnConnected;
|
public ConnectedCallback OnConnected;
|
||||||
public EventCallback OnEvent;
|
public EventCallback OnEvent;
|
||||||
|
|
||||||
public bool Running => _Running;
|
public bool Running { get; private set; }
|
||||||
|
|
||||||
|
private readonly Uri _Address;
|
||||||
|
private readonly Simulator _Simulator;
|
||||||
|
private readonly CancellationTokenSource _queueCts;
|
||||||
|
private bool _Dead;
|
||||||
|
private OSD _AckPayload;
|
||||||
|
|
||||||
protected readonly Uri _Address;
|
|
||||||
protected readonly Simulator _Simulator;
|
|
||||||
protected bool _Dead;
|
|
||||||
protected bool _Running;
|
|
||||||
private CancellationTokenSource _HttpCts;
|
|
||||||
|
|
||||||
/// <summary>Number of times we've received an unknown CAPS exception in series.</summary>
|
/// <summary>Number of times we've received an unknown CAPS exception in series.</summary>
|
||||||
private int _errorCount;
|
private int _errorCount;
|
||||||
|
|
@ -63,19 +64,71 @@ namespace OpenMetaverse.Http
|
||||||
{
|
{
|
||||||
_Address = eventQueueLocation;
|
_Address = eventQueueLocation;
|
||||||
_Simulator = sim;
|
_Simulator = sim;
|
||||||
|
_queueCts = new CancellationTokenSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
_Dead = false;
|
_Dead = false;
|
||||||
_Running = true;
|
Running = true;
|
||||||
|
|
||||||
// Create an EventQueueGet request
|
Task.Factory.StartNew(() =>
|
||||||
OSDMap payload = new OSDMap {["ack"] = new OSD(), ["done"] = OSD.FromBoolean(false)};
|
{
|
||||||
|
// Initial request
|
||||||
|
_AckPayload = new OSDMap { ["ack"] = new OSD(), ["done"] = OSD.FromBoolean(false) };
|
||||||
|
var initialTimeoutCts = CancellationTokenSource.CreateLinkedTokenSource(_queueCts.Token);
|
||||||
|
initialTimeoutCts.CancelAfter(TimeSpan.FromSeconds(30));
|
||||||
|
|
||||||
|
Task initialReq = _Simulator.Client.HttpCapsClient.PostRequestAsync(_Address, OSDFormat.Xml, _AckPayload,
|
||||||
|
initialTimeoutCts.Token, RequestCompletedHandler, null, ConnectedResponseHandler);
|
||||||
|
|
||||||
|
initialReq.Wait(initialTimeoutCts.Token);
|
||||||
|
initialTimeoutCts.Dispose();
|
||||||
|
|
||||||
|
while (Running && !_queueCts.Token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
if (_errorCount > 0)
|
||||||
|
{ // Exponentially back off, so we don't hammer the CPU
|
||||||
|
while (!_queueCts.Token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
_queueCts.Token.WaitHandle.WaitOne(
|
||||||
|
Math.Min(REQUEST_BACKOFF_SECONDS + _errorCount * REQUEST_BACKOFF_SECONDS_INC,
|
||||||
|
REQUEST_BACKOFF_SECONDS_MAX));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Resume the connection.
|
||||||
|
if (!_queueCts.Token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
using (CancellationTokenSource timeoutCts =
|
||||||
|
CancellationTokenSource.CreateLinkedTokenSource(_queueCts.Token))
|
||||||
|
{
|
||||||
|
timeoutCts.CancelAfter(TimeSpan.FromSeconds(30));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Task req = _Simulator.Client.HttpCapsClient.PostRequestAsync(_Address, OSDFormat.Xml,
|
||||||
|
_AckPayload, timeoutCts.Token, RequestCompletedHandler);
|
||||||
|
req.Wait(timeoutCts.Token);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
/*no-op*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If the event queue is dead at this point, turn it off since
|
||||||
|
// that was the last thing we want to do
|
||||||
|
if (_Dead)
|
||||||
|
{
|
||||||
|
Running = false;
|
||||||
|
Logger.DebugLog($"Sent event queue shutdown message for {_Simulator}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}, _queueCts.Token); // TOOD: TaskCreationOptions.LongRunning?
|
||||||
|
|
||||||
_HttpCts = new CancellationTokenSource();
|
|
||||||
Task req = _Simulator.Client.HttpCapsClient.PostRequestAsync(_Address, OSDFormat.Xml, payload, _HttpCts.Token,
|
|
||||||
RequestCompletedHandler, null, ConnectedResponseHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop(bool immediate)
|
public void Stop(bool immediate)
|
||||||
|
|
@ -84,17 +137,17 @@ namespace OpenMetaverse.Http
|
||||||
|
|
||||||
if (immediate)
|
if (immediate)
|
||||||
{
|
{
|
||||||
_Running = false;
|
Running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_HttpCts.Cancel();
|
_queueCts.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectedResponseHandler(HttpResponseMessage response)
|
void ConnectedResponseHandler(HttpResponseMessage response)
|
||||||
{
|
{
|
||||||
if (!response.IsSuccessStatusCode) { return; }
|
if (!response.IsSuccessStatusCode) { return; }
|
||||||
|
|
||||||
_Running = true;
|
Running = true;
|
||||||
|
|
||||||
// The event queue is starting up for the first time
|
// The event queue is starting up for the first time
|
||||||
if (OnConnected != null)
|
if (OnConnected != null)
|
||||||
|
|
@ -120,11 +173,11 @@ namespace OpenMetaverse.Http
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Log($"Got an unparseable response from {_Simulator} event queue: \"" +
|
Logger.Log($"Received an invalid response from {_Simulator} event queue: \"" +
|
||||||
System.Text.Encoding.UTF8.GetString(responseData) + "\"", Helpers.LogLevel.Warning);
|
System.Text.Encoding.UTF8.GetString(responseData) + "\"", Helpers.LogLevel.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (error != null)
|
else if (response != null && error != null)
|
||||||
{
|
{
|
||||||
#region Error handling
|
#region Error handling
|
||||||
|
|
||||||
|
|
@ -132,30 +185,31 @@ namespace OpenMetaverse.Http
|
||||||
{
|
{
|
||||||
case HttpStatusCode.NotFound:
|
case HttpStatusCode.NotFound:
|
||||||
case HttpStatusCode.Gone:
|
case HttpStatusCode.Gone:
|
||||||
Logger.Log($"Closing event queue at {_Simulator} due to missing caps URI", Helpers.LogLevel.Info);
|
Logger.Log($"Closing event queue at {_Simulator} due to missing caps URI", Helpers.LogLevel.Info, _Simulator.Client);
|
||||||
|
|
||||||
_Running = false;
|
Running = false;
|
||||||
_Dead = true;
|
_Dead = true;
|
||||||
break;
|
break;
|
||||||
case (HttpStatusCode)499: // weird error returned occasionally, ignore for now
|
case (HttpStatusCode)499: // weird error returned occasionally, ignore for now
|
||||||
// I believe this is the timeout error invented by LL for LSL HTTP-out requests (gwyneth 20220413)
|
// I believe this is the timeout error invented by LL for LSL HTTP-out requests (gwyneth 20220413)
|
||||||
Logger.Log($"Possible HTTP-out timeout error from {_Simulator}, no need to continue", Helpers.LogLevel.Debug);
|
Logger.Log($"Possible HTTP-out timeout error from {_Simulator}, no need to continue", Helpers.LogLevel.Debug, _Simulator.Client);
|
||||||
|
|
||||||
_Running = false;
|
Running = false;
|
||||||
_Dead = true;
|
_Dead = true;
|
||||||
break;
|
break;
|
||||||
case HttpStatusCode.InternalServerError:
|
case HttpStatusCode.InternalServerError:
|
||||||
// As per LL's instructions, we ought to consider this a
|
// As per LL's instructions, we ought to consider this a
|
||||||
// 'request to close client' (gwyneth 20220413)
|
// 'request to close client' (gwyneth 20220413)
|
||||||
Logger.Log($"Grid sent a {response.StatusCode} at {_Simulator}, closing connection", Helpers.LogLevel.Debug);
|
Logger.Log($"Grid sent a {response.StatusCode} at {_Simulator}, closing connection", Helpers.LogLevel.Debug, _Simulator.Client);
|
||||||
|
|
||||||
// ... but do we happen to have an InnerException? Log it!
|
// ... but do we happen to have an InnerException? Log it!
|
||||||
if (error.InnerException != null)
|
if (error.InnerException != null)
|
||||||
{
|
{
|
||||||
// unravel the whole inner error message, so we finally figure out what it is!
|
// unravel the whole inner error message, so we finally figure out what it is!
|
||||||
// (gwyneth 20220414)
|
// (gwyneth 20220414)
|
||||||
Logger.Log($"Unrecognized internal caps exception from {_Simulator}: '{error.InnerException.Message}'", Helpers.LogLevel.Warning);
|
Logger.Log($"Unrecognized internal caps exception from {_Simulator}: '{error.InnerException.Message}'",
|
||||||
Logger.Log($"\nMessage ---\n{error.Message}", Helpers.LogLevel.Warning);
|
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
|
Logger.Log($"\nMessage ---\n{error.Message}", Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
if (error.Data.Count > 0)
|
if (error.Data.Count > 0)
|
||||||
{
|
{
|
||||||
Logger.Log(" Extra details:", Helpers.LogLevel.Warning);
|
Logger.Log(" Extra details:", Helpers.LogLevel.Warning);
|
||||||
|
|
@ -163,13 +217,13 @@ namespace OpenMetaverse.Http
|
||||||
{
|
{
|
||||||
Logger.Log(String.Format(" Key: {0,-20} Value: '{1}'",
|
Logger.Log(String.Format(" Key: {0,-20} Value: '{1}'",
|
||||||
de.Key, de.Value),
|
de.Key, de.Value),
|
||||||
Helpers.LogLevel.Warning);
|
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// but we'll nevertheless close this connection (gwyneth 20220414)
|
// but we'll nevertheless close this connection (gwyneth 20220414)
|
||||||
}
|
}
|
||||||
|
|
||||||
_Running = false;
|
Running = false;
|
||||||
_Dead = true;
|
_Dead = true;
|
||||||
break;
|
break;
|
||||||
case HttpStatusCode.BadGateway:
|
case HttpStatusCode.BadGateway:
|
||||||
|
|
@ -182,7 +236,8 @@ namespace OpenMetaverse.Http
|
||||||
// Note: if this condition persists, it _might_ be the grid trying to request
|
// Note: if this condition persists, it _might_ be the grid trying to request
|
||||||
// that the client closes the connection, as per LL's specs (gwyneth 20220414)
|
// that the client closes the connection, as per LL's specs (gwyneth 20220414)
|
||||||
Logger.Log($"Grid sent a Bad Gateway Error at {_Simulator}; " +
|
Logger.Log($"Grid sent a Bad Gateway Error at {_Simulator}; " +
|
||||||
$"probably a time-out from the grid's EventQueue server (normal) -- ignoring and continuing", Helpers.LogLevel.Debug);
|
$"probably a time-out from the grid's EventQueue server (normal) -- ignoring and continuing",
|
||||||
|
Helpers.LogLevel.Debug, _Simulator.Client);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
++_errorCount;
|
++_errorCount;
|
||||||
|
|
@ -191,71 +246,55 @@ namespace OpenMetaverse.Http
|
||||||
if (response.StatusCode != HttpStatusCode.OK)
|
if (response.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
Logger.Log($"Unrecognized caps connection problem from {_Simulator}: {response.StatusCode} {response.ReasonPhrase}",
|
Logger.Log($"Unrecognized caps connection problem from {_Simulator}: {response.StatusCode} {response.ReasonPhrase}",
|
||||||
Helpers.LogLevel.Warning);
|
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
}
|
}
|
||||||
else if (error.InnerException != null)
|
else if (error.InnerException != null)
|
||||||
{
|
{
|
||||||
// see comment above (gwyneth 20220414)
|
// see comment above (gwyneth 20220414)
|
||||||
Logger.Log($"Unrecognized internal caps exception from {_Simulator}: '{error.InnerException.Message}'", Helpers.LogLevel.Warning);
|
Logger.Log($"Unrecognized internal caps exception from {_Simulator}: '{error.InnerException.Message}'",
|
||||||
Logger.Log($"Message ---\n{error.Message}", Helpers.LogLevel.Warning);
|
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
|
Logger.Log($"Message ---\n{error.Message}", Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
if (error.Data.Count > 0)
|
if (error.Data.Count > 0)
|
||||||
{
|
{
|
||||||
Logger.Log(" Extra details:", Helpers.LogLevel.Warning);
|
Logger.Log(" Extra details:", Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
foreach (DictionaryEntry de in error.Data)
|
foreach (DictionaryEntry de in error.Data)
|
||||||
{
|
{
|
||||||
Logger.Log(string.Format(" Key: {0,-20} Value: {1}",
|
Logger.Log(string.Format(" Key: {0,-20} Value: {1}",
|
||||||
"'" + de.Key + "'", de.Value),
|
"'" + de.Key + "'", de.Value),
|
||||||
Helpers.LogLevel.Warning);
|
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Log($"Unrecognized caps exception from {_Simulator}: {error.Message}",
|
Logger.Log($"Unrecognized caps exception from {_Simulator}: {error.Message}",
|
||||||
Helpers.LogLevel.Warning);
|
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
#endregion Error handling
|
#endregion Error handling
|
||||||
}
|
}
|
||||||
|
else if (error != null)
|
||||||
|
{
|
||||||
|
++_errorCount;
|
||||||
|
Logger.Log($"Exception thrown from {_Simulator} event queue: " +
|
||||||
|
$"{(error.InnerException != null ? error.InnerException.Message : error.Message)}", Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
++_errorCount;
|
++_errorCount;
|
||||||
|
Logger.Log($"No response from {_Simulator} event queue with no reported error", Helpers.LogLevel.Warning, _Simulator.Client);
|
||||||
Logger.Log($"No response from {_Simulator} event queue but no reported error either", Helpers.LogLevel.Warning);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CS0164 // This label has not been referenced
|
if (Running)
|
||||||
HandlingDone:
|
|
||||||
|
|
||||||
#region Resume the connection
|
|
||||||
|
|
||||||
if (_Running)
|
|
||||||
{
|
{
|
||||||
OSDMap payload = new OSDMap();
|
OSDMap payload = new OSDMap();
|
||||||
if (ack != 0) { payload["ack"] = OSD.FromInteger(ack); }
|
if (ack != 0) { payload["ack"] = OSD.FromInteger(ack); }
|
||||||
else { payload["ack"] = new OSD(); }
|
else { payload["ack"] = new OSD(); }
|
||||||
payload["done"] = OSD.FromBoolean(_Dead);
|
payload["done"] = OSD.FromBoolean(_Dead);
|
||||||
|
_AckPayload = payload;
|
||||||
if (_errorCount > 0) { // Exponentially back off, so we don't hammer the CPU
|
|
||||||
Thread.Sleep(Math.Min(REQUEST_BACKOFF_SECONDS + _errorCount * REQUEST_BACKOFF_SECONDS_INC, REQUEST_BACKOFF_SECONDS_MAX));
|
|
||||||
}
|
}
|
||||||
// Resume the connection.
|
|
||||||
Task req = _Simulator.Client.HttpCapsClient.PostRequestAsync(_Address, OSDFormat.Xml, payload, _HttpCts.Token,
|
|
||||||
RequestCompletedHandler);
|
|
||||||
|
|
||||||
// If the event queue is dead at this point, turn it off since
|
|
||||||
// that was the last thing we want to do
|
|
||||||
if (_Dead)
|
|
||||||
{
|
|
||||||
_Running = false;
|
|
||||||
Logger.DebugLog($"Sent event queue shutdown message for {_Simulator}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#pragma warning restore CS0164 // This label has not been referenced
|
|
||||||
|
|
||||||
#endregion Resume the connection
|
|
||||||
|
|
||||||
#region Handle incoming events
|
#region Handle incoming events
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Sjofn, LLC.
|
* Copyright (c) 2022-2023, Sjofn, LLC.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* - Redistribution and use in source and binary forms, with or without
|
* - Redistribution and use in source and binary forms, with or without
|
||||||
|
|
@ -233,6 +233,8 @@ namespace LibreMetaverse
|
||||||
|
|
||||||
private async Task SendRequestAsync(HttpRequestMessage request, CancellationToken? cancellationToken,
|
private async Task SendRequestAsync(HttpRequestMessage request, CancellationToken? cancellationToken,
|
||||||
DownloadCompleteHandler completeHandler, DownloadProgressHandler progressHandler, ConnectedHandler connectedHandler)
|
DownloadCompleteHandler completeHandler, DownloadProgressHandler progressHandler, ConnectedHandler connectedHandler)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using (var response = (cancellationToken.HasValue)
|
using (var response = (cancellationToken.HasValue)
|
||||||
? await SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken.Value)
|
? await SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken.Value)
|
||||||
|
|
@ -249,6 +251,11 @@ namespace LibreMetaverse
|
||||||
await ProcessResponseAsync(response, cancellationToken, completeHandler, progressHandler);
|
await ProcessResponseAsync(response, cancellationToken, completeHandler, progressHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
completeHandler?.Invoke(null, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task ProcessResponseAsync(HttpResponseMessage response, CancellationToken? cancellationToken,
|
private static async Task ProcessResponseAsync(HttpResponseMessage response, CancellationToken? cancellationToken,
|
||||||
DownloadCompleteHandler completeHandler, DownloadProgressHandler progressHandler)
|
DownloadCompleteHandler completeHandler, DownloadProgressHandler progressHandler)
|
||||||
|
|
|
||||||
|
|
@ -307,6 +307,7 @@ namespace OpenMetaverse
|
||||||
private void EventQueueConnectedHandler()
|
private void EventQueueConnectedHandler()
|
||||||
{
|
{
|
||||||
Logger.DebugLog($"Event queue for {Simulator} is connected", Simulator.Client);
|
Logger.DebugLog($"Event queue for {Simulator} is connected", Simulator.Client);
|
||||||
|
Simulator.DisconnectCandidate = false;
|
||||||
Simulator.Client.Network.RaiseConnectedEvent(Simulator);
|
Simulator.Client.Network.RaiseConnectedEvent(Simulator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,7 +334,7 @@ namespace OpenMetaverse
|
||||||
{
|
{
|
||||||
Logger.Log($"No Message handler exists for event {eventName}. Unable to decode. Will try Generic Handler next",
|
Logger.Log($"No Message handler exists for event {eventName}. Unable to decode. Will try Generic Handler next",
|
||||||
Helpers.LogLevel.Warning);
|
Helpers.LogLevel.Warning);
|
||||||
Logger.Log("Please report this information at https://radegast.life/bugs/issue-entry/: " + Environment.NewLine + body,
|
Logger.Log("Please report this information at https://github.com/cinderblocks/libremetaverse/issues: " + Environment.NewLine + body,
|
||||||
Helpers.LogLevel.Debug);
|
Helpers.LogLevel.Debug);
|
||||||
|
|
||||||
// try generic decoder next which takes a caps event and tries to match it to an existing packet
|
// try generic decoder next which takes a caps event and tries to match it to an existing packet
|
||||||
|
|
|
||||||
|
|
@ -1029,7 +1029,7 @@ namespace OpenMetaverse
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches Places for land owned by the specified group
|
/// Searches Places for land owned by the specified group
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="groupID">ID of the group you want to recieve land list for (You must be a member of the group)</param>
|
/// <param name="groupID">ID of the group you want to receive land list for (You must be a member of the group)</param>
|
||||||
/// <returns>Transaction (Query) ID which can be associated with results from your request.</returns>
|
/// <returns>Transaction (Query) ID which can be associated with results from your request.</returns>
|
||||||
public UUID StartPlacesSearch(UUID groupID)
|
public UUID StartPlacesSearch(UUID groupID)
|
||||||
{
|
{
|
||||||
|
|
@ -1055,7 +1055,7 @@ namespace OpenMetaverse
|
||||||
/// <param name="searchCategory">One of the values from the SearchCategory Struct, ie: Any, Linden, Newcomer</param>
|
/// <param name="searchCategory">One of the values from the SearchCategory Struct, ie: Any, Linden, Newcomer</param>
|
||||||
/// <param name="searchText">A string containing a list of keywords to search for separated by a space character</param>
|
/// <param name="searchText">A string containing a list of keywords to search for separated by a space character</param>
|
||||||
/// <param name="simulatorName">String Simulator Name to search in</param>
|
/// <param name="simulatorName">String Simulator Name to search in</param>
|
||||||
/// <param name="groupID">LLUID of group you want to recieve results for</param>
|
/// <param name="groupID">LLUID of group you want to receive results for</param>
|
||||||
/// <param name="transactionID">Transaction (Query) ID which can be associated with results from your request.</param>
|
/// <param name="transactionID">Transaction (Query) ID which can be associated with results from your request.</param>
|
||||||
/// <returns>Transaction (Query) ID which can be associated with results from your request.</returns>
|
/// <returns>Transaction (Query) ID which can be associated with results from your request.</returns>
|
||||||
public UUID StartPlacesSearch(DirFindFlags findFlags, ParcelCategory searchCategory, string searchText, string simulatorName,
|
public UUID StartPlacesSearch(DirFindFlags findFlags, ParcelCategory searchCategory, string searchText, string simulatorName,
|
||||||
|
|
|
||||||
|
|
@ -167,8 +167,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnTopCollidersReply(TopCollidersReplyEventArgs e)
|
protected virtual void OnTopCollidersReply(TopCollidersReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<TopCollidersReplyEventArgs> handler = m_TopCollidersReply;
|
EventHandler<TopCollidersReplyEventArgs> handler = m_TopCollidersReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -190,8 +189,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnTopScriptsReply(TopScriptsReplyEventArgs e)
|
protected virtual void OnTopScriptsReply(TopScriptsReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<TopScriptsReplyEventArgs> handler = m_TopScriptsReply;
|
EventHandler<TopScriptsReplyEventArgs> handler = m_TopScriptsReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -214,8 +212,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnEstateUsersReply(EstateUsersReplyEventArgs e)
|
protected virtual void OnEstateUsersReply(EstateUsersReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<EstateUsersReplyEventArgs> handler = m_EstateUsersReply;
|
EventHandler<EstateUsersReplyEventArgs> handler = m_EstateUsersReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -238,8 +235,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnEstateGroupsReply(EstateGroupsReplyEventArgs e)
|
protected virtual void OnEstateGroupsReply(EstateGroupsReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<EstateGroupsReplyEventArgs> handler = m_EstateGroupsReply;
|
EventHandler<EstateGroupsReplyEventArgs> handler = m_EstateGroupsReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -261,8 +257,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnEstateManagersReply(EstateManagersReplyEventArgs e)
|
protected virtual void OnEstateManagersReply(EstateManagersReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<EstateManagersReplyEventArgs> handler = m_EstateManagersReply;
|
EventHandler<EstateManagersReplyEventArgs> handler = m_EstateManagersReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -284,8 +279,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnEstateBansReply(EstateBansReplyEventArgs e)
|
protected virtual void OnEstateBansReply(EstateBansReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<EstateBansReplyEventArgs> handler = m_EstateBansReply;
|
EventHandler<EstateBansReplyEventArgs> handler = m_EstateBansReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -307,8 +301,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnEstateCovenantReply(EstateCovenantReplyEventArgs e)
|
protected virtual void OnEstateCovenantReply(EstateCovenantReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<EstateCovenantReplyEventArgs> handler = m_EstateCovenantReply;
|
EventHandler<EstateCovenantReplyEventArgs> handler = m_EstateCovenantReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -331,8 +324,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnEstateUpdateInfoReply(EstateUpdateInfoReplyEventArgs e)
|
protected virtual void OnEstateUpdateInfoReply(EstateUpdateInfoReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<EstateUpdateInfoReplyEventArgs> handler = m_EstateUpdateInfoReply;
|
EventHandler<EstateUpdateInfoReplyEventArgs> handler = m_EstateUpdateInfoReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
|
||||||
|
|
@ -218,8 +218,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnfriendsListReady(FriendsReadyEventArgs e)
|
protected virtual void OnfriendsListReady(FriendsReadyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<FriendsReadyEventArgs> handler = m_FriendsListReadyResponse;
|
EventHandler<FriendsReadyEventArgs> handler = m_FriendsListReadyResponse;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -240,8 +239,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnFriendOnline(FriendInfoEventArgs e)
|
protected virtual void OnFriendOnline(FriendInfoEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<FriendInfoEventArgs> handler = m_FriendOnline;
|
EventHandler<FriendInfoEventArgs> handler = m_FriendOnline;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -263,8 +261,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnFriendOffline(FriendInfoEventArgs e)
|
protected virtual void OnFriendOffline(FriendInfoEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<FriendInfoEventArgs> handler = m_FriendOffline;
|
EventHandler<FriendInfoEventArgs> handler = m_FriendOffline;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -286,8 +283,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnFriendRights(FriendInfoEventArgs e)
|
protected virtual void OnFriendRights(FriendInfoEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<FriendInfoEventArgs> handler = m_FriendRights;
|
EventHandler<FriendInfoEventArgs> handler = m_FriendRights;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -309,8 +305,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnFriendNames(FriendNamesEventArgs e)
|
protected virtual void OnFriendNames(FriendNamesEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<FriendNamesEventArgs> handler = m_FriendNames;
|
EventHandler<FriendNamesEventArgs> handler = m_FriendNames;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -332,8 +327,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnFriendshipOffered(FriendshipOfferedEventArgs e)
|
protected virtual void OnFriendshipOffered(FriendshipOfferedEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<FriendshipOfferedEventArgs> handler = m_FriendshipOffered;
|
EventHandler<FriendshipOfferedEventArgs> handler = m_FriendshipOffered;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -355,8 +349,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnFriendshipResponse(FriendshipResponseEventArgs e)
|
protected virtual void OnFriendshipResponse(FriendshipResponseEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<FriendshipResponseEventArgs> handler = m_FriendshipResponse;
|
EventHandler<FriendshipResponseEventArgs> handler = m_FriendshipResponse;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -378,8 +371,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnFriendshipTerminated(FriendshipTerminatedEventArgs e)
|
protected virtual void OnFriendshipTerminated(FriendshipTerminatedEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<FriendshipTerminatedEventArgs> handler = m_FriendshipTerminated;
|
EventHandler<FriendshipTerminatedEventArgs> handler = m_FriendshipTerminated;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -402,8 +394,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnFriendFoundReply(FriendFoundReplyEventArgs e)
|
protected virtual void OnFriendFoundReply(FriendFoundReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<FriendFoundReplyEventArgs> handler = m_FriendFound;
|
EventHandler<FriendFoundReplyEventArgs> handler = m_FriendFound;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,6 @@ namespace OpenMetaverse
|
||||||
{
|
{
|
||||||
AllowAutoRedirect = true,
|
AllowAutoRedirect = true,
|
||||||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
|
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
|
||||||
MaxConnectionsPerServer = Settings.MAX_HTTP_CONNECTIONS,
|
|
||||||
ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
|
ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
|
||||||
{
|
{
|
||||||
if (sslPolicyErrors == SslPolicyErrors.None)
|
if (sslPolicyErrors == SslPolicyErrors.None)
|
||||||
|
|
@ -157,6 +156,10 @@ namespace OpenMetaverse
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (Utils.GetRunningRuntime() != Utils.Runtime.Mono)
|
||||||
|
handler.MaxConnectionsPerServer = Settings.MAX_HTTP_CONNECTIONS;
|
||||||
|
|
||||||
HttpCapsClient client = new HttpCapsClient(handler);
|
HttpCapsClient client = new HttpCapsClient(handler);
|
||||||
client.DefaultRequestHeaders.Accept.Clear();
|
client.DefaultRequestHeaders.Accept.Clear();
|
||||||
client.DefaultRequestHeaders.Add("User-Agent", $"{Settings.USER_AGENT}");
|
client.DefaultRequestHeaders.Add("User-Agent", $"{Settings.USER_AGENT}");
|
||||||
|
|
|
||||||
|
|
@ -158,14 +158,15 @@ namespace OpenMetaverse
|
||||||
public uint GlobalY;
|
public uint GlobalY;
|
||||||
|
|
||||||
/// <summary>Get the Local X position of the item</summary>
|
/// <summary>Get the Local X position of the item</summary>
|
||||||
public uint LocalX { get { return GlobalX % 256; } }
|
public uint LocalX { get { return GlobalX % Simulator.DefaultRegionSizeX; } }
|
||||||
/// <summary>Get the Local Y position of the item</summary>
|
/// <summary>Get the Local Y position of the item</summary>
|
||||||
public uint LocalY { get { return GlobalY % 256; } }
|
public uint LocalY { get { return GlobalY % Simulator.DefaultRegionSizeY; } }
|
||||||
|
|
||||||
/// <summary>Get the Handle of the region</summary>
|
/// <summary>Get the Handle of the region</summary>
|
||||||
public ulong RegionHandle
|
public ulong RegionHandle
|
||||||
{
|
{
|
||||||
get { return Utils.UIntsToLong((uint)(GlobalX - (GlobalX % 256)), (uint)(GlobalY - (GlobalY % 256))); }
|
get { return Utils.UIntsToLong((uint)(GlobalX - (GlobalX % Simulator.DefaultRegionSizeX)),
|
||||||
|
(uint)(GlobalY - (GlobalY % Simulator.DefaultRegionSizeY))); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1047,9 +1047,7 @@ namespace OpenMetaverse
|
||||||
UUID requestID = UUID.Random();
|
UUID requestID = UUID.Random();
|
||||||
Uri cap = null;
|
Uri cap = null;
|
||||||
|
|
||||||
if (Client.Network.CurrentSim != null
|
if ((cap = Client.Network.CurrentSim?.Caps?.CapabilityURI("GroupMemberData")) != null)
|
||||||
&& Client.Network.CurrentSim.Caps != null
|
|
||||||
&& (cap = Client.Network.CurrentSim.Caps.CapabilityURI("GroupMemberData")) != null)
|
|
||||||
{
|
{
|
||||||
OSDMap payload = new OSDMap(1) { ["group_id"] = @group };
|
OSDMap payload = new OSDMap(1) { ["group_id"] = @group };
|
||||||
Task req = Client.HttpCapsClient.PostRequestAsync(cap, OSDFormat.Xml, payload, CancellationToken.None,
|
Task req = Client.HttpCapsClient.PostRequestAsync(cap, OSDFormat.Xml, payload, CancellationToken.None,
|
||||||
|
|
@ -1630,11 +1628,9 @@ namespace OpenMetaverse
|
||||||
{
|
{
|
||||||
Uri ret = null;
|
Uri ret = null;
|
||||||
|
|
||||||
if (Client.Network.Connected
|
if (Client.Network.Connected)
|
||||||
&& Client.Network.CurrentSim != null
|
|
||||||
&& Client.Network.CurrentSim.Caps != null)
|
|
||||||
{
|
{
|
||||||
ret = Client.Network.CurrentSim.Caps.CapabilityURI("GroupAPIv1");
|
ret = Client.Network.CurrentSim?.Caps?.CapabilityURI("GroupAPIv1");
|
||||||
if (ret != null)
|
if (ret != null)
|
||||||
{
|
{
|
||||||
ret = new Uri($"{ret}?group_id={groupID.ToString()}");
|
ret = new Uri($"{ret}?group_id={groupID.ToString()}");
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,11 @@ namespace OpenMetaverse
|
||||||
/// Given an X/Y location in absolute (grid-relative) terms, a region
|
/// Given an X/Y location in absolute (grid-relative) terms, a region
|
||||||
/// handle is returned along with the local X/Y location in that region
|
/// handle is returned along with the local X/Y location in that region
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// NOTE: this does not work for varregions -- the region handle is correct but
|
||||||
|
/// the local X,Y are wrong. TODO: create new function
|
||||||
|
/// that takes a reference to the region and thus can calculate region local address.
|
||||||
|
/// </remarks>
|
||||||
/// <param name="globalX">The absolute X location, a number such as
|
/// <param name="globalX">The absolute X location, a number such as
|
||||||
/// 255360.35</param>
|
/// 255360.35</param>
|
||||||
/// <param name="globalY">The absolute Y location, a number such as
|
/// <param name="globalY">The absolute Y location, a number such as
|
||||||
|
|
@ -160,8 +165,8 @@ namespace OpenMetaverse
|
||||||
/// <returns>A 64-bit region handle that can be used to teleport to</returns>
|
/// <returns>A 64-bit region handle that can be used to teleport to</returns>
|
||||||
public static ulong GlobalPosToRegionHandle(float globalX, float globalY, out float localX, out float localY)
|
public static ulong GlobalPosToRegionHandle(float globalX, float globalY, out float localX, out float localY)
|
||||||
{
|
{
|
||||||
uint x = ((uint)globalX / 256) * 256;
|
uint x = ((uint)globalX / Simulator.DefaultRegionSizeX) * Simulator.DefaultRegionSizeX;
|
||||||
uint y = ((uint)globalY / 256) * 256;
|
uint y = ((uint)globalY / Simulator.DefaultRegionSizeY) * Simulator.DefaultRegionSizeY;
|
||||||
localX = globalX - (float)x;
|
localX = globalX - (float)x;
|
||||||
localY = globalY - (float)y;
|
localY = globalY - (float)y;
|
||||||
return Utils.UIntsToLong(x, y);
|
return Utils.UIntsToLong(x, y);
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,8 @@ namespace OpenMetaverse.ImportExport
|
||||||
Client.Inventory.RequestFetchInventory(reply["new_inventory_item"].AsUUID(), Client.Self.AgentID);
|
Client.Inventory.RequestFetchInventory(reply["new_inventory_item"].AsUUID(), Client.Self.AgentID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (callback != null) callback(contents);
|
|
||||||
|
callback?.Invoke(contents);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,7 @@ namespace LibreMetaverse
|
||||||
Client = client;
|
Client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAvailable => (Client.Network.CurrentSim.Caps != null &&
|
public bool IsAvailable => (Client.Network.CurrentSim.Caps?.CapabilityURI(INVENTORY_CAP_NAME) != null);
|
||||||
Client.Network.CurrentSim.Caps.CapabilityURI(INVENTORY_CAP_NAME) != null);
|
|
||||||
|
|
||||||
public async Task CreateInventory(UUID parentUuid, OSD newInventory, bool createLink, InventoryManager.ItemCreatedCallback callback)
|
public async Task CreateInventory(UUID parentUuid, OSD newInventory, bool createLink, InventoryManager.ItemCreatedCallback callback)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -582,8 +582,7 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
|
|
||||||
Uri cap;
|
Uri cap;
|
||||||
if (Client.Network.CurrentSim.Caps != null &&
|
if ((cap = Client.Network.CurrentSim?.Caps?.CapabilityURI("FetchInventory2")) != null)
|
||||||
(cap = Client.Network.CurrentSim.Caps.CapabilityURI("FetchInventory2")) != null)
|
|
||||||
{
|
{
|
||||||
OSDMap payload = new OSDMap { ["agent_id"] = Client.Self.AgentID };
|
OSDMap payload = new OSDMap { ["agent_id"] = Client.Self.AgentID };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||||
<NoWarn>0419,1574,1591</NoWarn>
|
<NoWarn>0419,1574,1591</NoWarn>
|
||||||
<TargetFrameworks>net48;netstandard2.1;net6.0;net7.0</TargetFrameworks>
|
<TargetFrameworks>net7.0</TargetFrameworks>
|
||||||
<Platforms>x64;x86;AnyCPU</Platforms>
|
<Platforms>x64;x86;AnyCPU</Platforms>
|
||||||
<OutputPath>..\bin\</OutputPath>
|
<OutputPath>..\bin\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
@ -44,8 +44,8 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="log4net" Version="2.0.15" />
|
<PackageReference Include="log4net" Version="2.0.15" />
|
||||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.9" />
|
||||||
<PackageReference Include="OggVorbisEncoder" Version="1.2.1" />
|
<PackageReference Include="OggVorbisEncoder" Version="1.2.2" />
|
||||||
<PackageReference Include="OpenJpegDotNet-LMV" Version="2.4.0.5" />
|
<PackageReference Include="OpenJpegDotNet-LMV" Version="2.4.0.5" />
|
||||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||||
|
|
|
||||||
|
|
@ -369,6 +369,8 @@ namespace OpenMetaverse
|
||||||
public int CircuitCode;
|
public int CircuitCode;
|
||||||
public uint RegionX;
|
public uint RegionX;
|
||||||
public uint RegionY;
|
public uint RegionY;
|
||||||
|
public uint RegionSizeX;
|
||||||
|
public uint RegionSizeY;
|
||||||
public ushort SimPort;
|
public ushort SimPort;
|
||||||
public IPAddress SimIP;
|
public IPAddress SimIP;
|
||||||
public string SeedCapability;
|
public string SeedCapability;
|
||||||
|
|
@ -488,6 +490,9 @@ namespace OpenMetaverse
|
||||||
CircuitCode = (int)ParseUInt("circuit_code", reply);
|
CircuitCode = (int)ParseUInt("circuit_code", reply);
|
||||||
RegionX = ParseUInt("region_x", reply);
|
RegionX = ParseUInt("region_x", reply);
|
||||||
RegionY = ParseUInt("region_y", reply);
|
RegionY = ParseUInt("region_y", reply);
|
||||||
|
// Region size is returned by OpenSimulator derived systems but not SL
|
||||||
|
RegionSizeX = reply.ContainsKey("region_size_x") ? ParseUInt("region_size_x", reply) : Simulator.DefaultRegionSizeX;
|
||||||
|
RegionSizeY = reply.ContainsKey("region_size_y") ? ParseUInt("region_size_y", reply) : Simulator.DefaultRegionSizeY;
|
||||||
SimPort = (ushort)ParseUInt("sim_port", reply);
|
SimPort = (ushort)ParseUInt("sim_port", reply);
|
||||||
var simIP = ParseString("sim_ip", reply);
|
var simIP = ParseString("sim_ip", reply);
|
||||||
IPAddress.TryParse(simIP, out SimIP);
|
IPAddress.TryParse(simIP, out SimIP);
|
||||||
|
|
@ -693,6 +698,9 @@ namespace OpenMetaverse
|
||||||
CircuitCode = (int)ParseUInt("circuit_code", reply);
|
CircuitCode = (int)ParseUInt("circuit_code", reply);
|
||||||
RegionX = ParseUInt("region_x", reply);
|
RegionX = ParseUInt("region_x", reply);
|
||||||
RegionY = ParseUInt("region_y", reply);
|
RegionY = ParseUInt("region_y", reply);
|
||||||
|
// Region size is returned by OpenSimulator derived systems but not SL
|
||||||
|
RegionSizeX = reply.ContainsKey("region_size_x") ? ParseUInt("region_size_x", reply) : Simulator.DefaultRegionSizeX;
|
||||||
|
RegionSizeY = reply.ContainsKey("region_size_y") ? ParseUInt("region_size_y", reply) : Simulator.DefaultRegionSizeY;
|
||||||
SimPort = (ushort)ParseUInt("sim_port", reply);
|
SimPort = (ushort)ParseUInt("sim_port", reply);
|
||||||
var simIP = ParseString("sim_ip", reply);
|
var simIP = ParseString("sim_ip", reply);
|
||||||
IPAddress.TryParse(simIP, out SimIP);
|
IPAddress.TryParse(simIP, out SimIP);
|
||||||
|
|
@ -1691,7 +1699,7 @@ namespace OpenMetaverse
|
||||||
var handle = Utils.UIntsToLong(regionX, regionY);
|
var handle = Utils.UIntsToLong(regionX, regionY);
|
||||||
|
|
||||||
// Connect to the sim given in the login reply
|
// Connect to the sim given in the login reply
|
||||||
if (Connect(reply.SimIP, simPort, handle, true, LoginSeedCapability) != null)
|
if (Connect(reply.SimIP, simPort, handle, true, LoginSeedCapability, reply.RegionSizeX, reply.RegionSizeY) != null)
|
||||||
{
|
{
|
||||||
// Request the economy data right after login
|
// Request the economy data right after login
|
||||||
SendPacket(new EconomyDataRequestPacket());
|
SendPacket(new EconomyDataRequestPacket());
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2016, openmetaverse.co
|
* Copyright (c) 2006-2016, openmetaverse.co
|
||||||
* Copyright (c) 2021-2022, Sjofn LLC
|
* Copyright (c) 2021-2022, Sjofn LLC
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
|
@ -61,6 +61,10 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
/// <summary>Status flags indicating the state of the Agent upon arrival, Flying, etc.</summary>
|
/// <summary>Status flags indicating the state of the Agent upon arrival, Flying, etc.</summary>
|
||||||
public TeleportFlags Flags;
|
public TeleportFlags Flags;
|
||||||
|
|
||||||
|
/// <summary> The size of the region teleporting into </summary>
|
||||||
|
public uint RegionSizeX;
|
||||||
|
public uint RegionSizeY;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serialize the object
|
/// Serialize the object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -71,7 +75,7 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
|
|
||||||
OSDArray infoArray = new OSDArray(1);
|
OSDArray infoArray = new OSDArray(1);
|
||||||
|
|
||||||
OSDMap info = new OSDMap(8)
|
OSDMap info = new OSDMap(10)
|
||||||
{
|
{
|
||||||
{"AgentID", OSD.FromUUID(AgentID)},
|
{"AgentID", OSD.FromUUID(AgentID)},
|
||||||
{"LocationID", OSD.FromInteger(LocationID)},
|
{"LocationID", OSD.FromInteger(LocationID)},
|
||||||
|
|
@ -80,7 +84,9 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
{"SimAccess", OSD.FromInteger((byte) SimAccess)},
|
{"SimAccess", OSD.FromInteger((byte) SimAccess)},
|
||||||
{"SimIP", MessageUtils.FromIP(IP)},
|
{"SimIP", MessageUtils.FromIP(IP)},
|
||||||
{"SimPort", OSD.FromInteger(Port)},
|
{"SimPort", OSD.FromInteger(Port)},
|
||||||
{"TeleportFlags", OSD.FromUInteger((uint) Flags)}
|
{"TeleportFlags", OSD.FromUInteger((uint) Flags)},
|
||||||
|
{"RegionSizeX", OSD.FromUInteger((uint) RegionSizeX)},
|
||||||
|
{"RegionSizeY", OSD.FromUInteger((uint) RegionSizeY)}
|
||||||
};
|
};
|
||||||
// Unused by the client
|
// Unused by the client
|
||||||
|
|
||||||
|
|
@ -108,6 +114,8 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
IP = MessageUtils.ToIP(blockMap["SimIP"]);
|
IP = MessageUtils.ToIP(blockMap["SimIP"]);
|
||||||
Port = blockMap["SimPort"].AsInteger();
|
Port = blockMap["SimPort"].AsInteger();
|
||||||
Flags = (TeleportFlags)blockMap["TeleportFlags"].AsUInteger();
|
Flags = (TeleportFlags)blockMap["TeleportFlags"].AsUInteger();
|
||||||
|
RegionSizeX = blockMap.ContainsKey("RegionSizeX") ? blockMap["RegionSizeX"].AsUInteger() : Simulator.DefaultRegionSizeX;
|
||||||
|
RegionSizeY = blockMap.ContainsKey("RegionSizeY") ? blockMap["RegionSizeY"].AsUInteger() : Simulator.DefaultRegionSizeY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,6 +170,8 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
public Uri SeedCapability;
|
public Uri SeedCapability;
|
||||||
public IPAddress IP;
|
public IPAddress IP;
|
||||||
public int Port;
|
public int Port;
|
||||||
|
public uint RegionSizeX;
|
||||||
|
public uint RegionSizeY;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serialize the object
|
/// Serialize the object
|
||||||
|
|
@ -190,12 +200,14 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
map["AgentData"] = agentDataArray;
|
map["AgentData"] = agentDataArray;
|
||||||
|
|
||||||
OSDArray regionDataArray = new OSDArray(1);
|
OSDArray regionDataArray = new OSDArray(1);
|
||||||
OSDMap regionDataMap = new OSDMap(4)
|
OSDMap regionDataMap = new OSDMap(6)
|
||||||
{
|
{
|
||||||
["RegionHandle"] = OSD.FromULong(RegionHandle),
|
["RegionHandle"] = OSD.FromULong(RegionHandle),
|
||||||
["SeedCapability"] = OSD.FromUri(SeedCapability),
|
["SeedCapability"] = OSD.FromUri(SeedCapability),
|
||||||
["SimIP"] = MessageUtils.FromIP(IP),
|
["SimIP"] = MessageUtils.FromIP(IP),
|
||||||
["SimPort"] = OSD.FromInteger(Port)
|
["SimPort"] = OSD.FromInteger(Port),
|
||||||
|
["RegionSizeX"] = OSD.FromUInteger(RegionSizeX),
|
||||||
|
["RegionSizeY"] = OSD.FromUInteger(RegionSizeY)
|
||||||
};
|
};
|
||||||
regionDataArray.Add(regionDataMap);
|
regionDataArray.Add(regionDataMap);
|
||||||
map["RegionData"] = regionDataArray;
|
map["RegionData"] = regionDataArray;
|
||||||
|
|
@ -222,6 +234,8 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
SeedCapability = regionDataMap["SeedCapability"].AsUri();
|
SeedCapability = regionDataMap["SeedCapability"].AsUri();
|
||||||
IP = MessageUtils.ToIP(regionDataMap["SimIP"]);
|
IP = MessageUtils.ToIP(regionDataMap["SimIP"]);
|
||||||
Port = regionDataMap["SimPort"].AsInteger();
|
Port = regionDataMap["SimPort"].AsInteger();
|
||||||
|
RegionSizeX = regionDataMap.ContainsKey("RegionSizeX") ? regionDataMap["RegionSizeX"].AsUInteger() : Simulator.DefaultRegionSizeX;
|
||||||
|
RegionSizeY = regionDataMap.ContainsKey("RegionSizeY") ? regionDataMap["RegionSizeY"].AsUInteger() : Simulator.DefaultRegionSizeY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,6 +246,8 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
public ulong RegionHandle;
|
public ulong RegionHandle;
|
||||||
public IPAddress IP;
|
public IPAddress IP;
|
||||||
public int Port;
|
public int Port;
|
||||||
|
public uint RegionSizeX;
|
||||||
|
public uint RegionSizeY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimulatorInfoBlock[] Simulators;
|
public SimulatorInfoBlock[] Simulators;
|
||||||
|
|
@ -247,11 +263,13 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
OSDArray array = new OSDArray(Simulators.Length);
|
OSDArray array = new OSDArray(Simulators.Length);
|
||||||
foreach (SimulatorInfoBlock block in Simulators)
|
foreach (SimulatorInfoBlock block in Simulators)
|
||||||
{
|
{
|
||||||
OSDMap blockMap = new OSDMap(3)
|
OSDMap blockMap = new OSDMap(5)
|
||||||
{
|
{
|
||||||
["Handle"] = OSD.FromULong(block.RegionHandle),
|
["Handle"] = OSD.FromULong(block.RegionHandle),
|
||||||
["IP"] = MessageUtils.FromIP(block.IP),
|
["IP"] = MessageUtils.FromIP(block.IP),
|
||||||
["Port"] = OSD.FromInteger(block.Port)
|
["Port"] = OSD.FromInteger(block.Port),
|
||||||
|
["RegionSizeX"] = OSD.FromUInteger(block.RegionSizeX),
|
||||||
|
["RegionSizeY"] = OSD.FromUInteger(block.RegionSizeY),
|
||||||
};
|
};
|
||||||
array.Add(blockMap);
|
array.Add(blockMap);
|
||||||
}
|
}
|
||||||
|
|
@ -277,7 +295,9 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
{
|
{
|
||||||
RegionHandle = blockMap["Handle"].AsULong(),
|
RegionHandle = blockMap["Handle"].AsULong(),
|
||||||
IP = MessageUtils.ToIP(blockMap["IP"]),
|
IP = MessageUtils.ToIP(blockMap["IP"]),
|
||||||
Port = blockMap["Port"].AsInteger()
|
Port = blockMap["Port"].AsInteger(),
|
||||||
|
RegionSizeX = blockMap.ContainsKey("RegionSizeX") ? blockMap["RegionSizeX"].AsUInteger() : Simulator.DefaultRegionSizeX,
|
||||||
|
RegionSizeY = blockMap.ContainsKey("RegionSizeY") ? blockMap["RegionSizeY"].AsUInteger() : Simulator.DefaultRegionSizeY,
|
||||||
};
|
};
|
||||||
Simulators[i] = block;
|
Simulators[i] = block;
|
||||||
}
|
}
|
||||||
|
|
@ -5395,7 +5415,7 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Message recieved in response to request to change display name
|
/// Message received in response to request to change display name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SetDisplayNameReplyMessage : IMessage
|
public class SetDisplayNameReplyMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -5434,7 +5454,7 @@ namespace OpenMetaverse.Messages.Linden
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Message recieved when someone nearby changes their display name
|
/// Message received when someone nearby changes their display name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DisplayNameUpdateMessage : IMessage
|
public class DisplayNameUpdateMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -504,7 +504,7 @@ namespace OpenMetaverse
|
||||||
if (dif > 10)
|
if (dif > 10)
|
||||||
{
|
{
|
||||||
lastpacketwarning = now;
|
lastpacketwarning = now;
|
||||||
Logger.Log(source+" is null (Are we disconnected?) - from: "+ function,
|
Logger.Log(source+" is null (Are we disconnected?) - from: " + function,
|
||||||
Helpers.LogLevel.Debug);
|
Helpers.LogLevel.Debug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -526,6 +526,19 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connect to simulator assuming legacy region size
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ip">IP address to connect to</param>
|
||||||
|
/// <param name="port">Port to connect to</param>
|
||||||
|
/// <param name="handle"></param>
|
||||||
|
/// <param name="setDefault"></param>
|
||||||
|
/// <param name="seedcaps"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Simulator Connect(IPAddress ip, ushort port, ulong handle, bool setDefault, Uri seedcaps)
|
||||||
|
{
|
||||||
|
return Connect(ip, port, handle, setDefault, seedcaps, Simulator.DefaultRegionSizeX, Simulator.DefaultRegionSizeY);
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connect to a simulator
|
/// Connect to a simulator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -537,13 +550,26 @@ namespace OpenMetaverse
|
||||||
/// connection, use this if the avatar is moving in to this simulator</param>
|
/// connection, use this if the avatar is moving in to this simulator</param>
|
||||||
/// <param name="seedcaps">URL of the capabilities server to use for
|
/// <param name="seedcaps">URL of the capabilities server to use for
|
||||||
/// this sim connection</param>
|
/// this sim connection</param>
|
||||||
|
/// <param name="sizeX">Size of the region in X meters</param>
|
||||||
|
/// <param name="sizeY">Size of the region in Y meters</param>
|
||||||
/// <returns>A Simulator object on success, otherwise null</returns>
|
/// <returns>A Simulator object on success, otherwise null</returns>
|
||||||
public Simulator Connect(IPAddress ip, ushort port, ulong handle, bool setDefault, Uri seedcaps)
|
public Simulator Connect(IPAddress ip, ushort port, ulong handle, bool setDefault, Uri seedcaps, uint sizeX, uint sizeY)
|
||||||
{
|
{
|
||||||
IPEndPoint endPoint = new IPEndPoint(ip, port);
|
IPEndPoint endPoint = new IPEndPoint(ip, port);
|
||||||
return Connect(endPoint, handle, setDefault, seedcaps);
|
return Connect(endPoint, handle, setDefault, seedcaps, sizeX, sizeY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connect to simulator assuming legacy region size
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="endPoint"></param>
|
||||||
|
/// <param name="handle"></param>
|
||||||
|
/// <param name="setDefault"></param>
|
||||||
|
/// <param name="seedcaps"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Simulator Connect(IPEndPoint endPoint, ulong handle, bool setDefault, Uri seedcaps) {
|
||||||
|
return Connect(endPoint, handle, setDefault, seedcaps, Simulator.DefaultRegionSizeX, Simulator.DefaultRegionSizeY);
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connect to a simulator
|
/// Connect to a simulator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -554,15 +580,17 @@ namespace OpenMetaverse
|
||||||
/// connection, use this if the avatar is moving in to this simulator</param>
|
/// connection, use this if the avatar is moving in to this simulator</param>
|
||||||
/// <param name="seedcaps">URL of the capabilities server to use for
|
/// <param name="seedcaps">URL of the capabilities server to use for
|
||||||
/// this sim connection</param>
|
/// this sim connection</param>
|
||||||
|
/// <param name="sizeX">Size of the region in X meters</param>
|
||||||
|
/// <param name="sizeY">Size of the region in Y meters</param>
|
||||||
/// <returns>A Simulator object on success, otherwise null</returns>
|
/// <returns>A Simulator object on success, otherwise null</returns>
|
||||||
public Simulator Connect(IPEndPoint endPoint, ulong handle, bool setDefault, Uri seedcaps)
|
public Simulator Connect(IPEndPoint endPoint, ulong handle, bool setDefault, Uri seedcaps, uint sizeX, uint sizeY)
|
||||||
{
|
{
|
||||||
Simulator simulator = FindSimulator(endPoint);
|
Simulator simulator = FindSimulator(endPoint);
|
||||||
|
|
||||||
if (simulator == null)
|
if (simulator == null)
|
||||||
{
|
{
|
||||||
// We're not tracking this sim, create a new Simulator object
|
// We're not tracking this sim, create a new Simulator object
|
||||||
simulator = new Simulator(Client, endPoint, handle);
|
simulator = new Simulator(Client, endPoint, handle, sizeX, sizeY);
|
||||||
|
|
||||||
// Immediately add this simulator to the list of current sims. It will be removed if the
|
// Immediately add this simulator to the list of current sims. It will be removed if the
|
||||||
// connection fails
|
// connection fails
|
||||||
|
|
@ -682,13 +710,13 @@ namespace OpenMetaverse
|
||||||
// Otherwise we fire it manually with a NetworkTimeout type after LOGOUT_TIMEOUT
|
// Otherwise we fire it manually with a NetworkTimeout type after LOGOUT_TIMEOUT
|
||||||
System.Timers.Timer timeout = new System.Timers.Timer();
|
System.Timers.Timer timeout = new System.Timers.Timer();
|
||||||
|
|
||||||
EventHandler<LoggedOutEventArgs> callback = delegate
|
void Callback(object sender, LoggedOutEventArgs e)
|
||||||
{
|
{
|
||||||
Shutdown(DisconnectType.ClientInitiated);
|
Shutdown(DisconnectType.ClientInitiated);
|
||||||
timeout.Stop();
|
timeout.Stop();
|
||||||
};
|
}
|
||||||
|
|
||||||
LoggedOut += callback;
|
LoggedOut += Callback;
|
||||||
|
|
||||||
timeout.Interval = Client.Settings.LOGOUT_TIMEOUT;
|
timeout.Interval = Client.Settings.LOGOUT_TIMEOUT;
|
||||||
timeout.Elapsed += delegate
|
timeout.Elapsed += delegate
|
||||||
|
|
@ -702,7 +730,7 @@ namespace OpenMetaverse
|
||||||
// Send the packet requesting a clean logout
|
// Send the packet requesting a clean logout
|
||||||
RequestLogout();
|
RequestLogout();
|
||||||
|
|
||||||
LoggedOut -= callback;
|
LoggedOut -= Callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -713,9 +741,13 @@ namespace OpenMetaverse
|
||||||
public void Logout()
|
public void Logout()
|
||||||
{
|
{
|
||||||
AutoResetEvent logoutEvent = new AutoResetEvent(false);
|
AutoResetEvent logoutEvent = new AutoResetEvent(false);
|
||||||
EventHandler<LoggedOutEventArgs> callback = delegate { logoutEvent.Set(); };
|
|
||||||
|
|
||||||
LoggedOut += callback;
|
void Callback(object sender, LoggedOutEventArgs e)
|
||||||
|
{
|
||||||
|
logoutEvent.Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggedOut += Callback;
|
||||||
|
|
||||||
// Send the packet requesting a clean logout
|
// Send the packet requesting a clean logout
|
||||||
RequestLogout();
|
RequestLogout();
|
||||||
|
|
@ -724,9 +756,11 @@ namespace OpenMetaverse
|
||||||
// will be fired in the callback. Otherwise we fire it manually with
|
// will be fired in the callback. Otherwise we fire it manually with
|
||||||
// a NetworkTimeout type
|
// a NetworkTimeout type
|
||||||
if (!logoutEvent.WaitOne(Client.Settings.LOGOUT_TIMEOUT, false))
|
if (!logoutEvent.WaitOne(Client.Settings.LOGOUT_TIMEOUT, false))
|
||||||
|
{
|
||||||
Shutdown(DisconnectType.NetworkTimeout);
|
Shutdown(DisconnectType.NetworkTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
LoggedOut -= callback;
|
LoggedOut -= Callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -787,7 +821,10 @@ namespace OpenMetaverse
|
||||||
simulatorsCount = Simulators.Count;
|
simulatorsCount = Simulators.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simulatorsCount == 0) Shutdown(DisconnectType.SimShutdown);
|
if (simulatorsCount == 0)
|
||||||
|
{
|
||||||
|
Shutdown(DisconnectType.SimShutdown, $"You have disconnected from {simulator.Name}.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -797,10 +834,13 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shutdown will disconnect all the sims except for the current sim
|
/// This method disconnects Client from all simulators leaving CurrentSim
|
||||||
/// first, and then kill the connection to CurrentSim. This should only
|
/// last to disconnect.
|
||||||
/// be called if the logout process times out on <code>RequestLogout</code>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This should only be called if the logout process times out on
|
||||||
|
/// <code>RequestLogout</code>
|
||||||
|
/// </remarks>
|
||||||
/// <param name="type">Type of shutdown</param>
|
/// <param name="type">Type of shutdown</param>
|
||||||
public void Shutdown(DisconnectType type)
|
public void Shutdown(DisconnectType type)
|
||||||
{
|
{
|
||||||
|
|
@ -808,10 +848,13 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shutdown will disconnect all the sims except for the current sim
|
/// This method disconnects Client from all simulators leaving CurrentSim
|
||||||
/// first, and then kill the connection to CurrentSim. This should only
|
/// last to disconnect.
|
||||||
/// be called if the logout process times out on <code>RequestLogout</code>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This should only be called if the logout process times out on
|
||||||
|
/// <code>RequestLogout</code>
|
||||||
|
/// </remarks>
|
||||||
/// <param name="type">Type of shutdown</param>
|
/// <param name="type">Type of shutdown</param>
|
||||||
/// <param name="message">Shutdown message</param>
|
/// <param name="message">Shutdown message</param>
|
||||||
public void Shutdown(DisconnectType type, string message)
|
public void Shutdown(DisconnectType type, string message)
|
||||||
|
|
@ -824,17 +867,14 @@ namespace OpenMetaverse
|
||||||
lock (Simulators)
|
lock (Simulators)
|
||||||
{
|
{
|
||||||
// Disconnect all simulators except the current one
|
// Disconnect all simulators except the current one
|
||||||
foreach (Simulator t in Simulators)
|
foreach (var sim in Simulators.Where(t => t != null && t != CurrentSim))
|
||||||
{
|
{
|
||||||
if (t != null && t != CurrentSim)
|
sim.Disconnect(sendCloseCircuit);
|
||||||
{
|
|
||||||
t.Disconnect(sendCloseCircuit);
|
|
||||||
|
|
||||||
// Fire the SimDisconnected event if a handler is registered
|
// Fire the SimDisconnected event if a handler is registered
|
||||||
if (m_SimDisconnected != null)
|
if (m_SimDisconnected != null)
|
||||||
{
|
{
|
||||||
OnSimDisconnected(new SimDisconnectedEventArgs(t, type));
|
OnSimDisconnected(new SimDisconnectedEventArgs(sim, type));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -843,7 +883,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
if (CurrentSim != null)
|
if (CurrentSim != null)
|
||||||
{
|
{
|
||||||
// Kill the connection to the curent simulator
|
// Kill the connection to the current simulator
|
||||||
CurrentSim.Disconnect(sendCloseCircuit);
|
CurrentSim.Disconnect(sendCloseCircuit);
|
||||||
|
|
||||||
// Fire the SimDisconnected event if a handler is registered
|
// Fire the SimDisconnected event if a handler is registered
|
||||||
|
|
@ -881,10 +921,9 @@ namespace OpenMetaverse
|
||||||
{
|
{
|
||||||
lock (Simulators)
|
lock (Simulators)
|
||||||
{
|
{
|
||||||
foreach (Simulator t in Simulators)
|
foreach (var sim in Simulators.Where(t => t.IPEndPoint.Equals(endPoint)))
|
||||||
{
|
{
|
||||||
if (t.IPEndPoint.Equals(endPoint))
|
return sim;
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1277,7 +1316,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
if (FindSimulator(endPoint) != null) return;
|
if (FindSimulator(endPoint) != null) return;
|
||||||
|
|
||||||
if (Connect(ip, port, handle, false, null) == null)
|
if (Connect(ip, port, handle, false, null, t.RegionSizeX, t.RegionSizeY) == null)
|
||||||
{
|
{
|
||||||
Logger.Log($"Unable to connect to new sim {ip}:{port}",
|
Logger.Log($"Unable to connect to new sim {ip}:{port}",
|
||||||
Helpers.LogLevel.Error, Client);
|
Helpers.LogLevel.Error, Client);
|
||||||
|
|
|
||||||
|
|
@ -198,8 +198,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnObjectProperties(ObjectPropertiesEventArgs e)
|
protected virtual void OnObjectProperties(ObjectPropertiesEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<ObjectPropertiesEventArgs> handler = m_ObjectProperties;
|
EventHandler<ObjectPropertiesEventArgs> handler = m_ObjectProperties;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -224,8 +223,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnObjectPropertiesUpdated(ObjectPropertiesUpdatedEventArgs e)
|
protected virtual void OnObjectPropertiesUpdated(ObjectPropertiesUpdatedEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<ObjectPropertiesUpdatedEventArgs> handler = m_ObjectPropertiesUpdated;
|
EventHandler<ObjectPropertiesUpdatedEventArgs> handler = m_ObjectPropertiesUpdated;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -250,8 +248,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnObjectPropertiesFamily(ObjectPropertiesFamilyEventArgs e)
|
protected virtual void OnObjectPropertiesFamily(ObjectPropertiesFamilyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<ObjectPropertiesFamilyEventArgs> handler = m_ObjectPropertiesFamily;
|
EventHandler<ObjectPropertiesFamilyEventArgs> handler = m_ObjectPropertiesFamily;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -278,8 +275,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnAvatarUpdate(AvatarUpdateEventArgs e)
|
protected virtual void OnAvatarUpdate(AvatarUpdateEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<AvatarUpdateEventArgs> handler = m_AvatarUpdate;
|
EventHandler<AvatarUpdateEventArgs> handler = m_AvatarUpdate;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raises the ParticleUpdate Event
|
/// Raises the ParticleUpdate Event
|
||||||
|
|
@ -288,8 +284,7 @@ namespace OpenMetaverse
|
||||||
/// the data sent from the simulator</param>
|
/// the data sent from the simulator</param>
|
||||||
protected virtual void OnParticleUpdate(ParticleUpdateEventArgs e) {
|
protected virtual void OnParticleUpdate(ParticleUpdateEventArgs e) {
|
||||||
EventHandler<ParticleUpdateEventArgs> handler = m_ParticleUpdate;
|
EventHandler<ParticleUpdateEventArgs> handler = m_ParticleUpdate;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -337,8 +332,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnObjectDataBlockUpdate(ObjectDataBlockUpdateEventArgs e)
|
protected virtual void OnObjectDataBlockUpdate(ObjectDataBlockUpdateEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<ObjectDataBlockUpdateEventArgs> handler = m_ObjectDataBlockUpdate;
|
EventHandler<ObjectDataBlockUpdateEventArgs> handler = m_ObjectDataBlockUpdate;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -363,8 +357,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnKillObject(KillObjectEventArgs e)
|
protected virtual void OnKillObject(KillObjectEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<KillObjectEventArgs> handler = m_KillObject;
|
EventHandler<KillObjectEventArgs> handler = m_KillObject;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -389,8 +382,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnKillObjects(KillObjectsEventArgs e)
|
protected virtual void OnKillObjects(KillObjectsEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<KillObjectsEventArgs> handler = m_KillObjects;
|
EventHandler<KillObjectsEventArgs> handler = m_KillObjects;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -415,8 +407,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnAvatarSitChanged(AvatarSitChangedEventArgs e)
|
protected virtual void OnAvatarSitChanged(AvatarSitChangedEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<AvatarSitChangedEventArgs> handler = m_AvatarSitChanged;
|
EventHandler<AvatarSitChangedEventArgs> handler = m_AvatarSitChanged;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -441,8 +432,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnPayPriceReply(PayPriceReplyEventArgs e)
|
protected virtual void OnPayPriceReply(PayPriceReplyEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<PayPriceReplyEventArgs> handler = m_PayPriceReply;
|
EventHandler<PayPriceReplyEventArgs> handler = m_PayPriceReply;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -475,8 +465,7 @@ namespace OpenMetaverse
|
||||||
protected virtual void OnPhysicsProperties(PhysicsPropertiesEventArgs e)
|
protected virtual void OnPhysicsProperties(PhysicsPropertiesEventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler<PhysicsPropertiesEventArgs> handler = m_PhysicsProperties;
|
EventHandler<PhysicsPropertiesEventArgs> handler = m_PhysicsProperties;
|
||||||
if (handler != null)
|
handler?.Invoke(this, e);
|
||||||
handler(this, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Thread sync lock object</summary>
|
/// <summary>Thread sync lock object</summary>
|
||||||
|
|
@ -2611,8 +2600,7 @@ namespace OpenMetaverse
|
||||||
#region Raise Events
|
#region Raise Events
|
||||||
|
|
||||||
EventHandler<PrimEventArgs> handler = m_ObjectUpdate;
|
EventHandler<PrimEventArgs> handler = m_ObjectUpdate;
|
||||||
if (handler != null)
|
handler?.Invoke(this, new PrimEventArgs(simulator, prim, update.RegionData.TimeDilation, isNew, prim.IsAttachment));
|
||||||
handler(this, new PrimEventArgs(simulator, prim, update.RegionData.TimeDilation, isNew, prim.IsAttachment));
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
@ -3310,10 +3298,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
// Start the timer again. Use a minimum of a 50ms pause in between calculations
|
// Start the timer again. Use a minimum of a 50ms pause in between calculations
|
||||||
int delay = Math.Max(50, Settings.INTERPOLATION_INTERVAL - elapsed);
|
int delay = Math.Max(50, Settings.INTERPOLATION_INTERVAL - elapsed);
|
||||||
if (InterpolationTimer != null)
|
InterpolationTimer?.Change(delay, Timeout.Infinite);
|
||||||
{
|
|
||||||
InterpolationTimer.Change(delay, Timeout.Infinite);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -606,13 +606,12 @@ namespace OpenMetaverse
|
||||||
Media = new ParcelMedia();
|
Media = new ParcelMedia();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public void Update(GridClient client)
|
||||||
/// Update the parcel (in the current sim)
|
{
|
||||||
/// </summary>
|
Update(client, client.Network.CurrentSim, false);
|
||||||
/// <param name="client">Client message originates from</param>
|
}
|
||||||
/// <param name="wantReply">Whether we want the simulator to confirm
|
|
||||||
/// the update with a reply packet or not [default false]</param>
|
public void Update(GridClient client, bool wantReply)
|
||||||
public void Update(GridClient client, bool wantReply = false)
|
|
||||||
{
|
{
|
||||||
Update(client, client.Network.CurrentSim, wantReply);
|
Update(client, client.Network.CurrentSim, wantReply);
|
||||||
}
|
}
|
||||||
|
|
@ -1688,7 +1687,17 @@ namespace OpenMetaverse
|
||||||
{
|
{
|
||||||
OSD res = null;
|
OSD res = null;
|
||||||
await Client.HttpCapsClient.PostRequestAsync(cap, OSDFormat.Xml, msg.Serialize(), CancellationToken.None,
|
await Client.HttpCapsClient.PostRequestAsync(cap, OSDFormat.Xml, msg.Serialize(), CancellationToken.None,
|
||||||
(response, data, error) => res = OSDParser.Deserialize(data));
|
(response, data, error) =>
|
||||||
|
{
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
res = OSDParser.Deserialize(data);
|
||||||
|
}
|
||||||
|
else if (error != null)
|
||||||
|
{
|
||||||
|
Logger.Log("Did not receive response from RemoteParcelRequest: " + error.Message, Helpers.LogLevel.Warning, Client);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (res is OSDMap result)
|
if (res is OSDMap result)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -767,17 +767,12 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FromBytes(byte[] data, int pos, int length)
|
private void FromBytes(byte[] data, int pos, int length)
|
||||||
{
|
|
||||||
if (length < 16)
|
|
||||||
{
|
|
||||||
// No TextureEntry to process
|
|
||||||
DefaultTexture = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
DefaultTexture = new TextureEntryFace(null);
|
DefaultTexture = new TextureEntryFace(null);
|
||||||
}
|
|
||||||
|
if (length < 16)
|
||||||
|
// No TextureEntry to process
|
||||||
|
return;
|
||||||
|
|
||||||
uint bitfieldSize = 0;
|
uint bitfieldSize = 0;
|
||||||
uint faceBits = 0;
|
uint faceBits = 0;
|
||||||
|
|
|
||||||
|
|
@ -217,10 +217,6 @@ namespace OpenMetaverse
|
||||||
/// server the full object info will automatically be requested</summary>
|
/// server the full object info will automatically be requested</summary>
|
||||||
public bool ALWAYS_REQUEST_OBJECTS = true;
|
public bool ALWAYS_REQUEST_OBJECTS = true;
|
||||||
|
|
||||||
/// <summary>Whether to establish connections to HTTP capabilities
|
|
||||||
/// servers for simulators</summary>
|
|
||||||
public bool ENABLE_CAPS = true;
|
|
||||||
|
|
||||||
/// <summary>Whether to decode sim stats</summary>
|
/// <summary>Whether to decode sim stats</summary>
|
||||||
public bool ENABLE_SIMSTATS = true;
|
public bool ENABLE_SIMSTATS = true;
|
||||||
|
|
||||||
|
|
@ -342,11 +338,7 @@ namespace OpenMetaverse
|
||||||
/// You will get no output on the console. This behavior can be overriden by creating
|
/// You will get no output on the console. This behavior can be overriden by creating
|
||||||
/// a logger configuration file for log4net
|
/// a logger configuration file for log4net
|
||||||
/// </summary>
|
/// </summary>
|
||||||
#if DEBUG
|
|
||||||
public static Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.Debug;
|
|
||||||
#else
|
|
||||||
public static Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.None;
|
public static Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.None;
|
||||||
#endif
|
|
||||||
|
|
||||||
/// <summary>Attach avatar names to log messages</summary>
|
/// <summary>Attach avatar names to log messages</summary>
|
||||||
public bool LOG_NAMES = true;
|
public bool LOG_NAMES = true;
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ namespace OpenMetaverse
|
||||||
public int ConnectTime;
|
public int ConnectTime;
|
||||||
/// <summary>Total number of packets that have been resent</summary>
|
/// <summary>Total number of packets that have been resent</summary>
|
||||||
public int ResentPackets;
|
public int ResentPackets;
|
||||||
/// <summary>Total number of resent packets recieved</summary>
|
/// <summary>Total number of resent packets received</summary>
|
||||||
public int ReceivedResends;
|
public int ReceivedResends;
|
||||||
/// <summary>Total number of pings sent to this simulator by this agent</summary>
|
/// <summary>Total number of pings sent to this simulator by this agent</summary>
|
||||||
public int SentPings;
|
public int SentPings;
|
||||||
|
|
@ -180,7 +180,7 @@ namespace OpenMetaverse
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Incoming bytes per second
|
/// Incoming bytes per second
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>It would be nice to have this claculated on the fly, but
|
/// <remarks>It would be nice to have this calculated on the fly, but
|
||||||
/// this is far, far easier</remarks>
|
/// this is far, far easier</remarks>
|
||||||
public int IncomingBPS;
|
public int IncomingBPS;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -252,6 +252,11 @@ namespace OpenMetaverse
|
||||||
#endregion Structs
|
#endregion Structs
|
||||||
|
|
||||||
#region Public Members
|
#region Public Members
|
||||||
|
|
||||||
|
// Default legacy simulator/region size
|
||||||
|
public const uint DefaultRegionSizeX = 256;
|
||||||
|
public const uint DefaultRegionSizeY = 256;
|
||||||
|
|
||||||
/// <summary>A public reference to the client that this Simulator object is attached to</summary>
|
/// <summary>A public reference to the client that this Simulator object is attached to</summary>
|
||||||
public GridClient Client;
|
public GridClient Client;
|
||||||
/// <summary>A Unique Cache identifier for this simulator</summary>
|
/// <summary>A Unique Cache identifier for this simulator</summary>
|
||||||
|
|
@ -260,6 +265,10 @@ namespace OpenMetaverse
|
||||||
public Caps Caps;
|
public Caps Caps;
|
||||||
/// <summary>Unique identified for this region generated via it's coordinates on the world map</summary>
|
/// <summary>Unique identified for this region generated via it's coordinates on the world map</summary>
|
||||||
public ulong Handle;
|
public ulong Handle;
|
||||||
|
/// <summary>Simulator land size in X direction in meters</summary>
|
||||||
|
public uint SizeX;
|
||||||
|
/// <summary>Simulator land size in Y direction in meters</summary>
|
||||||
|
public uint SizeY;
|
||||||
/// <summary>The current version of software this simulator is running</summary>
|
/// <summary>The current version of software this simulator is running</summary>
|
||||||
public string SimVersion = String.Empty;
|
public string SimVersion = String.Empty;
|
||||||
/// <summary>Human readable name given to the simulator</summary>
|
/// <summary>Human readable name given to the simulator</summary>
|
||||||
|
|
@ -497,10 +506,7 @@ namespace OpenMetaverse
|
||||||
public readonly SimulatorDataPool DataPool;
|
public readonly SimulatorDataPool DataPool;
|
||||||
internal bool DownloadingParcelMap
|
internal bool DownloadingParcelMap
|
||||||
{
|
{
|
||||||
get
|
get => Client.Settings.POOL_PARCEL_DATA ? DataPool.DownloadingParcelMap : _DownloadingParcelMap;
|
||||||
{
|
|
||||||
return Client.Settings.POOL_PARCEL_DATA ? DataPool.DownloadingParcelMap : _DownloadingParcelMap;
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (Client.Settings.POOL_PARCEL_DATA) DataPool.DownloadingParcelMap = value;
|
if (Client.Settings.POOL_PARCEL_DATA) DataPool.DownloadingParcelMap = value;
|
||||||
|
|
@ -520,7 +526,7 @@ namespace OpenMetaverse
|
||||||
/// <param name="client">Reference to the <seealso cref="GridClient"/> object</param>
|
/// <param name="client">Reference to the <seealso cref="GridClient"/> object</param>
|
||||||
/// <param name="address">IPEndPoint of the simulator</param>
|
/// <param name="address">IPEndPoint of the simulator</param>
|
||||||
/// <param name="handle">Region handle for the simulator</param>
|
/// <param name="handle">Region handle for the simulator</param>
|
||||||
public Simulator(GridClient client, IPEndPoint address, ulong handle)
|
public Simulator(GridClient client, IPEndPoint address, ulong handle, uint sizeX = DefaultRegionSizeX, uint sizeY = DefaultRegionSizeY)
|
||||||
: base(address)
|
: base(address)
|
||||||
{
|
{
|
||||||
Client = client;
|
Client = client;
|
||||||
|
|
@ -532,14 +538,16 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
Handle = handle;
|
Handle = handle;
|
||||||
Network = Client.Network;
|
Network = Client.Network;
|
||||||
|
SizeX = sizeX;
|
||||||
|
SizeY = sizeY;
|
||||||
PacketArchive = new IncomingPacketIDCollection(Settings.PACKET_ARCHIVE_SIZE);
|
PacketArchive = new IncomingPacketIDCollection(Settings.PACKET_ARCHIVE_SIZE);
|
||||||
InBytes = new Queue<long>(Client.Settings.STATS_QUEUE_SIZE);
|
InBytes = new Queue<long>(Client.Settings.STATS_QUEUE_SIZE);
|
||||||
OutBytes = new Queue<long>(Client.Settings.STATS_QUEUE_SIZE);
|
OutBytes = new Queue<long>(Client.Settings.STATS_QUEUE_SIZE);
|
||||||
|
|
||||||
if (client.Settings.STORE_LAND_PATCHES)
|
if (client.Settings.STORE_LAND_PATCHES)
|
||||||
{
|
{
|
||||||
Terrain = new TerrainPatch[16 * 16];
|
Terrain = new TerrainPatch[sizeX/16 * sizeY/16];
|
||||||
WindSpeeds = new Vector2[16 * 16];
|
WindSpeeds = new Vector2[sizeX/16 * sizeY/16];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -648,7 +656,7 @@ namespace OpenMetaverse
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initiates connection to the simulator
|
/// Initiates connection to the simulator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="waitForAck">Should we block until ack for this packet is recieved</param>
|
/// <param name="waitForAck">Should we block until ack for this packet is received</param>
|
||||||
public void UseCircuitCode(bool waitForAck)
|
public void UseCircuitCode(bool waitForAck)
|
||||||
{
|
{
|
||||||
// Send the UseCircuitCode packet to initiate the connection
|
// Send the UseCircuitCode packet to initiate the connection
|
||||||
|
|
@ -690,17 +698,14 @@ namespace OpenMetaverse
|
||||||
Caps = null;
|
Caps = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Client.Settings.ENABLE_CAPS)
|
// Connect to the CAPS system
|
||||||
{
|
|
||||||
// Connect to the new CAPS system
|
|
||||||
if (seedcaps != null)
|
if (seedcaps != null)
|
||||||
{
|
{
|
||||||
Caps = new Caps(this, seedcaps);
|
Caps = new Caps(this, seedcaps);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Log("Setting up a sim without a valid capabilities server!", Helpers.LogLevel.Error, Client);
|
Logger.Log("Setting up a sim without valid http capabilities", Helpers.LogLevel.Error, Client);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -709,6 +714,8 @@ namespace OpenMetaverse
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Disconnect(bool sendCloseCircuit)
|
public void Disconnect(bool sendCloseCircuit)
|
||||||
{
|
{
|
||||||
|
DisconnectCandidate = false;
|
||||||
|
|
||||||
if (!connected) return;
|
if (!connected) return;
|
||||||
|
|
||||||
connected = false;
|
connected = false;
|
||||||
|
|
@ -795,7 +802,7 @@ namespace OpenMetaverse
|
||||||
/// <returns>True if the lookup was successful, otherwise false</returns>
|
/// <returns>True if the lookup was successful, otherwise false</returns>
|
||||||
public bool TerrainHeightAtPoint(int x, int y, out float height)
|
public bool TerrainHeightAtPoint(int x, int y, out float height)
|
||||||
{
|
{
|
||||||
if (Terrain != null && x >= 0 && x < 256 && y >= 0 && y < 256)
|
if (Terrain != null && x >= 0 && x < SizeX && y >= 0 && y < SizeY)
|
||||||
{
|
{
|
||||||
int patchX = x / 16;
|
int patchX = x / 16;
|
||||||
int patchY = y / 16;
|
int patchY = y / 16;
|
||||||
|
|
@ -1002,7 +1009,7 @@ namespace OpenMetaverse
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns Simulator Name as a String
|
/// Returns Simulator Name as a String
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns>Simulator name as String</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return !String.IsNullOrEmpty(Name)
|
return !String.IsNullOrEmpty(Name)
|
||||||
|
|
@ -1059,8 +1066,8 @@ namespace OpenMetaverse
|
||||||
// Check if this packet came from the server we expected it to come from
|
// Check if this packet came from the server we expected it to come from
|
||||||
if (!remoteEndPoint.Address.Equals(((IPEndPoint)buffer.RemoteEndPoint).Address))
|
if (!remoteEndPoint.Address.Equals(((IPEndPoint)buffer.RemoteEndPoint).Address))
|
||||||
{
|
{
|
||||||
Logger.Log("Received " + buffer.DataLength + " bytes of data from unrecognized source " +
|
Logger.Log($"Received {buffer.DataLength} bytes of data from unrecognized source {(IPEndPoint)buffer.RemoteEndPoint}",
|
||||||
((IPEndPoint)buffer.RemoteEndPoint), Helpers.LogLevel.Warning, Client);
|
Helpers.LogLevel.Warning, Client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1201,7 +1208,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends out pending acknowledgements
|
/// Sends out pending acknowledgments
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Number of ACKs sent</returns>
|
/// <returns>Number of ACKs sent</returns>
|
||||||
private int SendAcks()
|
private int SendAcks()
|
||||||
|
|
|
||||||
|
|
@ -61,16 +61,27 @@ namespace OpenMetaverse
|
||||||
public int PatchIDs;
|
public int PatchIDs;
|
||||||
public uint WordBits;
|
public uint WordBits;
|
||||||
|
|
||||||
|
// true if PatchIDs are 32 bits and not 10
|
||||||
|
public bool LargeRegion { get; set; }
|
||||||
|
|
||||||
public int X
|
public int X
|
||||||
{
|
{
|
||||||
get { return PatchIDs >> 5; }
|
get { return PatchIDs >> (LargeRegion ? 16 : 5); }
|
||||||
set { PatchIDs += (value << 5); }
|
set { PatchIDs += (value << (LargeRegion ? 16 : 5)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Y
|
public int Y
|
||||||
{
|
{
|
||||||
get { return PatchIDs & 0x1F; }
|
get { return PatchIDs & (LargeRegion ? 0xffff : 0x1F); }
|
||||||
set { PatchIDs |= value & 0x1F; }
|
set { PatchIDs |= value & (LargeRegion ? 0xffff : 0x1F); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int setPatchIDs(int xx, int yy) {
|
||||||
|
if (LargeRegion)
|
||||||
|
PatchIDs = (xx << 16) | (yy & 0xffff);
|
||||||
|
else
|
||||||
|
PatchIDs = (xx << 5) | (yy & 0x1f);
|
||||||
|
return PatchIDs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,14 +159,18 @@ namespace OpenMetaverse
|
||||||
/// simulator heightmap and an array of indices of patches to compress
|
/// simulator heightmap and an array of indices of patches to compress
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="heightmap">A 256 * 256 array of floating point values
|
/// <param name="heightmap">A 256 * 256 array of floating point values
|
||||||
/// specifying the height at each meter in the simulator</param>
|
/// specifying the height at each meter in the simulator.
|
||||||
|
/// This can be larger if it is a varregion.</param>
|
||||||
/// <param name="patches">Array of indexes in the 16x16 grid of patches
|
/// <param name="patches">Array of indexes in the 16x16 grid of patches
|
||||||
/// for this simulator. For example if 1 and 17 are specified, patches
|
/// for this simulator. For example if 1 and 17 are specified, patches
|
||||||
/// x=1,y=0 and x=1,y=1 are sent</param>
|
/// x=1,y=0 and x=1,y=1 are sent</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static LayerDataPacket CreateLandPacket(float[] heightmap, int[] patches)
|
public static LayerDataPacket CreateLandPacket(float[] heightmap, int[] patches)
|
||||||
{
|
{
|
||||||
LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = (byte) TerrainPatch.LayerType.Land}};
|
var layerType = TerrainPatch.LayerType.Land;
|
||||||
|
if (heightmap.Length > Simulator.DefaultRegionSizeY * Simulator.DefaultRegionSizeY)
|
||||||
|
layerType = TerrainPatch.LayerType.LandExtended;
|
||||||
|
LayerDataPacket layer = new LayerDataPacket {LayerID = {Type = (byte) layerType}};
|
||||||
|
|
||||||
TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
|
TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader
|
||||||
{
|
{
|
||||||
|
|
@ -235,15 +250,19 @@ namespace OpenMetaverse
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CreatePatch(BitPack output, float[] patchData, int x, int y)
|
private static void CreatePatch(BitPack output, float[] patchData, int x, int y)
|
||||||
|
{
|
||||||
|
CreatePatch(output, patchData, x, y, false);
|
||||||
|
}
|
||||||
|
private static void CreatePatch(BitPack output, float[] patchData, int x, int y, bool largeRegion)
|
||||||
{
|
{
|
||||||
if (patchData.Length != 16 * 16)
|
if (patchData.Length != 16 * 16)
|
||||||
throw new ArgumentException("Patch data must be a 16x16 array");
|
throw new ArgumentException("Patch data must be a 16x16 array");
|
||||||
|
|
||||||
TerrainPatch.Header header = PrescanPatch(patchData);
|
TerrainPatch.Header header = PrescanPatch(patchData);
|
||||||
|
header.LargeRegion = largeRegion;
|
||||||
header.QuantWBits = 136;
|
header.QuantWBits = 136;
|
||||||
header.PatchIDs = (y & 0x1F);
|
header.setPatchIDs(x, y);
|
||||||
header.PatchIDs += (x << 5);
|
|
||||||
|
|
||||||
// NOTE: No idea what prequant and postquant should be or what they do
|
// NOTE: No idea what prequant and postquant should be or what they do
|
||||||
int[] patch = CompressPatch(patchData, header, 10);
|
int[] patch = CompressPatch(patchData, header, 10);
|
||||||
|
|
@ -252,14 +271,18 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CreatePatch(BitPack output, float[,] patchData, int x, int y)
|
public static void CreatePatch(BitPack output, float[,] patchData, int x, int y)
|
||||||
|
{
|
||||||
|
CreatePatch(output, patchData, x, y, false);
|
||||||
|
}
|
||||||
|
public static void CreatePatch(BitPack output, float[,] patchData, int x, int y, bool largeRegion)
|
||||||
{
|
{
|
||||||
if (patchData.Length != 16 * 16)
|
if (patchData.Length != 16 * 16)
|
||||||
throw new ArgumentException("Patch data must be a 16x16 array");
|
throw new ArgumentException("Patch data must be a 16x16 array");
|
||||||
|
|
||||||
var header = PrescanPatch(patchData);
|
var header = PrescanPatch(patchData);
|
||||||
|
header.LargeRegion = largeRegion;
|
||||||
header.QuantWBits = 136;
|
header.QuantWBits = 136;
|
||||||
header.PatchIDs = (y & 0x1F);
|
header.setPatchIDs(x, y);
|
||||||
header.PatchIDs += (x << 5);
|
|
||||||
|
|
||||||
// NOTE: No idea what prequant and postquant should be or what they do
|
// NOTE: No idea what prequant and postquant should be or what they do
|
||||||
int[] patch = CompressPatch(patchData, header, 10);
|
int[] patch = CompressPatch(patchData, header, 10);
|
||||||
|
|
@ -278,6 +301,10 @@ namespace OpenMetaverse
|
||||||
/// <param name="y">Y offset of the patch to create, valid values are
|
/// <param name="y">Y offset of the patch to create, valid values are
|
||||||
/// from 0 to 15</param>
|
/// from 0 to 15</param>
|
||||||
public static void CreatePatchFromHeightmap(BitPack output, float[] heightmap, int x, int y)
|
public static void CreatePatchFromHeightmap(BitPack output, float[] heightmap, int x, int y)
|
||||||
|
{
|
||||||
|
CreatePatchFromHeightmap(output, heightmap, x, y, false);
|
||||||
|
}
|
||||||
|
public static void CreatePatchFromHeightmap(BitPack output, float[] heightmap, int x, int y, bool largeRegion)
|
||||||
{
|
{
|
||||||
if (heightmap.Length != 256 * 256)
|
if (heightmap.Length != 256 * 256)
|
||||||
throw new ArgumentException("Heightmap data must be 256x256");
|
throw new ArgumentException("Heightmap data must be 256x256");
|
||||||
|
|
@ -286,9 +313,9 @@ namespace OpenMetaverse
|
||||||
throw new ArgumentException("X and Y patch offsets must be from 0 to 15");
|
throw new ArgumentException("X and Y patch offsets must be from 0 to 15");
|
||||||
|
|
||||||
var header = PrescanPatch(heightmap, x, y);
|
var header = PrescanPatch(heightmap, x, y);
|
||||||
|
header.LargeRegion = largeRegion;
|
||||||
header.QuantWBits = 136;
|
header.QuantWBits = 136;
|
||||||
header.PatchIDs = (y & 0x1F);
|
header.setPatchIDs(x, y);
|
||||||
header.PatchIDs += (x << 5);
|
|
||||||
|
|
||||||
// NOTE: No idea what prequant and postquant should be or what they do
|
// NOTE: No idea what prequant and postquant should be or what they do
|
||||||
int[] patch = CompressPatch(heightmap, x, y, header, 10);
|
int[] patch = CompressPatch(heightmap, x, y, header, 10);
|
||||||
|
|
@ -296,6 +323,8 @@ namespace OpenMetaverse
|
||||||
EncodePatch(output, patch, 0, wbits);
|
EncodePatch(output, patch, 0, wbits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scan the height map to get the range of values so the values can be compressed.
|
||||||
|
// Returns a TerrainPatch.Header with the range information filled in.
|
||||||
private static TerrainPatch.Header PrescanPatch(float[] patch)
|
private static TerrainPatch.Header PrescanPatch(float[] patch)
|
||||||
{
|
{
|
||||||
TerrainPatch.Header header = new TerrainPatch.Header();
|
TerrainPatch.Header header = new TerrainPatch.Header();
|
||||||
|
|
@ -318,6 +347,8 @@ namespace OpenMetaverse
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scan the height map to get the range of values so the values can be compressed.
|
||||||
|
// Returns a TerrainPatch.Header with the range information filled in.
|
||||||
private static TerrainPatch.Header PrescanPatch(float[,] patch)
|
private static TerrainPatch.Header PrescanPatch(float[,] patch)
|
||||||
{
|
{
|
||||||
TerrainPatch.Header header = new TerrainPatch.Header();
|
TerrainPatch.Header header = new TerrainPatch.Header();
|
||||||
|
|
@ -340,6 +371,8 @@ namespace OpenMetaverse
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scan the height map to get the range of values so the values can be compressed.
|
||||||
|
// Returns a TerrainPatch.Header with the range information filled in.
|
||||||
private static TerrainPatch.Header PrescanPatch(float[] heightmap, int patchX, int patchY)
|
private static TerrainPatch.Header PrescanPatch(float[] heightmap, int patchX, int patchY)
|
||||||
{
|
{
|
||||||
TerrainPatch.Header header = new TerrainPatch.Header();
|
TerrainPatch.Header header = new TerrainPatch.Header();
|
||||||
|
|
@ -363,6 +396,11 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack)
|
public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack)
|
||||||
|
{
|
||||||
|
return DecodePatchHeader(bitpack, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
public static TerrainPatch.Header DecodePatchHeader(BitPack bitpack, bool largeRegion)
|
||||||
{
|
{
|
||||||
TerrainPatch.Header header = new TerrainPatch.Header {QuantWBits = bitpack.UnpackBits(8)};
|
TerrainPatch.Header header = new TerrainPatch.Header {QuantWBits = bitpack.UnpackBits(8)};
|
||||||
|
|
||||||
|
|
@ -377,7 +415,9 @@ namespace OpenMetaverse
|
||||||
header.Range = bitpack.UnpackBits(16);
|
header.Range = bitpack.UnpackBits(16);
|
||||||
|
|
||||||
// Patch IDs (10 bits)
|
// Patch IDs (10 bits)
|
||||||
header.PatchIDs = bitpack.UnpackBits(10);
|
|
||||||
|
header.LargeRegion = largeRegion;
|
||||||
|
header.PatchIDs = bitpack.UnpackBits(largeRegion ? 32 : 10);
|
||||||
|
|
||||||
// Word bits
|
// Word bits
|
||||||
header.WordBits = (uint)((header.QuantWBits & 0x0f) + 2);
|
header.WordBits = (uint)((header.QuantWBits & 0x0f) + 2);
|
||||||
|
|
@ -428,7 +468,7 @@ namespace OpenMetaverse
|
||||||
output.PackBits(header.QuantWBits, 8);
|
output.PackBits(header.QuantWBits, 8);
|
||||||
output.PackFloat(header.DCOffset);
|
output.PackFloat(header.DCOffset);
|
||||||
output.PackBits(header.Range, 16);
|
output.PackBits(header.Range, 16);
|
||||||
output.PackBits(header.PatchIDs, 10);
|
output.PackBits(header.PatchIDs, header.LargeRegion ? 32 : 10); // the IDs are larger for large regions
|
||||||
|
|
||||||
return wbits;
|
return wbits;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ namespace OpenMetaverse
|
||||||
Client.Network.RegisterCallback(PacketType.LayerData, LayerDataHandler);
|
Client.Network.RegisterCallback(PacketType.LayerData, LayerDataHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DecompressLand(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
|
private void DecompressLand(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group, bool largeRegion = false)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|
@ -76,7 +76,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack);
|
TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack, largeRegion);
|
||||||
|
|
||||||
if (header.QuantWBits == TerrainCompressor.END_OF_PATCHES)
|
if (header.QuantWBits == TerrainCompressor.END_OF_PATCHES)
|
||||||
break;
|
break;
|
||||||
|
|
@ -84,7 +84,7 @@ namespace OpenMetaverse
|
||||||
x = header.X;
|
x = header.X;
|
||||||
y = header.Y;
|
y = header.Y;
|
||||||
|
|
||||||
if (x >= TerrainCompressor.PATCHES_PER_EDGE || y >= TerrainCompressor.PATCHES_PER_EDGE)
|
if (!largeRegion && (x >= TerrainCompressor.PATCHES_PER_EDGE || y >= TerrainCompressor.PATCHES_PER_EDGE))
|
||||||
{
|
{
|
||||||
Logger.Log(String.Format(
|
Logger.Log(String.Format(
|
||||||
"Invalid LayerData land packet, x={0}, y={1}, dc_offset={2}, range={3}, quant_wbits={4}, patchids={5}, count={6}",
|
"Invalid LayerData land packet, x={0}, y={1}, dc_offset={2}, range={3}, quant_wbits={4}, patchids={5}, count={6}",
|
||||||
|
|
@ -117,7 +117,7 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DecompressWind(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
|
private void DecompressWind(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group, bool largeRegion = false)
|
||||||
{
|
{
|
||||||
int[] patches = new int[32 * 32];
|
int[] patches = new int[32 * 32];
|
||||||
|
|
||||||
|
|
@ -131,12 +131,12 @@ namespace OpenMetaverse
|
||||||
// wind_direction = vec2(x,y)
|
// wind_direction = vec2(x,y)
|
||||||
|
|
||||||
// X values
|
// X values
|
||||||
TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack);
|
TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack, largeRegion);
|
||||||
TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
|
TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
|
||||||
float[] xvalues = TerrainCompressor.DecompressPatch(patches, header, group);
|
float[] xvalues = TerrainCompressor.DecompressPatch(patches, header, group);
|
||||||
|
|
||||||
// Y values
|
// Y values
|
||||||
header = TerrainCompressor.DecodePatchHeader(bitpack);
|
header = TerrainCompressor.DecodePatchHeader(bitpack, largeRegion);
|
||||||
TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
|
TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
|
||||||
float[] yvalues = TerrainCompressor.DecompressPatch(patches, header, group);
|
float[] yvalues = TerrainCompressor.DecompressPatch(patches, header, group);
|
||||||
|
|
||||||
|
|
@ -172,6 +172,10 @@ namespace OpenMetaverse
|
||||||
if (m_LandPatchReceivedEvent != null || Client.Settings.STORE_LAND_PATCHES)
|
if (m_LandPatchReceivedEvent != null || Client.Settings.STORE_LAND_PATCHES)
|
||||||
DecompressLand(e.Simulator, bitpack, header);
|
DecompressLand(e.Simulator, bitpack, header);
|
||||||
break;
|
break;
|
||||||
|
case TerrainPatch.LayerType.LandExtended:
|
||||||
|
if (m_LandPatchReceivedEvent != null || Client.Settings.STORE_LAND_PATCHES)
|
||||||
|
DecompressLand(e.Simulator, bitpack, header, true);
|
||||||
|
break;
|
||||||
case TerrainPatch.LayerType.Water:
|
case TerrainPatch.LayerType.Water:
|
||||||
Logger.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Error, Client);
|
Logger.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Error, Client);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ namespace OpenMetaverse
|
||||||
|
|
||||||
// kick off an async receive. The Start() method will return, the
|
// kick off an async receive. The Start() method will return, the
|
||||||
// actual receives will occur asynchronously and will be caught in
|
// actual receives will occur asynchronously and will be caught in
|
||||||
// AsyncEndRecieve().
|
// AsyncEndReceive().
|
||||||
AsyncBeginReceive();
|
AsyncBeginReceive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10023,6 +10023,9 @@ namespace OpenMetaverse.Packets
|
||||||
public byte[] SeedCapability;
|
public byte[] SeedCapability;
|
||||||
public byte SimAccess;
|
public byte SimAccess;
|
||||||
public uint TeleportFlags;
|
public uint TeleportFlags;
|
||||||
|
// Sim/region size information sent in TeleportFinishMesssage
|
||||||
|
public uint RegionSizeX = Simulator.DefaultRegionSizeX;
|
||||||
|
public uint RegionSizeY = Simulator.DefaultRegionSizeY;
|
||||||
|
|
||||||
public override int Length
|
public override int Length
|
||||||
{
|
{
|
||||||
|
|
@ -10075,6 +10078,7 @@ namespace OpenMetaverse.Packets
|
||||||
Buffer.BlockCopy(SeedCapability, 0, bytes, i, SeedCapability.Length); i += SeedCapability.Length;
|
Buffer.BlockCopy(SeedCapability, 0, bytes, i, SeedCapability.Length); i += SeedCapability.Length;
|
||||||
bytes[i++] = SimAccess;
|
bytes[i++] = SimAccess;
|
||||||
Utils.UIntToBytes(TeleportFlags, bytes, i); i += 4;
|
Utils.UIntToBytes(TeleportFlags, bytes, i); i += 4;
|
||||||
|
// size information is not sent in the UDP packet
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ namespace SecondBotEvents.Commands
|
||||||
return Failure("Unknown group", new[] { group, avatar, state });
|
return Failure("Unknown group", new[] { group, avatar, state });
|
||||||
}
|
}
|
||||||
ProcessAvatar(avatar);
|
ProcessAvatar(avatar);
|
||||||
if(avataruuid == null)
|
if(avataruuid == UUID.Zero)
|
||||||
{
|
{
|
||||||
return Failure("Unknown avatar", new[] { group, avatar, state });
|
return Failure("Unknown avatar", new[] { group, avatar, state });
|
||||||
}
|
}
|
||||||
|
|
@ -75,8 +75,10 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
Action = GroupBanAction.Unban;
|
Action = GroupBanAction.Unban;
|
||||||
}
|
}
|
||||||
List<UUID> avatarstoaction = new List<UUID>();
|
List<UUID> avatarstoaction = new()
|
||||||
avatarstoaction.Add(avataruuid);
|
{
|
||||||
|
avataruuid
|
||||||
|
};
|
||||||
GetClient().Groups.RequestBanAction(groupuuid, Action, avatarstoaction.ToArray());
|
GetClient().Groups.RequestBanAction(groupuuid, Action, avatarstoaction.ToArray());
|
||||||
return BasicReply("Accepted");
|
return BasicReply("Accepted");
|
||||||
}
|
}
|
||||||
|
|
@ -104,7 +106,7 @@ namespace SecondBotEvents.Commands
|
||||||
return Failure("Unknown group", new[] { group, avatar });
|
return Failure("Unknown group", new[] { group, avatar });
|
||||||
}
|
}
|
||||||
ProcessAvatar(avatar);
|
ProcessAvatar(avatar);
|
||||||
if (avataruuid == null)
|
if (avataruuid == UUID.Zero)
|
||||||
{
|
{
|
||||||
return Failure("Unknown avatar", new[] { group, avatar});
|
return Failure("Unknown avatar", new[] { group, avatar});
|
||||||
}
|
}
|
||||||
|
|
@ -172,12 +174,13 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return Failure("avatar lookup", new [] { group, avatar, role });
|
return Failure("avatar lookup", new [] { group, avatar, role });
|
||||||
}
|
}
|
||||||
List<UUID> roles = new List<UUID>();
|
List<UUID> roles = new()
|
||||||
roles.Add(UUID.Zero);
|
|
||||||
if(role != "everyone")
|
|
||||||
{
|
{
|
||||||
UUID roleuuid = UUID.Zero;
|
UUID.Zero
|
||||||
if (UUID.TryParse(role, out roleuuid) == false)
|
};
|
||||||
|
if (role != "everyone")
|
||||||
|
{
|
||||||
|
if (UUID.TryParse(role, out UUID roleuuid) == false)
|
||||||
{
|
{
|
||||||
return Failure("Unable to process role UUID", new[] { group, avatar, role });
|
return Failure("Unable to process role UUID", new[] { group, avatar, role });
|
||||||
}
|
}
|
||||||
|
|
@ -215,10 +218,12 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return Failure("Message empty", new [] { group, title, message });
|
return Failure("Message empty", new [] { group, title, message });
|
||||||
}
|
}
|
||||||
GroupNotice NewNotice = new GroupNotice();
|
GroupNotice NewNotice = new()
|
||||||
NewNotice.Subject = title;
|
{
|
||||||
NewNotice.Message = message;
|
Subject = title,
|
||||||
NewNotice.OwnerID = GetClient().Self.AgentID;
|
Message = message,
|
||||||
|
OwnerID = GetClient().Self.AgentID
|
||||||
|
};
|
||||||
GetClient().Groups.SendGroupNotice(groupuuid, NewNotice);
|
GetClient().Groups.SendGroupNotice(groupuuid, NewNotice);
|
||||||
return BasicReply("Sending notice", new [] { group, title, message });
|
return BasicReply("Sending notice", new [] { group, title, message });
|
||||||
}
|
}
|
||||||
|
|
@ -301,11 +306,13 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return Failure("Message empty", new [] { group, title, message, attachment });
|
return Failure("Message empty", new [] { group, title, message, attachment });
|
||||||
}
|
}
|
||||||
GroupNotice NewNotice = new GroupNotice();
|
GroupNotice NewNotice = new()
|
||||||
NewNotice.Subject = title;
|
{
|
||||||
NewNotice.Message = message;
|
Subject = title,
|
||||||
NewNotice.OwnerID = GetClient().Self.AgentID;
|
Message = message,
|
||||||
NewNotice.AttachmentID = inventoryuuid;
|
OwnerID = GetClient().Self.AgentID,
|
||||||
|
AttachmentID = inventoryuuid
|
||||||
|
};
|
||||||
GetClient().Groups.SendGroupNotice(groupuuid, NewNotice);
|
GetClient().Groups.SendGroupNotice(groupuuid, NewNotice);
|
||||||
return BasicReply("Sending notice with attachment", new [] { group, title, message, attachment });
|
return BasicReply("Sending notice with attachment", new [] { group, title, message, attachment });
|
||||||
}
|
}
|
||||||
|
|
@ -351,8 +358,7 @@ namespace SecondBotEvents.Commands
|
||||||
[ArgHints("group", "the UUID of the group")]
|
[ArgHints("group", "the UUID of the group")]
|
||||||
public object GroupchatGroupHasUnread(string group)
|
public object GroupchatGroupHasUnread(string group)
|
||||||
{
|
{
|
||||||
UUID groupUUID = UUID.Zero;
|
if(UUID.TryParse(group,out UUID groupUUID) == false)
|
||||||
if(UUID.TryParse(group,out groupUUID) == false)
|
|
||||||
{
|
{
|
||||||
return Failure("group value is invaild", new [] { group });
|
return Failure("group value is invaild", new [] { group });
|
||||||
}
|
}
|
||||||
|
|
@ -400,8 +406,7 @@ namespace SecondBotEvents.Commands
|
||||||
[ReturnHintsFailure("Unknown group")]
|
[ReturnHintsFailure("Unknown group")]
|
||||||
public object Groupchat(string group, string message)
|
public object Groupchat(string group, string message)
|
||||||
{
|
{
|
||||||
UUID groupUUID = UUID.Zero;
|
if (UUID.TryParse(group, out UUID groupUUID) == false)
|
||||||
if (UUID.TryParse(group, out groupUUID) == false)
|
|
||||||
{
|
{
|
||||||
return Failure("group value is invaild", new [] { group, message });
|
return Failure("group value is invaild", new [] { group, message });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,10 @@ namespace SecondBotEvents.Commands
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AssetSound S = new AssetSound();
|
AssetSound S = new()
|
||||||
S.AssetData = audioData;
|
{
|
||||||
|
AssetData = audioData
|
||||||
|
};
|
||||||
S.Encode();
|
S.Encode();
|
||||||
|
|
||||||
GetClient().Inventory.RequestCreateItemFromAsset(S.AssetData, inventoryName, "", AssetType.Sound, InventoryType.Sound, AA.UUID, null);
|
GetClient().Inventory.RequestCreateItemFromAsset(S.AssetData, inventoryName, "", AssetType.Sound, InventoryType.Sound, AA.UUID, null);
|
||||||
|
|
@ -204,7 +206,7 @@ namespace SecondBotEvents.Commands
|
||||||
return Failure("Cant find target folder", new [] { name });
|
return Failure("Cant find target folder", new [] { name });
|
||||||
}
|
}
|
||||||
List<InventoryBase> contents = GetClient().Inventory.FolderContents(AA.UUID, GetClient().Self.AgentID, true, true, InventorySortOrder.ByName, 5 * 1000);
|
List<InventoryBase> contents = GetClient().Inventory.FolderContents(AA.UUID, GetClient().Self.AgentID, true, true, InventorySortOrder.ByName, 5 * 1000);
|
||||||
List<InventoryItem> wareables = new List<InventoryItem>();
|
List<InventoryItem> wareables = new();
|
||||||
if (contents == null)
|
if (contents == null)
|
||||||
{
|
{
|
||||||
return Failure("target folder is empty or so full I cant get it in 5 secs...", new [] { name });
|
return Failure("target folder is empty or so full I cant get it in 5 secs...", new [] { name });
|
||||||
|
|
@ -241,7 +243,7 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return Failure("Unable to find notecard folder");
|
return Failure("Unable to find notecard folder");
|
||||||
}
|
}
|
||||||
List<UUID> purge_notecards = new List<UUID>();
|
List<UUID> purge_notecards = new();
|
||||||
List<InventoryBase> contents = GetClient().Inventory.FolderContents(NotecardFolder.UUID, GetClient().Self.AgentID, true, true, InventorySortOrder.ByDate, 40 * 1000);
|
List<InventoryBase> contents = GetClient().Inventory.FolderContents(NotecardFolder.UUID, GetClient().Self.AgentID, true, true, InventorySortOrder.ByDate, 40 * 1000);
|
||||||
foreach (InventoryBase C in contents)
|
foreach (InventoryBase C in contents)
|
||||||
{
|
{
|
||||||
|
|
@ -255,7 +257,7 @@ namespace SecondBotEvents.Commands
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (purge_notecards.Count() > 0)
|
if (purge_notecards.Count > 0)
|
||||||
{
|
{
|
||||||
GetClient().Inventory.Remove(purge_notecards, new List<UUID>());
|
GetClient().Inventory.Remove(purge_notecards, new List<UUID>());
|
||||||
}
|
}
|
||||||
|
|
@ -266,7 +268,7 @@ namespace SecondBotEvents.Commands
|
||||||
[ReturnHints("Asset UUID or UUID zero")]
|
[ReturnHints("Asset UUID or UUID zero")]
|
||||||
[ReturnHints("Invaild item uuid")]
|
[ReturnHints("Invaild item uuid")]
|
||||||
[ArgHints("item", "inventory level UUID of item")]
|
[ArgHints("item", "inventory level UUID of item")]
|
||||||
public object getRealUUID(string item)
|
public object GetRealUUID(string item)
|
||||||
{
|
{
|
||||||
if (UUID.TryParse(item, out UUID itemUUID) == false)
|
if (UUID.TryParse(item, out UUID itemUUID) == false)
|
||||||
{
|
{
|
||||||
|
|
@ -364,7 +366,7 @@ namespace SecondBotEvents.Commands
|
||||||
return Failure("Unable to find inventory", new [] { item, objectuuid, running });
|
return Failure("Unable to find inventory", new [] { item, objectuuid, running });
|
||||||
}
|
}
|
||||||
Dictionary<uint, Primitive> objects_copy = GetClient().Network.CurrentSim.ObjectsPrimitives.Copy();
|
Dictionary<uint, Primitive> objects_copy = GetClient().Network.CurrentSim.ObjectsPrimitives.Copy();
|
||||||
KeyValuePair<uint, Primitive> RealObject = new KeyValuePair<uint, Primitive>(0,null);
|
KeyValuePair<uint, Primitive> RealObject = new(0, null);
|
||||||
foreach (KeyValuePair<uint, Primitive> Obj in objects_copy)
|
foreach (KeyValuePair<uint, Primitive> Obj in objects_copy)
|
||||||
{
|
{
|
||||||
if (Obj.Value.ID == objectUUID)
|
if (Obj.Value.ID == objectUUID)
|
||||||
|
|
@ -431,7 +433,7 @@ namespace SecondBotEvents.Commands
|
||||||
[ReturnHintsFailure("new folder name is too short, must be longer than 3 characters.")]
|
[ReturnHintsFailure("new folder name is too short, must be longer than 3 characters.")]
|
||||||
[ArgHints("parentFolder", "UUID of folder to create a subfolder in")]
|
[ArgHints("parentFolder", "UUID of folder to create a subfolder in")]
|
||||||
[ArgHints("folderName", "name of the new folder")]
|
[ArgHints("folderName", "name of the new folder")]
|
||||||
public object CreateInventoryFolder(string parentFolder, string folderName, string token)
|
public object CreateInventoryFolder(string parentFolder, string folderName)
|
||||||
{
|
{
|
||||||
if (UUID.TryParse(parentFolder, out UUID parentFolderUUID) == false)
|
if (UUID.TryParse(parentFolder, out UUID parentFolderUUID) == false)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ namespace SecondBotEvents.Commands
|
||||||
}
|
}
|
||||||
targetparcel.SalePrice = amountvalue;
|
targetparcel.SalePrice = amountvalue;
|
||||||
targetparcel.AuthBuyerID = avataruuid;
|
targetparcel.AuthBuyerID = avataruuid;
|
||||||
parcel_static.ParcelSetFlag(ParcelFlags.ForSale, targetparcel, true);
|
ParcelStatic.ParcelSetFlag(ParcelFlags.ForSale, targetparcel, true);
|
||||||
parcel_static.ParcelSetFlag(ParcelFlags.ForSaleObjects, targetparcel, false);
|
ParcelStatic.ParcelSetFlag(ParcelFlags.ForSaleObjects, targetparcel, false);
|
||||||
targetparcel.Update(GetClient());
|
targetparcel.Update(GetClient());
|
||||||
return Failure("ok", new [] { amount, avatar });
|
return Failure("ok", new [] { amount, avatar });
|
||||||
}
|
}
|
||||||
|
|
@ -167,8 +167,8 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return Failure(tests.Value);
|
return Failure(tests.Value);
|
||||||
}
|
}
|
||||||
Dictionary<string, ParcelFlags> flags = parcel_static.get_flags_list();
|
Dictionary<string, ParcelFlags> flags = ParcelStatic.GetFlagsList();
|
||||||
Dictionary<string, string> collection = new Dictionary<string, string>();
|
Dictionary<string, string> collection = new();
|
||||||
foreach (ParcelFlags cfg in flags.Values)
|
foreach (ParcelFlags cfg in flags.Values)
|
||||||
{
|
{
|
||||||
collection.Add(cfg.ToString(), targetparcel.Flags.HasFlag(cfg).ToString());
|
collection.Add(cfg.ToString(), targetparcel.Flags.HasFlag(cfg).ToString());
|
||||||
|
|
@ -237,10 +237,12 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return BasicReply("Avatar is in the blacklist", new [] { avatar });
|
return BasicReply("Avatar is in the blacklist", new [] { avatar });
|
||||||
}
|
}
|
||||||
ParcelAccessEntry entry = new ParcelAccessEntry();
|
ParcelAccessEntry entry = new()
|
||||||
entry.AgentID = avataruuid;
|
{
|
||||||
entry.Flags = AccessList.Ban;
|
AgentID = avataruuid,
|
||||||
entry.Time = new System.DateTime(3030, 03, 03);
|
Flags = AccessList.Ban,
|
||||||
|
Time = new System.DateTime(3030, 03, 03)
|
||||||
|
};
|
||||||
targetparcel.AccessBlackList.Add(entry);
|
targetparcel.AccessBlackList.Add(entry);
|
||||||
targetparcel.Update(GetClient());
|
targetparcel.Update(GetClient());
|
||||||
return BasicReply("ok", new [] { avatar });
|
return BasicReply("ok", new [] { avatar });
|
||||||
|
|
@ -266,7 +268,7 @@ namespace SecondBotEvents.Commands
|
||||||
return Failure("Invaild avatar", new [] { avatar });
|
return Failure("Invaild avatar", new [] { avatar });
|
||||||
}
|
}
|
||||||
bool alreadyBanned = false;
|
bool alreadyBanned = false;
|
||||||
ParcelAccessEntry removeentry = new ParcelAccessEntry();
|
ParcelAccessEntry removeentry = new();
|
||||||
foreach (ParcelAccessEntry E in targetparcel.AccessBlackList)
|
foreach (ParcelAccessEntry E in targetparcel.AccessBlackList)
|
||||||
{
|
{
|
||||||
if (E.AgentID == avataruuid)
|
if (E.AgentID == avataruuid)
|
||||||
|
|
@ -298,7 +300,7 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return Failure(tests.Value, new [] { musicurl });
|
return Failure(tests.Value, new [] { musicurl });
|
||||||
}
|
}
|
||||||
bool status = parcel_static.set_parcel_music(GetClient(), targetparcel, musicurl);
|
bool status = ParcelStatic.SetParcelMusic(GetClient(), targetparcel, musicurl);
|
||||||
return BasicReply(status.ToString(), new [] { musicurl });
|
return BasicReply(status.ToString(), new [] { musicurl });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,11 +321,11 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return Failure(tests.Value, new [] { escapedflagdata });
|
return Failure(tests.Value, new [] { escapedflagdata });
|
||||||
}
|
}
|
||||||
List<string> acceptablewords = new List<string>();
|
List<string> acceptablewords = new();
|
||||||
Dictionary<string, ParcelFlags> flags = parcel_static.get_flags_list();
|
Dictionary<string, ParcelFlags> flags = ParcelStatic.GetFlagsList();
|
||||||
acceptablewords.AddRange(new[] { "True", "False" });
|
acceptablewords.AddRange(new[] { "True", "False" });
|
||||||
|
|
||||||
Dictionary<string, bool> setflags = new Dictionary<string, bool>();
|
Dictionary<string, bool> setflags = new();
|
||||||
string[] args = escapedflagdata.Split(":::");
|
string[] args = escapedflagdata.Split(":::");
|
||||||
foreach (string a in args)
|
foreach (string a in args)
|
||||||
{
|
{
|
||||||
|
|
@ -348,7 +350,7 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return Failure("No accepted flags", new [] { escapedflagdata });
|
return Failure("No accepted flags", new [] { escapedflagdata });
|
||||||
}
|
}
|
||||||
if (parcel_static.has_parcel_perm(targetparcel, GetClient()) == false)
|
if (ParcelStatic.HasParcelPerm(targetparcel, GetClient()) == false)
|
||||||
{
|
{
|
||||||
return Failure("Incorrect perms to control parcel", new [] { escapedflagdata });
|
return Failure("Incorrect perms to control parcel", new [] { escapedflagdata });
|
||||||
}
|
}
|
||||||
|
|
@ -356,7 +358,7 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
if (flags.ContainsKey(cfg.Key) == true)
|
if (flags.ContainsKey(cfg.Key) == true)
|
||||||
{
|
{
|
||||||
parcel_static.ParcelSetFlag(flags[cfg.Key], targetparcel, cfg.Value);
|
ParcelStatic.ParcelSetFlag(flags[cfg.Key], targetparcel, cfg.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetparcel.Update(GetClient());
|
targetparcel.Update(GetClient());
|
||||||
|
|
@ -494,7 +496,7 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
return Failure(tests.Value);
|
return Failure(tests.Value);
|
||||||
}
|
}
|
||||||
GetParcelBanlistObject reply = new GetParcelBanlistObject();
|
GetParcelBanlistObject reply = new();
|
||||||
int delays = 0;
|
int delays = 0;
|
||||||
bool haslookup = true;
|
bool haslookup = true;
|
||||||
while ((haslookup == true) && (delays < 3))
|
while ((haslookup == true) && (delays < 3))
|
||||||
|
|
@ -582,7 +584,7 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
if (bits[0] == "MediaType")
|
if (bits[0] == "MediaType")
|
||||||
{
|
{
|
||||||
UpdateParcel_MediaType(targetparcel, bits[1]);
|
UpdateParcelMediaType(targetparcel, bits[1]);
|
||||||
}
|
}
|
||||||
else if ((bits[0] == "MediaWidth") || (bits[0] == "MediaHeight"))
|
else if ((bits[0] == "MediaWidth") || (bits[0] == "MediaHeight"))
|
||||||
{
|
{
|
||||||
|
|
@ -636,7 +638,7 @@ namespace SecondBotEvents.Commands
|
||||||
return BasicReply("ok", new [] { escapedflagdata });
|
return BasicReply("ok", new [] { escapedflagdata });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool UpdateParcel_MediaType(Parcel targetparcel, string value)
|
protected static bool UpdateParcelMediaType(Parcel targetparcel, string value)
|
||||||
{
|
{
|
||||||
if (value == "IMG-PNG")
|
if (value == "IMG-PNG")
|
||||||
{
|
{
|
||||||
|
|
@ -670,7 +672,7 @@ namespace SecondBotEvents.Commands
|
||||||
|
|
||||||
public class GetParcelBanlistObject
|
public class GetParcelBanlistObject
|
||||||
{
|
{
|
||||||
public Dictionary<UUID, string> entrys = new Dictionary<UUID, string>();
|
public Dictionary<UUID, string> entrys = new();
|
||||||
public string parcelName = "";
|
public string parcelName = "";
|
||||||
public string regionName = "";
|
public string regionName = "";
|
||||||
public int delay = 0;
|
public int delay = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,25 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk;Microsoft.NET.Sdk.Publish">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<StartupObject>SecondBotEvents.Startup</StartupObject>
|
<StartupObject>SecondBotEvents.Startup</StartupObject>
|
||||||
<MSBuildGitHashCommand>git rev-parse --short HEAD</MSBuildGitHashCommand>
|
<MSBuildGitHashCommand>git rev-parse --short HEAD</MSBuildGitHashCommand>
|
||||||
<MSBuildGitHashValidate>False</MSBuildGitHashValidate>
|
<MSBuildGitHashValidate>False</MSBuildGitHashValidate>
|
||||||
<MSBuildGitHashSuppressDirtyWarning>False</MSBuildGitHashSuppressDirtyWarning>
|
<MSBuildGitHashSuppressDirtyWarning>False</MSBuildGitHashSuppressDirtyWarning>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net" Version="3.4.1" />
|
<PackageReference Include="Discord.Net" Version="3.11.0" />
|
||||||
<PackageReference Include="Discord.Net.WebSocket" Version="3.7.2" />
|
<PackageReference Include="Discord.Net.WebSocket" Version="3.11.0" />
|
||||||
<PackageReference Include="EmbedIO" Version="3.4.3" />
|
<PackageReference Include="EmbedIO" Version="3.5.2" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Build.Containers" Version="7.0.306" />
|
||||||
<PackageReference Include="MSBuildGitHash" Version="2.0.2">
|
<PackageReference Include="MSBuildGitHash" Version="2.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="RestSharp" Version="107.3.0" />
|
<PackageReference Include="RestSharp" Version="110.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\LibreMetaverse\LibreMetaverse.csproj" />
|
<ProjectReference Include="..\LibreMetaverse\LibreMetaverse.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.Assets;
|
using OpenMetaverse.Assets;
|
||||||
using SecondBotEvents.Config;
|
using SecondBotEvents.Config;
|
||||||
|
using Swan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
@ -200,7 +201,9 @@ namespace SecondBotEvents.Services
|
||||||
{
|
{
|
||||||
return "No sim";
|
return "No sim";
|
||||||
}
|
}
|
||||||
return client.Network.CurrentSim.Name + " " + client.Self.SimPosition.ToString();
|
Vector3 pos = client.Self.SimPosition;
|
||||||
|
string loc = "" + Math.Round(pos.X).ToString() + "," + Math.Round(pos.Y).ToString() + "," + Math.Round(pos.Z).ToString();
|
||||||
|
return client.Network.CurrentSim.Name + " " + loc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,25 +18,25 @@ namespace SecondBotEvents.Services
|
||||||
myConfig = new DataStoreConfig(master.fromEnv,master.fromFolder);
|
myConfig = new DataStoreConfig(master.fromEnv,master.fromFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Dictionary<string, UUID> avatarsName2Key = new Dictionary<string, UUID>();
|
protected Dictionary<string, UUID> avatarsName2Key = new();
|
||||||
protected Dictionary<UUID, long> avatarLastUsed = new Dictionary<UUID, long>();
|
protected Dictionary<UUID, long> avatarLastUsed = new();
|
||||||
|
|
||||||
protected Dictionary<UUID, string> groupsKey2Name = new Dictionary<UUID, string>();
|
protected Dictionary<UUID, string> groupsKey2Name = new();
|
||||||
|
|
||||||
protected Dictionary<UUID, List<UUID>> groupMembers = new Dictionary<UUID, List<UUID>>();
|
protected Dictionary<UUID, List<UUID>> groupMembers = new();
|
||||||
protected Dictionary<UUID, Dictionary<UUID, GroupRole>> groupRoles = new Dictionary<UUID, Dictionary<UUID, GroupRole>>();
|
protected Dictionary<UUID, Dictionary<UUID, GroupRole>> groupRoles = new();
|
||||||
|
|
||||||
protected List<string> localChatHistory = new List<string>();
|
protected List<string> localChatHistory = new();
|
||||||
|
|
||||||
protected Dictionary<UUID, List<string>> chatWindows = new Dictionary<UUID, List<string>>(); // sess, list chat
|
protected Dictionary<UUID, List<string>> chatWindows = new(); // sess, list chat
|
||||||
protected Dictionary<UUID, bool> chatWindowsUnread = new Dictionary<UUID, bool>(); // sess, bool
|
protected Dictionary<UUID, bool> chatWindowsUnread = new(); // sess, bool
|
||||||
protected Dictionary<UUID, bool> chatWindowsIsGroup = new Dictionary<UUID, bool>(); // sess, bool
|
protected Dictionary<UUID, bool> chatWindowsIsGroup = new(); // sess, bool
|
||||||
protected Dictionary<UUID, UUID> chatWindowsOwner = new Dictionary<UUID, UUID>(); // sess, owner id
|
protected Dictionary<UUID, UUID> chatWindowsOwner = new(); // sess, owner id
|
||||||
|
|
||||||
protected Dictionary<string, string> KeyValueStore = new Dictionary<string, string>();
|
protected Dictionary<string, string> KeyValueStore = new();
|
||||||
protected Dictionary<string, long> KeyValueStoreLastUsed = new Dictionary<string, long>();
|
protected Dictionary<string, long> KeyValueStoreLastUsed = new();
|
||||||
|
|
||||||
protected List<CommandHistory> commandHistories = new List<CommandHistory>();
|
protected List<CommandHistory> commandHistories = new();
|
||||||
|
|
||||||
protected long lastCleanupKeyValueStore = 0;
|
protected long lastCleanupKeyValueStore = 0;
|
||||||
protected long lastCleanupAvatarStore = 0;
|
protected long lastCleanupAvatarStore = 0;
|
||||||
|
|
@ -53,7 +53,7 @@ namespace SecondBotEvents.Services
|
||||||
return groupsKey2Name[group];
|
return groupsKey2Name[group];
|
||||||
}
|
}
|
||||||
string reply = "lookup";
|
string reply = "lookup";
|
||||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
AutoResetEvent fetchEvent = new(false);
|
||||||
void callback(object sender, CurrentGroupsEventArgs e)
|
void callback(object sender, CurrentGroupsEventArgs e)
|
||||||
{
|
{
|
||||||
foreach(KeyValuePair<UUID,Group> entry in e.Groups)
|
foreach(KeyValuePair<UUID,Group> entry in e.Groups)
|
||||||
|
|
@ -91,7 +91,7 @@ namespace SecondBotEvents.Services
|
||||||
if (dif > 125)
|
if (dif > 125)
|
||||||
{
|
{
|
||||||
lastCleanupKeyValueStore = unixtime;
|
lastCleanupKeyValueStore = unixtime;
|
||||||
List<string> clearentrys = new List<string>();
|
List<string> clearentrys = new();
|
||||||
foreach (KeyValuePair<string, long> entry in KeyValueStoreLastUsed)
|
foreach (KeyValuePair<string, long> entry in KeyValueStoreLastUsed)
|
||||||
{
|
{
|
||||||
dif = unixtime - entry.Value;
|
dif = unixtime - entry.Value;
|
||||||
|
|
@ -121,7 +121,7 @@ namespace SecondBotEvents.Services
|
||||||
if (dif > 75)
|
if (dif > 75)
|
||||||
{
|
{
|
||||||
lastCleanupAvatarStore = unixtime;
|
lastCleanupAvatarStore = unixtime;
|
||||||
Dictionary<UUID, string> clearLinks = new Dictionary<UUID, string>();
|
Dictionary<UUID, string> clearLinks = new();
|
||||||
foreach (KeyValuePair<string, UUID> entry in avatarsName2Key)
|
foreach (KeyValuePair<string, UUID> entry in avatarsName2Key)
|
||||||
{
|
{
|
||||||
dif = unixtime - avatarLastUsed[entry.Value];
|
dif = unixtime - avatarLastUsed[entry.Value];
|
||||||
|
|
@ -141,10 +141,10 @@ namespace SecondBotEvents.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int sum = commandHistories.Count() + KeyValueStoreLastUsed.Count() + KeyValueStore.Count() +
|
int sum = commandHistories.Count + KeyValueStoreLastUsed.Count + KeyValueStore.Count +
|
||||||
chatWindowsOwner.Count() + chatWindowsIsGroup.Count() + chatWindowsUnread.Count() +
|
chatWindowsOwner.Count + chatWindowsIsGroup.Count + chatWindowsUnread.Count +
|
||||||
chatWindows.Count() + localChatHistory.Count() + groupRoles.Count() +
|
chatWindows.Count + localChatHistory.Count + groupRoles.Count +
|
||||||
groupMembers.Count() + groupsKey2Name.Count() + avatarsName2Key.Count();
|
groupMembers.Count + groupsKey2Name.Count + avatarsName2Key.Count;
|
||||||
return sum.ToString();
|
return sum.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,7 +152,7 @@ namespace SecondBotEvents.Services
|
||||||
{
|
{
|
||||||
lock (commandHistories)
|
lock (commandHistories)
|
||||||
{
|
{
|
||||||
CommandHistory A = new CommandHistory(status, command, args, SecondbotHelpers.UnixTimeNow());
|
CommandHistory A = new(status, command, args, SecondbotHelpers.UnixTimeNow());
|
||||||
commandHistories.Add(A);
|
commandHistories.Add(A);
|
||||||
int c = commandHistories.Count;
|
int c = commandHistories.Count;
|
||||||
while (c > myConfig.GetCommandHistoryLimit())
|
while (c > myConfig.GetCommandHistoryLimit())
|
||||||
|
|
@ -226,7 +226,7 @@ namespace SecondBotEvents.Services
|
||||||
|
|
||||||
public List<UUID> GetAllGroupsChatWithUnread()
|
public List<UUID> GetAllGroupsChatWithUnread()
|
||||||
{
|
{
|
||||||
List<UUID> reply = new List<UUID>();
|
List<UUID> reply = new();
|
||||||
foreach(KeyValuePair<UUID, bool> windowState in chatWindowsUnread)
|
foreach(KeyValuePair<UUID, bool> windowState in chatWindowsUnread)
|
||||||
{
|
{
|
||||||
if(windowState.Value == false)
|
if(windowState.Value == false)
|
||||||
|
|
@ -299,11 +299,11 @@ namespace SecondBotEvents.Services
|
||||||
|
|
||||||
public Dictionary<UUID, string> GetGroupRoles(UUID group)
|
public Dictionary<UUID, string> GetGroupRoles(UUID group)
|
||||||
{
|
{
|
||||||
Dictionary<UUID, string> reply = new Dictionary<UUID, string>();
|
Dictionary<UUID, string> reply = new();
|
||||||
if (groupRoles.ContainsKey(group) == false)
|
if (groupRoles.ContainsKey(group) == false)
|
||||||
{
|
{
|
||||||
|
|
||||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
AutoResetEvent fetchEvent = new(false);
|
||||||
void callback(object sender, GroupRolesDataReplyEventArgs e)
|
void callback(object sender, GroupRolesDataReplyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.GroupID == group)
|
if (e.GroupID == group)
|
||||||
|
|
@ -341,7 +341,7 @@ namespace SecondBotEvents.Services
|
||||||
if (groupMembers[group].Contains(avatar) == false)
|
if (groupMembers[group].Contains(avatar) == false)
|
||||||
{
|
{
|
||||||
reply = false;
|
reply = false;
|
||||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
AutoResetEvent fetchEvent = new(false);
|
||||||
void callback(object sender, GroupMembersReplyEventArgs e)
|
void callback(object sender, GroupMembersReplyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.GroupID == group)
|
if (e.GroupID == group)
|
||||||
|
|
@ -395,7 +395,7 @@ namespace SecondBotEvents.Services
|
||||||
{
|
{
|
||||||
purgeLen = myConfig.GetGroupChatHistoryLimitPerGroup();
|
purgeLen = myConfig.GetGroupChatHistoryLimitPerGroup();
|
||||||
}
|
}
|
||||||
int counter = chatWindows[sessionID].Count();
|
int counter = chatWindows[sessionID].Count;
|
||||||
while (counter > purgeLen)
|
while (counter > purgeLen)
|
||||||
{
|
{
|
||||||
chatWindows[sessionID].RemoveAt(0);
|
chatWindows[sessionID].RemoveAt(0);
|
||||||
|
|
@ -471,7 +471,7 @@ namespace SecondBotEvents.Services
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Dictionary<string, KeyValuePair<string, long>> notecardDataStore = new Dictionary<string, KeyValuePair<string, long>>();
|
protected Dictionary<string, KeyValuePair<string, long>> notecardDataStore = new();
|
||||||
|
|
||||||
public List<string> GetLocalChat()
|
public List<string> GetLocalChat()
|
||||||
{
|
{
|
||||||
|
|
@ -532,7 +532,7 @@ namespace SecondBotEvents.Services
|
||||||
if(avatarsName2Key.ContainsValue(avatarId) == false)
|
if(avatarsName2Key.ContainsValue(avatarId) == false)
|
||||||
{
|
{
|
||||||
bool hasReply = false;
|
bool hasReply = false;
|
||||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
AutoResetEvent fetchEvent = new(false);
|
||||||
void callback(object sender, UUIDNameReplyEventArgs e)
|
void callback(object sender, UUIDNameReplyEventArgs e)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<UUID, string> av in e.Names)
|
foreach (KeyValuePair<UUID, string> av in e.Names)
|
||||||
|
|
@ -563,7 +563,7 @@ namespace SecondBotEvents.Services
|
||||||
UUID wantedReplyID = UUID.SecureRandom();
|
UUID wantedReplyID = UUID.SecureRandom();
|
||||||
|
|
||||||
bool hasReply = false;
|
bool hasReply = false;
|
||||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
AutoResetEvent fetchEvent = new(false);
|
||||||
void callback(object sender, AvatarPickerReplyEventArgs e)
|
void callback(object sender, AvatarPickerReplyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.QueryID == wantedReplyID)
|
if (e.QueryID == wantedReplyID)
|
||||||
|
|
@ -590,7 +590,7 @@ namespace SecondBotEvents.Services
|
||||||
|
|
||||||
public void GetAvatarNames(List<UUID> avatars)
|
public void GetAvatarNames(List<UUID> avatars)
|
||||||
{
|
{
|
||||||
List<UUID> lookup = new List<UUID>();
|
List<UUID> lookup = new();
|
||||||
foreach (UUID id in avatars)
|
foreach (UUID id in avatars)
|
||||||
{
|
{
|
||||||
if (avatarsName2Key.ContainsValue(id) == false)
|
if (avatarsName2Key.ContainsValue(id) == false)
|
||||||
|
|
@ -664,7 +664,7 @@ namespace SecondBotEvents.Services
|
||||||
|
|
||||||
public Dictionary<UUID,string> GetAvatarImWindows()
|
public Dictionary<UUID,string> GetAvatarImWindows()
|
||||||
{
|
{
|
||||||
Dictionary<UUID, string> windows = new Dictionary<UUID, string>();
|
Dictionary<UUID, string> windows = new();
|
||||||
foreach (KeyValuePair<UUID,bool> links in chatWindowsIsGroup)
|
foreach (KeyValuePair<UUID,bool> links in chatWindowsIsGroup)
|
||||||
{
|
{
|
||||||
if(links.Value == true)
|
if(links.Value == true)
|
||||||
|
|
@ -728,7 +728,7 @@ namespace SecondBotEvents.Services
|
||||||
|
|
||||||
public List<UUID> GetAvatarImWindowsUnread()
|
public List<UUID> GetAvatarImWindowsUnread()
|
||||||
{
|
{
|
||||||
List<UUID> windows = new List<UUID>();
|
List<UUID> windows = new();
|
||||||
foreach (KeyValuePair<UUID, bool> links in chatWindowsIsGroup)
|
foreach (KeyValuePair<UUID, bool> links in chatWindowsIsGroup)
|
||||||
{
|
{
|
||||||
if (links.Value == true)
|
if (links.Value == true)
|
||||||
|
|
@ -834,8 +834,8 @@ namespace SecondBotEvents.Services
|
||||||
{
|
{
|
||||||
if (estateBanlist == null)
|
if (estateBanlist == null)
|
||||||
{
|
{
|
||||||
List<UUID> reply = new List<UUID>();
|
List<UUID> reply = new();
|
||||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
AutoResetEvent fetchEvent = new(false);
|
||||||
void callback(object sender, EstateBansReplyEventArgs e)
|
void callback(object sender, EstateBansReplyEventArgs e)
|
||||||
{
|
{
|
||||||
reply = e.Banned;
|
reply = e.Banned;
|
||||||
|
|
@ -1077,7 +1077,7 @@ namespace SecondBotEvents.Services
|
||||||
public class CommandHistory
|
public class CommandHistory
|
||||||
{
|
{
|
||||||
public string Command = "";
|
public string Command = "";
|
||||||
public string[] Args = new string[] { };
|
public string[] Args = Array.Empty<string>();
|
||||||
public long Unixtime = 0;
|
public long Unixtime = 0;
|
||||||
public bool status = false;
|
public bool status = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,11 @@ namespace SecondBotEvents.Services
|
||||||
protected bool attemptedTeleportBackup = false;
|
protected bool attemptedTeleportBackup = false;
|
||||||
protected long teleportActionLockout = 0;
|
protected long teleportActionLockout = 0;
|
||||||
|
|
||||||
public void GoHome()
|
public bool GoHome()
|
||||||
{
|
{
|
||||||
attemptedTeleportHome = true;
|
attemptedTeleportHome = true;
|
||||||
LogFormater.Info("Teleporting to home sim");
|
LogFormater.Info("Teleporting to home sim");
|
||||||
GetClient().Self.Teleport(home.name, new Vector3(home.x, home.y, home.z), new Vector3(0, 0, 0));
|
return GetClient().Self.Teleport(home.name, new Vector3(home.x, home.y, home.z), new Vector3(0, 0, 0));
|
||||||
}
|
}
|
||||||
protected void Tick()
|
protected void Tick()
|
||||||
{
|
{
|
||||||
|
|
@ -84,9 +84,15 @@ namespace SecondBotEvents.Services
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (simNickname == "")
|
if (simNickname == "")
|
||||||
|
{
|
||||||
|
if (GetClient().Network.CurrentSim != null)
|
||||||
|
{
|
||||||
|
simNickname = ""+ GetClient().Network.CurrentSim.Name+" # ";
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
simNickname = "Someplace # ";
|
simNickname = "Someplace # ";
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
long dif = SecondbotHelpers.UnixTimeNow() - teleportActionLockout;
|
long dif = SecondbotHelpers.UnixTimeNow() - teleportActionLockout;
|
||||||
if(dif < 30)
|
if(dif < 30)
|
||||||
|
|
@ -96,7 +102,10 @@ namespace SecondBotEvents.Services
|
||||||
teleportActionLockout = SecondbotHelpers.UnixTimeNow();
|
teleportActionLockout = SecondbotHelpers.UnixTimeNow();
|
||||||
if (attemptedTeleportHome == false)
|
if (attemptedTeleportHome == false)
|
||||||
{
|
{
|
||||||
GoHome();
|
if(GoHome() == false)
|
||||||
|
{
|
||||||
|
LogFormater.Warn("Unable to teleport to home sim");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(attemptedTeleportBackup == false)
|
else if(attemptedTeleportBackup == false)
|
||||||
|
|
@ -104,7 +113,10 @@ namespace SecondBotEvents.Services
|
||||||
attemptedTeleportBackup = true;
|
attemptedTeleportBackup = true;
|
||||||
LogFormater.Info("Teleporting to backup sim");
|
LogFormater.Info("Teleporting to backup sim");
|
||||||
teleportActionLockout = SecondbotHelpers.UnixTimeNow();
|
teleportActionLockout = SecondbotHelpers.UnixTimeNow();
|
||||||
GetClient().Self.Teleport(backup.name, new Vector3(backup.x, backup.y, backup.z), new Vector3(0, 0, 0));
|
if(GetClient().Self.Teleport(backup.name, new Vector3(backup.x, backup.y, backup.z), new Vector3(0, 0, 0)) == false)
|
||||||
|
{
|
||||||
|
LogFormater.Warn("Unable to teleport to backup sim");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
attemptedTeleportHome = false;
|
attemptedTeleportHome = false;
|
||||||
|
|
|
||||||
|
|
@ -161,13 +161,16 @@ namespace SecondBotEvents.Services
|
||||||
string UUIDfetch = master.DataStoreService.GetAvatarUUID(avatar);
|
string UUIDfetch = master.DataStoreService.GetAvatarUUID(avatar);
|
||||||
if (UUIDfetch != "lookup")
|
if (UUIDfetch != "lookup")
|
||||||
{
|
{
|
||||||
UUID.TryParse(UUIDfetch, out avataruuid);
|
if(UUID.TryParse(UUIDfetch, out avataruuid) == false)
|
||||||
|
{
|
||||||
|
avataruuid = UUID.Zero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected object BasicReply(string input)
|
protected object BasicReply(string input)
|
||||||
{
|
{
|
||||||
return BasicReply(input, new string[] { }, GetCallingCommand());
|
return BasicReply(input, Array.Empty<string>(), GetCallingCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected object BasicReply(string input, string[] args)
|
protected object BasicReply(string input, string[] args)
|
||||||
|
|
@ -178,13 +181,13 @@ namespace SecondBotEvents.Services
|
||||||
protected object BasicReply(string input, string[] args, string command)
|
protected object BasicReply(string input, string[] args, string command)
|
||||||
{
|
{
|
||||||
master.DataStoreService.AddCommandToHistory(true, command, args);
|
master.DataStoreService.AddCommandToHistory(true, command, args);
|
||||||
return new { command = command, args = args, reply = input, status = true };
|
return new { command, args, reply = input, status = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected object Failure(string input, string command, string[] args, string whyfailed)
|
protected object Failure(string input, string command, string[] args, string whyfailed)
|
||||||
{
|
{
|
||||||
master.DataStoreService.AddCommandToHistory(false, command, args);
|
master.DataStoreService.AddCommandToHistory(false, command, args);
|
||||||
return new { command = command, args = args, reply = input, status = false, whyfailed = whyfailed };
|
return new { command, args, reply = input, status = false, whyfailed };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected object Failure(string input, string[] args)
|
protected object Failure(string input, string[] args)
|
||||||
|
|
@ -194,10 +197,10 @@ namespace SecondBotEvents.Services
|
||||||
|
|
||||||
protected object Failure(string input)
|
protected object Failure(string input)
|
||||||
{
|
{
|
||||||
return Failure(input, GetCallingCommand(), new string[] { }, null);
|
return Failure(input, GetCallingCommand(), Array.Empty<string>(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string GetCallingCommand()
|
protected static string GetCallingCommand()
|
||||||
{
|
{
|
||||||
return (new System.Diagnostics.StackTrace()).GetFrame(2).GetMethod().Name;
|
return (new System.Diagnostics.StackTrace()).GetFrame(2).GetMethod().Name;
|
||||||
}
|
}
|
||||||
|
|
@ -272,7 +275,7 @@ namespace SecondBotEvents.Services
|
||||||
|
|
||||||
public string Run([FormField] string commandName, [FormField] string args, [FormField] string signing, [FormField] string unixtime)
|
public string Run([FormField] string commandName, [FormField] string args, [FormField] string signing, [FormField] string unixtime)
|
||||||
{
|
{
|
||||||
string[] myArgs = new string[] { };
|
string[] myArgs = Array.Empty<string>();
|
||||||
if(args != null)
|
if(args != null)
|
||||||
{
|
{
|
||||||
myArgs = args.Split("~#~", StringSplitOptions.RemoveEmptyEntries);
|
myArgs = args.Split("~#~", StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
@ -285,7 +288,7 @@ namespace SecondBotEvents.Services
|
||||||
{
|
{
|
||||||
return "No bot connected yet";
|
return "No bot connected yet";
|
||||||
}
|
}
|
||||||
SignedCommand C = new SignedCommand(commandName, signing, myArgs, cmdUnixtime, null, true, 5, master.CommandsService.myConfig.GetSharedSecret());
|
SignedCommand C = new(commandName, signing, myArgs, cmdUnixtime, null, true, 5, master.CommandsService.myConfig.GetSharedSecret());
|
||||||
if(C.accepted == false)
|
if(C.accepted == false)
|
||||||
{
|
{
|
||||||
return "Command request rejected";
|
return "Command request rejected";
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace SecondBotEvents.Services
|
||||||
{
|
{
|
||||||
protected RelayConfig myConfig;
|
protected RelayConfig myConfig;
|
||||||
protected bool botConnected = false;
|
protected bool botConnected = false;
|
||||||
protected List<RelaySys> Relays = new List<RelaySys>();
|
protected List<RelaySys> Relays = new();
|
||||||
public RelayService(EventsSecondBot setMaster) : base(setMaster)
|
public RelayService(EventsSecondBot setMaster) : base(setMaster)
|
||||||
{
|
{
|
||||||
myConfig = new RelayConfig(master.fromEnv, master.fromFolder);
|
myConfig = new RelayConfig(master.fromEnv, master.fromFolder);
|
||||||
|
|
@ -348,7 +348,7 @@ namespace SecondBotEvents.Services
|
||||||
readonly string[] vaildToOptions = new[] { "avatar", "group", "localchat", "discord", "http" };
|
readonly string[] vaildToOptions = new[] { "avatar", "group", "localchat", "discord", "http" };
|
||||||
readonly
|
readonly
|
||||||
|
|
||||||
protected HttpClient HTTPclient = new HttpClient();
|
protected HttpClient HTTPclient = new();
|
||||||
public void TriggerWith(string sourceType, string message, string filterOption1, string filterOption2=null, string filterOption3 = null)
|
public void TriggerWith(string sourceType, string message, string filterOption1, string filterOption2=null, string filterOption3 = null)
|
||||||
{
|
{
|
||||||
// avatarim, {message}, avatarUUID
|
// avatarim, {message}, avatarUUID
|
||||||
|
|
@ -414,7 +414,7 @@ namespace SecondBotEvents.Services
|
||||||
case "http":
|
case "http":
|
||||||
{
|
{
|
||||||
long unixtime = SecondbotHelpers.UnixTimeNow();
|
long unixtime = SecondbotHelpers.UnixTimeNow();
|
||||||
Dictionary<string, string> values = new Dictionary<string, string>
|
Dictionary<string, string> values = new()
|
||||||
{
|
{
|
||||||
{ "fromType", fromType },
|
{ "fromType", fromType },
|
||||||
{ "fromOption", fromOption },
|
{ "fromOption", fromOption },
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ using System.Text;
|
||||||
|
|
||||||
namespace SecondBotEvents
|
namespace SecondBotEvents
|
||||||
{
|
{
|
||||||
public static class parcel_static
|
public static class ParcelStatic
|
||||||
{
|
{
|
||||||
public static bool set_parcel_music(GridClient bot, Parcel p, string url)
|
public static bool SetParcelMusic(GridClient bot, Parcel p, string url)
|
||||||
{
|
{
|
||||||
if (p.MusicURL != url)
|
if (p.MusicURL != url)
|
||||||
{
|
{
|
||||||
|
|
@ -27,7 +27,7 @@ namespace SecondBotEvents
|
||||||
p.Flags |= F;
|
p.Flags |= F;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static bool has_parcel_perm(Parcel P, GridClient bot)
|
public static bool HasParcelPerm(Parcel P, GridClient bot)
|
||||||
{
|
{
|
||||||
bool has_perm = true;
|
bool has_perm = true;
|
||||||
if (P.OwnerID != bot.Self.AgentID)
|
if (P.OwnerID != bot.Self.AgentID)
|
||||||
|
|
@ -54,30 +54,32 @@ namespace SecondBotEvents
|
||||||
return has_perm;
|
return has_perm;
|
||||||
|
|
||||||
}
|
}
|
||||||
public static string[] get_flag_names()
|
public static string[] GetFlagNames()
|
||||||
{
|
{
|
||||||
System.Type enumType = typeof(ParcelFlags);
|
System.Type enumType = typeof(ParcelFlags);
|
||||||
List<string> flagnames = new List<string>(System.Enum.GetNames(enumType));
|
List<string> flagnames = new(System.Enum.GetNames(enumType));
|
||||||
flagnames.Remove("None");
|
flagnames.Remove("None");
|
||||||
return flagnames.ToArray();
|
return flagnames.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, string> get_media_list()
|
public static Dictionary<string, string> GetMediaList()
|
||||||
{
|
{
|
||||||
Dictionary<string, string> flags = new Dictionary<string, string>();
|
Dictionary<string, string> flags = new()
|
||||||
flags.Add("MediaAutoScale", "Bool (True|False)");
|
{
|
||||||
flags.Add("MediaLoop", "Bool (True|False)");
|
{ "MediaAutoScale", "Bool (True|False)" },
|
||||||
flags.Add("MediaID", "UUID (Texture)");
|
{ "MediaLoop", "Bool (True|False)" },
|
||||||
flags.Add("MediaURL", "String");
|
{ "MediaID", "UUID (Texture)" },
|
||||||
flags.Add("MediaDesc", "String");
|
{ "MediaURL", "String" },
|
||||||
flags.Add("MediaHeight", "Int (256 to 1024)");
|
{ "MediaDesc", "String" },
|
||||||
flags.Add("MediaWidth", "Int (256 to 1024)");
|
{ "MediaHeight", "Int (256 to 1024)" },
|
||||||
flags.Add("MediaType", "String [\"IMG-PNG\",\"IMG-JPG\",\"VID-MP4\",\"VID-AVI\" or \"Custom-MIME_TYPE_CODE\"]");
|
{ "MediaWidth", "Int (256 to 1024)" },
|
||||||
|
{ "MediaType", "String [\"IMG-PNG\",\"IMG-JPG\",\"VID-MP4\",\"VID-AVI\" or \"Custom-MIME_TYPE_CODE\"]" }
|
||||||
|
};
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
public static Dictionary<string, ParcelFlags> get_flags_list()
|
public static Dictionary<string, ParcelFlags> GetFlagsList()
|
||||||
{
|
{
|
||||||
Dictionary<string, ParcelFlags> flags = new Dictionary<string, ParcelFlags>();
|
Dictionary<string, ParcelFlags> flags = new();
|
||||||
Type enumType = typeof(ParcelFlags);
|
Type enumType = typeof(ParcelFlags);
|
||||||
Array enumValues = Enum.GetValues(enumType);
|
Array enumValues = Enum.GetValues(enumType);
|
||||||
Array enumNames = Enum.GetNames(enumType);
|
Array enumNames = Enum.GetNames(enumType);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue