mirror of
https://github.com/OpenSim-NGC/OpenSim-Sasquatch.git
synced 2024-11-21 14:29:10 -07:00
Sync up to upstream through 04/26/2022
This commit is contained in:
commit
7837a7f664
304 changed files with 33028 additions and 31809 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
115
OpenSim/Capabilities/Handlers/FetchInventory/FetchLib2Handler.cs
Normal file
115
OpenSim/Capabilities/Handlers/FetchInventory/FetchLib2Handler.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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://";
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace OpenSim.Framework.Serialization
|
|||
if (!dirName.EndsWith("/"))
|
||||
dirName += "/";
|
||||
|
||||
WriteFile(dirName, new byte[0]);
|
||||
WriteFile(dirName, Array.Empty<byte>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -182,9 +182,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
}
|
||||
|
||||
data = response;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
343
OpenSim/Framework/TerrainTaintsArray.cs
Normal file
343
OpenSim/Framework/TerrainTaintsArray.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
328
OpenSim/Region/ClientStack/Linden/Caps/FetchLibDescModule.cs
Normal file
328
OpenSim/Region/ClientStack/Linden/Caps/FetchLibDescModule.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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) {} );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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))
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"><x,y,?></param>
|
||||
/// <param name="boundingOrigin"><x,y,?></param>
|
||||
/// <param name="boundingSize"><x,y,?></param>
|
||||
/// <param name="regionSize"><x,y,?></param>
|
||||
/// <param name="newRegionSize"><x,y,?></param>
|
||||
/// <param name="isEmptyNow">out: This is set if the resultant bitmap is now empty</param>
|
||||
/// <param name="AABBMin">out: parcel.AABBMin <x,y,0></param>
|
||||
/// <param name="AABBMax">out: parcel.AABBMax <x,y,0></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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue