Sync up to upstream through 04/26/2022

This commit is contained in:
Mike Dickson 2022-04-27 15:10:27 -04:00
commit 7837a7f664
304 changed files with 33028 additions and 31809 deletions

4
.gitignore vendored
View file

@ -13,6 +13,8 @@
*.dll
*.log
.idea
*.bak
*.lnk
launchSettings.json
@ -53,6 +55,7 @@ bin/ScriptEngines/*-*-*-*-*
bin/ScriptEngines/*.dll
bin/ScriptEngines/*/*.dll
bin/ScriptEngines/*/*.state
bin/ScriptEngines/Yengine/*
bin/*.maddin
bin/*.exe
bin/*.ini
@ -64,6 +67,7 @@ bin/UserAssets
bin/assetcache
bin/maptiles
bin/bakes
bin/MeshCache
bin/estate_settings.xml
bin/config-include/CenomeCache.ini
bin/config-include/FlotsamCache.ini

View file

@ -401,7 +401,7 @@ namespace OpenSim.Groups
msg.ParentEstateID = 0;
msg.Position = Vector3.Zero;
msg.RegionID = UUID.Zero.Guid;
msg.binaryBucket = new byte[0];
msg.binaryBucket = Array.Empty<byte>();
OutgoingInstantMessage(msg, invitee);
IClientAPI inviteeClient = GetActiveRootClient(invitee);
@ -1117,7 +1117,7 @@ namespace OpenSim.Groups
msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ;
msg.fromAgentName = string.Empty;
msg.message = string.Empty;
msg.binaryBucket = new byte[0];
msg.binaryBucket = Array.Empty<byte>(); ;
}
return msg;
@ -1276,7 +1276,7 @@ namespace OpenSim.Groups
msg.ParentEstateID = 0;
msg.Position = Vector3.Zero;
msg.RegionID = regionInfo.RegionID.Guid;
msg.binaryBucket = new byte[0];
msg.binaryBucket = Array.Empty<byte>(); ;
OutgoingInstantMessage(msg, ejecteeID);
}
@ -1294,7 +1294,7 @@ namespace OpenSim.Groups
msg.ParentEstateID = 0;
msg.Position = Vector3.Zero;
msg.RegionID = regionInfo.RegionID.Guid;
msg.binaryBucket = new byte[0];
msg.binaryBucket = Array.Empty<byte>(); ;
OutgoingInstantMessage(msg, agentID);
}

View file

@ -72,7 +72,7 @@ namespace OpenSim.OfflineIM
//
// We tried, but this doesn't exist. We can't proceed.
//
if (dllName.Equals(String.Empty))
if (string.IsNullOrEmpty(dllName))
throw new Exception("No StorageProvider configured");
m_Database = LoadPlugin<IOfflineIMData>(dllName, new Object[] { connString, realm });

View file

@ -26,9 +26,7 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
@ -47,18 +45,22 @@ namespace OpenSim.Capabilities.Handlers
{
public class FetchInvDescHandler
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static byte[] EmptyResponse = Util.UTF8NBGetbytes("<llsd><map><key>folders</key><array /></map></llsd>");
private IInventoryService m_InventoryService;
private ILibraryService m_LibraryService;
private IScene m_Scene;
private static readonly byte[] EmptyResponse = Util.UTF8NBGetbytes("<llsd><map><key>folders</key><array /></map></llsd>");
private readonly IInventoryService m_InventoryService;
private readonly ILibraryService m_LibraryService;
private readonly UUID libOwner;
private readonly IScene m_Scene;
public FetchInvDescHandler(IInventoryService invService, ILibraryService libService, IScene s)
{
m_InventoryService = invService;
m_LibraryService = libService;
if(libService != null && libService.LibraryRootFolder != null)
{
m_LibraryService = libService;
libOwner = libService.LibraryRootFolder.Owner;
}
m_Scene = s;
}
@ -167,24 +169,16 @@ namespace OpenSim.Capabilities.Handlers
return;
}
int total_folders = 0;
int total_items = 0;
UUID requester = folders[0].owner_id;
List<InventoryCollection> invcollSet = Fetch(folders, bad_folders, ref total_folders, ref total_items);
List<InventoryCollection> invcollSet = Fetch(folders, bad_folders);
//m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);
int invcollSetCount = 0;
if (invcollSet != null)
invcollSetCount = invcollSet.Count;
int mem = 8192 + ((256 * invcollSetCount +
384 * total_folders +
1024 * total_items +
128 * bad_folders.Count) & 0x7ffff000);
osUTF8 lastresponse = LLSDxmlEncode2.Start(mem);
osUTF8 lastresponse = LLSDxmlEncode2.Start();
if (invcollSetCount > 0)
{
@ -280,7 +274,7 @@ namespace OpenSim.Capabilities.Handlers
httpResponse.RawBuffer = LLSDxmlEncode2.EndToBytes(lastresponse);
}
private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> libFolders, List<InventoryCollection> result, ref int total_folders, ref int total_items)
private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> libFolders, List<InventoryCollection> result)
{
InventoryFolderImpl fold;
if (m_LibraryService == null || m_LibraryService.LibraryRootFolder == null)
@ -299,8 +293,6 @@ namespace OpenSim.Capabilities.Handlers
Collection.Version = fold.Version;
Collection.Descendents = Collection.Items.Count + Collection.Folders.Count;
total_folders += Collection.Folders.Count;
total_items += Collection.Items.Count;
result.Add(Collection);
//m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
@ -308,7 +300,7 @@ namespace OpenSim.Capabilities.Handlers
}
}
private List<InventoryCollection> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders, ref int total_folders, ref int total_items)
private List<InventoryCollection> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders)
{
//m_log.DebugFormat(
// "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id);
@ -321,10 +313,7 @@ namespace OpenSim.Capabilities.Handlers
HashSet<UUID> libIDs = new HashSet<UUID>();
HashSet<UUID> otherIDs = new HashSet<UUID>();
bool dolib = (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null);
UUID libOwner = UUID.Zero;
if(dolib)
libOwner = m_LibraryService.LibraryRootFolder.Owner;
bool dolib = m_LibraryService != null;
// Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
// and can kill the sim (all root folders have parent_id Zero)
@ -345,7 +334,7 @@ namespace OpenSim.Capabilities.Handlers
result.Add(Collection);
continue;
}
if(dolib && f.owner_id == libOwner)
if(dolib && f.owner_id.Equals(libOwner))
{
if(libIDs.Contains(f.folder_id))
continue;
@ -364,8 +353,6 @@ namespace OpenSim.Capabilities.Handlers
if(otherFolders.Count > 0)
{
int i = 0;
//m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids));
InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(otherFolders[0].owner_id, otherIDs.ToArray());
@ -380,7 +367,7 @@ namespace OpenSim.Capabilities.Handlers
}
else
{
i = 0;
int i = 0;
// Do some post-processing. May need to fetch more from inv server for links
foreach (InventoryCollection contents in fetchedContents)
{
@ -402,17 +389,13 @@ namespace OpenSim.Capabilities.Handlers
// Next: link management
ProcessLinks(freq, contents);
total_folders += contents.Folders.Count;
total_items += contents.Items.Count;
result.Add(contents);
}
}
}
if(dolib && libFolders.Count > 0)
{
AddLibraryFolders(libFolders, result, ref total_folders, ref total_items);
}
if(libFolders.Count > 0)
AddLibraryFolders(libFolders, result);
return result;
}

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Net;
using System.Reflection;
using System.Text;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
using log4net;
namespace OpenSim.Capabilities.Handlers
{
public class FetchLib2Handler
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IInventoryService m_inventoryService;
private ILibraryService m_LibraryService;
private UUID m_agentID;
private UUID libOwner;
public FetchLib2Handler(IInventoryService invService, ILibraryService libraryService, UUID agentId)
{
m_inventoryService = invService;
m_agentID = agentId;
m_LibraryService = libraryService;
if(libraryService != null)
libOwner = m_LibraryService.LibraryRootFolder.Owner;
}
public void FetchLibSimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap, ExpiringKey<UUID> BadRequests)
{
//m_log.DebugFormat("[FETCH LIB INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
if (BadRequests == null)
{
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
if (m_LibraryService == null || m_agentID == UUID.Zero)
{
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
OSDArray itemsRequested = (OSDArray)requestmap["items"];
UUID[] itemIDs = new UUID[itemsRequested.Count];
int i = 0;
foreach (OSDMap osdItemId in itemsRequested)
{
UUID id = osdItemId["item_id"].AsUUID();
if (!BadRequests.ContainsKey(id))
itemIDs[i++] = id;
}
InventoryItemBase[] items = null;
//items = m_inventoryService.GetMultipleItems(libOwner, itemIDs);
items = m_LibraryService.GetMultipleItems(itemIDs);
osUTF8 lsl = LLSDxmlEncode2.Start(4096);
LLSDxmlEncode2.AddMap(lsl);
LLSDxmlEncode2.AddElem("agent_id", m_agentID, lsl);
if(items == null || items.Length == 0)
{
LLSDxmlEncode2.AddEmptyArray("items", lsl);
}
else
{
LLSDxmlEncode2.AddArray("items", lsl);
foreach (InventoryItemBase item in items)
{
if (item != null)
item.ToLLSDxml(lsl);
}
LLSDxmlEncode2.AddEndArray(lsl);
}
LLSDxmlEncode2.AddEndMap(lsl);
httpResponse.RawBuffer = LLSDxmlEncode2.EndToBytes(lsl);
httpResponse.StatusCode = (int)HttpStatusCode.OK;
}
}
}

View file

@ -0,0 +1,343 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Text;
using log4net;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
namespace OpenSim.Capabilities.Handlers
{
public class FetchLibDescHandler
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly byte[] EmptyResponse = Util.UTF8NBGetbytes("<llsd><map><key>folders</key><array /></map></llsd>");
private readonly ILibraryService m_LibraryService;
private readonly UUID libOwner;
private readonly IScene m_Scene;
public FetchLibDescHandler(ILibraryService libService, IScene s)
{
m_LibraryService = libService;
libOwner = m_LibraryService.LibraryRootFolder.Owner;
m_Scene = s;
}
public void FetchRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, ExpiringKey<UUID> BadRequests, UUID agentID)
{
//m_log.DebugFormat("[XXX]: FetchLibDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request);
if (m_LibraryService == null || m_LibraryService.LibraryRootFolder == null)
{
httpResponse.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
return;
}
httpResponse.StatusCode = (int)HttpStatusCode.OK;
List<LLSDFetchInventoryDescendents> folders = null;
List<UUID> bad_folders = new List<UUID>();
try
{
OSDArray foldersrequested = null;
OSD tmp = OSDParser.DeserializeLLSDXml(httpRequest.InputStream);
httpRequest.InputStream.Dispose();
OSDMap map = (OSDMap)tmp;
if(map.TryGetValue("folders", out tmp) && tmp is OSDArray)
foldersrequested = tmp as OSDArray;
if (foldersrequested == null || foldersrequested.Count == 0)
{
httpResponse.RawBuffer = EmptyResponse;
return;
}
folders = new List<LLSDFetchInventoryDescendents>(foldersrequested.Count);
for (int i = 0; i < foldersrequested.Count; i++)
{
OSDMap mfolder = foldersrequested[i] as OSDMap;
UUID id = mfolder["folder_id"].AsUUID();
if(BadRequests.ContainsKey(id))
{
bad_folders.Add(id);
}
else
{
LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
try
{
llsdRequest.folder_id = id;
llsdRequest.owner_id = mfolder["owner_id"].AsUUID();
llsdRequest.sort_order = mfolder["sort_order"].AsInteger();
llsdRequest.fetch_folders = mfolder["fetch_folders"].AsBoolean();
llsdRequest.fetch_items = mfolder["fetch_items"].AsBoolean();
}
catch (Exception e)
{
m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e.Message);
continue;
}
folders.Add(llsdRequest);
}
}
foldersrequested = null;
map.Clear();
map = null;
}
catch (Exception e)
{
m_log.ErrorFormat("[FETCH LIB DESC]: fail parsing request: {0}", e.Message);
httpResponse.RawBuffer = EmptyResponse;
return;
}
if (folders == null || folders.Count == 0)
{
if(bad_folders.Count == 0)
{
httpResponse.RawBuffer = EmptyResponse;
return;
}
osUTF8 osu = OSUTF8Cached.Acquire();
osu.AppendASCII("[FETCH LIB DESC HANDLER]: Unable to fetch folders:");
int limit = 5;
int count = 0;
foreach (UUID bad in bad_folders)
{
if (BadRequests.ContainsKey(bad))
continue;
osu.Append((byte)' ');
osu.AppendASCII(bad.ToString());
++count;
if (--limit < 0)
break;
}
if(count > 0)
{
if (limit < 0)
osu.AppendASCII(" ...");
m_log.Warn(osu.ToString());
}
osu.Clear();
osu.AppendASCII("<llsd><map><key>folders</key><array /></map><map><key>bad_folders</key><array>");
foreach (UUID bad in bad_folders)
{
osu.AppendASCII("<map><key>folder_id</key><uuid>");
osu.AppendASCII(bad.ToString());
osu.AppendASCII("</uuid><key>error</key><string>Unknown</string></map>");
}
osu.AppendASCII("</array></map></llsd>");
httpResponse.RawBuffer = OSUTF8Cached.GetArrayAndRelease(osu);
return;
}
UUID requester = folders[0].owner_id;
List<InventoryCollection> invcollSet = Fetch(folders, bad_folders);
//m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);
int invcollSetCount = 0;
if (invcollSet != null)
invcollSetCount = invcollSet.Count;
osUTF8 lastresponse = LLSDxmlEncode2.Start();
if (invcollSetCount > 0)
{
lastresponse.AppendASCII("<map><key>folders</key><array>");
int i = 0;
InventoryCollection thiscoll;
for (i = 0; i < invcollSetCount; i++)
{
thiscoll = invcollSet[i];
invcollSet[i] = null;
LLSDxmlEncode2.AddMap(lastresponse);
LLSDxmlEncode2.AddElem_folder_id(thiscoll.FolderID, lastresponse);
LLSDxmlEncode2.AddElem_agent_id(agentID, lastresponse);
LLSDxmlEncode2.AddElem_owner_id(thiscoll.OwnerID, lastresponse);
LLSDxmlEncode2.AddElem("descendents", thiscoll.Descendents, lastresponse);
LLSDxmlEncode2.AddElem_version(thiscoll.Version, lastresponse);
if (thiscoll.Folders == null || thiscoll.Folders.Count == 0)
LLSDxmlEncode2.AddEmptyArray("categories", lastresponse);
else
{
LLSDxmlEncode2.AddArray("categories", lastresponse);
foreach (InventoryFolderBase invFolder in thiscoll.Folders)
{
LLSDxmlEncode2.AddMap(lastresponse);
LLSDxmlEncode2.AddElem_category_id(invFolder.ID, lastresponse);
LLSDxmlEncode2.AddElem_parent_id(invFolder.ParentID, lastresponse);
LLSDxmlEncode2.AddElem_name(invFolder.Name, lastresponse);
LLSDxmlEncode2.AddElem("type_default", invFolder.Type, lastresponse);
LLSDxmlEncode2.AddElem_version( invFolder.Version, lastresponse);
LLSDxmlEncode2.AddEndMap(lastresponse);
}
LLSDxmlEncode2.AddEndArray(lastresponse);
}
if (thiscoll.Items == null || thiscoll.Items.Count == 0)
LLSDxmlEncode2.AddEmptyArray("items", lastresponse);
else
{
LLSDxmlEncode2.AddArray("items", lastresponse);
foreach (InventoryItemBase invItem in thiscoll.Items)
{
invItem.ToLLSDxml(lastresponse);
}
LLSDxmlEncode2.AddEndArray(lastresponse);
}
LLSDxmlEncode2.AddEndMap(lastresponse);
invcollSet[i] = null;
}
LLSDxmlEncode2.AddEndArrayAndMap(lastresponse);
thiscoll = null;
}
else
{
lastresponse.AppendASCII("<map><key>folders</key><array /></map>");
}
if (bad_folders.Count > 0)
{
lastresponse.AppendASCII("<map><key>bad_folders</key><array>");
foreach (UUID bad in bad_folders)
{
BadRequests.Add(bad);
lastresponse.AppendASCII("<map><key>folder_id</key><uuid>");
lastresponse.AppendASCII(bad.ToString());
lastresponse.AppendASCII("</uuid><key>error</key><string>Unknown</string></map>");
}
lastresponse.AppendASCII("</array></map>");
StringBuilder sb = osStringBuilderCache.Acquire();
sb.Append("[WEB FETCH INV DESC HANDLER]: Unable to fetch folders owned by ");
sb.Append(requester.ToString());
sb.Append(" :");
int limit = 9;
foreach (UUID bad in bad_folders)
{
sb.Append(" ");
sb.Append(bad.ToString());
if(--limit < 0)
break;
}
if(limit < 0)
sb.Append(" ...");
m_log.Warn(osStringBuilderCache.GetStringAndRelease(sb));
}
httpResponse.RawBuffer = LLSDxmlEncode2.EndToBytes(lastresponse);
}
private List<InventoryCollection> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders)
{
//m_log.DebugFormat(
// "[FETCH LIB DESC HANDLER]: Fetching {0} folders", fetchFolders.Count);
// FIXME MAYBE: We're not handling sortOrder!
int cntr = fetchFolders.Count;
List<InventoryCollection> result = new List<InventoryCollection>(cntr);
List<LLSDFetchInventoryDescendents> libFolders = new List<LLSDFetchInventoryDescendents>(cntr);
HashSet<UUID> libIDs = new HashSet<UUID>();
// Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
// and can kill the sim (all root folders have parent_id Zero)
// send something.
bool doneZeroID = false;
foreach(LLSDFetchInventoryDescendents f in fetchFolders)
{
if (f.folder_id.IsZero())
{
if(doneZeroID)
continue;
doneZeroID = true;
InventoryCollection Collection = new InventoryCollection()
{
OwnerID = f.owner_id,
Version = -1,
FolderID = f.folder_id,
Descendents = 0
};
result.Add(Collection);
continue;
}
if(f.owner_id.Equals(libOwner))
{
if(libIDs.Contains(f.folder_id))
continue;
libIDs.Add(f.folder_id);
libFolders.Add(f);
continue;
}
}
if (libFolders.Count > 0)
{
foreach (LLSDFetchInventoryDescendents f in libFolders)
{
InventoryFolderImpl fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id);
if (fold != null)
{
InventoryCollection Collection = new InventoryCollection()
{
Folders = fold.RequestListOfFolders(),
Items = fold.RequestListOfItems(),
OwnerID = m_LibraryService.LibraryRootFolder.Owner,
FolderID = f.folder_id,
Version = fold.Version
};
Collection.Descendents = Collection.Items.Count + Collection.Folders.Count;
result.Add(Collection);
//m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
}
else
bad_folders.Add(f.folder_id);
}
}
return result;
}
}
}

View file

@ -292,7 +292,7 @@ namespace OpenSim.Capabilities.Handlers
private byte[] ConvertTextureData(AssetBase texture, string format)
{
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
byte[] data = new byte[0];
byte[] data = Array.Empty<byte>(); ;
MemoryStream imgstream = new MemoryStream();
Bitmap mTexture = null;

View file

@ -320,7 +320,7 @@ namespace OpenSim.Capabilities.Handlers
private byte[] ConvertTextureData(AssetBase texture, string format)
{
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
byte[] data = new byte[0];
byte[] data = Array.Empty<byte>(); ;
MemoryStream imgstream = new MemoryStream();
Bitmap mTexture = null;

View file

@ -25,10 +25,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.IO;
using System.Text;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
namespace OpenSim.Framework.Capabilities
@ -62,7 +61,7 @@ namespace OpenSim.Framework.Capabilities
Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request);
if(hash == null)
return new byte[0];
return Array.Empty<byte>();
TRequest llsdRequest = new TRequest();
LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);

View file

@ -49,23 +49,21 @@ namespace OpenSim.Data
Type idtype = id.GetType();
if (idtype == typeof(string))
{
UUID.TryParse((string)id, out UUID result);
return result;
}
if (idtype == typeof(Guid))
return new UUID((Guid)id);
if (id.GetType() == typeof(string))
{
Guid gg;
if (Guid.TryParse((string)id, out gg))
return new UUID(gg);
return UUID.Zero;
}
if (idtype == typeof(byte[]))
{
if (((byte[])id).Length < 16)
return UUID.Zero;
return new UUID((byte[])id, 0);
byte[] idb = (byte[])id;
return idb.Length < 16 ? UUID.Zero : new UUID(idb, 0);
}
throw new Exception("Failed to convert db value to UUID: " + id.ToString());
}
}

View file

@ -1592,7 +1592,7 @@ namespace OpenSim.Data.MySQL
if (prim.KeyframeMotion != null)
cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize());
else
cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]);
cmd.Parameters.AddWithValue("KeyframeMotion", Array.Empty<byte>());
if (prim.PhysicsInertia != null)
cmd.Parameters.AddWithValue("PhysInertia", prim.PhysicsInertia.ToXml2());

View file

@ -183,7 +183,7 @@ namespace OpenSim.Data.PGSQL
catch(Exception e)
{
m_log.Error("[PGSQL FSASSETS] Failed to store asset with ID " + meta.ID);
m_log.Error(e.ToString());
m_log.Error(e.ToString());
return false;
}
}

View file

@ -2170,7 +2170,7 @@ namespace OpenSim.Data.SQLite
if (prim.KeyframeMotion != null)
row["KeyframeMotion"] = prim.KeyframeMotion.Serialize();
else
row["KeyframeMotion"] = new Byte[0];
row["KeyframeMotion"] = Array.Empty<byte>(); ;
row["PassTouches"] = prim.PassTouches;
row["PassCollisions"] = prim.PassCollisions;

View file

@ -235,7 +235,7 @@ namespace OpenSim.Data.Tests
foreach (string store in stores)
{
string s = "'" + store + "'";
if (lst == "")
if (lst.Length == 0)
lst = s;
else
lst += ", " + s;

View file

@ -860,17 +860,17 @@ namespace OpenSim.Data.Tests
UUID tertex2 = UUID.Random();
UUID tertex3 = UUID.Random();
UUID tertex4 = UUID.Random();
double elev1nw = random.Next();
double elev2nw = random.Next();
double elev1ne = random.Next();
double elev2ne = random.Next();
double elev1se = random.Next();
double elev2se = random.Next();
double elev1sw = random.Next();
double elev2sw = random.Next();
double waterh = random.Next();
double terrainraise = random.Next();
double terrainlower = random.Next();
double elev1nw = 1000;
double elev2nw = 1001;
double elev1ne = 1002;
double elev2ne = 1003;
double elev1se = 1004;
double elev2se = 1425;
double elev1sw = 352;
double elev2sw = 774;
double waterh = 125;
double terrainraise = 74;
double terrainlower = -79;
Vector3 sunvector = new Vector3((float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5));
UUID terimgid = UUID.Random();
UUID cov = UUID.Random();

View file

@ -35,11 +35,6 @@ namespace OpenSim.Framework
/// </summary>
public class AgentUpdateArgs : EventArgs
{
/// <summary>
/// Agent's unique ID
/// </summary>
public UUID AgentID;
/// <summary>
/// Rotation of the avatar's body
/// </summary>
@ -76,7 +71,6 @@ namespace OpenSim.Framework
/// <summary>
/// Session Id
/// </summary>
public UUID SessionID;
public byte State;
public Vector3 ClientAgentPosition;

View file

@ -74,34 +74,34 @@ namespace OpenSim.Framework
protected float m_avatarFeetOffset = 0;
protected float m_avatarAnimOffset = 0;
public virtual int Serial
public int Serial
{
get { return m_serial; }
set { m_serial = value; }
}
public virtual byte[] VisualParams
public byte[] VisualParams
{
get { return m_visualparams; }
set { m_visualparams = value; }
}
public virtual Vector3 AvatarSize
public Vector3 AvatarSize
{
get { return m_avatarSize; }
}
public virtual Vector3 AvatarBoxSize
public Vector3 AvatarBoxSize
{
get { return m_avatarBoxSize; }
}
public virtual float AvatarFeetOffset
public float AvatarFeetOffset
{
get { return m_avatarFeetOffset + m_avatarAnimOffset; }
}
public virtual Primitive.TextureEntry Texture
public Primitive.TextureEntry Texture
{
get { return m_texture; }
set
@ -111,25 +111,25 @@ namespace OpenSim.Framework
}
}
public virtual AvatarWearable[] Wearables
public AvatarWearable[] Wearables
{
get { return m_wearables; }
set { m_wearables = value; }
}
public virtual float AvatarHeight
public float AvatarHeight
{
get { return m_avatarHeight; }
set { m_avatarHeight = value; }
}
public virtual WearableCacheItem[] WearableCacheItems
public WearableCacheItem[] WearableCacheItems
{
get { return m_cacheitems; }
set { m_cacheitems = value; }
}
public virtual float AvatarPreferencesHoverZ { get; set; }
public float AvatarPreferencesHoverZ { get; set; }
public AvatarAppearance()
{
@ -278,7 +278,7 @@ namespace OpenSim.Framework
m_wearables[i] = new AvatarWearable();
}
protected virtual void SetDefaultWearables()
protected void SetDefaultWearables()
{
m_wearables = AvatarWearable.DefaultWearables;
}
@ -287,7 +287,7 @@ namespace OpenSim.Framework
/// Invalidate all of the baked textures in the appearance, useful
/// if you know that none are valid
/// </summary>
public virtual void ResetAppearance()
public void ResetAppearance()
{
// m_log.WarnFormat("[AVATAR APPEARANCE]: Reset appearance");
@ -303,31 +303,21 @@ namespace OpenSim.Framework
// }
}
protected virtual void SetDefaultParams()
protected void SetDefaultParams()
{
m_visualparams = new byte[] { 33,61,85,23,58,127,63,85,63,42,0,85,63,36,85,95,153,63,34,0,63,109,88,132,63,136,81,85,103,136,127,0,150,150,150,127,0,0,0,0,0,127,0,0,255,127,114,127,99,63,127,140,127,127,0,0,0,191,0,104,0,0,0,0,0,0,0,0,0,145,216,133,0,127,0,127,170,0,0,127,127,109,85,127,127,63,85,42,150,150,150,150,150,150,150,25,150,150,150,0,127,0,0,144,85,127,132,127,85,0,127,127,127,127,127,127,59,127,85,127,127,106,47,79,127,127,204,2,141,66,0,0,127,127,0,0,0,0,127,0,159,0,0,178,127,36,85,131,127,127,127,153,95,0,140,75,27,127,127,0,150,150,198,0,0,63,30,127,165,209,198,127,127,153,204,51,51,255,255,255,204,0,255,150,150,150,150,150,150,150,150,150,150,0,150,150,150,150,150,0,127,127,150,150,150,150,150,150,150,150,0,0,150,51,132,150,150,150 };
// for (int i = 0; i < VISUALPARAM_COUNT; i++)
// {
// m_visualparams[i] = 150;
// }
}
/// <summary>
/// Invalidate all of the baked textures in the appearance, useful
/// if you know that none are valid
/// </summary>
public virtual void ResetBakedTextures()
public void ResetBakedTextures()
{
SetDefaultTexture();
//for (int i = 0; i < BAKE_INDICES.Length; i++)
// {
// int idx = BAKE_INDICES[i];
// m_texture.FaceTextures[idx].TextureID = UUID.Zero;
// }
}
protected virtual void SetDefaultTexture()
protected void SetDefaultTexture()
{
m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
}
@ -339,7 +329,7 @@ namespace OpenSim.Framework
/// True if any existing texture id was changed by the new data.
/// False if there were no changes or no existing texture ids.
/// </returns>
public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry)
public bool SetTextureEntries(Primitive.TextureEntry textureEntry)
{
if (textureEntry == null)
return false;
@ -347,23 +337,26 @@ namespace OpenSim.Framework
bool changed = false;
Primitive.TextureEntryFace newface;
Primitive.TextureEntryFace tmpFace;
Primitive.TextureEntryFace curFace;
//make sure textureEntry.DefaultTexture is the unused one(DEFAULT_AVATAR_TEXTURE).
Primitive.TextureEntry converted = new Primitive.TextureEntry(AppearanceManager.DEFAULT_AVATAR_TEXTURE);
for (uint i = 0; i < TEXTURE_COUNT; ++i)
{
newface = textureEntry.GetFace(i);
if (newface.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
curFace = m_texture.FaceTextures[i];
if (newface.TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE))
{
tmpFace = converted.GetFace(i);
tmpFace.TextureID = newface.TextureID; // we need a full high level copy, assuming all other parameters are the same.
if (m_texture.FaceTextures[i] == null || newface.TextureID != m_texture.FaceTextures[i].TextureID)
if (curFace == null)
continue;
if (!curFace.TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE))
changed = true;
}
else
{ if (m_texture.FaceTextures[i] == null)
continue;
if(m_texture.FaceTextures[i].TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
{
tmpFace = converted.GetFace(i);
tmpFace.TextureID = newface.TextureID; // we need a full high level copy, assuming all other parameters are the same.
if (curFace == null || !curFace.TextureID.Equals(newface.TextureID))
changed = true;
}
}
@ -379,7 +372,7 @@ namespace OpenSim.Framework
/// True if any existing visual parameter was changed by the new data.
/// False if there were no changes or no existing visual parameters.
/// </returns>
public virtual bool SetVisualParams(byte[] visualParams)
public bool SetVisualParams(byte[] visualParams)
{
if (visualParams == null)
return false;
@ -404,8 +397,8 @@ namespace OpenSim.Framework
if (visualParams[i] != m_visualparams[i])
{
// DEBUG ON
// m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
// i,m_visualparams[i],visualParams[i]);
// m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
// i,m_visualparams[i],visualParams[i]);
// DEBUG OFF
m_visualparams[i] = visualParams[i];
changed = true;
@ -413,13 +406,13 @@ namespace OpenSim.Framework
}
}
// Reset the height if the visual parameters actually changed
// if (changed)
// SetHeight();
//if (changed)
// SetHeight();
return changed;
}
public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
{
SetTextureEntries(textureEntry);
SetVisualParams(visualParams);
@ -428,7 +421,7 @@ namespace OpenSim.Framework
/// <summary>
/// Set avatar height by a calculation based on their visual parameters.
/// </summary>
public virtual void SetHeight()
public void SetHeight()
{
/*
// Start with shortest possible female avatar height
@ -474,7 +467,7 @@ namespace OpenSim.Framework
m_avatarHeight = m_avatarSize.Z;
}
public virtual void SetWearable(int wearableId, AvatarWearable wearable)
public void SetWearable(int wearableId, AvatarWearable wearable)
{
// DEBUG ON
// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
@ -540,9 +533,9 @@ namespace OpenSim.Framework
internal void AppendAttachment(AvatarAttachment attach)
{
// m_log.DebugFormat(
// "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}",
// attach.ItemID, attach.AssetID, attach.AttachPoint);
//m_log.DebugFormat(
// "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}",
// attach.ItemID, attach.AssetID, attach.AttachPoint);
lock (m_attachments)
{
@ -551,7 +544,7 @@ namespace OpenSim.Framework
foreach (AvatarAttachment prev in m_attachments[attach.AttachPoint])
{
if (prev.ItemID == attach.ItemID)
if (prev.ItemID.Equals(attach.ItemID))
return;
}
@ -561,9 +554,9 @@ namespace OpenSim.Framework
internal void ReplaceAttachment(AvatarAttachment attach)
{
// m_log.DebugFormat(
// "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}",
// attach.ItemID, attach.AssetID, attach.AttachPoint);
//m_log.DebugFormat(
// "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}",
// attach.ItemID, attach.AssetID, attach.AttachPoint);
lock (m_attachments)
{
@ -589,9 +582,9 @@ namespace OpenSim.Framework
/// </returns>
public bool SetAttachment(int attachpoint, UUID item, UUID asset)
{
// m_log.DebugFormat(
// "[AVATAR APPEARANCE]: Setting attachment at {0} with item ID {1}, asset ID {2}",
// attachpoint, item, asset);
//m_log.DebugFormat(
// "[AVATAR APPEARANCE]: Setting attachment at {0} with item ID {1}, asset ID {2}",
// attachpoint, item, asset);
if (attachpoint == 0)
return false;
@ -599,15 +592,7 @@ namespace OpenSim.Framework
lock (m_attachments)
{
if (item.IsZero())
{
if (m_attachments.ContainsKey(attachpoint))
{
m_attachments.Remove(attachpoint);
return true;
}
return false;
}
return m_attachments.Remove(attachpoint);
// When a user logs in, the attachment item ids are pulled from persistence in the Avatars table. However,
// the asset ids are not saved. When the avatar enters a simulator the attachments are set again. If
@ -665,7 +650,7 @@ namespace OpenSim.Framework
{
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID.Equals(itemID); });
if (index >= 0)
return kvp.Value[index];
}
@ -680,7 +665,7 @@ namespace OpenSim.Framework
{
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID.Equals(itemID); });
if (index >= 0)
return kvp.Key;
}
@ -694,12 +679,12 @@ namespace OpenSim.Framework
{
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID.Equals(itemID); });
if (index >= 0)
{
// m_log.DebugFormat(
// "[AVATAR APPEARANCE]: Detaching attachment {0}, index {1}, point {2}",
// m_attachments[kvp.Key][index].ItemID, index, m_attachments[kvp.Key][index].AttachPoint);
//m_log.DebugFormat(
// "[AVATAR APPEARANCE]: Detaching attachment {0}, index {1}, point {2}",
// m_attachments[kvp.Key][index].ItemID, index, m_attachments[kvp.Key][index].AttachPoint);
// Remove it from the list of attachments at that attach point
m_attachments[kvp.Key].RemoveAt(index);
@ -847,7 +832,7 @@ namespace OpenSim.Framework
int idx = BAKE_INDICES[i];
if (m_texture.FaceTextures[idx] == null)
continue;
if (m_texture.FaceTextures[idx].TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE ||
if (m_texture.FaceTextures[idx].TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE) ||
m_texture.FaceTextures[idx].TextureID.IsZero())
continue;
needExtra = true;
@ -1004,9 +989,9 @@ namespace OpenSim.Framework
AvatarAttachment att = new AvatarAttachment((OSDMap)attachs[i]);
AppendAttachment(att);
// m_log.DebugFormat(
// "[AVATAR APPEARANCE]: Unpacked attachment itemID {0}, assetID {1}, point {2}",
// att.ItemID, att.AssetID, att.AttachPoint);
//m_log.DebugFormat(
// "[AVATAR APPEARANCE]: Unpacked attachment itemID {0}, assetID {1}, point {2}",
// att.ItemID, att.AssetID, att.AttachPoint);
}
}
}
@ -1036,7 +1021,8 @@ namespace OpenSim.Framework
int idx = BAKE_INDICES[i];
if (m_texture.FaceTextures[idx] == null)
continue;
if (m_texture.FaceTextures[idx].TextureID.IsZero() || m_texture.FaceTextures[idx].TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE))
if (m_texture.FaceTextures[idx].TextureID.IsZero() ||
m_texture.FaceTextures[idx].TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE))
continue;
return false;
}

View file

@ -541,10 +541,10 @@ namespace OpenSim.Framework
args["controllers"] = controls;
}
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
if (!string.IsNullOrEmpty(CallbackURI))
args["callback_uri"] = OSD.FromString(CallbackURI);
if ((NewCallbackURI != null) && (!NewCallbackURI.Equals("")))
if (!string.IsNullOrEmpty(NewCallbackURI))
args["cb_uri"] = OSD.FromString(NewCallbackURI);
// Attachment objects for fatpack messages
@ -775,7 +775,7 @@ namespace OpenSim.Framework
// packed_appearence should contain all appearance information
if (args.TryGetValue("packed_appearance", out tmp) && tmp is OSDMap)
{
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance");
//m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance");
Appearance = new AvatarAppearance((OSDMap)tmp);
}
else

View file

@ -47,10 +47,14 @@ namespace OpenSim.Framework
public const int MinRegionSize = 256;
public const int TerrainPatchSize = 16;
public const int LandUnit = 4; // parcels only have sizes multiple of this
public const float MinSimulationHeight = -100f;
public const float MaxSimulationHeight = 50000f;
public const float MinTerrainHeightmap = -100f;
public const float MaxTerrainHeightmap = 4000f;
public const float MinWaterHeight = 0;
public const float MaxWaterHeight = 8000f;
public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f";

View file

@ -41,6 +41,7 @@ namespace OpenSim.Framework
private ReaderWriterLockSlim m_rwLock;
private readonly Dictionary<TKey1, int> m_expireControl;
private readonly Dictionary<TKey1, TValue1> m_values;
TValue1[] valuesArrayCache = null;
private readonly double m_startTS;
private readonly int m_expire;
@ -142,6 +143,7 @@ namespace OpenSim.Framework
gotWriteLock = true;
}
valuesArrayCache = null;
foreach (TKey1 key in expired)
{
m_expireControl.Remove(key);
@ -190,6 +192,7 @@ namespace OpenSim.Framework
m_expireControl[key] = now;
m_values[key] = val;
valuesArrayCache = null;
CheckTimer();
}
finally
@ -234,6 +237,7 @@ namespace OpenSim.Framework
m_expireControl[key] = now;
m_values[key] = val;
valuesArrayCache = null;
CheckTimer();
}
finally
@ -258,7 +262,9 @@ namespace OpenSim.Framework
}
success = m_expireControl.Remove(key);
success |= m_values.Remove(key);
if(m_expireControl.Count == 0)
if(success)
valuesArrayCache = null;
if (m_expireControl.Count == 0)
DisposeTimer();
}
finally
@ -285,6 +291,7 @@ namespace OpenSim.Framework
DisposeTimer();
m_expireControl.Clear();
m_values.Clear();
valuesArrayCache = null;
}
finally
{
@ -381,9 +388,7 @@ namespace OpenSim.Framework
public bool TryGetValue(TKey1 key, out TValue1 value)
{
bool success;
bool gotLock = false;
try
{
try {}
@ -393,15 +398,13 @@ namespace OpenSim.Framework
gotLock = true;
}
success = m_values.TryGetValue(key, out value);
return m_values.TryGetValue(key, out value);
}
finally
{
if (gotLock)
m_rwLock.ExitReadLock();
}
return success;
}
public bool TryGetValue(TKey1 key, int expireMS, out TValue1 value)
@ -457,7 +460,7 @@ namespace OpenSim.Framework
return success;
}
public ICollection<TValue1> Values
public TValue1[] Values
{
get
{
@ -470,7 +473,12 @@ namespace OpenSim.Framework
m_rwLock.EnterUpgradeableReadLock();
gotLock = true;
}
return m_values.Values;
if(valuesArrayCache == null)
{
valuesArrayCache = new TValue1[m_values.Count];
m_values.Values.CopyTo(valuesArrayCache, 0);
}
return valuesArrayCache;
}
finally
{
@ -480,6 +488,7 @@ namespace OpenSim.Framework
}
}
/*
public ICollection<TKey1> Keys
{
get
@ -502,5 +511,6 @@ namespace OpenSim.Framework
}
}
}
*/
}
}

View file

@ -50,7 +50,7 @@ namespace OpenSim.Framework
public GridInstantMessage()
{
binaryBucket = new byte[0];
binaryBucket = Array.Empty<byte>(); ;
}
public GridInstantMessage(GridInstantMessage im, bool addTimestamp)
@ -108,7 +108,7 @@ namespace OpenSim.Framework
string _message, bool _offline,
Vector3 _position) : this(scene, _fromAgentID, _fromAgentName,
_toAgentID, _dialog, false, _message,
_fromAgentID ^ _toAgentID, _offline, _position, new byte[0], true)
_fromAgentID ^ _toAgentID, _offline, _position, Array.Empty<byte>(), true)
{
}
}

View file

@ -757,6 +757,7 @@ namespace OpenSim.Framework
event DeRezObject OnDeRezObject;
event RezRestoreToWorld OnRezRestoreToWorld;
event Action<IClientAPI> OnRegionHandShakeReply;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")]
event GenericCall1 OnRequestWearables;
event Action<IClientAPI, bool> OnCompleteMovementToRegion;
@ -1086,7 +1087,6 @@ namespace OpenSim.Framework
void SendLayerData(int[] map);
void SendWindData(int version, Vector2[] windSpeeds);
void SendCloudData(int version, float[] cloudCover);
/// <summary>
/// Sent when an agent completes its movement into a region.

View file

@ -35,7 +35,7 @@ namespace OpenSim.Framework
{
public class InventoryFolderImpl : InventoryFolderBase
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public static readonly string PATH_DELIMITER = "/";
@ -77,12 +77,14 @@ namespace OpenSim.Framework
{
if (!m_childFolders.ContainsKey(folderID))
{
InventoryFolderImpl subFold = new InventoryFolderImpl();
subFold.Name = folderName;
subFold.ID = folderID;
subFold.Type = (short)type;
subFold.ParentID = this.ID;
subFold.Owner = Owner;
InventoryFolderImpl subFold = new InventoryFolderImpl()
{
Name = folderName,
ID = folderID,
Type = (short)type,
ParentID = this.ID,
Owner = Owner
};
m_childFolders.Add(subFold.ID, subFold);
return subFold;
@ -122,14 +124,11 @@ namespace OpenSim.Framework
/// <returns>The folder if it exists, null if it doesn't</returns>
public InventoryFolderImpl GetChildFolder(UUID folderID)
{
InventoryFolderImpl folder = null;
lock (m_childFolders)
{
m_childFolders.TryGetValue(folderID, out folder);
m_childFolders.TryGetValue(folderID, out InventoryFolderImpl folder);
return folder;
}
return folder;
}
/// <summary>
@ -141,18 +140,15 @@ namespace OpenSim.Framework
/// </returns>
public InventoryFolderImpl RemoveChildFolder(UUID folderID)
{
InventoryFolderImpl removedFolder = null;
lock (m_childFolders)
{
if (m_childFolders.ContainsKey(folderID))
if (m_childFolders.TryGetValue(folderID, out InventoryFolderImpl removedFolder))
{
removedFolder = m_childFolders[folderID];
m_childFolders.Remove(folderID);
return removedFolder;
}
}
return removedFolder;
return null;
}
/// <summary>
@ -178,10 +174,8 @@ namespace OpenSim.Framework
{
lock (Items)
{
if (Items.ContainsKey(itemID))
{
return Items[itemID];
}
if (Items.TryGetValue(itemID, out InventoryItemBase it))
return it;
}
lock (m_childFolders)
@ -189,14 +183,10 @@ namespace OpenSim.Framework
foreach (InventoryFolderImpl folder in m_childFolders.Values)
{
InventoryItemBase item = folder.FindItem(itemID);
if (item != null)
{
return item;
}
}
}
return null;
}
@ -206,7 +196,7 @@ namespace OpenSim.Framework
{
foreach (InventoryItemBase item in Items.Values)
{
if (item.AssetID == assetID)
if (item.AssetID.Equals(assetID))
return item;
}
}
@ -216,11 +206,8 @@ namespace OpenSim.Framework
foreach (InventoryFolderImpl folder in m_childFolders.Values)
{
InventoryItemBase item = folder.FindAsset(assetID);
if (item != null)
{
return item;
}
}
}
@ -234,31 +221,21 @@ namespace OpenSim.Framework
/// <returns></returns>
public bool DeleteItem(UUID itemID)
{
bool found = false;
lock (Items)
{
if (Items.ContainsKey(itemID))
{
Items.Remove(itemID);
if (Items.Remove(itemID))
return true;
}
}
lock (m_childFolders)
{
foreach (InventoryFolderImpl folder in m_childFolders.Values)
{
found = folder.DeleteItem(itemID);
if (found == true)
{
break;
}
if(folder.DeleteItem(itemID))
return true;
}
}
return found;
return false;
}
/// <summary>
@ -268,7 +245,7 @@ namespace OpenSim.Framework
/// <returns>The requested folder if it exists, null if it does not.</returns>
public InventoryFolderImpl FindFolder(UUID folderID)
{
if (folderID == ID)
if (folderID.Equals(ID))
return this;
lock (m_childFolders)
@ -276,12 +253,10 @@ namespace OpenSim.Framework
foreach (InventoryFolderImpl folder in m_childFolders.Values)
{
InventoryFolderImpl returnFolder = folder.FindFolder(folderID);
if (returnFolder != null)
return returnFolder;
}
}
return null;
}
@ -322,11 +297,10 @@ namespace OpenSim.Framework
/// <returns>null if the folder is not found</returns>
public InventoryFolderImpl FindFolderByPath(string path)
{
path = path.Trim();
if (path.Length == 0)
return this;
path = path.Trim();
if (path == PATH_DELIMITER)
return this;
@ -404,9 +378,9 @@ namespace OpenSim.Framework
{
foreach (InventoryItemBase item in Items.Values)
{
// m_log.DebugFormat(
// "[INVENTORY FOLDER IMPL]: Returning item {0} {1}, OwnerPermissions {2:X}",
// item.Name, item.ID, item.CurrentPermissions);
//m_log.DebugFormat(
// "[INVENTORY FOLDER IMPL]: Returning item {0} {1}, OwnerPermissions {2:X}",
// item.Name, item.ID, item.CurrentPermissions);
itemList.Add(item);
}
@ -422,7 +396,7 @@ namespace OpenSim.Framework
/// </summary>
public List<InventoryFolderBase> RequestListOfFolders()
{
List<InventoryFolderBase> folderList = new List<InventoryFolderBase>();
List<InventoryFolderBase> folderList = new List<InventoryFolderBase>(m_childFolders.Count);
lock (m_childFolders)
{
@ -437,7 +411,7 @@ namespace OpenSim.Framework
public List<InventoryFolderImpl> RequestListOfFolderImpls()
{
List<InventoryFolderImpl> folderList = new List<InventoryFolderImpl>();
List<InventoryFolderImpl> folderList = new List<InventoryFolderImpl>(m_childFolders.Count);
lock (m_childFolders)
{
@ -459,12 +433,10 @@ namespace OpenSim.Framework
get
{
int total = Items.Count;
foreach (InventoryFolderImpl folder in m_childFolders.Values)
{
total = total + folder.TotalCount;
total += folder.TotalCount;
}
return total;
}
}

View file

@ -906,7 +906,7 @@ namespace OpenSim.Framework
{
OSDMap args = new OSDMap();
args["region_id"] = OSD.FromUUID(RegionID);
if ((RegionName != null) && !RegionName.Equals(""))
if (!string.IsNullOrEmpty(RegionName))
args["region_name"] = OSD.FromString(RegionName);
args["external_host_name"] = OSD.FromString(ExternalHostName);
args["http_port"] = OSD.FromString(HttpPort.ToString());
@ -920,10 +920,10 @@ namespace OpenSim.Framework
args["internal_ep_address"] = OSD.FromString(InternalEndPoint.Address.ToString());
args["internal_ep_port"] = OSD.FromString(InternalEndPoint.Port.ToString());
if ((RemotingAddress != null) && !RemotingAddress.Equals(""))
if (!string.IsNullOrEmpty(RemotingAddress))
args["remoting_address"] = OSD.FromString(RemotingAddress);
args["remoting_port"] = OSD.FromString(RemotingPort.ToString());
if ((proxyUrl != null) && !proxyUrl.Equals(""))
if (!string.IsNullOrEmpty(proxyUrl))
args["proxy_url"] = OSD.FromString(proxyUrl);
if (RegionType != String.Empty)
args["region_type"] = OSD.FromString(RegionType);

View file

@ -280,77 +280,77 @@ namespace OpenSim.Framework
public double Elevation1NW
{
get { return m_Elevation1NW; }
set { m_Elevation1NW = value; }
set { m_Elevation1NW = Utils.Clamp(value, Constants.MinTerrainHeightmap, Constants.MaxTerrainHeightmap); ; }
}
private double m_Elevation2NW = 60;
public double Elevation2NW
{
get { return m_Elevation2NW; }
set { m_Elevation2NW = value; }
set { m_Elevation2NW = Utils.Clamp(value, Constants.MinTerrainHeightmap, Constants.MaxTerrainHeightmap); ; }
}
private double m_Elevation1NE = 10;
public double Elevation1NE
{
get { return m_Elevation1NE; }
set { m_Elevation1NE = value; }
set { m_Elevation1NE = Utils.Clamp(value, Constants.MinTerrainHeightmap, Constants.MaxTerrainHeightmap); ; }
}
private double m_Elevation2NE = 60;
public double Elevation2NE
{
get { return m_Elevation2NE; }
set { m_Elevation2NE = value; }
set { m_Elevation2NE = Utils.Clamp(value, Constants.MinTerrainHeightmap, Constants.MaxTerrainHeightmap); ; }
}
private double m_Elevation1SE = 10;
public double Elevation1SE
{
get { return m_Elevation1SE; }
set { m_Elevation1SE = value; }
set { m_Elevation1SE = Utils.Clamp(value, Constants.MinTerrainHeightmap, Constants.MaxTerrainHeightmap); ; }
}
private double m_Elevation2SE = 60;
public double Elevation2SE
{
get { return m_Elevation2SE; }
set { m_Elevation2SE = value; }
set { m_Elevation2SE = Utils.Clamp(value, Constants.MinTerrainHeightmap, Constants.MaxTerrainHeightmap); ; }
}
private double m_Elevation1SW = 10;
public double Elevation1SW
{
get { return m_Elevation1SW; }
set { m_Elevation1SW = value; }
set { m_Elevation1SW = Utils.Clamp(value, Constants.MinTerrainHeightmap, Constants.MaxTerrainHeightmap); ; }
}
private double m_Elevation2SW = 60;
public double Elevation2SW
{
get { return m_Elevation2SW; }
set { m_Elevation2SW = value; }
set { m_Elevation2SW = Utils.Clamp(value, Constants.MinTerrainHeightmap, Constants.MaxTerrainHeightmap); ; }
}
private double m_WaterHeight = 20;
public double WaterHeight
{
get { return m_WaterHeight; }
set { m_WaterHeight = value; }
set { m_WaterHeight = Utils.Clamp(value, Constants.MinWaterHeight, Constants.MaxWaterHeight); }
}
private double m_TerrainRaiseLimit = 100;
public double TerrainRaiseLimit
{
get { return m_TerrainRaiseLimit; }
set { m_TerrainRaiseLimit = value; }
set { m_TerrainRaiseLimit = Utils.Clamp(value, 0, 200f); }
}
private double m_TerrainLowerLimit = -100;
public double TerrainLowerLimit
{
get { return m_TerrainLowerLimit; }
set { m_TerrainLowerLimit = value; }
set { m_TerrainLowerLimit = Utils.Clamp(value, -200f, 0);}
}
private bool m_UseEstateSun = true;

View file

@ -140,10 +140,12 @@ namespace OpenSim.Framework
switch (tmpSlice.ToString())
{
case "http":
case "hg":
case "hop":
case "http":
case "surl":
case "x-grid-info":
// only https has this defined
if (issecure)
{
Schema = "https://";

View file

@ -61,7 +61,7 @@ namespace OpenSim.Framework.Serialization
if (!dirName.EndsWith("/"))
dirName += "/";
WriteFile(dirName, new byte[0]);
WriteFile(dirName, Array.Empty<byte>());
}
/// <summary>

View file

@ -1615,7 +1615,7 @@ namespace OpenSim.Framework.Servers.HttpServer
return null;
}
byte[] buffer = new byte[0];
byte[] buffer = Array.Empty<byte>();
if (llsdResponse.ToString() == "shutdown404!")
{
response.ContentType = "text/plain";
@ -2434,7 +2434,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
if (httpRequest.QueryFlags.Contains("about"))
{
httpResponse.Redirect("http://opensimulator.org/wiki/0.9.2.1_Release");
httpResponse.Redirect("http://opensimulator.org/wiki/0.9.2.2_Release");
return;
}
if (!httpRequest.QueryAsDictionary.TryGetValue("method", out string methods) || string.IsNullOrWhiteSpace(methods))

View file

@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Net;
using OpenSim.Framework.ServiceAuth;
@ -65,7 +66,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{
httpResponse.StatusCode = (int)statusCode;
httpResponse.ContentType = "text/plain";
return new byte[0];
return Array.Empty<byte>();
}
}

View file

@ -24,7 +24,8 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenSim.Framework;
using System;
using System.IO;
namespace OpenSim.Framework.Servers.HttpServer
@ -78,7 +79,7 @@ namespace OpenSim.Framework.Servers.HttpServer
protected virtual byte[] ThrottledRequest(
string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
return new byte[0];
return Array.Empty<byte>();
}

View file

@ -182,9 +182,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
data = response;
return true;
}
}
}

View file

@ -1,4 +1,5 @@
using System;
using OpenMetaverse;
namespace OSHttpServer.Parser
{
@ -7,16 +8,8 @@ namespace OSHttpServer.Parser
/// </summary>
public class HeaderEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="HeaderEventArgs"/> class.
/// </summary>
/// <param name="name">Name of header.</param>
/// <param name="value">Header value.</param>
public HeaderEventArgs(string name, string value)
{
Name = name;
Value = value;
}
public osUTF8Slice Name;
public string Value;
/// <summary>
/// Initializes a new instance of the <see cref="HeaderEventArgs"/> class.
@ -26,13 +19,14 @@ namespace OSHttpServer.Parser
}
/// <summary>
/// Gets or sets header name.
/// Initializes a new instance of the <see cref="HeaderEventArgs"/> class.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets or sets header value.
/// </summary>
public string Value { get; set; }
/// <param name="name">Name of header.</param>
/// <param name="value">Header value.</param>
public HeaderEventArgs(osUTF8Slice name, string value)
{
Name = name;
Value = value;
}
}
}

View file

@ -8,6 +8,7 @@ using OSHttpServer.Exceptions;
using OSHttpServer.Parser;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using OpenMetaverse;
namespace OSHttpServer
{
@ -165,6 +166,7 @@ namespace OSHttpServer
m_currentRequest.AddToBody(e.Buffer, e.Offset, e.Count);
}
private static readonly byte[] OSUTF8expect = osUTF8.GetASCIIBytes("expect");
/// <summary>
///
/// </summary>
@ -172,7 +174,7 @@ namespace OSHttpServer
/// <param name="e"></param>
protected virtual void OnHeaderReceived(object sender, HeaderEventArgs e)
{
if (string.Compare(e.Name, "expect", true) == 0 && e.Value.Contains("100-continue"))
if (e.Name.ACSIILowerEquals(OSUTF8expect) && e.Value.Contains("100-continue"))
{
lock (m_requestsLock)
{
@ -180,7 +182,7 @@ namespace OSHttpServer
Respond("HTTP/1.1", HttpStatusCode.Continue, null);
}
}
m_currentRequest.AddHeader(e.Name, e.Value);
m_currentRequest.AddHeader(e.Name.ToString(), e.Value);
}
private void OnRequestLine(object sender, RequestLineEventArgs e)

View file

@ -33,7 +33,7 @@ namespace OSHttpServer
/// <param name="name">form name.</param>
/// <param name="ignoreChanges">if set to <c>true</c> all changes will be ignored. </param>
/// <remarks>this constructor should only be used by Empty</remarks>
protected HttpInput(string name, bool ignoreChanges)
protected HttpInput(string name, bool ignoreChanges)
{
_name = name;
_ignoreChanges = ignoreChanges;

View file

@ -17,18 +17,18 @@ namespace OSHttpServer
/// </remarks>
public class HttpInputItem : IHttpInput
{
/// <summary> Representation of a non-initialized <see cref="HttpInputItem"/>.</summary>
/// <summary> Representation of a non-initialized <see cref="HttpInputItem"/>.</summary>
public static readonly HttpInputItem Empty = new HttpInputItem(string.Empty, true);
private readonly IDictionary<string, HttpInputItem> _items = new Dictionary<string, HttpInputItem>();
private readonly List<string> _values = new List<string>();
private string _name;
private readonly bool _ignoreChanges;
/// <summary>
/// Initializes an input item setting its name/identifier and value
/// </summary>
/// <param name="name">Parameter name/id</param>
/// <param name="value">Parameter value</param>
/// <summary>
/// Initializes an input item setting its name/identifier and value
/// </summary>
/// <param name="name">Parameter name/id</param>
/// <param name="value">Parameter value</param>
public HttpInputItem(string name, string value)
{
Name = name;
@ -41,20 +41,20 @@ namespace OSHttpServer
_ignoreChanges = ignore;
}
/// <summary>Creates a deep copy of the item specified</summary>
/// <param name="item">The item to copy</param>
/// <remarks>The function makes a deep copy of quite a lot which can be slow</remarks>
public HttpInputItem(HttpInputItem item)
{
foreach (KeyValuePair<string, HttpInputItem> pair in item._items)
_items.Add(pair.Key, pair.Value);
foreach (string value in item._values)
_values.Add(value);
_ignoreChanges = item._ignoreChanges;
_name = item.Name;
}
/// <summary>Creates a deep copy of the item specified</summary>
/// <param name="item">The item to copy</param>
/// <remarks>The function makes a deep copy of quite a lot which can be slow</remarks>
public HttpInputItem(HttpInputItem item)
{
foreach (KeyValuePair<string, HttpInputItem> pair in item._items)
_items.Add(pair.Key, pair.Value);
foreach (string value in item._values)
_values.Add(value);
_ignoreChanges = item._ignoreChanges;
_name = item.Name;
}
/// <summary>
/// Number of values
@ -147,16 +147,16 @@ namespace OSHttpServer
return _items.ContainsKey(name) && _items[name].Value != null;
}
/// <summary> Returns a formatted representation of the instance with the values of all contained parameters </summary>
/// <summary> Returns a formatted representation of the instance with the values of all contained parameters </summary>
public override string ToString()
{
return ToString(string.Empty);
}
/// <summary>
/// Outputs the string in a formatted manner
/// </summary>
/// <param name="prefix">A prefix to append, used internally</param>
/// <summary>
/// Outputs the string in a formatted manner
/// </summary>
/// <param name="prefix">A prefix to append, used internally</param>
/// <param name="asQuerySting">produce a query string</param>
public string ToString(string prefix, bool asQuerySting)
{

View file

@ -15,7 +15,11 @@ namespace OSHttpServer
private readonly IHttpContextFactory m_contextFactory;
private readonly int m_port;
private readonly ManualResetEvent m_shutdownEvent = new ManualResetEvent(false);
private readonly SslProtocols m_sslProtocol = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3 | SslProtocols.Ssl2;
#if NET48
private readonly SslProtocols m_sslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13 | SslProtocols.Ssl3 | SslProtocols.Ssl2;
#else
private readonly SslProtocols m_sslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3 | SslProtocols.Ssl2;
#endif
private TcpListener m_listener;
private ILogWriter m_logWriter = NullLogWriter.Instance;
private int m_pendingAccepts;
@ -62,13 +66,13 @@ namespace OSHttpServer
/// <param name="port">TCP Port to listen on, default HTTPS port is 443</param>
/// <param name="factory">Factory used to create <see cref="IHttpClientContext"/>es.</param>
/// <param name="certificate">Certificate to use</param>
/// <param name="protocol">which HTTPS protocol to use, default is TLS.</param>
/// <param name="protocols">which HTTPS protocol to use, default is TLS.</param>
protected OSHttpListener(IPAddress address, int port, X509Certificate certificate,
SslProtocols protocol)
SslProtocols protocols)
: this(address, port)
{
m_certificate = certificate;
m_sslProtocol = protocol;
m_sslProtocols = protocols;
}
public static OSHttpListener Create(IPAddress address, int port)
@ -81,9 +85,9 @@ namespace OSHttpServer
return new OSHttpListener(address, port, certificate);
}
public static OSHttpListener Create(IPAddress address, int port, X509Certificate certificate, SslProtocols protocol)
public static OSHttpListener Create(IPAddress address, int port, X509Certificate certificate, SslProtocols protocols)
{
return new OSHttpListener(address, port, certificate, protocol);
return new OSHttpListener(address, port, certificate, protocols);
}
private void OnRequestReceived(object sender, RequestEventArgs e)
@ -110,7 +114,7 @@ namespace OSHttpServer
m_logWriter = value ?? NullLogWriter.Instance;
if (m_certificate != null)
m_logWriter.Write(this, LogPrio.Info,
"HTTPS(" + m_sslProtocol + ") listening on " + m_address + ":" + m_port);
"HTTPS(" + m_sslProtocols + ") listening on " + m_address + ":" + m_port);
else
m_logWriter.Write(this, LogPrio.Info, "HTTP listening on " + m_address + ":" + m_port);
}
@ -159,7 +163,7 @@ namespace OSHttpServer
m_logWriter.Write(this, LogPrio.Debug, "Accepted connection from: " + socket.RemoteEndPoint);
if (m_certificate != null)
m_contextFactory.CreateSecureContext(socket, m_certificate, m_sslProtocol, m_clientCertValCallback);
m_contextFactory.CreateSecureContext(socket, m_certificate, m_sslProtocols, m_clientCertValCallback);
else
m_contextFactory.CreateContext(socket);
}

View file

@ -17,7 +17,7 @@ namespace OSHttpServer
private List<HttpInputItem> _items = new List<HttpInputItem>();
/// <summary>Initialises the class to hold a value either from a post request or a querystring request</summary>
/// <summary>Initialises the class to hold a value either from a post request or a querystring request</summary>
public HttpParam(IHttpInput form, IHttpInput query)
{
m_form = form;

View file

@ -1,6 +1,7 @@
using System;
using System.Text;
using OSHttpServer.Exceptions;
using OpenMetaverse;
namespace OSHttpServer.Parser
{
@ -13,8 +14,8 @@ namespace OSHttpServer.Parser
private readonly HeaderEventArgs m_headerArgs = new HeaderEventArgs();
private readonly BodyEventArgs m_bodyEventArgs = new BodyEventArgs();
private readonly RequestLineEventArgs m_requestLineArgs = new RequestLineEventArgs();
private string m_curHeaderName = string.Empty;
private string m_curHeaderValue = string.Empty;
private osUTF8Slice m_curHeaderName = new osUTF8Slice();
private osUTF8Slice m_curHeaderValue = new osUTF8Slice();
private int m_bodyBytesLeft;
/// <summary>
@ -81,8 +82,8 @@ namespace OSHttpServer.Parser
public void Clear()
{
m_bodyBytesLeft = 0;
m_curHeaderName = string.Empty;
m_curHeaderValue = string.Empty;
m_curHeaderName.Clear();
m_curHeaderValue.Clear();
CurrentState = RequestParserState.FirstLine;
}
@ -153,6 +154,7 @@ namespace OSHttpServer.Parser
}
}
private static readonly byte[] OSUTF8contentlength = osUTF8.GetASCIIBytes("content-length");
/// <summary>
/// We've parsed a new header.
/// </summary>
@ -161,21 +163,23 @@ namespace OSHttpServer.Parser
/// <exception cref="BadRequestException">If content length cannot be parsed.</exception>
protected void OnHeader()
{
if (string.Compare(m_curHeaderName, "content-length", true) == 0)
if (m_curHeaderName.ACSIILowerEquals(OSUTF8contentlength))
{
if (!int.TryParse(m_curHeaderValue, out m_bodyBytesLeft))
if (!m_curHeaderValue.TryParseInt(out m_bodyBytesLeft))
throw new BadRequestException("Content length is not a number.");
if(m_bodyBytesLeft > 64 * 1024 * 1204)
throw new BadRequestException("Content length too large.");
}
if (HeaderReceived != null)
{
m_headerArgs.Name = m_curHeaderName;
m_headerArgs.Value = m_curHeaderValue;
m_headerArgs.Value = m_curHeaderValue.ToString();
HeaderReceived?.Invoke(this, m_headerArgs);
}
m_curHeaderName = string.Empty;
m_curHeaderValue = string.Empty;
m_curHeaderName.Clear();
m_curHeaderValue.Clear();
}
private void OnRequestCompleted()
@ -288,7 +292,7 @@ namespace OSHttpServer.Parser
"Expected header name, got colon on line " + currentLine);
throw new BadRequestException("Expected header name, got colon on line " + currentLine);
}
m_curHeaderName = Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos);
m_curHeaderName = new osUTF8Slice(buffer, startPos, currentPos - startPos);
handledBytes = currentPos + 1;
startPos = handledBytes;
if (ch == ':')
@ -374,8 +378,13 @@ namespace OSHttpServer.Parser
&& (buffer[currentPos + newLineSize] == ' ' || buffer[currentPos + newLineSize] == '\t'))
{
if (startPos != -1)
m_curHeaderValue += Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos);
{
osUTF8Slice osUTF8SliceTmp = new osUTF8Slice(buffer, startPos, currentPos - startPos);
if (m_curHeaderValue.Length == 0)
m_curHeaderValue = osUTF8SliceTmp.Clone();
else
m_curHeaderValue.Append(osUTF8SliceTmp);
}
m_log.Write(this, LogPrio.Trace, "Header value is on multiple lines.");
CurrentState = RequestParserState.Between;
currentPos += newLineSize - 1;
@ -384,8 +393,14 @@ namespace OSHttpServer.Parser
}
else
{
m_curHeaderValue += Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos);
osUTF8Slice osUTF8SliceTmp = new osUTF8Slice(buffer, startPos, currentPos - startPos);
if (m_curHeaderValue.Length == 0)
m_curHeaderValue = osUTF8SliceTmp.Clone();
else
m_curHeaderValue.Append(osUTF8SliceTmp);
m_log.Write(this, LogPrio.Trace, "Header [" + m_curHeaderName + ": " + m_curHeaderValue + "]");
OnHeader();
startPos = -1;

View file

@ -49,15 +49,15 @@ namespace OSHttpServer
/// </summary>
event EventHandler<HeaderEventArgs> HeaderReceived;
/// <summary>
/// Clear parser state.
/// </summary>
void Clear();
/// <summary>
/// Clear parser state.
/// </summary>
void Clear();
/// <summary>
/// Gets or sets the log writer.
/// </summary>
ILogWriter LogWriter { get; set; }
/// <summary>
/// Gets or sets the log writer.
/// </summary>
ILogWriter LogWriter { get; set; }
}
/// <summary>

View file

@ -146,10 +146,10 @@ namespace OSHttpServer
#endregion
/// <summary>
/// Remove a cookie from the collection.
/// </summary>
/// <param name="cookieName">Name of cookie.</param>
/// <summary>
/// Remove a cookie from the collection.
/// </summary>
/// <param name="cookieName">Name of cookie.</param>
public void Remove(string cookieName)
{
lock (_items)

View file

@ -580,7 +580,8 @@ namespace OpenSim.Framework.Servers.HttpServer
_receiveDone.Set();
_initialMsgTimeout = 0;
}
WebSocketFrame pingFrame = new WebSocketFrame() { Header = WebsocketFrameHeader.HeaderDefault(), WebSocketPayload = new byte[0] };
WebSocketFrame pingFrame = new WebSocketFrame() { Header = WebsocketFrameHeader.HeaderDefault(), WebSocketPayload = Array.Empty<byte>()
};
pingFrame.Header.Opcode = WebSocketReader.OpCode.Ping;
pingFrame.Header.IsEnd = true;
_pingtime = Util.EnvironmentTickCount();
@ -651,7 +652,7 @@ namespace OpenSim.Framework.Servers.HttpServer
pingD(this, new PingEventArgs());
}
WebSocketFrame pongFrame = new WebSocketFrame(){Header = WebsocketFrameHeader.HeaderDefault(),WebSocketPayload = new byte[0]};
WebSocketFrame pongFrame = new WebSocketFrame(){Header = WebsocketFrameHeader.HeaderDefault(),WebSocketPayload = Array.Empty<byte>()};
pongFrame.Header.Opcode = WebSocketReader.OpCode.Pong;
pongFrame.Header.IsEnd = true;
SendSocket(pongFrame.ToBytes());
@ -960,7 +961,7 @@ dec 0 1 2 3
* When reading these, the frames are possibly fragmented and interleaved with control frames
* the fragmented frames are not interleaved with data frames. Just control frames
*/
public static readonly WebSocketFrame DefaultFrame = new WebSocketFrame(){Header = new WebsocketFrameHeader(),WebSocketPayload = new byte[0]};
public static readonly WebSocketFrame DefaultFrame = new WebSocketFrame(){Header = new WebsocketFrameHeader(),WebSocketPayload = Array.Empty<byte>()};
public WebsocketFrameHeader Header;
public byte[] WebSocketPayload;

View file

@ -520,13 +520,10 @@ namespace OpenSim.Framework.Servers
public virtual void HandleShow(string module, string[] cmd)
{
List<string> args = new List<string>(cmd);
if(cmd.Length < 2)
return;
args.RemoveAt(0);
string[] showParams = args.ToArray();
switch (showParams[0])
switch (cmd[1])
{
case "info":
ShowInfo();
@ -553,18 +550,14 @@ namespace OpenSim.Framework.Servers
/// <param name="cmd"></param>
private void HandleConfig(string module, string[] cmd)
{
List<string> args = new List<string>(cmd);
args.RemoveAt(0);
string[] cmdparams = args.ToArray();
if (cmdparams.Length > 0)
if (cmd.Length > 1)
{
string firstParam = cmdparams[0].ToLower();
string firstParam = cmd[1].ToLower();
switch (firstParam)
{
case "set":
if (cmdparams.Length < 4)
if (cmd.Length < 5)
{
Notice("Syntax: config set <section> <key> <value>");
Notice("Example: config set ScriptEngine.DotNetEngine NumberOfScriptThreads 5");
@ -573,21 +566,21 @@ namespace OpenSim.Framework.Servers
{
IConfig c;
IConfigSource source = new IniConfigSource();
c = source.AddConfig(cmdparams[1]);
c = source.AddConfig(cmd[2]);
if (c != null)
{
string _value = String.Join(" ", cmdparams, 3, cmdparams.Length - 3);
c.Set(cmdparams[2], _value);
string _value = String.Join(" ", cmd, 4, cmd.Length - 4);
c.Set(cmd[3], _value);
Config.Merge(source);
Notice("In section [{0}], set {1} = {2}", c.Name, cmdparams[2], _value);
Notice("In section [{0}], set {1} = {2}", c.Name, cmd[3], _value);
}
}
break;
case "get":
case "show":
if (cmdparams.Length == 1)
if (cmd.Length == 2)
{
foreach (IConfig config in Config.Configs)
{
@ -597,17 +590,17 @@ namespace OpenSim.Framework.Servers
Notice(" {0} = {1}", key, config.GetString(key));
}
}
else if (cmdparams.Length == 2 || cmdparams.Length == 3)
else if (cmd.Length == 3 || cmd.Length == 4)
{
IConfig config = Config.Configs[cmdparams[1]];
IConfig config = Config.Configs[cmd[2]];
if (config == null)
{
Notice("Section \"{0}\" does not exist.",cmdparams[1]);
Notice("Section \"{0}\" does not exist.",cmd[2]);
break;
}
else
{
if (cmdparams.Length == 2)
if (cmd.Length == 3)
{
Notice("[{0}]", config.Name);
foreach (string key in config.GetKeys())
@ -617,7 +610,7 @@ namespace OpenSim.Framework.Servers
{
Notice(
"config get {0} {1} : {2}",
cmdparams[1], cmdparams[2], config.GetString(cmdparams[2]));
cmd[2], cmd[3], config.GetString(cmd[3]));
}
}
}
@ -630,13 +623,13 @@ namespace OpenSim.Framework.Servers
break;
case "save":
if (cmdparams.Length < 2)
if (cmd.Length < 3)
{
Notice("Syntax: config save <path>");
return;
}
string path = cmdparams[1];
string path = cmd[2];
Notice("Saving configuration file: {0}", path);
if (Config is IniConfigSource)

View file

@ -74,9 +74,12 @@ namespace OpenSim.Framework
private float[,] m_heightmap;
// Remember subregions of the heightmap that has changed.
private BitArray m_taint;
private int m_taintSizeX;
private int m_taintSizeY;
private TerrainTaintsArray m_taints;
private readonly int m_taintSizeX;
private readonly int m_taintSizeY;
private readonly int m_mapStride;
private readonly int m_mapPatchsStride;
// legacy CompressionFactor
public float CompressionFactor { get; private set; }
@ -107,7 +110,7 @@ namespace OpenSim.Framework
{
m_heightmap[x, y] = value;
int yy = y / Constants.TerrainPatchSize;
m_taint[x / Constants.TerrainPatchSize + yy * m_taintSizeX] = true;
m_taints.Set(x / Constants.TerrainPatchSize + yy * m_taintSizeX, true);
}
}
}
@ -118,19 +121,24 @@ namespace OpenSim.Framework
set { this[x, y] = value; }
}
public TerrainTaintsArray GetTaints()
{
return m_taints;
}
public void ClearTaint()
{
m_taint.SetAll(false);
m_taints.SetAll(false);
}
public void TaintAllTerrain()
{
m_taint.SetAll(true);
m_taints.SetAll(true);
}
private void SetAllTaint(bool setting)
{
m_taint.SetAll(setting);
m_taints.SetAll(setting);
}
public void ClearLand()
@ -145,6 +153,12 @@ namespace OpenSim.Framework
m_heightmap[xx, yy] = pHeight;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool IsTainted()
{
return m_taints.IsTaited();
}
// Return 'true' of the patch that contains these region coordinates has been modified.
// Note that checking the taint clears it.
// There is existing code that relies on this feature.
@ -153,59 +167,51 @@ namespace OpenSim.Framework
{
yy /= Constants.TerrainPatchSize;
int indx = xx / Constants.TerrainPatchSize + yy * m_taintSizeX;
bool ret = m_taint[indx];
if (ret && clearOnTest)
m_taint[indx] = false;
return ret;
return m_taints.Get(indx, clearOnTest);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool IsTaintedAt(int xx, int yy)
{
yy /= Constants.TerrainPatchSize;
return m_taint[xx / Constants.TerrainPatchSize + yy * m_taintSizeX];
return m_taints.Get(xx / Constants.TerrainPatchSize + yy * m_taintSizeX);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool IsTaintedAtPatch(int xx, int yy, bool clearOnTest)
{
int indx = xx + yy * m_taintSizeX;
bool ret = m_taint[indx];
if (ret && clearOnTest)
m_taint[indx] = false;
return ret;
return m_taints.Get(indx, clearOnTest);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool IsTaintedAtPatch(int xx, int yy)
{
return m_taint[xx + yy * m_taintSizeX];
return m_taints.Get(xx + yy * m_taintSizeX);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool IsTaintedAtPatch(int indx, bool clearOnTest)
{
bool ret = m_taint[indx];
if (ret && clearOnTest)
m_taint[indx] = false;
return ret;
return m_taints.Get(indx, clearOnTest);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool IsTaintedAtPatchWithClear(int indx)
{
if(m_taint[indx])
{
m_taint[indx] = false;
return true;
}
return false;
return m_taints.GetAndClear(indx);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool IsTaintedAtPatch(int indx)
{
return m_taint[indx];
return m_taints.Get(indx);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public int GetAndClearNextTaint(int startIndex)
{
return m_taints.GetAndClearNextTrue(startIndex);
}
// TerrainData.GetDatabaseBlob
// The user wants something to store in the database.
@ -233,6 +239,7 @@ namespace OpenSim.Framework
{
TerrainData ret = new TerrainData(SizeX, SizeY, SizeZ);
ret.m_heightmap = (float[,])this.m_heightmap.Clone();
return ret;
}
@ -266,22 +273,26 @@ namespace OpenSim.Framework
zmax = float.MinValue;
zmin = float.MaxValue;
int stride = m_heightmap.GetLength(1);
int startx = px * 16 * stride;
int endx = (px + 1) * 16 * stride;
int starty = py * 16;
int mpy = Constants.TerrainPatchSize * py;
fixed (float* map = m_heightmap)
{
for (int i = startx; i < endx; i += stride)
float* p = map + px * m_mapPatchsStride;
float* pend = p + m_mapPatchsStride;
while (p < pend)
{
float* p = &map[i];
for (int j = starty; j < starty + 16; j++)
float* yt = p + mpy;
float* ytend = yt + 16;
while(yt < ytend)
{
float val = p[j];
if (val > zmax) zmax = val;
if (val < zmin) zmin = val;
float val = *yt;
if (val > zmax)
zmax = val;
else if (val < zmin)
zmin = val;
yt++;
}
p += m_mapStride;
}
}
}
@ -289,19 +300,21 @@ namespace OpenSim.Framework
public unsafe void GetPatchBlock(float* block, int px, int py, float sub, float premult)
{
int k = 0;
int stride = m_heightmap.GetLength(1);
int startX = px * 16 * stride;
int endX = (px + 1) * 16 * stride;
int startY = py * 16;
fixed(float* map = m_heightmap)
int startX = px * m_mapPatchsStride;
int endX = startX + m_mapPatchsStride;
int mpy = py * Constants.TerrainPatchSize;
fixed (float* map = m_heightmap)
{
for (int y = startY; y < startY + 16; y++)
float* yp = map + mpy;
float* yend = yp + 16;
while (yp < yend)
{
for (int x = startX; x < endX; x += stride)
for (int x = startX; x < endX; x += m_mapStride)
{
block[k++] = (map[x + y] - sub) * premult;
block[k++] = (yp[x] - sub) * premult;
}
++yp;
}
}
}
@ -351,9 +364,13 @@ namespace OpenSim.Framework
m_taintSizeX = SizeX / Constants.TerrainPatchSize;
m_taintSizeY = SizeY / Constants.TerrainPatchSize;
m_mapStride = SizeY;
m_mapPatchsStride = m_mapStride * Constants.TerrainPatchSize;
SizeZ = (int)Constants.RegionHeight;
CompressionFactor = 100.0f;
m_heightmap = new float[SizeX, SizeY];
for (int ii = 0; ii < SizeX; ii++)
{
@ -365,7 +382,7 @@ namespace OpenSim.Framework
}
// m_log.DebugFormat("{0} new by doubles. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ);
m_taint = new BitArray(m_taintSizeX * m_taintSizeY, false);
m_taints = new TerrainTaintsArray(m_taintSizeX * m_taintSizeY);
}
// Create underlying structures but don't initialize the heightmap assuming the caller will immediately do that
@ -376,9 +393,12 @@ namespace OpenSim.Framework
SizeZ = pZ;
m_taintSizeX = SizeX / Constants.TerrainPatchSize;
m_taintSizeY = SizeY / Constants.TerrainPatchSize;
m_mapStride = SizeY;
m_mapPatchsStride = m_mapStride * Constants.TerrainPatchSize;
CompressionFactor = 100.0f;
m_heightmap = new float[SizeX, SizeY];
m_taint = new BitArray(m_taintSizeX * m_taintSizeY, false);
m_taints = new TerrainTaintsArray(m_taintSizeX * m_taintSizeY);
// m_log.DebugFormat("{0} new by dimensions. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ);
ClearLand(0f);
@ -498,8 +518,8 @@ namespace OpenSim.Framework
for (int yy = 0; yy < SizeY; yy++)
for (int xx = 0; xx < SizeX; xx++)
{
// reduce to 1cm resolution
float val = (float)Math.Round(m_heightmap[xx, yy],2,MidpointRounding.ToEven);
// reduce to 1mm resolution
float val = (float)Math.Round(m_heightmap[xx, yy],3,MidpointRounding.AwayFromZero);
bw.Write(val);
}
}
@ -575,15 +595,26 @@ namespace OpenSim.Framework
CompressionFactor = hmCompressionFactor;
// In case database info doesn't match real terrain size, initialize the whole terrain.
ClearLand();
bool needClear = false;
if (hmSizeX > SizeX)
hmSizeX = SizeX;
else if (hmSizeX < SizeX)
needClear = true;
if (hmSizeY > SizeY)
hmSizeY = SizeY;
else if (hmSizeY < SizeY)
needClear = true;
if (needClear)
ClearLand();
for (int yy = 0; yy < hmSizeY; yy++)
{
for (int xx = 0; xx < hmSizeX; xx++)
{
float val = FromCompressedHeight(br.ReadInt16());
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = val;
m_heightmap[xx, yy] = val;
}
}
}
@ -611,16 +642,26 @@ namespace OpenSim.Framework
hmSizeX = br.ReadInt32();
hmSizeY = br.ReadInt32();
// In case database info doesn't match real terrain size, initialize the whole terrain.
ClearLand();
bool needClear = false;
if (hmSizeX > SizeX)
hmSizeX = SizeX;
else if (hmSizeX < SizeX)
needClear = true;
if (hmSizeY > SizeY)
hmSizeY = SizeY;
else if (hmSizeY < SizeY)
needClear = true;
if (needClear)
ClearLand();
for (int yy = 0; yy < hmSizeY; yy++)
{
for (int xx = 0; xx < hmSizeX; xx++)
{
float val = br.ReadSingle();
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = val;
m_heightmap[xx, yy] = val;
}
}
}
@ -645,8 +686,7 @@ namespace OpenSim.Framework
{
m_log.InfoFormat("{0} VD2Gzip {1} bytes input",
LogHeader, pBlob.Length);
Int32 hmSizeX, hmSizeY;
int hmSizeX, hmSizeY;
try
{
@ -668,16 +708,26 @@ namespace OpenSim.Framework
hmSizeX = br.ReadInt32();
hmSizeY = br.ReadInt32();
// In case database info doesn't match real terrain size, initialize the whole terrain.
ClearLand();
bool needClear = false;
if(hmSizeX > SizeX)
hmSizeX = SizeX;
else if (hmSizeX < SizeX)
needClear = true;
if (hmSizeY > SizeY)
hmSizeY = SizeY;
else if (hmSizeY < SizeY)
needClear = true;
if (needClear)
ClearLand();
for (int yy = 0; yy < hmSizeY; yy++)
{
for (int xx = 0; xx < hmSizeX; xx++)
{
float val = br.ReadSingle();
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = val;
m_heightmap[xx, yy] = val;
}
}
}

View file

@ -0,0 +1,343 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Runtime.CompilerServices;
using System.Threading;
namespace OpenSim.Framework
{
public class TerrainTaintsArray
{
public const int VectorNumberBits = 32;
public const int VectorNumberBitsLog2 = 5;
public const int FALSEWORD = 0;
public const int TRUEWORD = ~FALSEWORD;
private int[] m_data;
private readonly int m_nbits;
private volatile int m_ntainted;
private object m_mainlock = new object();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TerrainTaintsArray(int lenght) : this(lenght, false) { }
public TerrainTaintsArray(int lenght, bool preset)
{
m_nbits = lenght;
int nInts = calclen(m_nbits);
m_data = new int[nInts];
if (preset)
{
for (int i = 0; i < m_data.Length; i++)
m_data[i] = TRUEWORD;
m_ntainted = m_nbits;
}
else
m_ntainted = 0;
}
public int Length
{
get
{
return m_nbits;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int TaitedCount()
{
return m_ntainted;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsTaited()
{
return m_ntainted > 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Get(int bitindex)
{
int indexh = bitindex >> VectorNumberBitsLog2;
int mask = 1 << (bitindex & (VectorNumberBits - 1));
return (m_data[indexh] & mask) != 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Get(int bitindex, bool clear)
{
int indexh = bitindex >> VectorNumberBitsLog2;
int mask = 1 << (bitindex & (VectorNumberBits - 1));
lock (m_mainlock)
{
if ((m_data[indexh] & mask) != 0)
{
if (clear)
{
m_data[indexh] ^= mask;
--m_ntainted;
}
return true;
}
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe bool GetAndClear(int bitindex)
{
int indexh = bitindex >> VectorNumberBitsLog2;
int mask = 1 << (bitindex & (VectorNumberBits - 1));
lock (m_mainlock)
{
if ((m_data[indexh] & mask) != 0)
{
m_data[indexh] ^= mask;
--m_ntainted;
return true;
}
}
return false;
}
public void Set(int bitindex, bool val)
{
int indexh = bitindex >> VectorNumberBitsLog2;
int mask = 1 << (bitindex & (VectorNumberBits - 1));
lock (m_mainlock)
{
if (val)
{
if ((m_data[indexh] & mask) == 0)
{
m_data[indexh] |= mask;
++m_ntainted;
}
}
else
{
if ((m_data[indexh] & mask) != 0)
{
m_data[indexh] ^= mask;
--m_ntainted;
}
}
}
}
public bool this[int bitindex]
{
get
{
return Get(bitindex);
}
set
{
int indexh = bitindex >> VectorNumberBitsLog2;
int mask = 1 << (bitindex & (VectorNumberBits - 1));
lock (m_mainlock)
{
if (value)
{
if ((m_data[indexh] & mask) == 0)
{
m_data[indexh] |= mask;
++m_ntainted;
}
}
else
{
if ((m_data[indexh] & mask) != 0)
{
m_data[indexh] ^= mask;
--m_ntainted;
}
}
}
}
}
public void SetAll(bool val)
{
lock (m_mainlock)
{
if (val)
{
for (int i = 0; i < m_data.Length; ++i)
m_data[i] = TRUEWORD;
m_ntainted = m_nbits;
}
else
{
for (int i = 0; i < m_data.Length; ++i)
m_data[i] = 0;
m_ntainted = 0;
}
}
}
public bool IsVectorOfFalse(int vectorIndex)
{
return m_data[vectorIndex] == 0;
}
public bool IsVectorOfBitFalse(int bitindex)
{
return m_data[(bitindex >> VectorNumberBitsLog2)] == 0;
}
public bool IsVectorTrue(int vectorIndex)
{
return m_data[vectorIndex] == unchecked(((int)0xffffffff));
}
public bool IsVectorOfBitTrue(int bitindex)
{
return m_data[(bitindex >> VectorNumberBitsLog2)] == unchecked(((int)0xffffffff));
}
public void Or(TerrainTaintsArray other)
{
if (m_nbits != other.m_nbits)
return;
lock (m_mainlock)
{
lock (other.m_mainlock)
{
for (int i = 0; i < m_data.Length; ++i)
{
int tr = other.m_data[i];
if (tr == 0)
continue;
int tt = m_data[i] | tr;
tr ^= tt;
if (tr != 0)
{
m_data[i] = tt;
for (int j = 1; j != 0; j <<= 1)
{
if ((tr & j) != 0)
++m_ntainted;
}
}
}
}
}
}
public int GetNextTrue(int startBitIndex)
{
if (startBitIndex < 0 || startBitIndex >= m_nbits)
return -1;
int indexh = startBitIndex >> VectorNumberBitsLog2;
int j = startBitIndex & (VectorNumberBits - 1);
int cur = m_data[indexh];
if (cur != 0)
{
for (; j < VectorNumberBits; ++j)
{
if ((cur & (1 << j)) != 0)
return (indexh << VectorNumberBitsLog2) | j;
}
}
while (++indexh < m_data.Length)
{
cur = m_data[indexh];
if (cur != 0)
{
for (j = 0; j < VectorNumberBits; ++j)
{
if ((cur & (1 << j)) != 0)
return (indexh << VectorNumberBitsLog2) | j;
}
}
}
return -1;
}
public int GetAndClearNextTrue(int startBitIndex)
{
if (m_ntainted <= 0 || startBitIndex < 0 || startBitIndex >= m_nbits)
return -1;
int indexh = startBitIndex >> VectorNumberBitsLog2;
int j = startBitIndex & (VectorNumberBits - 1);
lock (m_mainlock)
{
int cur = m_data[indexh];
if (cur != 0)
{
for (; j < VectorNumberBits; ++j)
{
int mask = (1 << j);
if ((cur & mask) != 0)
{
m_data[indexh] ^= mask;
--m_ntainted;
return (indexh << VectorNumberBitsLog2) | j;
}
}
}
while (++indexh < m_data.Length)
{
cur = m_data[indexh];
if (cur != 0)
{
for (j = 0; j < VectorNumberBits; ++j)
{
int mask = (1 << j);
if ((cur & mask) != 0)
{
m_data[indexh] ^= mask;
--m_ntainted;
return (indexh << VectorNumberBitsLog2) | j;
}
}
}
}
}
return -1;
}
private int calclen(int bitsLen)
{
return bitsLen > 0 ? ((bitsLen - 1) >> VectorNumberBitsLog2) + 1 : 0;
}
}
}

View file

@ -106,7 +106,7 @@ namespace OpenSim.Framework.Tests
{
UUID Random1 = UUID.Random();
UUID Random2 = UUID.Random();
byte[] data = new byte[0];
byte[] data = Array.Empty<byte>();
CacheItemBase cb1 = new CacheItemBase(Random1.ToString(), DateTime.Now + TimeSpan.FromDays(1));
CacheItemBase cb2 = new CacheItemBase(Random2.ToString(), DateTime.Now + TimeSpan.FromDays(1));
CacheItemBase cb3 = new CacheItemBase(Random1.ToString(), DateTime.Now + TimeSpan.FromDays(1));

File diff suppressed because it is too large Load diff

View file

@ -29,10 +29,10 @@ namespace OpenSim
{
public class VersionInfo
{
public const string VersionNumber = "0.9.2.1";
public const string AssemblyVersionNumber = "0.9.2.1";
public const string VersionNumber = "0.9.2.2";
public const string AssemblyVersionNumber = "0.9.2.2";
public const string Release = "202109";
public const Flavour VERSION_FLAVOUR = Flavour.Dev;
public enum Flavour

View file

@ -35,10 +35,10 @@ namespace OpenSim.Framework
[Serializable]
public class WearableCacheItem
{
public uint TextureIndex { get; set; }
public UUID CacheId { get; set; }
public UUID TextureID { get; set; }
public AssetBase TextureAsset { get; set; }
public uint TextureIndex;
public UUID CacheId;
public UUID TextureID;
public AssetBase TextureAsset;
public static WearableCacheItem[] GetDefaultCacheItem()
@ -186,7 +186,7 @@ namespace OpenSim.Framework
{
for (int i = 0; i < pcacheItems.Length; i++)
{
if (pcacheItems[i].CacheId == pCacheId)
if (pcacheItems[i].CacheId.Equals(pCacheId))
return pcacheItems[i];
}
return null;
@ -195,7 +195,7 @@ namespace OpenSim.Framework
{
for (int i = 0; i < pcacheItems.Length; i++)
{
if (pcacheItems[i].TextureID == pTextureId)
if (pcacheItems[i].TextureID.Equals(pTextureId))
return pcacheItems[i];
}
return null;

View file

@ -114,12 +114,12 @@ namespace OpenSim.Framework
/// </summary>
public static OSDMap PutToServiceCompressed(string url, OSDMap data, int timeout)
{
return ServiceOSDRequest(url,data, "PUT", timeout, true, false);
return ServiceOSDRequest(url, data, "PUT", timeout, true, false);
}
public static OSDMap PutToService(string url, OSDMap data, int timeout)
{
return ServiceOSDRequest(url,data, "PUT", timeout, false, false);
return ServiceOSDRequest(url, data, "PUT", timeout, false, false);
}
public static OSDMap PostToService(string url, OSDMap data, int timeout, bool rpc)
@ -1336,8 +1336,7 @@ namespace OpenSim.Framework
}
else if (WebUtil.DebugLevel >= 4)
{
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms",
reqnum, tickdiff);
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms", reqnum, tickdiff);
}
return deserial;
}
@ -1347,7 +1346,7 @@ namespace OpenSim.Framework
int reqnum = WebUtil.RequestNumber++;
if (WebUtil.DebugLevel >= 3)
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} SRestObjReq GET {2}", reqnum, requestUrl);
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} SRestObjReq GET {1}", reqnum, requestUrl);
int tickstart = Util.EnvironmentTickCount();
TResponse deserial = default(TResponse);

View file

@ -1030,7 +1030,7 @@ namespace OpenSim
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
if (regInfo.EstateSettings.EstateID != 0)
return false; // estate info in the database did not change
return false; // estate info in the database did not change
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
@ -1161,10 +1161,10 @@ namespace OpenSim
MainConsole.Instance.Output("Joining the estate failed. Please try again.");
}
}
}
}
return true; // need to update the database
}
return true; // need to update the database
}
}
public class OpenSimConfigSource

View file

@ -1320,14 +1320,14 @@ namespace OpenSim.Region.ClientStack.Linden
m_Scene.TryGetClient(agentID, out client);
if (objectID != UUID.Zero)
if (!objectID.IsZero())
{
SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
if(part == null)
throw new Exception("failed to find object with notecard item" + notecardID.ToString());
TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
if (taskItem == null || taskItem.AssetID == UUID.Zero)
if (taskItem == null || taskItem.AssetID.IsZero())
throw new Exception("Failed to find notecard item" + notecardID.ToString());
if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, agentID))
@ -1352,10 +1352,10 @@ namespace OpenSim.Region.ClientStack.Linden
return;
}
if (notecardID != UUID.Zero)
if (!notecardID.IsZero())
{
InventoryItemBase noteItem = m_Scene.InventoryService.GetItem(agentID, notecardID);
if (noteItem == null || noteItem.AssetID == UUID.Zero)
if (noteItem == null || noteItem.AssetID.IsZero())
throw new Exception("Failed to find notecard item" + notecardID.ToString());
noteAssetID = noteItem.AssetID;
}
@ -1385,7 +1385,7 @@ namespace OpenSim.Region.ClientStack.Linden
// find where to put it
InventoryFolderBase folder = null;
if (folderID != UUID.Zero)
if (!folderID.IsZero())
folder = m_Scene.InventoryService.GetFolder(agentID, folderID);
if (folder == null && Enum.IsDefined(typeof(FolderType), (sbyte)item.AssetType))
@ -2288,49 +2288,46 @@ namespace OpenSim.Region.ClientStack.Linden
NameValueCollection query = httpRequest.QueryString;
string[] ids = query.GetValues("ids");
Dictionary<UUID,string> names = m_UserManager.GetKnownUserNames(ids, m_scopeID);
osUTF8 lsl = LLSDxmlEncode2.Start(names.Count * 256 + 256);
LLSDxmlEncode2.AddMap(lsl);
int ct = 0;
if(names.Count == 0)
osUTF8 lsl;
if(ids.Length == 0)
{
lsl = LLSDxmlEncode2.Start();
LLSDxmlEncode2.AddMap(lsl);
LLSDxmlEncode2.AddEmptyArray("agents", lsl);
}
else
{
LLSDxmlEncode2.AddArray("agents", lsl);
List<UserData> names = m_UserManager.GetKnownUsers(ids, m_scopeID);
lsl = LLSDxmlEncode2.Start(names.Count * 256 + 256);
foreach (KeyValuePair<UUID,string> kvp in names)
LLSDxmlEncode2.AddMap(lsl);
if (names.Count == 0)
LLSDxmlEncode2.AddEmptyArray("agents", lsl);
else
{
string[] parts = kvp.Value.Split(new char[] {' '});
string fullname = kvp.Value;
LLSDxmlEncode2.AddArray("agents", lsl);
if (string.IsNullOrEmpty(kvp.Value))
foreach (UserData ud in names)
{
parts = new string[] {"(hippos)", ""};
fullname = "(hippos)";
// dont tell about unknown users, we can't send them back on Bad either
if (string.IsNullOrEmpty(ud.FirstName) || ud.FirstName.Equals("Unkown"))
continue;
string fullname = ud.FirstName + " " + ud.LastName;
LLSDxmlEncode2.AddMap(lsl);
LLSDxmlEncode2.AddElem("username", fullname, lsl);
LLSDxmlEncode2.AddElem("display_name", fullname, lsl);
LLSDxmlEncode2.AddElem("display_name_next_update", DateTime.UtcNow.AddDays(8), lsl);
LLSDxmlEncode2.AddElem("display_name_expires", DateTime.UtcNow.AddMonths(1), lsl);
LLSDxmlEncode2.AddElem("legacy_first_name", ud.FirstName, lsl);
LLSDxmlEncode2.AddElem("legacy_last_name", ud.LastName, lsl);
LLSDxmlEncode2.AddElem("id", ud.Id, lsl);
LLSDxmlEncode2.AddElem("is_display_name_default", true, lsl);
LLSDxmlEncode2.AddEndMap(lsl);
}
if(kvp.Key.IsZero())
continue;
// dont tell about unknown users, we can't send them back on Bad either
if(parts[0] == "Unknown")
continue;
LLSDxmlEncode2.AddMap(lsl);
LLSDxmlEncode2.AddElem("display_name_next_update", DateTime.UtcNow.AddDays(8), lsl);
LLSDxmlEncode2.AddElem("display_name_expires", DateTime.UtcNow.AddMonths(1), lsl);
LLSDxmlEncode2.AddElem("display_name", fullname, lsl);
LLSDxmlEncode2.AddElem("legacy_first_name", parts[0], lsl);
LLSDxmlEncode2.AddElem("legacy_last_name", parts[1], lsl);
LLSDxmlEncode2.AddElem("username", fullname, lsl);
LLSDxmlEncode2.AddElem("id", kvp.Key, lsl);
LLSDxmlEncode2.AddElem("is_display_name_default", true, lsl);
LLSDxmlEncode2.AddEndMap(lsl);
ct++;
LLSDxmlEncode2.AddEndArray(lsl);
}
LLSDxmlEncode2.AddEndArray(lsl);
}
LLSDxmlEncode2.AddEndMap(lsl);
httpResponse.RawBuffer = LLSDxmlEncode2.EndToNBBytes(lsl);

View file

@ -55,8 +55,11 @@ namespace OpenSim.Region.ClientStack.Linden
private IInventoryService m_inventoryService = null;
private ILibraryService m_LibraryService = null;
private string m_fetchInventory2Url;
private ExpiringKey<UUID> m_badRequests;
private string m_fetchLib2Url;
#region ISharedRegionModule Members
public void Initialise(IConfigSource source)
@ -66,8 +69,9 @@ namespace OpenSim.Region.ClientStack.Linden
return;
m_fetchInventory2Url = config.GetString("Cap_FetchInventory2", string.Empty);
m_fetchLib2Url = config.GetString("Cap_FetchLib2", "localhost");
if (m_fetchInventory2Url != string.Empty)
if (m_fetchInventory2Url.Length > 0)
Enabled = true;
}
@ -127,6 +131,14 @@ namespace OpenSim.Region.ClientStack.Linden
private void RegisterCaps(UUID agentID, Caps caps)
{
if (m_fetchInventory2Url == "localhost")
RegisterFetchCap(agentID, caps, m_fetchInventory2Url);
if (m_fetchLib2Url == "localhost")
RegisterFetchLibCap(agentID, caps, "FetchLib2", m_fetchLib2Url);
}
private void RegisterFetchCap(UUID agentID, Caps caps, string url)
{
if (url == "localhost")
{
FetchInventory2Handler fetchHandler = new FetchInventory2Handler(m_inventoryService, agentID);
caps.RegisterSimpleHandler("FetchInventory2",
@ -138,12 +150,33 @@ namespace OpenSim.Region.ClientStack.Linden
}
else
{
caps.RegisterHandler("FetchInventory2", m_fetchInventory2Url);
caps.RegisterHandler("FetchInventory2", url);
}
// m_log.DebugFormat(
// "[FETCH INVENTORY2 MODULE]: Registered capability {0} at {1} in region {2} for {3}",
// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
//m_log.DebugFormat(
// "[FETCH INVENTORY2 MODULE]: Registered capability FetchInventory2 at {0} in region {1} for {2}",
// capUrl, m_scene.RegionInfo.RegionName, agentID);
}
private void RegisterFetchLibCap(UUID agentID, Caps caps, string capName, string url)
{
if (url == "localhost")
{
FetchLib2Handler fetchHandler = new FetchLib2Handler(m_inventoryService, m_LibraryService, agentID);
caps.RegisterSimpleHandler("FetchLib2",
new SimpleOSDMapHandler("POST", "/" + UUID.Random(), delegate (IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map)
{
fetchHandler.FetchLibSimpleRequest(httpRequest, httpResponse, map, m_badRequests);
}
));
}
else
{
caps.RegisterHandler("FetchLib2", url);
}
//m_log.DebugFormat(
// "[FETCH INVENTORY2 MODULE]: Registered capability FetchLib2 at {0} in region {1} for {2}",
// capUrl, m_scene.RegionInfo.RegionName, agentID);
}
}
}

View file

@ -0,0 +1,328 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Nini.Config;
using Mono.Addins;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OpenSim.Capabilities.Handlers;
using OpenSim.Framework.Monitoring;
using OpenMetaverse.StructuredData;
namespace OpenSim.Region.ClientStack.Linden
{
/// <summary>
/// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities.
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FetchLibDescModule")]
public class FetchLibDescModule : INonSharedRegionModule
{
class APollRequest
{
public PollServiceInventoryEventArgs thepoll;
public UUID reqID;
public OSHttpRequest request;
}
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Control whether requests will be processed asynchronously.
/// </summary>
/// <remarks>
/// Defaults to true. Can currently not be changed once a region has been added to the module.
/// </remarks>
public bool ProcessQueuedRequestsAsync { get; private set; }
/// <summary>
/// Number of inventory requests processed by this module.
/// </summary>
/// <remarks>
/// It's the PollServiceRequestManager that actually sends completed requests back to the requester.
/// </remarks>
public static int ProcessedRequestsCount { get; set; }
public Scene Scene { get; private set; }
private ILibraryService m_LibraryService;
private bool m_Enabled;
private ExpiringKey<UUID> m_badRequests;
private string m_fetchLibDescendents2Url;
private static FetchLibDescHandler m_FetchHandler;
private static ObjectJobEngine m_workerpool = null;
#region ISharedRegionModule Members
public FetchLibDescModule() : this(true) {}
public FetchLibDescModule(bool processQueuedResultsAsync)
{
ProcessQueuedRequestsAsync = processQueuedResultsAsync;
}
public void Initialise(IConfigSource source)
{
IConfig config = source.Configs["ClientStack.LindenCaps"];
if (config == null)
return;
m_fetchLibDescendents2Url = config.GetString("Cap_FetchLibDescendents2", string.Empty);
m_Enabled = m_fetchLibDescendents2Url.Length > 0;
}
public void AddRegion(Scene s)
{
if (!m_Enabled)
return;
Scene = s;
}
public void RemoveRegion(Scene s)
{
if (!m_Enabled)
return;
Scene.EventManager.OnRegisterCaps -= RegisterCaps;
Scene = null;
}
public void RegionLoaded(Scene s)
{
if (!m_Enabled)
return;
m_LibraryService = Scene.LibraryService;
// We'll reuse the same handler for all requests.
m_FetchHandler = new FetchLibDescHandler(m_LibraryService, Scene);
Scene.EventManager.OnRegisterCaps += RegisterCaps;
if(m_badRequests == null)
m_badRequests = new ExpiringKey<UUID>(30000);
if (ProcessQueuedRequestsAsync && m_workerpool == null)
m_workerpool = new ObjectJobEngine(DoInventoryRequests, "LibInventoryWorker", 2000, 2);
}
public void PostInitialise()
{
}
public void Close()
{
if (!m_Enabled)
return;
if (ProcessQueuedRequestsAsync)
{
if (m_workerpool != null)
{
m_workerpool.Dispose();
m_workerpool = null;
m_badRequests.Dispose();
m_badRequests = null;
}
}
//m_queue.Dispose();
}
public string Name { get { return "FetchLibDescModule"; } }
public Type ReplaceableInterface
{
get { return null; }
}
#endregion
private class PollServiceInventoryEventArgs : PollServiceEventArgs
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<UUID, Hashtable> responses = new Dictionary<UUID, Hashtable>();
private HashSet<UUID> dropedResponses = new HashSet<UUID>();
private FetchLibDescModule m_module;
public PollServiceInventoryEventArgs(FetchLibDescModule module, string url, UUID pId) :
base(null, url, null, null, null, null, pId, int.MaxValue)
{
m_module = module;
HasEvents = (requestID, y) =>
{
lock (responses)
return responses.ContainsKey(requestID);
};
Drop = (requestID, y) =>
{
lock (responses)
{
responses.Remove(requestID);
lock(dropedResponses)
dropedResponses.Add(requestID);
}
};
GetEvents = (requestID, y) =>
{
lock (responses)
{
try
{
return responses[requestID];
}
finally
{
responses.Remove(requestID);
}
}
};
Request = (requestID, request) =>
{
APollRequest reqinfo = new APollRequest();
reqinfo.thepoll = this;
reqinfo.reqID = requestID;
reqinfo.request = request;
m_workerpool.Enqueue(reqinfo);
return null;
};
NoEvents = (x, y) =>
{
Hashtable response = new Hashtable();
response["int_response_code"] = 500;
response["str_response_string"] = "Script timeout";
response["content_type"] = "text/plain";
response["keepalive"] = false;
return response;
};
}
public void Process(APollRequest requestinfo)
{
if(m_module == null || m_module.Scene == null || m_module.Scene.ShuttingDown)
return;
UUID requestID = requestinfo.reqID;
lock(responses)
{
lock(dropedResponses)
{
if(dropedResponses.Contains(requestID))
{
dropedResponses.Remove(requestID);
return;
}
}
}
OSHttpResponse osresponse = new OSHttpResponse(requestinfo.request);
m_FetchHandler.FetchRequest(requestinfo.request, osresponse, m_module.m_badRequests, requestinfo.thepoll.Id);
requestinfo.request.InputStream.Dispose();
lock (responses)
{
lock(dropedResponses)
{
if(dropedResponses.Contains(requestID))
{
dropedResponses.Remove(requestID);
ProcessedRequestsCount++;
return;
}
}
Hashtable response = new Hashtable();
response["h"] = osresponse;
responses[requestID] = response;
}
ProcessedRequestsCount++;
}
}
private void RegisterCaps(UUID agentID, Caps caps)
{
RegisterFetchLibDescendentsCap(agentID, caps, "FetchLibDescendents2", m_fetchLibDescendents2Url);
}
private void RegisterFetchLibDescendentsCap(UUID agentID, Caps caps, string capName, string url)
{
string capUrl;
// handled by the simulator
if (url == "localhost")
{
capUrl = "/" + UUID.Random();
// Register this as a poll service
PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(this, capUrl, agentID);
//args.Type = PollServiceEventArgs.EventType.Inventory;
caps.RegisterPollHandler(capName, args);
}
// external handler
else
{
capUrl = url;
IExternalCapsModule handler = Scene.RequestModuleInterface<IExternalCapsModule>();
if (handler != null)
handler.RegisterExternalUserCapsHandler(agentID, caps, capName, capUrl);
else
caps.RegisterHandler(capName, capUrl);
}
}
private static void DoInventoryRequests(object o)
{
APollRequest poolreq = o as APollRequest;
if (poolreq != null && poolreq.thepoll != null)
poolreq.thepoll.Process(poolreq);
}
}
}

View file

@ -393,7 +393,7 @@ namespace OpenSim.Region.ClientStack.Linden
else
caps.RegisterPollHandler("ViewerAsset", new PollServiceAssetEventArgs(capUrl, agentID, m_scene, hgassets));
}
else if (string.IsNullOrEmpty(m_GetAssetURL))
else if (!string.IsNullOrEmpty(m_GetAssetURL))
caps.RegisterHandler("ViewerAsset", m_GetAssetURL);
}
}

View file

@ -259,14 +259,14 @@ namespace OpenSim.Region.ClientStack.Linden
// This isn't the cheapest way of doing this but the rate
// of occurrence is low (on sim entry only) and it's a sure
// way to get a true deep copy.
OSD copy = OSDParser.DeserializeLLSDXml(OSDParser.SerializeLLSDXmlString(m_features));
OSD copy = OSDParser.DeserializeLLSDXml(OSDParser.SerializeLLSDXmlToBytes(m_features));
return (OSDMap)copy;
}
private void HandleSimulatorFeaturesRequest(IOSHttpRequest request, IOSHttpResponse response, UUID agentID)
{
// m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
// m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
if (request.HttpMethod != "GET")
{
@ -274,6 +274,7 @@ namespace OpenSim.Region.ClientStack.Linden
return;
}
/*
ScenePresence sp = m_scene.GetScenePresence(agentID);
if (sp == null)
{
@ -281,17 +282,31 @@ namespace OpenSim.Region.ClientStack.Linden
response.AddHeader("Retry-After", "5");
return;
}
*/
OSDMap copy = DeepCopy();
// Let's add the agentID to the destination guide, if it is expecting that.
if (copy.ContainsKey("OpenSimExtras") && ((OSDMap)(copy["OpenSimExtras"])).ContainsKey("destination-guide-url"))
((OSDMap)copy["OpenSimExtras"])["destination-guide-url"] = Replace(((OSDMap)copy["OpenSimExtras"])["destination-guide-url"], "[USERID]", agentID.ToString());
if(copy.TryGetValue("OpenSimExtras", out OSD oe))
{
if(((OSDMap)oe).TryGetValue("destination-guide-url", out OSD dgl))
{
((OSDMap)oe)["destination-guide-url"] = Replace(dgl.AsString(), "[USERID]", agentID.ToString());
}
}
OnSimulatorFeaturesRequest?.Invoke(agentID, ref copy);
if(OnSimulatorFeaturesRequest != null)
{
foreach(SimulatorFeaturesRequestDelegate sd in OnSimulatorFeaturesRequest.GetInvocationList())
try
{
sd?.Invoke(agentID, ref copy);
}
catch { }
}
//Send back data
response.RawBuffer = Util.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(copy));
response.RawBuffer = OSDParser.SerializeLLSDXmlToBytes(copy);
response.StatusCode = (int)HttpStatusCode.OK;
}

View file

@ -94,7 +94,6 @@ namespace OpenSim.Region.ClientStack.Linden
private ExpiringKey<UUID> m_badRequests;
private string m_fetchInventoryDescendents2Url;
// private string m_webFetchInventoryDescendentsUrl;
private static FetchInvDescHandler m_webFetchHandler;
@ -118,13 +117,7 @@ namespace OpenSim.Region.ClientStack.Linden
return;
m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty);
// m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
// if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty)
if (m_fetchInventoryDescendents2Url != string.Empty)
{
m_Enabled = true;
}
m_Enabled = m_fetchInventoryDescendents2Url.Length > 0;
}
public void AddRegion(Scene s)
@ -222,7 +215,7 @@ namespace OpenSim.Region.ClientStack.Linden
m_badRequests = null;
}
}
// m_queue.Dispose();
//m_queue.Dispose();
}
public string Name { get { return "WebFetchInvDescModule"; } }
@ -346,38 +339,23 @@ namespace OpenSim.Region.ClientStack.Linden
private void RegisterCaps(UUID agentID, Caps caps)
{
RegisterFetchDescendentsCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
}
private void RegisterFetchDescendentsCap(UUID agentID, Caps caps, string capName, string url)
{
string capUrl;
// disable the cap clause
if (url.Length == 0)
{
return;
}
// handled by the simulator
else if (url == "localhost")
if (m_fetchInventoryDescendents2Url == "localhost")
{
capUrl = "/" + UUID.Random();
// Register this as a poll service
PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(this, capUrl, agentID);
PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(this, "/" + UUID.Random(), agentID);
//args.Type = PollServiceEventArgs.EventType.Inventory;
caps.RegisterPollHandler(capName, args);
caps.RegisterPollHandler("FetchInventoryDescendents2", args);
}
// external handler
else
{
capUrl = url;
IExternalCapsModule handler = Scene.RequestModuleInterface<IExternalCapsModule>();
if (handler != null)
handler.RegisterExternalUserCapsHandler(agentID,caps,capName,capUrl);
handler.RegisterExternalUserCapsHandler(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
else
caps.RegisterHandler(capName, capUrl);
caps.RegisterHandler("FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
}
}

View file

@ -369,7 +369,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
/// cannot retain a reference to it outside of that method.
/// </remarks>
private AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
private readonly AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@ -1769,65 +1769,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(pkt, ThrottleOutPacketType.Wind);
}
// cloud caching
private static Dictionary<ulong,int> lastCloudVersion = new Dictionary<ulong,int>();
private static Dictionary<ulong,List<LayerDataPacket>> lastCloudPackets =
new Dictionary<ulong,List<LayerDataPacket>>();
/// <summary>
/// Send the cloud matrix to the client
/// </summary>
/// <param name="windSpeeds">16x16 array of cloud densities</param>
public virtual void SendCloudData(int version, float[] cloudDensity)
{
ulong handle = this.Scene.RegionInfo.RegionHandle;
bool isNewData;
lock(lastWindPackets)
{
if(!lastCloudVersion.ContainsKey(handle) ||
!lastCloudPackets.ContainsKey(handle))
{
lastCloudVersion[handle] = 0;
lastCloudPackets[handle] = new List<LayerDataPacket>();
isNewData = true;
}
else
isNewData = lastCloudVersion[handle] != version;
}
if(isNewData)
{
TerrainPatch[] patches = new TerrainPatch[1];
patches[0] = new TerrainPatch();
patches[0].Data = new float[16 * 16];
for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 16; x++)
{
patches[0].Data[y * 16 + x] = cloudDensity[y * 16 + x];
}
}
// neither we or viewers have extended clouds
byte layerType = (byte)TerrainPatch.LayerType.Cloud;
LayerDataPacket layerpack =
OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(
patches, layerType);
layerpack.Header.Zerocoded = true;
lock(lastCloudPackets)
{
lastCloudPackets[handle].Clear();
lastCloudPackets[handle].Add(layerpack);
lastCloudVersion[handle] = version;
}
}
lock(lastCloudPackets)
foreach(LayerDataPacket pkt in lastCloudPackets[handle])
OutPacket(pkt, ThrottleOutPacketType.Cloud);
}
/// <summary>
/// Tell the client that the given neighbour region is ready to receive a child agent.
/// </summary>
@ -2419,7 +2360,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
packet.FolderData[0].FolderID = UUID.Zero;
packet.FolderData[0].ParentID = UUID.Zero;
packet.FolderData[0].Type = -1;
packet.FolderData[0].Name = new byte[0];
packet.FolderData[0].Name = Array.Empty<byte>();
}
private void AddNullItemBlockToDescendentsPacket(ref InventoryDescendentsPacket packet)
@ -2430,12 +2371,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
packet.ItemData[0].AssetID = UUID.Zero;
packet.ItemData[0].CreatorID = UUID.Zero;
packet.ItemData[0].BaseMask = 0;
packet.ItemData[0].Description = new byte[0];
packet.ItemData[0].Description = Array.Empty<byte>();
packet.ItemData[0].EveryoneMask = 0;
packet.ItemData[0].OwnerMask = 0;
packet.ItemData[0].FolderID = UUID.Zero;
packet.ItemData[0].InvType = (sbyte)0;
packet.ItemData[0].Name = new byte[0];
packet.ItemData[0].Name = Array.Empty<byte>();
packet.ItemData[0].NextOwnerMask = 0;
packet.ItemData[0].OwnerID = UUID.Zero;
packet.ItemData[0].Type = -1;
@ -2728,7 +2669,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
bulkUpdate.FolderData[0].FolderID = UUID.Zero;
bulkUpdate.FolderData[0].ParentID = UUID.Zero;
bulkUpdate.FolderData[0].Type = -1;
bulkUpdate.FolderData[0].Name = new byte[0];
bulkUpdate.FolderData[0].Name = Array.Empty<byte>();
bulkUpdate.ItemData = new BulkUpdateInventoryPacket.ItemDataBlock[1];
bulkUpdate.ItemData[0] = new BulkUpdateInventoryPacket.ItemDataBlock();
@ -3106,7 +3047,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[1];
alertPack.AlertInfo[0] = new AlertMessagePacket.AlertInfoBlock();
alertPack.AlertInfo[0].Message = Util.StringToBytes256(info);
alertPack.AlertInfo[0].ExtraParams = new Byte[0];
alertPack.AlertInfo[0].ExtraParams = Array.Empty<byte>();
OutPacket(alertPack, ThrottleOutPacketType.Task);
}
@ -3717,7 +3658,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (land.Description != null && land.Description != String.Empty)
reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
else
reply.Data.Desc = new Byte[0];
reply.Data.Desc = Array.Empty<byte>();
reply.Data.ActualArea = land.Area;
reply.Data.BillableArea = land.Area; // TODO: what is this?
@ -4373,7 +4314,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
gmp.MethodData.Method = Util.StringToBytes256("emptymutelist");
gmp.ParamList = new GenericMessagePacket.ParamListBlock[1];
gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
gmp.ParamList[0].Parameter = new byte[0];
gmp.ParamList[0].Parameter = Array.Empty<byte>();
OutPacket(gmp, ThrottleOutPacketType.Task);
}
@ -8283,20 +8224,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
if(
(x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed
// || ((x.ControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0 &&
// (x.ControlFlags & 0x3f8dfff) != 0) // we need to rotate the av on fly
|| x.ControlFlags != (byte)AgentManager.ControlFlags.NONE// actually all movement controls need to pass
|| (x.ControlFlags & ~(uint)AgentManager.ControlFlags.AGENT_CONTROL_FINISH_ANIM) != (uint)AgentManager.ControlFlags.NONE
|| (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed
|| (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed
|| (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed
)
return true;
float qdelta = Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation));
if(qdelta < QDELTABody) // significant if body rotation above(below cos) threshold
return true;
return false;
float qdelta = Math.Abs(x.BodyRotation.Dot(m_thisAgentUpdateArgs.BodyRotation));
return qdelta < QDELTABody; // significant if body rotation above(below cos) threshold
}
/// <summary>
@ -8307,26 +8243,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name='x'></param>
private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
{
if(Math.Abs(x.CameraCenter.X - m_thisAgentUpdateArgs.CameraCenter.X) > VDELTA ||
Math.Abs(x.CameraCenter.Y - m_thisAgentUpdateArgs.CameraCenter.Y) > VDELTA ||
Math.Abs(x.CameraCenter.Z - m_thisAgentUpdateArgs.CameraCenter.Z) > VDELTA ||
return (Math.Abs(x.CameraCenter.X - m_thisAgentUpdateArgs.CameraCenter.X) > VDELTA ||
Math.Abs(x.CameraCenter.Y - m_thisAgentUpdateArgs.CameraCenter.Y) > VDELTA ||
Math.Abs(x.CameraCenter.Z - m_thisAgentUpdateArgs.CameraCenter.Z) > VDELTA ||
Math.Abs(x.CameraAtAxis.X - m_thisAgentUpdateArgs.CameraAtAxis.X) > VDELTA ||
Math.Abs(x.CameraAtAxis.Y - m_thisAgentUpdateArgs.CameraAtAxis.Y) > VDELTA ||
// Math.Abs(x.CameraAtAxis.Z - m_thisAgentUpdateArgs.CameraAtAxis.Z) > VDELTA ||
Math.Abs(x.CameraAtAxis.X - m_thisAgentUpdateArgs.CameraAtAxis.X) > VDELTA ||
Math.Abs(x.CameraAtAxis.Y - m_thisAgentUpdateArgs.CameraAtAxis.Y) > VDELTA ||
Math.Abs(x.CameraLeftAxis.X - m_thisAgentUpdateArgs.CameraLeftAxis.X) > VDELTA ||
Math.Abs(x.CameraLeftAxis.Y - m_thisAgentUpdateArgs.CameraLeftAxis.Y) > VDELTA ||
// Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA ||
Math.Abs(x.CameraUpAxis.X - m_thisAgentUpdateArgs.CameraUpAxis.X) > VDELTA ||
Math.Abs(x.CameraUpAxis.Y - m_thisAgentUpdateArgs.CameraUpAxis.Y) > VDELTA
// Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA ||
)
return true;
return false;
}
Math.Abs(x.CameraUpAxis.X - m_thisAgentUpdateArgs.CameraUpAxis.X) > VDELTA ||
Math.Abs(x.CameraUpAxis.Y - m_thisAgentUpdateArgs.CameraUpAxis.Y) > VDELTA
);
}
private void HandleAgentUpdate(Packet packet)
{
@ -12595,12 +12522,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (cachedtex.AgentData.SessionID.NotEqual(m_sessionId) || cachedtex.AgentData.AgentID.NotEqual(m_agentId))
return;
// TODO: don't create new blocks if recycling an old packet
cachedresp.AgentData.AgentID = m_agentId;
cachedresp.AgentData.SessionID = m_sessionId;
cachedresp.AgentData.SerialNum = cachedtex.AgentData.SerialNum;
cachedresp.WearableData =
new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
int cacheHits = 0;
@ -12623,29 +12548,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
maxWearablesLoop = cacheItems.Length;
for (int i = 0; i < maxWearablesLoop; i++)
{
int idx = cachedtex.WearableData[i].TextureIndex;
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
cachedresp.WearableData[i].HostName = new byte[0];
if (cachedtex.WearableData[i].ID == cacheItems[idx].CacheId)
var checkdWear = cachedtex.WearableData[i];
int idx = checkdWear.TextureIndex;
var respWear = new AgentCachedTextureResponsePacket.WearableDataBlock()
{
cachedresp.WearableData[i].TextureID = cacheItems[idx].TextureID;
TextureIndex = (byte)idx,
HostName = Array.Empty<byte>()
};
if (checkdWear.ID.Equals(cacheItems[idx].CacheId))
{
respWear.TextureID = cacheItems[idx].TextureID;
cacheHits++;
}
else
{
cachedresp.WearableData[i].TextureID = UUID.Zero;
respWear.TextureID = UUID.Zero;
}
cachedresp.WearableData[i] = respWear;
}
}
else
{
for (int i = 0; i < maxWearablesLoop; i++)
{
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
cachedresp.WearableData[i].TextureID = UUID.Zero;
cachedresp.WearableData[i].HostName = new byte[0];
var newWear = new AgentCachedTextureResponsePacket.WearableDataBlock()
{
TextureIndex = cachedtex.WearableData[i].TextureIndex,
TextureID = UUID.Zero,
HostName = Array.Empty<byte>()
};
cachedresp.WearableData[i] = newWear;
}
}
@ -12682,7 +12614,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex = (byte)cachedTextures[i].BakedTextureIndex;
cachedresp.WearableData[i].TextureID = cachedTextures[i].BakedTextureID;
cachedresp.WearableData[i].HostName = new byte[0];
cachedresp.WearableData[i].HostName = Array.Empty<byte>();
}
cachedresp.Header.Zerocoded = true;

View file

@ -83,9 +83,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uint port = (uint)scene.RegionInfo.InternalEndPoint.Port;
IPAddress listenIP = scene.RegionInfo.InternalEndPoint.Address;
Initialise(listenIP, ref port, scene.RegionInfo.ProxyOffset, m_Config, scene.AuthenticateHandler);
scene.RegionInfo.InternalEndPoint.Port = (int)port;
m_udpServer = new LLUDPServer(listenIP, port, scene.RegionInfo.ProxyOffset, m_Config, scene.AuthenticateHandler);
scene.RegionInfo.InternalEndPoint.Port = m_udpServer.Port;
AddScene(scene);
}
@ -100,11 +99,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
#endregion
public virtual void Initialise(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, IConfigSource configSource, AgentCircuitManager circuitManager)
{
m_udpServer = new LLUDPServer(listenIP, ref port, proxyPortOffsetParm, configSource, circuitManager);
}
public virtual void AddScene(IScene scene)
{
m_udpServer.AddScene(scene);
@ -373,7 +367,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public JobEngine OqrEngine { get; protected set; }
public LLUDPServer(
IPAddress listenIP, ref uint port, int proxyPortOffsetParm,
IPAddress listenIP, uint port, int proxyPortOffsetParm,
IConfigSource configSource, AgentCircuitManager circuitManager)
: base(listenIP, (int)port)
{
@ -411,7 +405,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_circuitManager = circuitManager;
int sceneThrottleBps = 0;
// bool usePools = false;
// bool usePools = false;
IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null)
@ -441,8 +435,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packetConfig != null)
{
//PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
// PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
// usePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", usePools);
//PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
//usePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", usePools);
}
#region BinaryStats
@ -460,15 +454,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps * 10e-3f);
ThrottleRates = new ThrottleRates(configSource);
// if (usePools)
// EnablePools();
//if (usePools)
// EnablePools();
}
public void Start()
{
StartInbound();
StartOutbound();
// IpahEngine.Start();
//IpahEngine.Start();
OqrEngine.Start();
m_elapsedMSSinceLastStatReport = Environment.TickCount;
@ -513,7 +507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name);
base.StopOutbound();
base.StopInbound();
// IpahEngine.Stop();
//IpahEngine.Stop();
OqrEngine.Stop();
}
@ -621,7 +615,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = GetTotalQueuedOutgoingPackets(),
StatVerbosity.Info));
/*
/*
StatsManager.RegisterStat(
new Stat(
"IncomingPacketAsyncRequestsWaiting",
@ -634,7 +628,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
MeasuresOfInterest.None,
stat => stat.Value = IpahEngine.JobsWaiting,
StatVerbosity.Debug));
*/
*/
StatsManager.RegisterStat(
new Stat(
"OQRERequestsWaiting",
@ -681,45 +675,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return total;
}
// public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting)
// {
// // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way
// if ((packet.Type == PacketType.CoarseLocationUpdate || packet.Type == PacketType.AvatarGroupsReply) && allowSplitting)
// allowSplitting = false;
//
// if (allowSplitting && packet.HasVariableBlocks)
// {
// byte[][] datas = packet.ToBytesMultiple();
// int packetCount = datas.Length;
//
// if (packetCount < 1)
// m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length);
//
// for (int i = 0; i < packetCount; i++)
// {
// byte[] data = datas[i];
// m_scene.ForEachClient(
// delegate(IClientAPI client)
// {
// if (client is LLClientView)
// SendPacketData(((LLClientView)client).UDPClient, data, packet.Type, category, null);
// }
// );
// }
// }
// else
// {
// byte[] data = packet.ToBytes();
// m_scene.ForEachClient(
// delegate(IClientAPI client)
// {
// if (client is LLClientView)
// SendPacketData(((LLClientView)client).UDPClient, data, packet.Type, category, null);
// }
// );
// }
// }
/// <summary>
/// Start the process of sending a packet to the client.
/// </summary>
@ -1222,8 +1177,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Debugging/Profiling
//try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
//catch (Exception) { }
// m_log.DebugFormat(
// "[LLUDPSERVER]: Packet received from {0} in {1}", buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
//m_log.DebugFormat(
// "[LLUDPSERVER]: Packet received from {0} in {1}", buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
Packet packet = null;
int bufferLen = buffer.DataLength;
@ -1233,9 +1188,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (bufferLen < 7)
{
// m_log.WarnFormat(
// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
//m_log.WarnFormat(
// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
RecordMalformedInboundPacket(endPoint);
FreeUDPBuffer(buffer);
return; // Drop undersized packet
@ -1414,9 +1369,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Header.Reliable)
{
// m_log.DebugFormat(
// "[LLUDPSERVER]: Adding ack request for {0} {1} from {2} in {3}",
// packet.Type, packet.Header.Sequence, client.Name, m_scene.Name);
//m_log.DebugFormat(
// "[LLUDPSERVER]: Adding ack request for {0} {1} from {2} in {3}",
// packet.Type, packet.Header.Sequence, client.Name, m_scene.Name);
udpClient.PendingAcks.Enqueue(packet.Header.Sequence);
@ -1469,7 +1424,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Type == PacketType.StartPingCheck)
{
// m_log.DebugFormat("[LLUDPSERVER]: Handling ping from {0} in {1}", client.Name, m_scene.Name);
//m_log.DebugFormat("[LLUDPSERVER]: Handling ping from {0} in {1}", client.Name, m_scene.Name);
// We don't need to do anything else with ping checks
StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
@ -1497,14 +1452,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
IncomingPacket incomingPacket;
incomingPacket = new IncomingPacket((LLClientView)client, packet);
// if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
// incomingPacket.Packet.Type == PacketType.ChatFromViewer)
// if (incomingPacket.Packet.Type == PacketType.ChatFromViewer)
// packetInbox.PriorityEnqueue(incomingPacket);
// else
// packetInbox.Enqueue(incomingPacket);
incomingPacket = new IncomingPacket((LLClientView)client, packet);
packetInbox.Add(incomingPacket);
}
@ -1622,7 +1570,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
try
{
// DateTime startTime = DateTime.Now;
object[] array = (object[])o;
endPoint = (IPEndPoint)array[0];
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
@ -1744,7 +1691,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
// AsyncBeginSend(buffer);
SyncSend(buffer);
FreeUDPBuffer(buffer);
}
@ -1939,7 +1885,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Thread.Sleep(100);
}
else if (!m_packetSent)
// Thread.Sleep((int)TickCountResolution); outch this is bad on linux
Thread.Sleep(15); // match the 16ms of windows, dont ask 16 or win may decide to do 32ms.
Watchdog.UpdateThread();

View file

@ -247,7 +247,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
// "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}",
// m_asset.FullID, m_asset.Type, XferID, ourClient.Name);
ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]);
ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, Array.Empty<byte>());
}
protected void SendCompleteMessage()

View file

@ -322,7 +322,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
public class XferDownLoad
{
public IClientAPI remoteClient;
public byte[] Data = new byte[0];
public byte[] Data = Array.Empty<byte>();
public string FileName = String.Empty;
public ulong XferID = 0;
public bool isDeleted = false;

View file

@ -93,8 +93,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// disabled. Registering only when enabled allows for other attachments module implementations.
m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
m_scene.EventManager.OnStartScript += (localID, itemID) => OnScriptStateChange(localID, true);
m_scene.EventManager.OnStopScript += (localID, itemID) => OnScriptStateChange(localID, false);
m_scene.EventManager.OnStartScript += OnScriptStarted;
m_scene.EventManager.OnStopScript += OnScriptStopped;
}
@ -108,6 +108,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.UnregisterModuleInterface<IAttachmentsModule>(this);
m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
m_scene.EventManager.OnStartScript -= OnScriptStarted;
m_scene.EventManager.OnStopScript -= OnScriptStopped;
}
public void RegionLoaded(Scene scene)
@ -286,24 +288,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// </summary>
/// <param name='localID'></param>
/// <param name='itemID'></param>
private void OnScriptStateChange(uint localID, bool started)
private void OnScriptStarted(uint localID, UUID itemID)
{
SceneObjectGroup sog = m_scene.GetGroupByPrim(localID);
if (sog != null && sog.IsAttachment)
sog.HasGroupChanged = true;
}
private void OnScriptStopped(uint localID, UUID itemID)
{
SceneObjectGroup sog = m_scene.GetGroupByPrim(localID);
if (sog != null && sog.IsAttachment)
{
if (!started)
{
// FIXME: This is a convoluted way for working out whether the script state has changed to stop
// because it has been manually stopped or because the stop was called in UpdateDetachedObject() below
// This needs to be handled in a less tangled way.
ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar);
if (sp.ControllingClient.IsActive)
sog.HasGroupChanged = true;
}
else
{
// FIXME: This is a convoluted way for working out whether the script state has changed to stop
// because it has been manually stopped or because the stop was called in UpdateDetachedObject() below
// This needs to be handled in a less tangled way.
ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar);
if (sp.ControllingClient.IsActive)
sog.HasGroupChanged = true;
}
}
}
@ -357,21 +360,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
DeleteAttachmentsFromScene(isp, true); // delete
}
List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(ad.AttachmentObjects.Count);
int i = 0;
for (int indx = 0; indx < ad.AttachmentObjects.Count; ++indx)
{
SceneObjectGroup sog = (SceneObjectGroup)ad.AttachmentObjects[indx];
sog.LocalId = 0;
sog.RootPart.ClearUpdateSchedule();
SceneObjectGroup sog = ad.AttachmentObjects[indx] as SceneObjectGroup;
if(sog != null)
{
sog.LocalId = 0;
sog.RootPart.ClearUpdateSchedule();
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Copying script state with {0} bytes for object {1} for {2} in {3}",
// ad.AttachmentObjectStates[i].Length, sog.Name, sp.Name, m_scene.Name);
sog.SetState(ad.AttachmentObjectStates[i++], m_scene);
m_scene.IncomingCreateObject(Vector3.Zero, sog);
sog.SetState(ad.AttachmentObjectStates[i++], m_scene);
attachments.Add(sog);
}
}
ad.AttachmentObjects = null;
ad.AttachmentObjectStates = null;
if (attachments.Count > 0)
m_scene.IncomingAttechments(sp, attachments);
else
sp.GotAttachmentsData = true;
}
else
sp.GotAttachmentsData = true;
}
public void RezAttachments(IScenePresence sp)
@ -1198,8 +1211,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// grid may use an incompatible script engine.
bool saveChanged
= sp.PresenceType != PresenceType.Npc
&& (m_scene.UserManagementModule == null
|| m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
&& (m_scene.UserManagementModule == null || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
// Remove the object from the scene so no more updates
// are sent. Doing this before the below changes will ensure

View file

@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public const string BAKED_TEXTURES_REPORT_FORMAT = "{0,-9} {1}";
public const string BAKED_TEXTURES_REPORT_FORMAT = " {0,-9} {1}";
private Scene m_scene = null;
@ -204,7 +204,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
//WriteBakedTexturesReport(sp, m_log.DebugFormat);
UpdateBakedTextureCache(sp, cacheItems);
@ -219,11 +219,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
SendAppearance((ScenePresence)sp);
return;
}
// save only if there were changes, send no matter what (doesn't hurt to send twice)
// save only if there were changes
if (changed)
QueueAppearanceSave(sp.ControllingClient.AgentId);
QueueAppearanceSend(sp.ControllingClient.AgentId);
}
@ -377,7 +375,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
wearableCache = WearableCacheItem.GetDefaultCacheItem();
else
{
hadSkirt = !wearableCache[19].TextureID.IsZero();
hadSkirt = wearableCache[19].CacheId.IsNotZero(); // .TextureID.IsNotZero();
}
HashSet<uint> updatedFaces = new HashSet<uint>();
@ -386,8 +384,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// Process received baked textures
for (int i = 0; i < cacheItems.Length; i++)
{
uint idx = cacheItems[i].TextureIndex;
if(idx >= AvatarAppearance.TEXTURE_COUNT)
var curCacheItem = cacheItems[i];
uint idx = curCacheItem.TextureIndex;
if (idx >= AvatarAppearance.TEXTURE_COUNT)
{
hits++;
continue;
@ -395,13 +394,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
updatedFaces.Add(idx);
wearableCache[idx].TextureAsset = null; // just in case
var wcacheidx = wearableCache[idx];
wcacheidx.TextureAsset = null; // just in case
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
if (face == null || face.TextureID.IsZero() || face.TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE))
{
wearableCache[idx].CacheId = UUID.Zero;
wearableCache[idx].TextureID = UUID.Zero;
wcacheidx.CacheId = UUID.Zero;
wcacheidx.TextureID = UUID.Zero;
if (idx == 19)
{
hits++;
@ -415,23 +415,23 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{
AssetBase asb = null;
cache.Get(face.TextureID.ToString(), out asb);
wearableCache[idx].TextureAsset = asb;
wcacheidx.TextureAsset = asb;
}
if (wearableCache[idx].TextureAsset != null)
if (wcacheidx.TextureAsset != null)
{
if ( wearableCache[idx].TextureID != face.TextureID ||
wearableCache[idx].CacheId != cacheItems[i].CacheId)
if (wcacheidx.TextureID.NotEqual(face.TextureID) ||
wcacheidx.CacheId.NotEqual(curCacheItem.CacheId))
validDirtyBakes++;
wearableCache[idx].TextureID = face.TextureID;
wearableCache[idx].CacheId = cacheItems[i].CacheId;
wcacheidx.TextureID = face.TextureID;
wcacheidx.CacheId = curCacheItem.CacheId;
hits++;
}
else
{
wearableCache[idx].CacheId = UUID.Zero;
wearableCache[idx].TextureID = UUID.Zero;
wcacheidx.CacheId = UUID.Zero;
wcacheidx.TextureID = UUID.Zero;
missing.Add(face.TextureID);
continue;
}
@ -446,11 +446,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
sp.Appearance.Texture.FaceTextures[idx] = null;
wearableCache[idx].CacheId = UUID.Zero;
wearableCache[idx].TextureID = UUID.Zero;
wearableCache[idx].TextureAsset = null;
var wcacheidx = wearableCache[idx];
wcacheidx.CacheId = UUID.Zero;
wcacheidx.TextureID = UUID.Zero;
wcacheidx.TextureAsset = null;
}
sp.Appearance.WearableCacheItems = wearableCache;
if (missing.Count > 0)
@ -502,19 +503,22 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (cache == null)
return false;
IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
lock (m_setAppearanceLock)
{
WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems;
var spAppearanceTextureFaceTextures = sp.Appearance.Texture.FaceTextures;
/*
// big debug
// m_log.DebugFormat("[AVFACTORY]: ValidateBakedTextureCache start for {0} {1}", sp.Name, sp.UUID);
/*
m_log.DebugFormat("[AVFACTORY]: ValidateBakedTextureCache start for {0} {1}", sp.Name, sp.UUID);
for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++)
{
int j = AvatarAppearance.BAKE_INDICES[iter];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[j];
Primitive.TextureEntryFace face = spAppearanceTextureFaceTextures[j];
if (wearableCache == null)
{
if (face != null)
@ -538,7 +542,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
);
}
}
*/
*/
bool wearableCacheValid = false;
if (wearableCache == null)
@ -552,26 +556,40 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
face = sp.Appearance.Texture.FaceTextures[idx];
if(face == null || face.TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE))
face = spAppearanceTextureFaceTextures[idx];
var wcacheidx = wearableCache[idx];
if (face == null || face.TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE))
{
wearableCache[idx].CacheId = UUID.Zero;
wearableCache[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
wcacheidx.CacheId = UUID.Zero;
wcacheidx.TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
hits++;
continue;
}
if (face.TextureID.Equals(wearableCache[idx].TextureID) && !face.TextureID.IsZero())
if(face.TextureID.IsNotZero())
{
if (cache.Check((wearableCache[idx].TextureID).ToString()))
// fs junk
if (i >= AvatarAppearance.BAKES_COUNT_PV7 && wcacheidx.CacheId.IsZero())
{
spAppearanceTextureFaceTextures[idx] = null;
wcacheidx.CacheId = UUID.Zero;
wcacheidx.TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
hits++;
continue;
}
if (face.TextureID.Equals(wcacheidx.TextureID))
{
if (cache.Check(wcacheidx.TextureID.ToString()))
{
hits++;
continue;
}
}
}
wearableCache[idx].CacheId = UUID.Zero;
wearableCache[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
wcacheidx.CacheId = UUID.Zero;
wcacheidx.TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
wearableCacheValid = false;
}
}
@ -602,16 +620,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
for (int i = 0; i < bakedModuleCache.Length; i++)
{
int j = (int)bakedModuleCache[i].TextureIndex;
if (j < AvatarAppearance.TEXTURE_COUNT && bakedModuleCache[i].TextureAsset != null)
var bacachei = bakedModuleCache[i];
int j = (int)bacachei.TextureIndex;
if (j < AvatarAppearance.TEXTURE_COUNT && bacachei.TextureAsset != null)
{
wearableCache[j].TextureID = bakedModuleCache[i].TextureID;
wearableCache[j].CacheId = bakedModuleCache[i].CacheId;
wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset;
bakedModuleCache[i].TextureAsset.Temporary = true;
bakedModuleCache[i].TextureAsset.Local = true;
var wcachej = wearableCache[j];
wcachej.TextureID = bacachei.TextureID;
wcachej.CacheId = bacachei.CacheId;
wcachej.TextureAsset = bacachei.TextureAsset;
bacachei.TextureAsset.Temporary = true;
bacachei.TextureAsset.Local = true;
//bakedModuleCache[i].TextureAsset.Flags = AssetFlags.AvatarBake;
cache.Cache(bakedModuleCache[i].TextureAsset);
cache.Cache(bacachei.TextureAsset);
}
}
@ -619,36 +639,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
if (wearableCache[idx].TextureAsset == null)
var wcacheidx = wearableCache[idx];
var faceTextureidx = spAppearanceTextureFaceTextures[idx];
if (wcacheidx.TextureAsset == null)
{
if(idx == 19)
{
sp.Appearance.Texture.FaceTextures[idx] = null;
faceTextureidx = null;
hits++;
}
else if(sp.Appearance.Texture.FaceTextures[idx] == null ||
sp.Appearance.Texture.FaceTextures[idx].TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE))
else if(faceTextureidx == null || faceTextureidx.TextureID.Equals(AppearanceManager.DEFAULT_AVATAR_TEXTURE))
hits++;
wearableCache[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
wearableCache[idx].CacheId = UUID.Zero;
wcacheidx.TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
wcacheidx.CacheId = UUID.Zero;
continue;
}
Primitive.TextureEntryFace face = sp.Appearance.Texture.GetFace((uint)idx);
face.TextureID = wearableCache[idx].TextureID;
face.TextureID = wcacheidx.TextureID;
hits++;
wearableCache[idx].TextureAsset = null;
wcacheidx.TextureAsset = null;
}
}
}
sp.Appearance.WearableCacheItems = wearableCache;
}
// debug
// m_log.DebugFormat("[ValidateBakedCache]: Completed texture check for {0} {1} with {2} hits", sp.Name, sp.UUID, hits);
/*
// m_log.DebugFormat("[ValidateBakedCache]: Completed texture check for {0} {1} with {2} hits", sp.Name, sp.UUID, hits);
/*
for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++)
{
int j = AvatarAppearance.BAKE_INDICES[iter];
@ -657,7 +677,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
sp.Appearance.WearableCacheItems[j].CacheId + ", t-" +
sp.Appearance.WearableCacheItems[j].TextureID);
}
*/
*/
return (hits >= AvatarAppearance.BAKE_INDICES.Length); // skirt is optional
}
@ -732,9 +752,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (bakeType == BakeType.Unknown)
continue;
// m_log.DebugFormat(
// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
//m_log.DebugFormat(
// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture
@ -874,184 +894,184 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
}
// IInventoryService invService = m_scene.InventoryService;
// bool resetwearable = false;
// if (invService.GetRootFolder(userID) != null)
// {
// for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
// {
// for (int j = 0; j < appearance.Wearables[i].Count; j++)
// {
// // Check if the default wearables are not set
// if (appearance.Wearables[i][j].ItemID == UUID.Zero)
// {
// switch ((WearableType) i)
// {
// case WearableType.Eyes:
// case WearableType.Hair:
// case WearableType.Shape:
// case WearableType.Skin:
// //case WearableType.Underpants:
// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
// resetwearable = true;
// m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
// resetwearable = true;
// break;
//
// }
// continue;
// }
//
// // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
// if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
// {
// switch ((WearableType)i)
// {
// case WearableType.Eyes:
// case WearableType.Hair:
// case WearableType.Shape:
// case WearableType.Skin:
// //case WearableType.Underpants:
// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
//
// m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
// resetwearable = true;
// break;
//
// }
// continue;
// }
//
// InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
// baseItem = invService.GetItem(baseItem);
//
// if (baseItem != null)
// {
// appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
// int unmodifiedWearableIndexForClosure = i;
// m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
// delegate(string x, object y, AssetBase z)
// {
// if (z == null)
// {
// TryAndRepairBrokenWearable(
// (WearableType)unmodifiedWearableIndexForClosure, invService,
// userID, appearance);
// }
// });
// }
// else
// {
// m_log.ErrorFormat(
// "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
// appearance.Wearables[i][j].ItemID, (WearableType)i);
//
// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
// resetwearable = true;
//
// }
// }
// }
//
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int) WearableType.Eyes] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
//
// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
// appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
// appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int)WearableType.Shape] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
//
// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
// appearance.Wearables[(int)WearableType.Shape][0].ItemID,
// appearance.Wearables[(int)WearableType.Shape][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int)WearableType.Hair] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
//
// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
// appearance.Wearables[(int)WearableType.Hair][0].ItemID,
// appearance.Wearables[(int)WearableType.Hair][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int)WearableType.Skin] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
//
// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
// appearance.Wearables[(int)WearableType.Skin][0].ItemID,
// appearance.Wearables[(int)WearableType.Skin][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// if (resetwearable)
// {
// ScenePresence presence = null;
// if (m_scene.TryGetScenePresence(userID, out presence))
// {
// presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
// presence.Appearance.Serial++);
// }
// }
//
// }
// else
// {
// m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
// }
//IInventoryService invService = m_scene.InventoryService;
//bool resetwearable = false;
//if (invService.GetRootFolder(userID) != null)
//{
// for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
// {
// for (int j = 0; j < appearance.Wearables[i].Count; j++)
// {
// // Check if the default wearables are not set
// if (appearance.Wearables[i][j].ItemID.IsZero())
// {
// switch ((WearableType) i)
// {
// case WearableType.Eyes:
// case WearableType.Hair:
// case WearableType.Shape:
// case WearableType.Skin:
// //case WearableType.Underpants:
// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
// resetwearable = true;
// m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
// resetwearable = true;
// break;
//
// }
// continue;
// }
//
// // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
// if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
// {
// switch ((WearableType)i)
// {
// case WearableType.Eyes:
// case WearableType.Hair:
// case WearableType.Shape:
// case WearableType.Skin:
// //case WearableType.Underpants:
// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
//
// m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
// resetwearable = true;
// break;
//
// }
// continue;
// }
//
// InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
// baseItem = invService.GetItem(baseItem);
//
// if (baseItem != null)
// {
// appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
// int unmodifiedWearableIndexForClosure = i;
// m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
// delegate(string x, object y, AssetBase z)
// {
// if (z == null)
// {
// TryAndRepairBrokenWearable(
// (WearableType)unmodifiedWearableIndexForClosure, invService,
// userID, appearance);
// }
// });
// }
// else
// {
// m_log.ErrorFormat(
// "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
// appearance.Wearables[i][j].ItemID, (WearableType)i);
//
// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
// resetwearable = true;
//
// }
// }
// }
//
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int) WearableType.Eyes] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
//
// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
// appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
// appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int)WearableType.Shape] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
//
// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
// appearance.Wearables[(int)WearableType.Shape][0].ItemID,
// appearance.Wearables[(int)WearableType.Shape][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int)WearableType.Hair] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
//
// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
// appearance.Wearables[(int)WearableType.Hair][0].ItemID,
// appearance.Wearables[(int)WearableType.Hair][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
// if (appearance.Wearables[(int)WearableType.Skin] == null)
// {
// m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
//
// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
// resetwearable = true;
// }
// else
// {
// if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
// {
// m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
// appearance.Wearables[(int)WearableType.Skin][0].ItemID,
// appearance.Wearables[(int)WearableType.Skin][0].AssetID);
// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
// resetwearable = true;
//
// }
//
// }
// if (resetwearable)
// {
// ScenePresence presence = null;
// if (m_scene.TryGetScenePresence(userID, out presence))
// {
// presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
// presence.Appearance.Serial++);
// }
// }
//
//}
//else
//{
// m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
//}
}
private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
@ -1154,7 +1174,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp != null)
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial);
else
m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
}, null, "AvatarFactoryModule.OnClientRequestWearables");
@ -1263,8 +1283,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public void WriteBakedTexturesReport(IScenePresence sp, ReportOutputAction outputAction)
{
outputAction("For {0} in {1}", null, sp.Name, m_scene.RegionInfo.RegionName);
outputAction(BAKED_TEXTURES_REPORT_FORMAT, null, "Bake Type", "UUID");
outputAction("For {0} in {1}", sp.Name, m_scene.RegionInfo.RegionName);
outputAction(BAKED_TEXTURES_REPORT_FORMAT, "Bake Type", "UUID");
Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp.UUID);
@ -1291,11 +1311,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
}
}
outputAction(BAKED_TEXTURES_REPORT_FORMAT, null, bt, rawTextureID);
outputAction(BAKED_TEXTURES_REPORT_FORMAT, bt, rawTextureID);
}
bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp);
outputAction("{0} baked appearance texture is {1}", null, sp.Name, bakedTextureValid ? "OK" : "incomplete");
outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete");
}
public void SetPreferencesHoverZ(UUID agentId, float val)

View file

@ -112,10 +112,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
return;
ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface<ISimulatorFeaturesModule>();
if (featuresModule != null)
featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest;
{
featuresModule.AddOpenSimExtraFeature("say-range", new OSDInteger(m_saydistance));
featuresModule.AddOpenSimExtraFeature("whisper-range", new OSDInteger(m_whisperdistance));
featuresModule.AddOpenSimExtraFeature("shout-range", new OSDInteger(m_shoutdistance));
}
}
public virtual void RemoveRegion(Scene scene)
@ -491,30 +493,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
Timers.Remove(target);
Timer.Dispose();
}
#region SimulatorFeaturesRequest
protected static OSDInteger m_SayRange, m_WhisperRange, m_ShoutRange;
protected virtual void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features)
{
OSD extras;
if (!features.TryGetValue("OpenSimExtras", out extras))
extras = new OSDMap();
if (m_SayRange == null)
{
// Do this only once
m_SayRange = new OSDInteger(m_saydistance);
m_WhisperRange = new OSDInteger(m_whisperdistance);
m_ShoutRange = new OSDInteger(m_shoutdistance);
}
((OSDMap)extras)["say-range"] = m_SayRange;
((OSDMap)extras)["whisper-range"] = m_WhisperRange;
((OSDMap)extras)["shout-range"] = m_ShoutRange;
}
#endregion
}
}

View file

@ -142,12 +142,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
// We must update the scenes in order to make the root new root agents trigger position updates in their
// children.
sceneWest.Update(4);
sceneEast.Update(4);
for (int i = 0; i < 6; ++i)
{
sceneWest.Update(1);
sceneEast.Update(1);
}
sp1.DrawDistance += 64;
sp2.DrawDistance += 64;
sceneWest.Update(2);
sceneEast.Update(2);
for (int i = 0; i < 6; ++i)
{
sceneWest.Update(1);
sceneEast.Update(1);
}
// Check child positions are correct.
Assert.AreEqual(
@ -171,11 +177,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
sp1Position = new Vector3(30, 128, 20);
sp1.AbsolutePosition = sp1Position;
sceneWest.Update(1);
sceneEast.Update(1);
for (int i = 0; i < 2; ++i)
{
sceneWest.Update(1);
sceneEast.Update(1);
}
Thread.Sleep(12000); // child updates are now time limited
sceneWest.Update(5);
sceneEast.Update(5);
for (int i = 0; i < 6; ++i)
{
sceneWest.Update(1);
sceneEast.Update(1);
}
// Check child position is correct.
Assert.AreEqual(
@ -237,12 +249,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
// We must update the scenes in order to make the root new root agents trigger position updates in their
// children.
sceneNorth.Update(4);
sceneSouth.Update(4);
for (int i = 0; i < 6; ++i)
{
sceneNorth.Update(1);
sceneSouth.Update(1);
}
sp1.DrawDistance += 64;
sp2.DrawDistance += 64;
sceneNorth.Update(4);
sceneSouth.Update(4);
for (int i = 0; i < 6; ++i)
{
sceneNorth.Update(1);
sceneSouth.Update(1);
}
// Check child positions are correct.
Assert.AreEqual(
@ -266,11 +284,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
sp1Position = new Vector3(30, 128, 20);
sp1.AbsolutePosition = sp1Position;
sceneNorth.Update(1);
sceneSouth.Update(1);
sceneNorth.Update(6);
sceneSouth.Update(6);
Thread.Sleep(12000); // child updates are now time limited
sceneNorth.Update(5);
sceneSouth.Update(5);
sceneNorth.Update(6);
sceneSouth.Update(6);
// Check child position is correct.
Assert.AreEqual(

View file

@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.FirstName+" "+client.LastName,
destID, (byte)211, false,
String.Empty,
transactionID, false, new Vector3(), new byte[0], true),
transactionID, false, new Vector3(), Array.Empty<byte>(), true),
delegate(bool success) {} );
}
}

View file

@ -179,13 +179,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
if (finfo.TheirFlags != -1)
{
if (!UUID.TryParse(finfo.Friend, out UUID id))
if (Util.ParseFullUniversalUserIdentifier(finfo.Friend, out UUID id, out string url, out string first, out string last))
{
if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out string url, out string first, out string last, out string tmp))
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: caching {0}", finfo.Friend);
uMan.AddUser(id,first,last, url);
}
//m_log.DebugFormat("[HGFRIENDS MODULE]: caching {0}", finfo.Friend);
uMan.AddUser(id,first,last, url);
}
}
}
@ -272,8 +269,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
else
{
// it's a foreign friend
string url = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out string url))
{
// Let's try our luck in the local sim. Who knows, maybe it's here
if (LocalStatusNotification(userID, friendID, online))
@ -303,9 +299,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return true;
// fid is not a UUID...
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out string url, out string f, out string l, out string tmp))
if (Util.ParseFullUniversalUserIdentifier(fid, out agentID, out string url, out string f, out string l))
{
if (!agentID.Equals(UUID.Zero))
if (agentID.IsNotZero())
{
m_uMan.AddUser(agentID, f, l, url);
@ -515,8 +511,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
theFriendUUID = friendUUI;
// If it's confirming the friendship, we already have the full UUI with the secret
if (Util.ParseUniversalUserIdentifier(theFriendUUID, out UUID utmp, out string url,
out string first, out string last, out secret))
if (Util.ParseFullUniversalUserIdentifier(theFriendUUID, out UUID utmp, out string url,
out string first, out string last))
{
agentUUID = agentUUI + ";" + secret;
m_uMan.AddUser(utmp, first, last, url);
@ -757,9 +753,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void Delete(UUID foreignUser, UUID localUser, string uui)
{
UUID id;
string url = string.Empty, secret = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
if (Util.ParseFullUniversalUserIdentifier(uui, out UUID id, out string url, out string tmp, out string tmp1, out string secret))
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);

View file

@ -44,8 +44,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// ASSUMPTION: we assume that all users for one home domain
// have exactly the same set of service URLs.
// If this is ever not true, we need to change this.
UUID friendID = UUID.Zero; String tmp = String.Empty;
if (Util.ParseUniversalUserIdentifier(ids[0], out friendID, out tmp, out tmp, out tmp, out tmp))
if (Util.ParseUniversalUserIdentifier(ids[0], out UUID friendID))
{
string friendsServerURI = m_FriendsModule.UserManagementModule.GetUserServerURL(friendID, "FriendsServerURI");
if (friendsServerURI != string.Empty)

View file

@ -190,8 +190,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
//m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
if (recipientUUI.Length > 0)
{
if (Util.ParseUniversalUserIdentifier(recipientUUI, out UUID id, out string tourl,
out string first, out string last, out string secret))
if (Util.ParseFullUniversalUserIdentifier(recipientUUI, out UUID id, out string tourl,
out string first, out string last) && !string.IsNullOrEmpty(tourl))
{
success = m_IMService.OutgoingInstantMessage(im, tourl, true);
if (success)

View file

@ -225,7 +225,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
uint ParentEstateID=0;
Vector3 Position = Vector3.Zero;
UUID RegionID = UUID.Zero ;
byte[] binaryBucket = new byte[0];
byte[] binaryBucket = Array.Empty<byte>();
float pos_x = 0;
float pos_y = 0;
@ -367,7 +367,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
string requestData3 = (string)requestData["binary_bucket"];
if (string.IsNullOrEmpty(requestData3))
{
binaryBucket = new byte[0];
binaryBucket = Array.Empty<byte>();
}
else
{

View file

@ -132,14 +132,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
client.OnInstantMessage += OnInstantMessage;
}
private Scene FindClientScene(UUID agentId)
private Scene FindClientAndScene(UUID agentId, out ScenePresence presence)
{
presence = null;
lock (m_Scenelist)
{
foreach (Scene scene in m_Scenelist)
{
ScenePresence presence = scene.GetScenePresence(agentId);
if (presence != null)
presence = scene.GetScenePresence(agentId);
if (presence != null && !presence.IsDeleted)
return scene;
}
}
@ -153,7 +154,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
// (InstantMessageDialog)im.dialog, client.Name,
// im.fromAgentID, im.fromAgentName, im.toAgentID);
Scene scene = FindClientScene(client.AgentId);
Scene scene = client.Scene as Scene;
if (scene == null) // Something seriously wrong here.
return;
@ -416,15 +417,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
private void OnGridInstantMessage(GridInstantMessage im)
{
// Check if this is ours to handle
//
Scene scene = FindClientScene(new UUID(im.toAgentID));
UUID recipientID = new UUID(im.toAgentID);
Scene scene = FindClientAndScene(recipientID, out ScenePresence user);
if (scene == null)
return;
// Find agent to deliver to
//
ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
if (user == null)
return;
@ -443,7 +440,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
if (assetType == AssetType.LinkFolder || assetType == AssetType.Link)
return;
UUID recipientID = new UUID(im.toAgentID);
UUID copyID;
if (AssetType.Folder == assetType)
@ -482,8 +478,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
if (im.binaryBucket.Length < 1) // Invalid
return;
UUID recipientID = new UUID(im.toAgentID);
// Bucket is the asset type
AssetType assetType = (AssetType)im.binaryBucket[0];

View file

@ -196,7 +196,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
client.FirstName+" "+client.LastName, targetid,
(byte)InstantMessageDialog.RequestTeleport, false,
message, sessionID, false, presence.AbsolutePosition,
new Byte[0], true);
Array.Empty<byte>(), true);
m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message);

View file

@ -180,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
client.FirstName+" "+client.LastName, targetid,
(byte)InstantMessageDialog.GodLikeRequestTeleport, false,
message, dest, false, presence.AbsolutePosition,
new Byte[0], true);
Array.Empty<byte>(), true);
}
else
{
@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
client.FirstName+" "+client.LastName, targetid,
(byte)InstantMessageDialog.RequestTeleport, false,
message, dest, false, presence.AbsolutePosition,
new Byte[0], true);
Array.Empty<byte>(), true);
}
if (m_TransferModule != null)

View file

@ -49,8 +49,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGEntityTransferModule")]
public class HGEntityTransferModule
: EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule
public class HGEntityTransferModule : EntityTransferModule, IUserAgentVerificationModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -84,19 +83,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Wrong user account name format {0}. Specify 'First Last'", name);
return null;
}
UserAccount account = Scene.UserAccountService.GetUserAccount(UUID.Zero, parts[0], parts[1]);
UserAccount account = m_scene.UserAccountService.GetUserAccount(UUID.Zero, parts[0], parts[1]);
if (account == null)
{
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unknown account {0}", m_AccountName);
return null;
}
AvatarAppearance a = Scene.AvatarService.GetAppearance(account.PrincipalID);
AvatarAppearance a = m_scene.AvatarService.GetAppearance(account.PrincipalID);
if (a != null)
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Successfully retrieved appearance for {0}", name);
foreach (AvatarAttachment att in a.GetAttachments())
{
InventoryItemBase item = Scene.InventoryService.GetItem(account.PrincipalID, att.ItemID);
InventoryItemBase item = m_scene.InventoryService.GetItem(account.PrincipalID, att.ItemID);
if (item != null)
a.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID);
else
@ -214,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected override GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message)
{
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID);
int flags = m_scene.GridService.GetRegionFlags(m_sceneRegionInfo.ScopeID, region.RegionID);
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionName, flags);
message = null;
@ -237,7 +236,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (OutViewRange)
return true;
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
int flags = m_scene.GridService.GetRegionFlags(m_sceneRegionInfo.ScopeID, reg.RegionID);
if (flags == -1 || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
return true;
@ -250,9 +249,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (logout)
{
// Log them out of this grid
Scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
string userId = Scene.UserManagementModule.GetUserUUI(sp.UUID);
Scene.GridUserService.LoggedOut(userId, UUID.Zero, Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
m_scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
string userId = m_scene.UserManagementModule.GetUserUUI(sp.UUID);
m_scene.GridUserService.LoggedOut(userId, UUID.Zero, m_sceneRegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
}
}
@ -261,12 +260,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI);
reason = string.Empty;
logout = false;
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
int flags = Scene.GridService.GetRegionFlags(m_sceneRegionInfo.ScopeID, reg.RegionID);
if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
{
// this user is going to another grid
// for local users, check if HyperGrid teleport is allowed, based on user level
bool isLocal = Scene.UserManagementModule.IsLocalGridUser(sp.UUID);
bool isLocal = m_scene.UserManagementModule.IsLocalGridUser(sp.UUID);
if (isLocal && sp.GodController.UserLevel < m_levelHGTeleport)
{
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel.");
@ -284,7 +283,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
else
connector = new UserAgentServiceConnector(userAgentDriver);
GridRegion source = new GridRegion(Scene.RegionInfo)
GridRegion source = new GridRegion(m_sceneRegionInfo)
{
RawServerURI = m_thisGridInfo.GateKeeperURL
};
@ -293,7 +292,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
logout = success; // flag for later logout from this grid; this is an HG TP
if (success)
Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
m_scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
return success;
}
@ -320,11 +319,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// The rest is only needed for controlling appearance
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
int flags = m_scene.GridService.GetRegionFlags(m_sceneRegionInfo.ScopeID, reg.RegionID);
if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
{
// this user is going to another grid
if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID))
if (m_scene.UserManagementModule.IsLocalGridUser(sp.UUID))
{
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance");
@ -434,7 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public override bool TeleportHome(UUID id, IClientAPI client)
{
// Let's find out if this is a foreign user or a local user
IUserManagement uMan = Scene.RequestModuleInterface<IUserManagement>();
IUserManagement uMan = m_scene.RequestModuleInterface<IUserManagement>();
if (uMan != null && uMan.IsLocalGridUser(id))
{
// local grid user
@ -549,7 +548,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
(string.IsNullOrEmpty(lm.Gatekeeper)) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
ScenePresence sp = Scene.GetScenePresence(remoteClient.AgentId);
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
if (sp == null || sp.IsDeleted || sp.IsInTransit || sp.IsChildAgent || sp.IsNPC)
return;
@ -557,7 +556,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (m_thisGridInfo.IsLocalGrid(gatekeeperHost) != 0)
{
// Local region?
GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
if (info == null)
{
remoteClient.SendTeleportFailed("Landmark region not found");
@ -567,11 +566,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
//check if region on same position and fix local offset
if (Util.CompareRegionHandles(lm.RegionHandle, lm.Position, info.RegionLocX, info.RegionLocY, info.RegionSizeX, info.RegionSizeY, out Vector3 offset))
{
Scene.RequestTeleportLocation(remoteClient, info.RegionHandle, offset,
m_scene.RequestTeleportLocation(remoteClient, info.RegionHandle, offset,
lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
}
else //region may had move to other grid slot. assume the lm position is good
Scene.RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
m_scene.RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
return;
}
@ -593,7 +592,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
RegionFlags = OpenSim.Framework.RegionFlags.Hyperlink
};
string homeURI = Scene.GetAgentHomeURI(remoteClient.AgentId);
string homeURI = m_scene.GetAgentHomeURI(remoteClient.AgentId);
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, lm.RegionID, remoteClient.AgentId, homeURI, out string message);
@ -648,11 +647,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public override bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition)
{
UUID OwnerID = so.OwnerID;
if (Scene.RegionInfo.EstateSettings.IsBanned(OwnerID))
if (m_sceneRegionInfo.EstateSettings.IsBanned(OwnerID))
{
m_log.DebugFormat(
"[HG TRANSFER MODULE]: Denied prim crossing of {0} {1} into {2} for banned avatar {3}",
so.Name, so.UUID, Scene.Name, so.OwnerID);
so.Name, so.UUID, m_sceneName, so.OwnerID);
return false;
}
@ -662,11 +661,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return base.HandleIncomingSceneObject(so, newPosition);
// Equally, we can't use so.AttachedAvatar here.
if (OwnerID.IsZero() || Scene.UserManagementModule.IsLocalGridUser(OwnerID))
if (OwnerID.IsZero() || m_scene.UserManagementModule.IsLocalGridUser(OwnerID))
return base.HandleIncomingSceneObject(so, newPosition);
// foreign user
AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(OwnerID);
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(OwnerID);
if (aCircuit != null)
{
if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) == 0)
@ -689,7 +688,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// so.Name, so.AttachedAvatar, url);
IDictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url, ids);
HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, url, ids);
uuidGatherer.AddForInspection(defso);
while (!uuidGatherer.Complete)
@ -755,6 +754,95 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return true;
}
public override bool HandleIncomingAttachments(ScenePresence sp, List<SceneObjectGroup> attachments)
{
UUID OwnerID = sp.UUID;
if (m_sceneRegionInfo.EstateSettings.IsBanned(OwnerID))
{
m_log.DebugFormat(
"[HG TRANSFER MODULE]: Attachments of banned avatar {0} into {1}", sp.Name, m_sceneName);
return false;
}
if (OwnerID.IsZero() || m_scene.UserManagementModule.IsLocalGridUser(OwnerID))
return base.HandleIncomingAttachments(sp, attachments);
// foreign user
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(OwnerID);
if (aCircuit != null)
{
if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) == 0)
{
// first region in local grid did pull the necessary attachments from the source grid.
base.HandleIncomingAttachments(sp, attachments);
}
else
{
if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
{
ScenePresence defsp = sp;
List<SceneObjectGroup> deftatt = attachments;
List<SceneObjectGroup> toadd = new List<SceneObjectGroup>(deftatt.Count);
m_incomingSceneObjectEngine.QueueJob(
string.Format("HG UUID Gather attachments {0}", defsp.Name), () =>
{
string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
IDictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, url, ids);
foreach (SceneObjectGroup defso in deftatt)
{
uuidGatherer.AddForInspection(defso);
while (!uuidGatherer.Complete)
{
if (sp.IsDeleted)
{
deftatt = null;
defsp = null;
uuidGatherer = null;
toadd = null;
return;
}
uuidGatherer.GatherNext();
}
toadd.Add(defso);
}
deftatt = null;
foreach (UUID id in ids.Keys)
{
int tickStart = Util.EnvironmentTickCount();
uuidGatherer.FetchAsset(id);
int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);
if (sp.IsDeleted || ticksElapsed > 30000)
{
m_log.WarnFormat(
"[HG ENTITY TRANSFER]: Aborting fetch attachments assets for HG user {0}", sp.Name);
defsp = null;
uuidGatherer = null;
toadd = null;
return;
}
}
base.HandleIncomingAttachments(sp, toadd);
defsp = null;
uuidGatherer = null;
toadd = null;
},
OwnerID.ToString());
}
}
}
return true;
}
#endregion
#region IUserAgentVerificationModule
@ -783,7 +871,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
// Let's find out if this is a foreign user or a local user
IUserManagement uMan = Scene.RequestModuleInterface<IUserManagement>();
IUserManagement uMan = m_scene.RequestModuleInterface<IUserManagement>();
// UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, obj.AgentId);
if (uMan != null && uMan.IsLocalGridUser(obj.AgentId))

View file

@ -308,12 +308,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
if (sb == null)
sb = new StringBuilder(512);
i = notFound.Count;
i = notFound.Count - 1;
sb.Append("[HG ASSET MAPPER POST]: did not find embedded UUIDs as assets:\n\t");
for (int j = 0; j < notFound.Count; ++j)
{
sb.Append(notFound[j]);
if (i < j)
if (j < i)
sb.Append(',');
}
m_log.Debug(sb.ToString());
@ -338,12 +338,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
if (sb == null)
sb = new StringBuilder(512);
i = posted.Count;
i = posted.Count - 1;
sb.Append("[HG ASSET MAPPER POST]: Posted assets:\n\t");
for (int j = 0; j < posted.Count; ++j)
{
sb.Append(posted[j]);
if (i < j)
if (j < i)
sb.Append(',');
}
m_log.Debug(sb.ToString());

View file

@ -471,11 +471,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
{
foreach (GridUserInfo uInfo in pinfos)
{
if (uInfo != null && uInfo.UserID.Length >= 36)
if (uInfo != null && uInfo.UserID.Length > 36)
{
string url, first, last, tmp;
UUID u;
if (uInfo.UserID.Length >= 36 && Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp))
if (Util.ParseFullUniversalUserIdentifier(uInfo.UserID, out UUID u, out string url, out string first, out string last))
{
bool isvalid = CheckUrl(url, out bool islocal, out OSHHTPHost host);
var userdata = new UserData();
@ -605,11 +603,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
{
foreach (GridUserInfo uInfo in pinfos)
{
if (uInfo != null && uInfo.UserID.Length >= 36)
if (uInfo != null && uInfo.UserID.Length > 36)
{
string url, first, last, tmp;
UUID uuid;
if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out uuid, out url, out first, out last, out tmp))
if (Util.ParseFullUniversalUserIdentifier(uInfo.UserID, out UUID uuid, out string url, out string first, out string last))
{
bool isvalid = CheckUrl(url, out bool islocal, out OSHHTPHost host);
var userdata = new UserData();
@ -656,6 +652,122 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return ret;
}
public List<UserData> GetKnownUsers(string[] ids, UUID scopeID)
{
if (m_Scenes.Count <= 0)
return new List<UserData>();
var ret = new List<UserData>(ids.Length);
List<string> missing = new List<string>(ids.Length);
var untried = new Dictionary<UUID, UserData>();
foreach (string id in ids)
{
if (!UUID.TryParse(id, out UUID uuid) || uuid.IsZero())
continue;
if (m_userCacheByID.TryGetValue(uuid, out UserData userdata))
{
if (userdata.HasGridUserTried)
{
if (!userdata.IsUnknownUser)
ret.Add(userdata);
continue;
}
else
untried[uuid] = userdata;
}
missing.Add(id);
}
if (missing.Count == 0)
return ret;
ids = null;
List<UserAccount> accounts = m_userAccountService.GetUserAccounts(scopeID, missing);
if (accounts.Count != 0)
{
foreach (UserAccount uac in accounts)
{
if (uac != null)
{
UUID id = uac.PrincipalID;
var userdata = new UserData();
userdata.Id = id;
userdata.FirstName = uac.FirstName;
userdata.LastName = uac.LastName;
userdata.HomeURL = string.Empty;
userdata.IsUnknownUser = false;
userdata.IsLocal = true;
userdata.HasGridUserTried = true;
m_userCacheByID.Add(id, userdata, 1800000);
ret.Add(userdata);
missing.Remove(id.ToString()); // slowww
untried.Remove(id);
}
}
}
if (missing.Count == 0 || m_gridUserService == null)
return ret;
GridUserInfo[] pinfos = m_gridUserService.GetGridUserInfo(missing.ToArray());
missing = null;
if (pinfos.Length > 0)
{
foreach (GridUserInfo uInfo in pinfos)
{
if (uInfo != null && uInfo.UserID.Length > 36)
{
if (Util.ParseFullUniversalUserIdentifier(uInfo.UserID, out UUID uuid, out string url, out string first, out string last))
{
bool isvalid = CheckUrl(url, out bool islocal, out OSHHTPHost host);
var userdata = new UserData();
userdata.Id = uuid;
if (isvalid)
{
if (islocal)
{
userdata.FirstName = first;
userdata.LastName = last;
userdata.HomeURL = string.Empty;
userdata.IsLocal = true;
}
else
{
userdata.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", ".");
userdata.HomeURL = host.URI;
userdata.LastName = "@" + host.HostAndPort;
userdata.IsLocal = false;
}
userdata.IsUnknownUser = false;
userdata.HasGridUserTried = true;
m_userCacheByID.Add(uuid, userdata, 1800000);
untried.Remove(uuid);
ret.Add(userdata);
}
}
else
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID);
}
}
}
foreach (UserData ud in untried.Values)
{
ud.HasGridUserTried = true;
m_userCacheByID.Add(ud.Id, ud, 1800000);
if (!ud.IsUnknownUser)
ret.Add(ud);
}
return ret;
}
public virtual string GetUserHomeURL(UUID userID)
{
if (GetUser(userID, out UserData user) && user != null)
@ -903,9 +1015,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
if (uInfo != null)
{
string url, first, last, tmp;
UUID u;
if (uInfo.UserID.Length >= 36 && Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp))
if (Util.ParseFullUniversalUserIdentifier(uInfo.UserID, out UUID u, out string url, out string first, out string last))
{
bool isvalid = CheckUrl(url, out bool islocal, out OSHHTPHost host);
@ -1237,9 +1347,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
cdt.AddColumn("HomeURL", 40);
cdt.AddColumn("Checked", 10);
ICollection<UserData> copy = m_userCacheByID.Values;
foreach(UserData u in copy)
foreach(UserData u in m_userCacheByID.Values)
{
cdt.AddRow(u.Id, string.Format("{0} {1}", u.FirstName, u.LastName), u.HomeURL, u.HasGridUserTried ? "yes" : "no");
}

View file

@ -567,7 +567,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
if(backImage == null)
{
SetAlpha(ref image1, newAlpha);
byte[] result = new byte[0];
byte[] result = Array.Empty<byte>();
try
{
@ -597,7 +597,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
image1.Dispose();
image2.Dispose();
byte[] result = new byte[0];
byte[] result = Array.Empty<byte>();
try
{

View file

@ -27,11 +27,13 @@
using System;
using System.Collections.Generic;
using System.Net.Security;
using System.Reflection;
using System.Text.RegularExpressions;
using DotNetOpenMail;
using DotNetOpenMail.SmtpAuth;
using System.Security.Cryptography.X509Certificates;
using log4net;
using MailKit;
using MailKit.Net.Smtp;
using MimeKit;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
@ -44,6 +46,12 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EmailModule")]
public class EmailModule : ISharedRegionModule, IEmailModule
{
public class throttleControlInfo
{
public double lastTime;
public double count;
}
//
// Log
//
@ -52,73 +60,162 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
//
// Module vars
//
private IConfigSource m_Config;
private string m_HostName = string.Empty;
//private string m_RegionName = string.Empty;
private string SMTP_SERVER_HOSTNAME = string.Empty;
private bool SMTP_SERVER_TLS = false;
private string SMTP_SERVER_HOSTNAME = null;
private int SMTP_SERVER_PORT = 25;
private string SMTP_SERVER_LOGIN = string.Empty;
private string SMTP_SERVER_PASSWORD = string.Empty;
private MailboxAddress SMTP_MAIL_FROM = null;
private string SMTP_SERVER_LOGIN = null;
private string SMTP_SERVER_PASSWORD = null;
private bool m_enableEmailToExternalObjects = true;
private bool m_enableEmailToSMTP = true;
private ParserOptions m_mailParseOptions;
private int m_MaxQueueSize = 50; // maximum size of an object mail queue
private Dictionary<UUID, List<Email>> m_MailQueues = new Dictionary<UUID, List<Email>>();
private Dictionary<UUID, DateTime> m_LastGetEmailCall = new Dictionary<UUID, DateTime>();
private TimeSpan m_QueueTimeout = new TimeSpan(2, 0, 0); // 2 hours without llGetNextEmail drops the queue
private Dictionary<UUID, double> m_LastGetEmailCall = new Dictionary<UUID, double>();
private Dictionary<UUID, throttleControlInfo> m_ownerThrottles = new Dictionary<UUID, throttleControlInfo>();
private Dictionary<string, throttleControlInfo> m_primAddressThrottles = new Dictionary<string, throttleControlInfo>();
private Dictionary<string, throttleControlInfo> m_SMPTAddressThrottles = new Dictionary<string, throttleControlInfo>();
private double m_QueueTimeout = 30 * 60; // 15min;
private double m_nextQueuesExpire;
private double m_nextOwnerThrottlesExpire;
private double m_nextPrimAddressThrottlesExpire;
private double m_nextSMTPAddressThrottlesExpire;
private string m_InterObjectHostname = "lsl.opensim.local";
private int m_SMTP_MailsPerDay = 100;
private double m_SMTP_MailsRate = 100.0 / 86400.0;
private double m_SMTPLastTime;
private double m_SMTPCount;
private int m_MailsToPrimAddressPerHour = 50;
private double m_MailsToPrimAddressRate = 50.0 / 3600.0;
private int m_MailsToSMTPAddressPerHour = 10;
private double m_MailsToSMTPAddressRate = 20.0 / 3600.0;
private int m_MailsFromOwnerPerHour = 500;
private double m_MailsFromOwnerRate = 500.0 / 3600.0;
private int m_MaxEmailSize = 4096; // largest email allowed by default, as per lsl docs.
private static SslPolicyErrors m_SMTP_SslPolicyErrorsMask;
private bool m_checkSpecName;
private object m_queuesLock = new object();
// Scenes by Region Handle
private Dictionary<ulong, Scene> m_Scenes =
new Dictionary<ulong, Scene>();
private Dictionary<ulong, Scene> m_Scenes = new Dictionary<ulong, Scene>();
private bool m_Enabled = false;
#region ISharedRegionModule
public void Initialise(IConfigSource config)
{
m_Config = config;
IConfig SMTPConfig;
IConfig startupConfig = config.Configs["Startup"];
if(startupConfig == null)
return;
//FIXME: RegionName is correct??
//m_RegionName = scene.RegionInfo.RegionName;
IConfig startupConfig = m_Config.Configs["Startup"];
m_Enabled = (startupConfig.GetString("emailmodule", "DefaultEmailModule") == "DefaultEmailModule");
if(startupConfig.GetString("emailmodule", "DefaultEmailModule") != "DefaultEmailModule")
return;
//Load SMTP SERVER config
try
{
if ((SMTPConfig = m_Config.Configs["SMTP"]) == null)
{
m_Enabled = false;
IConfig SMTPConfig = config.Configs["SMTP"];
if (SMTPConfig == null)
return;
}
if (!SMTPConfig.GetBoolean("enabled", false))
{
m_Enabled = false;
if(!SMTPConfig.GetBoolean("enabled", false))
return;
}
m_HostName = SMTPConfig.GetString("host_domain_header_from", m_HostName);
m_enableEmailToExternalObjects = SMTPConfig.GetBoolean("enableEmailToExternalObjects", m_enableEmailToExternalObjects);
m_enableEmailToSMTP = SMTPConfig.GetBoolean("enableEmailToSMTP", m_enableEmailToSMTP);
m_MailsToPrimAddressPerHour = SMTPConfig.GetInt("MailsToPrimAddressPerHour", m_MailsToPrimAddressPerHour);
m_MailsToPrimAddressRate = m_MailsToPrimAddressPerHour / 3600.0;
m_MailsFromOwnerPerHour = SMTPConfig.GetInt("MailsFromOwnerPerHour", m_MailsFromOwnerPerHour);
m_MailsFromOwnerRate = m_MailsFromOwnerPerHour / 3600.0;
m_mailParseOptions = new ParserOptions()
{
AllowAddressesWithoutDomain = false,
};
m_InterObjectHostname = SMTPConfig.GetString("internal_object_host", m_InterObjectHostname);
SMTP_SERVER_HOSTNAME = SMTPConfig.GetString("SMTP_SERVER_HOSTNAME", SMTP_SERVER_HOSTNAME);
SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT);
SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN);
SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD);
m_checkSpecName = !m_InterObjectHostname.Equals("lsl.secondlife.com");
if (m_enableEmailToSMTP)
{
m_SMTP_MailsPerDay = SMTPConfig.GetInt("SMTP_MailsPerDay", m_SMTP_MailsPerDay);
m_SMTP_MailsRate = m_SMTP_MailsPerDay / 86400.0;
m_MailsToSMTPAddressPerHour = SMTPConfig.GetInt("MailsToSMTPAddressPerHour", m_MailsToPrimAddressPerHour);
m_MailsToSMTPAddressRate = m_MailsToPrimAddressPerHour / 3600.0;
SMTP_SERVER_HOSTNAME = SMTPConfig.GetString("SMTP_SERVER_HOSTNAME", SMTP_SERVER_HOSTNAME);
OSHHTPHost hosttmp = new OSHHTPHost(SMTP_SERVER_HOSTNAME, true);
if(!hosttmp.IsResolvedHost)
{
m_log.ErrorFormat("[EMAIL]: could not resolve SMTP_SERVER_HOSTNAME {0}", SMTP_SERVER_HOSTNAME);
return;
}
SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT);
SMTP_SERVER_TLS = SMTPConfig.GetBoolean("SMTP_SERVER_TLS", SMTP_SERVER_TLS);
string smtpfrom = SMTPConfig.GetString("SMTP_SERVER_FROM", string.Empty);
m_HostName = SMTPConfig.GetString("host_domain_header_from", m_HostName);
if (!string.IsNullOrEmpty(smtpfrom) && !MailboxAddress.TryParse(m_mailParseOptions, smtpfrom, out SMTP_MAIL_FROM))
{
m_log.ErrorFormat("[EMAIL]: Invalid SMTP_SERVER_FROM {0}", smtpfrom);
return;
}
SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN);
SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD);
bool VerifyCertChain = SMTPConfig.GetBoolean("SMTP_VerifyCertChain", true);
bool VerifyCertNames = SMTPConfig.GetBoolean("SMTP_VerifyCertNames", true);
m_SMTP_SslPolicyErrorsMask = VerifyCertChain ? 0 : SslPolicyErrors.RemoteCertificateChainErrors;
if (!VerifyCertNames)
m_SMTP_SslPolicyErrorsMask |= SslPolicyErrors.RemoteCertificateNameMismatch;
m_SMTP_SslPolicyErrorsMask = ~m_SMTP_SslPolicyErrorsMask;
}
else
{
m_SMTP_SslPolicyErrorsMask = ~SslPolicyErrors.None;
m_log.Warn("[EMAIL]: SMTP disabled, set enableEmailSMTP to enable");
}
m_MaxEmailSize = SMTPConfig.GetInt("email_max_size", m_MaxEmailSize);
if(m_MaxEmailSize < 256 || m_MaxEmailSize > 1000000)
{
m_log.Warn("[EMAIL]: email_max_size out of range [256, 1000000], Changed to default 4096");
m_MaxEmailSize = 4096;
}
}
catch (Exception e)
{
m_log.Error("[EMAIL]: DefaultEmailModule not configured: " + e.Message);
m_Enabled = false;
return;
}
}
double now = Util.GetTimeStamp();
m_nextQueuesExpire = now + m_QueueTimeout;
m_nextOwnerThrottlesExpire = now + 3600;
m_nextPrimAddressThrottlesExpire = now + 3600;
m_nextSMTPAddressThrottlesExpire = now + 3600;
m_SMTPLastTime = now;
m_SMTPCount = m_SMTP_MailsPerDay;
m_Enabled = true;
}
public void AddRegion(Scene scene)
{
@ -132,14 +229,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
scene.RegisterModuleInterface<IEmailModule>(this);
// Add to scene list
if (m_Scenes.ContainsKey(scene.RegionInfo.RegionHandle))
{
m_Scenes[scene.RegionInfo.RegionHandle] = scene;
}
else
{
m_Scenes.Add(scene.RegionInfo.RegionHandle, scene);
}
m_Scenes[scene.RegionInfo.RegionHandle] = scene;
}
m_log.Info("[EMAIL]: Activated DefaultEmailModule");
@ -173,34 +263,71 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
#endregion
public void AddPartMailBox(UUID objectID)
{
if (m_Enabled)
{
lock (m_queuesLock)
{
if (!m_MailQueues.TryGetValue(objectID, out List<Email> elist))
{
m_MailQueues[objectID] = null;
//TODO external global
}
}
}
}
public void RemovePartMailBox(UUID objectID)
{
if (m_Enabled)
{
lock (m_queuesLock)
{
m_LastGetEmailCall.Remove(objectID);
if (m_MailQueues.Remove(objectID))
{
//TODO external global
}
}
}
}
public void InsertEmail(UUID to, Email email)
{
// It's tempting to create the queue here. Don't; objects which have
// not yet called GetNextEmail should have no queue, and emails to them
// should be silently dropped.
lock (m_MailQueues)
lock (m_queuesLock)
{
if (m_MailQueues.ContainsKey(to))
if (m_MailQueues.TryGetValue(to, out List<Email> elist))
{
if (m_MailQueues[to].Count >= m_MaxQueueSize)
if(elist == null)
{
// fail silently
return;
elist = new List<Email>();
elist.Add(email);
m_MailQueues[to] = elist;
}
lock (m_MailQueues[to])
else
{
m_MailQueues[to].Add(email);
if (elist.Count >= m_MaxQueueSize)
return;
lock (elist)
elist.Add(email);
}
m_LastGetEmailCall[to] = Util.GetTimeStamp() + m_QueueTimeout;
}
}
}
private bool IsLocal(UUID objectID)
{
string unused;
return (null != findPrim(objectID, out unused));
lock (m_Scenes)
{
foreach (Scene s in m_Scenes.Values)
{
if (s.GetSceneObjectPart(objectID) != null)
return true;
}
}
return false;
}
private SceneObjectPart findPrim(UUID objectID, out string ObjectRegionName)
@ -212,10 +339,9 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
SceneObjectPart part = s.GetSceneObjectPart(objectID);
if (part != null)
{
ObjectRegionName = s.RegionInfo.RegionName;
uint localX = s.RegionInfo.WorldLocX;
uint localY = s.RegionInfo.WorldLocY;
ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")";
RegionInfo sri = s.RegionInfo;
ObjectRegionName = sri.RegionName;
ObjectRegionName = ObjectRegionName + " (" + sri.WorldLocX + ", " + sri.WorldLocY + ")";
return part;
}
}
@ -226,25 +352,24 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
private bool resolveNamePositionRegionName(UUID objectID, out string ObjectName, out string ObjectAbsolutePosition, out string ObjectRegionName)
{
ObjectName = ObjectAbsolutePosition = ObjectRegionName = String.Empty;
string m_ObjectRegionName;
int objectLocX;
int objectLocY;
int objectLocZ;
SceneObjectPart part = findPrim(objectID, out m_ObjectRegionName);
SceneObjectPart part = findPrim(objectID, out ObjectRegionName);
if (part != null)
{
objectLocX = (int)part.AbsolutePosition.X;
objectLocY = (int)part.AbsolutePosition.Y;
objectLocZ = (int)part.AbsolutePosition.Z;
ObjectAbsolutePosition = "(" + objectLocX + ", " + objectLocY + ", " + objectLocZ + ")";
Vector3 pos = part.AbsolutePosition;
ObjectAbsolutePosition = "(" + (int)pos.X + ", " + (int)pos.Y + ", " + (int)pos.Z + ")";
ObjectName = part.Name;
ObjectRegionName = m_ObjectRegionName;
return true;
}
ObjectName = ObjectAbsolutePosition = ObjectRegionName = string.Empty;
return false;
}
public static bool smptValidateServerCertificate(object sender, X509Certificate certificate,
X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return (sslPolicyErrors & m_SMTP_SslPolicyErrorsMask) == SslPolicyErrors.None;
}
/// <summary>
/// SendMail function utilized by llEMail
/// </summary>
@ -252,70 +377,137 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
/// <param name="address"></param>
/// <param name="subject"></param>
/// <param name="body"></param>
public void SendEmail(UUID objectID, string address, string subject, string body)
public void SendEmail(UUID objectID, UUID ownerID, string address, string subject, string body)
{
//Check if address is empty
if (address.Length == 0)
//Check if address is empty or too large
if(string.IsNullOrEmpty(address))
return;
address = address.Trim();
if (address.Length == 0 || address.Length > 320)
return;
//FIXED:Check the email is correct form in REGEX
string EMailpatternStrict = @"^(([^<>()[\]\\.,;:\s@\""]+"
+ @"(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@"
+ @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
+ @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+"
+ @"[a-zA-Z]{2,}))$";
Regex EMailreStrict = new Regex(EMailpatternStrict);
bool isEMailStrictMatch = EMailreStrict.IsMatch(address);
if (!isEMailStrictMatch)
double now = Util.GetTimeStamp();
throttleControlInfo tci;
lock (m_ownerThrottles)
{
m_log.Error("[EMAIL]: REGEX Problem in EMail Address: "+address);
if (m_ownerThrottles.TryGetValue(ownerID, out tci))
{
tci.count += (now - tci.lastTime) * m_MailsFromOwnerRate;
tci.lastTime = now;
if (tci.count > m_MailsFromOwnerPerHour)
tci.count = m_MailsFromOwnerPerHour;
else if (tci.count <= 0)
return;
--tci.count;
}
else
{
tci = new throttleControlInfo
{
lastTime = now,
count = m_MailsFromOwnerPerHour
};
m_ownerThrottles[ownerID] = tci;
}
}
string addressLower = address.ToLower();
if (!MailboxAddress.TryParse(address, out MailboxAddress mailTo))
{
m_log.ErrorFormat("[EMAIL]: invalid TO email address {0}",address);
return;
}
if ((subject.Length + body.Length) > m_MaxEmailSize)
{
m_log.Error("[EMAIL]: subject + body larger than limit of " + m_MaxEmailSize + " bytes");
return;
}
string LastObjectName = string.Empty;
string LastObjectPosition = string.Empty;
string LastObjectRegionName = string.Empty;
if (!resolveNamePositionRegionName(objectID, out LastObjectName, out LastObjectPosition, out LastObjectRegionName))
if (!resolveNamePositionRegionName(objectID, out string LastObjectName, out string LastObjectPosition, out string LastObjectRegionName))
return;
if (!address.EndsWith(m_InterObjectHostname))
string objectIDstr = objectID.ToString();
if (!address.EndsWith(m_InterObjectHostname, StringComparison.InvariantCultureIgnoreCase) &&
!(m_checkSpecName && address.EndsWith("lsl.secondlife.com", StringComparison.InvariantCultureIgnoreCase)))
{
if(!m_enableEmailToSMTP)
return; //smtp disabled
m_SMTPCount += (m_SMTPLastTime - now) * m_SMTP_MailsRate;
m_SMTPLastTime = now;
if (m_SMTPCount > m_SMTP_MailsPerDay)
m_SMTPCount = m_SMTP_MailsPerDay;
else if (m_SMTPCount <= 0)
return;
--m_SMTPCount;
lock (m_SMPTAddressThrottles)
{
if (m_SMPTAddressThrottles.TryGetValue(addressLower, out tci))
{
tci.count += (now - tci.lastTime) * m_MailsToSMTPAddressRate;
tci.lastTime = now;
if (tci.count > m_MailsToSMTPAddressPerHour)
tci.count = m_MailsToSMTPAddressPerHour;
else if (tci.count <= 0)
return;
--tci.count;
}
else
{
tci = new throttleControlInfo
{
lastTime = now,
count = m_MailsToSMTPAddressPerHour
};
m_SMPTAddressThrottles[addressLower] = tci;
}
}
// regular email, send it out
try
{
//Creation EmailMessage
EmailMessage emailMessage = new EmailMessage();
//From
emailMessage.FromAddress = new EmailAddress(objectID.ToString() + "@" + m_HostName);
//To - Only One
emailMessage.AddToAddress(new EmailAddress(address));
//Subject
emailMessage.Subject = subject;
//TEXT Body
if (!resolveNamePositionRegionName(objectID, out LastObjectName, out LastObjectPosition, out LastObjectRegionName))
return;
emailMessage.BodyText = "Object-Name: " + LastObjectName +
"\nRegion: " + LastObjectRegionName + "\nLocal-Position: " +
LastObjectPosition + "\n\n" + body;
MimeMessage mmsg = new MimeMessage();
//Config SMTP Server
//Set SMTP SERVER config
SmtpServer smtpServer=new SmtpServer(SMTP_SERVER_HOSTNAME,SMTP_SERVER_PORT);
// Add authentication only when requested
//
if (SMTP_SERVER_LOGIN != String.Empty && SMTP_SERVER_PASSWORD != String.Empty)
if(SMTP_MAIL_FROM != null)
{
//Authentication
smtpServer.SmtpAuthToken=new SmtpAuthToken(SMTP_SERVER_LOGIN, SMTP_SERVER_PASSWORD);
mmsg.From.Add(SMTP_MAIL_FROM);
mmsg.Subject = "(OSObj" + objectIDstr + ") " + subject;
}
else
{
mmsg.From.Add(MailboxAddress.Parse(objectIDstr + "@" + m_HostName));
mmsg.Subject = subject;
}
mmsg.To.Add(mailTo);
mmsg.Headers["X-Owner-ID"] = ownerID.ToString();
mmsg.Headers["X-Task-ID"] = objectIDstr;
mmsg.Body = new TextPart("plain") {
Text = "Object-Name: " + LastObjectName +
"\nRegion: " + LastObjectRegionName + "\nLocal-Position: " +
LastObjectPosition + "\n\n" + body
};
using (var client = new SmtpClient())
{
if (SMTP_SERVER_TLS)
{
client.ServerCertificateValidationCallback = smptValidateServerCertificate;
client.Connect(SMTP_SERVER_HOSTNAME, SMTP_SERVER_PORT, MailKit.Security.SecureSocketOptions.StartTls);
}
else
client.Connect(SMTP_SERVER_HOSTNAME, SMTP_SERVER_PORT);
if (!string.IsNullOrEmpty(SMTP_SERVER_LOGIN) && !string.IsNullOrEmpty(SMTP_SERVER_PASSWORD))
client.Authenticate(SMTP_SERVER_LOGIN, SMTP_SERVER_PASSWORD);
client.Send(mmsg);
client.Disconnect(true);
}
//Send Email Message
emailMessage.Send(smtpServer);
//Log
m_log.Info("[EMAIL]: EMail sent to: " + address + " from object: " + objectID.ToString() + "@" + m_HostName);
@ -327,25 +519,53 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
}
else
{
// inter object email, keep it in the family
lock (m_primAddressThrottles)
{
if (m_primAddressThrottles.TryGetValue(addressLower, out tci))
{
tci.count += (now - tci.lastTime) * m_MailsToPrimAddressRate;
tci.lastTime = now;
if (tci.count > m_MailsToPrimAddressPerHour)
tci.count = m_MailsToPrimAddressPerHour;
else if (tci.count <= 0)
return;
--tci.count;
}
else
{
tci = new throttleControlInfo
{
lastTime = now,
count = m_MailsToPrimAddressPerHour
};
m_primAddressThrottles[addressLower] = tci;
}
}
// inter object email
int indx = address.IndexOf('@');
if (indx < 0)
return;
if (!UUID.TryParse(address.Substring(0, indx), out UUID toID))
return;
Email email = new Email();
email.time = ((int)((DateTime.UtcNow - new DateTime(1970,1,1,0,0,0)).TotalSeconds)).ToString();
email.time = Util.UnixTimeSinceEpoch().ToString();
email.subject = subject;
email.sender = objectID.ToString() + "@" + m_InterObjectHostname;
email.message = "Object-Name: " + LastObjectName +
"\nRegion: " + LastObjectRegionName + "\nLocal-Position: " +
LastObjectPosition + "\n\n" + body;
string guid = address.Substring(0, address.IndexOf("@"));
UUID toID = new UUID(guid);
if (IsLocal(toID)) // TODO FIX check to see if it is local
if (IsLocal(toID))
{
// object in this region
// object in this instance
InsertEmail(toID, email);
}
else
{
if (!m_enableEmailToExternalObjects)
return;
// object on another region
// TODO FIX
}
@ -361,81 +581,119 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
/// <returns></returns>
public Email GetNextEmail(UUID objectID, string sender, string subject)
{
List<Email> queue = null;
lock (m_LastGetEmailCall)
double now = Util.GetTimeStamp();
double lasthour = now - 3600;
lock (m_ownerThrottles)
{
if (m_LastGetEmailCall.ContainsKey(objectID))
if (m_ownerThrottles.Count > 0 && now > m_nextOwnerThrottlesExpire)
{
m_LastGetEmailCall.Remove(objectID);
}
m_LastGetEmailCall.Add(objectID, DateTime.Now);
// Hopefully this isn't too time consuming. If it is, we can always push it into a worker thread.
DateTime now = DateTime.Now;
List<UUID> removal = new List<UUID>();
foreach (UUID uuid in m_LastGetEmailCall.Keys)
{
if ((now - m_LastGetEmailCall[uuid]) > m_QueueTimeout)
List<UUID> removal = new List<UUID>(m_ownerThrottles.Count);
foreach (KeyValuePair<UUID, throttleControlInfo> kpv in m_ownerThrottles)
{
removal.Add(uuid);
if (kpv.Value.lastTime < lasthour)
removal.Add(kpv.Key);
}
}
foreach (UUID remove in removal)
{
m_LastGetEmailCall.Remove(remove);
lock (m_MailQueues)
{
m_MailQueues.Remove(remove);
}
foreach (UUID remove in removal)
m_ownerThrottles.Remove(remove);
m_nextOwnerThrottlesExpire = now + 3600;
}
}
lock (m_MailQueues)
lock (m_primAddressThrottles)
{
if (m_MailQueues.ContainsKey(objectID))
if (m_primAddressThrottles.Count > 0 && now > m_nextPrimAddressThrottlesExpire)
{
queue = m_MailQueues[objectID];
List<string> removal = new List<string>(m_primAddressThrottles.Count);
foreach (KeyValuePair<string, throttleControlInfo> kpv in m_primAddressThrottles)
{
if (kpv.Value.lastTime < lasthour)
removal.Add(kpv.Key);
}
foreach (string remove in removal)
m_primAddressThrottles.Remove(remove);
m_nextPrimAddressThrottlesExpire = now + 3600;
}
}
if (queue != null)
lock (m_SMPTAddressThrottles)
{
lock (queue)
if (m_SMPTAddressThrottles.Count > 0 && now > m_nextSMTPAddressThrottlesExpire)
{
if (queue.Count > 0)
List<string> removal = new List<string>(m_SMPTAddressThrottles.Count);
foreach (KeyValuePair<string, throttleControlInfo> kpv in m_SMPTAddressThrottles)
{
int i;
if (kpv.Value.lastTime < lasthour)
removal.Add(kpv.Key);
}
for (i = 0; i < queue.Count; i++)
foreach (string remove in removal)
m_SMPTAddressThrottles.Remove(remove);
m_nextSMTPAddressThrottlesExpire = now + 3600;
}
}
lock (m_queuesLock)
{
m_LastGetEmailCall[objectID] = now + m_QueueTimeout;
if(m_LastGetEmailCall.Count > 1 && now > m_nextQueuesExpire)
{
List<UUID> removal = new List<UUID>(m_LastGetEmailCall.Count);
foreach (KeyValuePair<UUID, double> kpv in m_LastGetEmailCall)
{
if (kpv.Value < now)
removal.Add(kpv.Key);
}
foreach (UUID remove in removal)
{
m_LastGetEmailCall.Remove(remove);
m_MailQueues[remove] = null;
}
m_nextQueuesExpire = now + m_QueueTimeout;
}
m_MailQueues.TryGetValue(objectID, out List<Email> queue);
if (queue != null)
{
lock (queue)
{
if (queue.Count > 0)
{
if ((sender == null || sender.Equals("") || sender.Equals(queue[i].sender)) &&
(subject == null || subject.Equals("") || subject.Equals(queue[i].subject)))
bool emptySender = string.IsNullOrEmpty(sender);
bool emptySubject = string.IsNullOrEmpty(subject);
int i;
Email ret;
for (i = 0; i < queue.Count; i++)
{
break;
ret = queue[i];
if (emptySender || sender.Equals(ret.sender, StringComparison.InvariantCultureIgnoreCase) &&
(emptySubject || subject.Equals(ret.subject, StringComparison.InvariantCultureIgnoreCase)))
{
if (queue.Count == 1)
{
m_MailQueues[objectID] = null;
m_LastGetEmailCall.Remove(objectID);
ret.numLeft = 0;
}
else
{
queue.RemoveAt(i);
ret.numLeft = queue.Count;
}
return ret;
}
}
}
if (i != queue.Count)
{
Email ret = queue[i];
queue.Remove(ret);
ret.numLeft = queue.Count;
return ret;
}
}
}
}
else
{
lock (m_MailQueues)
{
m_MailQueues.Add(objectID, new List<Email>());
}
}
return null;
}
}

View file

@ -201,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
RequestState state = (RequestState) result.AsyncState;
WebRequest request = (WebRequest) state.Request;
Stream stream = null;
byte[] imageJ2000 = new byte[0];
byte[] imageJ2000 = Array.Empty<byte>();
Size newSize = new Size(0, 0);
HttpWebResponse response = null;

View file

@ -382,7 +382,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
GDIDraw(data, graph, altDataDelim, out reuseable);
}
byte[] imageJ2000 = new byte[0];
byte[] imageJ2000 = Array.Empty<byte>();
// This code exists for testing purposes, please do not remove.
// if (s_flipper)

View file

@ -646,7 +646,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
rs.SunPosition = 12.0;
rs.ObjectBonus = 1.4;
rs.RestrictPushing = true;
rs.TerrainLowerLimit = 0.4;
rs.TerrainLowerLimit = -17.9;
rs.TerrainRaiseLimit = 17.9;
rs.TerrainTexture1 = UUID.Parse("00000000-0000-0000-0000-000000000020");
rs.TerrainTexture2 = UUID.Parse("00000000-0000-0000-0000-000000000040");
@ -692,7 +692,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1));
Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4));
Assert.That(loadedRs.RestrictPushing, Is.True);
Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4));
Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(-17.9));
Assert.That(loadedRs.TerrainRaiseLimit, Is.EqualTo(17.9));
Assert.That(loadedRs.TerrainTexture1, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000020")));
Assert.That(loadedRs.TerrainTexture2, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000040")));

View file

@ -1,262 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Threading;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.World
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CloudModule")]
public class CloudModule : ICloudModule, INonSharedRegionModule
{
// private static readonly log4net.ILog m_log
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private uint m_frame = 0;
private int m_frameUpdateRate = 1000;
private Random m_rndnums;
private Scene m_scene = null;
private bool m_ready = false;
private bool m_enabled = false;
private float m_cloudDensity = 1.0F;
private float[] cloudCover = new float[16 * 16];
private int m_dataVersion;
private bool m_busy;
private object cloudlock = new object();
public void Initialise(IConfigSource config)
{
IConfig cloudConfig = config.Configs["Cloud"];
if (cloudConfig != null)
{
m_enabled = cloudConfig.GetBoolean("enabled", false);
m_cloudDensity = cloudConfig.GetFloat("density", 0.5F);
m_frameUpdateRate = cloudConfig.GetInt("cloud_update_rate", 1000);
}
}
public void AddRegion(Scene scene)
{
if (!m_enabled)
return;
m_scene = scene;
scene.RegisterModuleInterface<ICloudModule>(this);
int seed = Environment.TickCount;
seed += (int)(scene.RegionInfo.RegionLocX << 16);
seed += (int)(scene.RegionInfo.RegionLocY);
m_rndnums = new Random(seed);
GenerateCloudCover();
m_dataVersion = m_scene.AllocateIntId();
scene.EventManager.OnNewClient += CloudsToClient;
scene.EventManager.OnFrame += CloudUpdate;
m_ready = true;
}
public void RemoveRegion(Scene scene)
{
if (!m_enabled)
return;
m_ready = false;
// Remove our hooks
m_scene.EventManager.OnNewClient -= CloudsToClient;
m_scene.EventManager.OnFrame -= CloudUpdate;
m_scene.UnregisterModuleInterface<ICloudModule>(this);
m_scene = null;
}
public void RegionLoaded(Scene scene)
{
}
public void PostInitialise()
{
}
public void Close()
{
}
public string Name
{
get { return "CloudModule"; }
}
public Type ReplaceableInterface
{
get { return null; }
}
public float CloudCover(int x, int y, int z)
{
float cover = 0f;
x /= 16;
y /= 16;
if (x < 0) x = 0;
if (x > 15) x = 15;
if (y < 0) y = 0;
if (y > 15) y = 15;
if (cloudCover != null)
{
lock(cloudlock)
cover = cloudCover[y * 16 + x];
}
return cover;
}
private void UpdateCloudCover()
{
float[] newCover = new float[16 * 16];
int rowAbove = new int();
int rowBelow = new int();
int columnLeft = new int();
int columnRight = new int();
for (int x = 0; x < 16; x++)
{
if (x == 0)
{
columnRight = x + 1;
columnLeft = 15;
}
else if (x == 15)
{
columnRight = 0;
columnLeft = x - 1;
}
else
{
columnRight = x + 1;
columnLeft = x - 1;
}
for (int y = 0; y< 16; y++)
{
if (y == 0)
{
rowAbove = y + 1;
rowBelow = 15;
}
else if (y == 15)
{
rowAbove = 0;
rowBelow = y - 1;
}
else
{
rowAbove = y + 1;
rowBelow = y - 1;
}
float neighborAverage = (cloudCover[rowBelow * 16 + columnLeft] +
cloudCover[y * 16 + columnLeft] +
cloudCover[rowAbove * 16 + columnLeft] +
cloudCover[rowBelow * 16 + x] +
cloudCover[rowAbove * 16 + x] +
cloudCover[rowBelow * 16 + columnRight] +
cloudCover[y * 16 + columnRight] +
cloudCover[rowAbove * 16 + columnRight] +
cloudCover[y * 16 + x]) / 9;
newCover[y * 16 + x] = ((neighborAverage / m_cloudDensity) + 0.175f) % 1.0f;
newCover[y * 16 + x] *= m_cloudDensity;
}
}
Array.Copy(newCover, cloudCover, 16 * 16);
m_dataVersion++;
}
private void CloudUpdate()
{
if ((!m_ready || m_busy || m_cloudDensity == 0 ||
(m_frame++ % m_frameUpdateRate) != 0))
return;
if(Monitor.TryEnter(cloudlock))
{
m_busy = true;
Util.FireAndForget(delegate
{
try
{
lock(cloudlock)
{
UpdateCloudCover();
m_scene.ForEachClient(delegate(IClientAPI client)
{
client.SendCloudData(m_dataVersion, cloudCover);
});
}
}
finally
{
m_busy = false;
}
},
null, "CloudModuleUpdate");
Monitor.Exit(cloudlock);
}
}
public void CloudsToClient(IClientAPI client)
{
if (m_ready)
{
lock(cloudlock)
client.SendCloudData(m_dataVersion, cloudCover);
}
}
/// <summary>
/// Calculate the cloud cover over the region.
/// </summary>
private void GenerateCloudCover()
{
for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 16; x++)
{
cloudCover[y * 16 + x] = (float)(m_rndnums.NextDouble()); // 0 to 1
cloudCover[y * 16 + x] *= m_cloudDensity;
}
}
}
}
}

View file

@ -187,7 +187,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
private bool Call(GridRegion region, Dictionary<string, object> sendData)
{
string reqString = ServerUtils.BuildQueryString(sendData);
// m_log.DebugFormat("[XESTATE CONNECTOR]: queryString = {0}", reqString);
// m_log.DebugFormat("[ESTATE CONNECTOR]: queryString = {0}", reqString);
try
{
//string url = "";
@ -207,11 +207,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
return indx > 0;
}
else
m_log.DebugFormat("[XESTATE CONNECTOR]: received empty reply");
m_log.DebugFormat("[ESTATE CONNECTOR]: received empty reply");
}
catch (Exception e)
{
m_log.DebugFormat("[XESTATE CONNECTOR]: Exception when contacting remote sim: {0}", e.Message);
m_log.DebugFormat("[ESTATE CONNECTOR]: Exception when contacting remote sim: {0}", e.Message);
}
return false;

View file

@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
m_asset = new AssetBase(UUID.Zero, pClientFilename, type, pRemoteClient.AgentId.ToString())
{
Data = new byte[0],
Data = Array.Empty<byte>(),
Description = "empty",
Local = true,
Temporary = true

View file

@ -26,6 +26,8 @@
*/
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
@ -100,97 +102,115 @@ namespace OpenSim.Region.CoreModules.World.Land
}
#region ILandChannel Members
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObject(float x_float, float y_float)
{
return m_landManagementModule != null ? m_landManagementModule.GetLandObject(x_float, y_float) : null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObject(int localID)
{
return m_landManagementModule != null ? m_landManagementModule.GetLandObject(localID) : null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObject(UUID GlobalID)
{
return m_landManagementModule != null ? m_landManagementModule.GetLandObject(GlobalID) : null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObject(Vector3 position)
{
return GetLandObject(position.X, position.Y);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObject(int x, int y)
{
return m_landManagementModule != null ? m_landManagementModule.GetLandObject(x, y) : null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObjectClippedXY(float x, float y)
{
return m_landManagementModule != null ? m_landManagementModule.GetLandObjectClippedXY(x, y) : null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public List<ILandObject> AllParcels()
{
return m_landManagementModule != null ? m_landManagementModule.AllParcels() : new List<ILandObject>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear(bool setupDefaultParcel)
{
m_landManagementModule?.Clear(setupDefaultParcel);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public List<ILandObject> ParcelsNearPoint(Vector3 position)
{
return m_landManagementModule != null ? m_landManagementModule.ParcelsNearPoint(position) : new List<ILandObject>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsForcefulBansAllowed()
{
return m_landManagementModule != null ? m_landManagementModule.AllowedForcefulBans : false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void UpdateLandObject(int localID, LandData data)
{
m_landManagementModule?.UpdateLandObject(localID, data);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SendParcelsOverlay(IClientAPI client)
{
m_landManagementModule?.SendParcelOverlay(client);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
{
m_landManagementModule?.Join(start_x, start_y, end_x, end_y, attempting_user_id);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
{
m_landManagementModule?.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
{
m_landManagementModule?.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel)
{
m_landManagementModule?.setParcelObjectMaxOverride(overrideDel);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel)
{
m_landManagementModule?.setSimulatorObjectMaxOverride(overrideDel);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)
{
m_landManagementModule?.SetParcelOtherCleanTime(remoteClient, localID, otherCleanTime);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void sendClientInitialLandInfo(IClientAPI remoteClient, bool overlay)
{
m_landManagementModule?.sendClientInitialLandInfo(remoteClient, overlay);

View file

@ -30,7 +30,9 @@ using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using log4net;
using Nini.Config;
using OpenMetaverse;
@ -38,20 +40,18 @@ using OpenMetaverse.StructuredData;
using OpenMetaverse.Messages.Linden;
using Mono.Addins;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.PhysicsModules.SharedBase;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using Extension = Mono.Addins.ExtensionAttribute;
namespace OpenSim.Region.CoreModules.World.Land
{
// used for caching
@ -72,8 +72,6 @@ namespace OpenSim.Region.CoreModules.World.Land
/// Minimum land unit size in region co-ordinates.
/// </summary>
public const int LandUnit = 4;
private Scene m_scene;
//private LandChannel m_landChannel;
@ -166,7 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Land
m_regionHandler = m_scene.RegionInfo.RegionHandle;
m_regionSizeX = (int)m_scene.RegionInfo.RegionSizeX;
m_regionSizeY = (int)m_scene.RegionInfo.RegionSizeY;
m_landIDList = new int[m_regionSizeX / LandUnit, m_regionSizeY / LandUnit];
m_landIDList = new int[m_regionSizeX / Constants.LandUnit, m_regionSizeY / Constants.LandUnit];
m_scene.LandChannel = this;
@ -309,7 +307,7 @@ namespace OpenSim.Region.CoreModules.World.Land
m_landFakeIDs.Clear();
m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
m_landIDList = new int[m_regionSizeX / LandUnit, m_regionSizeY / LandUnit];
m_landIDList = new int[m_regionSizeX / Constants.LandUnit, m_regionSizeY / Constants.LandUnit];
}
}
@ -458,7 +456,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
{
if (m_scene.RegionInfo.RegionID == regionID)
if (m_scene.RegionInfo.RegionID.Equals(regionID))
{
ILandObject parcelAvatarIsEntering;
lock (m_landList)
@ -467,7 +465,7 @@ namespace OpenSim.Region.CoreModules.World.Land
}
if (parcelAvatarIsEntering != null &&
avatar.currentParcelUUID != parcelAvatarIsEntering.LandData.GlobalID)
avatar.currentParcelUUID.NotEqual(parcelAvatarIsEntering.LandData.GlobalID))
{
SendLandUpdate(avatar, parcelAvatarIsEntering);
avatar.currentParcelUUID = parcelAvatarIsEntering.LandData.GlobalID;
@ -581,7 +579,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if(ldata == null)
return;
if(ldata.OwnerID == targetID)
if(ldata.OwnerID.Equals(targetID))
return;
if(ldata.PassHours == 0)
@ -605,7 +603,7 @@ namespace OpenSim.Region.CoreModules.World.Land
int idx = land.LandData.ParcelAccessList.FindIndex(
delegate(LandAccessEntry e)
{
if (e.AgentID == targetID && e.Flags == AccessList.Access)
if (e.Flags == AccessList.Access && e.AgentID.Equals(targetID))
return true;
return false;
});
@ -997,7 +995,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
try
{
return m_landList[m_landIDList[avx / LandUnit, avy / LandUnit]];
return m_landList[m_landIDList[avx / Constants.LandUnit, avy / Constants.LandUnit]];
}
catch (IndexOutOfRangeException)
{
@ -1008,11 +1006,13 @@ namespace OpenSim.Region.CoreModules.World.Land
// Public entry.
// Throws exception if land object is not found
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObject(int x, int y)
{
return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds)
{
if (x >= m_regionSizeX || y >= m_regionSizeY || x < 0 || y < 0)
@ -1032,15 +1032,16 @@ namespace OpenSim.Region.CoreModules.World.Land
{
try
{
return m_landList[m_landIDList[x / LandUnit, y / LandUnit]];
return m_landList[m_landIDList[x / Constants.LandUnit, y / Constants.LandUnit]];
}
catch (IndexOutOfRangeException)
{
return null;
return null;
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObjectinLandUnits(int x, int y)
{
if (m_landList.Count == 0 || m_landIDList == null)
@ -1059,6 +1060,7 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject GetLandObjectinLandUnitsInt(int x, int y)
{
lock (m_landIDList)
@ -1074,6 +1076,7 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetLandObjectIDinLandUnits(int x, int y)
{
lock (m_landIDList)
@ -1230,6 +1233,7 @@ namespace OpenSim.Region.CoreModules.World.Land
}
//Loop through the points
int area = 0;
try
{
for (int y = start_y; y < end_y; y++)
@ -1241,6 +1245,7 @@ namespace OpenSim.Region.CoreModules.World.Land
return;
if (tempLandObject != startLandObject)
return;
area++;
}
}
}
@ -1249,6 +1254,13 @@ namespace OpenSim.Region.CoreModules.World.Land
return;
}
LandData startLandData = startLandObject.LandData;
if (area >= startLandData.Area)
{
// split is a replace, keep as is
return;
}
//Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
ILandObject newLand = startLandObject.Copy();
LandData newLandData = newLand.LandData;
@ -1269,7 +1281,7 @@ namespace OpenSim.Region.CoreModules.World.Land
lock (m_landList)
{
m_landList[startLandObjectIndex].SetLandBitmap(newLand.ModifyLandBitmapSquare(startLandObject.GetLandBitmap(), start_x, start_y, end_x, end_y, false));
m_landList[startLandObjectIndex].ForceUpdateLandInfo();
//m_landList[startLandObjectIndex].ForceUpdateLandInfo();
}
UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData);
@ -1395,12 +1407,12 @@ namespace OpenSim.Region.CoreModules.World.Land
int byteArrayCount = 0;
int sequenceID = 0;
int sx = m_regionSizeX / LandUnit;
int sx = m_regionSizeX / Constants.LandUnit;
byte curByte;
byte tmpByte;
// Layer data is in LandUnit (4m) chunks
for (int y = 0; y < m_regionSizeY / LandUnit; ++y)
for (int y = 0; y < m_regionSizeY / Constants.LandUnit; ++y)
{
for (int x = 0; x < sx;)
{
@ -1413,7 +1425,7 @@ namespace OpenSim.Region.CoreModules.World.Land
continue;
// types
if (currentParcel.LandData.OwnerID == remote_client.AgentId)
if (currentParcel.LandData.OwnerID.Equals(remote_client.AgentId))
{
//Owner Flag
curByte = LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
@ -1537,8 +1549,8 @@ namespace OpenSim.Region.CoreModules.World.Land
if (start_x >= m_regionSizeX || start_y >= m_regionSizeX || end_x > m_regionSizeX || end_y > m_regionSizeY)
return;
if (end_x - start_x <= LandUnit &&
end_y - start_y <= LandUnit)
if (end_x - start_x <= Constants.LandUnit &&
end_y - start_y <= Constants.LandUnit)
{
ILandObject parcel = GetLandObject(start_x, start_y);
if(parcel != null)
@ -1546,10 +1558,10 @@ namespace OpenSim.Region.CoreModules.World.Land
return;
}
start_x /= LandUnit;
start_y /= LandUnit;
end_x /= LandUnit;
end_y /= LandUnit;
start_x /= Constants.LandUnit;
start_y /= Constants.LandUnit;
end_x /= Constants.LandUnit;
end_y /= Constants.LandUnit;
//Get the land objects within the bounds
Dictionary<int, ILandObject> temp = new Dictionary<int, ILandObject>();
@ -1612,7 +1624,7 @@ namespace OpenSim.Region.CoreModules.World.Land
else if (land == aland)
aland.SendLandProperties(0, true, LandChannel.LAND_RESULT_SINGLE, client);
}
if (avatar.currentParcelUUID == parcelID)
if (avatar.currentParcelUUID.Equals(parcelID))
avatar.currentParcelUUID = parcelID; // force parcel flags review
});
}
@ -1831,9 +1843,9 @@ namespace OpenSim.Region.CoreModules.World.Land
IncomingLandObjectFromStorage(data[i]);
// Layer data is in LandUnit (4m) chunks
for (int y = 0; y < m_regionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
for (int y = 0; y < m_regionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / Constants.LandUnit); y++)
{
for (int x = 0; x < m_regionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
for (int x = 0; x < m_regionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / Constants.LandUnit); x++)
{
if (m_landIDList[x, y] == 0)
{
@ -2179,7 +2191,7 @@ namespace OpenSim.Region.CoreModules.World.Land
else if (args.TryGetValue("region_id", out tmp) && tmp is OSDUUID)
{
UUID regionID = tmp.AsUUID();
if (regionID == m_scene.RegionInfo.RegionID)
if (regionID.Equals(m_scene.RegionInfo.RegionID))
{
ILandObject l = GetLandObjectClippedXY(x, y);
if (l != null)
@ -2423,7 +2435,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
{
if (e.OwnerID == targetID)
if (e.OwnerID.Equals(targetID))
{
returns.Add(e);
}
@ -2434,7 +2446,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
{
if (e.OwnerID == targetID)
if (e.OwnerID.Equals(targetID))
{
if (e.ContainsScripts())
{
@ -2447,7 +2459,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
{
if (e.OwnerID == targetID)
if (e.OwnerID.Equals(targetID))
{
ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
if (landobject.LandData.OwnerID != e.OwnerID)
@ -2594,7 +2606,7 @@ namespace OpenSim.Region.CoreModules.World.Land
m_scene.Permissions.IsAdministrator(remoteClient.AgentId) ||
m_scene.Permissions.IsGod(remoteClient.AgentId) ||
// (b) land owners can set home
remoteClient.AgentId == land.LandData.OwnerID ||
remoteClient.AgentId.Equals(land.LandData.OwnerID) ||
// (c) members of the land-associated group in roles that can set home
((gpowers & (ulong)GroupPowers.AllowSetHome) == (ulong)GroupPowers.AllowSetHome) ||
// (d) parcels with telehubs can be the home of anyone

View file

@ -28,6 +28,8 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
@ -49,17 +51,22 @@ namespace OpenSim.Region.CoreModules.World.Land
protected const int GROUPMEMBERCACHETIMEOUT = 30000; // cache invalidation after 30s
private readonly int landUnit = 4;
private int m_lastSeqId = 0;
private int m_lastSeqId = 0;
private int m_expiryCounter = 0;
protected Scene m_scene;
protected readonly Scene m_scene;
protected readonly int m_regionSizeX;
protected readonly int m_regionSizeY;
protected readonly RegionInfo m_regionInfo;
protected readonly RegionSettings m_regionSettings;
protected readonly ScenePermissions m_scenePermissions;
protected readonly EstateSettings m_estateSettings;
protected readonly List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
private readonly Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
private readonly ExpiringCacheOS<uint, UUID> m_listTransactions = new ExpiringCacheOS<uint, UUID>(30000);
private readonly object m_listTransactionsLock = new object();
protected readonly ExpiringCacheOS<UUID, bool> m_groupMemberCache = new ExpiringCacheOS<UUID, bool>();
protected readonly ExpiringCacheOS<UUID, bool> m_groupMemberCache = new ExpiringCacheOS<UUID, bool>(30000);
IDwellModule m_dwellModule;
private bool[,] m_landBitmap;
@ -130,7 +137,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public UUID RegionUUID
{
get { return m_scene.RegionInfo.RegionID; }
get { return m_regionInfo.RegionID; }
}
private Vector2 m_startPoint = Vector2.Zero;
@ -164,11 +171,13 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ISceneObject[] GetSceneObjectGroups()
{
return primsOverMe.ToArray();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector2? GetNearestPoint(Vector3 pos)
{
Vector3 direction = new Vector3(m_centerPoint.X - pos.X, m_centerPoint.Y - pos.Y, 0f );
@ -180,8 +189,8 @@ namespace OpenSim.Region.CoreModules.World.Land
Vector2 testpos;
Vector2 direction;
testpos.X = pos.X / landUnit;
testpos.Y = pos.Y / landUnit;
testpos.X = pos.X / Constants.LandUnit;
testpos.Y = pos.Y / Constants.LandUnit;
if(LandBitmap[(int)testpos.X, (int)testpos.Y])
return new Vector2(pos.X, pos.Y); // we are already here
@ -194,8 +203,8 @@ namespace OpenSim.Region.CoreModules.World.Land
direction.Normalize();
int minx = (int)(m_AABBmin.X / landUnit);
int maxx = (int)(m_AABBmax.X / landUnit);
int minx = (int)(m_AABBmin.X / Constants.LandUnit);
int maxx = (int)(m_AABBmax.X / Constants.LandUnit);
// check against AABB
if(direction.X > 0f)
@ -220,8 +229,8 @@ namespace OpenSim.Region.CoreModules.World.Land
return null; // will never get there
}
int miny = (int)(m_AABBmin.Y / landUnit);
int maxy = (int)(m_AABBmax.Y / landUnit);
int miny = (int)(m_AABBmin.Y / Constants.LandUnit);
int maxy = (int)(m_AABBmax.Y / Constants.LandUnit);
if(direction.Y > 0f)
{
@ -259,13 +268,13 @@ namespace OpenSim.Region.CoreModules.World.Land
return null;
}
testpos *= landUnit;
testpos *= Constants.LandUnit;
float ftmp;
if(Math.Abs(direction.X) > Math.Abs(direction.Y))
{
if(direction.X < 0)
testpos.X += landUnit - 0.5f;
testpos.X += Constants.LandUnit - 0.5f;
else
testpos.X += 0.5f;
ftmp = testpos.X - pos.X;
@ -278,7 +287,7 @@ namespace OpenSim.Region.CoreModules.World.Land
ftmp = testpos.Y + .5f;
else
{
testpos.Y += landUnit - 0.5f;
testpos.Y += Constants.LandUnit - 0.5f;
if(ftmp > testpos.Y)
ftmp = testpos.Y;
}
@ -287,7 +296,7 @@ namespace OpenSim.Region.CoreModules.World.Land
else
{
if(direction.Y < 0)
testpos.Y += landUnit - 0.5f;
testpos.Y += Constants.LandUnit - 0.5f;
else
testpos.Y += 0.5f;
ftmp = testpos.Y - pos.Y;
@ -300,7 +309,7 @@ namespace OpenSim.Region.CoreModules.World.Land
ftmp = testpos.X + .5f;
else
{
testpos.X += landUnit - 0.5f;
testpos.X += Constants.LandUnit - 0.5f;
if(ftmp > testpos.X)
ftmp = testpos.X;
}
@ -316,6 +325,14 @@ namespace OpenSim.Region.CoreModules.World.Land
{
LandData = landData.Copy();
m_scene = scene;
m_scenePermissions = scene.Permissions;
m_regionInfo = scene.RegionInfo;
m_regionSettings = scene.RegionInfo.RegionSettings;
m_estateSettings = m_regionInfo.EstateSettings;
m_regionSizeX = (int)m_regionInfo.RegionSizeX;
m_regionSizeY = (int)m_regionInfo.RegionSizeY;
m_scene.EventManager.OnFrame += OnFrame;
m_dwellModule = m_scene.RequestModuleInterface<IDwellModule>();
}
@ -324,10 +341,21 @@ namespace OpenSim.Region.CoreModules.World.Land
{
m_scene = scene;
if (m_scene == null)
LandBitmap = new bool[Constants.RegionSize / landUnit, Constants.RegionSize / landUnit];
{
m_regionSizeX = (int)Constants.RegionSize;
m_regionSizeY = (int)Constants.RegionSize;
LandBitmap = new bool[Constants.RegionSize / Constants.LandUnit, Constants.RegionSize / Constants.LandUnit];
}
else
{
LandBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
m_scenePermissions = scene.Permissions;
m_regionInfo = scene.RegionInfo;
m_regionSettings = scene.RegionInfo.RegionSettings;
m_estateSettings = m_regionInfo.EstateSettings;
m_regionSizeX = (int)m_regionInfo.RegionSizeX;
m_regionSizeY = (int)m_regionInfo.RegionSizeY;
LandBitmap = new bool[m_regionSizeX / Constants.LandUnit, m_regionSizeY / Constants.LandUnit];
m_dwellModule = m_scene.RequestModuleInterface<IDwellModule>();
}
@ -368,11 +396,12 @@ namespace OpenSim.Region.CoreModules.World.Land
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns>Returns true if the piece of land contains the specified point</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool ContainsPoint(int x, int y)
{
if (x >= 0 && y >= 0 && x < m_scene.RegionInfo.RegionSizeX && y < m_scene.RegionInfo.RegionSizeY)
if (x >= 0 && y >= 0 && x < m_regionSizeX && y < m_regionSizeY)
{
return LandBitmap[x / landUnit, y / landUnit];
return LandBitmap[x / Constants.LandUnit, y / Constants.LandUnit];
}
else
{
@ -380,6 +409,7 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ILandObject Copy()
{
ILandObject newLand = new LandObject(LandData, m_scene);
@ -390,15 +420,19 @@ namespace OpenSim.Region.CoreModules.World.Land
static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount;
static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel)
{
overrideParcelMaxPrimCount = overrideDel;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel)
{
overrideSimulatorMaxPrimCount = overrideDel;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetParcelMaxPrimCount()
{
if (overrideParcelMaxPrimCount != null)
@ -410,20 +444,21 @@ namespace OpenSim.Region.CoreModules.World.Land
// Normal Calculations
int parcelMax = (int)(
(double)LandData.Area
* (double)m_scene.RegionInfo.ObjectCapacity
* (double)m_scene.RegionInfo.RegionSettings.ObjectBonus
/ (double)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)
* (double)m_regionInfo.ObjectCapacity
* (double)m_regionSettings.ObjectBonus
/ (double)(m_regionSizeX * m_regionSizeY)
+ 0.5 );
if(parcelMax > m_scene.RegionInfo.ObjectCapacity)
parcelMax = m_scene.RegionInfo.ObjectCapacity;
if(parcelMax > m_regionInfo.ObjectCapacity)
parcelMax = m_regionInfo.ObjectCapacity;
//m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax);
//m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_regionInfo.ObjectCapacity, m_regionInfo.RegionSettings.ObjectBonus, parcelMax);
return parcelMax;
}
}
// the total prims a parcel owner can have on a region
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetSimulatorMaxPrimCount()
{
if (overrideSimulatorMaxPrimCount != null)
@ -434,15 +469,15 @@ namespace OpenSim.Region.CoreModules.World.Land
{
//Normal Calculations
int simMax = (int)( (double)LandData.SimwideArea
* (double)m_scene.RegionInfo.ObjectCapacity
* (double)m_scene.RegionInfo.RegionSettings.ObjectBonus
/ (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)
* (double)m_regionInfo.ObjectCapacity
* (double)m_regionSettings.ObjectBonus
/ (long)(m_regionSizeX * m_regionSizeY)
+0.5 );
// sanity check
if(simMax > m_scene.RegionInfo.ObjectCapacity)
simMax = m_scene.RegionInfo.ObjectCapacity;
if(simMax > m_regionInfo.ObjectCapacity)
simMax = m_regionInfo.ObjectCapacity;
//m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}, SimWidePrims {3}",
// LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax, LandData.SimwidePrims);
// LandData.SimwideArea, m_regionInfo.ObjectCapacity, simMax, LandData.SimwidePrims);
return simMax;
}
}
@ -453,7 +488,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
{
if(m_scene.RegionInfo.RegionSettings.AllowDamage)
if(m_regionSettings.AllowDamage)
remote_client.SceneAgent.Invulnerable = false;
else
remote_client.SceneAgent.Invulnerable = (m_landData.Flags & (uint)ParcelFlags.AllowDamage) == 0;
@ -484,7 +519,7 @@ namespace OpenSim.Region.CoreModules.World.Land
remote_client.SendLandProperties(seq_id,
snap_selection, request_result, this,
(float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
(float)m_regionSettings.ObjectBonus,
GetParcelMaxPrimCount(),
GetSimulatorMaxPrimCount(), regionFlags);
}
@ -502,7 +537,7 @@ namespace OpenSim.Region.CoreModules.World.Land
// ParcelFlags.ForSaleObjects
// ParcelFlags.LindenHome
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, false))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, false))
{
allowedDelta |= (uint)(ParcelFlags.AllowLandmark |
ParcelFlags.AllowTerraform |
@ -520,7 +555,7 @@ namespace OpenSim.Region.CoreModules.World.Land
newData.GroupAVSounds = args.GroupAVSounds;
}
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale, true))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale, true))
{
if (args.AuthBuyerID != newData.AuthBuyerID ||
args.SalePrice != newData.SalePrice)
@ -545,7 +580,7 @@ namespace OpenSim.Region.CoreModules.World.Land
allowedDelta |= (uint)ParcelFlags.ForSale;
}
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces, false))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces, false))
{
newData.Category = args.Category;
@ -554,21 +589,21 @@ namespace OpenSim.Region.CoreModules.World.Land
ParcelFlags.MaturePublish) | (uint)(1 << 23);
}
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity, false))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity, false))
{
newData.Description = args.Desc;
newData.Name = args.Name;
newData.SnapshotID = args.SnapshotID;
}
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint, false))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint, false))
{
newData.LandingType = args.LandingType;
newData.UserLocation = args.UserLocation;
newData.UserLookAt = args.UserLookAt;
}
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia, false))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia, false))
{
newData.MediaAutoScale = args.MediaAutoScale;
newData.MediaID = args.MediaID;
@ -589,10 +624,10 @@ namespace OpenSim.Region.CoreModules.World.Land
ParcelFlags.UseEstateVoiceChan);
}
if(!m_scene.RegionInfo.EstateSettings.TaxFree)
if(!m_estateSettings.TaxFree)
{
// don't allow passes on group owned until we can give money to groups
if (!newData.IsGroupOwned && m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false))
if (!newData.IsGroupOwned && m_scenePermissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false))
{
newData.PassHours = args.PassHours;
newData.PassPrice = args.PassPrice;
@ -600,13 +635,13 @@ namespace OpenSim.Region.CoreModules.World.Land
allowedDelta |= (uint)ParcelFlags.UsePassList;
}
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed, false))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed, false))
{
allowedDelta |= (uint)(ParcelFlags.UseAccessGroup |
ParcelFlags.UseAccessList);
}
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned, false))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned, false))
{
allowedDelta |= (uint)(ParcelFlags.UseBanList |
ParcelFlags.DenyAnonymous |
@ -615,13 +650,13 @@ namespace OpenSim.Region.CoreModules.World.Land
}
// enforce estate age and payinfo limitations
if (m_scene.RegionInfo.EstateSettings.DenyMinors)
if (m_estateSettings.DenyMinors)
{
args.ParcelFlags |= (uint)ParcelFlags.DenyAgeUnverified;
allowedDelta |= (uint)ParcelFlags.DenyAgeUnverified;
}
if (m_scene.RegionInfo.EstateSettings.DenyAnonymous)
if (m_estateSettings.DenyAnonymous)
{
args.ParcelFlags |= (uint)ParcelFlags.DenyAnonymous;
allowedDelta |= (uint)ParcelFlags.DenyAnonymous;
@ -683,7 +718,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool IsEitherBannedOrRestricted(UUID avatar)
{
if (m_scene.RegionInfo.EstateSettings.TaxFree) // region access control only
if (m_estateSettings.TaxFree) // region access control only
return false;
if (IsBannedFromLand(avatar))
@ -699,7 +734,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool CanBeOnThisLand(UUID avatar, float posHeight)
{
if (m_scene.RegionInfo.EstateSettings.TaxFree) // region access control only
if (m_estateSettings.TaxFree) // region access control only
return true;
if (posHeight < m_scene.LandChannel.BanLineSafeHeight && IsBannedFromLand(avatar))
@ -715,17 +750,19 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool HasGroupAccess(UUID avatar)
{
if (!LandData.GroupID.IsZero() && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
if (LandData.GroupID.IsNotZero() && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) != 0)
{
if (m_groupMemberCache.TryGetValue(avatar, out bool isMember))
if (m_groupMemberCache.TryGetValue(avatar, GROUPMEMBERCACHETIMEOUT, out bool isMember))
return isMember;
if (m_scene.TryGetScenePresence(avatar, out ScenePresence sp))
{
isMember = sp.ControllingClient.IsGroupMember(LandData.GroupID);
m_groupMemberCache.Add(avatar, isMember, GROUPMEMBERCACHETIMEOUT);
return isMember;
}
if (!m_scene.TryGetScenePresence(avatar, out ScenePresence sp))
else
{
IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
if (groupsModule == null)
return false;
@ -739,7 +776,7 @@ namespace OpenSim.Region.CoreModules.World.Land
foreach (GroupMembershipData d in membership)
{
if (d.GroupID == LandData.GroupID)
if (d.GroupID.Equals(LandData.GroupID))
{
m_groupMemberCache.Add(avatar, true, GROUPMEMBERCACHETIMEOUT);
return true;
@ -748,12 +785,6 @@ namespace OpenSim.Region.CoreModules.World.Land
m_groupMemberCache.Add(avatar, false, GROUPMEMBERCACHETIMEOUT);
return false;
}
else
{
isMember = sp.ControllingClient.IsGroupMember(LandData.GroupID);
m_groupMemberCache.Add(avatar, isMember, GROUPMEMBERCACHETIMEOUT);
return isMember;
}
}
return false;
}
@ -762,16 +793,16 @@ namespace OpenSim.Region.CoreModules.World.Land
{
ExpireAccessList();
if (m_scene.RegionInfo.EstateSettings.TaxFree) // region access control only
if (m_estateSettings.TaxFree) // region access control only
return false;
if (m_scene.Permissions.IsAdministrator(avatar))
if (m_scenePermissions.IsAdministrator(avatar))
return false;
if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar))
if (m_estateSettings.IsEstateManagerOrOwner(avatar))
return false;
if (avatar == LandData.OwnerID)
if (avatar.Equals(LandData.OwnerID))
return false;
if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0)
@ -779,7 +810,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if (LandData.ParcelAccessList.FindIndex(
delegate(LandAccessEntry e)
{
if (e.AgentID == avatar && e.Flags == AccessList.Ban)
if (e.Flags == AccessList.Ban && e.AgentID.Equals(avatar))
return true;
return false;
}) != -1)
@ -792,15 +823,15 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool IsRestrictedFromLand(UUID avatar)
{
if (m_scene.RegionInfo.EstateSettings.TaxFree) // estate access only
if (m_estateSettings.TaxFree) // estate access only
return false;
if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0)
{
bool adults = m_scene.RegionInfo.EstateSettings.DoDenyMinors &&
(m_scene.RegionInfo.EstateSettings.DenyMinors || ((LandData.Flags & (uint)ParcelFlags.DenyAgeUnverified) != 0));
bool anonymous = m_scene.RegionInfo.EstateSettings.DoDenyAnonymous &&
(m_scene.RegionInfo.EstateSettings.DenyAnonymous || ((LandData.Flags & (uint)ParcelFlags.DenyAnonymous) != 0));
bool adults = m_estateSettings.DoDenyMinors &&
(m_estateSettings.DenyMinors || ((LandData.Flags & (uint)ParcelFlags.DenyAgeUnverified) != 0));
bool anonymous = m_estateSettings.DoDenyAnonymous &&
(m_estateSettings.DenyAnonymous || ((LandData.Flags & (uint)ParcelFlags.DenyAnonymous) != 0));
if(adults || anonymous)
{
int userflags;
@ -821,13 +852,13 @@ namespace OpenSim.Region.CoreModules.World.Land
return false;
}
if (m_scene.Permissions.IsAdministrator(avatar))
if (m_scenePermissions.IsAdministrator(avatar))
return false;
if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar))
if (m_estateSettings.IsEstateManagerOrOwner(avatar))
return false;
if (avatar == LandData.OwnerID)
if (avatar.Equals(LandData.OwnerID))
return false;
if (HasGroupAccess(avatar))
@ -866,7 +897,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if (LandData.ParcelAccessList.FindIndex(
delegate(LandAccessEntry e)
{
if (e.AgentID == avatar && e.Flags == AccessList.Access)
if (e.Flags == AccessList.Access && e.AgentID.Equals(avatar))
return true;
return false;
}) == -1)
@ -876,17 +907,20 @@ namespace OpenSim.Region.CoreModules.World.Land
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SendLandUpdateToClient(IClientAPI remote_client)
{
SendLandProperties(0, false, 0, remote_client);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client)
{
m_scene.EventManager.TriggerParcelPrimCountUpdate();
SendLandProperties(0, snap_selection, 0, remote_client);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SendLandUpdateToAvatarsOverMe()
{
SendLandUpdateToAvatarsOverMe(false);
@ -900,31 +934,15 @@ namespace OpenSim.Region.CoreModules.World.Land
if (avatar.IsNPC)
return;
ILandObject over = null;
try
if(ContainsPoint((int)avatar.AbsolutePosition.X, (int)avatar.AbsolutePosition.Y))
{
over =
m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)),
Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1)));
}
catch (Exception)
{
m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " +
Math.Round(avatar.AbsolutePosition.Y));
}
if(m_regionSettings.AllowDamage)
avatar.Invulnerable = false;
else
avatar.Invulnerable = (LandData.Flags & (uint)ParcelFlags.AllowDamage) == 0;
if (over != null)
{
if (over.LandData.LocalID == LandData.LocalID)
{
if(m_scene.RegionInfo.RegionSettings.AllowDamage)
avatar.Invulnerable = false;
else
avatar.Invulnerable = (over.LandData.Flags & (uint)ParcelFlags.AllowDamage) == 0;
SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
avatar.currentParcelUUID = LandData.GlobalID;
}
SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
avatar.currentParcelUUID = LandData.GlobalID;
}
});
}
@ -941,32 +959,16 @@ namespace OpenSim.Region.CoreModules.World.Land
SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, avatar.ControllingClient);
return;
}
ILandObject over = null;
try
if (ContainsPoint((int)avatar.AbsolutePosition.X, (int)avatar.AbsolutePosition.Y))
{
over =
m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)),
Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1)));
}
catch (Exception)
{
m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " +
Math.Round(avatar.AbsolutePosition.Y));
}
if (over != null)
{
if (over.LandData.LocalID == LandData.LocalID)
{
if (m_scene.RegionInfo.RegionSettings.AllowDamage)
if (m_regionSettings.AllowDamage)
avatar.Invulnerable = false;
else
avatar.Invulnerable = (over.LandData.Flags & (uint)ParcelFlags.AllowDamage) == 0;
else
avatar.Invulnerable = (LandData.Flags & (uint)ParcelFlags.AllowDamage) == 0;
avatar.currentParcelUUID = LandData.GlobalID;
SendLandProperties(0, true, LandChannel.LAND_RESULT_SINGLE, avatar.ControllingClient);
return;
}
avatar.currentParcelUUID = LandData.GlobalID;
SendLandProperties(0, true, LandChannel.LAND_RESULT_SINGLE, avatar.ControllingClient);
return;
}
SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, avatar.ControllingClient);
});
@ -1018,10 +1020,10 @@ namespace OpenSim.Region.CoreModules.World.Land
public void UpdateAccessList(uint flags, UUID transactionID, List<LandAccessEntry> entries)
{
if((flags & 0x03) == 0)
flags &= 0x03;
if (flags == 0)
return; // we only have access and ban
flags &=0x03 ;
// get a work copy of lists
List<LandAccessEntry> parcelAccessList = new List<LandAccessEntry>(LandData.ParcelAccessList);
@ -1029,10 +1031,10 @@ namespace OpenSim.Region.CoreModules.World.Land
// we need to this way because viewer protocol does not seem reliable
lock (m_listTransactionsLock)
{
if ((!m_listTransactions.ContainsKey(flags)) ||
m_listTransactions[flags] != transactionID)
if ((!m_listTransactions.TryGetValue(flags, out UUID flagsID)) || flagsID.NotEqual(transactionID))
{
m_listTransactions[flags] = transactionID;
m_listTransactions.Add(flags, transactionID);
List<LandAccessEntry> toRemove = new List<LandAccessEntry>();
foreach (LandAccessEntry entry in parcelAccessList)
{
@ -1077,6 +1079,7 @@ namespace OpenSim.Region.CoreModules.World.Land
#region Update Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void UpdateLandBitmapByteArray()
{
LandData.Bitmap = ConvertLandBitmapToBytes();
@ -1085,12 +1088,14 @@ namespace OpenSim.Region.CoreModules.World.Land
/// <summary>
/// Update all settings in land such as area, bitmap byte array, etc
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ForceUpdateLandInfo()
{
UpdateGeometryValues();
UpdateLandBitmapByteArray();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetLandBitmapFromByteArray()
{
LandBitmap = ConvertBytesToLandBitmap();
@ -1134,8 +1139,8 @@ namespace OpenSim.Region.CoreModules.World.Land
{
avgx = x;
avgy = y;
m_startPoint.X = x * landUnit;
m_startPoint.Y = y * landUnit;
m_startPoint.X = x * Constants.LandUnit;
m_startPoint.Y = y * Constants.LandUnit;
needFirst = false;
}
else
@ -1153,38 +1158,51 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
int halfunit = landUnit/2;
if(tempArea == 0)
{
m_centerPoint = Vector2.Zero;
m_endPoint = Vector2.Zero;
m_AABBmin = Vector2.Zero;
m_AABBmax = Vector2.Zero;
m_centerPoint.X = avgx * landUnit + halfunit;
m_centerPoint.Y = avgy * landUnit + halfunit;
LandData.AABBMin = Vector3.Zero;
LandData.AABBMax = Vector3.Zero;
LandData.Area = 0;
m_endPoint.X = lastX * landUnit + landUnit;
m_endPoint.Y = lastY * landUnit + landUnit;
if (m_scene != null)
{
//create a fake ID
LandData.FakeID = Util.BuildFakeParcelID(m_regionInfo.RegionHandle, 0, 0);
}
return;
}
const int halfunit = Constants.LandUnit / 2;
m_centerPoint.X = avgx * Constants.LandUnit + halfunit;
m_centerPoint.Y = avgy * Constants.LandUnit + halfunit;
m_endPoint.X = lastX * Constants.LandUnit + Constants.LandUnit;
m_endPoint.Y = lastY * Constants.LandUnit + Constants.LandUnit;
// next tests should not be needed
// if they fail, something is wrong
int regionSizeX = (int)Constants.RegionSize;
int regionSizeY = (int)Constants.RegionSize;
ulong regionHandle;
if(m_scene != null)
{
RegionInfo ri = m_scene.RegionInfo;
regionSizeX = (int)ri.RegionSizeX;
regionSizeY = (int)ri.RegionSizeY;
regionHandle = ri.RegionHandle;
regionHandle = m_regionInfo.RegionHandle;
//create a fake ID
LandData.FakeID = Util.BuildFakeParcelID(regionHandle, (uint)(lastX * landUnit), (uint)(lastY * landUnit));
LandData.FakeID = Util.BuildFakeParcelID(regionHandle, (uint)(lastX * Constants.LandUnit), (uint)(lastY * Constants.LandUnit));
}
int tx = min_x * landUnit;
if (tx >= regionSizeX)
tx = regionSizeX - 1;
int tx = min_x * Constants.LandUnit;
if (tx >= m_regionSizeX)
tx = m_regionSizeX - 1;
int ty = min_y * landUnit;
if (ty >= regionSizeY)
ty = regionSizeY - 1;
int ty = min_y * Constants.LandUnit;
if (ty >= m_regionSizeY)
ty = m_regionSizeY - 1;
m_AABBmin.X = tx;
m_AABBmin.Y = ty;
@ -1195,14 +1213,14 @@ namespace OpenSim.Region.CoreModules.World.Land
LandData.AABBMin = new Vector3(tx, ty, (float)m_scene.Heightmap[tx, ty]);
max_x++;
tx = max_x * landUnit;
if (tx > regionSizeX)
tx = regionSizeX;
tx = max_x * Constants.LandUnit;
if (tx > m_regionSizeX)
tx = m_regionSizeX;
max_y++;
ty = max_y * landUnit;
if (ty > regionSizeY)
ty = regionSizeY;
ty = max_y * Constants.LandUnit;
if (ty > m_regionSizeY)
ty = m_regionSizeY;
m_AABBmax.X = tx;
m_AABBmax.Y = ty;
@ -1212,7 +1230,7 @@ namespace OpenSim.Region.CoreModules.World.Land
else
LandData.AABBMax = new Vector3(tx, ty, (float)m_scene.Heightmap[tx - 1, ty - 1]);
tempArea *= landUnit * landUnit;
tempArea *= Constants.LandUnit * Constants.LandUnit;
LandData.Area = tempArea;
}
@ -1224,6 +1242,7 @@ namespace OpenSim.Region.CoreModules.World.Land
/// Sets the land's bitmap manually
/// </summary>
/// <param name="bitmap">block representing where this land is on a map mapped in a 4x4 meter grid</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetLandBitmap(bool[,] bitmap)
{
LandBitmap = bitmap;
@ -1234,16 +1253,19 @@ namespace OpenSim.Region.CoreModules.World.Land
/// Gets the land's bitmap manually
/// </summary>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool[,] GetLandBitmap()
{
return LandBitmap;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool[,] BasicFullRegionLandBitmap()
{
return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY, true);
return GetSquareLandBitmap(0, 0, m_regionSizeX, m_regionSizeY, true);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y, bool set_value = true)
{
bool[,] tempBitmap = ModifyLandBitmapSquare(null, start_x, start_y, end_x, end_y, set_value);
@ -1265,15 +1287,15 @@ namespace OpenSim.Region.CoreModules.World.Land
{
if(land_bitmap == null)
{
land_bitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
land_bitmap = new bool[m_regionSizeX / Constants.LandUnit, m_regionSizeY / Constants.LandUnit];
if(!set_value)
return land_bitmap;
}
start_x /= landUnit;
end_x /= landUnit;
start_y /= landUnit;
end_y /= landUnit;
start_x /= Constants.LandUnit;
end_x /= Constants.LandUnit;
start_y /= Constants.LandUnit;
end_y /= Constants.LandUnit;
for (int x = start_x; x < end_x; ++x)
{
@ -1324,12 +1346,12 @@ namespace OpenSim.Region.CoreModules.World.Land
/// <param name="displacement">&lt;x,y,?&gt;</param>
/// <param name="boundingOrigin">&lt;x,y,?&gt;</param>
/// <param name="boundingSize">&lt;x,y,?&gt;</param>
/// <param name="regionSize">&lt;x,y,?&gt;</param>
/// <param name="newRegionSize">&lt;x,y,?&gt;</param>
/// <param name="isEmptyNow">out: This is set if the resultant bitmap is now empty</param>
/// <param name="AABBMin">out: parcel.AABBMin &lt;x,y,0&gt</param>
/// <param name="AABBMax">out: parcel.AABBMax &lt;x,y,0&gt</param>
/// <returns>New parcel bitmap</returns>
public bool[,] RemapLandBitmap(bool[,] bitmap_base, Vector2 displacement, float rotationDegrees, Vector2 boundingOrigin, Vector2 boundingSize, Vector2 regionSize, out bool isEmptyNow)
public bool[,] RemapLandBitmap(bool[,] bitmap_base, Vector2 displacement, float rotationDegrees, Vector2 boundingOrigin, Vector2 boundingSize, Vector2 newRegionSize, out bool isEmptyNow)
{
// get the size of the incoming bitmap
int baseX = bitmap_base.GetLength(0);
@ -1402,25 +1424,25 @@ namespace OpenSim.Region.CoreModules.World.Land
// So... our output land bitmap must be the size of the current region but rememeber, parcel landbitmaps are landUnit metres (4x4 metres) per point,
// and region sizes, boundaries and displacements are in metres so we need to scale down
int newX = (int)(regionSize.X / landUnit);
int newY = (int)(regionSize.Y / landUnit);
int newX = (int)(newRegionSize.X / Constants.LandUnit);
int newY = (int)(newRegionSize.Y / Constants.LandUnit);
bool[,] bitmap_new = new bool[newX, newY];
// displacement is relative to <0,0> in the destination region and defines where the origin of the data selected by the bounding-rectangle is placed
int dispX = (int)Math.Floor(displacement.X / landUnit);
int dispY = (int)Math.Floor(displacement.Y / landUnit);
int dispX = (int)Math.Floor(displacement.X / Constants.LandUnit);
int dispY = (int)Math.Floor(displacement.Y / Constants.LandUnit);
// startX/Y and endX/Y are coordinates in bitmap_tmp
int startX = (int)Math.Floor(boundingOrigin.X / landUnit) + offsetX;
int startX = (int)Math.Floor(boundingOrigin.X / Constants.LandUnit) + offsetX;
if (startX > tmpX) startX = tmpX;
if (startX < 0) startX = 0;
int startY = (int)Math.Floor(boundingOrigin.Y / landUnit) + offsetY;
int startY = (int)Math.Floor(boundingOrigin.Y / Constants.LandUnit) + offsetY;
if (startY > tmpY) startY = tmpY;
if (startY < 0) startY = 0;
int endX = (int)Math.Floor((boundingOrigin.X + boundingSize.X) / landUnit) + offsetX;
int endX = (int)Math.Floor((boundingOrigin.X + boundingSize.X) / Constants.LandUnit) + offsetX;
if (endX > tmpX) endX = tmpX;
if (endX < 0) endX = 0;
int endY = (int)Math.Floor((boundingOrigin.Y + boundingSize.Y) / landUnit) + offsetY;
int endY = (int)Math.Floor((boundingOrigin.Y + boundingSize.Y) / Constants.LandUnit) + offsetY;
if (endY > tmpY) endY = tmpY;
if (endY < 0) endY = 0;
@ -1550,16 +1572,16 @@ namespace OpenSim.Region.CoreModules.World.Land
}
else
{
tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
tempConvertMap = new bool[m_regionSizeX / Constants.LandUnit, m_regionSizeY / Constants.LandUnit];
tempConvertMap.Initialize();
// Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8);
xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit);
xLen = (m_regionSizeX / Constants.LandUnit);
if (bitmapLen == 512)
{
// Legacy bitmap being passed in. Use the legacy region size
// and only set the lower area of the larger region.
xLen = (int)(Constants.RegionSize / landUnit);
xLen = (int)(Constants.RegionSize / Constants.LandUnit);
}
}
// m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen);
@ -1624,7 +1646,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client)
{
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
{
List<uint> resultLocalIDs = new List<uint>();
try
@ -1673,7 +1695,7 @@ namespace OpenSim.Region.CoreModules.World.Land
/// </param>
public void SendLandObjectOwners(IClientAPI remote_client)
{
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
if (m_scenePermissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
{
Dictionary<UUID, int> primCount = new Dictionary<UUID, int>();
List<UUID> groups = new List<UUID>();
@ -1707,7 +1729,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
m_log.Error("[LAND]: Unable to match a prim with it's owner.");
}
if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID)))
if (obj.OwnerID.Equals(obj.GroupID) && (!groups.Contains(obj.OwnerID)))
groups.Add(obj.OwnerID);
}
}
@ -1778,7 +1800,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{
foreach (SceneObjectGroup obj in primsOverMe)
{
if(m_scene.Permissions.CanSellObject(previousOwner,obj, (byte)SaleType.Original))
if(m_scenePermissions.CanSellObject(previousOwner,obj, (byte)SaleType.Original))
m_BuySellModule.BuyObject(sp.ControllingClient, UUID.Zero, obj.LocalId, (byte)SaleType.Original, 0);
}
}
@ -1788,6 +1810,7 @@ namespace OpenSim.Region.CoreModules.World.Land
#region Object Returning
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReturnObject(SceneObjectGroup obj)
{
SceneObjectGroup[] objs = new SceneObjectGroup[1];
@ -1808,11 +1831,10 @@ namespace OpenSim.Region.CoreModules.World.Land
{
foreach (SceneObjectGroup obj in primsOverMe)
{
if (obj.OwnerID == LandData.OwnerID)
if (obj.OwnerID.Equals(LandData.OwnerID))
{
if (!returns.ContainsKey(obj.OwnerID))
returns[obj.OwnerID] =
new List<SceneObjectGroup>();
returns[obj.OwnerID] = new List<SceneObjectGroup>();
returns[obj.OwnerID].Add(obj);
}
}
@ -1821,13 +1843,12 @@ namespace OpenSim.Region.CoreModules.World.Land
{
foreach (SceneObjectGroup obj in primsOverMe)
{
if (obj.GroupID == LandData.GroupID)
if (obj.GroupID.Equals(LandData.GroupID))
{
if (obj.OwnerID == LandData.OwnerID)
if (obj.OwnerID.Equals(LandData.OwnerID))
continue;
if (!returns.ContainsKey(obj.OwnerID))
returns[obj.OwnerID] =
new List<SceneObjectGroup>();
returns[obj.OwnerID] = new List<SceneObjectGroup>();
returns[obj.OwnerID].Add(obj);
}
}
@ -1836,8 +1857,8 @@ namespace OpenSim.Region.CoreModules.World.Land
{
foreach (SceneObjectGroup obj in primsOverMe)
{
if (obj.OwnerID != LandData.OwnerID &&
(obj.GroupID != LandData.GroupID ||
if (obj.OwnerID.NotEqual(LandData.OwnerID) &&
(obj.GroupID.NotEqual(LandData.GroupID) ||
LandData.GroupID.IsZero()))
{
if (!returns.ContainsKey(obj.OwnerID))
@ -1855,8 +1876,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if (ownerlist.Contains(obj.OwnerID))
{
if (!returns.ContainsKey(obj.OwnerID))
returns[obj.OwnerID] =
new List<SceneObjectGroup>();
returns[obj.OwnerID] = new List<SceneObjectGroup>();
returns[obj.OwnerID].Add(obj);
}
}
@ -1865,7 +1885,7 @@ namespace OpenSim.Region.CoreModules.World.Land
foreach (List<SceneObjectGroup> ol in returns.Values)
{
if (m_scene.Permissions.CanReturnObjects(this, remote_client, ol))
if (m_scenePermissions.CanReturnObjects(this, remote_client, ol))
m_scene.returnObjects(ol.ToArray(), remote_client);
}
}
@ -1874,12 +1894,14 @@ namespace OpenSim.Region.CoreModules.World.Land
#region Object Adding/Removing from Parcel
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ResetOverMeRecord()
{
lock (primsOverMe)
primsOverMe.Clear();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AddPrimOverMe(SceneObjectGroup obj)
{
// m_log.DebugFormat("[LAND OBJECT]: Adding scene object {0} {1} over {2}", obj.Name, obj.LocalId, LandData.Name);
@ -1888,10 +1910,10 @@ namespace OpenSim.Region.CoreModules.World.Land
primsOverMe.Add(obj);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemovePrimFromOverMe(SceneObjectGroup obj)
{
// m_log.DebugFormat("[LAND OBJECT]: Removing scene object {0} {1} from over {2}", obj.Name, obj.LocalId, LandData.Name);
//m_log.DebugFormat("[LAND OBJECT]: Removing scene object {0} {1} from over {2}", obj.Name, obj.LocalId, LandData.Name);
lock (primsOverMe)
primsOverMe.Remove(obj);
}
@ -1952,6 +1974,7 @@ namespace OpenSim.Region.CoreModules.World.Land
/// Get the music url for this land parcel
/// </summary>
/// <returns>The music url.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string GetMusicUrl()
{
return LandData.MusicURL;

View file

@ -248,7 +248,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
lo.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
lo = lmm.AddLandObject(lo);
lmm.Subdivide(0, 0, LandManagementModule.LandUnit, LandManagementModule.LandUnit, userId);
lmm.Subdivide(0, 0, Constants.LandUnit, Constants.LandUnit, userId);
{
ILandObject loAtCoord = lmm.GetLandObject(0, 0);
@ -257,7 +257,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
}
{
ILandObject loAtCoord = lmm.GetLandObject(LandManagementModule.LandUnit, LandManagementModule.LandUnit);
ILandObject loAtCoord = lmm.GetLandObject(Constants.LandUnit, Constants.LandUnit);
Assert.That(loAtCoord.LandData.LocalID, Is.EqualTo(lo.LandData.LocalID));
Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(lo.LandData.GlobalID));
}

View file

@ -301,7 +301,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
if (!m_scene.TryGetSceneObjectPart(objectID, out part))
return;
volume = Util.Clip((float)volume, 0, 1);
volume = Utils.Clamp(volume, 0, 1);
UUID parentID = part.ParentGroup.UUID;

View file

@ -152,41 +152,19 @@ namespace OpenSim.Region.CoreModules.World.Terrain
protected string parseFloat(String s, out float f)
{
string result;
float d;
if (float.TryParse(s, out d))
{
try
{
f = (float)d;
result = String.Empty;
}
catch(InvalidCastException)
{
result = String.Format("{0} is invalid", s);
f = -1.0f;
}
}
else
{
f = -1.0f;
result = String.Format("{0} is invalid", s);
}
return result;
if (float.TryParse(s, out f))
return string.Empty;
f = -1.0f;
return string.Format("{0} is invalid", s);
}
protected string parseInt(String s, out int i)
{
string result;
if (Int32.TryParse(s, out i))
{
result = String.Empty;
}
else
{
result = String.Format("{0} is invalid", s);
}
return result;
return string.Empty;
return string.Format("{0} is invalid", s);
}
protected void applyModification(ITerrainChannel map, TerrainModifierData data)

View file

@ -99,45 +99,39 @@ namespace OpenSim.Region.CoreModules.World.Terrain
// patch packet is queued to the client, the bit for that patch is set to 'false'.
private class PatchUpdates
{
private BitArray updated; // for each patch, whether it needs to be sent to this client
private int updateCount; // number of patches that need to be sent
public TerrainTaintsArray taints; // for each patch, whether it needs to be sent to this client
public ScenePresence Presence; // a reference to the client to send to
public bool sendAll;
public int sendAllcurrentX;
public int sendAllcurrentY;
private int xsize;
private int ysize;
public int sendAllIndex;
public int xsize;
public int ysize;
public PatchUpdates(TerrainData terrData, ScenePresence pPresence)
{
xsize = terrData.SizeX / Constants.TerrainPatchSize;
ysize = terrData.SizeY / Constants.TerrainPatchSize;
updated = new BitArray(xsize * ysize, true);
updateCount = xsize * ysize;
taints = new TerrainTaintsArray(xsize * ysize, true);
Presence = pPresence;
// Initially, send all patches to the client
sendAll = true;
sendAllcurrentX = 0;
sendAllcurrentY = 0;
sendAllIndex = 0;
}
public PatchUpdates(TerrainData terrData, ScenePresence pPresence, bool defaultState)
{
xsize = terrData.SizeX / Constants.TerrainPatchSize;
ysize = terrData.SizeY / Constants.TerrainPatchSize;
updated = new BitArray(xsize * ysize, true);
updateCount = defaultState ? xsize * ysize : 0;
taints = new TerrainTaintsArray(xsize * ysize, true);
Presence = pPresence;
sendAll = defaultState;
sendAllcurrentX = 0;
sendAllcurrentY = 0;
sendAllIndex = 0;
}
// Returns 'true' if there are any patches marked for sending
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool HasUpdates()
{
return (updateCount > 0);
return (taints.IsTaited());
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
@ -149,121 +143,65 @@ namespace OpenSim.Region.CoreModules.World.Terrain
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool GetByPatch(int patchX, int patchY)
{
return updated[patchX + xsize * patchY];
return taints[patchX + xsize * patchY];
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool GetByPatch(int indx)
{
return updated[indx];
return taints.Get(indx);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public bool GetByPatchAndClear(int patchX, int patchY)
{
int indx = patchX + xsize * patchY;
if(updated[indx])
{
updated[indx] = false;
--updateCount;
return true;
}
return false;
return (taints.GetAndClear(patchX + xsize * patchY));
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public void SetByPatch(int patchX, int patchY, bool state)
{
int indx = patchX + xsize * patchY;
bool prevState = updated[indx];
updated[indx] = state;
if (state)
{
if (!prevState)
++updateCount;
}
else
{
if (prevState)
--updateCount;
}
taints.Set(indx, state);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public void SetTrueByPatch(int patchX, int patchY)
{
int indx = patchX + xsize * patchY;
if (!updated[indx])
{
updated[indx] = true;
++updateCount;
}
taints.Set(indx, true);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public void SetTrueByPatch(int indx)
{
if (!updated[indx])
{
updated[indx] = true;
++updateCount;
}
taints.Set(indx, true);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public void SetFalseByPatch(int patchX, int patchY)
{
int indx = patchX + xsize * patchY;
if (updated[indx])
{
updated[indx] = false;
--updateCount;
}
taints.Set(indx, false);
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public void SetFalseByPatch(int indx)
{
if (updated[indx])
{
updated[indx] = false;
--updateCount;
}
taints.Set(indx, false);
}
public void SetAll(bool state)
{
updated.SetAll(state);
if (state)
{
sendAll = true;
updateCount = xsize * ysize;
}
else updateCount = 0;
sendAllcurrentX = 0;
sendAllcurrentY = 0;
taints.SetAll(state);
sendAll = state;
sendAllIndex = 0;
}
// Logically OR's the terrain data's patch taint map into this client's update map.
public void SetAll(TerrainData terrData)
{
if (xsize != (terrData.SizeX / Constants.TerrainPatchSize)
|| ysize != (terrData.SizeY / Constants.TerrainPatchSize))
{
throw new Exception(
String.Format("{0} PatchUpdates.SetAll: patch array not same size as terrain. arr=<{1},{2}>, terr=<{3},{4}>",
LogHeader, xsize, ysize,
terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize)
);
}
for (int indx = 0; indx < updated.Length; ++indx)
{
if (terrData.IsTaintedAtPatch(indx))
SetTrueByPatch(indx);
}
taints.Or(terrData.GetTaints());
}
}
@ -299,9 +237,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
if (terrainConfig != null)
{
m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
m_sendTerrainUpdatesByViewDistance =
terrainConfig.GetBoolean(
"SendTerrainUpdatesByViewDistance",m_sendTerrainUpdatesByViewDistance);
m_sendTerrainUpdatesByViewDistance = terrainConfig.GetBoolean("SendTerrainUpdatesByViewDistance",m_sendTerrainUpdatesByViewDistance);
}
}
@ -940,8 +876,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
/// doing it async, since currently this is 2 heavy for heartbeat
private void EventManager_TerrainCheckUpdates()
{
Util.FireAndForget(
EventManager_TerrainCheckUpdatesAsync);
Util.FireAndForget(EventManager_TerrainCheckUpdatesAsync);
}
object TerrainCheckUpdatesLock = new object();
@ -954,17 +889,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
TerrainData terrData = m_channel.GetTerrainData();
bool shouldTaint = false;
int sx = terrData.SizeX / Constants.TerrainPatchSize;
for (int y = 0, py = 0; y < terrData.SizeY / Constants.TerrainPatchSize; y++, py += sx)
if(terrData.IsTainted())
{
for (int x = 0; x < sx; x++)
int nextChanged = 0;
while((nextChanged = terrData.GetAndClearNextTaint(nextChanged)) >= 0)
{
if (terrData.IsTaintedAtPatchWithClear(x + py))
{
// Found a patch that was modified. Push this flag into the clients.
SendToClients(terrData, x, y);
shouldTaint = true;
}
SendToClients(terrData, nextChanged);
++nextChanged;
shouldTaint = true;
}
}
@ -1145,7 +1077,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
/// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
/// <param name="px">x patch coords</param>
/// <param name="py">y patch coords</param>
private void SendToClients(TerrainData terrData, int px, int py)
private void SendToClients(TerrainData terrData, int patchIndex)
{
if (m_sendTerrainUpdatesByViewDistance)
{
@ -1154,13 +1086,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{
m_scene.ForEachScenePresence(presence =>
{
if(presence.IsNPC)
return;
if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out PatchUpdates thisClientUpdates))
{
// There is a ScenePresence without a send patch map. Create one. should not happen
thisClientUpdates = new PatchUpdates(terrData, presence, false);
m_perClientPatchUpdates.Add(presence.UUID, thisClientUpdates);
}
thisClientUpdates.SetTrueByPatch(px, py);
thisClientUpdates.SetTrueByPatch(patchIndex);
}
);
}
@ -1170,6 +1104,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
// Legacy update sending where the update is sent out as soon as noticed
// We know the actual terrain data that is passed is ignored so this passes a dummy heightmap.
//float[] heightMap = terrData.GetFloatsSerialized();
int sx = terrData.SizeX / Constants.TerrainPatchSize;
int py = patchIndex / sx;
int px = patchIndex - py * sx;
int[] map = new int[]{px, py};
m_scene.ForEachClient(
delegate (IClientAPI controller)
@ -1238,66 +1175,43 @@ namespace OpenSim.Region.CoreModules.World.Terrain
}
private void SendAllModifiedPatchs(PatchUpdates pups)
{
if (!pups.sendAll) // sanity
if (!pups.sendAll || !pups.HasUpdates())
return;
int limitX = (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize;
int limitY = (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize;
if (pups.sendAllcurrentX >= limitX && pups.sendAllcurrentY >= limitY)
{
pups.sendAll = false;
pups.sendAllcurrentX = 0;
pups.sendAllcurrentY = 0;
return;
}
int next = pups.sendAllIndex;
if (pups.sendAllIndex >= pups.taints.Length)
next = 0;
int npatchs = 0;
List<PatchesToSend> patchs = new List<PatchesToSend>();
int x = pups.sendAllcurrentX;
int y = pups.sendAllcurrentY;
// send it in the order viewer draws it
// even if not best for memory scan
for (; y < limitY; y++)
List<int> patchs = new List<int>(128);
while ((next = pups.taints.GetAndClearNextTrue(next)) >= 0)
{
for (; x < limitX; x++)
{
if (pups.GetByPatchAndClear(x, y))
{
patchs.Add(new PatchesToSend(x, y, 0));
if (++npatchs >= 128)
{
x++;
break;
}
}
}
if (npatchs >= 128)
patchs.Add(next);
++next;
if(++npatchs >= 128)
break;
x = 0;
}
if (x >= limitX && y >= limitY)
{
pups.sendAll = false;
pups.sendAllcurrentX = 0;
pups.sendAllcurrentY = 0;
if(next < 0)
{
pups.sendAll = pups.HasUpdates();
pups.sendAllIndex = 0;
}
else
{
pups.sendAllcurrentX = x;
pups.sendAllcurrentY = y;
}
pups.sendAllIndex = next;
npatchs = patchs.Count;
if (npatchs > 0)
{
int[] patchPieces = new int[npatchs * 2];
int pieceIndex = 0;
foreach (PatchesToSend pts in patchs)
int sx = pups.xsize;
int[] patchPieces = new int[2 * npatchs];
for(int i = 0, pieceIndex = 0; i < patchs.Count; ++i)
{
patchPieces[pieceIndex++] = pts.PatchX;
patchPieces[pieceIndex++] = pts.PatchY;
int patchIndex = patchs[i];
int py = patchIndex / sx;
int px = patchIndex - py * sx;
patchPieces[pieceIndex++] = px;
patchPieces[pieceIndex++] = py;
}
pups.Presence.ControllingClient.SendLayerData(patchPieces);
}
@ -1306,8 +1220,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private List<PatchesToSend> GetModifiedPatchesInViewDistance(PatchUpdates pups)
{
List<PatchesToSend> ret = new List<PatchesToSend>();
int npatchs = 0;
if (!pups.HasUpdates())
return ret;
ScenePresence presence = pups.Presence;
if (presence == null)
@ -1373,6 +1287,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
DrawDistance *= DrawDistance;
int npatchs = 0;
for (int y = startY, py = startY * limitX; y < endY; y++, py += limitX)
{
distysq = y - testposY;
@ -1387,7 +1302,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
distxsq *= distxsq;
if (distxsq < distlimitsq)
{
pups.SetFalseByPatch(x + py);
pups.SetFalseByPatch(indx);
ret.Add(new PatchesToSend(x, y, distxsq + distysq));
if (npatchs++ > 1024)
{

View file

@ -176,9 +176,11 @@ namespace OpenSim.Region.CoreModules.Hypergrid
{
if (m_UserManagement != null && !string.IsNullOrEmpty(m_MapImageServerURL) && !m_UserManagement.IsLocalGridUser(agentID))
{
OSD extras;
if (!features.TryGetValue("OpenSimExtras", out extras))
if (!features.TryGetValue("OpenSimExtras", out OSD extras))
{
extras = new OSDMap();
features["OpenSimExtras"] = extras;
}
((OSDMap)extras)["map-server-url"] = m_MapImageServerURL;

View file

@ -232,7 +232,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
// this has to be called with a lock on m_scene
protected virtual void AddHandlers()
{
myMapImageJPEG = new byte[0];
myMapImageJPEG = Array.Empty<byte>();
string regionimage = "regionImage" + m_scene.RegionInfo.RegionID.ToString();
regionimage = regionimage.Replace("-", "");
@ -1576,7 +1576,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
{
m_scene.AssetService.Delete(lastID.ToString());
m_scene.RegionInfo.RegionSettings.TerrainImageID = UUID.Zero;
myMapImageJPEG = new byte[0];
myMapImageJPEG = Array.Empty<byte>();
needRegionSave = true;
}
@ -1709,7 +1709,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
private Byte[] GenerateOverlay()
{
int landTileSize = LandManagementModule.LandUnit;
const int landTileSize = Constants.LandUnit;
// These need to be ints for bitmap generation
int regionSizeX = (int)m_scene.RegionInfo.RegionSizeX;

View file

@ -40,7 +40,9 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IEmailModule
{
void SendEmail(UUID objectID, string address, string subject, string body);
void SendEmail(UUID objectID, UUID ownerID, string address, string subject, string body);
Email GetNextEmail(UUID objectID, string sender, string subject);
void AddPartMailBox(UUID objectID);
void RemovePartMailBox(UUID objectID);
}
}

View file

@ -25,8 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Services.Interfaces;
using System.Collections.Generic;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenMetaverse;
@ -97,8 +96,7 @@ namespace OpenSim.Region.Framework.Interfaces
void EnableChildAgent(ScenePresence agent, GridRegion region);
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, EntityTransferContext ctx,
out Vector3 newpos, out string reason);
GridRegion GetDestination(UUID agentID, Vector3 pos, EntityTransferContext ctx, out Vector3 newpos, out string reason);
GridRegion GetObjectDestination(SceneObjectGroup grp, Vector3 targetPosition, out Vector3 newpos);
bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position, EntityTransferContext ctx, out string reason);
@ -109,6 +107,7 @@ namespace OpenSim.Region.Framework.Interfaces
bool CrossAgentCreateFarChild(ScenePresence agent, GridRegion neighbourRegion, Vector3 pos, EntityTransferContext ctx);
bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition);
bool HandleIncomingAttachments(ScenePresence sp, List<SceneObjectGroup> attachments);
}
public interface IUserAgentVerificationModule

View file

@ -42,11 +42,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation
[Serializable]
public class AnimationSet
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private OpenSim.Framework.Animation m_implicitDefaultAnimation = new OpenSim.Framework.Animation();
private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation();
private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>();
private readonly List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>();
public OpenSim.Framework.Animation DefaultAnimation
{
@ -71,12 +71,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
public bool HasAnimation(UUID animID)
{
if (m_defaultAnimation.AnimID == animID)
if (m_defaultAnimation.AnimID.Equals(animID))
return true;
for (int i = 0; i < m_animations.Count; ++i)
{
if (m_animations[i].AnimID == animID)
if (m_animations[i].AnimID.Equals(animID))
return true;
}
@ -108,7 +108,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
{
lock (m_animations)
{
if (m_defaultAnimation.AnimID == animID)
if (m_defaultAnimation.AnimID.Equals(animID))
{
if (allowNoDefault)
m_defaultAnimation = new OpenSim.Framework.Animation(UUID.Zero, 1, UUID.Zero);
@ -119,7 +119,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
{
for (int i = 0; i < m_animations.Count; i++)
{
if (m_animations[i].AnimID == animID)
if (m_animations[i].AnimID.Equals(animID))
{
m_animations.RemoveAt(i);
return true;
@ -142,13 +142,14 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// </summary>
public bool SetDefaultAnimation(UUID animID, int sequenceNum, UUID objectID)
{
if (m_defaultAnimation.AnimID != animID)
if (m_defaultAnimation.AnimID.NotEqual(animID))
{
m_defaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID);
m_implicitDefaultAnimation = m_defaultAnimation;
return true;
//return true;
}
return false;
//return false;
return true;
}
// Called from serialization only
@ -167,9 +168,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// </summary>
public bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID)
{
// m_log.DebugFormat(
// "[ANIMATION SET]: Setting default animation {0}, sequence number {1}, object id {2}",
// anim, sequenceNum, objectID);
//m_log.DebugFormat(
// "[ANIMATION SET]: Setting default animation {0}, sequence number {1}, object id {2}",
// anim, sequenceNum, objectID);
if (DefaultAvatarAnimations.AnimsUUIDbyName.TryGetValue(anim, out UUID id))
{
@ -178,6 +179,27 @@ namespace OpenSim.Region.Framework.Scenes.Animation
return false;
}
public void GetAnimationIDsArray(out UUID[] animIDs)
{
lock (m_animations)
{
int j = m_defaultAnimation.AnimID.IsZero() ? 0 : 1;
int defaultSize = m_animations.Count + j;
animIDs = new UUID[defaultSize];
if (j > 0)
{
animIDs[0] = m_defaultAnimation.AnimID;
}
for (int i = 0; i < m_animations.Count; ++i, ++j)
{
animIDs[j] = m_animations[i].AnimID;
}
}
}
public void GetArrays(out UUID[] animIDs, out int[] sequenceNums, out UUID[] objectIDs)
{
lock (m_animations)
@ -189,7 +211,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
sequenceNums = new int[defaultSize];
objectIDs = new UUID[defaultSize];
if (!m_defaultAnimation.AnimID.IsZero())
if (j > 0)
{
animIDs[0] = m_defaultAnimation.AnimID;
sequenceNums[0] = m_defaultAnimation.SequenceNum;

View file

@ -81,6 +81,12 @@ namespace OpenSim.Region.Framework.Scenes
return UUID.Zero;
}
public bool TryGetOverriddenAnimation(string state, out UUID animID)
{
lock (MAOLock)
return m_overrides.TryGetValue(state, out animID);
}
public Dictionary<string, UUID> CloneAOPairs()
{
lock (MAOLock)

View file

@ -61,9 +61,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
private int m_animTickLand;
private int m_animTickJump;
public bool m_jumping = false;
public bool isJumping;
// private int m_landing = 0;
// private int m_landing = 0;
/// <summary>
/// Is the avatar falling?
@ -80,7 +80,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
public ScenePresenceAnimator(ScenePresence sp)
{
m_scenePresence = sp;
CurrentMovementAnimation = "CROUCH";
CurrentMovementAnimation = "STAND";
}
public void AddAnimation(UUID animID, UUID objectID)
@ -88,7 +88,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
if (m_scenePresence.IsChildAgent)
return;
// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name);
// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name);
if (m_scenePresence.Scene.DebugAnimations)
m_log.DebugFormat(
"[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}",
@ -111,7 +111,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
if (animID.IsZero())
return;
// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name);
// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name);
AddAnimation(animID, objectID);
}
@ -189,69 +189,61 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// </summary>
/// <returns>'true' if the animation was updated</returns>
///
public bool TrySetMovementAnimation(string anim)
{
bool ret = false;
if (!m_scenePresence.IsChildAgent)
{
// m_log.DebugFormat(
// "[SCENE PRESENCE ANIMATOR]: Setting movement animation {0} for {1}",
// anim, m_scenePresence.Name);
if (!aoSitGndAnim.IsZero())
{
avnChangeAnim(aoSitGndAnim, false, true);
aoSitGndAnim = UUID.Zero;
}
UUID overridenAnim = m_scenePresence.Overrides.GetOverriddenAnimation(anim);
if (!overridenAnim.IsZero())
{
if (anim == "SITGROUND")
{
UUID defsit = DefaultAvatarAnimations.AnimsUUIDbyName["SIT_GROUND_CONSTRAINED"];
if (defsit.IsZero())
return false;
m_animations.SetDefaultAnimation(defsit, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID);
aoSitGndAnim = overridenAnim;
avnChangeAnim(overridenAnim, true, false);
}
else
{
m_animations.SetDefaultAnimation(overridenAnim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID);
}
m_scenePresence.SendScriptChangedEventToAttachments(Changed.ANIMATION);
SendAnimPack();
ret = true;
}
else
{
// translate sit and sitground state animations
if (anim == "SIT" || anim == "SITGROUND")
anim = m_scenePresence.sitAnimation;
if (m_animations.TrySetDefaultAnimation(anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
{
// m_log.DebugFormat(
// "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}",
// anim, m_scenePresence.Name);
m_scenePresence.SendScriptChangedEventToAttachments(Changed.ANIMATION);
SendAnimPack();
ret = true;
}
}
}
else
if (m_scenePresence.IsChildAgent)
{
m_log.WarnFormat(
"[SCENE PRESENCE ANIMATOR]: Tried to set movement animation {0} on child presence {1}",
anim, m_scenePresence.Name);
return false;
}
return ret;
//m_log.DebugFormat(
// "[SCENE PRESENCE ANIMATOR]: Setting movement animation {0} for {1}",
// anim, m_scenePresence.Name);
if (!aoSitGndAnim.IsZero())
{
avnChangeAnim(aoSitGndAnim, false, true);
aoSitGndAnim = UUID.Zero;
}
if (m_scenePresence.Overrides.TryGetOverriddenAnimation(anim, out UUID overridenAnim))
{
if (anim.Equals("SITGROUND"))
{
UUID defsit = DefaultAvatarAnimations.AnimsUUIDbyName["SIT_GROUND_CONSTRAINED"];
if (defsit.IsZero())
return false;
m_animations.SetDefaultAnimation(defsit, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID);
aoSitGndAnim = overridenAnim;
avnChangeAnim(overridenAnim, true, false);
}
else
{
m_animations.SetDefaultAnimation(overridenAnim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID);
}
m_scenePresence.SendScriptChangedEventToAttachments(Changed.ANIMATION);
SendAnimPack();
return true;
}
// translate sit and sitground state animations
if (anim.Equals("SIT") || anim.Equals("SITGROUND"))
anim = m_scenePresence.sitAnimation;
if (m_animations.TrySetDefaultAnimation(anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
{
//m_log.DebugFormat(
// "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}",
// anim, m_scenePresence.Name);
m_scenePresence.SendScriptChangedEventToAttachments(Changed.ANIMATION);
SendAnimPack();
return true;
}
return false;
}
public enum motionControlStates : byte
@ -259,6 +251,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
sitted = 0,
flying,
falling,
prejumping,
jumping,
landing,
onsurface
@ -272,8 +265,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
private string DetermineMovementAnimation()
{
const int FALL_DELAY = 800;
const int PREJUMP_DELAY = 200;
const int JUMP_PERIOD = 800;
const int PREJUMP_DELAY = 450;
const int JUMP_PERIOD = 1050;
#region Inputs
if (m_scenePresence.IsInTransit)
@ -282,16 +275,19 @@ namespace OpenSim.Region.Framework.Scenes.Animation
if (m_scenePresence.SitGround)
{
currentControlState = motionControlStates.sitted;
isJumping = false;
Falling = false;
return "SITGROUND";
}
if (m_scenePresence.ParentID != 0 || !m_scenePresence.ParentUUID.IsZero())
{
currentControlState = motionControlStates.sitted;
isJumping = false;
Falling = false;
return "SIT";
}
AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
PhysicsActor actor = m_scenePresence.PhysicsActor;
const AgentManager.ControlFlags ANYXYMASK = (
AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS |
@ -299,37 +295,44 @@ namespace OpenSim.Region.Framework.Scenes.Animation
AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS |
AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG
);
const AgentManager.ControlFlags ANYXYZMASK = (ANYXYMASK |
AgentManager.ControlFlags.AGENT_CONTROL_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS |
AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
);
// Check control flags
/* not in use
bool heldForward = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)) != 0);
bool heldBack = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG)) != 0);
bool heldLeft = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS)) != 0);
bool heldRight = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG)) != 0);
*/
bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
// bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS)) != 0);
// excluded nudge up so it doesn't trigger jump state
// excluded nudge up so it doesn't trigger jump state
bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS)) != 0);
bool heldDown = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG)) != 0);
//bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
//bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;
bool heldOnXY = ((controlFlags & ANYXYMASK) != 0);
if (heldOnXY || heldUp || heldDown)
bool heldTurnLeft;
bool heldTurnRight;
if ((controlFlags & ANYXYZMASK) != 0)
{
heldTurnLeft = false;
heldTurnRight = false;
}
else
{
heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0;
heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0;
//heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0;
//heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0;
}
#endregion Inputs
PhysicsActor actor = m_scenePresence.PhysicsActor;
// no physics actor case
if (actor == null)
{
// well what to do?
isJumping = false;
Falling = false;
// well what to do?
currentControlState = motionControlStates.onsurface;
if (heldOnXY)
return "WALK";
@ -337,15 +340,14 @@ namespace OpenSim.Region.Framework.Scenes.Animation
return "STAND";
}
#region Flying
bool isColliding = actor.IsColliding;
#region Flying
if (actor.Flying)
{
m_animTickFall = 0;
m_animTickJump = 0;
m_jumping = false;
isJumping = false;
Falling = false;
currentControlState = motionControlStates.flying;
@ -392,7 +394,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation
if (!isColliding && currentControlState != motionControlStates.jumping)
{
float fallVelocity = actor.Velocity.Z;
// if stable on Hover assume falling
if(actor.PIDHoverActive && fallVelocity < 0.05f)
{
@ -434,14 +435,38 @@ namespace OpenSim.Region.Framework.Scenes.Animation
#region Jumping // section added for jumping...
if (isColliding && heldUp && currentControlState != motionControlStates.jumping && !actor.PIDHoverActive)
if (isColliding && heldUp && !isJumping && !actor.PIDHoverActive)
{
// Start jumping, prejump
currentControlState = motionControlStates.jumping;
m_jumping = true;
isJumping = true;
Falling = false;
m_animTickJump = Environment.TickCount;
return "PREJUMP";
if ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_FINISH_ANIM)) == 0)
{
currentControlState = motionControlStates.prejumping;
m_animTickJump = Environment.TickCount;
// Start jumping, prejump
return "PREJUMP";
}
m_animTickJump = Environment.TickCount - PREJUMP_DELAY - 1;
currentControlState = motionControlStates.jumping;
m_scenePresence.Jump(9.4f);
return "JUMP";
}
if (currentControlState == motionControlStates.prejumping)
{
if((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_FINISH_ANIM)) == 0)
{
int jumptime = Environment.TickCount - m_animTickJump;
if (jumptime < PREJUMP_DELAY)
return CurrentMovementAnimation;
}
// jump up
isJumping = true;
currentControlState = motionControlStates.jumping;
m_scenePresence.Jump(9.4f);
return "JUMP";
}
if (currentControlState == motionControlStates.jumping)
@ -450,7 +475,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding)
{
// end jumping
m_jumping = false;
isJumping = false;
Falling = false;
actor.Selected = false; // borrowed for jumping flag
m_animTickLand = Environment.TickCount;
@ -462,12 +487,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation
// jump down
return "JUMP";
}
else if (jumptime > PREJUMP_DELAY)
{
// jump up
m_jumping = true;
return "JUMP";
}
return CurrentMovementAnimation;
}
@ -479,37 +498,38 @@ namespace OpenSim.Region.Framework.Scenes.Animation
{
Falling = false;
currentControlState = motionControlStates.landing;
m_animTickLand = Environment.TickCount;
// TODO: SOFT_LAND support
float fallVsq = m_lastFallVelocity * m_lastFallVelocity;
if (fallVsq > 300f) // aprox 20*h
return "STANDUP";
else if (fallVsq > 160f)
return "SOFT_LAND";
else
return "LAND";
}
if ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_FINISH_ANIM)) == 0)
{
float fallVsq = m_lastFallVelocity * m_lastFallVelocity;
if (fallVsq > 300f) // aprox 20*h
{
m_animTickLand = Environment.TickCount + 3000;
return "STANDUP";
}
if (fallVsq > 160f)
{
m_animTickLand = Environment.TickCount + 1500;
return "SOFT_LAND";
}
}
m_animTickLand = Environment.TickCount + 600;
return "LAND";
}
if (currentControlState == motionControlStates.landing)
{
Falling = false;
int landElapsed = Environment.TickCount - m_animTickLand;
int limit = 1000;
if (CurrentMovementAnimation == "LAND")
limit = 350;
// NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client
if ((m_animTickLand != 0) && (landElapsed <= limit))
if ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_FINISH_ANIM)) == 0)
{
return CurrentMovementAnimation;
}
else
{
currentControlState = motionControlStates.onsurface;
m_animTickLand = 0;
return "STAND";
if ((m_animTickLand != 0) && (m_animTickLand > Environment.TickCount))
return CurrentMovementAnimation;
}
currentControlState = motionControlStates.onsurface;
m_animTickLand = 0;
return "STAND";
}
// next section moved outside paren. and realigned for jumping
@ -558,26 +578,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// <returns>'true' if the animation was changed</returns>
public bool UpdateMovementAnimations()
{
// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Updating movement animations for {0}", m_scenePresence.Name);
bool ret = false;
// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Updating movement animations for {0}", m_scenePresence.Name);
lock (m_animations)
{
string newMovementAnimation = DetermineMovementAnimation();
if (CurrentMovementAnimation != newMovementAnimation)
{
CurrentMovementAnimation = newMovementAnimation;
if (CurrentMovementAnimation.Equals(newMovementAnimation))
return false;
// m_log.DebugFormat(
// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()",
// CurrentMovementAnimation, m_scenePresence.Name);
CurrentMovementAnimation = newMovementAnimation;
//m_log.DebugFormat(
// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} {2} {3} in UpdateMovementAnimations()",
// CurrentMovementAnimation, m_scenePresence.Name, isJumping, Falling);
// Only set it if it's actually changed, give a script
// a chance to stop a default animation
ret = TrySetMovementAnimation(CurrentMovementAnimation);
}
// Only set it if it's actually changed, give a script
// a chance to stop a default animation
return TrySetMovementAnimation(CurrentMovementAnimation);
}
return ret;
}
public bool ForceUpdateMovementAnimations()
@ -600,13 +616,15 @@ namespace OpenSim.Region.Framework.Scenes.Animation
public UUID[] GetAnimationArray()
{
UUID[] animIDs;
int[] sequenceNums;
UUID[] objectIDs;
m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
m_animations.GetAnimationIDsArray(out UUID[] animIDs);
return animIDs;
}
public bool HasAnimation(UUID animID)
{
return m_animations.HasAnimation(animID);
}
public BinBVHAnimation GenerateRandomAnimation()
{
int rnditerations = 3;
@ -850,7 +868,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation
m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
// SendAnimPack(animIDs, sequenceNums, objectIDs);
m_scenePresence.SendAnimPack(animIDs, sequenceNums, objectIDs);
}

View file

@ -785,25 +785,7 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_sceneGraph.PhysicsScene; }
set
{
// If we're not doing the initial set
// Then we've got to remove the previous
// event handler
if (PhysicsScene != null && PhysicsScene.SupportsNINJAJoints)
{
PhysicsScene.OnJointMoved -= jointMoved;
PhysicsScene.OnJointDeactivated -= jointDeactivated;
PhysicsScene.OnJointErrorMessage -= jointErrorMessage;
}
m_sceneGraph.PhysicsScene = value;
if (PhysicsScene != null && m_sceneGraph.PhysicsScene.SupportsNINJAJoints)
{
// register event handlers to respond to joint movement/deactivation
PhysicsScene.OnJointMoved += jointMoved;
PhysicsScene.OnJointDeactivated += jointDeactivated;
PhysicsScene.OnJointErrorMessage += jointErrorMessage;
}
}
}
@ -2872,11 +2854,13 @@ namespace OpenSim.Region.Framework.Scenes
part.KeyframeMotion = null;
}
if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
if ((part.AggregatedScriptEvents & scriptEvents.email) != 0)
{
PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
IEmailModule imm = RequestModuleInterface<IEmailModule>();
if (imm != null)
imm.RemovePartMailBox(part.UUID);
}
else if (part.PhysActor != null)
if (part.PhysActor != null)
{
part.RemoveFromPhysics();
}
@ -2985,6 +2969,7 @@ namespace OpenSim.Region.Framework.Scenes
// This test is mostly used to see if a region crossing is necessary.
// Assuming the position is relative to the region so anything outside its bounds.
// Return 'true' if position inside region.
public bool PositionIsInCurrentRegion(Vector3 pos)
{
float t = pos.X;
@ -3028,6 +3013,21 @@ namespace OpenSim.Region.Framework.Scenes
return true;
}
public bool IncomingAttechments(ScenePresence sp, List<SceneObjectGroup> attachments)
{
//m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition,
// ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment);
if (!EntityTransferModule.HandleIncomingAttachments(sp, attachments) || sp.IsDeleted)
return false;
// Do this as late as possible so that listeners have full access to the incoming object
foreach(SceneObjectGroup newObject in attachments)
EventManager.TriggerOnIncomingSceneObject(newObject);
return true;
}
/// <summary>
/// Adds a Scene Object group to the Scene.
/// Verifies that the creator of the object is not banned from the simulator.
@ -5022,6 +5022,9 @@ Label_GroupsDone:
public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
{
if(!AllowAvatarCrossing)
return false;
if (EntityTransferModule != null)
{
return EntityTransferModule.Cross(agent, isFlying);
@ -5624,139 +5627,6 @@ Environment.Exit(1);
return health;
}
// This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
// update non-physical objects like the joint proxy objects that represent the position
// of the joints in the scene.
// This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
// WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
// from within the OdePhysicsScene.
protected internal void jointMoved(PhysicsJoint joint)
{
// m_parentScene.PhysicsScene.DumpJointInfo(); // non-thread-locked version; we should already be in a lock (OdeLock) when this callback is invoked
SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
if (jointProxyObject == null)
{
jointErrorMessage(joint, "WARNING, joint proxy not found, name " + joint.ObjectNameInScene);
return;
}
// now update the joint proxy object in the scene to have the position of the joint as returned by the physics engine
SceneObjectPart trackedBody = GetSceneObjectPart(joint.TrackedBodyName); // FIXME: causes a sequential lookup
if (trackedBody == null) return; // the actor may have been deleted but the joint still lingers around a few frames waiting for deletion. during this time, trackedBody is NULL to prevent further motion of the joint proxy.
jointProxyObject.Velocity = trackedBody.Velocity;
jointProxyObject.AngularVelocity = trackedBody.AngularVelocity;
switch (joint.Type)
{
case PhysicsJointType.Ball:
{
Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
Vector3 proxyPos = jointAnchor;
jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
}
break;
case PhysicsJointType.Hinge:
{
Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
// Normally, we would just ask the physics scene to return the axis for the joint.
// Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should
// never occur. Therefore we cannot rely on ODE to always return a correct joint axis.
// Therefore the following call does not always work:
//PhysicsVector phyJointAxis = _PhyScene.GetJointAxis(joint);
// instead we compute the joint orientation by saving the original joint orientation
// relative to one of the jointed bodies, and applying this transformation
// to the current position of the jointed bodies (the tracked body) to compute the
// current joint orientation.
if (joint.TrackedBodyName == null)
{
jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene);
}
Vector3 proxyPos = jointAnchor;
Quaternion q = trackedBody.RotationOffset * joint.LocalRotation;
jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
jointProxyObject.ParentGroup.UpdateGroupRotationR(q); // schedules the entire group for a terse update
}
break;
}
}
// This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
// update non-physical objects like the joint proxy objects that represent the position
// of the joints in the scene.
// This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
// WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
// from within the OdePhysicsScene.
protected internal void jointDeactivated(PhysicsJoint joint)
{
//m_log.Debug("[NINJA] SceneGraph.jointDeactivated, joint:" + joint.ObjectNameInScene);
SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
if (jointProxyObject == null)
{
jointErrorMessage(joint, "WARNING, trying to deactivate (stop interpolation of) joint proxy, but not found, name " + joint.ObjectNameInScene);
return;
}
// turn the proxy non-physical, which also stops its client-side interpolation
bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0);
if (wasUsingPhysics)
{
jointProxyObject.UpdatePrimFlags(false, false, true, false,false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
}
}
// This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
// alert the user of errors by using the debug channel in the same way that scripts alert
// the user of compile errors.
// This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
// WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
// from within the OdePhysicsScene.
public void jointErrorMessage(PhysicsJoint joint, string message)
{
if (joint != null)
{
if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages)
return;
SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
if (jointProxyObject != null)
{
SimChat(Utils.StringToBytes("[NINJA]: " + message),
ChatTypeEnum.DebugChannel,
2147483647,
jointProxyObject.AbsolutePosition,
jointProxyObject.Name,
jointProxyObject.UUID,
false);
joint.ErrorMessageCount++;
if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages)
{
SimChat(Utils.StringToBytes("[NINJA]: Too many messages for this joint, suppressing further messages."),
ChatTypeEnum.DebugChannel,
2147483647,
jointProxyObject.AbsolutePosition,
jointProxyObject.Name,
jointProxyObject.UUID,
false);
}
}
else
{
// couldn't find the joint proxy object; the error message is silently suppressed
}
}
}
public Scene ConsoleScene()
{
if (MainConsole.Instance == null)
@ -6103,40 +5973,40 @@ Environment.Exit(1);
mapModule.GenerateMaptile();
}
// public void CleanDroppedAttachments()
// {
// List<SceneObjectGroup> objectsToDelete =
// new List<SceneObjectGroup>();
//
// lock (m_cleaningAttachments)
// {
// ForEachSOG(delegate (SceneObjectGroup grp)
// {
// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
// {
// UUID agentID = grp.OwnerID;
// if (agentID == UUID.Zero)
// {
// objectsToDelete.Add(grp);
// return;
// }
//
// ScenePresence sp = GetScenePresence(agentID);
// if (sp == null)
// {
// objectsToDelete.Add(grp);
// return;
// }
// }
// });
// }
//
// foreach (SceneObjectGroup grp in objectsToDelete)
// {
// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
// DeleteSceneObject(grp, true);
// }
// }
// public void CleanDroppedAttachments()
// {
// List<SceneObjectGroup> objectsToDelete =
// new List<SceneObjectGroup>();
//
// lock (m_cleaningAttachments)
// {
// ForEachSOG(delegate (SceneObjectGroup grp)
// {
// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
// {
// UUID agentID = grp.OwnerID;
// if (agentID.IsZero())
// {
// objectsToDelete.Add(grp);
// return;
// }
//
// ScenePresence sp = GetScenePresence(agentID);
// if (sp == null)
// {
// objectsToDelete.Add(grp);
// return;
// }
// }
// });
// }
//
// foreach (SceneObjectGroup grp in objectsToDelete)
// {
// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
// DeleteSceneObject(grp, true);
// }
// }
public void ThreadAlive(int threadCode)
{

View file

@ -659,12 +659,12 @@ namespace OpenSim.Region.Framework.Scenes
protected internal void AddPhysicalPrim(int number)
{
m_physicalPrim += number;
Interlocked.Add(ref m_physicalPrim, number);
}
protected internal void RemovePhysicalPrim(int number)
{
m_physicalPrim -= number;
Interlocked.Add(ref m_physicalPrim, -number);
}
protected internal void AddToScriptLPS(int number)
@ -674,7 +674,7 @@ namespace OpenSim.Region.Framework.Scenes
protected internal void AddActiveScripts(int number)
{
m_activeScripts += number;
Interlocked.Add(ref m_activeScripts, number);
}
protected internal void HandleUndo(IClientAPI remoteClient, UUID primId)

Some files were not shown because too many files have changed in this diff Show more