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>
|
||||
<Description>LibreMetaverse structured data library</Description>
|
||||
<PackageId>LibreMetaverse.StructuredData</PackageId>
|
||||
<TargetFrameworks>net48;netstandard2.1;net6.0;net7.0</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0</TargetFrameworks>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>LibreMetaverse.StructuredData</RootNamespace>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<AssemblyName>LibreMetaverse.Types</AssemblyName>
|
||||
<PackageId>LibreMetaverse.Types</PackageId>
|
||||
<Description>LibreMetaverse type library</Description>
|
||||
<TargetFrameworks>net48;netstandard2.1;net6.0;net7.0</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0</TargetFrameworks>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>LibreMetaverse</RootNamespace>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ namespace OpenMetaverse
|
|||
public static string MD5(string str)
|
||||
{
|
||||
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
|
||||
foreach (byte b in hash)
|
||||
|
|
@ -399,7 +399,7 @@ namespace OpenMetaverse
|
|||
/// <returns>The PBKDF2 hash of the supplied string</returns>
|
||||
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[] salt = derivebytes.Salt;
|
||||
return Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash);
|
||||
|
|
|
|||
|
|
@ -910,7 +910,7 @@ namespace OpenMetaverse
|
|||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
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>
|
||||
public event EventHandler<InstantMessageEventArgs> IM
|
||||
{
|
||||
|
|
@ -1104,8 +1104,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnCameraConstraint(CameraConstraintEventArgs e)
|
||||
{
|
||||
EventHandler<CameraConstraintEventArgs> handler = m_CameraConstraint;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -1128,8 +1127,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnScriptSensorReply(ScriptSensorReplyEventArgs e)
|
||||
{
|
||||
EventHandler<ScriptSensorReplyEventArgs> handler = m_ScriptSensorReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -1151,8 +1149,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnAvatarSitResponse(AvatarSitResponseEventArgs e)
|
||||
{
|
||||
EventHandler<AvatarSitResponseEventArgs> handler = m_AvatarSitResponse;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -1478,7 +1475,7 @@ namespace OpenMetaverse
|
|||
|
||||
private HomeInfo home;
|
||||
private string fullName;
|
||||
private TeleportStatus teleportStat = TeleportStatus.None;
|
||||
private TeleportStatus teleportStatus = TeleportStatus.None;
|
||||
private ManualResetEvent teleportEvent = new ManualResetEvent(false);
|
||||
private uint heightWidthGenCounter;
|
||||
private Dictionary<UUID, AssetGesture> gestureCache = new Dictionary<UUID, AssetGesture>();
|
||||
|
|
@ -2966,7 +2963,13 @@ namespace OpenMetaverse
|
|||
/// <returns>true on success, false on failure</returns>
|
||||
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();
|
||||
TeleportLandmarkRequestPacket p = new TeleportLandmarkRequestPacket
|
||||
{
|
||||
|
|
@ -2981,15 +2984,15 @@ namespace OpenMetaverse
|
|||
|
||||
teleportEvent.WaitOne(Client.Settings.TELEPORT_TIMEOUT, false);
|
||||
|
||||
if (teleportStat == TeleportStatus.None ||
|
||||
teleportStat == TeleportStatus.Start ||
|
||||
teleportStat == TeleportStatus.Progress)
|
||||
if (teleportStatus == TeleportStatus.None ||
|
||||
teleportStatus == TeleportStatus.Start ||
|
||||
teleportStatus == TeleportStatus.Progress)
|
||||
{
|
||||
TeleportMessage = "Teleport timed out.";
|
||||
teleportStat = TeleportStatus.Failed;
|
||||
teleportStatus = TeleportStatus.Failed;
|
||||
}
|
||||
|
||||
return (teleportStat == TeleportStatus.Finished);
|
||||
return (teleportStatus == TeleportStatus.Finished);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -3018,7 +3021,14 @@ namespace OpenMetaverse
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -3030,7 +3040,7 @@ namespace OpenMetaverse
|
|||
else
|
||||
{
|
||||
TeleportMessage = $"Unable to resolve simulator named: {simName}";
|
||||
teleportStat = TeleportStatus.Failed;
|
||||
teleportStatus = TeleportStatus.Failed;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -3063,40 +3073,46 @@ namespace OpenMetaverse
|
|||
/// <remarks>This call is blocking</remarks>
|
||||
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 ||
|
||||
Client.Network.CurrentSim.Caps == null ||
|
||||
!Client.Network.CurrentSim.Caps.IsEventQueueRunning)
|
||||
{
|
||||
// Wait a bit to see if the event queue comes online
|
||||
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)
|
||||
{
|
||||
if (e.Simulator == Client.Network.CurrentSim) { queueEvent.Set(); }
|
||||
}
|
||||
|
||||
Client.Network.EventQueueRunning += QueueCallback;
|
||||
queueEvent.WaitOne(10 * 1000, false);
|
||||
Client.Network.EventQueueRunning -= queueCallback;
|
||||
Client.Network.EventQueueRunning -= QueueCallback;
|
||||
}
|
||||
|
||||
teleportStat = TeleportStatus.None;
|
||||
teleportStatus = TeleportStatus.None;
|
||||
teleportEvent.Reset();
|
||||
|
||||
RequestTeleport(regionHandle, position, lookAt);
|
||||
|
||||
teleportEvent.WaitOne(Client.Settings.TELEPORT_TIMEOUT, false);
|
||||
|
||||
if (teleportStat == TeleportStatus.None ||
|
||||
teleportStat == TeleportStatus.Start ||
|
||||
teleportStat == TeleportStatus.Progress)
|
||||
if (teleportStatus == TeleportStatus.None ||
|
||||
teleportStatus == TeleportStatus.Start ||
|
||||
teleportStatus == TeleportStatus.Progress)
|
||||
{
|
||||
TeleportMessage = "Teleport timed out.";
|
||||
teleportStat = TeleportStatus.Failed;
|
||||
teleportStatus = TeleportStatus.Failed;
|
||||
}
|
||||
|
||||
return (teleportStat == TeleportStatus.Finished);
|
||||
return (teleportStatus == TeleportStatus.Finished);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -3117,8 +3133,7 @@ namespace OpenMetaverse
|
|||
/// <param name="lookAt"><seealso cref="Vector3"/> direction in destination sim agent will look at</param>
|
||||
public void RequestTeleport(ulong regionHandle, Vector3 position, Vector3 lookAt)
|
||||
{
|
||||
if (Client.Network.CurrentSim != null &&
|
||||
Client.Network.CurrentSim.Caps != null &&
|
||||
if (Client.Network?.CurrentSim?.Caps != null &&
|
||||
Client.Network.CurrentSim.Caps.IsEventQueueRunning)
|
||||
{
|
||||
TeleportLocationRequestPacket teleport = new TeleportLocationRequestPacket
|
||||
|
|
@ -3144,7 +3159,7 @@ namespace OpenMetaverse
|
|||
{
|
||||
TeleportMessage = "CAPS event queue is not running";
|
||||
teleportEvent.Set();
|
||||
teleportStat = TeleportStatus.Failed;
|
||||
teleportStatus = TeleportStatus.Failed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3251,7 +3266,7 @@ namespace OpenMetaverse
|
|||
}
|
||||
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
|
||||
|
|
@ -4302,7 +4317,9 @@ namespace OpenMetaverse
|
|||
SimAccess = (byte) msg.SimAccess,
|
||||
SimIP = Utils.IPToUInt(msg.IP),
|
||||
SimPort = (ushort) msg.Port,
|
||||
TeleportFlags = (uint) msg.Flags
|
||||
TeleportFlags = (uint) msg.Flags,
|
||||
RegionSizeX = msg.RegionSizeX,
|
||||
RegionSizeY = msg.RegionSizeY
|
||||
}
|
||||
};
|
||||
// FIXME: Check This
|
||||
|
|
@ -4328,7 +4345,7 @@ namespace OpenMetaverse
|
|||
|
||||
TeleportMessage = "Teleport started";
|
||||
flags = (TeleportFlags)start.Info.TeleportFlags;
|
||||
teleportStat = TeleportStatus.Start;
|
||||
teleportStatus = TeleportStatus.Start;
|
||||
|
||||
Logger.DebugLog($"TeleportStart received, Flags: {flags}", Client);
|
||||
}
|
||||
|
|
@ -4338,7 +4355,7 @@ namespace OpenMetaverse
|
|||
|
||||
TeleportMessage = Utils.BytesToString(progress.Info.Message);
|
||||
flags = (TeleportFlags)progress.Info.TeleportFlags;
|
||||
teleportStat = TeleportStatus.Progress;
|
||||
teleportStatus = TeleportStatus.Progress;
|
||||
|
||||
Logger.DebugLog($"TeleportProgress received, Message: {TeleportMessage}, Flags: {flags}", Client);
|
||||
}
|
||||
|
|
@ -4347,7 +4364,7 @@ namespace OpenMetaverse
|
|||
TeleportFailedPacket failed = (TeleportFailedPacket)packet;
|
||||
|
||||
TeleportMessage = Utils.BytesToString(failed.Info.Reason);
|
||||
teleportStat = TeleportStatus.Failed;
|
||||
teleportStatus = TeleportStatus.Failed;
|
||||
finished = true;
|
||||
|
||||
Logger.DebugLog($"TeleportFailed received, Reason: {TeleportMessage}", Client);
|
||||
|
|
@ -4365,19 +4382,20 @@ namespace OpenMetaverse
|
|||
// Connect to the new sim
|
||||
Client.Network.CurrentSim.AgentMovementComplete = false; // we're not there anymore
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
TeleportMessage = "Failed to connect to the new sim after a teleport";
|
||||
teleportStat = TeleportStatus.Failed;
|
||||
TeleportMessage = $"Failed to connect to {newSimulator} after teleport";
|
||||
teleportStatus = TeleportStatus.Failed;
|
||||
|
||||
// We're going to get disconnected now
|
||||
Logger.Log(TeleportMessage, Helpers.LogLevel.Error, Client);
|
||||
|
|
@ -4388,7 +4406,7 @@ namespace OpenMetaverse
|
|||
//TeleportCancelPacket cancel = (TeleportCancelPacket)packet;
|
||||
|
||||
TeleportMessage = "Cancelled";
|
||||
teleportStat = TeleportStatus.Cancelled;
|
||||
teleportStatus = TeleportStatus.Cancelled;
|
||||
finished = true;
|
||||
|
||||
Logger.DebugLog($"TeleportCancel received from {simulator}", Client);
|
||||
|
|
@ -4399,7 +4417,7 @@ namespace OpenMetaverse
|
|||
|
||||
TeleportMessage = "Teleport finished";
|
||||
flags = (TeleportFlags)local.Info.TeleportFlags;
|
||||
teleportStat = TeleportStatus.Finished;
|
||||
teleportStatus = TeleportStatus.Finished;
|
||||
relativePosition = local.Info.Position;
|
||||
Movement.Camera.LookDirection(local.Info.LookAt);
|
||||
// This field is apparently not used for anything
|
||||
|
|
@ -4411,7 +4429,7 @@ namespace OpenMetaverse
|
|||
|
||||
if (m_Teleport != null)
|
||||
{
|
||||
OnTeleport(new TeleportEventArgs(TeleportMessage, teleportStat, flags));
|
||||
OnTeleport(new TeleportEventArgs(TeleportMessage, teleportStatus, flags));
|
||||
}
|
||||
|
||||
if (finished) { teleportEvent.Set(); }
|
||||
|
|
@ -4541,7 +4559,8 @@ namespace OpenMetaverse
|
|||
Logger.DebugLog($"Crossed in to new region area, attempting to connect to {endPoint}", Client);
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -393,18 +393,12 @@ namespace OpenMetaverse
|
|||
{
|
||||
if (value > 0)
|
||||
{
|
||||
if (updateTimer != null)
|
||||
{
|
||||
updateTimer.Change(value, value);
|
||||
}
|
||||
updateTimer?.Change(value, value);
|
||||
updateInterval = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (updateTimer != null)
|
||||
{
|
||||
updateTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
updateTimer?.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
updateInterval = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ namespace OpenMetaverse
|
|||
/// </summary>
|
||||
/// <param name="assetID">UUID of the asset</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)
|
||||
{
|
||||
if (!Operational())
|
||||
|
|
|
|||
|
|
@ -319,8 +319,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnXferReceived(XferReceivedEventArgs e)
|
||||
{
|
||||
EventHandler<XferReceivedEventArgs> handler = m_XferReceivedEvent;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -344,8 +343,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnAssetUploaded(AssetUploadEventArgs e)
|
||||
{
|
||||
EventHandler<AssetUploadEventArgs> handler = m_AssetUploadedEvent;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -369,8 +367,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnUploadProgress(AssetUploadEventArgs e)
|
||||
{
|
||||
EventHandler<AssetUploadEventArgs> handler = m_UploadProgressEvent;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -394,8 +391,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnInitiateDownload(InitiateDownloadEventArgs e)
|
||||
{
|
||||
EventHandler<InitiateDownloadEventArgs> handler = m_InitiateDownloadEvent;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -419,8 +415,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnImageReceiveProgress(ImageReceiveProgressEventArgs e)
|
||||
{
|
||||
EventHandler<ImageReceiveProgressEventArgs> handler = m_ImageReceiveProgressEvent;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <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 (Client.Network.CurrentSim.Caps != null
|
||||
&& Client.Network.CurrentSim.Caps.CapabilityURI("ViewerAsset") != null)
|
||||
if (Client.Network.CurrentSim?.Caps?.CapabilityURI("ViewerAsset") != null)
|
||||
{
|
||||
RequestAssetHTTP(assetID, transfer, callback);
|
||||
}
|
||||
|
|
@ -827,10 +821,20 @@ namespace OpenMetaverse
|
|||
}
|
||||
|
||||
// If ViewerAsset capability exists, use that, if not, fallback to UDP
|
||||
if (Client.Network.CurrentSim.Caps != null
|
||||
&& Client.Network.CurrentSim.Caps.CapabilityURI("ViewerAsset") != null)
|
||||
if (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
|
||||
{
|
||||
|
|
@ -849,6 +853,7 @@ namespace OpenMetaverse
|
|||
/// <param name="callback"></param>
|
||||
private void RequestInventoryAssetHTTP(UUID assetID, AssetDownload transfer, AssetReceivedCallback callback)
|
||||
{
|
||||
int attempts = 0;
|
||||
DownloadRequest req = new DownloadRequest(
|
||||
BuildFetchRequestUri(transfer.AssetType, assetID),
|
||||
null,
|
||||
|
|
@ -873,6 +878,7 @@ namespace OpenMetaverse
|
|||
}
|
||||
else // download failed
|
||||
{
|
||||
attempts++;
|
||||
Logger.Log($"Failed to fetch asset {assetID}: {((error == null) ? "" : error.Message)}",
|
||||
Helpers.LogLevel.Warning, Client);
|
||||
if (callback != null)
|
||||
|
|
@ -880,6 +886,10 @@ namespace OpenMetaverse
|
|||
transfer.Success = false;
|
||||
transfer.Status = StatusCode.Error;
|
||||
}
|
||||
if (attempts == 5)
|
||||
{
|
||||
callback(transfer, null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1213,8 +1223,7 @@ namespace OpenMetaverse
|
|||
if (meshID == UUID.Zero || callback == null)
|
||||
return;
|
||||
|
||||
if (Client.Network.CurrentSim.Caps != null &&
|
||||
Client.Network.CurrentSim.Caps.GetMeshCapURI() != null)
|
||||
if (Client.Network.CurrentSim?.Caps?.GetMeshCapURI() != null)
|
||||
{
|
||||
// Do we have this mesh asset in the cache?
|
||||
if (Client.Assets.Cache.HasAsset(meshID))
|
||||
|
|
@ -1329,8 +1338,7 @@ namespace OpenMetaverse
|
|||
uint packetStart, TextureDownloadCallback callback, bool progress)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ namespace OpenMetaverse.Assets
|
|||
|
||||
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];
|
||||
bool loaded = false;
|
||||
|
||||
|
|
@ -350,10 +351,10 @@ namespace OpenMetaverse.Assets
|
|||
BinaryWriter bs = new BinaryWriter(s);
|
||||
|
||||
int y;
|
||||
for (y = 0; y < 256; y++)
|
||||
for (y = 0; y < sim.SizeY; y++)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < 256; x++)
|
||||
for (x = 0; x < sim.SizeX; x++)
|
||||
{
|
||||
float height;
|
||||
sim.TerrainHeightAtPoint(x, y, out height);
|
||||
|
|
|
|||
|
|
@ -689,9 +689,7 @@ namespace OpenMetaverse
|
|||
/// <returns>True if Display name functionality is available</returns>
|
||||
public bool DisplayNamesAvailable()
|
||||
{
|
||||
return (Client.Network.CurrentSim != null
|
||||
&& Client.Network.CurrentSim.Caps != null)
|
||||
&& Client.Network.CurrentSim.Caps.CapabilityURI("GetDisplayNames") != null;
|
||||
return Client.Network.CurrentSim?.Caps?.CapabilityURI("GetDisplayNames") != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -296,8 +296,7 @@ namespace OpenMetaverse.Http
|
|||
}
|
||||
|
||||
// Fire the download progress callback for each chunk of received data
|
||||
if (state.DownloadProgressCallback != null)
|
||||
state.DownloadProgressCallback(state.Request, response, totalBytesRead, totalSize);
|
||||
state.DownloadProgressCallback?.Invoke(state.Request, response, totalBytesRead, totalSize);
|
||||
}
|
||||
|
||||
if (nolength)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2016, openmetaverse.co
|
||||
* Copyright (c) 2022, Sjofn LLC.
|
||||
* Copyright (c) 2022-2023, Sjofn LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* - Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -38,9 +38,9 @@ namespace OpenMetaverse.Http
|
|||
public class EventQueueClient
|
||||
{
|
||||
/// <summary>For exponential backoff on error.</summary>
|
||||
public const int REQUEST_BACKOFF_SECONDS = 15 * 1000; // 15 seconds start
|
||||
public 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 = 15 * 1000; // 15 seconds start
|
||||
private const int REQUEST_BACKOFF_SECONDS_INC = 5 * 1000; // 5 seconds increase
|
||||
private const int REQUEST_BACKOFF_SECONDS_MAX = 5 * 60 * 1000; // 5 minutes
|
||||
|
||||
public delegate void ConnectedCallback();
|
||||
public delegate void EventCallback(string eventName, OSDMap body);
|
||||
|
|
@ -48,13 +48,14 @@ namespace OpenMetaverse.Http
|
|||
public ConnectedCallback OnConnected;
|
||||
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>
|
||||
private int _errorCount;
|
||||
|
|
@ -63,19 +64,71 @@ namespace OpenMetaverse.Http
|
|||
{
|
||||
_Address = eventQueueLocation;
|
||||
_Simulator = sim;
|
||||
_queueCts = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_Dead = false;
|
||||
_Running = true;
|
||||
Running = true;
|
||||
|
||||
// Create an EventQueueGet request
|
||||
OSDMap payload = new OSDMap {["ack"] = new OSD(), ["done"] = OSD.FromBoolean(false)};
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
// 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)
|
||||
|
|
@ -84,17 +137,17 @@ namespace OpenMetaverse.Http
|
|||
|
||||
if (immediate)
|
||||
{
|
||||
_Running = false;
|
||||
Running = false;
|
||||
}
|
||||
|
||||
_HttpCts.Cancel();
|
||||
_queueCts.Cancel();
|
||||
}
|
||||
|
||||
void ConnectedResponseHandler(HttpResponseMessage response)
|
||||
{
|
||||
if (!response.IsSuccessStatusCode) { return; }
|
||||
|
||||
_Running = true;
|
||||
Running = true;
|
||||
|
||||
// The event queue is starting up for the first time
|
||||
if (OnConnected != null)
|
||||
|
|
@ -120,11 +173,11 @@ namespace OpenMetaverse.Http
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
else if (error != null)
|
||||
else if (response != null && error != null)
|
||||
{
|
||||
#region Error handling
|
||||
|
||||
|
|
@ -132,30 +185,31 @@ namespace OpenMetaverse.Http
|
|||
{
|
||||
case HttpStatusCode.NotFound:
|
||||
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;
|
||||
break;
|
||||
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)
|
||||
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;
|
||||
break;
|
||||
case HttpStatusCode.InternalServerError:
|
||||
// As per LL's instructions, we ought to consider this a
|
||||
// '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!
|
||||
if (error.InnerException != null)
|
||||
{
|
||||
// unravel the whole inner error message, so we finally figure out what it is!
|
||||
// (gwyneth 20220414)
|
||||
Logger.Log($"Unrecognized internal caps exception from {_Simulator}: '{error.InnerException.Message}'", Helpers.LogLevel.Warning);
|
||||
Logger.Log($"\nMessage ---\n{error.Message}", Helpers.LogLevel.Warning);
|
||||
Logger.Log($"Unrecognized internal caps exception from {_Simulator}: '{error.InnerException.Message}'",
|
||||
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||
Logger.Log($"\nMessage ---\n{error.Message}", Helpers.LogLevel.Warning, _Simulator.Client);
|
||||
if (error.Data.Count > 0)
|
||||
{
|
||||
Logger.Log(" Extra details:", Helpers.LogLevel.Warning);
|
||||
|
|
@ -163,13 +217,13 @@ namespace OpenMetaverse.Http
|
|||
{
|
||||
Logger.Log(String.Format(" Key: {0,-20} Value: '{1}'",
|
||||
de.Key, de.Value),
|
||||
Helpers.LogLevel.Warning);
|
||||
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||
}
|
||||
}
|
||||
// but we'll nevertheless close this connection (gwyneth 20220414)
|
||||
}
|
||||
|
||||
_Running = false;
|
||||
Running = false;
|
||||
_Dead = true;
|
||||
break;
|
||||
case HttpStatusCode.BadGateway:
|
||||
|
|
@ -182,7 +236,8 @@ namespace OpenMetaverse.Http
|
|||
// 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)
|
||||
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;
|
||||
default:
|
||||
++_errorCount;
|
||||
|
|
@ -191,71 +246,55 @@ namespace OpenMetaverse.Http
|
|||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// see comment above (gwyneth 20220414)
|
||||
Logger.Log($"Unrecognized internal caps exception from {_Simulator}: '{error.InnerException.Message}'", Helpers.LogLevel.Warning);
|
||||
Logger.Log($"Message ---\n{error.Message}", Helpers.LogLevel.Warning);
|
||||
Logger.Log($"Unrecognized internal caps exception from {_Simulator}: '{error.InnerException.Message}'",
|
||||
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||
Logger.Log($"Message ---\n{error.Message}", Helpers.LogLevel.Warning, _Simulator.Client);
|
||||
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)
|
||||
{
|
||||
Logger.Log(string.Format(" Key: {0,-20} Value: {1}",
|
||||
"'" + de.Key + "'", de.Value),
|
||||
Helpers.LogLevel.Warning);
|
||||
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log($"Unrecognized caps exception from {_Simulator}: {error.Message}",
|
||||
Helpers.LogLevel.Warning);
|
||||
Helpers.LogLevel.Warning, _Simulator.Client);
|
||||
}
|
||||
break;
|
||||
} // end switch
|
||||
|
||||
#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
|
||||
{
|
||||
++_errorCount;
|
||||
|
||||
Logger.Log($"No response from {_Simulator} event queue but no reported error either", Helpers.LogLevel.Warning);
|
||||
Logger.Log($"No response from {_Simulator} event queue with no reported error", Helpers.LogLevel.Warning, _Simulator.Client);
|
||||
}
|
||||
|
||||
#pragma warning disable CS0164 // This label has not been referenced
|
||||
HandlingDone:
|
||||
|
||||
#region Resume the connection
|
||||
|
||||
if (_Running)
|
||||
if (Running)
|
||||
{
|
||||
OSDMap payload = new OSDMap();
|
||||
if (ack != 0) { payload["ack"] = OSD.FromInteger(ack); }
|
||||
else { payload["ack"] = new OSD(); }
|
||||
payload["done"] = OSD.FromBoolean(_Dead);
|
||||
|
||||
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}");
|
||||
}
|
||||
_AckPayload = payload;
|
||||
}
|
||||
#pragma warning restore CS0164 // This label has not been referenced
|
||||
|
||||
#endregion Resume the connection
|
||||
|
||||
#region Handle incoming events
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Sjofn, LLC.
|
||||
* Copyright (c) 2022-2023, Sjofn, LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* - Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -234,19 +234,26 @@ namespace LibreMetaverse
|
|||
private async Task SendRequestAsync(HttpRequestMessage request, CancellationToken? cancellationToken,
|
||||
DownloadCompleteHandler completeHandler, DownloadProgressHandler progressHandler, ConnectedHandler connectedHandler)
|
||||
{
|
||||
using (var response = (cancellationToken.HasValue)
|
||||
? await SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken.Value)
|
||||
: await SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
|
||||
try
|
||||
{
|
||||
if (!response.IsSuccessStatusCode)
|
||||
using (var response = (cancellationToken.HasValue)
|
||||
? await SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken.Value)
|
||||
: await SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
|
||||
{
|
||||
completeHandler?.Invoke(response, null,
|
||||
new HttpRequestException(response.StatusCode + " " + response.ReasonPhrase));
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
completeHandler?.Invoke(response, null,
|
||||
new HttpRequestException(response.StatusCode + " " + response.ReasonPhrase));
|
||||
}
|
||||
|
||||
connectedHandler?.Invoke(response);
|
||||
|
||||
await ProcessResponseAsync(response, cancellationToken, completeHandler, progressHandler);
|
||||
}
|
||||
|
||||
connectedHandler?.Invoke(response);
|
||||
|
||||
await ProcessResponseAsync(response, cancellationToken, completeHandler, progressHandler);
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
completeHandler?.Invoke(null, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -307,6 +307,7 @@ namespace OpenMetaverse
|
|||
private void EventQueueConnectedHandler()
|
||||
{
|
||||
Logger.DebugLog($"Event queue for {Simulator} is connected", Simulator.Client);
|
||||
Simulator.DisconnectCandidate = false;
|
||||
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",
|
||||
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);
|
||||
|
||||
// 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>
|
||||
/// Searches Places for land owned by the specified group
|
||||
/// </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>
|
||||
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="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="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>
|
||||
/// <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,
|
||||
|
|
|
|||
|
|
@ -167,8 +167,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnTopCollidersReply(TopCollidersReplyEventArgs e)
|
||||
{
|
||||
EventHandler<TopCollidersReplyEventArgs> handler = m_TopCollidersReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -190,8 +189,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnTopScriptsReply(TopScriptsReplyEventArgs e)
|
||||
{
|
||||
EventHandler<TopScriptsReplyEventArgs> handler = m_TopScriptsReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -214,8 +212,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnEstateUsersReply(EstateUsersReplyEventArgs e)
|
||||
{
|
||||
EventHandler<EstateUsersReplyEventArgs> handler = m_EstateUsersReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -238,8 +235,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnEstateGroupsReply(EstateGroupsReplyEventArgs e)
|
||||
{
|
||||
EventHandler<EstateGroupsReplyEventArgs> handler = m_EstateGroupsReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -261,8 +257,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnEstateManagersReply(EstateManagersReplyEventArgs e)
|
||||
{
|
||||
EventHandler<EstateManagersReplyEventArgs> handler = m_EstateManagersReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -284,8 +279,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnEstateBansReply(EstateBansReplyEventArgs e)
|
||||
{
|
||||
EventHandler<EstateBansReplyEventArgs> handler = m_EstateBansReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -307,8 +301,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnEstateCovenantReply(EstateCovenantReplyEventArgs e)
|
||||
{
|
||||
EventHandler<EstateCovenantReplyEventArgs> handler = m_EstateCovenantReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -331,8 +324,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnEstateUpdateInfoReply(EstateUpdateInfoReplyEventArgs e)
|
||||
{
|
||||
EventHandler<EstateUpdateInfoReplyEventArgs> handler = m_EstateUpdateInfoReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
|
|||
|
|
@ -218,8 +218,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnfriendsListReady(FriendsReadyEventArgs e)
|
||||
{
|
||||
EventHandler<FriendsReadyEventArgs> handler = m_FriendsListReadyResponse;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -240,8 +239,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnFriendOnline(FriendInfoEventArgs e)
|
||||
{
|
||||
EventHandler<FriendInfoEventArgs> handler = m_FriendOnline;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -263,8 +261,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnFriendOffline(FriendInfoEventArgs e)
|
||||
{
|
||||
EventHandler<FriendInfoEventArgs> handler = m_FriendOffline;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -286,8 +283,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnFriendRights(FriendInfoEventArgs e)
|
||||
{
|
||||
EventHandler<FriendInfoEventArgs> handler = m_FriendRights;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -309,8 +305,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnFriendNames(FriendNamesEventArgs e)
|
||||
{
|
||||
EventHandler<FriendNamesEventArgs> handler = m_FriendNames;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -332,8 +327,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnFriendshipOffered(FriendshipOfferedEventArgs e)
|
||||
{
|
||||
EventHandler<FriendshipOfferedEventArgs> handler = m_FriendshipOffered;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -355,8 +349,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnFriendshipResponse(FriendshipResponseEventArgs e)
|
||||
{
|
||||
EventHandler<FriendshipResponseEventArgs> handler = m_FriendshipResponse;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -378,8 +371,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnFriendshipTerminated(FriendshipTerminatedEventArgs e)
|
||||
{
|
||||
EventHandler<FriendshipTerminatedEventArgs> handler = m_FriendshipTerminated;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -402,8 +394,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnFriendFoundReply(FriendFoundReplyEventArgs e)
|
||||
{
|
||||
EventHandler<FriendFoundReplyEventArgs> handler = m_FriendFound;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
|
|||
|
|
@ -145,7 +145,6 @@ namespace OpenMetaverse
|
|||
{
|
||||
AllowAutoRedirect = true,
|
||||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
|
||||
MaxConnectionsPerServer = Settings.MAX_HTTP_CONNECTIONS,
|
||||
ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
|
||||
{
|
||||
if (sslPolicyErrors == SslPolicyErrors.None)
|
||||
|
|
@ -157,6 +156,10 @@ namespace OpenMetaverse
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
if (Utils.GetRunningRuntime() != Utils.Runtime.Mono)
|
||||
handler.MaxConnectionsPerServer = Settings.MAX_HTTP_CONNECTIONS;
|
||||
|
||||
HttpCapsClient client = new HttpCapsClient(handler);
|
||||
client.DefaultRequestHeaders.Accept.Clear();
|
||||
client.DefaultRequestHeaders.Add("User-Agent", $"{Settings.USER_AGENT}");
|
||||
|
|
|
|||
|
|
@ -158,14 +158,15 @@ namespace OpenMetaverse
|
|||
public uint GlobalY;
|
||||
|
||||
/// <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>
|
||||
public uint LocalY { get { return GlobalY % 256; } }
|
||||
public uint LocalY { get { return GlobalY % Simulator.DefaultRegionSizeY; } }
|
||||
|
||||
/// <summary>Get the Handle of the region</summary>
|
||||
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();
|
||||
Uri cap = null;
|
||||
|
||||
if (Client.Network.CurrentSim != null
|
||||
&& Client.Network.CurrentSim.Caps != null
|
||||
&& (cap = Client.Network.CurrentSim.Caps.CapabilityURI("GroupMemberData")) != null)
|
||||
if ((cap = Client.Network.CurrentSim?.Caps?.CapabilityURI("GroupMemberData")) != null)
|
||||
{
|
||||
OSDMap payload = new OSDMap(1) { ["group_id"] = @group };
|
||||
Task req = Client.HttpCapsClient.PostRequestAsync(cap, OSDFormat.Xml, payload, CancellationToken.None,
|
||||
|
|
@ -1630,11 +1628,9 @@ namespace OpenMetaverse
|
|||
{
|
||||
Uri ret = null;
|
||||
|
||||
if (Client.Network.Connected
|
||||
&& Client.Network.CurrentSim != null
|
||||
&& Client.Network.CurrentSim.Caps != null)
|
||||
if (Client.Network.Connected)
|
||||
{
|
||||
ret = Client.Network.CurrentSim.Caps.CapabilityURI("GroupAPIv1");
|
||||
ret = Client.Network.CurrentSim?.Caps?.CapabilityURI("GroupAPIv1");
|
||||
if (ret != null)
|
||||
{
|
||||
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
|
||||
/// handle is returned along with the local X/Y location in that region
|
||||
/// </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
|
||||
/// 255360.35</param>
|
||||
/// <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>
|
||||
public static ulong GlobalPosToRegionHandle(float globalX, float globalY, out float localX, out float localY)
|
||||
{
|
||||
uint x = ((uint)globalX / 256) * 256;
|
||||
uint y = ((uint)globalY / 256) * 256;
|
||||
uint x = ((uint)globalX / Simulator.DefaultRegionSizeX) * Simulator.DefaultRegionSizeX;
|
||||
uint y = ((uint)globalY / Simulator.DefaultRegionSizeY) * Simulator.DefaultRegionSizeY;
|
||||
localX = globalX - (float)x;
|
||||
localY = globalY - (float)y;
|
||||
return Utils.UIntsToLong(x, y);
|
||||
|
|
|
|||
|
|
@ -196,7 +196,8 @@ namespace OpenMetaverse.ImportExport
|
|||
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;
|
||||
}
|
||||
|
||||
public bool IsAvailable => (Client.Network.CurrentSim.Caps != null &&
|
||||
Client.Network.CurrentSim.Caps.CapabilityURI(INVENTORY_CAP_NAME) != null);
|
||||
public bool IsAvailable => (Client.Network.CurrentSim.Caps?.CapabilityURI(INVENTORY_CAP_NAME) != null);
|
||||
|
||||
public async Task CreateInventory(UUID parentUuid, OSD newInventory, bool createLink, InventoryManager.ItemCreatedCallback callback)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -582,8 +582,7 @@ namespace OpenMetaverse
|
|||
}
|
||||
|
||||
Uri cap;
|
||||
if (Client.Network.CurrentSim.Caps != null &&
|
||||
(cap = Client.Network.CurrentSim.Caps.CapabilityURI("FetchInventory2")) != null)
|
||||
if ((cap = Client.Network.CurrentSim?.Caps?.CapabilityURI("FetchInventory2")) != null)
|
||||
{
|
||||
OSDMap payload = new OSDMap { ["agent_id"] = Client.Self.AgentID };
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<NoWarn>0419,1574,1591</NoWarn>
|
||||
<TargetFrameworks>net48;netstandard2.1;net6.0;net7.0</TargetFrameworks>
|
||||
<TargetFrameworks>net7.0</TargetFrameworks>
|
||||
<Platforms>x64;x86;AnyCPU</Platforms>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
|
@ -44,8 +44,8 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="log4net" Version="2.0.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.0" />
|
||||
<PackageReference Include="OggVorbisEncoder" Version="1.2.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.9" />
|
||||
<PackageReference Include="OggVorbisEncoder" Version="1.2.2" />
|
||||
<PackageReference Include="OpenJpegDotNet-LMV" Version="2.4.0.5" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
|
|
|
|||
|
|
@ -369,6 +369,8 @@ namespace OpenMetaverse
|
|||
public int CircuitCode;
|
||||
public uint RegionX;
|
||||
public uint RegionY;
|
||||
public uint RegionSizeX;
|
||||
public uint RegionSizeY;
|
||||
public ushort SimPort;
|
||||
public IPAddress SimIP;
|
||||
public string SeedCapability;
|
||||
|
|
@ -488,6 +490,9 @@ namespace OpenMetaverse
|
|||
CircuitCode = (int)ParseUInt("circuit_code", reply);
|
||||
RegionX = ParseUInt("region_x", 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);
|
||||
var simIP = ParseString("sim_ip", reply);
|
||||
IPAddress.TryParse(simIP, out SimIP);
|
||||
|
|
@ -693,6 +698,9 @@ namespace OpenMetaverse
|
|||
CircuitCode = (int)ParseUInt("circuit_code", reply);
|
||||
RegionX = ParseUInt("region_x", 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);
|
||||
var simIP = ParseString("sim_ip", reply);
|
||||
IPAddress.TryParse(simIP, out SimIP);
|
||||
|
|
@ -1691,7 +1699,7 @@ namespace OpenMetaverse
|
|||
var handle = Utils.UIntsToLong(regionX, regionY);
|
||||
|
||||
// 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
|
||||
SendPacket(new EconomyDataRequestPacket());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) 2006-2016, openmetaverse.co
|
||||
* Copyright (c) 2021-2022, Sjofn LLC
|
||||
* 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>
|
||||
public TeleportFlags Flags;
|
||||
|
||||
/// <summary> The size of the region teleporting into </summary>
|
||||
public uint RegionSizeX;
|
||||
public uint RegionSizeY;
|
||||
|
||||
/// <summary>
|
||||
/// Serialize the object
|
||||
/// </summary>
|
||||
|
|
@ -71,7 +75,7 @@ namespace OpenMetaverse.Messages.Linden
|
|||
|
||||
OSDArray infoArray = new OSDArray(1);
|
||||
|
||||
OSDMap info = new OSDMap(8)
|
||||
OSDMap info = new OSDMap(10)
|
||||
{
|
||||
{"AgentID", OSD.FromUUID(AgentID)},
|
||||
{"LocationID", OSD.FromInteger(LocationID)},
|
||||
|
|
@ -80,7 +84,9 @@ namespace OpenMetaverse.Messages.Linden
|
|||
{"SimAccess", OSD.FromInteger((byte) SimAccess)},
|
||||
{"SimIP", MessageUtils.FromIP(IP)},
|
||||
{"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
|
||||
|
||||
|
|
@ -108,6 +114,8 @@ namespace OpenMetaverse.Messages.Linden
|
|||
IP = MessageUtils.ToIP(blockMap["SimIP"]);
|
||||
Port = blockMap["SimPort"].AsInteger();
|
||||
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 IPAddress IP;
|
||||
public int Port;
|
||||
public uint RegionSizeX;
|
||||
public uint RegionSizeY;
|
||||
|
||||
/// <summary>
|
||||
/// Serialize the object
|
||||
|
|
@ -190,12 +200,14 @@ namespace OpenMetaverse.Messages.Linden
|
|||
map["AgentData"] = agentDataArray;
|
||||
|
||||
OSDArray regionDataArray = new OSDArray(1);
|
||||
OSDMap regionDataMap = new OSDMap(4)
|
||||
OSDMap regionDataMap = new OSDMap(6)
|
||||
{
|
||||
["RegionHandle"] = OSD.FromULong(RegionHandle),
|
||||
["SeedCapability"] = OSD.FromUri(SeedCapability),
|
||||
["SimIP"] = MessageUtils.FromIP(IP),
|
||||
["SimPort"] = OSD.FromInteger(Port)
|
||||
["SimPort"] = OSD.FromInteger(Port),
|
||||
["RegionSizeX"] = OSD.FromUInteger(RegionSizeX),
|
||||
["RegionSizeY"] = OSD.FromUInteger(RegionSizeY)
|
||||
};
|
||||
regionDataArray.Add(regionDataMap);
|
||||
map["RegionData"] = regionDataArray;
|
||||
|
|
@ -222,6 +234,8 @@ namespace OpenMetaverse.Messages.Linden
|
|||
SeedCapability = regionDataMap["SeedCapability"].AsUri();
|
||||
IP = MessageUtils.ToIP(regionDataMap["SimIP"]);
|
||||
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 IPAddress IP;
|
||||
public int Port;
|
||||
public uint RegionSizeX;
|
||||
public uint RegionSizeY;
|
||||
}
|
||||
|
||||
public SimulatorInfoBlock[] Simulators;
|
||||
|
|
@ -247,11 +263,13 @@ namespace OpenMetaverse.Messages.Linden
|
|||
OSDArray array = new OSDArray(Simulators.Length);
|
||||
foreach (SimulatorInfoBlock block in Simulators)
|
||||
{
|
||||
OSDMap blockMap = new OSDMap(3)
|
||||
OSDMap blockMap = new OSDMap(5)
|
||||
{
|
||||
["Handle"] = OSD.FromULong(block.RegionHandle),
|
||||
["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);
|
||||
}
|
||||
|
|
@ -277,7 +295,9 @@ namespace OpenMetaverse.Messages.Linden
|
|||
{
|
||||
RegionHandle = blockMap["Handle"].AsULong(),
|
||||
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;
|
||||
}
|
||||
|
|
@ -5395,7 +5415,7 @@ namespace OpenMetaverse.Messages.Linden
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Message recieved in response to request to change display name
|
||||
/// Message received in response to request to change display name
|
||||
/// </summary>
|
||||
public class SetDisplayNameReplyMessage : IMessage
|
||||
{
|
||||
|
|
@ -5434,7 +5454,7 @@ namespace OpenMetaverse.Messages.Linden
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Message recieved when someone nearby changes their display name
|
||||
/// Message received when someone nearby changes their display name
|
||||
/// </summary>
|
||||
public class DisplayNameUpdateMessage : IMessage
|
||||
{
|
||||
|
|
|
|||
|
|
@ -504,7 +504,7 @@ namespace OpenMetaverse
|
|||
if (dif > 10)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
/// Connect to a simulator
|
||||
/// </summary>
|
||||
|
|
@ -537,13 +550,26 @@ namespace OpenMetaverse
|
|||
/// connection, use this if the avatar is moving in to this simulator</param>
|
||||
/// <param name="seedcaps">URL of the capabilities server to use for
|
||||
/// 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>
|
||||
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);
|
||||
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>
|
||||
/// Connect to a simulator
|
||||
/// </summary>
|
||||
|
|
@ -554,15 +580,17 @@ namespace OpenMetaverse
|
|||
/// connection, use this if the avatar is moving in to this simulator</param>
|
||||
/// <param name="seedcaps">URL of the capabilities server to use for
|
||||
/// 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>
|
||||
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);
|
||||
|
||||
if (simulator == null)
|
||||
{
|
||||
// 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
|
||||
// connection fails
|
||||
|
|
@ -682,13 +710,13 @@ namespace OpenMetaverse
|
|||
// Otherwise we fire it manually with a NetworkTimeout type after LOGOUT_TIMEOUT
|
||||
System.Timers.Timer timeout = new System.Timers.Timer();
|
||||
|
||||
EventHandler<LoggedOutEventArgs> callback = delegate
|
||||
void Callback(object sender, LoggedOutEventArgs e)
|
||||
{
|
||||
Shutdown(DisconnectType.ClientInitiated);
|
||||
timeout.Stop();
|
||||
};
|
||||
}
|
||||
|
||||
LoggedOut += callback;
|
||||
LoggedOut += Callback;
|
||||
|
||||
timeout.Interval = Client.Settings.LOGOUT_TIMEOUT;
|
||||
timeout.Elapsed += delegate
|
||||
|
|
@ -702,7 +730,7 @@ namespace OpenMetaverse
|
|||
// Send the packet requesting a clean logout
|
||||
RequestLogout();
|
||||
|
||||
LoggedOut -= callback;
|
||||
LoggedOut -= Callback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -713,9 +741,13 @@ namespace OpenMetaverse
|
|||
public void Logout()
|
||||
{
|
||||
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
|
||||
RequestLogout();
|
||||
|
|
@ -724,9 +756,11 @@ namespace OpenMetaverse
|
|||
// will be fired in the callback. Otherwise we fire it manually with
|
||||
// a NetworkTimeout type
|
||||
if (!logoutEvent.WaitOne(Client.Settings.LOGOUT_TIMEOUT, false))
|
||||
{
|
||||
Shutdown(DisconnectType.NetworkTimeout);
|
||||
}
|
||||
|
||||
LoggedOut -= callback;
|
||||
LoggedOut -= Callback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -787,7 +821,10 @@ namespace OpenMetaverse
|
|||
simulatorsCount = Simulators.Count;
|
||||
}
|
||||
|
||||
if (simulatorsCount == 0) Shutdown(DisconnectType.SimShutdown);
|
||||
if (simulatorsCount == 0)
|
||||
{
|
||||
Shutdown(DisconnectType.SimShutdown, $"You have disconnected from {simulator.Name}.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -797,10 +834,13 @@ namespace OpenMetaverse
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// Shutdown will disconnect all the sims except for the current sim
|
||||
/// first, and then kill the connection to CurrentSim. This should only
|
||||
/// be called if the logout process times out on <code>RequestLogout</code>
|
||||
/// This method disconnects Client from all simulators leaving CurrentSim
|
||||
/// last to disconnect.
|
||||
/// </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>
|
||||
public void Shutdown(DisconnectType type)
|
||||
{
|
||||
|
|
@ -808,10 +848,13 @@ namespace OpenMetaverse
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shutdown will disconnect all the sims except for the current sim
|
||||
/// first, and then kill the connection to CurrentSim. This should only
|
||||
/// be called if the logout process times out on <code>RequestLogout</code>
|
||||
/// This method disconnects Client from all simulators leaving CurrentSim
|
||||
/// last to disconnect.
|
||||
/// </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="message">Shutdown message</param>
|
||||
public void Shutdown(DisconnectType type, string message)
|
||||
|
|
@ -824,17 +867,14 @@ namespace OpenMetaverse
|
|||
lock (Simulators)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
t.Disconnect(sendCloseCircuit);
|
||||
sim.Disconnect(sendCloseCircuit);
|
||||
|
||||
// Fire the SimDisconnected event if a handler is registered
|
||||
if (m_SimDisconnected != null)
|
||||
{
|
||||
OnSimDisconnected(new SimDisconnectedEventArgs(t, type));
|
||||
}
|
||||
// Fire the SimDisconnected event if a handler is registered
|
||||
if (m_SimDisconnected != null)
|
||||
{
|
||||
OnSimDisconnected(new SimDisconnectedEventArgs(sim, type));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -843,7 +883,7 @@ namespace OpenMetaverse
|
|||
|
||||
if (CurrentSim != null)
|
||||
{
|
||||
// Kill the connection to the curent simulator
|
||||
// Kill the connection to the current simulator
|
||||
CurrentSim.Disconnect(sendCloseCircuit);
|
||||
|
||||
// Fire the SimDisconnected event if a handler is registered
|
||||
|
|
@ -881,10 +921,9 @@ namespace OpenMetaverse
|
|||
{
|
||||
lock (Simulators)
|
||||
{
|
||||
foreach (Simulator t in Simulators)
|
||||
foreach (var sim in Simulators.Where(t => t.IPEndPoint.Equals(endPoint)))
|
||||
{
|
||||
if (t.IPEndPoint.Equals(endPoint))
|
||||
return t;
|
||||
return sim;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1277,10 +1316,10 @@ namespace OpenMetaverse
|
|||
|
||||
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}",
|
||||
Helpers.LogLevel.Error, Client);
|
||||
Helpers.LogLevel.Error, Client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,8 +198,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnObjectProperties(ObjectPropertiesEventArgs e)
|
||||
{
|
||||
EventHandler<ObjectPropertiesEventArgs> handler = m_ObjectProperties;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -224,8 +223,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnObjectPropertiesUpdated(ObjectPropertiesUpdatedEventArgs e)
|
||||
{
|
||||
EventHandler<ObjectPropertiesUpdatedEventArgs> handler = m_ObjectPropertiesUpdated;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -250,8 +248,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnObjectPropertiesFamily(ObjectPropertiesFamilyEventArgs e)
|
||||
{
|
||||
EventHandler<ObjectPropertiesFamilyEventArgs> handler = m_ObjectPropertiesFamily;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -278,8 +275,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnAvatarUpdate(AvatarUpdateEventArgs e)
|
||||
{
|
||||
EventHandler<AvatarUpdateEventArgs> handler = m_AvatarUpdate;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
/// <summary>
|
||||
/// Raises the ParticleUpdate Event
|
||||
|
|
@ -288,8 +284,7 @@ namespace OpenMetaverse
|
|||
/// the data sent from the simulator</param>
|
||||
protected virtual void OnParticleUpdate(ParticleUpdateEventArgs e) {
|
||||
EventHandler<ParticleUpdateEventArgs> handler = m_ParticleUpdate;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -337,8 +332,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnObjectDataBlockUpdate(ObjectDataBlockUpdateEventArgs e)
|
||||
{
|
||||
EventHandler<ObjectDataBlockUpdateEventArgs> handler = m_ObjectDataBlockUpdate;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -363,8 +357,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnKillObject(KillObjectEventArgs e)
|
||||
{
|
||||
EventHandler<KillObjectEventArgs> handler = m_KillObject;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -389,8 +382,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnKillObjects(KillObjectsEventArgs e)
|
||||
{
|
||||
EventHandler<KillObjectsEventArgs> handler = m_KillObjects;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -415,8 +407,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnAvatarSitChanged(AvatarSitChangedEventArgs e)
|
||||
{
|
||||
EventHandler<AvatarSitChangedEventArgs> handler = m_AvatarSitChanged;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -441,8 +432,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnPayPriceReply(PayPriceReplyEventArgs e)
|
||||
{
|
||||
EventHandler<PayPriceReplyEventArgs> handler = m_PayPriceReply;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -475,8 +465,7 @@ namespace OpenMetaverse
|
|||
protected virtual void OnPhysicsProperties(PhysicsPropertiesEventArgs e)
|
||||
{
|
||||
EventHandler<PhysicsPropertiesEventArgs> handler = m_PhysicsProperties;
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>Thread sync lock object</summary>
|
||||
|
|
@ -2611,8 +2600,7 @@ namespace OpenMetaverse
|
|||
#region Raise Events
|
||||
|
||||
EventHandler<PrimEventArgs> handler = m_ObjectUpdate;
|
||||
if (handler != null)
|
||||
handler(this, new PrimEventArgs(simulator, prim, update.RegionData.TimeDilation, isNew, prim.IsAttachment));
|
||||
handler?.Invoke(this, new PrimEventArgs(simulator, prim, update.RegionData.TimeDilation, isNew, prim.IsAttachment));
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
@ -3310,10 +3298,7 @@ namespace OpenMetaverse
|
|||
|
||||
// Start the timer again. Use a minimum of a 50ms pause in between calculations
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the parcel (in the current sim)
|
||||
/// </summary>
|
||||
/// <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 = false)
|
||||
public void Update(GridClient client)
|
||||
{
|
||||
Update(client, client.Network.CurrentSim, false);
|
||||
}
|
||||
|
||||
public void Update(GridClient client, bool wantReply)
|
||||
{
|
||||
Update(client, client.Network.CurrentSim, wantReply);
|
||||
}
|
||||
|
|
@ -1688,7 +1687,17 @@ namespace OpenMetaverse
|
|||
{
|
||||
OSD res = null;
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -768,16 +768,11 @@ namespace OpenMetaverse
|
|||
|
||||
private void FromBytes(byte[] data, int pos, int length)
|
||||
{
|
||||
DefaultTexture = new TextureEntryFace(null);
|
||||
|
||||
if (length < 16)
|
||||
{
|
||||
// No TextureEntry to process
|
||||
DefaultTexture = null;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultTexture = new TextureEntryFace(null);
|
||||
}
|
||||
|
||||
uint bitfieldSize = 0;
|
||||
uint faceBits = 0;
|
||||
|
|
|
|||
|
|
@ -217,10 +217,6 @@ namespace OpenMetaverse
|
|||
/// server the full object info will automatically be requested</summary>
|
||||
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>
|
||||
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
|
||||
/// a logger configuration file for log4net
|
||||
/// </summary>
|
||||
#if DEBUG
|
||||
public static Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.Debug;
|
||||
#else
|
||||
public static Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.None;
|
||||
#endif
|
||||
|
||||
/// <summary>Attach avatar names to log messages</summary>
|
||||
public bool LOG_NAMES = true;
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ namespace OpenMetaverse
|
|||
public int ConnectTime;
|
||||
/// <summary>Total number of packets that have been resent</summary>
|
||||
public int ResentPackets;
|
||||
/// <summary>Total number of resent packets recieved</summary>
|
||||
/// <summary>Total number of resent packets received</summary>
|
||||
public int ReceivedResends;
|
||||
/// <summary>Total number of pings sent to this simulator by this agent</summary>
|
||||
public int SentPings;
|
||||
|
|
@ -180,7 +180,7 @@ namespace OpenMetaverse
|
|||
/// <summary>
|
||||
/// Incoming bytes per second
|
||||
/// </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>
|
||||
public int IncomingBPS;
|
||||
/// <summary>
|
||||
|
|
@ -252,6 +252,11 @@ namespace OpenMetaverse
|
|||
#endregion Structs
|
||||
|
||||
#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>
|
||||
public GridClient Client;
|
||||
/// <summary>A Unique Cache identifier for this simulator</summary>
|
||||
|
|
@ -260,6 +265,10 @@ namespace OpenMetaverse
|
|||
public Caps Caps;
|
||||
/// <summary>Unique identified for this region generated via it's coordinates on the world map</summary>
|
||||
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>
|
||||
public string SimVersion = String.Empty;
|
||||
/// <summary>Human readable name given to the simulator</summary>
|
||||
|
|
@ -497,10 +506,7 @@ namespace OpenMetaverse
|
|||
public readonly SimulatorDataPool DataPool;
|
||||
internal bool DownloadingParcelMap
|
||||
{
|
||||
get
|
||||
{
|
||||
return Client.Settings.POOL_PARCEL_DATA ? DataPool.DownloadingParcelMap : _DownloadingParcelMap;
|
||||
}
|
||||
get => Client.Settings.POOL_PARCEL_DATA ? DataPool.DownloadingParcelMap : _DownloadingParcelMap;
|
||||
set
|
||||
{
|
||||
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="address">IPEndPoint of 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)
|
||||
{
|
||||
Client = client;
|
||||
|
|
@ -532,14 +538,16 @@ namespace OpenMetaverse
|
|||
|
||||
Handle = handle;
|
||||
Network = Client.Network;
|
||||
SizeX = sizeX;
|
||||
SizeY = sizeY;
|
||||
PacketArchive = new IncomingPacketIDCollection(Settings.PACKET_ARCHIVE_SIZE);
|
||||
InBytes = new Queue<long>(Client.Settings.STATS_QUEUE_SIZE);
|
||||
OutBytes = new Queue<long>(Client.Settings.STATS_QUEUE_SIZE);
|
||||
|
||||
if (client.Settings.STORE_LAND_PATCHES)
|
||||
{
|
||||
Terrain = new TerrainPatch[16 * 16];
|
||||
WindSpeeds = new Vector2[16 * 16];
|
||||
Terrain = new TerrainPatch[sizeX/16 * sizeY/16];
|
||||
WindSpeeds = new Vector2[sizeX/16 * sizeY/16];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -648,7 +656,7 @@ namespace OpenMetaverse
|
|||
/// <summary>
|
||||
/// Initiates connection to the simulator
|
||||
/// </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)
|
||||
{
|
||||
// Send the UseCircuitCode packet to initiate the connection
|
||||
|
|
@ -690,17 +698,14 @@ namespace OpenMetaverse
|
|||
Caps = null;
|
||||
}
|
||||
|
||||
if (Client.Settings.ENABLE_CAPS)
|
||||
// Connect to the CAPS system
|
||||
if (seedcaps != null)
|
||||
{
|
||||
// Connect to the new CAPS system
|
||||
if (seedcaps != null)
|
||||
{
|
||||
Caps = new Caps(this, seedcaps);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log("Setting up a sim without a valid capabilities server!", Helpers.LogLevel.Error, Client);
|
||||
}
|
||||
Caps = new Caps(this, seedcaps);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log("Setting up a sim without valid http capabilities", Helpers.LogLevel.Error, Client);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -709,6 +714,8 @@ namespace OpenMetaverse
|
|||
/// </summary>
|
||||
public void Disconnect(bool sendCloseCircuit)
|
||||
{
|
||||
DisconnectCandidate = false;
|
||||
|
||||
if (!connected) return;
|
||||
|
||||
connected = false;
|
||||
|
|
@ -795,7 +802,7 @@ namespace OpenMetaverse
|
|||
/// <returns>True if the lookup was successful, otherwise false</returns>
|
||||
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 patchY = y / 16;
|
||||
|
|
@ -1002,7 +1009,7 @@ namespace OpenMetaverse
|
|||
/// <summary>
|
||||
/// Returns Simulator Name as a String
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <returns>Simulator name as String</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return !String.IsNullOrEmpty(Name)
|
||||
|
|
@ -1059,8 +1066,8 @@ namespace OpenMetaverse
|
|||
// Check if this packet came from the server we expected it to come from
|
||||
if (!remoteEndPoint.Address.Equals(((IPEndPoint)buffer.RemoteEndPoint).Address))
|
||||
{
|
||||
Logger.Log("Received " + buffer.DataLength + " bytes of data from unrecognized source " +
|
||||
((IPEndPoint)buffer.RemoteEndPoint), Helpers.LogLevel.Warning, Client);
|
||||
Logger.Log($"Received {buffer.DataLength} bytes of data from unrecognized source {(IPEndPoint)buffer.RemoteEndPoint}",
|
||||
Helpers.LogLevel.Warning, Client);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1201,7 +1208,7 @@ namespace OpenMetaverse
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// Sends out pending acknowledgements
|
||||
/// Sends out pending acknowledgments
|
||||
/// </summary>
|
||||
/// <returns>Number of ACKs sent</returns>
|
||||
private int SendAcks()
|
||||
|
|
|
|||
|
|
@ -61,16 +61,27 @@ namespace OpenMetaverse
|
|||
public int PatchIDs;
|
||||
public uint WordBits;
|
||||
|
||||
// true if PatchIDs are 32 bits and not 10
|
||||
public bool LargeRegion { get; set; }
|
||||
|
||||
public int X
|
||||
{
|
||||
get { return PatchIDs >> 5; }
|
||||
set { PatchIDs += (value << 5); }
|
||||
get { return PatchIDs >> (LargeRegion ? 16 : 5); }
|
||||
set { PatchIDs += (value << (LargeRegion ? 16 : 5)); }
|
||||
}
|
||||
|
||||
public int Y
|
||||
{
|
||||
get { return PatchIDs & 0x1F; }
|
||||
set { PatchIDs |= value & 0x1F; }
|
||||
get { return PatchIDs & (LargeRegion ? 0xffff : 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
|
||||
/// </summary>
|
||||
/// <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
|
||||
/// for this simulator. For example if 1 and 17 are specified, patches
|
||||
/// x=1,y=0 and x=1,y=1 are sent</param>
|
||||
/// <returns></returns>
|
||||
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
|
||||
{
|
||||
|
|
@ -235,15 +250,19 @@ namespace OpenMetaverse
|
|||
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)
|
||||
throw new ArgumentException("Patch data must be a 16x16 array");
|
||||
|
||||
TerrainPatch.Header header = PrescanPatch(patchData);
|
||||
header.LargeRegion = largeRegion;
|
||||
header.QuantWBits = 136;
|
||||
header.PatchIDs = (y & 0x1F);
|
||||
header.PatchIDs += (x << 5);
|
||||
header.setPatchIDs(x, y);
|
||||
|
||||
// NOTE: No idea what prequant and postquant should be or what they do
|
||||
int[] patch = CompressPatch(patchData, header, 10);
|
||||
|
|
@ -252,14 +271,18 @@ namespace OpenMetaverse
|
|||
}
|
||||
|
||||
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)
|
||||
throw new ArgumentException("Patch data must be a 16x16 array");
|
||||
|
||||
var header = PrescanPatch(patchData);
|
||||
header.LargeRegion = largeRegion;
|
||||
header.QuantWBits = 136;
|
||||
header.PatchIDs = (y & 0x1F);
|
||||
header.PatchIDs += (x << 5);
|
||||
header.setPatchIDs(x, y);
|
||||
|
||||
// NOTE: No idea what prequant and postquant should be or what they do
|
||||
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
|
||||
/// from 0 to 15</param>
|
||||
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)
|
||||
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");
|
||||
|
||||
var header = PrescanPatch(heightmap, x, y);
|
||||
header.LargeRegion = largeRegion;
|
||||
header.QuantWBits = 136;
|
||||
header.PatchIDs = (y & 0x1F);
|
||||
header.PatchIDs += (x << 5);
|
||||
header.setPatchIDs(x, y);
|
||||
|
||||
// NOTE: No idea what prequant and postquant should be or what they do
|
||||
int[] patch = CompressPatch(heightmap, x, y, header, 10);
|
||||
|
|
@ -296,6 +323,8 @@ namespace OpenMetaverse
|
|||
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)
|
||||
{
|
||||
TerrainPatch.Header header = new TerrainPatch.Header();
|
||||
|
|
@ -318,6 +347,8 @@ namespace OpenMetaverse
|
|||
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)
|
||||
{
|
||||
TerrainPatch.Header header = new TerrainPatch.Header();
|
||||
|
|
@ -340,6 +371,8 @@ namespace OpenMetaverse
|
|||
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)
|
||||
{
|
||||
TerrainPatch.Header header = new TerrainPatch.Header();
|
||||
|
|
@ -363,6 +396,11 @@ namespace OpenMetaverse
|
|||
}
|
||||
|
||||
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)};
|
||||
|
||||
|
|
@ -377,7 +415,9 @@ namespace OpenMetaverse
|
|||
header.Range = bitpack.UnpackBits(16);
|
||||
|
||||
// Patch IDs (10 bits)
|
||||
header.PatchIDs = bitpack.UnpackBits(10);
|
||||
|
||||
header.LargeRegion = largeRegion;
|
||||
header.PatchIDs = bitpack.UnpackBits(largeRegion ? 32 : 10);
|
||||
|
||||
// Word bits
|
||||
header.WordBits = (uint)((header.QuantWBits & 0x0f) + 2);
|
||||
|
|
@ -428,7 +468,7 @@ namespace OpenMetaverse
|
|||
output.PackBits(header.QuantWBits, 8);
|
||||
output.PackFloat(header.DCOffset);
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ namespace OpenMetaverse
|
|||
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 y;
|
||||
|
|
@ -76,7 +76,7 @@ namespace OpenMetaverse
|
|||
|
||||
while (true)
|
||||
{
|
||||
TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack);
|
||||
TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack, largeRegion);
|
||||
|
||||
if (header.QuantWBits == TerrainCompressor.END_OF_PATCHES)
|
||||
break;
|
||||
|
|
@ -84,7 +84,7 @@ namespace OpenMetaverse
|
|||
x = header.X;
|
||||
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(
|
||||
"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];
|
||||
|
||||
|
|
@ -131,12 +131,12 @@ namespace OpenMetaverse
|
|||
// wind_direction = vec2(x,y)
|
||||
|
||||
// X values
|
||||
TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack);
|
||||
TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack, largeRegion);
|
||||
TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
|
||||
float[] xvalues = TerrainCompressor.DecompressPatch(patches, header, group);
|
||||
|
||||
// Y values
|
||||
header = TerrainCompressor.DecodePatchHeader(bitpack);
|
||||
header = TerrainCompressor.DecodePatchHeader(bitpack, largeRegion);
|
||||
TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
|
||||
float[] yvalues = TerrainCompressor.DecompressPatch(patches, header, group);
|
||||
|
||||
|
|
@ -172,6 +172,10 @@ namespace OpenMetaverse
|
|||
if (m_LandPatchReceivedEvent != null || Client.Settings.STORE_LAND_PATCHES)
|
||||
DecompressLand(e.Simulator, bitpack, header);
|
||||
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:
|
||||
Logger.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Error, Client);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ namespace OpenMetaverse
|
|||
|
||||
// kick off an async receive. The Start() method will return, the
|
||||
// actual receives will occur asynchronously and will be caught in
|
||||
// AsyncEndRecieve().
|
||||
// AsyncEndReceive().
|
||||
AsyncBeginReceive();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10023,6 +10023,9 @@ namespace OpenMetaverse.Packets
|
|||
public byte[] SeedCapability;
|
||||
public byte SimAccess;
|
||||
public uint TeleportFlags;
|
||||
// Sim/region size information sent in TeleportFinishMesssage
|
||||
public uint RegionSizeX = Simulator.DefaultRegionSizeX;
|
||||
public uint RegionSizeY = Simulator.DefaultRegionSizeY;
|
||||
|
||||
public override int Length
|
||||
{
|
||||
|
|
@ -10075,6 +10078,7 @@ namespace OpenMetaverse.Packets
|
|||
Buffer.BlockCopy(SeedCapability, 0, bytes, i, SeedCapability.Length); i += SeedCapability.Length;
|
||||
bytes[i++] = SimAccess;
|
||||
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 });
|
||||
}
|
||||
ProcessAvatar(avatar);
|
||||
if(avataruuid == null)
|
||||
if(avataruuid == UUID.Zero)
|
||||
{
|
||||
return Failure("Unknown avatar", new[] { group, avatar, state });
|
||||
}
|
||||
|
|
@ -75,8 +75,10 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
Action = GroupBanAction.Unban;
|
||||
}
|
||||
List<UUID> avatarstoaction = new List<UUID>();
|
||||
avatarstoaction.Add(avataruuid);
|
||||
List<UUID> avatarstoaction = new()
|
||||
{
|
||||
avataruuid
|
||||
};
|
||||
GetClient().Groups.RequestBanAction(groupuuid, Action, avatarstoaction.ToArray());
|
||||
return BasicReply("Accepted");
|
||||
}
|
||||
|
|
@ -104,7 +106,7 @@ namespace SecondBotEvents.Commands
|
|||
return Failure("Unknown group", new[] { group, avatar });
|
||||
}
|
||||
ProcessAvatar(avatar);
|
||||
if (avataruuid == null)
|
||||
if (avataruuid == UUID.Zero)
|
||||
{
|
||||
return Failure("Unknown avatar", new[] { group, avatar});
|
||||
}
|
||||
|
|
@ -172,12 +174,13 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
return Failure("avatar lookup", new [] { group, avatar, role });
|
||||
}
|
||||
List<UUID> roles = new List<UUID>();
|
||||
roles.Add(UUID.Zero);
|
||||
if(role != "everyone")
|
||||
List<UUID> roles = new()
|
||||
{
|
||||
UUID roleuuid = UUID.Zero;
|
||||
if (UUID.TryParse(role, out roleuuid) == false)
|
||||
UUID.Zero
|
||||
};
|
||||
if (role != "everyone")
|
||||
{
|
||||
if (UUID.TryParse(role, out UUID roleuuid) == false)
|
||||
{
|
||||
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 });
|
||||
}
|
||||
GroupNotice NewNotice = new GroupNotice();
|
||||
NewNotice.Subject = title;
|
||||
NewNotice.Message = message;
|
||||
NewNotice.OwnerID = GetClient().Self.AgentID;
|
||||
GroupNotice NewNotice = new()
|
||||
{
|
||||
Subject = title,
|
||||
Message = message,
|
||||
OwnerID = GetClient().Self.AgentID
|
||||
};
|
||||
GetClient().Groups.SendGroupNotice(groupuuid, NewNotice);
|
||||
return BasicReply("Sending notice", new [] { group, title, message });
|
||||
}
|
||||
|
|
@ -301,11 +306,13 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
return Failure("Message empty", new [] { group, title, message, attachment });
|
||||
}
|
||||
GroupNotice NewNotice = new GroupNotice();
|
||||
NewNotice.Subject = title;
|
||||
NewNotice.Message = message;
|
||||
NewNotice.OwnerID = GetClient().Self.AgentID;
|
||||
NewNotice.AttachmentID = inventoryuuid;
|
||||
GroupNotice NewNotice = new()
|
||||
{
|
||||
Subject = title,
|
||||
Message = message,
|
||||
OwnerID = GetClient().Self.AgentID,
|
||||
AttachmentID = inventoryuuid
|
||||
};
|
||||
GetClient().Groups.SendGroupNotice(groupuuid, NewNotice);
|
||||
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")]
|
||||
public object GroupchatGroupHasUnread(string group)
|
||||
{
|
||||
UUID groupUUID = UUID.Zero;
|
||||
if(UUID.TryParse(group,out groupUUID) == false)
|
||||
if(UUID.TryParse(group,out UUID groupUUID) == false)
|
||||
{
|
||||
return Failure("group value is invaild", new [] { group });
|
||||
}
|
||||
|
|
@ -400,8 +406,7 @@ namespace SecondBotEvents.Commands
|
|||
[ReturnHintsFailure("Unknown group")]
|
||||
public object Groupchat(string group, string message)
|
||||
{
|
||||
UUID groupUUID = UUID.Zero;
|
||||
if (UUID.TryParse(group, out groupUUID) == false)
|
||||
if (UUID.TryParse(group, out UUID groupUUID) == false)
|
||||
{
|
||||
return Failure("group value is invaild", new [] { group, message });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,10 @@ namespace SecondBotEvents.Commands
|
|||
break;
|
||||
}
|
||||
}
|
||||
AssetSound S = new AssetSound();
|
||||
S.AssetData = audioData;
|
||||
AssetSound S = new()
|
||||
{
|
||||
AssetData = audioData
|
||||
};
|
||||
S.Encode();
|
||||
|
||||
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 });
|
||||
}
|
||||
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)
|
||||
{
|
||||
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");
|
||||
}
|
||||
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);
|
||||
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>());
|
||||
}
|
||||
|
|
@ -266,7 +268,7 @@ namespace SecondBotEvents.Commands
|
|||
[ReturnHints("Asset UUID or UUID zero")]
|
||||
[ReturnHints("Invaild item uuid")]
|
||||
[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)
|
||||
{
|
||||
|
|
@ -364,7 +366,7 @@ namespace SecondBotEvents.Commands
|
|||
return Failure("Unable to find inventory", new [] { item, objectuuid, running });
|
||||
}
|
||||
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)
|
||||
{
|
||||
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.")]
|
||||
[ArgHints("parentFolder", "UUID of folder to create a subfolder in")]
|
||||
[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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ namespace SecondBotEvents.Commands
|
|||
}
|
||||
targetparcel.SalePrice = amountvalue;
|
||||
targetparcel.AuthBuyerID = avataruuid;
|
||||
parcel_static.ParcelSetFlag(ParcelFlags.ForSale, targetparcel, true);
|
||||
parcel_static.ParcelSetFlag(ParcelFlags.ForSaleObjects, targetparcel, false);
|
||||
ParcelStatic.ParcelSetFlag(ParcelFlags.ForSale, targetparcel, true);
|
||||
ParcelStatic.ParcelSetFlag(ParcelFlags.ForSaleObjects, targetparcel, false);
|
||||
targetparcel.Update(GetClient());
|
||||
return Failure("ok", new [] { amount, avatar });
|
||||
}
|
||||
|
|
@ -167,8 +167,8 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
return Failure(tests.Value);
|
||||
}
|
||||
Dictionary<string, ParcelFlags> flags = parcel_static.get_flags_list();
|
||||
Dictionary<string, string> collection = new Dictionary<string, string>();
|
||||
Dictionary<string, ParcelFlags> flags = ParcelStatic.GetFlagsList();
|
||||
Dictionary<string, string> collection = new();
|
||||
foreach (ParcelFlags cfg in flags.Values)
|
||||
{
|
||||
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 });
|
||||
}
|
||||
ParcelAccessEntry entry = new ParcelAccessEntry();
|
||||
entry.AgentID = avataruuid;
|
||||
entry.Flags = AccessList.Ban;
|
||||
entry.Time = new System.DateTime(3030, 03, 03);
|
||||
ParcelAccessEntry entry = new()
|
||||
{
|
||||
AgentID = avataruuid,
|
||||
Flags = AccessList.Ban,
|
||||
Time = new System.DateTime(3030, 03, 03)
|
||||
};
|
||||
targetparcel.AccessBlackList.Add(entry);
|
||||
targetparcel.Update(GetClient());
|
||||
return BasicReply("ok", new [] { avatar });
|
||||
|
|
@ -266,7 +268,7 @@ namespace SecondBotEvents.Commands
|
|||
return Failure("Invaild avatar", new [] { avatar });
|
||||
}
|
||||
bool alreadyBanned = false;
|
||||
ParcelAccessEntry removeentry = new ParcelAccessEntry();
|
||||
ParcelAccessEntry removeentry = new();
|
||||
foreach (ParcelAccessEntry E in targetparcel.AccessBlackList)
|
||||
{
|
||||
if (E.AgentID == avataruuid)
|
||||
|
|
@ -298,7 +300,7 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
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 });
|
||||
}
|
||||
|
||||
|
|
@ -319,11 +321,11 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
return Failure(tests.Value, new [] { escapedflagdata });
|
||||
}
|
||||
List<string> acceptablewords = new List<string>();
|
||||
Dictionary<string, ParcelFlags> flags = parcel_static.get_flags_list();
|
||||
List<string> acceptablewords = new();
|
||||
Dictionary<string, ParcelFlags> flags = ParcelStatic.GetFlagsList();
|
||||
acceptablewords.AddRange(new[] { "True", "False" });
|
||||
|
||||
Dictionary<string, bool> setflags = new Dictionary<string, bool>();
|
||||
Dictionary<string, bool> setflags = new();
|
||||
string[] args = escapedflagdata.Split(":::");
|
||||
foreach (string a in args)
|
||||
{
|
||||
|
|
@ -348,7 +350,7 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
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 });
|
||||
}
|
||||
|
|
@ -356,7 +358,7 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
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());
|
||||
|
|
@ -494,7 +496,7 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
return Failure(tests.Value);
|
||||
}
|
||||
GetParcelBanlistObject reply = new GetParcelBanlistObject();
|
||||
GetParcelBanlistObject reply = new();
|
||||
int delays = 0;
|
||||
bool haslookup = true;
|
||||
while ((haslookup == true) && (delays < 3))
|
||||
|
|
@ -582,7 +584,7 @@ namespace SecondBotEvents.Commands
|
|||
{
|
||||
if (bits[0] == "MediaType")
|
||||
{
|
||||
UpdateParcel_MediaType(targetparcel, bits[1]);
|
||||
UpdateParcelMediaType(targetparcel, bits[1]);
|
||||
}
|
||||
else if ((bits[0] == "MediaWidth") || (bits[0] == "MediaHeight"))
|
||||
{
|
||||
|
|
@ -636,7 +638,7 @@ namespace SecondBotEvents.Commands
|
|||
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")
|
||||
{
|
||||
|
|
@ -670,7 +672,7 @@ namespace SecondBotEvents.Commands
|
|||
|
||||
public class GetParcelBanlistObject
|
||||
{
|
||||
public Dictionary<UUID, string> entrys = new Dictionary<UUID, string>();
|
||||
public Dictionary<UUID, string> entrys = new();
|
||||
public string parcelName = "";
|
||||
public string regionName = "";
|
||||
public int delay = 0;
|
||||
|
|
|
|||
|
|
@ -1,28 +1,25 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk;Microsoft.NET.Sdk.Publish">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<StartupObject>SecondBotEvents.Startup</StartupObject>
|
||||
<MSBuildGitHashCommand>git rev-parse --short HEAD</MSBuildGitHashCommand>
|
||||
<MSBuildGitHashValidate>False</MSBuildGitHashValidate>
|
||||
<MSBuildGitHashSuppressDirtyWarning>False</MSBuildGitHashSuppressDirtyWarning>
|
||||
<MSBuildGitHashCommand>git rev-parse --short HEAD</MSBuildGitHashCommand>
|
||||
<MSBuildGitHashValidate>False</MSBuildGitHashValidate>
|
||||
<MSBuildGitHashSuppressDirtyWarning>False</MSBuildGitHashSuppressDirtyWarning>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net" Version="3.4.1" />
|
||||
<PackageReference Include="Discord.Net.WebSocket" Version="3.7.2" />
|
||||
<PackageReference Include="EmbedIO" Version="3.4.3" />
|
||||
<PackageReference Include="Discord.Net" Version="3.11.0" />
|
||||
<PackageReference Include="Discord.Net.WebSocket" Version="3.11.0" />
|
||||
<PackageReference Include="EmbedIO" Version="3.5.2" />
|
||||
<PackageReference Include="Microsoft.NET.Build.Containers" Version="7.0.306" />
|
||||
<PackageReference Include="MSBuildGitHash" Version="2.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="RestSharp" Version="107.3.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="RestSharp" Version="110.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LibreMetaverse\LibreMetaverse.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using OpenMetaverse;
|
||||
using OpenMetaverse.Assets;
|
||||
using SecondBotEvents.Config;
|
||||
using Swan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
|
@ -200,7 +201,9 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
protected Dictionary<string, UUID> avatarsName2Key = new Dictionary<string, UUID>();
|
||||
protected Dictionary<UUID, long> avatarLastUsed = new Dictionary<UUID, long>();
|
||||
protected Dictionary<string, UUID> avatarsName2Key = new();
|
||||
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, Dictionary<UUID, GroupRole>> groupRoles = new Dictionary<UUID, Dictionary<UUID, GroupRole>>();
|
||||
protected Dictionary<UUID, List<UUID>> groupMembers = new();
|
||||
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, bool> chatWindowsUnread = new Dictionary<UUID, bool>(); // sess, bool
|
||||
protected Dictionary<UUID, bool> chatWindowsIsGroup = new Dictionary<UUID, bool>(); // sess, bool
|
||||
protected Dictionary<UUID, UUID> chatWindowsOwner = new Dictionary<UUID, UUID>(); // sess, owner id
|
||||
protected Dictionary<UUID, List<string>> chatWindows = new(); // sess, list chat
|
||||
protected Dictionary<UUID, bool> chatWindowsUnread = new(); // sess, bool
|
||||
protected Dictionary<UUID, bool> chatWindowsIsGroup = new(); // sess, bool
|
||||
protected Dictionary<UUID, UUID> chatWindowsOwner = new(); // sess, owner id
|
||||
|
||||
protected Dictionary<string, string> KeyValueStore = new Dictionary<string, string>();
|
||||
protected Dictionary<string, long> KeyValueStoreLastUsed = new Dictionary<string, long>();
|
||||
protected Dictionary<string, string> KeyValueStore = new();
|
||||
protected Dictionary<string, long> KeyValueStoreLastUsed = new();
|
||||
|
||||
protected List<CommandHistory> commandHistories = new List<CommandHistory>();
|
||||
protected List<CommandHistory> commandHistories = new();
|
||||
|
||||
protected long lastCleanupKeyValueStore = 0;
|
||||
protected long lastCleanupAvatarStore = 0;
|
||||
|
|
@ -53,7 +53,7 @@ namespace SecondBotEvents.Services
|
|||
return groupsKey2Name[group];
|
||||
}
|
||||
string reply = "lookup";
|
||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
||||
AutoResetEvent fetchEvent = new(false);
|
||||
void callback(object sender, CurrentGroupsEventArgs e)
|
||||
{
|
||||
foreach(KeyValuePair<UUID,Group> entry in e.Groups)
|
||||
|
|
@ -91,7 +91,7 @@ namespace SecondBotEvents.Services
|
|||
if (dif > 125)
|
||||
{
|
||||
lastCleanupKeyValueStore = unixtime;
|
||||
List<string> clearentrys = new List<string>();
|
||||
List<string> clearentrys = new();
|
||||
foreach (KeyValuePair<string, long> entry in KeyValueStoreLastUsed)
|
||||
{
|
||||
dif = unixtime - entry.Value;
|
||||
|
|
@ -121,7 +121,7 @@ namespace SecondBotEvents.Services
|
|||
if (dif > 75)
|
||||
{
|
||||
lastCleanupAvatarStore = unixtime;
|
||||
Dictionary<UUID, string> clearLinks = new Dictionary<UUID, string>();
|
||||
Dictionary<UUID, string> clearLinks = new();
|
||||
foreach (KeyValuePair<string, UUID> entry in avatarsName2Key)
|
||||
{
|
||||
dif = unixtime - avatarLastUsed[entry.Value];
|
||||
|
|
@ -141,10 +141,10 @@ namespace SecondBotEvents.Services
|
|||
}
|
||||
}
|
||||
}
|
||||
int sum = commandHistories.Count() + KeyValueStoreLastUsed.Count() + KeyValueStore.Count() +
|
||||
chatWindowsOwner.Count() + chatWindowsIsGroup.Count() + chatWindowsUnread.Count() +
|
||||
chatWindows.Count() + localChatHistory.Count() + groupRoles.Count() +
|
||||
groupMembers.Count() + groupsKey2Name.Count() + avatarsName2Key.Count();
|
||||
int sum = commandHistories.Count + KeyValueStoreLastUsed.Count + KeyValueStore.Count +
|
||||
chatWindowsOwner.Count + chatWindowsIsGroup.Count + chatWindowsUnread.Count +
|
||||
chatWindows.Count + localChatHistory.Count + groupRoles.Count +
|
||||
groupMembers.Count + groupsKey2Name.Count + avatarsName2Key.Count;
|
||||
return sum.ToString();
|
||||
}
|
||||
|
||||
|
|
@ -152,7 +152,7 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
lock (commandHistories)
|
||||
{
|
||||
CommandHistory A = new CommandHistory(status, command, args, SecondbotHelpers.UnixTimeNow());
|
||||
CommandHistory A = new(status, command, args, SecondbotHelpers.UnixTimeNow());
|
||||
commandHistories.Add(A);
|
||||
int c = commandHistories.Count;
|
||||
while (c > myConfig.GetCommandHistoryLimit())
|
||||
|
|
@ -226,7 +226,7 @@ namespace SecondBotEvents.Services
|
|||
|
||||
public List<UUID> GetAllGroupsChatWithUnread()
|
||||
{
|
||||
List<UUID> reply = new List<UUID>();
|
||||
List<UUID> reply = new();
|
||||
foreach(KeyValuePair<UUID, bool> windowState in chatWindowsUnread)
|
||||
{
|
||||
if(windowState.Value == false)
|
||||
|
|
@ -299,11 +299,11 @@ namespace SecondBotEvents.Services
|
|||
|
||||
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)
|
||||
{
|
||||
|
||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
||||
AutoResetEvent fetchEvent = new(false);
|
||||
void callback(object sender, GroupRolesDataReplyEventArgs e)
|
||||
{
|
||||
if (e.GroupID == group)
|
||||
|
|
@ -341,7 +341,7 @@ namespace SecondBotEvents.Services
|
|||
if (groupMembers[group].Contains(avatar) == false)
|
||||
{
|
||||
reply = false;
|
||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
||||
AutoResetEvent fetchEvent = new(false);
|
||||
void callback(object sender, GroupMembersReplyEventArgs e)
|
||||
{
|
||||
if (e.GroupID == group)
|
||||
|
|
@ -395,7 +395,7 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
purgeLen = myConfig.GetGroupChatHistoryLimitPerGroup();
|
||||
}
|
||||
int counter = chatWindows[sessionID].Count();
|
||||
int counter = chatWindows[sessionID].Count;
|
||||
while (counter > purgeLen)
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
|
@ -532,7 +532,7 @@ namespace SecondBotEvents.Services
|
|||
if(avatarsName2Key.ContainsValue(avatarId) == false)
|
||||
{
|
||||
bool hasReply = false;
|
||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
||||
AutoResetEvent fetchEvent = new(false);
|
||||
void callback(object sender, UUIDNameReplyEventArgs e)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, string> av in e.Names)
|
||||
|
|
@ -563,7 +563,7 @@ namespace SecondBotEvents.Services
|
|||
UUID wantedReplyID = UUID.SecureRandom();
|
||||
|
||||
bool hasReply = false;
|
||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
||||
AutoResetEvent fetchEvent = new(false);
|
||||
void callback(object sender, AvatarPickerReplyEventArgs e)
|
||||
{
|
||||
if (e.QueryID == wantedReplyID)
|
||||
|
|
@ -590,7 +590,7 @@ namespace SecondBotEvents.Services
|
|||
|
||||
public void GetAvatarNames(List<UUID> avatars)
|
||||
{
|
||||
List<UUID> lookup = new List<UUID>();
|
||||
List<UUID> lookup = new();
|
||||
foreach (UUID id in avatars)
|
||||
{
|
||||
if (avatarsName2Key.ContainsValue(id) == false)
|
||||
|
|
@ -664,7 +664,7 @@ namespace SecondBotEvents.Services
|
|||
|
||||
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)
|
||||
{
|
||||
if(links.Value == true)
|
||||
|
|
@ -728,7 +728,7 @@ namespace SecondBotEvents.Services
|
|||
|
||||
public List<UUID> GetAvatarImWindowsUnread()
|
||||
{
|
||||
List<UUID> windows = new List<UUID>();
|
||||
List<UUID> windows = new();
|
||||
foreach (KeyValuePair<UUID, bool> links in chatWindowsIsGroup)
|
||||
{
|
||||
if (links.Value == true)
|
||||
|
|
@ -834,8 +834,8 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
if (estateBanlist == null)
|
||||
{
|
||||
List<UUID> reply = new List<UUID>();
|
||||
AutoResetEvent fetchEvent = new AutoResetEvent(false);
|
||||
List<UUID> reply = new();
|
||||
AutoResetEvent fetchEvent = new(false);
|
||||
void callback(object sender, EstateBansReplyEventArgs e)
|
||||
{
|
||||
reply = e.Banned;
|
||||
|
|
@ -1077,7 +1077,7 @@ namespace SecondBotEvents.Services
|
|||
public class CommandHistory
|
||||
{
|
||||
public string Command = "";
|
||||
public string[] Args = new string[] { };
|
||||
public string[] Args = Array.Empty<string>();
|
||||
public long Unixtime = 0;
|
||||
public bool status = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ namespace SecondBotEvents.Services
|
|||
protected bool attemptedTeleportBackup = false;
|
||||
protected long teleportActionLockout = 0;
|
||||
|
||||
public void GoHome()
|
||||
public bool GoHome()
|
||||
{
|
||||
attemptedTeleportHome = true;
|
||||
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()
|
||||
{
|
||||
|
|
@ -85,8 +85,14 @@ namespace SecondBotEvents.Services
|
|||
}
|
||||
if (simNickname == "")
|
||||
{
|
||||
simNickname = "Someplace # ";
|
||||
return;
|
||||
if (GetClient().Network.CurrentSim != null)
|
||||
{
|
||||
simNickname = ""+ GetClient().Network.CurrentSim.Name+" # ";
|
||||
}
|
||||
else
|
||||
{
|
||||
simNickname = "Someplace # ";
|
||||
}
|
||||
}
|
||||
long dif = SecondbotHelpers.UnixTimeNow() - teleportActionLockout;
|
||||
if(dif < 30)
|
||||
|
|
@ -96,7 +102,10 @@ namespace SecondBotEvents.Services
|
|||
teleportActionLockout = SecondbotHelpers.UnixTimeNow();
|
||||
if (attemptedTeleportHome == false)
|
||||
{
|
||||
GoHome();
|
||||
if(GoHome() == false)
|
||||
{
|
||||
LogFormater.Warn("Unable to teleport to home sim");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(attemptedTeleportBackup == false)
|
||||
|
|
@ -104,7 +113,10 @@ namespace SecondBotEvents.Services
|
|||
attemptedTeleportBackup = true;
|
||||
LogFormater.Info("Teleporting to backup sim");
|
||||
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;
|
||||
}
|
||||
attemptedTeleportHome = false;
|
||||
|
|
|
|||
|
|
@ -161,13 +161,16 @@ namespace SecondBotEvents.Services
|
|||
string UUIDfetch = master.DataStoreService.GetAvatarUUID(avatar);
|
||||
if (UUIDfetch != "lookup")
|
||||
{
|
||||
UUID.TryParse(UUIDfetch, out avataruuid);
|
||||
if(UUID.TryParse(UUIDfetch, out avataruuid) == false)
|
||||
{
|
||||
avataruuid = UUID.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -178,13 +181,13 @@ namespace SecondBotEvents.Services
|
|||
protected object BasicReply(string input, string[] args, string command)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
|
@ -194,10 +197,10 @@ namespace SecondBotEvents.Services
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
@ -272,7 +275,7 @@ namespace SecondBotEvents.Services
|
|||
|
||||
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)
|
||||
{
|
||||
myArgs = args.Split("~#~", StringSplitOptions.RemoveEmptyEntries);
|
||||
|
|
@ -285,7 +288,7 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
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)
|
||||
{
|
||||
return "Command request rejected";
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace SecondBotEvents.Services
|
|||
{
|
||||
protected RelayConfig myConfig;
|
||||
protected bool botConnected = false;
|
||||
protected List<RelaySys> Relays = new List<RelaySys>();
|
||||
protected List<RelaySys> Relays = new();
|
||||
public RelayService(EventsSecondBot setMaster) : base(setMaster)
|
||||
{
|
||||
myConfig = new RelayConfig(master.fromEnv, master.fromFolder);
|
||||
|
|
@ -348,7 +348,7 @@ namespace SecondBotEvents.Services
|
|||
readonly string[] vaildToOptions = new[] { "avatar", "group", "localchat", "discord", "http" };
|
||||
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)
|
||||
{
|
||||
// avatarim, {message}, avatarUUID
|
||||
|
|
@ -414,7 +414,7 @@ namespace SecondBotEvents.Services
|
|||
case "http":
|
||||
{
|
||||
long unixtime = SecondbotHelpers.UnixTimeNow();
|
||||
Dictionary<string, string> values = new Dictionary<string, string>
|
||||
Dictionary<string, string> values = new()
|
||||
{
|
||||
{ "fromType", fromType },
|
||||
{ "fromOption", fromOption },
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ using System.Text;
|
|||
|
||||
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)
|
||||
{
|
||||
|
|
@ -27,7 +27,7 @@ namespace SecondBotEvents
|
|||
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;
|
||||
if (P.OwnerID != bot.Self.AgentID)
|
||||
|
|
@ -54,30 +54,32 @@ namespace SecondBotEvents
|
|||
return has_perm;
|
||||
|
||||
}
|
||||
public static string[] get_flag_names()
|
||||
public static string[] GetFlagNames()
|
||||
{
|
||||
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");
|
||||
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>();
|
||||
flags.Add("MediaAutoScale", "Bool (True|False)");
|
||||
flags.Add("MediaLoop", "Bool (True|False)");
|
||||
flags.Add("MediaID", "UUID (Texture)");
|
||||
flags.Add("MediaURL", "String");
|
||||
flags.Add("MediaDesc", "String");
|
||||
flags.Add("MediaHeight", "Int (256 to 1024)");
|
||||
flags.Add("MediaWidth", "Int (256 to 1024)");
|
||||
flags.Add("MediaType", "String [\"IMG-PNG\",\"IMG-JPG\",\"VID-MP4\",\"VID-AVI\" or \"Custom-MIME_TYPE_CODE\"]");
|
||||
Dictionary<string, string> flags = new()
|
||||
{
|
||||
{ "MediaAutoScale", "Bool (True|False)" },
|
||||
{ "MediaLoop", "Bool (True|False)" },
|
||||
{ "MediaID", "UUID (Texture)" },
|
||||
{ "MediaURL", "String" },
|
||||
{ "MediaDesc", "String" },
|
||||
{ "MediaHeight", "Int (256 to 1024)" },
|
||||
{ "MediaWidth", "Int (256 to 1024)" },
|
||||
{ "MediaType", "String [\"IMG-PNG\",\"IMG-JPG\",\"VID-MP4\",\"VID-AVI\" or \"Custom-MIME_TYPE_CODE\"]" }
|
||||
};
|
||||
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);
|
||||
Array enumValues = Enum.GetValues(enumType);
|
||||
Array enumNames = Enum.GetNames(enumType);
|
||||
|
|
|
|||
Loading…
Reference in a new issue