bad merge?
commit
371c9dd2af
|
@ -1,5 +1,6 @@
|
|||
.project
|
||||
.settings
|
||||
.gitignore
|
||||
*.csproj
|
||||
*.csproj.user
|
||||
*.build
|
||||
|
@ -10,6 +11,7 @@
|
|||
*.pidb
|
||||
*.dll.build
|
||||
*.dll
|
||||
*.log
|
||||
|
||||
# Ignore .user and .suo files as these are user preference specific
|
||||
# http://stackoverflow.com/questions/72298/should-i-add-the-visual-studio-suo-and-user-files-to-source-control
|
||||
|
@ -29,6 +31,7 @@
|
|||
*/*/*/*/*/bin
|
||||
*/*/*/*/*/*/bin
|
||||
*/*/*/*/*/*/*/bin
|
||||
addon-modules/
|
||||
bin/Debug/*.dll
|
||||
bin/*.dll.mdb
|
||||
bin/*.db
|
||||
|
|
|
@ -75,6 +75,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
private string m_name = "RemoteAdminPlugin";
|
||||
private string m_version = "0.0";
|
||||
private string m_openSimVersion;
|
||||
|
||||
public string Version
|
||||
{
|
||||
|
@ -94,6 +95,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
public void Initialise(OpenSimBase openSim)
|
||||
{
|
||||
m_openSimVersion = openSim.GetVersionText();
|
||||
|
||||
m_configSource = openSim.ConfigSource.Source;
|
||||
try
|
||||
{
|
||||
|
@ -136,6 +139,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod);
|
||||
availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod);
|
||||
availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod);
|
||||
availableMethods["admin_dialog"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDialogMethod);
|
||||
availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod);
|
||||
availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod);
|
||||
availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod);
|
||||
|
@ -164,8 +168,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
|
||||
availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
|
||||
|
||||
// Land management
|
||||
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
|
||||
// Misc
|
||||
availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch);
|
||||
availableMethods["admin_refresh_map"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshMap);
|
||||
availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion);
|
||||
availableMethods["admin_get_agent_count"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentCount);
|
||||
|
||||
// Either enable full remote functionality or just selected features
|
||||
string enabledMethods = m_config.GetString("enabled_methods", "all");
|
||||
|
@ -266,25 +273,105 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
try
|
||||
{
|
||||
m_log.Info("[RADMIN]: Request to restart Region.");
|
||||
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene rebootedScene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
|
||||
bool restartAll = false;
|
||||
|
||||
IConfig startupConfig = m_configSource.Configs["Startup"];
|
||||
if (startupConfig != null)
|
||||
{
|
||||
if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
|
||||
{
|
||||
rebootedScene = m_application.SceneManager.CurrentOrFirstScene;
|
||||
restartAll = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rebootedScene == null)
|
||||
{
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
|
||||
}
|
||||
|
||||
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
|
||||
|
||||
responseData["success"] = false;
|
||||
responseData["accepted"] = true;
|
||||
responseData["rebooting"] = true;
|
||||
|
||||
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
|
||||
if (restartModule != null)
|
||||
{
|
||||
List<int> times = new List<int> { 30, 15 };
|
||||
string message;
|
||||
List<int> times = new List<int>();
|
||||
|
||||
restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
|
||||
responseData["success"] = true;
|
||||
if (requestData.ContainsKey("alerts"))
|
||||
{
|
||||
string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','});
|
||||
if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Request to cancel restart.");
|
||||
|
||||
if (restartModule != null)
|
||||
{
|
||||
message = "Restart has been cancelled";
|
||||
|
||||
if (requestData.ContainsKey("message"))
|
||||
message = requestData["message"].ToString();
|
||||
|
||||
restartModule.AbortRestart(message);
|
||||
|
||||
responseData["success"] = true;
|
||||
responseData["rebooting"] = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
foreach (string a in alertTimes)
|
||||
times.Add(Convert.ToInt32(a));
|
||||
}
|
||||
else
|
||||
{
|
||||
int timeout = 30;
|
||||
if (requestData.ContainsKey("milliseconds"))
|
||||
timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000;
|
||||
while (timeout > 0)
|
||||
{
|
||||
times.Add(timeout);
|
||||
if (timeout > 300)
|
||||
timeout -= 120;
|
||||
else if (timeout > 30)
|
||||
timeout -= 30;
|
||||
else
|
||||
timeout -= 15;
|
||||
}
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Request to restart Region.");
|
||||
|
||||
message = "Region is restarting in {0}. Please save what you are doing and log out.";
|
||||
|
||||
if (requestData.ContainsKey("message"))
|
||||
message = requestData["message"].ToString();
|
||||
|
||||
bool notice = true;
|
||||
if (requestData.ContainsKey("noticetype")
|
||||
&& ((string)requestData["noticetype"] == "dialog"))
|
||||
{
|
||||
notice = false;
|
||||
}
|
||||
|
||||
List<Scene> restartList;
|
||||
|
||||
if (restartAll)
|
||||
restartList = m_application.SceneManager.Scenes;
|
||||
else
|
||||
restartList = new List<Scene>() { rebootedScene };
|
||||
|
||||
foreach (Scene s in m_application.SceneManager.Scenes)
|
||||
{
|
||||
restartModule = s.RequestModuleInterface<IRestartModule>();
|
||||
if (restartModule != null)
|
||||
restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice);
|
||||
}
|
||||
responseData["success"] = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -321,6 +408,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
m_log.Info("[RADMIN]: Alert request complete");
|
||||
}
|
||||
|
||||
public void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
|
||||
m_log.Info("[RADMIN]: Dialog request started");
|
||||
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
string message = (string)requestData["message"];
|
||||
string fromuuid = (string)requestData["from"];
|
||||
m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
|
||||
|
||||
responseData["accepted"] = true;
|
||||
responseData["success"] = true;
|
||||
|
||||
m_application.SceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
|
||||
});
|
||||
|
||||
m_log.Info("[RADMIN]: Dialog request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Load height maps request started");
|
||||
|
@ -424,13 +537,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
message = "Region is going down now.";
|
||||
}
|
||||
|
||||
m_application.SceneManager.ForEachScene(
|
||||
if (requestData.ContainsKey("noticetype")
|
||||
&& ((string) requestData["noticetype"] == "dialog"))
|
||||
{
|
||||
m_application.SceneManager.ForEachScene(
|
||||
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!requestData.ContainsKey("noticetype")
|
||||
|| ((string)requestData["noticetype"] != "none"))
|
||||
{
|
||||
m_application.SceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendGeneralAlert(message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Perform shutdown
|
||||
System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
|
||||
|
@ -1489,7 +1621,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
}
|
||||
|
||||
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
|
||||
Dictionary<string, object> archiveOptions = new Dictionary<string,object>();
|
||||
Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
|
||||
if (mergeOar) archiveOptions.Add("merge", null);
|
||||
if (skipAssets) archiveOptions.Add("skipAssets", null);
|
||||
if (archiver != null)
|
||||
|
@ -1749,21 +1881,31 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
|
||||
private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Query XML Administrator Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
int flags = 0;
|
||||
string text = String.Empty;
|
||||
int health = 0;
|
||||
responseData["success"] = true;
|
||||
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
|
||||
int health = scene.GetHealth();
|
||||
responseData["health"] = health;
|
||||
try
|
||||
{
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
health = scene.GetHealth(out flags, out text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
responseData["error"] = null;
|
||||
}
|
||||
|
||||
responseData["success"] = true;
|
||||
m_log.Info("[RADMIN]: Query XML Administrator Request complete");
|
||||
responseData["health"] = health;
|
||||
responseData["flags"] = flags;
|
||||
responseData["message"] = text;
|
||||
}
|
||||
|
||||
private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
|
@ -2068,55 +2210,97 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
responseData["success"] = true;
|
||||
}
|
||||
|
||||
private void XmlRpcResetLand(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
m_log.Info("[RADMIN]: Received Refresh Search Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
string musicURL = string.Empty;
|
||||
UUID groupID = UUID.Zero;
|
||||
uint flags = 0;
|
||||
bool set_group = false, set_music = false, set_flags = false;
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
if (requestData.Contains("group") && requestData["group"] != null)
|
||||
set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
|
||||
if (requestData.Contains("music") && requestData["music"] != null)
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
|
||||
ISearchModule searchModule = scene.RequestModuleInterface<ISearchModule>();
|
||||
if (searchModule != null)
|
||||
{
|
||||
musicURL = requestData["music"].ToString();
|
||||
set_music = true;
|
||||
searchModule.Refresh();
|
||||
responseData["success"] = true;
|
||||
}
|
||||
if (requestData.Contains("flags") && requestData["flags"] != null)
|
||||
set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags);
|
||||
|
||||
m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}",
|
||||
(set_group ? groupID.ToString() : "unchanged"),
|
||||
(set_music ? musicURL : "unchanged"),
|
||||
(set_flags ? flags.ToString() : "unchanged"));
|
||||
|
||||
m_application.SceneManager.ForEachScene(delegate(Scene s)
|
||||
else
|
||||
{
|
||||
List<ILandObject> parcels = s.LandChannel.AllParcels();
|
||||
foreach (ILandObject p in parcels)
|
||||
{
|
||||
if (set_music)
|
||||
p.LandData.MusicURL = musicURL;
|
||||
|
||||
if (set_group)
|
||||
p.LandData.GroupID = groupID;
|
||||
|
||||
if (set_flags)
|
||||
p.LandData.Flags = flags;
|
||||
|
||||
s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData);
|
||||
}
|
||||
responseData["success"] = false;
|
||||
}
|
||||
);
|
||||
|
||||
responseData["success"] = true;
|
||||
|
||||
m_log.Info("[RADMIN]: Reset Land Request complete");
|
||||
m_log.Info("[RADMIN]: Refresh Search Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcRefreshMap(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Refresh Map Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
|
||||
IMapImageUploadModule mapTileModule = scene.RequestModuleInterface<IMapImageUploadModule>();
|
||||
if (mapTileModule != null)
|
||||
{
|
||||
Util.FireAndForget((x) =>
|
||||
{
|
||||
mapTileModule.UploadMapTile(scene);
|
||||
});
|
||||
responseData["success"] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseData["success"] = false;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Refresh Map Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Get OpenSim Version Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
|
||||
responseData["version"] = m_openSimVersion;
|
||||
responseData["success"] = true;
|
||||
|
||||
m_log.Info("[RADMIN]: Get OpenSim Version Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcGetAgentCount(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Get Agent Count Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
|
||||
if (scene == null)
|
||||
{
|
||||
responseData["success"] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseData["count"] = scene.GetRootAgentCount();
|
||||
responseData["success"] = true;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Get Agent Count Request complete");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a float with the given parameter name from a request data hash table.
|
||||
|
@ -2823,7 +3007,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
|||
/// </summary>
|
||||
private void ApplyNextOwnerPermissions(InventoryItemBase item)
|
||||
{
|
||||
if (item.InvType == (int)InventoryType.Object)
|
||||
if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
|
||||
{
|
||||
uint perms = item.CurrentPermissions;
|
||||
PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms);
|
||||
|
|
|
@ -30,6 +30,7 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
|
@ -71,6 +72,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
private IHttpServer m_httpListener;
|
||||
private UUID m_agentID;
|
||||
private string m_regionName;
|
||||
private ManualResetEvent m_capsActive = new ManualResetEvent(false);
|
||||
|
||||
public UUID AgentID
|
||||
{
|
||||
|
@ -136,6 +138,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
m_agentID = agent;
|
||||
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
|
||||
m_regionName = regionName;
|
||||
m_capsActive.Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -255,5 +258,16 @@ namespace OpenSim.Framework.Capabilities
|
|||
|
||||
return caps;
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
m_capsActive.Set();
|
||||
}
|
||||
|
||||
public bool WaitForActivation()
|
||||
{
|
||||
// Wait for 30s. If that elapses, return false and run without caps
|
||||
return m_capsActive.WaitOne(120000);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,6 +90,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
lock (m_capsHandlers)
|
||||
{
|
||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
|
||||
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[capsName].Path);
|
||||
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
|
||||
m_capsHandlers.Remove(capsName);
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
llsdItem.asset_id = invItem.AssetID;
|
||||
llsdItem.created_at = invItem.CreationDate;
|
||||
llsdItem.desc = invItem.Description;
|
||||
llsdItem.flags = (int)invItem.Flags;
|
||||
llsdItem.flags = ((int)invItem.Flags) & 0xff;
|
||||
llsdItem.item_id = invItem.ID;
|
||||
llsdItem.name = invItem.Name;
|
||||
llsdItem.parent_id = invItem.Folder;
|
||||
|
|
|
@ -44,26 +44,64 @@ namespace OpenSim.Capabilities.Handlers
|
|||
public class GetMeshHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IAssetService m_assetService;
|
||||
|
||||
// TODO: Change this to a config option
|
||||
private string m_RedirectURL = null;
|
||||
public const string DefaultFormat = "vnd.ll.mesh";
|
||||
|
||||
public GetMeshHandler(string path, IAssetService assService, string name, string description, string redirectURL)
|
||||
: base("GET", path, name, description)
|
||||
public GetMeshHandler(IAssetService assService)
|
||||
{
|
||||
m_assetService = assService;
|
||||
m_RedirectURL = redirectURL;
|
||||
if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
|
||||
m_RedirectURL += "/";
|
||||
}
|
||||
public Hashtable Handle(Hashtable request)
|
||||
{
|
||||
Hashtable ret = new Hashtable();
|
||||
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
||||
ret["content_type"] = "text/plain";
|
||||
ret["keepalive"] = false;
|
||||
ret["reusecontext"] = false;
|
||||
ret["int_bytes"] = 0;
|
||||
ret["int_lod"] = 0;
|
||||
string MeshStr = (string)request["mesh_id"];
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
|
||||
//m_log.DebugFormat("[GETMESH]: called {0}", MeshStr);
|
||||
|
||||
if (m_assetService == null)
|
||||
{
|
||||
m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service");
|
||||
}
|
||||
|
||||
UUID meshID;
|
||||
if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID))
|
||||
{
|
||||
// m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID);
|
||||
|
||||
|
||||
ret = ProcessGetMesh(request, UUID.Zero, null);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
||||
{
|
||||
// Try to parse the texture ID from the request URL
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
string textureStr = query.GetOne("mesh_id");
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["int_lod"] = 0;
|
||||
responsedata["int_bytes"] = 0;
|
||||
|
||||
if (m_assetService == null)
|
||||
{
|
||||
|
@ -160,40 +198,121 @@ namespace OpenSim.Capabilities.Handlers
|
|||
// sending back the last byte instead of an error status
|
||||
if (start >= texture.Data.Length)
|
||||
{
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle the case where no second range value was given. This is equivalent to requesting
|
||||
// the rest of the entity.
|
||||
if (end == -1)
|
||||
end = int.MaxValue;
|
||||
|
||||
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
|
||||
start = Utils.Clamp(start, 0, end);
|
||||
int len = end - start + 1;
|
||||
Hashtable headers = new Hashtable();
|
||||
responsedata["headers"] = headers;
|
||||
|
||||
if (0 == start && len == texture.Data.Length)
|
||||
string range = String.Empty;
|
||||
|
||||
if (((Hashtable)request["headers"])["range"] != null)
|
||||
range = (string)((Hashtable)request["headers"])["range"];
|
||||
|
||||
else if (((Hashtable)request["headers"])["Range"] != null)
|
||||
range = (string)((Hashtable)request["headers"])["Range"];
|
||||
|
||||
if (!String.IsNullOrEmpty(range)) // Mesh Asset LOD // Physics
|
||||
{
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
// Range request
|
||||
int start, end;
|
||||
if (TryParseRange(range, out start, out end))
|
||||
{
|
||||
// Before clamping start make sure we can satisfy it in order to avoid
|
||||
// sending back the last byte instead of an error status
|
||||
if (start >= mesh.Data.Length)
|
||||
{
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "This range doesnt exist.";
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["int_lod"] = 3;
|
||||
return responsedata;
|
||||
}
|
||||
else
|
||||
{
|
||||
end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
|
||||
start = Utils.Clamp(start, 0, end);
|
||||
int len = end - start + 1;
|
||||
|
||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||
|
||||
if (start > 20000)
|
||||
{
|
||||
responsedata["int_lod"] = 3;
|
||||
}
|
||||
else if (start < 4097)
|
||||
{
|
||||
responsedata["int_lod"] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
responsedata["int_lod"] = 2;
|
||||
}
|
||||
|
||||
|
||||
if (start == 0 && len == mesh.Data.Length) // well redudante maybe
|
||||
{
|
||||
responsedata["int_response_code"] = (int) System.Net.HttpStatusCode.OK;
|
||||
responsedata["bin_response_data"] = mesh.Data;
|
||||
responsedata["int_bytes"] = mesh.Data.Length;
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["int_lod"] = 3;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
responsedata["int_response_code"] =
|
||||
(int) System.Net.HttpStatusCode.PartialContent;
|
||||
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end,
|
||||
mesh.Data.Length);
|
||||
|
||||
byte[] d = new byte[len];
|
||||
Array.Copy(mesh.Data, start, d, 0, len);
|
||||
responsedata["bin_response_data"] = d;
|
||||
responsedata["int_bytes"] = len;
|
||||
responsedata["reusecontext"] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
|
||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||
responsedata["int_response_code"] = 200;
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["int_lod"] = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
|
||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||
responsedata["int_response_code"] = 200;
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["int_lod"] = 3;
|
||||
}
|
||||
|
||||
response.ContentLength = len;
|
||||
response.ContentType = "application/vnd.ll.mesh";
|
||||
|
||||
response.Body.Write(texture.Data, start, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["int_lod"] = 1;
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETMESH]: Malformed Range header: " + range);
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["int_lod"] = 0;
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -246,6 +365,21 @@ namespace OpenSim.Capabilities.Handlers
|
|||
}
|
||||
}
|
||||
|
||||
start = end = 0;
|
||||
return false;
|
||||
}
|
||||
private bool TryParseRange(string header, out int start, out int end)
|
||||
{
|
||||
if (header.StartsWith("bytes="))
|
||||
{
|
||||
string[] rangeValues = header.Substring(6).Split('-');
|
||||
if (rangeValues.Length == 2)
|
||||
{
|
||||
if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
start = end = 0;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -47,10 +47,11 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
|
|||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class GetTextureHandler : BaseStreamHandler
|
||||
public class GetTextureHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IAssetService m_assetService;
|
||||
|
||||
public const string DefaultFormat = "x-j2c";
|
||||
|
@ -58,8 +59,8 @@ namespace OpenSim.Capabilities.Handlers
|
|||
// TODO: Change this to a config option
|
||||
private string m_RedirectURL = null;
|
||||
|
||||
public GetTextureHandler(string path, IAssetService assService, string name, string description, string redirectURL)
|
||||
: base("GET", path, name, description)
|
||||
|
||||
public GetTextureHandler(IAssetService assService)
|
||||
{
|
||||
m_assetService = assService;
|
||||
m_RedirectURL = redirectURL;
|
||||
|
@ -67,19 +68,22 @@ namespace OpenSim.Capabilities.Handlers
|
|||
m_RedirectURL += "/";
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
public Hashtable Handle(Hashtable request)
|
||||
{
|
||||
// Try to parse the texture ID from the request URL
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
string textureStr = query.GetOne("texture_id");
|
||||
string format = query.GetOne("format");
|
||||
Hashtable ret = new Hashtable();
|
||||
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
||||
ret["content_type"] = "text/plain";
|
||||
ret["keepalive"] = false;
|
||||
ret["reusecontext"] = false;
|
||||
ret["int_bytes"] = 0;
|
||||
string textureStr = (string)request["texture_id"];
|
||||
string format = (string)request["format"];
|
||||
|
||||
//m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
|
||||
|
||||
if (m_assetService == null)
|
||||
{
|
||||
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
}
|
||||
|
||||
UUID textureID;
|
||||
|
@ -94,30 +98,41 @@ namespace OpenSim.Capabilities.Handlers
|
|||
}
|
||||
else
|
||||
{
|
||||
formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
|
||||
formats = new string[1] { DefaultFormat }; // default
|
||||
if (((Hashtable)request["headers"])["Accept"] != null)
|
||||
formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
|
||||
if (formats.Length == 0)
|
||||
formats = new string[1] { DefaultFormat }; // default
|
||||
|
||||
}
|
||||
// OK, we have an array with preferred formats, possibly with only one entry
|
||||
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
bool foundtexture = false;
|
||||
foreach (string f in formats)
|
||||
{
|
||||
if (FetchTexture(httpRequest, httpResponse, textureID, f))
|
||||
foundtexture = FetchTexture(request, ret, textureID, f);
|
||||
if (foundtexture)
|
||||
break;
|
||||
}
|
||||
if (!foundtexture)
|
||||
{
|
||||
ret["int_response_code"] = 404;
|
||||
ret["error_status_text"] = "not found";
|
||||
ret["str_response_string"] = "not found";
|
||||
ret["content_type"] = "text/plain";
|
||||
ret["keepalive"] = false;
|
||||
ret["reusecontext"] = false;
|
||||
ret["int_bytes"] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
|
||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
||||
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
||||
|
||||
return null;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -128,7 +143,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
/// <param name="textureID"></param>
|
||||
/// <param name="format"></param>
|
||||
/// <returns>False for "caller try another codec"; true otherwise</returns>
|
||||
private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
|
||||
private bool FetchTexture(Hashtable request, Hashtable response, UUID textureID, string format)
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
|
||||
AssetBase texture;
|
||||
|
@ -137,86 +152,70 @@ namespace OpenSim.Capabilities.Handlers
|
|||
if (format != DefaultFormat)
|
||||
fullID = fullID + "-" + format;
|
||||
|
||||
if (!String.IsNullOrEmpty(m_RedirectURL))
|
||||
// try the cache
|
||||
texture = m_assetService.GetCached(fullID);
|
||||
|
||||
if (texture == null)
|
||||
{
|
||||
// Only try to fetch locally cached textures. Misses are redirected
|
||||
texture = m_assetService.GetCached(fullID);
|
||||
//m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
|
||||
|
||||
// Fetch locally or remotely. Misses return a 404
|
||||
texture = m_assetService.Get(textureID.ToString());
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
if (texture.Type != (sbyte)AssetType.Texture)
|
||||
return true;
|
||||
|
||||
if (format == DefaultFormat)
|
||||
{
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
WriteTextureData(request, response, texture, format);
|
||||
return true;
|
||||
}
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
}
|
||||
else
|
||||
{
|
||||
string textureUrl = m_RedirectURL + "?texture_id="+ textureID.ToString();
|
||||
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
|
||||
httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently;
|
||||
httpResponse.RedirectLocation = textureUrl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else // no redirect
|
||||
{
|
||||
// try the cache
|
||||
texture = m_assetService.GetCached(fullID);
|
||||
|
||||
if (texture == null)
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
|
||||
|
||||
// Fetch locally or remotely. Misses return a 404
|
||||
texture = m_assetService.Get(textureID.ToString());
|
||||
|
||||
if (texture != null)
|
||||
else
|
||||
{
|
||||
if (texture.Type != (sbyte)AssetType.Texture)
|
||||
{
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
}
|
||||
if (format == DefaultFormat)
|
||||
{
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
|
||||
newTexture.Data = ConvertTextureData(texture, format);
|
||||
if (newTexture.Data.Length == 0)
|
||||
return false; // !!! Caller try another codec, please!
|
||||
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
|
||||
newTexture.Data = ConvertTextureData(texture, format);
|
||||
if (newTexture.Data.Length == 0)
|
||||
return false; // !!! Caller try another codec, please!
|
||||
|
||||
newTexture.Flags = AssetFlags.Collectable;
|
||||
newTexture.Temporary = true;
|
||||
newTexture.Local = true;
|
||||
m_assetService.Store(newTexture);
|
||||
WriteTextureData(httpRequest, httpResponse, newTexture, format);
|
||||
return true;
|
||||
}
|
||||
newTexture.Flags = AssetFlags.Collectable;
|
||||
newTexture.Temporary = true;
|
||||
newTexture.Local = true;
|
||||
m_assetService.Store(newTexture);
|
||||
WriteTextureData(request, response, newTexture, format);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else // it was on the cache
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // it was on the cache
|
||||
{
|
||||
//m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
|
||||
WriteTextureData(request, response, texture, format);
|
||||
return true;
|
||||
}
|
||||
|
||||
//response = new Hashtable();
|
||||
|
||||
|
||||
//WriteTextureData(request,response,null,format);
|
||||
// not found
|
||||
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
//m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
|
||||
private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
|
||||
{
|
||||
string range = request.Headers.GetOne("Range");
|
||||
Hashtable headers = new Hashtable();
|
||||
response["headers"] = headers;
|
||||
|
||||
string range = String.Empty;
|
||||
|
||||
if (((Hashtable)request["headers"])["range"] != null)
|
||||
range = (string)((Hashtable)request["headers"])["range"];
|
||||
|
||||
else if (((Hashtable)request["headers"])["Range"] != null)
|
||||
range = (string)((Hashtable)request["headers"])["Range"];
|
||||
|
||||
if (!String.IsNullOrEmpty(range)) // JP2's only
|
||||
{
|
||||
|
@ -244,10 +243,8 @@ namespace OpenSim.Capabilities.Handlers
|
|||
// However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
|
||||
|
||||
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||
// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
|
||||
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
// viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
|
||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -262,41 +259,46 @@ namespace OpenSim.Capabilities.Handlers
|
|||
|
||||
// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||
|
||||
// Always return PartialContent, even if the range covered the entire data length
|
||||
// We were accidentally sending back 404 before in this situation
|
||||
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
|
||||
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
|
||||
//
|
||||
// We also do not want to send back OK even if the whole range was satisfiable since this causes
|
||||
// HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
|
||||
// if (end > maxEnd)
|
||||
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
// else
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
response["content-type"] = texture.Metadata.ContentType;
|
||||
|
||||
response.ContentLength = len;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
|
||||
if (start == 0 && len == texture.Data.Length) // well redudante maybe
|
||||
{
|
||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
||||
response["bin_response_data"] = texture.Data;
|
||||
response["int_bytes"] = texture.Data.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
|
||||
|
||||
response.Body.Write(texture.Data, start, len);
|
||||
byte[] d = new byte[len];
|
||||
Array.Copy(texture.Data, start, d, 0, len);
|
||||
response["bin_response_data"] = d;
|
||||
response["int_bytes"] = len;
|
||||
}
|
||||
// response.Body.Write(texture.Data, start, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
|
||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
|
||||
}
|
||||
}
|
||||
else // JP2's or other formats
|
||||
{
|
||||
// Full content request
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
response.ContentLength = texture.Data.Length;
|
||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
||||
if (format == DefaultFormat)
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
response["content_type"] = texture.Metadata.ContentType;
|
||||
else
|
||||
response.ContentType = "image/" + format;
|
||||
response.Body.Write(texture.Data, 0, texture.Data.Length);
|
||||
response["content_type"] = "image/" + format;
|
||||
|
||||
response["bin_response_data"] = texture.Data;
|
||||
response["int_bytes"] = texture.Data.Length;
|
||||
|
||||
// response.Body.Write(texture.Data, 0, texture.Data.Length);
|
||||
}
|
||||
|
||||
// if (response.StatusCode < 200 || response.StatusCode > 299)
|
||||
|
|
|
@ -33,6 +33,7 @@ using OpenSim.Framework.Servers.HttpServer;
|
|||
using OpenSim.Server.Handlers.Base;
|
||||
using OpenMetaverse;
|
||||
|
||||
/*
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class GetTextureServerConnector : ServiceConnector
|
||||
|
@ -69,3 +70,4 @@ namespace OpenSim.Capabilities.Handlers
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -38,6 +38,7 @@ using OpenSim.Framework.Servers.HttpServer;
|
|||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
|
||||
/*
|
||||
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
|
@ -60,3 +61,4 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
|
@ -50,6 +51,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
{
|
||||
public class UploadBakedTextureHandler
|
||||
{
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Caps m_HostCapsObj;
|
||||
|
@ -81,7 +83,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
|
||||
|
||||
BakedTextureUploader uploader =
|
||||
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
|
||||
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_HostCapsObj.AgentID);
|
||||
uploader.OnUpLoad += BakedTextureUploaded;
|
||||
|
||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||
|
@ -117,7 +119,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
/// <param name="data"></param>
|
||||
private void BakedTextureUploaded(UUID assetID, byte[] data)
|
||||
{
|
||||
// m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString());
|
||||
m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString());
|
||||
|
||||
AssetBase asset;
|
||||
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
|
||||
|
@ -125,6 +127,7 @@ namespace OpenSim.Capabilities.Handlers
|
|||
asset.Temporary = true;
|
||||
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
|
||||
m_assetService.Store(asset);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,15 +140,19 @@ namespace OpenSim.Capabilities.Handlers
|
|||
private string uploaderPath = String.Empty;
|
||||
private UUID newAssetID;
|
||||
private IHttpServer httpListener;
|
||||
private UUID AgentId = UUID.Zero;
|
||||
|
||||
public BakedTextureUploader(string path, IHttpServer httpServer)
|
||||
public BakedTextureUploader(string path, IHttpServer httpServer, UUID uUID)
|
||||
{
|
||||
newAssetID = UUID.Random();
|
||||
uploaderPath = path;
|
||||
httpListener = httpServer;
|
||||
AgentId = uUID;
|
||||
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handle raw uploaded baked texture data.
|
||||
/// </summary>
|
||||
|
|
|
@ -0,0 +1,438 @@
|
|||
/*
|
||||
* 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 OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class WebFetchInvDescHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IInventoryService m_InventoryService;
|
||||
private ILibraryService m_LibraryService;
|
||||
// private object m_fetchLock = new Object();
|
||||
|
||||
public WebFetchInvDescHandler(IInventoryService invService, ILibraryService libService)
|
||||
{
|
||||
m_InventoryService = invService;
|
||||
m_LibraryService = libService;
|
||||
}
|
||||
|
||||
public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// lock (m_fetchLock)
|
||||
// {
|
||||
// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request {0}", request);
|
||||
|
||||
// nasty temporary hack here, the linden client falsely
|
||||
// identifies the uuid 00000000-0000-0000-0000-000000000000
|
||||
// as a string which breaks us
|
||||
//
|
||||
// correctly mark it as a uuid
|
||||
//
|
||||
request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
|
||||
|
||||
// another hack <integer>1</integer> results in a
|
||||
// System.ArgumentException: Object type System.Int32 cannot
|
||||
// be converted to target type: System.Boolean
|
||||
//
|
||||
request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
|
||||
request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
|
||||
|
||||
Hashtable hash = new Hashtable();
|
||||
try
|
||||
{
|
||||
hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
|
||||
}
|
||||
catch (LLSD.LLSDParseException e)
|
||||
{
|
||||
m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
|
||||
m_log.Error("Request: " + request);
|
||||
}
|
||||
|
||||
ArrayList foldersrequested = (ArrayList)hash["folders"];
|
||||
|
||||
string response = "";
|
||||
|
||||
for (int i = 0; i < foldersrequested.Count; i++)
|
||||
{
|
||||
string inventoryitemstr = "";
|
||||
Hashtable inventoryhash = (Hashtable)foldersrequested[i];
|
||||
|
||||
LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
|
||||
|
||||
try
|
||||
{
|
||||
LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
|
||||
}
|
||||
LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
|
||||
|
||||
inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
|
||||
inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
|
||||
inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
|
||||
|
||||
response += inventoryitemstr;
|
||||
}
|
||||
|
||||
if (response.Length == 0)
|
||||
{
|
||||
// Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
|
||||
// Therefore, I'm concluding that the client only has so many threads available to do requests
|
||||
// and when a thread stalls.. is stays stalled.
|
||||
// Therefore we need to return something valid
|
||||
response = "<llsd><map><key>folders</key><array /></map></llsd>";
|
||||
}
|
||||
else
|
||||
{
|
||||
response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
|
||||
//m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
|
||||
|
||||
return response;
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct an LLSD reply packet to a CAPS inventory request
|
||||
/// </summary>
|
||||
/// <param name="invFetch"></param>
|
||||
/// <returns></returns>
|
||||
private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
|
||||
{
|
||||
LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
|
||||
LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
|
||||
contents.agent_id = invFetch.owner_id;
|
||||
contents.owner_id = invFetch.owner_id;
|
||||
contents.folder_id = invFetch.folder_id;
|
||||
|
||||
reply.folders.Array.Add(contents);
|
||||
InventoryCollection inv = new InventoryCollection();
|
||||
inv.Folders = new List<InventoryFolderBase>();
|
||||
inv.Items = new List<InventoryItemBase>();
|
||||
int version = 0;
|
||||
int descendents = 0;
|
||||
|
||||
inv
|
||||
= Fetch(
|
||||
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
|
||||
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
|
||||
|
||||
if (inv != null && inv.Folders != null)
|
||||
{
|
||||
foreach (InventoryFolderBase invFolder in inv.Folders)
|
||||
{
|
||||
contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
|
||||
}
|
||||
|
||||
descendents += inv.Folders.Count;
|
||||
}
|
||||
|
||||
if (inv != null && inv.Items != null)
|
||||
{
|
||||
foreach (InventoryItemBase invItem in inv.Items)
|
||||
{
|
||||
contents.items.Array.Add(ConvertInventoryItem(invItem));
|
||||
}
|
||||
}
|
||||
|
||||
contents.descendents = descendents;
|
||||
contents.version = version;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}",
|
||||
// invFetch.folder_id,
|
||||
// invFetch.fetch_items,
|
||||
// invFetch.fetch_folders,
|
||||
// contents.items.Array.Count,
|
||||
// contents.categories.Array.Count,
|
||||
// invFetch.owner_id);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the caps inventory descendents fetch.
|
||||
/// </summary>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="folderID"></param>
|
||||
/// <param name="ownerID"></param>
|
||||
/// <param name="fetchFolders"></param>
|
||||
/// <param name="fetchItems"></param>
|
||||
/// <param name="sortOrder"></param>
|
||||
/// <param name="version"></param>
|
||||
/// <returns>An empty InventoryCollection if the inventory look up failed</returns>
|
||||
private InventoryCollection Fetch(
|
||||
UUID agentID, UUID folderID, UUID ownerID,
|
||||
bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
||||
// fetchFolders, fetchItems, folderID, agentID);
|
||||
|
||||
// FIXME MAYBE: We're not handling sortOrder!
|
||||
|
||||
version = 0;
|
||||
descendents = 0;
|
||||
|
||||
InventoryFolderImpl fold;
|
||||
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
|
||||
{
|
||||
if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
|
||||
{
|
||||
InventoryCollection ret = new InventoryCollection();
|
||||
ret.Folders = new List<InventoryFolderBase>();
|
||||
ret.Items = fold.RequestListOfItems();
|
||||
descendents = ret.Folders.Count + ret.Items.Count;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
InventoryCollection contents = new InventoryCollection();
|
||||
|
||||
if (folderID != UUID.Zero)
|
||||
{
|
||||
contents = m_InventoryService.GetFolderContent(agentID, folderID);
|
||||
InventoryFolderBase containingFolder = new InventoryFolderBase();
|
||||
containingFolder.ID = folderID;
|
||||
containingFolder.Owner = agentID;
|
||||
containingFolder = m_InventoryService.GetFolder(containingFolder);
|
||||
|
||||
if (containingFolder != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
|
||||
// containingFolder.Name, containingFolder.ID, agentID);
|
||||
|
||||
version = containingFolder.Version;
|
||||
|
||||
if (fetchItems)
|
||||
{
|
||||
List<InventoryItemBase> itemsToReturn = contents.Items;
|
||||
List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn);
|
||||
|
||||
// descendents must only include the links, not the linked items we add
|
||||
descendents = originalItems.Count;
|
||||
|
||||
// Add target items for links in this folder before the links themselves.
|
||||
foreach (InventoryItemBase item in originalItems)
|
||||
{
|
||||
if (item.AssetType == (int)AssetType.Link)
|
||||
{
|
||||
InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
||||
|
||||
// Take care of genuinely broken links where the target doesn't exist
|
||||
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||
// rather than having to keep track of every folder requested in the recursion.
|
||||
if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||
itemsToReturn.Insert(0, linkedItem);
|
||||
}
|
||||
}
|
||||
|
||||
// Now scan for folder links and insert the items they target and those links at the head of the return data
|
||||
foreach (InventoryItemBase item in originalItems)
|
||||
{
|
||||
if (item.AssetType == (int)AssetType.LinkFolder)
|
||||
{
|
||||
InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
|
||||
List<InventoryItemBase> links = linkedFolderContents.Items;
|
||||
|
||||
itemsToReturn.InsertRange(0, links);
|
||||
|
||||
foreach (InventoryItemBase link in linkedFolderContents.Items)
|
||||
{
|
||||
// Take care of genuinely broken links where the target doesn't exist
|
||||
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||
// rather than having to keep track of every folder requested in the recursion.
|
||||
if (link != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
|
||||
// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
|
||||
|
||||
InventoryItemBase linkedItem
|
||||
= m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
|
||||
|
||||
if (linkedItem != null)
|
||||
itemsToReturn.Insert(0, linkedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// foreach (InventoryItemBase item in contents.Items)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
|
||||
// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
|
||||
// }
|
||||
|
||||
// =====
|
||||
|
||||
//
|
||||
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
|
||||
// linkedItem.Name, folderID, agentID);
|
||||
//
|
||||
// contents.Items.Add(linkedItem);
|
||||
// }
|
||||
//
|
||||
// // If the folder requested contains links, then we need to send those folders first, otherwise the links
|
||||
// // will be broken in the viewer.
|
||||
// HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
|
||||
// foreach (InventoryItemBase item in contents.Items)
|
||||
// {
|
||||
// if (item.AssetType == (int)AssetType.Link)
|
||||
// {
|
||||
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
||||
//
|
||||
// // Take care of genuinely broken links where the target doesn't exist
|
||||
// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||
// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||
// // rather than having to keep track of every folder requested in the recursion.
|
||||
// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||
// {
|
||||
// // We don't need to send the folder if source and destination of the link are in the same
|
||||
// // folder.
|
||||
// if (linkedItem.Folder != containingFolder.ID)
|
||||
// linkedItemFolderIdsToSend.Add(linkedItem.Folder);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
|
||||
// linkedItemFolderId, folderID, agentID);
|
||||
//
|
||||
// int dummyVersion;
|
||||
// InventoryCollection linkedCollection
|
||||
// = Fetch(
|
||||
// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
|
||||
//
|
||||
// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
|
||||
// linkedFolder.Owner = agentID;
|
||||
// linkedFolder = m_InventoryService.GetFolder(linkedFolder);
|
||||
//
|
||||
//// contents.Folders.AddRange(linkedCollection.Folders);
|
||||
//
|
||||
// contents.Folders.Add(linkedFolder);
|
||||
// contents.Items.AddRange(linkedCollection.Items);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Lost items don't really need a version
|
||||
version = 1;
|
||||
}
|
||||
|
||||
return contents;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Convert an internal inventory folder object into an LLSD object.
|
||||
/// </summary>
|
||||
/// <param name="invFolder"></param>
|
||||
/// <returns></returns>
|
||||
private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
|
||||
{
|
||||
LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
|
||||
llsdFolder.folder_id = invFolder.ID;
|
||||
llsdFolder.parent_id = invFolder.ParentID;
|
||||
llsdFolder.name = invFolder.Name;
|
||||
llsdFolder.type = invFolder.Type;
|
||||
llsdFolder.preferred_type = -1;
|
||||
|
||||
return llsdFolder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an internal inventory item object into an LLSD object.
|
||||
/// </summary>
|
||||
/// <param name="invItem"></param>
|
||||
/// <returns></returns>
|
||||
private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
|
||||
{
|
||||
LLSDInventoryItem llsdItem = new LLSDInventoryItem();
|
||||
llsdItem.asset_id = invItem.AssetID;
|
||||
llsdItem.created_at = invItem.CreationDate;
|
||||
llsdItem.desc = invItem.Description;
|
||||
llsdItem.flags = ((int)invItem.Flags) & 0xff;
|
||||
llsdItem.item_id = invItem.ID;
|
||||
llsdItem.name = invItem.Name;
|
||||
llsdItem.parent_id = invItem.Folder;
|
||||
llsdItem.type = invItem.AssetType;
|
||||
llsdItem.inv_type = invItem.InvType;
|
||||
|
||||
llsdItem.permissions = new LLSDPermissions();
|
||||
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
|
||||
llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
|
||||
llsdItem.permissions.group_id = invItem.GroupID;
|
||||
llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
|
||||
llsdItem.permissions.is_owner_group = invItem.GroupOwned;
|
||||
llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
|
||||
llsdItem.permissions.owner_id = invItem.Owner;
|
||||
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||
llsdItem.sale_info = new LLSDSaleInfo();
|
||||
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||
llsdItem.sale_info.sale_type = invItem.SaleType;
|
||||
|
||||
return llsdItem;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,12 +30,15 @@ using OpenMetaverse;
|
|||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
|
||||
[LLSDType("MAP")]
|
||||
public class LLSDAssetUploadComplete
|
||||
{
|
||||
public string new_asset = String.Empty;
|
||||
public UUID new_inventory_item = UUID.Zero;
|
||||
// public UUID new_texture_folder_id = UUID.Zero;
|
||||
public string state = String.Empty;
|
||||
public LLSDAssetUploadError error = null;
|
||||
//public bool success = false;
|
||||
|
||||
public LLSDAssetUploadComplete()
|
||||
|
|
|
@ -30,15 +30,28 @@ using OpenMetaverse;
|
|||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDAssetResource
|
||||
{
|
||||
public OSDArray instance_list = new OSDArray();
|
||||
public OSDArray texture_list = new OSDArray();
|
||||
public OSDArray mesh_list = new OSDArray();
|
||||
public string metric = String.Empty;
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadRequest
|
||||
{
|
||||
public string asset_type = String.Empty;
|
||||
public string description = String.Empty;
|
||||
public UUID folder_id = UUID.Zero;
|
||||
public UUID texture_folder_id = UUID.Zero;
|
||||
public int next_owner_mask = 0;
|
||||
public int group_mask = 0;
|
||||
public int everyone_mask = 0;
|
||||
public string inventory_type = String.Empty;
|
||||
public string name = String.Empty;
|
||||
|
||||
public LLSDAssetResource asset_resources = new LLSDAssetResource();
|
||||
public LLSDAssetUploadRequest()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -26,20 +26,51 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadError
|
||||
{
|
||||
public string message = String.Empty;
|
||||
public UUID identifier = UUID.Zero;
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadResponsePricebrkDown
|
||||
{
|
||||
public int mesh_streaming;
|
||||
public int mesh_physics;
|
||||
public int mesh_instance;
|
||||
public int texture;
|
||||
public int model;
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadResponseData
|
||||
{
|
||||
public double resource_cost;
|
||||
public double model_streaming_cost;
|
||||
public double simulation_cost;
|
||||
public double physics_cost;
|
||||
public LLSDAssetUploadResponsePricebrkDown upload_price_breakdown = new LLSDAssetUploadResponsePricebrkDown();
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDAssetUploadResponse
|
||||
{
|
||||
public string uploader = String.Empty;
|
||||
public string state = String.Empty;
|
||||
|
||||
public int upload_price = 0;
|
||||
public LLSDAssetUploadResponseData data = null;
|
||||
public LLSDAssetUploadError error = null;
|
||||
public LLSDAssetUploadResponse()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDNewFileAngentInventoryVariablePriceReplyResponse
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace OpenSim.Data
|
|||
public abstract class AssetDataBase : IAssetDataPlugin
|
||||
{
|
||||
public abstract AssetBase GetAsset(UUID uuid);
|
||||
public abstract void StoreAsset(AssetBase asset);
|
||||
public abstract bool StoreAsset(AssetBase asset);
|
||||
public abstract bool[] AssetsExist(UUID[] uuids);
|
||||
|
||||
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace OpenSim.Data
|
|||
public interface IAssetDataPlugin : IPlugin
|
||||
{
|
||||
AssetBase GetAsset(UUID uuid);
|
||||
void StoreAsset(AssetBase asset);
|
||||
bool StoreAsset(AssetBase asset);
|
||||
bool[] AssetsExist(UUID[] uuids);
|
||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
void Initialise(string connect);
|
||||
|
|
|
@ -48,8 +48,6 @@ namespace OpenSim.Data
|
|||
bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
|
||||
bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
|
||||
bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result);
|
||||
bool UpdateUserPreferences(ref UserPreferences pref, ref string result);
|
||||
bool GetUserPreferences(ref UserPreferences pref, ref string result);
|
||||
bool GetUserAppData(ref UserAppData props, ref string result);
|
||||
bool SetUserAppData(UserAppData props, ref string result);
|
||||
OSDArray GetUserImageAssets(UUID avatarId);
|
||||
|
|
|
@ -50,5 +50,6 @@ namespace OpenSim.Data
|
|||
bool Store(UserAccountData data);
|
||||
bool Delete(string field, string val);
|
||||
UserAccountData[] GetUsers(UUID scopeID, string query);
|
||||
UserAccountData[] GetUsersWhere(UUID scopeID, string where);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
|
|
|
@ -154,7 +154,7 @@ namespace OpenSim.Data.MySQL
|
|||
/// </summary>
|
||||
/// <param name="asset">Asset UUID to create</param>
|
||||
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
|
||||
override public void StoreAsset(AssetBase asset)
|
||||
override public bool StoreAsset(AssetBase asset)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
|
@ -203,6 +203,43 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > 64)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?name", assetName);
|
||||
cmd.Parameters.AddWithValue("?description", assetDescription);
|
||||
cmd.Parameters.AddWithValue("?assetType", asset.Type);
|
||||
cmd.Parameters.AddWithValue("?local", asset.Local);
|
||||
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
|
||||
cmd.Parameters.AddWithValue("?create_time", now);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
|
||||
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
||||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
|
||||
asset.FullID, asset.Name, e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -45,14 +45,21 @@ namespace OpenSim.Data.MySQL
|
|||
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected string m_connectionString;
|
||||
protected object m_dbLock = new object();
|
||||
|
||||
protected MySqlFramework(string connectionString)
|
||||
{
|
||||
m_connectionString = connectionString;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// All non queries are funneled through one connection
|
||||
// to increase performance a little
|
||||
//
|
||||
protected int ExecuteNonQuery(MySqlCommand cmd)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
@ -60,7 +67,19 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
try
|
||||
{
|
||||
return cmd.ExecuteNonQuery();
|
||||
dbcon.Open();
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
try
|
||||
{
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(e.Message, e);
|
||||
m_log.Error(Environment.StackTrace.ToString());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -175,6 +175,11 @@ namespace OpenSim.Data.MySQL
|
|||
int v = Convert.ToInt32(reader[name]);
|
||||
m_Fields[name].SetValue(row, v);
|
||||
}
|
||||
else if (m_Fields[name].FieldType == typeof(uint))
|
||||
{
|
||||
uint v = Convert.ToUInt32(reader[name]);
|
||||
m_Fields[name].SetValue(row, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Fields[name].SetValue(row, reader[name]);
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
public RegionData Get(int posX, int posY, UUID scopeID)
|
||||
{
|
||||
/* fixed size regions
|
||||
string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY";
|
||||
if (scopeID != UUID.Zero)
|
||||
command += " and ScopeID = ?scopeID";
|
||||
|
@ -98,6 +99,45 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
return ret[0];
|
||||
}
|
||||
*/
|
||||
// extend database search for maximum region size area
|
||||
string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
|
||||
if (scopeID != UUID.Zero)
|
||||
command += " and ScopeID = ?scopeID";
|
||||
|
||||
int startX = posX - (int)Constants.MaximumRegionSize;
|
||||
int startY = posY - (int)Constants.MaximumRegionSize;
|
||||
int endX = posX;
|
||||
int endY = posY;
|
||||
|
||||
List<RegionData> ret;
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?startX", startX.ToString());
|
||||
cmd.Parameters.AddWithValue("?startY", startY.ToString());
|
||||
cmd.Parameters.AddWithValue("?endX", endX.ToString());
|
||||
cmd.Parameters.AddWithValue("?endY", endY.ToString());
|
||||
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
||||
|
||||
ret = RunCommand(cmd);
|
||||
}
|
||||
|
||||
if (ret.Count == 0)
|
||||
return null;
|
||||
|
||||
// find the first that contains pos
|
||||
RegionData rg = null;
|
||||
foreach (RegionData r in ret)
|
||||
{
|
||||
if (posX >= r.posX && posX < r.posX + r.sizeX
|
||||
&& posY >= r.posY && posY < r.posY + r.sizeY)
|
||||
{
|
||||
rg = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rg;
|
||||
}
|
||||
|
||||
public RegionData Get(UUID regionID, UUID scopeID)
|
||||
|
@ -121,6 +161,7 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
|
||||
{
|
||||
/* fix size regions
|
||||
string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY";
|
||||
if (scopeID != UUID.Zero)
|
||||
command += " and ScopeID = ?scopeID";
|
||||
|
@ -135,6 +176,38 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
return RunCommand(cmd);
|
||||
}
|
||||
*/
|
||||
string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
|
||||
if (scopeID != UUID.Zero)
|
||||
command += " and ScopeID = ?scopeID";
|
||||
|
||||
int qstartX = startX - (int)Constants.MaximumRegionSize;
|
||||
int qstartY = startY - (int)Constants.MaximumRegionSize;
|
||||
|
||||
List<RegionData> dbret;
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?startX", qstartX.ToString());
|
||||
cmd.Parameters.AddWithValue("?startY", qstartY.ToString());
|
||||
cmd.Parameters.AddWithValue("?endX", endX.ToString());
|
||||
cmd.Parameters.AddWithValue("?endY", endY.ToString());
|
||||
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
||||
|
||||
dbret = RunCommand(cmd);
|
||||
}
|
||||
|
||||
List<RegionData> ret = new List<RegionData>();
|
||||
|
||||
if (dbret.Count == 0)
|
||||
return ret;
|
||||
|
||||
foreach (RegionData r in dbret)
|
||||
{
|
||||
if (r.posX + r.sizeX > startX && r.posX <= endX
|
||||
&& r.posY + r.sizeX > startY && r.posY <= endY)
|
||||
ret.Add(r);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<RegionData> RunCommand(MySqlCommand cmd)
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace OpenSim.Data.MySQL
|
|||
Initialise(connectionString);
|
||||
}
|
||||
|
||||
public void Initialise(string connectionString)
|
||||
public virtual void Initialise(string connectionString)
|
||||
{
|
||||
m_connectionString = connectionString;
|
||||
|
||||
|
@ -123,7 +123,7 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
public void Dispose() {}
|
||||
|
||||
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
||||
public virtual void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
||||
{
|
||||
uint flags = obj.RootPart.GetEffectiveObjectFlags();
|
||||
|
||||
|
@ -183,10 +183,11 @@ namespace OpenSim.Data.MySQL
|
|||
"ParticleSystem, ClickAction, Material, " +
|
||||
"CollisionSound, CollisionSoundVolume, " +
|
||||
"PassTouches, " +
|
||||
"LinkNumber, MediaURL, AttachedPosX, " +
|
||||
"AttachedPosY, AttachedPosZ, KeyframeMotion, " +
|
||||
"PassCollisions, " +
|
||||
"LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " +
|
||||
"AttachedPosY, AttachedPosZ, " +
|
||||
"PhysicsShapeType, Density, GravityModifier, " +
|
||||
"Friction, Restitution, DynAttrs " +
|
||||
"Friction, Restitution, Vehicle, DynAttrs " +
|
||||
") values (" + "?UUID, " +
|
||||
"?CreationDate, ?Name, ?Text, " +
|
||||
"?Description, ?SitName, ?TouchName, " +
|
||||
|
@ -218,11 +219,11 @@ namespace OpenSim.Data.MySQL
|
|||
"?SaleType, ?ColorR, ?ColorG, " +
|
||||
"?ColorB, ?ColorA, ?ParticleSystem, " +
|
||||
"?ClickAction, ?Material, ?CollisionSound, " +
|
||||
"?CollisionSoundVolume, ?PassTouches, " +
|
||||
"?LinkNumber, ?MediaURL, ?AttachedPosX, " +
|
||||
"?AttachedPosY, ?AttachedPosZ, ?KeyframeMotion, " +
|
||||
"?CollisionSoundVolume, ?PassTouches, ?PassCollisions, " +
|
||||
"?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " +
|
||||
"?AttachedPosY, ?AttachedPosZ, " +
|
||||
"?PhysicsShapeType, ?Density, ?GravityModifier, " +
|
||||
"?Friction, ?Restitution, ?DynAttrs)";
|
||||
"?Friction, ?Restitution, ?Vehicle, ?DynAttrs)";
|
||||
|
||||
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
|
||||
|
||||
|
@ -262,7 +263,7 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
}
|
||||
|
||||
public void RemoveObject(UUID obj, UUID regionUUID)
|
||||
public virtual void RemoveObject(UUID obj, UUID regionUUID)
|
||||
{
|
||||
// m_log.DebugFormat("[REGION DB]: Deleting scene object {0} from {1} in database", obj, regionUUID);
|
||||
|
||||
|
@ -317,7 +318,8 @@ namespace OpenSim.Data.MySQL
|
|||
/// <param name="uuid">the Item UUID</param>
|
||||
private void RemoveItems(UUID uuid)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
// locked by caller
|
||||
// lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
|
@ -411,7 +413,7 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
}
|
||||
|
||||
public List<SceneObjectGroup> LoadObjects(UUID regionID)
|
||||
public virtual List<SceneObjectGroup> LoadObjects(UUID regionID)
|
||||
{
|
||||
const int ROWS_PER_QUERY = 5000;
|
||||
|
||||
|
@ -590,40 +592,53 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
public void StoreTerrain(TerrainData terrData, UUID regionID)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
Util.FireAndForget(delegate(object x)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
m_log.Info("[REGION DB]: Storing terrain");
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID";
|
||||
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
|
||||
dbcon.Open();
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID";
|
||||
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
|
||||
|
||||
int terrainDBRevision;
|
||||
Array terrainDBblob;
|
||||
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
|
||||
using (MySqlCommand cmd2 = dbcon.CreateCommand())
|
||||
{
|
||||
try
|
||||
{
|
||||
cmd2.CommandText = "insert into terrain (RegionUUID, " +
|
||||
"Revision, Heightfield) values (?RegionUUID, " +
|
||||
"?Revision, ?Heightfield)";
|
||||
|
||||
m_log.InfoFormat("{0} Storing terrain. X={1}, Y={2}, rev={3}",
|
||||
LogHeader, terrData.SizeX, terrData.SizeY, terrainDBRevision);
|
||||
int terrainDBRevision;
|
||||
Array terrainDBblob;
|
||||
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
|
||||
|
||||
cmd.CommandText = "insert into terrain (RegionUUID, Revision, Heightfield)"
|
||||
+ "values (?RegionUUID, ?Revision, ?Heightfield)";
|
||||
cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString());
|
||||
cmd2.Parameters.AddWithValue("Revision", terrainDBRevision);
|
||||
cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob);
|
||||
|
||||
cmd.Parameters.AddWithValue("Revision", terrainDBRevision);
|
||||
cmd.Parameters.AddWithValue("Heightfield", terrainDBblob);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
ExecuteNonQuery(cmd);
|
||||
ExecuteNonQuery(cmd2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Legacy region loading
|
||||
public double[,] LoadTerrain(UUID regionID)
|
||||
public virtual double[,] LoadTerrain(UUID regionID)
|
||||
{
|
||||
double[,] ret = null;
|
||||
TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
|
||||
|
@ -655,8 +670,11 @@ namespace OpenSim.Data.MySQL
|
|||
while (reader.Read())
|
||||
{
|
||||
int rev = Convert.ToInt32(reader["Revision"]);
|
||||
byte[] blob = (byte[])reader["Heightfield"];
|
||||
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
|
||||
if ((reader["Heightfield"] != DBNull.Value))
|
||||
{
|
||||
byte[] blob = (byte[])reader["Heightfield"];
|
||||
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -666,7 +684,7 @@ namespace OpenSim.Data.MySQL
|
|||
return terrData;
|
||||
}
|
||||
|
||||
public void RemoveLandObject(UUID globalID)
|
||||
public virtual void RemoveLandObject(UUID globalID)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
|
@ -685,7 +703,7 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
}
|
||||
|
||||
public void StoreLandObject(ILandObject parcel)
|
||||
public virtual void StoreLandObject(ILandObject parcel)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
|
@ -705,7 +723,8 @@ namespace OpenSim.Data.MySQL
|
|||
"UserLocationX, UserLocationY, UserLocationZ, " +
|
||||
"UserLookAtX, UserLookAtY, UserLookAtZ, " +
|
||||
"AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " +
|
||||
"MediaSize, MediaLoop, ObscureMusic, ObscureMedia) values (" +
|
||||
"MediaSize, MediaLoop, ObscureMusic, ObscureMedia, " +
|
||||
"SeeAVs, AnyAVSounds, GroupAVSounds) values (" +
|
||||
"?UUID, ?RegionUUID, " +
|
||||
"?LocalLandID, ?Bitmap, ?Name, ?Description, " +
|
||||
"?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " +
|
||||
|
@ -716,7 +735,8 @@ namespace OpenSim.Data.MySQL
|
|||
"?UserLocationX, ?UserLocationY, ?UserLocationZ, " +
|
||||
"?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " +
|
||||
"?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+
|
||||
"CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia)";
|
||||
"CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia, " +
|
||||
"?SeeAVs, ?AnyAVSounds, ?GroupAVSounds)";
|
||||
|
||||
FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID);
|
||||
|
||||
|
@ -742,7 +762,7 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
}
|
||||
|
||||
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
public virtual RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
RegionLightShareData nWP = new RegionLightShareData();
|
||||
nWP.OnSave += StoreRegionWindlightSettings;
|
||||
|
@ -840,7 +860,7 @@ namespace OpenSim.Data.MySQL
|
|||
return nWP;
|
||||
}
|
||||
|
||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
public virtual RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
{
|
||||
RegionSettings rs = null;
|
||||
|
||||
|
@ -880,7 +900,7 @@ namespace OpenSim.Data.MySQL
|
|||
return rs;
|
||||
}
|
||||
|
||||
public void StoreRegionWindlightSettings(RegionLightShareData wl)
|
||||
public virtual void StoreRegionWindlightSettings(RegionLightShareData wl)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
|
@ -983,7 +1003,7 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
}
|
||||
|
||||
public void RemoveRegionWindlightSettings(UUID regionID)
|
||||
public virtual void RemoveRegionWindlightSettings(UUID regionID)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
|
@ -1060,7 +1080,7 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
#endregion
|
||||
|
||||
public void StoreRegionSettings(RegionSettings rs)
|
||||
public virtual void StoreRegionSettings(RegionSettings rs)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
|
@ -1105,7 +1125,44 @@ namespace OpenSim.Data.MySQL
|
|||
"?TerrainImageID, " +
|
||||
"?TelehubObject, ?ParcelImageID)";
|
||||
|
||||
FillRegionSettingsCommand(cmd, rs);
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "replace into regionsettings (regionUUID, " +
|
||||
"block_terraform, block_fly, allow_damage, " +
|
||||
"restrict_pushing, allow_land_resell, " +
|
||||
"allow_land_join_divide, block_show_in_search, " +
|
||||
"agent_limit, object_bonus, maturity, " +
|
||||
"disable_scripts, disable_collisions, " +
|
||||
"disable_physics, terrain_texture_1, " +
|
||||
"terrain_texture_2, terrain_texture_3, " +
|
||||
"terrain_texture_4, elevation_1_nw, " +
|
||||
"elevation_2_nw, elevation_1_ne, " +
|
||||
"elevation_2_ne, elevation_1_se, " +
|
||||
"elevation_2_se, elevation_1_sw, " +
|
||||
"elevation_2_sw, water_height, " +
|
||||
"terrain_raise_limit, terrain_lower_limit, " +
|
||||
"use_estate_sun, fixed_sun, sun_position, " +
|
||||
"covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " +
|
||||
"sunvectorz, loaded_creation_datetime, " +
|
||||
"loaded_creation_id, map_tile_ID, block_search, casino, " +
|
||||
"TelehubObject, parcel_tile_ID) " +
|
||||
"values (?RegionUUID, ?BlockTerraform, " +
|
||||
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
|
||||
"?AllowLandResell, ?AllowLandJoinDivide, " +
|
||||
"?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
|
||||
"?Maturity, ?DisableScripts, ?DisableCollisions, " +
|
||||
"?DisablePhysics, ?TerrainTexture1, " +
|
||||
"?TerrainTexture2, ?TerrainTexture3, " +
|
||||
"?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " +
|
||||
"?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " +
|
||||
"?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " +
|
||||
"?WaterHeight, ?TerrainRaiseLimit, " +
|
||||
"?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " +
|
||||
"?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " +
|
||||
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
|
||||
"?LoadedCreationDateTime, ?LoadedCreationID, " +
|
||||
"?TerrainImageID, ?block_search, ?casino, " +
|
||||
"?TelehubObject, ?ParcelImageID)";
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
|
@ -1114,7 +1171,7 @@ namespace OpenSim.Data.MySQL
|
|||
SaveSpawnPoints(rs);
|
||||
}
|
||||
|
||||
public List<LandData> LoadLandObjects(UUID regionUUID)
|
||||
public virtual List<LandData> LoadLandObjects(UUID regionUUID)
|
||||
{
|
||||
List<LandData> landData = new List<LandData>();
|
||||
|
||||
|
@ -1296,6 +1353,7 @@ namespace OpenSim.Data.MySQL
|
|||
prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"];
|
||||
|
||||
prim.PassTouches = ((sbyte)row["PassTouches"] != 0);
|
||||
prim.PassCollisions = ((sbyte)row["PassCollisions"] != 0);
|
||||
prim.LinkNum = (int)row["LinkNumber"];
|
||||
|
||||
if (!(row["MediaURL"] is System.DBNull))
|
||||
|
@ -1334,6 +1392,15 @@ namespace OpenSim.Data.MySQL
|
|||
prim.Friction = (float)(double)row["Friction"];
|
||||
prim.Restitution = (float)(double)row["Restitution"];
|
||||
|
||||
SOPVehicle vehicle = null;
|
||||
|
||||
if (row["Vehicle"].ToString() != String.Empty)
|
||||
{
|
||||
vehicle = SOPVehicle.FromXml2(row["Vehicle"].ToString());
|
||||
if (vehicle != null)
|
||||
prim.VehicleParams = vehicle;
|
||||
}
|
||||
|
||||
return prim;
|
||||
}
|
||||
|
||||
|
@ -1344,32 +1411,40 @@ namespace OpenSim.Data.MySQL
|
|||
/// <returns></returns>
|
||||
private static TaskInventoryItem BuildItem(IDataReader row)
|
||||
{
|
||||
TaskInventoryItem taskItem = new TaskInventoryItem();
|
||||
try
|
||||
{
|
||||
TaskInventoryItem taskItem = new TaskInventoryItem();
|
||||
|
||||
taskItem.ItemID = DBGuid.FromDB(row["itemID"]);
|
||||
taskItem.ParentPartID = DBGuid.FromDB(row["primID"]);
|
||||
taskItem.AssetID = DBGuid.FromDB(row["assetID"]);
|
||||
taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]);
|
||||
taskItem.ItemID = DBGuid.FromDB(row["itemID"]);
|
||||
taskItem.ParentPartID = DBGuid.FromDB(row["primID"]);
|
||||
taskItem.AssetID = DBGuid.FromDB(row["assetID"]);
|
||||
taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]);
|
||||
|
||||
taskItem.InvType = Convert.ToInt32(row["invType"]);
|
||||
taskItem.Type = Convert.ToInt32(row["assetType"]);
|
||||
taskItem.InvType = Convert.ToInt32(row["invType"]);
|
||||
taskItem.Type = Convert.ToInt32(row["assetType"]);
|
||||
|
||||
taskItem.Name = (String)row["name"];
|
||||
taskItem.Description = (String)row["description"];
|
||||
taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
|
||||
taskItem.CreatorIdentification = (String)row["creatorID"];
|
||||
taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]);
|
||||
taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]);
|
||||
taskItem.GroupID = DBGuid.FromDB(row["groupID"]);
|
||||
taskItem.Name = (String)row["name"];
|
||||
taskItem.Description = (String)row["description"];
|
||||
taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
|
||||
taskItem.CreatorIdentification = (String)row["creatorID"];
|
||||
taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]);
|
||||
taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]);
|
||||
taskItem.GroupID = DBGuid.FromDB(row["groupID"]);
|
||||
|
||||
taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]);
|
||||
taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]);
|
||||
taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]);
|
||||
taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]);
|
||||
taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]);
|
||||
taskItem.Flags = Convert.ToUInt32(row["flags"]);
|
||||
taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]);
|
||||
taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]);
|
||||
taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]);
|
||||
taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]);
|
||||
taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]);
|
||||
taskItem.Flags = Convert.ToUInt32(row["flags"]);
|
||||
|
||||
return taskItem;
|
||||
return taskItem;
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.ErrorFormat("[MYSQL DB]: Error reading task inventory: itemID was {0}, primID was {1}", row["itemID"].ToString(), row["primID"].ToString());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static RegionSettings BuildRegionSettings(IDataReader row)
|
||||
|
@ -1427,6 +1502,9 @@ namespace OpenSim.Data.MySQL
|
|||
newSettings.ParcelImageID = DBGuid.FromDB(row["parcel_tile_ID"]);
|
||||
newSettings.TelehubObject = DBGuid.FromDB(row["TelehubObject"]);
|
||||
|
||||
newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]);
|
||||
newSettings.Casino = Convert.ToBoolean(row["casino"]);
|
||||
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
|
@ -1503,6 +1581,13 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
newData.ParcelAccessList = new List<LandAccessEntry>();
|
||||
|
||||
if (!(row["SeeAVs"] is System.DBNull))
|
||||
newData.SeeAVs = Convert.ToInt32(row["SeeAVs"]) != 0 ? true : false;
|
||||
if (!(row["AnyAVSounds"] is System.DBNull))
|
||||
newData.AnyAVSounds = Convert.ToInt32(row["AnyAVSounds"]) != 0 ? true : false;
|
||||
if (!(row["GroupAVSounds"] is System.DBNull))
|
||||
newData.GroupAVSounds = Convert.ToInt32(row["GroupAVSounds"]) != 0 ? true : false;
|
||||
|
||||
return newData;
|
||||
}
|
||||
|
||||
|
@ -1520,6 +1605,34 @@ namespace OpenSim.Data.MySQL
|
|||
return entry;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="val"></param>
|
||||
/// <returns></returns>
|
||||
private static Array SerializeTerrain(double[,] val, double[,] oldTerrain)
|
||||
{
|
||||
MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double));
|
||||
BinaryWriter bw = new BinaryWriter(str);
|
||||
|
||||
// TODO: COMPATIBILITY - Add byte-order conversions
|
||||
for (int x = 0; x < (int)Constants.RegionSize; x++)
|
||||
for (int y = 0; y < (int)Constants.RegionSize; y++)
|
||||
{
|
||||
double height = 20.0;
|
||||
if (oldTerrain != null)
|
||||
height = oldTerrain[x, y];
|
||||
if (!double.IsNaN(val[x, y]))
|
||||
height = val[x, y];
|
||||
if (height == 0.0)
|
||||
height = double.Epsilon;
|
||||
|
||||
bw.Write(height);
|
||||
}
|
||||
|
||||
return str.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill the prim command with prim values
|
||||
/// </summary>
|
||||
|
@ -1654,6 +1767,11 @@ namespace OpenSim.Data.MySQL
|
|||
else
|
||||
cmd.Parameters.AddWithValue("PassTouches", 0);
|
||||
|
||||
if (prim.PassCollisions)
|
||||
cmd.Parameters.AddWithValue("PassCollisions", 1);
|
||||
else
|
||||
cmd.Parameters.AddWithValue("PassCollisions", 0);
|
||||
|
||||
cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
|
||||
cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
|
||||
if (prim.AttachedPos != null)
|
||||
|
@ -1668,6 +1786,11 @@ namespace OpenSim.Data.MySQL
|
|||
else
|
||||
cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]);
|
||||
|
||||
if (prim.VehicleParams != null)
|
||||
cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2());
|
||||
else
|
||||
cmd.Parameters.AddWithValue("Vehicle", String.Empty);
|
||||
|
||||
if (prim.DynAttrs.CountNamespaces > 0)
|
||||
cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml());
|
||||
else
|
||||
|
@ -1756,6 +1879,8 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime);
|
||||
cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID);
|
||||
cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID);
|
||||
cmd.Parameters.AddWithValue("block_search", settings.GodBlockSearch);
|
||||
cmd.Parameters.AddWithValue("casino", settings.Casino);
|
||||
|
||||
cmd.Parameters.AddWithValue("ParcelImageID", settings.ParcelImageID);
|
||||
cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject);
|
||||
|
@ -1813,6 +1938,10 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop);
|
||||
cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic);
|
||||
cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia);
|
||||
cmd.Parameters.AddWithValue("SeeAVs", land.SeeAVs ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("AnyAVSounds", land.AnyAVSounds ? 1 : 0);
|
||||
cmd.Parameters.AddWithValue("GroupAVSounds", land.GroupAVSounds ? 1 : 0);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1919,7 +2048,7 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml());
|
||||
}
|
||||
|
||||
public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
|
||||
public virtual void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
|
@ -1963,6 +2092,37 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
}
|
||||
|
||||
public UUID[] GetObjectIDs(UUID regionID)
|
||||
{
|
||||
List<UUID> uuids = new List<UUID>();
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "select UUID from prims where RegionUUID = ?RegionUUID and SceneGroupID = UUID";
|
||||
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
|
||||
|
||||
using (IDataReader reader = ExecuteReader(cmd))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
UUID id = new UUID(reader["UUID"].ToString());
|
||||
|
||||
uuids.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return uuids.ToArray();
|
||||
}
|
||||
|
||||
private void LoadSpawnPoints(RegionSettings rs)
|
||||
{
|
||||
rs.ClearSpawnPoints();
|
||||
|
|
|
@ -46,17 +46,21 @@ namespace OpenSim.Data.MySQL
|
|||
{
|
||||
string[] words = query.Split(new char[] {' '});
|
||||
|
||||
bool valid = false;
|
||||
|
||||
for (int i = 0 ; i < words.Length ; i++)
|
||||
{
|
||||
if (words[i].Length < 3)
|
||||
{
|
||||
if (i != words.Length - 1)
|
||||
Array.Copy(words, i + 1, words, i, words.Length - i - 1);
|
||||
Array.Resize(ref words, words.Length - 1);
|
||||
}
|
||||
if (words[i].Length > 2)
|
||||
valid = true;
|
||||
// if (words[i].Length < 3)
|
||||
// {
|
||||
// if (i != words.Length - 1)
|
||||
// Array.Copy(words, i + 1, words, i, words.Length - i - 1);
|
||||
// Array.Resize(ref words, words.Length - 1);
|
||||
// }
|
||||
}
|
||||
|
||||
if (words.Length == 0)
|
||||
if ((!valid) || words.Length == 0)
|
||||
return new UserAccountData[0];
|
||||
|
||||
if (words.Length > 2)
|
||||
|
@ -66,20 +70,36 @@ namespace OpenSim.Data.MySQL
|
|||
{
|
||||
if (words.Length == 1)
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%");
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search) and active=1", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?search", words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst and LastName like ?searchLast) and active=1", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?searchFirst", words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?searchLast", words[1] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
if (scopeID != UUID.Zero)
|
||||
{
|
||||
where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")";
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
|
||||
cmd.CommandText = String.Format("select * from {0} where " + where, m_Realm);
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -631,6 +631,8 @@ namespace OpenSim.Data.MySQL
|
|||
{
|
||||
if(reader.HasRows)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": Getting data for {0}.", props.UserId);
|
||||
reader.Read();
|
||||
props.WebUrl = (string)reader["profileURL"];
|
||||
UUID.TryParse((string)reader["profileImage"], out props.ImageId);
|
||||
|
@ -646,6 +648,9 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": No data for {0}", props.UserId);
|
||||
|
||||
props.WebUrl = string.Empty;
|
||||
props.ImageId = UUID.Zero;
|
||||
props.AboutText = string.Empty;
|
||||
|
@ -891,7 +896,7 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
|
||||
#region User Preferences
|
||||
public bool GetUserPreferences(ref UserPreferences pref, ref string result)
|
||||
public OSDArray GetUserPreferences(UUID avatarId)
|
||||
{
|
||||
string query = string.Empty;
|
||||
|
||||
|
@ -908,16 +913,19 @@ namespace OpenSim.Data.MySQL
|
|||
dbcon.Open();
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?Id", pref.UserId.ToString());
|
||||
cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
|
||||
|
||||
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if(reader.HasRows)
|
||||
{
|
||||
reader.Read();
|
||||
bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
|
||||
bool.TryParse((string)reader["visible"], out pref.Visible);
|
||||
pref.EMail = (string)reader["email"];
|
||||
OSDMap record = new OSDMap();
|
||||
|
||||
record.Add("imviaemail",OSD.FromString((string)reader["imviaemail"]));
|
||||
record.Add("visible",OSD.FromString((string)reader["visible"]));
|
||||
record.Add("email",OSD.FromString((string)reader["email"]));
|
||||
data.Add(record);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -930,8 +938,8 @@ namespace OpenSim.Data.MySQL
|
|||
using (MySqlCommand put = new MySqlCommand(query, dbcon))
|
||||
{
|
||||
|
||||
put.Parameters.AddWithValue("?Email", pref.EMail);
|
||||
put.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
|
||||
// put.Parameters.AddWithValue("?Email", pref.EMail);
|
||||
// put.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
|
||||
|
||||
put.ExecuteNonQuery();
|
||||
}
|
||||
|
@ -944,17 +952,15 @@ namespace OpenSim.Data.MySQL
|
|||
{
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": Get preferences exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return data;
|
||||
}
|
||||
|
||||
public bool UpdateUserPreferences(ref UserPreferences pref, ref string result)
|
||||
public bool UpdateUserPreferences(bool emailIm, bool visible, UUID avatarId )
|
||||
{
|
||||
string query = string.Empty;
|
||||
|
||||
query += "UPDATE usersettings SET ";
|
||||
query += "UPDATE userpsettings SET ";
|
||||
query += "imviaemail=?ImViaEmail, ";
|
||||
query += "visible=?Visible, ";
|
||||
query += "email=?EMail ";
|
||||
|
@ -980,7 +986,6 @@ namespace OpenSim.Data.MySQL
|
|||
{
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UserPreferencesUpdate exception {0} {1}", e.Message, e.InnerException);
|
||||
result = e.Message;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -717,7 +717,7 @@ ALTER TABLE regionsettings ADD COLUMN loaded_creation_datetime int unsigned NOT
|
|||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 32
|
||||
:VERSION 32 #---------------------
|
||||
|
||||
BEGIN;
|
||||
CREATE TABLE `regionwindlight` (
|
||||
|
@ -939,6 +939,7 @@ ALTER TABLE prims ADD COLUMN AttachedPosY double default 0;
|
|||
ALTER TABLE prims ADD COLUMN AttachedPosZ double default 0;
|
||||
ALTER TABLE primshapes ADD COLUMN LastAttachPoint int(4) not null default '0';
|
||||
COMMIT;
|
||||
<<<<<<< HEAD
|
||||
|
||||
:VERSION 50 #---- Change LandFlags to unsigned
|
||||
|
||||
|
@ -948,3 +949,5 @@ ALTER TABLE land CHANGE COLUMN LandFlags LandFlags int unsigned default null;
|
|||
|
||||
COMMIT;
|
||||
|
||||
=======
|
||||
>>>>>>> avn/ubitvar
|
||||
|
|
|
@ -81,6 +81,7 @@ CREATE TABLE IF NOT EXISTS `userdata` (
|
|||
|
||||
commit;
|
||||
|
||||
<<<<<<< HEAD
|
||||
:VERSION 3 # -------------------------------
|
||||
begin;
|
||||
CREATE TABLE IF NOT EXISTS `usersettings` (
|
||||
|
@ -96,3 +97,5 @@ commit;
|
|||
begin;
|
||||
ALTER TABLE userpicks ADD COLUMN gatekeeper varchar(255);
|
||||
commit;
|
||||
=======
|
||||
>>>>>>> avn/ubitvar
|
||||
|
|
|
@ -140,7 +140,8 @@ namespace OpenSim.Data.Null
|
|||
{
|
||||
foreach (RegionData r in m_regionData.Values)
|
||||
{
|
||||
if (r.posX == posX && r.posY == posY)
|
||||
if (posX >= r.posX && posX < r.posX + r.sizeX
|
||||
&& posY >= r.posY && posY < r.posY + r.sizeY)
|
||||
ret.Add(r);
|
||||
}
|
||||
}
|
||||
|
@ -176,8 +177,9 @@ namespace OpenSim.Data.Null
|
|||
{
|
||||
foreach (RegionData r in m_regionData.Values)
|
||||
{
|
||||
if (r.posX >= startX && r.posX <= endX && r.posY >= startY && r.posY <= endY)
|
||||
ret.Add(r);
|
||||
if (r.posX + r.sizeX > startX && r.posX <= endX
|
||||
&& r.posY + r.sizeX > startY && r.posY <= endY)
|
||||
ret.Add(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -184,6 +184,11 @@ namespace OpenSim.Data.Null
|
|||
{
|
||||
}
|
||||
|
||||
public UUID[] GetObjectIDs(UUID regionID)
|
||||
{
|
||||
return new UUID[0];
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string value)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -193,5 +193,10 @@ namespace OpenSim.Data.Null
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ namespace OpenSim.Data.PGSQL
|
|||
/// Create asset in m_database
|
||||
/// </summary>
|
||||
/// <param name="asset">the asset</param>
|
||||
override public void StoreAsset(AssetBase asset)
|
||||
override public bool StoreAsset(AssetBase asset)
|
||||
{
|
||||
|
||||
string sql =
|
||||
|
@ -208,6 +208,7 @@ namespace OpenSim.Data.PGSQL
|
|||
m_log.Error("[ASSET DB]: Error storing item :" + e.Message + " sql "+sql);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -325,5 +325,10 @@ namespace OpenSim.Data.PGSQL
|
|||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ CREATE TABLE userdata (
|
|||
|
||||
commit;
|
||||
|
||||
<<<<<<< HEAD
|
||||
:VERSION 3 # -------------------------------
|
||||
begin;
|
||||
CREATE TABLE usersettings (
|
||||
|
@ -153,3 +154,5 @@ BEGIN;
|
|||
ALTER TABLE usersettings ALTER COLUMN imviaemail SET DATA TYPE boolean USING CASE WHEN false THEN false ELSE true END;
|
||||
|
||||
COMMIT;
|
||||
=======
|
||||
>>>>>>> avn/ubitvar
|
||||
|
|
|
@ -88,15 +88,3 @@ CREATE TABLE IF NOT EXISTS userdata (
|
|||
|
||||
commit;
|
||||
|
||||
|
||||
:VERSION 3 # -------------------------------
|
||||
|
||||
begin;
|
||||
CREATE TABLE IF NOT EXISTS usersettings (
|
||||
useruuid char(36) NOT NULL,
|
||||
imviaemail binary(1) NOT NULL,
|
||||
visible binary(1) NOT NULL,
|
||||
email varchar(254) NOT NULL,
|
||||
PRIMARY KEY (useruuid)
|
||||
)
|
||||
commit;
|
|
@ -131,7 +131,7 @@ namespace OpenSim.Data.SQLite
|
|||
/// Create an asset
|
||||
/// </summary>
|
||||
/// <param name="asset">Asset Base</param>
|
||||
override public void StoreAsset(AssetBase asset)
|
||||
override public bool StoreAsset(AssetBase asset)
|
||||
{
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
|
@ -171,6 +171,7 @@ namespace OpenSim.Data.SQLite
|
|||
cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -191,6 +192,7 @@ namespace OpenSim.Data.SQLite
|
|||
cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2013,6 +2013,7 @@ namespace OpenSim.Data.SQLite
|
|||
return entry;
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -2944,6 +2945,11 @@ namespace OpenSim.Data.SQLite
|
|||
}
|
||||
}
|
||||
|
||||
public UUID[] GetObjectIDs(UUID regionID)
|
||||
{
|
||||
return new UUID[0];
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string value)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -82,5 +82,10 @@ namespace OpenSim.Data.SQLite
|
|||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -741,6 +741,7 @@ namespace OpenSim.Data.SQLite
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
public bool UpdateUserPreferences(ref UserPreferences pref, ref string result)
|
||||
{
|
||||
string query = string.Empty;
|
||||
|
@ -825,6 +826,7 @@ namespace OpenSim.Data.SQLite
|
|||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
public bool GetUserAppData(ref UserAppData props, ref string result)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* 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 OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public delegate bool AnimationSetValidator(UUID animID);
|
||||
|
||||
public class AnimationSet
|
||||
{
|
||||
private bool m_parseError = false;
|
||||
|
||||
public const uint createBasePermitions = (uint)(PermissionMask.All); // no export ?
|
||||
public const uint createNextPermitions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
|
||||
|
||||
public const uint allowedBasePermitions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
|
||||
public const uint allowedNextPermitions = 0;
|
||||
|
||||
public static void setCreateItemPermitions(InventoryItemBase it)
|
||||
{
|
||||
if (it == null)
|
||||
return;
|
||||
|
||||
it.BasePermissions = createBasePermitions;
|
||||
it.CurrentPermissions = createBasePermitions;
|
||||
// it.GroupPermissions &= allowedPermitions;
|
||||
it.NextPermissions = createNextPermitions;
|
||||
// it.EveryOnePermissions &= allowedPermitions;
|
||||
it.GroupPermissions = 0;
|
||||
it.EveryOnePermissions = 0;
|
||||
}
|
||||
|
||||
public static void enforceItemPermitions(InventoryItemBase it, bool IsCreator)
|
||||
{
|
||||
if (it == null)
|
||||
return;
|
||||
|
||||
uint bp;
|
||||
uint np;
|
||||
|
||||
if (IsCreator)
|
||||
{
|
||||
bp = createBasePermitions;
|
||||
np = createNextPermitions;
|
||||
}
|
||||
else
|
||||
{
|
||||
bp = allowedBasePermitions;
|
||||
np = allowedNextPermitions;
|
||||
}
|
||||
|
||||
it.BasePermissions &= bp;
|
||||
it.CurrentPermissions &= bp;
|
||||
// it.GroupPermissions &= allowedPermitions;
|
||||
it.NextPermissions &= np;
|
||||
// it.EveryOnePermissions &= allowedPermitions;
|
||||
it.GroupPermissions = 0;
|
||||
it.EveryOnePermissions = 0;
|
||||
}
|
||||
|
||||
public int AnimationCount { get; private set; }
|
||||
private Dictionary<string, KeyValuePair<string, UUID>> m_animations = new Dictionary<string, KeyValuePair<string, UUID>>();
|
||||
|
||||
public UUID GetAnimation(string index)
|
||||
{
|
||||
KeyValuePair<string, UUID> val;
|
||||
if (m_animations.TryGetValue(index, out val))
|
||||
return val.Value;
|
||||
|
||||
return UUID.Zero;
|
||||
}
|
||||
|
||||
public string GetAnimationName(string index)
|
||||
{
|
||||
KeyValuePair<string, UUID> val;
|
||||
if (m_animations.TryGetValue(index, out val))
|
||||
return val.Key;
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
public void SetAnimation(string index, string name, UUID anim)
|
||||
{
|
||||
if (anim == UUID.Zero)
|
||||
{
|
||||
m_animations.Remove(index);
|
||||
return;
|
||||
}
|
||||
|
||||
m_animations[index] = new KeyValuePair<string, UUID>(name, anim);
|
||||
}
|
||||
|
||||
public AnimationSet(Byte[] data)
|
||||
{
|
||||
string assetData = System.Text.Encoding.ASCII.GetString(data);
|
||||
Console.WriteLine("--------------------");
|
||||
Console.WriteLine("AnimationSet length {0} bytes", assetData.Length);
|
||||
Console.WriteLine(assetData);
|
||||
Console.WriteLine("--------------------");
|
||||
}
|
||||
|
||||
public Byte[] ToBytes()
|
||||
{
|
||||
// If there was an error parsing the input, we give back an
|
||||
// empty set rather than the original data.
|
||||
if (m_parseError)
|
||||
{
|
||||
string dummy = "version 1\ncount 0\n";
|
||||
return System.Text.Encoding.ASCII.GetBytes(dummy);
|
||||
}
|
||||
|
||||
string assetData = String.Format("version 1\ncount {0}\n", m_animations.Count);
|
||||
foreach (KeyValuePair<string, KeyValuePair<string, UUID>> kvp in m_animations)
|
||||
assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key);
|
||||
return System.Text.Encoding.ASCII.GetBytes(assetData);
|
||||
}
|
||||
|
||||
public bool Validate(AnimationSetValidator val)
|
||||
{
|
||||
if (m_parseError)
|
||||
return false;
|
||||
|
||||
List<string> badAnims = new List<string>();
|
||||
|
||||
bool allOk = true;
|
||||
foreach (KeyValuePair<string, KeyValuePair<string, UUID>> kvp in m_animations)
|
||||
{
|
||||
if (!val(kvp.Value.Value))
|
||||
{
|
||||
allOk = false;
|
||||
badAnims.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string idx in badAnims)
|
||||
m_animations.Remove(idx);
|
||||
|
||||
return allOk;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -63,6 +63,8 @@ namespace OpenSim.Framework
|
|||
/// </summary>
|
||||
private AssetMetadata m_metadata;
|
||||
|
||||
private int m_uploadAttempts;
|
||||
|
||||
// This is needed for .NET serialization!!!
|
||||
// Do NOT "Optimize" away!
|
||||
public AssetBase()
|
||||
|
@ -148,7 +150,12 @@ namespace OpenSim.Framework
|
|||
Type == (sbyte)AssetType.Folder ||
|
||||
Type == (sbyte)AssetType.ImageJPEG ||
|
||||
Type == (sbyte)AssetType.ImageTGA ||
|
||||
<<<<<<< HEAD
|
||||
Type == (sbyte)AssetType.LSLBytecode);
|
||||
=======
|
||||
Type == (sbyte)AssetType.Mesh ||
|
||||
Type == (sbyte) AssetType.LSLBytecode);
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,6 +204,12 @@ namespace OpenSim.Framework
|
|||
set { m_metadata.Type = value; }
|
||||
}
|
||||
|
||||
public int UploadAttempts
|
||||
{
|
||||
get { return m_uploadAttempts; }
|
||||
set { m_uploadAttempts = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this a region only asset, or does this exist on the asset server also
|
||||
/// </summary>
|
||||
|
|
|
@ -53,7 +53,11 @@ namespace OpenSim.Framework
|
|||
// should be only used as initial default value ( V1 viewers )
|
||||
public readonly static int VISUALPARAM_COUNT = 218;
|
||||
|
||||
public readonly static int TEXTURE_COUNT = 21;
|
||||
// public readonly static int TEXTURE_COUNT = 21
|
||||
// 21 bad, make it be updated as libovm gets update
|
||||
// also keeping in sync with it
|
||||
public readonly static int TEXTURE_COUNT = Primitive.TextureEntry.MAX_FACES;
|
||||
|
||||
public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
|
||||
|
||||
protected int m_serial = 0;
|
||||
|
@ -179,11 +183,16 @@ namespace OpenSim.Framework
|
|||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||
}
|
||||
|
||||
public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true)
|
||||
public AvatarAppearance(AvatarAppearance appearance): this(appearance, true,true)
|
||||
{
|
||||
}
|
||||
|
||||
public AvatarAppearance(AvatarAppearance appearance, bool copyWearables)
|
||||
: this(appearance, copyWearables, true)
|
||||
{
|
||||
}
|
||||
|
||||
public AvatarAppearance(AvatarAppearance appearance, bool copyWearables, bool copyBaked)
|
||||
{
|
||||
// m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
|
||||
|
||||
|
@ -217,6 +226,10 @@ namespace OpenSim.Framework
|
|||
{
|
||||
byte[] tbytes = appearance.Texture.GetBytes();
|
||||
m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
|
||||
if (copyBaked && appearance.m_cacheitems != null)
|
||||
m_cacheitems = (WearableCacheItem[])appearance.m_cacheitems.Clone();
|
||||
else
|
||||
m_cacheitems = null;
|
||||
}
|
||||
|
||||
m_visualparams = null;
|
||||
|
@ -458,7 +471,10 @@ namespace OpenSim.Framework
|
|||
// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
|
||||
// DEBUG OFF
|
||||
m_wearables[wearableId].Clear();
|
||||
for (int i = 0; i < wearable.Count; i++)
|
||||
int count = wearable.Count;
|
||||
if (count > AvatarWearable.MAX_WEARABLES)
|
||||
count = AvatarWearable.MAX_WEARABLES;
|
||||
for (int i = 0; i < count; i++)
|
||||
m_wearables[wearableId].Add(wearable[i].ItemID, wearable[i].AssetID);
|
||||
}
|
||||
|
||||
|
@ -722,6 +738,13 @@ namespace OpenSim.Framework
|
|||
}
|
||||
data["textures"] = textures;
|
||||
|
||||
if (m_cacheitems != null)
|
||||
{
|
||||
OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems);
|
||||
if (baked != null)
|
||||
data["bakedcache"] = baked;
|
||||
}
|
||||
|
||||
// Visual Parameters
|
||||
OSDBinary visualparams = new OSDBinary(m_visualparams);
|
||||
data["visualparams"] = visualparams;
|
||||
|
@ -757,7 +780,12 @@ namespace OpenSim.Framework
|
|||
if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
|
||||
{
|
||||
OSDArray wears = (OSDArray)(data["wearables"]);
|
||||
for (int i = 0; i < wears.Count; i++)
|
||||
|
||||
int count = wears.Count;
|
||||
if (count > AvatarWearable.MAX_WEARABLES)
|
||||
count = AvatarWearable.MAX_WEARABLES;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
m_wearables[i] = new AvatarWearable((OSDArray)wears[i]);
|
||||
}
|
||||
else
|
||||
|
@ -783,6 +811,12 @@ namespace OpenSim.Framework
|
|||
m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures");
|
||||
}
|
||||
|
||||
if ((data != null) && (data["bakedcache"] != null) && (data["bakedcache"]).Type == OSDType.Array)
|
||||
{
|
||||
OSDArray bakedOSDArray = (OSDArray)(data["bakedcache"]);
|
||||
m_cacheitems = WearableCacheItem.BakedFromOSD(bakedOSDArray);
|
||||
}
|
||||
|
||||
// Visual Parameters
|
||||
SetDefaultParams();
|
||||
if ((data != null) && (data["visualparams"] != null))
|
||||
|
@ -1632,7 +1666,12 @@ namespace OpenSim.Framework
|
|||
BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247,
|
||||
BREAST_PHYSICS_LEFTRIGHT_SPRING= 248,
|
||||
BREAST_PHYSICS_LEFTRIGHT_GAIN = 249,
|
||||
BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250
|
||||
BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250,
|
||||
|
||||
// Ubit: 07/96/2013 new parameters
|
||||
_APPEARANCEMESSAGE_VERSION = 251, //ID 11000
|
||||
|
||||
SHAPE_HOVER = 252, //ID 11001
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -62,10 +62,16 @@ namespace OpenSim.Framework
|
|||
public static readonly int UNDERSHIRT = 10;
|
||||
public static readonly int UNDERPANTS = 11;
|
||||
public static readonly int SKIRT = 12;
|
||||
|
||||
public static readonly int MAX_BASICWEARABLES = 13;
|
||||
|
||||
public static readonly int ALPHA = 13;
|
||||
public static readonly int TATTOO = 14;
|
||||
|
||||
public static readonly int MAX_WEARABLES = 15;
|
||||
// public static readonly int MAX_WEARABLES = 15;
|
||||
public static readonly int PHYSICS = 15;
|
||||
public static int MAX_WEARABLES = 16;
|
||||
|
||||
|
||||
public static readonly UUID DEFAULT_BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9");
|
||||
public static readonly UUID DEFAULT_BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
|
||||
|
@ -219,7 +225,7 @@ namespace OpenSim.Framework
|
|||
{
|
||||
get
|
||||
{
|
||||
AvatarWearable[] defaultWearables = new AvatarWearable[MAX_WEARABLES]; //should be 15 of these
|
||||
AvatarWearable[] defaultWearables = new AvatarWearable[MAX_WEARABLES];
|
||||
for (int i = 0; i < MAX_WEARABLES; i++)
|
||||
{
|
||||
defaultWearables[i] = new AvatarWearable();
|
||||
|
@ -243,8 +249,11 @@ namespace OpenSim.Framework
|
|||
// // Alpha
|
||||
// defaultWearables[ALPHA].Add(DEFAULT_ALPHA_ITEM, DEFAULT_ALPHA_ASSET);
|
||||
|
||||
// // Tattoo
|
||||
// defaultWearables[TATTOO].Add(DEFAULT_TATTOO_ITEM, DEFAULT_TATTOO_ASSET);
|
||||
// // Tattoo
|
||||
// defaultWearables[TATTOO].Add(DEFAULT_TATTOO_ITEM, DEFAULT_TATTOO_ASSET);
|
||||
|
||||
// // Physics
|
||||
// defaultWearables[PHYSICS].Add(DEFAULT_TATTOO_ITEM, DEFAULT_TATTOO_ASSET);
|
||||
|
||||
return defaultWearables;
|
||||
}
|
||||
|
|
|
@ -76,10 +76,9 @@ namespace OpenSim.Framework
|
|||
{
|
||||
lock (m_queueSync)
|
||||
{
|
||||
bool success = true;
|
||||
while (m_queue.Count < 1 && m_pqueue.Count < 1 && success)
|
||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
{
|
||||
success = Monitor.Wait(m_queueSync, msTimeout);
|
||||
Monitor.Wait(m_queueSync, msTimeout);
|
||||
}
|
||||
|
||||
if (m_pqueue.Count > 0)
|
||||
|
|
|
@ -94,6 +94,7 @@ namespace OpenSim.Framework
|
|||
// This probably shouldn't be here
|
||||
public byte[] Throttles;
|
||||
|
||||
public Dictionary<ulong, string> ChildrenCapSeeds = null;
|
||||
|
||||
public OSDMap Pack()
|
||||
{
|
||||
|
@ -119,6 +120,19 @@ namespace OpenSim.Framework
|
|||
if ((Throttles != null) && (Throttles.Length > 0))
|
||||
args["throttles"] = OSD.FromBinary(Throttles);
|
||||
|
||||
if (ChildrenCapSeeds != null && ChildrenCapSeeds.Count > 0)
|
||||
{
|
||||
OSDArray childrenSeeds = new OSDArray(ChildrenCapSeeds.Count);
|
||||
foreach (KeyValuePair<ulong, string> kvp in ChildrenCapSeeds)
|
||||
{
|
||||
OSDMap pair = new OSDMap();
|
||||
pair["handle"] = OSD.FromString(kvp.Key.ToString());
|
||||
pair["seed"] = OSD.FromString(kvp.Value);
|
||||
childrenSeeds.Add(pair);
|
||||
}
|
||||
args["children_seeds"] = childrenSeeds;
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
|
@ -165,6 +179,30 @@ namespace OpenSim.Framework
|
|||
|
||||
if (args["throttles"] != null)
|
||||
Throttles = args["throttles"].AsBinary();
|
||||
|
||||
if (args.ContainsKey("children_seeds") && (args["children_seeds"] != null) &&
|
||||
(args["children_seeds"].Type == OSDType.Array))
|
||||
{
|
||||
OSDArray childrenSeeds = (OSDArray)(args["children_seeds"]);
|
||||
ChildrenCapSeeds = new Dictionary<ulong, string>();
|
||||
foreach (OSD o in childrenSeeds)
|
||||
{
|
||||
if (o.Type == OSDType.Map)
|
||||
{
|
||||
ulong handle = 0;
|
||||
string seed = "";
|
||||
OSDMap pair = (OSDMap)o;
|
||||
if (pair["handle"] != null)
|
||||
if (!UInt64.TryParse(pair["handle"].AsString(), out handle))
|
||||
continue;
|
||||
if (pair["seed"] != null)
|
||||
seed = pair["seed"].AsString();
|
||||
if (!ChildrenCapSeeds.ContainsKey(handle))
|
||||
ChildrenCapSeeds.Add(handle, seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -317,9 +355,11 @@ namespace OpenSim.Framework
|
|||
public UUID ActiveGroupID;
|
||||
|
||||
public AgentGroupData[] Groups;
|
||||
public Dictionary<ulong, string> ChildrenCapSeeds = null;
|
||||
public Animation[] Anims;
|
||||
public Animation DefaultAnim = null;
|
||||
public Animation AnimState = null;
|
||||
public Byte MotionState = 0;
|
||||
|
||||
public UUID GranterID;
|
||||
public UUID ParentPart;
|
||||
|
@ -349,6 +389,8 @@ namespace OpenSim.Framework
|
|||
public List<ISceneObject> AttachmentObjects;
|
||||
public List<string> AttachmentObjectStates;
|
||||
|
||||
public Dictionary<string, UUID> MovementAnimationOverRides = new Dictionary<string, UUID>();
|
||||
|
||||
public virtual OSDMap Pack()
|
||||
{
|
||||
// m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
||||
|
@ -399,6 +441,19 @@ namespace OpenSim.Framework
|
|||
args["groups"] = groups;
|
||||
}
|
||||
|
||||
if (ChildrenCapSeeds != null && ChildrenCapSeeds.Count > 0)
|
||||
{
|
||||
OSDArray childrenSeeds = new OSDArray(ChildrenCapSeeds.Count);
|
||||
foreach (KeyValuePair<ulong, string> kvp in ChildrenCapSeeds)
|
||||
{
|
||||
OSDMap pair = new OSDMap();
|
||||
pair["handle"] = OSD.FromString(kvp.Key.ToString());
|
||||
pair["seed"] = OSD.FromString(kvp.Value);
|
||||
childrenSeeds.Add(pair);
|
||||
}
|
||||
args["children_seeds"] = childrenSeeds;
|
||||
}
|
||||
|
||||
if ((Anims != null) && (Anims.Length > 0))
|
||||
{
|
||||
OSDArray anims = new OSDArray(Anims.Length);
|
||||
|
@ -417,6 +472,26 @@ namespace OpenSim.Framework
|
|||
args["animation_state"] = AnimState.PackUpdateMessage();
|
||||
}
|
||||
|
||||
if (MovementAnimationOverRides.Count > 0)
|
||||
{
|
||||
OSDArray AOs = new OSDArray(MovementAnimationOverRides.Count);
|
||||
{
|
||||
foreach (KeyValuePair<string, UUID> kvp in MovementAnimationOverRides)
|
||||
{
|
||||
OSDMap ao = new OSDMap(2);
|
||||
ao["state"] = OSD.FromString(kvp.Key);
|
||||
ao["uuid"] = OSD.FromUUID(kvp.Value);
|
||||
AOs.Add(ao);
|
||||
}
|
||||
}
|
||||
args["movementAO"] = AOs;
|
||||
}
|
||||
|
||||
if (MotionState != 0)
|
||||
{
|
||||
args["motion_state"] = OSD.FromInteger(MotionState);
|
||||
}
|
||||
|
||||
if (Appearance != null)
|
||||
args["packed_appearance"] = Appearance.Pack();
|
||||
|
||||
|
@ -431,6 +506,8 @@ namespace OpenSim.Framework
|
|||
// The code to pack textures, visuals, wearables and attachments
|
||||
// should be removed; packed appearance contains the full appearance
|
||||
// This is retained for backward compatibility only
|
||||
|
||||
/* then lets remove
|
||||
if (Appearance.Texture != null)
|
||||
{
|
||||
byte[] rawtextures = Appearance.Texture.GetBytes();
|
||||
|
@ -459,7 +536,7 @@ namespace OpenSim.Framework
|
|||
args["attachments"] = attachs;
|
||||
}
|
||||
// End of code to remove
|
||||
|
||||
*/
|
||||
if ((Controllers != null) && (Controllers.Length > 0))
|
||||
{
|
||||
OSDArray controls = new OSDArray(Controllers.Length);
|
||||
|
@ -600,6 +677,29 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
|
||||
if (args.ContainsKey("children_seeds") && (args["children_seeds"] != null) &&
|
||||
(args["children_seeds"].Type == OSDType.Array))
|
||||
{
|
||||
OSDArray childrenSeeds = (OSDArray)(args["children_seeds"]);
|
||||
ChildrenCapSeeds = new Dictionary<ulong, string>();
|
||||
foreach (OSD o in childrenSeeds)
|
||||
{
|
||||
if (o.Type == OSDType.Map)
|
||||
{
|
||||
ulong handle = 0;
|
||||
string seed = "";
|
||||
OSDMap pair = (OSDMap)o;
|
||||
if (pair["handle"] != null)
|
||||
if (!UInt64.TryParse(pair["handle"].AsString(), out handle))
|
||||
continue;
|
||||
if (pair["seed"] != null)
|
||||
seed = pair["seed"].AsString();
|
||||
if (!ChildrenCapSeeds.ContainsKey(handle))
|
||||
ChildrenCapSeeds.Add(handle, seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((args["animations"] != null) && (args["animations"]).Type == OSDType.Array)
|
||||
{
|
||||
OSDArray anims = (OSDArray)(args["animations"]);
|
||||
|
@ -638,6 +738,28 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
|
||||
MovementAnimationOverRides.Clear();
|
||||
|
||||
if (args["movementAO"] != null && args["movementAO"].Type == OSDType.Array)
|
||||
{
|
||||
OSDArray AOs = (OSDArray)(args["movementAO"]);
|
||||
int count = AOs.Count;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
OSDMap ao = (OSDMap)AOs[i];
|
||||
if (ao["state"] != null && ao["uuid"] != null)
|
||||
{
|
||||
string state = ao["state"].AsString();
|
||||
UUID id = ao["uuid"].AsUUID();
|
||||
MovementAnimationOverRides[state] = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (args.ContainsKey("motion_state"))
|
||||
MotionState = (byte)args["motion_state"].AsInteger();
|
||||
|
||||
//if ((args["agent_textures"] != null) && (args["agent_textures"]).Type == OSDType.Array)
|
||||
//{
|
||||
// OSDArray textures = (OSDArray)(args["agent_textures"]);
|
||||
|
@ -647,53 +769,71 @@ namespace OpenSim.Framework
|
|||
// AgentTextures[i++] = o.AsUUID();
|
||||
//}
|
||||
|
||||
Appearance = new AvatarAppearance();
|
||||
|
||||
// The code to unpack textures, visuals, wearables and attachments
|
||||
// should be removed; packed appearance contains the full appearance
|
||||
// This is retained for backward compatibility only
|
||||
if (args["texture_entry"] != null)
|
||||
// packed_appearence should contain all appearance information
|
||||
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
|
||||
{
|
||||
byte[] rawtextures = args["texture_entry"].AsBinary();
|
||||
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length);
|
||||
Appearance.SetTextureEntries(textures);
|
||||
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance");
|
||||
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
|
||||
}
|
||||
|
||||
if (args["visual_params"] != null)
|
||||
Appearance.SetVisualParams(args["visual_params"].AsBinary());
|
||||
|
||||
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
|
||||
else
|
||||
{
|
||||
OSDArray wears = (OSDArray)(args["wearables"]);
|
||||
for (int i = 0; i < wears.Count / 2; i++)
|
||||
// if missing try the old pack method
|
||||
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance, checking old method");
|
||||
|
||||
Appearance = new AvatarAppearance();
|
||||
|
||||
// The code to unpack textures, visuals, wearables and attachments
|
||||
// should be removed; packed appearance contains the full appearance
|
||||
// This is retained for backward compatibility only
|
||||
if (args["texture_entry"] != null)
|
||||
{
|
||||
AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]);
|
||||
Appearance.SetWearable(i,awear);
|
||||
byte[] rawtextures = args["texture_entry"].AsBinary();
|
||||
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures, 0, rawtextures.Length);
|
||||
Appearance.SetTextureEntries(textures);
|
||||
}
|
||||
}
|
||||
|
||||
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
|
||||
{
|
||||
OSDArray attachs = (OSDArray)(args["attachments"]);
|
||||
foreach (OSD o in attachs)
|
||||
if (args["visual_params"] != null)
|
||||
Appearance.SetVisualParams(args["visual_params"].AsBinary());
|
||||
|
||||
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
|
||||
{
|
||||
if (o.Type == OSDType.Map)
|
||||
OSDArray wears = (OSDArray)(args["wearables"]);
|
||||
|
||||
int count = wears.Count;
|
||||
if (count > AvatarWearable.MAX_WEARABLES)
|
||||
count = AvatarWearable.MAX_WEARABLES;
|
||||
|
||||
for (int i = 0; i < count / 2; i++)
|
||||
{
|
||||
// We know all of these must end up as attachments so we
|
||||
// append rather than replace to ensure multiple attachments
|
||||
// per point continues to work
|
||||
// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID);
|
||||
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
|
||||
AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]);
|
||||
Appearance.SetWearable(i, awear);
|
||||
}
|
||||
}
|
||||
}
|
||||
// end of code to remove
|
||||
|
||||
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
|
||||
{
|
||||
OSDArray attachs = (OSDArray)(args["attachments"]);
|
||||
foreach (OSD o in attachs)
|
||||
{
|
||||
if (o.Type == OSDType.Map)
|
||||
{
|
||||
// We know all of these must end up as attachments so we
|
||||
// append rather than replace to ensure multiple attachments
|
||||
// per point continues to work
|
||||
// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID);
|
||||
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
|
||||
}
|
||||
}
|
||||
}
|
||||
// end of code to remove
|
||||
}
|
||||
/* moved above
|
||||
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
|
||||
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
|
||||
else
|
||||
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
|
||||
|
||||
*/
|
||||
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
|
||||
{
|
||||
OSDArray controls = (OSDArray)(args["controllers"]);
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace OpenSim.Framework
|
|||
public Vector3 velVector = Vector3.Zero;
|
||||
public string nameStr = String.Empty;
|
||||
public int colliderType = 0;
|
||||
public int linkNumber;
|
||||
}
|
||||
|
||||
public class ColliderArgs : EventArgs
|
||||
|
|
|
@ -389,9 +389,32 @@ namespace OpenSim.Framework.Communications
|
|||
}
|
||||
}
|
||||
|
||||
if (_response != null)
|
||||
_response.Close();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
using (Stream src = _response.GetResponseStream())
|
||||
{
|
||||
int length = src.Read(_readbuf, 0, BufferSize);
|
||||
while (length > 0)
|
||||
{
|
||||
_resource.Write(_readbuf, 0, length);
|
||||
length = src.Read(_readbuf, 0, BufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO! Implement timeout, without killing the server
|
||||
// this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
|
||||
//ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
|
||||
|
||||
// _allDone.WaitOne();
|
||||
if (_response != null)
|
||||
_response.Close();
|
||||
>>>>>>> avn/ubitvar
|
||||
if (_asyncException != null)
|
||||
throw _asyncException;
|
||||
|
||||
|
@ -413,7 +436,7 @@ namespace OpenSim.Framework.Communications
|
|||
_request = (HttpWebRequest) WebRequest.Create(buildUri());
|
||||
_request.KeepAlive = false;
|
||||
_request.ContentType = "application/xml";
|
||||
_request.Timeout = 900000;
|
||||
_request.Timeout = 30000;
|
||||
_request.Method = RequestMethod;
|
||||
_asyncException = null;
|
||||
_request.ContentLength = src.Length;
|
||||
|
@ -421,6 +444,7 @@ namespace OpenSim.Framework.Communications
|
|||
auth.AddAuthorization(_request.Headers);
|
||||
|
||||
src.Seek(0, SeekOrigin.Begin);
|
||||
<<<<<<< HEAD
|
||||
|
||||
int reqnum = WebUtil.RequestNumber++;
|
||||
if (WebUtil.DebugLevel >= 3)
|
||||
|
@ -433,9 +457,22 @@ namespace OpenSim.Framework.Communications
|
|||
byte[] buf = new byte[1024];
|
||||
int length = src.Read(buf, 0, 1024);
|
||||
while (length > 0)
|
||||
=======
|
||||
m_log.Info("[REST]: Seek is ok");
|
||||
|
||||
using (Stream dst = _request.GetRequestStream())
|
||||
>>>>>>> avn/ubitvar
|
||||
{
|
||||
dst.Write(buf, 0, length);
|
||||
length = src.Read(buf, 0, 1024);
|
||||
m_log.Info("[REST]: GetRequestStream is ok");
|
||||
|
||||
byte[] buf = new byte[1024];
|
||||
int length = src.Read(buf, 0, 1024);
|
||||
m_log.Info("[REST]: First Read is ok");
|
||||
while (length > 0)
|
||||
{
|
||||
dst.Write(buf, 0, length);
|
||||
length = src.Read(buf, 0, 1024);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -470,6 +507,9 @@ namespace OpenSim.Framework.Communications
|
|||
|
||||
_response.Close();
|
||||
|
||||
if (_response != null)
|
||||
_response.Close();
|
||||
|
||||
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
|
||||
|
||||
// TODO! Implement timeout, without killing the server
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace OpenSim.Framework.Console
|
|||
= "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n";
|
||||
|
||||
public const string ItemHelpText
|
||||
= @"For more information, type 'help all' to get a list of all commands,
|
||||
= @"For more information, type 'help' to get a list of all commands,
|
||||
or type help <item>' where <item> is one of the following:";
|
||||
|
||||
/// <value>
|
||||
|
@ -115,14 +115,16 @@ namespace OpenSim.Framework.Console
|
|||
// General help
|
||||
if (helpParts.Count == 0)
|
||||
{
|
||||
help.Add(GeneralHelpText);
|
||||
help.AddRange(CollectAllCommandsHelp());
|
||||
}
|
||||
else if (helpParts.Count == 1 && helpParts[0] == "categories")
|
||||
{
|
||||
help.Add(""); // Will become a newline.
|
||||
help.Add(GeneralHelpText);
|
||||
help.Add(ItemHelpText);
|
||||
help.AddRange(CollectModulesHelp(tree));
|
||||
}
|
||||
else if (helpParts.Count == 1 && helpParts[0] == "all")
|
||||
{
|
||||
help.AddRange(CollectAllCommandsHelp());
|
||||
}
|
||||
else
|
||||
{
|
||||
help.AddRange(CollectHelp(helpParts));
|
||||
|
@ -145,8 +147,11 @@ namespace OpenSim.Framework.Console
|
|||
{
|
||||
foreach (List<CommandInfo> commands in m_modulesCommands.Values)
|
||||
{
|
||||
var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help));
|
||||
help.AddRange(ourHelpText);
|
||||
foreach (CommandInfo c in commands)
|
||||
{
|
||||
if (c.long_help != String.Empty)
|
||||
help.Add(string.Format("{0} - {1}", c.help_text, c.long_help));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public enum CustomAssetType : sbyte
|
||||
{
|
||||
CustomTypeBase = 0x60,
|
||||
AnimationSet = 0x60,
|
||||
}
|
||||
|
||||
public enum CustomInventoryType : sbyte
|
||||
{
|
||||
CustomTypeBase = 0x60,
|
||||
AnimationSet = 0x60,
|
||||
}
|
||||
}
|
|
@ -363,11 +363,30 @@ namespace OpenSim.Framework
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool IsBanned(UUID avatarID)
|
||||
public bool IsBanned(UUID avatarID, int userFlags)
|
||||
{
|
||||
foreach (EstateBan ban in l_EstateBans)
|
||||
if (ban.BannedUserID == avatarID)
|
||||
return true;
|
||||
|
||||
if (!IsEstateManagerOrOwner(avatarID) && !HasAccess(avatarID))
|
||||
{
|
||||
if (DenyMinors)
|
||||
{
|
||||
if ((userFlags & 32) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (DenyAnonymous)
|
||||
{
|
||||
if ((userFlags & 4) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -375,7 +394,7 @@ namespace OpenSim.Framework
|
|||
{
|
||||
if (ban == null)
|
||||
return;
|
||||
if (!IsBanned(ban.BannedUserID))
|
||||
if (!IsBanned(ban.BannedUserID, 32)) //Ignore age-based bans
|
||||
l_EstateBans.Add(ban);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,14 +64,15 @@ namespace OpenSim.Framework
|
|||
|
||||
public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes);
|
||||
|
||||
public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest);
|
||||
|
||||
public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize, WearableCacheItem[] CacheItems);
|
||||
public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest);
|
||||
|
||||
public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
|
||||
|
||||
public delegate void StopAnim(IClientAPI remoteClient, UUID animID);
|
||||
|
||||
public delegate void ChangeAnim(UUID animID, bool addOrRemove, bool sendPack);
|
||||
|
||||
public delegate void LinkObjects(IClientAPI remoteClient, uint parent, List<uint> children);
|
||||
|
||||
public delegate void DelinkObjects(List<uint> primIds, IClientAPI client);
|
||||
|
@ -132,6 +133,8 @@ namespace OpenSim.Framework
|
|||
|
||||
public delegate void UpdateVector(uint localID, Vector3 pos, IClientAPI remoteClient);
|
||||
|
||||
public delegate void ClientChangeObject(uint localID, object data ,IClientAPI remoteClient);
|
||||
|
||||
public delegate void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient);
|
||||
|
||||
public delegate void UpdatePrimSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient);
|
||||
|
@ -268,6 +271,9 @@ namespace OpenSim.Framework
|
|||
public delegate void MoveInventoryItem(
|
||||
IClientAPI remoteClient, List<InventoryItemBase> items);
|
||||
|
||||
public delegate void MoveItemsAndLeaveCopy(
|
||||
IClientAPI remoteClient, List<InventoryItemBase> items, UUID destFolder);
|
||||
|
||||
public delegate void RemoveInventoryItem(
|
||||
IClientAPI remoteClient, List<UUID> itemIDs);
|
||||
|
||||
|
@ -443,6 +449,7 @@ namespace OpenSim.Framework
|
|||
public delegate void ClassifiedInfoRequest(UUID classifiedID, IClientAPI client);
|
||||
public delegate void ClassifiedInfoUpdate(UUID classifiedID, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags, int price, IClientAPI client);
|
||||
public delegate void ClassifiedDelete(UUID classifiedID, IClientAPI client);
|
||||
public delegate void ClassifiedGodDelete(UUID classifiedID, UUID queryID, IClientAPI client);
|
||||
|
||||
public delegate void EventNotificationAddRequest(uint EventID, IClientAPI client);
|
||||
public delegate void EventNotificationRemoveRequest(uint EventID, IClientAPI client);
|
||||
|
@ -465,9 +472,9 @@ namespace OpenSim.Framework
|
|||
|
||||
public delegate void AgentFOV(IClientAPI client, float verticalAngle);
|
||||
|
||||
public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int Flags,UUID AgentID);
|
||||
public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int type, uint flags);
|
||||
|
||||
public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name, UUID AgentID);
|
||||
public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name);
|
||||
|
||||
public delegate void AvatarInterestReply(IClientAPI client,UUID target, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
|
||||
|
||||
|
@ -505,6 +512,7 @@ namespace OpenSim.Framework
|
|||
public delegate void SimWideDeletesDelegate(IClientAPI client,UUID agentID, int flags, UUID targetID);
|
||||
|
||||
public delegate void SendPostcard(IClientAPI client);
|
||||
public delegate void ChangeInventoryItemFlags(IClientAPI client, UUID itemID, uint flags);
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -734,6 +742,8 @@ namespace OpenSim.Framework
|
|||
|
||||
IScene Scene { get; }
|
||||
|
||||
List<uint> SelectedObjects { get; }
|
||||
|
||||
// [Obsolete("LLClientView Specific - Replace with ???")]
|
||||
int NextAnimationSequenceNumber { get; }
|
||||
|
||||
|
@ -747,6 +757,8 @@ namespace OpenSim.Framework
|
|||
/// </summary>
|
||||
bool IsActive { get; set; }
|
||||
|
||||
int PingTimeMS { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Set if the client is closing due to a logout request
|
||||
/// </summary>
|
||||
|
@ -794,6 +806,7 @@ namespace OpenSim.Framework
|
|||
event ObjectDrop OnObjectDrop;
|
||||
event StartAnim OnStartAnim;
|
||||
event StopAnim OnStopAnim;
|
||||
event ChangeAnim OnChangeAnim;
|
||||
event LinkObjects OnLinkObjects;
|
||||
event DelinkObjects OnDelinkObjects;
|
||||
event RequestMapBlocks OnRequestMapBlocks;
|
||||
|
@ -860,6 +873,7 @@ namespace OpenSim.Framework
|
|||
event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
|
||||
event UpdatePrimFlags OnUpdatePrimFlags;
|
||||
event UpdatePrimTexture OnUpdatePrimTexture;
|
||||
event ClientChangeObject onClientChangeObject;
|
||||
event UpdateVector OnUpdatePrimGroupPosition;
|
||||
event UpdateVector OnUpdatePrimSinglePosition;
|
||||
event UpdatePrimRotation OnUpdatePrimGroupRotation;
|
||||
|
@ -884,6 +898,7 @@ namespace OpenSim.Framework
|
|||
event RequestTaskInventory OnRequestTaskInventory;
|
||||
event UpdateInventoryItem OnUpdateInventoryItem;
|
||||
event CopyInventoryItem OnCopyInventoryItem;
|
||||
event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||
event MoveInventoryItem OnMoveInventoryItem;
|
||||
event RemoveInventoryFolder OnRemoveInventoryFolder;
|
||||
event RemoveInventoryItem OnRemoveInventoryItem;
|
||||
|
@ -1002,7 +1017,7 @@ namespace OpenSim.Framework
|
|||
event ClassifiedInfoRequest OnClassifiedInfoRequest;
|
||||
event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
|
||||
event ClassifiedDelete OnClassifiedDelete;
|
||||
event ClassifiedDelete OnClassifiedGodDelete;
|
||||
event ClassifiedGodDelete OnClassifiedGodDelete;
|
||||
|
||||
event EventNotificationAddRequest OnEventNotificationAddRequest;
|
||||
event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
|
||||
|
@ -1041,11 +1056,12 @@ namespace OpenSim.Framework
|
|||
event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
|
||||
event SimWideDeletesDelegate OnSimWideDeletes;
|
||||
event SendPostcard OnSendPostcard;
|
||||
event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
|
||||
event MuteListEntryUpdate OnUpdateMuteListEntry;
|
||||
event MuteListEntryRemove OnRemoveMuteListEntry;
|
||||
event GodlikeMessage onGodlikeMessage;
|
||||
event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
|
||||
|
||||
event GenericCall2 OnUpdateThrottles;
|
||||
/// <summary>
|
||||
/// Set the debug level at which packet output should be printed to console.
|
||||
/// </summary>
|
||||
|
@ -1066,7 +1082,7 @@ namespace OpenSim.Framework
|
|||
/// If true, attempts the close without checking active status. You do not want to try this except as a last
|
||||
/// ditch attempt where Active == false but the ScenePresence still exists.
|
||||
/// </param>
|
||||
void Close(bool force);
|
||||
void Close(bool sendStop, bool force);
|
||||
|
||||
void Kick(string message);
|
||||
|
||||
|
@ -1102,6 +1118,8 @@ namespace OpenSim.Framework
|
|||
/// <param name="localID"></param>
|
||||
void SendKillObject(List<uint> localID);
|
||||
|
||||
void SendPartFullUpdate(ISceneEntity ent, uint? parentID);
|
||||
|
||||
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
|
||||
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
|
||||
|
||||
|
@ -1125,6 +1143,8 @@ namespace OpenSim.Framework
|
|||
void SendGenericMessage(string method, UUID invoice, List<string> message);
|
||||
void SendGenericMessage(string method, UUID invoice, List<byte[]> message);
|
||||
|
||||
bool CanSendLayerData();
|
||||
|
||||
void SendLayerData(float[] map);
|
||||
void SendLayerData(int px, int py, float[] map);
|
||||
|
||||
|
@ -1168,6 +1188,10 @@ namespace OpenSim.Framework
|
|||
void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations);
|
||||
|
||||
void SetChildAgentThrottle(byte[] throttle);
|
||||
void SetChildAgentThrottle(byte[] throttle,float factor);
|
||||
|
||||
void SetAgentThrottleSilent(int throttle, int setting);
|
||||
int GetAgentThrottleSilent(int throttle);
|
||||
|
||||
void SendAvatarDataImmediate(ISceneEntity avatar);
|
||||
|
||||
|
@ -1192,6 +1216,7 @@ namespace OpenSim.Framework
|
|||
/// </summary>
|
||||
/// <param name="Item"></param>
|
||||
void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId);
|
||||
void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId);
|
||||
|
||||
void SendRemoveInventoryItem(UUID itemID);
|
||||
|
||||
|
@ -1211,7 +1236,7 @@ namespace OpenSim.Framework
|
|||
/// <param name="node"></param>
|
||||
void SendBulkUpdateInventory(InventoryNodeBase node);
|
||||
|
||||
void SendXferPacket(ulong xferID, uint packet, byte[] data);
|
||||
void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory);
|
||||
|
||||
void SendAbortXferPacket(ulong xferID);
|
||||
|
||||
|
|
|
@ -93,5 +93,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
|
||||
void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
|
||||
void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
|
||||
void sendClientInitialLandInfo(IClientAPI remoteClient);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace OpenSim.Framework
|
|||
void SendLandUpdateToAvatarsOverMe();
|
||||
|
||||
void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client);
|
||||
void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client);
|
||||
bool UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client, out bool snap_selection, out bool needOverlay);
|
||||
bool IsEitherBannedOrRestricted(UUID avatar);
|
||||
bool IsBannedFromLand(UUID avatar);
|
||||
bool CanBeOnThisLand(UUID avatar, float posHeight);
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace OpenSim.Framework
|
|||
public interface IMoneyModule
|
||||
{
|
||||
bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID,
|
||||
int amount);
|
||||
int amount, UUID txn, out string reason);
|
||||
|
||||
int GetBalance(UUID agentID);
|
||||
bool UploadCovered(UUID agentID, int amount);
|
||||
|
@ -41,6 +41,7 @@ namespace OpenSim.Framework
|
|||
void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type);
|
||||
void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData);
|
||||
void ApplyUploadCharge(UUID agentID, int amount, string text);
|
||||
void MoveMoney(UUID fromUser, UUID toUser, int amount, string text);
|
||||
|
||||
int UploadCharge { get; }
|
||||
int GroupCreationCharge { get; }
|
||||
|
|
|
@ -67,9 +67,9 @@ namespace OpenSim.Framework
|
|||
|
||||
private uint _flags = (uint)ParcelFlags.AllowFly | (uint)ParcelFlags.AllowLandmark |
|
||||
(uint)ParcelFlags.AllowAPrimitiveEntry |
|
||||
(uint)ParcelFlags.AllowDeedToGroup | (uint)ParcelFlags.AllowTerraform |
|
||||
(uint)ParcelFlags.AllowDeedToGroup |
|
||||
(uint)ParcelFlags.CreateObjects | (uint)ParcelFlags.AllowOtherScripts |
|
||||
(uint)ParcelFlags.SoundLocal | (uint)ParcelFlags.AllowVoiceChat;
|
||||
(uint)ParcelFlags.AllowVoiceChat;
|
||||
|
||||
private byte _landingType = 0;
|
||||
private string _name = "Your Parcel";
|
||||
|
@ -99,6 +99,10 @@ namespace OpenSim.Framework
|
|||
private bool _obscureMedia = false;
|
||||
private float _dwell = 0;
|
||||
|
||||
public bool SeeAVs { get; set; }
|
||||
public bool AnyAVSounds { get; set; }
|
||||
public bool GroupAVSounds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Traffic count of parcel
|
||||
/// </summary>
|
||||
|
@ -728,6 +732,9 @@ namespace OpenSim.Framework
|
|||
public LandData()
|
||||
{
|
||||
_globalID = UUID.Random();
|
||||
SeeAVs = true;
|
||||
AnyAVSounds = true;
|
||||
GroupAVSounds = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -778,6 +785,9 @@ namespace OpenSim.Framework
|
|||
landData._simwideArea = _simwideArea;
|
||||
landData._simwidePrims = _simwidePrims;
|
||||
landData._dwell = _dwell;
|
||||
landData.SeeAVs = SeeAVs;
|
||||
landData.AnyAVSounds = AnyAVSounds;
|
||||
landData.GroupAVSounds = GroupAVSounds;
|
||||
|
||||
landData._parcelAccessList.Clear();
|
||||
foreach (LandAccessEntry entry in _parcelAccessList)
|
||||
|
@ -793,21 +803,21 @@ namespace OpenSim.Framework
|
|||
return landData;
|
||||
}
|
||||
|
||||
public void ToXml(XmlWriter xmlWriter)
|
||||
{
|
||||
serializer.Serialize(xmlWriter, this);
|
||||
}
|
||||
// public void ToXml(XmlWriter xmlWriter)
|
||||
// {
|
||||
// serializer.Serialize(xmlWriter, this);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Restore a LandData object from the serialized xml representation.
|
||||
/// </summary>
|
||||
/// <param name="xmlReader"></param>
|
||||
/// <returns></returns>
|
||||
public static LandData FromXml(XmlReader xmlReader)
|
||||
{
|
||||
LandData land = (LandData)serializer.Deserialize(xmlReader);
|
||||
|
||||
return land;
|
||||
}
|
||||
// public static LandData FromXml(XmlReader xmlReader)
|
||||
// {
|
||||
// LandData land = (LandData)serializer.Deserialize(xmlReader);
|
||||
//
|
||||
// return land;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,5 +56,8 @@ namespace OpenSim.Framework
|
|||
public bool MediaLoop;
|
||||
public bool ObscureMusic;
|
||||
public bool ObscureMedia;
|
||||
public bool SeeAVs;
|
||||
public bool AnyAVSounds;
|
||||
public bool GroupAVSounds;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ using System.Threading;
|
|||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public sealed class LocklessQueue<T>
|
||||
public class LocklessQueue<T>
|
||||
{
|
||||
private sealed class SingleLinkNode
|
||||
{
|
||||
|
@ -41,7 +41,7 @@ namespace OpenSim.Framework
|
|||
SingleLinkNode tail;
|
||||
int count;
|
||||
|
||||
public int Count { get { return count; } }
|
||||
public virtual int Count { get { return count; } }
|
||||
|
||||
public LocklessQueue()
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ namespace OpenSim.Framework
|
|||
Interlocked.Increment(ref count);
|
||||
}
|
||||
|
||||
public bool Dequeue(out T item)
|
||||
public virtual bool Dequeue(out T item)
|
||||
{
|
||||
item = default(T);
|
||||
SingleLinkNode oldHead = null;
|
||||
|
|
|
@ -43,7 +43,6 @@ namespace OpenSim.Framework.Monitoring
|
|||
StringBuilder sb = new StringBuilder(Environment.NewLine);
|
||||
sb.Append("MEMORY STATISTICS");
|
||||
sb.Append(Environment.NewLine);
|
||||
|
||||
sb.AppendFormat(
|
||||
"Heap allocated to OpenSim : {0} MB\n",
|
||||
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
|
||||
|
@ -56,9 +55,23 @@ namespace OpenSim.Framework.Monitoring
|
|||
"Average heap allocation rate: {0} MB/s\n",
|
||||
Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1024.0 / 1024, 3));
|
||||
|
||||
sb.AppendFormat(
|
||||
"Process memory : {0} MB\n",
|
||||
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
|
||||
Process myprocess = Process.GetCurrentProcess();
|
||||
if (!myprocess.HasExited)
|
||||
{
|
||||
myprocess.Refresh();
|
||||
sb.AppendFormat(
|
||||
"Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
|
||||
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0),
|
||||
Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0),
|
||||
Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0));
|
||||
sb.AppendFormat(
|
||||
"Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
|
||||
Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0),
|
||||
Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0),
|
||||
Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0));
|
||||
}
|
||||
else
|
||||
sb.Append("Process reported as Exited \n");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
|
|
@ -249,6 +249,49 @@ namespace OpenSim.Framework.Monitoring
|
|||
(s) => { s.Value = Math.Round(MemoryWatchdog.LastHeapAllocationRate * 1000d / 1024d / 1024d, 3); });
|
||||
MakeStat("AverageHeapAllocationRate", null, "MB/sec", ContainerMemory,
|
||||
(s) => { s.Value = Math.Round(MemoryWatchdog.AverageHeapAllocationRate * 1000d / 1024d / 1024d, 3); });
|
||||
|
||||
MakeStat("ProcessResident", null, "MB", ContainerProcess,
|
||||
(s) =>
|
||||
{
|
||||
Process myprocess = Process.GetCurrentProcess();
|
||||
myprocess.Refresh();
|
||||
s.Value = Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0);
|
||||
});
|
||||
MakeStat("ProcessPaged", null, "MB", ContainerProcess,
|
||||
(s) =>
|
||||
{
|
||||
Process myprocess = Process.GetCurrentProcess();
|
||||
myprocess.Refresh();
|
||||
s.Value = Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0);
|
||||
});
|
||||
MakeStat("ProcessVirtual", null, "MB", ContainerProcess,
|
||||
(s) =>
|
||||
{
|
||||
Process myprocess = Process.GetCurrentProcess();
|
||||
myprocess.Refresh();
|
||||
s.Value = Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0);
|
||||
});
|
||||
MakeStat("PeakProcessResident", null, "MB", ContainerProcess,
|
||||
(s) =>
|
||||
{
|
||||
Process myprocess = Process.GetCurrentProcess();
|
||||
myprocess.Refresh();
|
||||
s.Value = Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0);
|
||||
});
|
||||
MakeStat("PeakProcessPaged", null, "MB", ContainerProcess,
|
||||
(s) =>
|
||||
{
|
||||
Process myprocess = Process.GetCurrentProcess();
|
||||
myprocess.Refresh();
|
||||
s.Value = Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0);
|
||||
});
|
||||
MakeStat("PeakProcessVirtual", null, "MB", ContainerProcess,
|
||||
(s) =>
|
||||
{
|
||||
Process myprocess = Process.GetCurrentProcess();
|
||||
myprocess.Refresh();
|
||||
s.Value = Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0);
|
||||
});
|
||||
}
|
||||
|
||||
// Notes on performance counters:
|
||||
|
|
|
@ -239,6 +239,17 @@ namespace OpenSim.Framework.Monitoring
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
public virtual OSDMap ToBriefOSDMap()
|
||||
{
|
||||
OSDMap ret = new OSDMap();
|
||||
|
||||
ret.Add("Value", OSD.FromReal(Value));
|
||||
|
||||
double lastChangeOverTime, averageChangeOverTime;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public virtual OSDMap ToOSDMap()
|
||||
{
|
||||
OSDMap ret = new OSDMap();
|
||||
|
|
|
@ -283,7 +283,7 @@ namespace OpenSim.Framework.Monitoring
|
|||
if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName))
|
||||
continue;
|
||||
|
||||
statMap.Add(statName, theStats[statName].ToOSDMap());
|
||||
statMap.Add(statName, theStats[statName].ToBriefOSDMap());
|
||||
}
|
||||
|
||||
contMap.Add(contName, statMap);
|
||||
|
@ -305,6 +305,17 @@ namespace OpenSim.Framework.Monitoring
|
|||
string pContainerName = StatsManager.AllSubCommand;
|
||||
string pStatName = StatsManager.AllSubCommand;
|
||||
|
||||
if (!request.ContainsKey("pass") || request["pass"].ToString() != "l0st4nge1s")
|
||||
{
|
||||
responsedata["int_response_code"] = response_code;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Access denied";
|
||||
responsedata["access_control_allow_origin"] = "*";
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
if (request.ContainsKey("cat")) pCategoryName = request["cat"].ToString();
|
||||
if (request.ContainsKey("cont")) pContainerName = request["cat"].ToString();
|
||||
if (request.ContainsKey("stat")) pStatName = request["stat"].ToString();
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace OpenSim.Framework
|
|||
|
||||
// "Out of band" managemnt https
|
||||
public bool ssl_listener = false;
|
||||
public bool ssl_external = false;
|
||||
public uint https_port = 0;
|
||||
public string cert_path = String.Empty;
|
||||
public string cert_pass = String.Empty;
|
||||
|
@ -64,6 +65,7 @@ namespace OpenSim.Framework
|
|||
|
||||
// "Out of band management https"
|
||||
ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false);
|
||||
ssl_external = config.Configs["Network"].GetBoolean("https_external",false);
|
||||
if( ssl_listener)
|
||||
{
|
||||
cert_path = config.Configs["Network"].GetString("cert_path",String.Empty);
|
||||
|
|
|
@ -51,12 +51,11 @@ namespace OpenSim.Framework
|
|||
protected object m_senderObject;
|
||||
protected ChatTypeEnum m_type;
|
||||
protected UUID m_fromID;
|
||||
protected UUID m_toID;
|
||||
protected UUID m_destination = UUID.Zero;
|
||||
|
||||
public OSChatMessage()
|
||||
{
|
||||
m_position = new Vector3();
|
||||
m_toID = UUID.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -104,15 +103,6 @@ namespace OpenSim.Framework
|
|||
set { m_from = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the sender (needed for scripts)
|
||||
/// </summary>
|
||||
public string To
|
||||
{
|
||||
get { return m_from; }
|
||||
set { m_from = value; }
|
||||
}
|
||||
|
||||
#region IEventArgs Members
|
||||
|
||||
/// TODO: Sender and SenderObject should just be Sender and of
|
||||
|
@ -142,13 +132,10 @@ namespace OpenSim.Framework
|
|||
set { m_fromID = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The single recipient or all if not set.
|
||||
/// </summary>
|
||||
public UUID TargetUUID
|
||||
public UUID Destination
|
||||
{
|
||||
get { return m_toID; }
|
||||
set { m_toID = value; }
|
||||
get { return m_destination; }
|
||||
set { m_destination = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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 OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public enum ObjectChangeType : uint
|
||||
{
|
||||
// bits definitions
|
||||
Position = 0x01,
|
||||
Rotation = 0x02,
|
||||
Scale = 0x04,
|
||||
Group = 0x08,
|
||||
UniformScale = 0x10,
|
||||
|
||||
// macros from above
|
||||
// single prim
|
||||
primP = 0x01,
|
||||
primR = 0x02,
|
||||
primPR = 0x03,
|
||||
primS = 0x04,
|
||||
primPS = 0x05,
|
||||
primRS = 0x06,
|
||||
primPSR = 0x07,
|
||||
|
||||
primUS = 0x14,
|
||||
primPUS = 0x15,
|
||||
primRUS = 0x16,
|
||||
primPUSR = 0x17,
|
||||
|
||||
// group
|
||||
groupP = 0x09,
|
||||
groupR = 0x0A,
|
||||
groupPR = 0x0B,
|
||||
groupS = 0x0C,
|
||||
groupPS = 0x0D,
|
||||
groupRS = 0x0E,
|
||||
groupPSR = 0x0F,
|
||||
|
||||
groupUS = 0x1C,
|
||||
groupPUS = 0x1D,
|
||||
groupRUS = 0x1E,
|
||||
groupPUSR = 0x1F,
|
||||
|
||||
PRSmask = 0x07
|
||||
}
|
||||
|
||||
public struct ObjectChangeData
|
||||
{
|
||||
public Quaternion rotation;
|
||||
public Vector3 position;
|
||||
public Vector3 scale;
|
||||
public ObjectChangeType change;
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public enum ParcelMediaCommandEnum
|
||||
public enum ParcelMediaCommandEnum : int
|
||||
{
|
||||
Stop = 0,
|
||||
Pause = 1,
|
||||
|
|
|
@ -72,8 +72,8 @@ namespace OpenSim.Framework
|
|||
/// <param name="mainPerms">The permissions variable to modify.</param>
|
||||
public static void ApplyFoldedPermissions(uint foldedPerms, ref uint mainPerms)
|
||||
{
|
||||
if ((foldedPerms & 7) == 0)
|
||||
return; // assume that if the folded permissions are 0 then this means that they weren't actually recorded
|
||||
// if ((foldedPerms & 7) == 0)
|
||||
// return; // assume that if the folded permissions are 0 then this means that they weren't actually recorded
|
||||
|
||||
if ((foldedPerms & ((uint)PermissionMask.Copy >> 13)) == 0)
|
||||
mainPerms &= ~(uint)PermissionMask.Copy;
|
||||
|
|
|
@ -245,6 +245,7 @@ namespace OpenSim.Framework
|
|||
// occasionally seems to corrupt its addin cache
|
||||
// Hence, as a temporary solution we'll remove it before each startup
|
||||
|
||||
<<<<<<< HEAD
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(dir + "/addin-db-000"))
|
||||
|
@ -252,6 +253,23 @@ namespace OpenSim.Framework
|
|||
|
||||
if (Directory.Exists(dir + "/addin-db-001"))
|
||||
Directory.Delete(dir + "/addin-db-001", true);
|
||||
=======
|
||||
string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY");
|
||||
string v0 = "addin-db-000";
|
||||
string v1 = "addin-db-001";
|
||||
if (customDir != null && customDir != String.Empty)
|
||||
{
|
||||
v0 = Path.Combine(customDir, v0);
|
||||
v1 = Path.Combine(customDir, v1);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(v0))
|
||||
Directory.Delete(v0, true);
|
||||
|
||||
if (Directory.Exists(v1))
|
||||
Directory.Delete(v1, true);
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
|
|
|
@ -728,7 +728,12 @@ namespace OpenSim.Framework
|
|||
return _lightColorR;
|
||||
}
|
||||
set {
|
||||
_lightColorR = value;
|
||||
if (value < 0)
|
||||
_lightColorR = 0;
|
||||
else if (value > 1.0f)
|
||||
_lightColorR = 1.0f;
|
||||
else
|
||||
_lightColorR = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -737,7 +742,12 @@ namespace OpenSim.Framework
|
|||
return _lightColorG;
|
||||
}
|
||||
set {
|
||||
_lightColorG = value;
|
||||
if (value < 0)
|
||||
_lightColorG = 0;
|
||||
else if (value > 1.0f)
|
||||
_lightColorG = 1.0f;
|
||||
else
|
||||
_lightColorG = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -746,7 +756,12 @@ namespace OpenSim.Framework
|
|||
return _lightColorB;
|
||||
}
|
||||
set {
|
||||
_lightColorB = value;
|
||||
if (value < 0)
|
||||
_lightColorB = 0;
|
||||
else if (value > 1.0f)
|
||||
_lightColorB = 1.0f;
|
||||
else
|
||||
_lightColorB = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -755,7 +770,12 @@ namespace OpenSim.Framework
|
|||
return _lightColorA;
|
||||
}
|
||||
set {
|
||||
_lightColorA = value;
|
||||
if (value < 0)
|
||||
_lightColorA = 0;
|
||||
else if (value > 1.0f)
|
||||
_lightColorA = 1.0f;
|
||||
else
|
||||
_lightColorA = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,6 +888,11 @@ namespace OpenSim.Framework
|
|||
}
|
||||
|
||||
public ulong GetMeshKey(Vector3 size, float lod)
|
||||
{
|
||||
return GetMeshKey(size, lod, false);
|
||||
}
|
||||
|
||||
public ulong GetMeshKey(Vector3 size, float lod, bool convex)
|
||||
{
|
||||
ulong hash = 5381;
|
||||
|
||||
|
@ -914,6 +939,9 @@ namespace OpenSim.Framework
|
|||
hash = djb2(hash, scaleBytes[i]);
|
||||
}
|
||||
|
||||
if(convex)
|
||||
hash = djb2(hash, 0xa5);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
@ -1417,7 +1445,7 @@ namespace OpenSim.Framework
|
|||
prim.Textures = this.Textures;
|
||||
|
||||
prim.Properties = new Primitive.ObjectProperties();
|
||||
prim.Properties.Name = "Primitive";
|
||||
prim.Properties.Name = "Object";
|
||||
prim.Properties.Description = "";
|
||||
prim.Properties.CreatorID = UUID.Zero;
|
||||
prim.Properties.GroupID = UUID.Zero;
|
||||
|
|
|
@ -45,7 +45,8 @@ namespace OpenSim.Framework
|
|||
/// <summary>
|
||||
/// Total number of queues (priorities) available
|
||||
/// </summary>
|
||||
public const uint NumberOfQueues = 12;
|
||||
|
||||
public const uint NumberOfQueues = 12; // includes immediate queues, m_queueCounts need to be set acording
|
||||
|
||||
/// <summary>
|
||||
/// Number of queuest (priorities) that are processed immediately
|
||||
|
@ -60,7 +61,10 @@ namespace OpenSim.Framework
|
|||
// each pass. weighted towards the higher priority queues
|
||||
private uint m_nextQueue = 0;
|
||||
private uint m_countFromQueue = 0;
|
||||
private uint[] m_queueCounts = { 8, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1 };
|
||||
// first queues are imediate, so no counts
|
||||
// private uint[] m_queueCounts = { 0, 0, 8, 4, 4, 2, 2, 2, 2, 1, 1, 1 };
|
||||
private uint[] m_queueCounts = {0, 0, 8, 8, 5, 4, 3, 2, 1, 1, 1, 1};
|
||||
// this is ava, ava, attach, <10m, 20,40,80,160m,320,640,1280, +
|
||||
|
||||
// next request is a counter of the number of updates queued, it provides
|
||||
// a total ordering on the updates coming through the queue and is more
|
||||
|
@ -130,6 +134,21 @@ namespace OpenSim.Framework
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
public void Remove(List<uint> ids)
|
||||
{
|
||||
LookupItem lookup;
|
||||
|
||||
foreach (uint localid in ids)
|
||||
{
|
||||
if (m_lookupTable.TryGetValue(localid, out lookup))
|
||||
{
|
||||
lookup.Heap.Remove(lookup.Handle);
|
||||
m_lookupTable.Remove(localid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove an item from one of the queues. Specifically, it removes the
|
||||
/// oldest item from the next queue in order to provide fair access to
|
||||
|
@ -137,7 +156,7 @@ namespace OpenSim.Framework
|
|||
/// </summary>
|
||||
public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue)
|
||||
{
|
||||
// If there is anything in priority queue 0, return it first no
|
||||
// If there is anything in imediate queues, return it first no
|
||||
// matter what else. Breaks fairness. But very useful.
|
||||
for (int iq = 0; iq < NumberOfImmediateQueues; iq++)
|
||||
{
|
||||
|
@ -172,14 +191,13 @@ namespace OpenSim.Framework
|
|||
}
|
||||
|
||||
// Find the next non-immediate queue with updates in it
|
||||
for (int i = 0; i < NumberOfQueues; ++i)
|
||||
for (uint i = NumberOfImmediateQueues; i < NumberOfQueues; ++i)
|
||||
{
|
||||
m_nextQueue = (uint)((m_nextQueue + 1) % NumberOfQueues);
|
||||
m_countFromQueue = m_queueCounts[m_nextQueue];
|
||||
m_nextQueue++;
|
||||
if(m_nextQueue >= NumberOfQueues)
|
||||
m_nextQueue = NumberOfImmediateQueues;
|
||||
|
||||
// if this is one of the immediate queues, just skip it
|
||||
if (m_nextQueue < NumberOfImmediateQueues)
|
||||
continue;
|
||||
m_countFromQueue = m_queueCounts[m_nextQueue];
|
||||
|
||||
if (m_heaps[m_nextQueue].Count > 0)
|
||||
{
|
||||
|
@ -189,7 +207,6 @@ namespace OpenSim.Framework
|
|||
m_lookupTable.Remove(item.Value.Entity.LocalId);
|
||||
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
|
||||
value = item.Value;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ using OpenMetaverse.StructuredData;
|
|||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
[Serializable]
|
||||
public class RegionLightShareData : ICloneable
|
||||
{
|
||||
public bool valid = false;
|
||||
|
@ -101,6 +102,12 @@ namespace OpenSim.Framework
|
|||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly string LogHeader = "[REGION INFO]";
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
public bool commFailTF = false;
|
||||
public ConfigurationMember configMember;
|
||||
public string DataStore = String.Empty;
|
||||
>>>>>>> avn/ubitvar
|
||||
public string RegionFile = String.Empty;
|
||||
public bool isSandbox = false;
|
||||
public bool Persistent = true;
|
||||
|
@ -527,7 +534,11 @@ namespace OpenSim.Framework
|
|||
return null;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
private void SetExtraSetting(string key, string value)
|
||||
=======
|
||||
public void SetExtraSetting(string key, string value)
|
||||
>>>>>>> avn/ubitvar
|
||||
{
|
||||
string keylower = key.ToLower();
|
||||
m_extraSettings[keylower] = value;
|
||||
|
@ -823,7 +834,15 @@ namespace OpenSim.Framework
|
|||
string location = String.Format("{0},{1}", RegionLocX, RegionLocY);
|
||||
config.Set("Location", location);
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (RegionSizeX > 0)
|
||||
=======
|
||||
if (DataStore != String.Empty)
|
||||
config.Set("Datastore", DataStore);
|
||||
|
||||
if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize)
|
||||
{
|
||||
>>>>>>> avn/ubitvar
|
||||
config.Set("SizeX", RegionSizeX);
|
||||
|
||||
if (RegionSizeY > 0)
|
||||
|
@ -901,6 +920,234 @@ namespace OpenSim.Framework
|
|||
throw new Exception("Invalid file type for region persistence.");
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
public void loadConfigurationOptionsFromMe()
|
||||
{
|
||||
configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID_NULL_FREE,
|
||||
"UUID of Region (Default is recommended, random UUID)",
|
||||
RegionID.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"Region Name", RegionName, true);
|
||||
|
||||
configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Grid Location (X Axis)", RegionLocX.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Grid Location (Y Axis)", RegionLocY.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in X dimension", RegionSizeX.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in Y dimension", RegionSizeY.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in Z dimension", RegionSizeZ.ToString(), true);
|
||||
|
||||
//m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
|
||||
configMember.addConfigurationOption("internal_ip_address",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
|
||||
"Internal IP Address for incoming UDP client connections",
|
||||
m_internalEndPoint.Address.ToString(),
|
||||
true);
|
||||
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Internal IP Port for incoming UDP client connections",
|
||||
m_internalEndPoint.Port.ToString(), true);
|
||||
configMember.addConfigurationOption("allow_alternate_ports",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
|
||||
"Allow sim to find alternate UDP ports when ports are in use?",
|
||||
m_allow_alternate_ports.ToString(), true);
|
||||
configMember.addConfigurationOption("external_host_name",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"External Host Name", m_externalHostName, true);
|
||||
configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"Last Map UUID", lastMapUUID.ToString(), true);
|
||||
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
|
||||
"Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
|
||||
"Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for physical prims", m_physPrimMax.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
|
||||
"Clamp prims to max size", m_clampPrimSize.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max objects this sim will hold", m_objectCapacity.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("linkset_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max prims an object will hold", m_linksetCapacity.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max avatars this sim will hold", m_agentCapacity.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"Scope ID for this region", ScopeID.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING,
|
||||
"Free form string describing the type of region", String.Empty, true);
|
||||
|
||||
configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"UUID of a texture to use as the map for this region", m_maptileStaticUUID.ToString(), true);
|
||||
}
|
||||
|
||||
public void loadConfigurationOptions()
|
||||
{
|
||||
configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"UUID of Region (Default is recommended, random UUID)",
|
||||
UUID.Random().ToString(), true);
|
||||
configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"Region Name", "OpenSim Test", false);
|
||||
|
||||
configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Grid Location (X Axis)", "1000", false);
|
||||
configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Grid Location (Y Axis)", "1000", false);
|
||||
configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in X dimension", Constants.RegionSize.ToString(), false);
|
||||
configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in Y dimension", Constants.RegionSize.ToString(), false);
|
||||
configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in Z dimension", Constants.RegionHeight.ToString(), false);
|
||||
|
||||
//m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
|
||||
configMember.addConfigurationOption("internal_ip_address",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
|
||||
"Internal IP Address for incoming UDP client connections", "0.0.0.0",
|
||||
false);
|
||||
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Internal IP Port for incoming UDP client connections",
|
||||
ConfigSettings.DefaultRegionHttpPort.ToString(), false);
|
||||
configMember.addConfigurationOption("allow_alternate_ports", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
|
||||
"Allow sim to find alternate UDP ports when ports are in use?",
|
||||
"false", true);
|
||||
configMember.addConfigurationOption("external_host_name",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"External Host Name", "127.0.0.1", false);
|
||||
configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"Last Map UUID", lastMapUUID.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for nonphysical prims", "0", true);
|
||||
|
||||
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for physical prims", "0", true);
|
||||
|
||||
configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
|
||||
"Clamp prims to max size", "false", true);
|
||||
|
||||
configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max objects this sim will hold", "15000", true);
|
||||
|
||||
configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max avatars this sim will hold", "100", true);
|
||||
|
||||
configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"Scope ID for this region", UUID.Zero.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING,
|
||||
"Region Type", String.Empty, true);
|
||||
|
||||
configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"UUID of a texture to use as the map for this region", String.Empty, true);
|
||||
}
|
||||
|
||||
public bool handleIncomingConfiguration(string configuration_key, object configuration_result)
|
||||
{
|
||||
switch (configuration_key)
|
||||
{
|
||||
case "sim_UUID":
|
||||
RegionID = (UUID) configuration_result;
|
||||
originRegionID = (UUID) configuration_result;
|
||||
break;
|
||||
case "sim_name":
|
||||
RegionName = (string) configuration_result;
|
||||
break;
|
||||
case "sim_location_x":
|
||||
RegionLocX = (uint) configuration_result;
|
||||
break;
|
||||
case "sim_location_y":
|
||||
RegionLocY = (uint) configuration_result;
|
||||
break;
|
||||
case "sim_size_x":
|
||||
RegionSizeX = (uint) configuration_result;
|
||||
break;
|
||||
case "sim_size_y":
|
||||
RegionSizeY = (uint) configuration_result;
|
||||
break;
|
||||
case "sim_size_z":
|
||||
RegionSizeZ = (uint) configuration_result;
|
||||
break;
|
||||
case "datastore":
|
||||
DataStore = (string) configuration_result;
|
||||
break;
|
||||
case "internal_ip_address":
|
||||
IPAddress address = (IPAddress) configuration_result;
|
||||
m_internalEndPoint = new IPEndPoint(address, 0);
|
||||
break;
|
||||
case "internal_ip_port":
|
||||
m_internalEndPoint.Port = (int) configuration_result;
|
||||
break;
|
||||
case "allow_alternate_ports":
|
||||
m_allow_alternate_ports = (bool) configuration_result;
|
||||
break;
|
||||
case "external_host_name":
|
||||
if ((string) configuration_result != "SYSTEMIP")
|
||||
{
|
||||
m_externalHostName = (string) configuration_result;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_externalHostName = Util.GetLocalHost().ToString();
|
||||
}
|
||||
break;
|
||||
case "lastmap_uuid":
|
||||
lastMapUUID = (UUID)configuration_result;
|
||||
break;
|
||||
case "lastmap_refresh":
|
||||
lastMapRefresh = (string)configuration_result;
|
||||
break;
|
||||
case "nonphysical_prim_max":
|
||||
m_nonphysPrimMax = (int)configuration_result;
|
||||
break;
|
||||
case "physical_prim_max":
|
||||
m_physPrimMax = (int)configuration_result;
|
||||
break;
|
||||
case "clamp_prim_size":
|
||||
m_clampPrimSize = (bool)configuration_result;
|
||||
break;
|
||||
case "object_capacity":
|
||||
m_objectCapacity = (int)configuration_result;
|
||||
break;
|
||||
case "linkset_capacity":
|
||||
m_linksetCapacity = (int)configuration_result;
|
||||
break;
|
||||
case "agent_capacity":
|
||||
m_agentCapacity = (int)configuration_result;
|
||||
break;
|
||||
case "scope_id":
|
||||
ScopeID = (UUID)configuration_result;
|
||||
break;
|
||||
case "region_type":
|
||||
m_regionType = (string)configuration_result;
|
||||
break;
|
||||
case "region_static_maptile":
|
||||
m_maptileStaticUUID = (UUID)configuration_result;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
>>>>>>> avn/ubitvar
|
||||
public void SaveLastMapUUID(UUID mapUUID)
|
||||
{
|
||||
lastMapUUID = mapUUID;
|
||||
|
@ -1004,5 +1251,28 @@ namespace OpenSim.Framework
|
|||
regionInfo.ServerURI = serverURI;
|
||||
return regionInfo;
|
||||
}
|
||||
|
||||
public int getInternalEndPointPort()
|
||||
{
|
||||
return m_internalEndPoint.Port;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> ToKeyValuePairs()
|
||||
{
|
||||
Dictionary<string, object> kvp = new Dictionary<string, object>();
|
||||
kvp["uuid"] = RegionID.ToString();
|
||||
kvp["locX"] = RegionLocX.ToString();
|
||||
kvp["locY"] = RegionLocY.ToString();
|
||||
kvp["external_ip_address"] = ExternalEndPoint.Address.ToString();
|
||||
kvp["external_port"] = ExternalEndPoint.Port.ToString();
|
||||
kvp["external_host_name"] = ExternalHostName;
|
||||
kvp["http_port"] = HttpPort.ToString();
|
||||
kvp["internal_ip_address"] = InternalEndPoint.Address.ToString();
|
||||
kvp["internal_port"] = InternalEndPoint.Port.ToString();
|
||||
kvp["alternate_ports"] = m_allow_alternate_ports.ToString();
|
||||
kvp["server_uri"] = ServerURI;
|
||||
|
||||
return kvp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ namespace OpenSim.Framework.RegionLoader.Web
|
|||
|
||||
public RegionInfo[] LoadRegions()
|
||||
{
|
||||
int tries = 3;
|
||||
int wait = 2000;
|
||||
|
||||
if (m_configSource == null)
|
||||
{
|
||||
m_log.Error("[WEBLOADER]: Unable to load configuration source!");
|
||||
|
@ -66,34 +69,59 @@ namespace OpenSim.Framework.RegionLoader.Web
|
|||
}
|
||||
else
|
||||
{
|
||||
RegionInfo[] regionInfos = new RegionInfo[] {};
|
||||
int regionCount = 0;
|
||||
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
|
||||
webRequest.Timeout = 30000; //30 Second Timeout
|
||||
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
|
||||
while(tries > 0)
|
||||
{
|
||||
RegionInfo[] regionInfos = new RegionInfo[] {};
|
||||
int regionCount = 0;
|
||||
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
|
||||
webRequest.Timeout = 30000; //30 Second Timeout
|
||||
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
|
||||
|
||||
try
|
||||
{
|
||||
string xmlSource = String.Empty;
|
||||
|
||||
using (HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse())
|
||||
{
|
||||
m_log.Debug("[WEBLOADER]: Downloading region information...");
|
||||
|
||||
using (Stream s = webResponse.GetResponseStream())
|
||||
try
|
||||
{
|
||||
HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse();
|
||||
m_log.Debug("[WEBLOADER]: Downloading region information...");
|
||||
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
|
||||
string xmlSource = String.Empty;
|
||||
string tempStr = reader.ReadLine();
|
||||
while (tempStr != null)
|
||||
{
|
||||
xmlSource = xmlSource + tempStr;
|
||||
tempStr = reader.ReadLine();
|
||||
}
|
||||
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
|
||||
xmlSource.Length);
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.LoadXml(xmlSource);
|
||||
if (xmlDoc.FirstChild.Name == "Nini")
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(s))
|
||||
{
|
||||
string tempStr = reader.ReadLine();
|
||||
while (tempStr != null)
|
||||
{
|
||||
xmlSource = xmlSource + tempStr;
|
||||
tempStr = reader.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
regionCount = xmlDoc.FirstChild.ChildNodes.Count;
|
||||
|
||||
if (regionCount > 0)
|
||||
{
|
||||
regionInfos = new RegionInfo[regionCount];
|
||||
int i;
|
||||
for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
|
||||
{
|
||||
m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
|
||||
regionInfos[i] =
|
||||
new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
|
||||
{
|
||||
if (!allowRegionless)
|
||||
throw ex;
|
||||
}
|
||||
else
|
||||
throw ex;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
|
||||
xmlSource.Length);
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
|
@ -118,28 +146,22 @@ namespace OpenSim.Framework.RegionLoader.Web
|
|||
catch (WebException ex)
|
||||
{
|
||||
using (HttpWebResponse response = (HttpWebResponse)ex.Response)
|
||||
{
|
||||
if (response.StatusCode == HttpStatusCode.NotFound)
|
||||
{
|
||||
if (!allowRegionless)
|
||||
throw ex;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
=======
|
||||
if (regionCount > 0 | allowRegionless)
|
||||
return regionInfos;
|
||||
|
||||
if (regionCount > 0 | allowRegionless)
|
||||
{
|
||||
return regionInfos;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error("[WEBLOADER]: No region configs were available.");
|
||||
return null;
|
||||
}
|
||||
m_log.Debug("[WEBLOADER]: Request yielded no regions.");
|
||||
tries--;
|
||||
if (tries > 0)
|
||||
>>>>>>> avn/ubitvar
|
||||
{
|
||||
m_log.Debug("[WEBLOADER]: Retrying");
|
||||
System.Threading.Thread.Sleep(wait);
|
||||
}
|
||||
}
|
||||
|
||||
m_log.Error("[WEBLOADER]: No region configs were available.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -482,6 +482,28 @@ namespace OpenSim.Framework
|
|||
set { m_LoadedCreationID = value; }
|
||||
}
|
||||
|
||||
private bool m_GodBlockSearch = false;
|
||||
public bool GodBlockSearch
|
||||
{
|
||||
get { return m_GodBlockSearch; }
|
||||
set { m_GodBlockSearch = value; }
|
||||
}
|
||||
|
||||
private bool m_Casino = false;
|
||||
public bool Casino
|
||||
{
|
||||
get { return m_Casino; }
|
||||
set { m_Casino = value; }
|
||||
}
|
||||
|
||||
// Telehub support
|
||||
private bool m_TelehubEnabled = false;
|
||||
public bool HasTelehub
|
||||
{
|
||||
get { return m_TelehubEnabled; }
|
||||
set { m_TelehubEnabled = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connected Telehub object
|
||||
/// </summary>
|
||||
|
|
|
@ -65,8 +65,12 @@ namespace OpenSim.Framework.Servers
|
|||
/// This will control a periodic log printout of the current 'show stats' (if they are active) for this
|
||||
/// server.
|
||||
/// </summary>
|
||||
<<<<<<< HEAD
|
||||
private int m_periodDiagnosticTimerMS = 60 * 60 * 1000;
|
||||
private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
|
||||
=======
|
||||
// private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
/// <summary>
|
||||
/// Random uuid for private data
|
||||
|
@ -84,6 +88,11 @@ namespace OpenSim.Framework.Servers
|
|||
// Random uuid for private data
|
||||
m_osSecret = UUID.Random().ToString();
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
// m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
|
||||
// m_periodicDiagnosticsTimer.Enabled = true;
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -147,13 +156,23 @@ namespace OpenSim.Framework.Servers
|
|||
/// </summary>
|
||||
public virtual void Startup()
|
||||
{
|
||||
m_log.Info("[STARTUP]: Beginning startup processing");
|
||||
|
||||
m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine);
|
||||
// clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
|
||||
// the clr version number doesn't match the project version number under Mono.
|
||||
//m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);
|
||||
m_log.InfoFormat(
|
||||
"[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n",
|
||||
Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32");
|
||||
|
||||
StartupSpecific();
|
||||
|
||||
TimeSpan timeTaken = DateTime.Now - m_startuptime;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED. Non-script portion of startup took {0}m {1}s.",
|
||||
timeTaken.Minutes, timeTaken.Seconds);
|
||||
// MainConsole.Instance.OutputFormat(
|
||||
// "PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED. Non-script portion of startup took {0}m {1}s.",
|
||||
// timeTaken.Minutes, timeTaken.Seconds);
|
||||
}
|
||||
|
||||
public string osSecret
|
||||
|
|
|
@ -403,6 +403,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
StreamReader reader = new StreamReader(requestStream, encoding);
|
||||
|
||||
string requestBody = reader.ReadToEnd();
|
||||
reader.Close();
|
||||
|
||||
Hashtable keysvals = new Hashtable();
|
||||
Hashtable headervals = new Hashtable();
|
||||
|
@ -460,7 +461,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
}
|
||||
|
||||
OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
|
||||
resp.ReuseContext = true;
|
||||
resp.ReuseContext = false;
|
||||
HandleRequest(req, resp);
|
||||
|
||||
// !!!HACK ALERT!!!
|
||||
|
@ -759,7 +760,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
// Every month or so this will wrap and give bad numbers, not really a problem
|
||||
// since its just for reporting
|
||||
int tickdiff = requestEndTick - requestStartTick;
|
||||
if (tickdiff > 3000 && requestHandler != null && requestHandler.Name != "GetTexture")
|
||||
if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture"))
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
|
||||
|
@ -1024,6 +1025,19 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
string responseString = String.Empty;
|
||||
XmlRpcRequest xmlRprcRequest = null;
|
||||
|
||||
bool gridproxy = false;
|
||||
if (requestBody.Contains("encoding=\"utf-8"))
|
||||
{
|
||||
int channelindx = -1;
|
||||
int optionsindx = requestBody.IndexOf(">options<");
|
||||
if(optionsindx >0)
|
||||
{
|
||||
channelindx = requestBody.IndexOf(">channel<");
|
||||
if (optionsindx < channelindx)
|
||||
gridproxy = true;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
|
||||
|
@ -1081,6 +1095,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
}
|
||||
xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3]
|
||||
|
||||
if (gridproxy)
|
||||
xmlRprcRequest.Params.Add("gridproxy"); // Param[4]
|
||||
try
|
||||
{
|
||||
xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint);
|
||||
|
@ -1732,10 +1748,40 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
|
||||
{
|
||||
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
|
||||
int responsecode = (int)responsedata["int_response_code"];
|
||||
string responseString = (string)responsedata["str_response_string"];
|
||||
string contentType = (string)responsedata["content_type"];
|
||||
int responsecode;
|
||||
string responseString = String.Empty;
|
||||
byte[] responseData = null;
|
||||
string contentType;
|
||||
|
||||
if (responsedata == null)
|
||||
{
|
||||
responsecode = 500;
|
||||
responseString = "No response could be obtained";
|
||||
contentType = "text/plain";
|
||||
responsedata = new Hashtable();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
|
||||
responsecode = (int)responsedata["int_response_code"];
|
||||
if (responsedata["bin_response_data"] != null)
|
||||
responseData = (byte[])responsedata["bin_response_data"];
|
||||
else
|
||||
responseString = (string)responsedata["str_response_string"];
|
||||
contentType = (string)responsedata["content_type"];
|
||||
if (responseString == null)
|
||||
responseString = String.Empty;
|
||||
}
|
||||
catch
|
||||
{
|
||||
responsecode = 500;
|
||||
responseString = "No response could be obtained";
|
||||
contentType = "text/plain";
|
||||
responsedata = new Hashtable();
|
||||
}
|
||||
}
|
||||
|
||||
if (responsedata.ContainsKey("error_status_text"))
|
||||
{
|
||||
|
@ -1780,25 +1826,40 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
response.AddHeader("Content-Type", contentType);
|
||||
|
||||
if (responsedata.ContainsKey("headers"))
|
||||
{
|
||||
Hashtable headerdata = (Hashtable)responsedata["headers"];
|
||||
|
||||
foreach (string header in headerdata.Keys)
|
||||
response.AddHeader(header, (string)headerdata[header]);
|
||||
}
|
||||
|
||||
byte[] buffer;
|
||||
|
||||
if (!(contentType.Contains("image")
|
||||
|| contentType.Contains("x-shockwave-flash")
|
||||
|| contentType.Contains("application/x-oar")
|
||||
|| contentType.Contains("application/vnd.ll.mesh")))
|
||||
if (responseData != null)
|
||||
{
|
||||
// Text
|
||||
buffer = Encoding.UTF8.GetBytes(responseString);
|
||||
buffer = responseData;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Binary!
|
||||
buffer = Convert.FromBase64String(responseString);
|
||||
}
|
||||
if (!(contentType.Contains("image")
|
||||
|| contentType.Contains("x-shockwave-flash")
|
||||
|| contentType.Contains("application/x-oar")
|
||||
|| contentType.Contains("application/vnd.ll.mesh")))
|
||||
{
|
||||
// Text
|
||||
buffer = Encoding.UTF8.GetBytes(responseString);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Binary!
|
||||
buffer = Convert.FromBase64String(responseString);
|
||||
}
|
||||
|
||||
response.SendChunked = false;
|
||||
response.ContentLength64 = buffer.Length;
|
||||
response.ContentEncoding = Encoding.UTF8;
|
||||
response.SendChunked = false;
|
||||
response.ContentLength64 = buffer.Length;
|
||||
response.ContentEncoding = Encoding.UTF8;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
@ -1886,9 +1947,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
m_httpListener2.Start(64);
|
||||
|
||||
// Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
|
||||
<<<<<<< HEAD
|
||||
PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000);
|
||||
PollServiceRequestManager.Start();
|
||||
|
||||
=======
|
||||
m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000);
|
||||
m_PollServiceManager.Start();
|
||||
>>>>>>> avn/ubitvar
|
||||
HTTPDRunning = true;
|
||||
|
||||
//HttpListenerContext context;
|
||||
|
@ -1937,7 +2003,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
public void httpServerException(object source, Exception exception)
|
||||
{
|
||||
m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception);
|
||||
if (source.ToString() == "HttpServer.HttpListener" && exception.ToString().StartsWith("Mono.Security.Protocol.Tls.TlsException"))
|
||||
return;
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
|
||||
/*
|
||||
if (HTTPDRunning)// && NotSocketErrors > 5)
|
||||
{
|
||||
|
@ -1984,6 +2052,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
public void RemoveHTTPHandler(string httpMethod, string path)
|
||||
{
|
||||
if (path == null) return; // Caps module isn't loaded, tries to remove handler where path = null
|
||||
lock (m_HTTPHandlers)
|
||||
{
|
||||
if (httpMethod != null && httpMethod.Length == 0)
|
||||
|
|
|
@ -52,7 +52,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
{
|
||||
LongPoll = 0,
|
||||
LslHttp = 1,
|
||||
Inventory = 2
|
||||
Inventory = 2,
|
||||
Texture = 3,
|
||||
Mesh = 4
|
||||
}
|
||||
|
||||
public string Url { get; set; }
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using HttpServer;
|
||||
|
@ -44,6 +45,24 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
public readonly IHttpRequest Request;
|
||||
public readonly int RequestTime;
|
||||
public readonly UUID RequestID;
|
||||
public int contextHash;
|
||||
|
||||
private void GenContextHash()
|
||||
{
|
||||
Random rnd = new Random();
|
||||
contextHash = 0;
|
||||
if (Request.Headers["remote_addr"] != null)
|
||||
contextHash = (Request.Headers["remote_addr"]).GetHashCode() << 16;
|
||||
else
|
||||
contextHash = rnd.Next() << 16;
|
||||
if (Request.Headers["remote_port"] != null)
|
||||
{
|
||||
string[] strPorts = Request.Headers["remote_port"].Split(new char[] { ',' });
|
||||
contextHash += Int32.Parse(strPorts[0]);
|
||||
}
|
||||
else
|
||||
contextHash += rnd.Next() & 0xffff;
|
||||
}
|
||||
|
||||
public PollServiceHttpRequest(
|
||||
PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
|
||||
|
@ -53,6 +72,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
Request = pRequest;
|
||||
RequestTime = System.Environment.TickCount;
|
||||
RequestID = UUID.Random();
|
||||
GenContextHash();
|
||||
}
|
||||
|
||||
internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
|
||||
|
@ -65,6 +85,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
response.SendChunked = false;
|
||||
response.ContentLength64 = buffer.Length;
|
||||
response.ContentEncoding = Encoding.UTF8;
|
||||
response.ReuseContext = false;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -93,5 +114,44 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
PollServiceArgs.RequestsHandled++;
|
||||
}
|
||||
}
|
||||
|
||||
internal void DoHTTPstop(BaseHttpServer server)
|
||||
{
|
||||
OSHttpResponse response
|
||||
= new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
|
||||
|
||||
response.SendChunked = false;
|
||||
response.ContentLength64 = 0;
|
||||
response.ContentEncoding = Encoding.UTF8;
|
||||
response.ReuseContext = false;
|
||||
response.KeepAlive = false;
|
||||
response.SendChunked = false;
|
||||
response.StatusCode = 503;
|
||||
|
||||
try
|
||||
{
|
||||
response.OutputStream.Flush();
|
||||
response.Send();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PollServiceHttpRequestComparer : IEqualityComparer<PollServiceHttpRequest>
|
||||
{
|
||||
public bool Equals(PollServiceHttpRequest b1, PollServiceHttpRequest b2)
|
||||
{
|
||||
if (b1.contextHash != b2.contextHash)
|
||||
return false;
|
||||
bool b = Object.ReferenceEquals(b1.HttpContext, b2.HttpContext);
|
||||
return b;
|
||||
}
|
||||
|
||||
public int GetHashCode(PollServiceHttpRequest b2)
|
||||
{
|
||||
return (int)b2.contextHash;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,15 +65,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
private readonly BaseHttpServer m_server;
|
||||
|
||||
private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext;
|
||||
private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
|
||||
private static List<PollServiceHttpRequest> m_longPollRequests = new List<PollServiceHttpRequest>();
|
||||
private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>();
|
||||
private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>();
|
||||
|
||||
private uint m_WorkerThreadCount = 0;
|
||||
private Thread[] m_workerThreads;
|
||||
private Thread m_retrysThread;
|
||||
|
||||
<<<<<<< HEAD
|
||||
private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2);
|
||||
|
||||
// private int m_timeout = 1000; // increase timeout 250; now use the event one
|
||||
=======
|
||||
private bool m_running = true;
|
||||
private int slowCount = 0;
|
||||
|
||||
private SmartThreadPool m_threadPool;
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
public PollServiceRequestManager(
|
||||
BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout)
|
||||
|
@ -83,6 +93,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
m_WorkerThreadCount = pWorkerThreadCount;
|
||||
m_workerThreads = new Thread[m_WorkerThreadCount];
|
||||
|
||||
<<<<<<< HEAD
|
||||
StatsManager.RegisterStat(
|
||||
new Stat(
|
||||
"QueuedPollResponses",
|
||||
|
@ -108,10 +119,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
MeasuresOfInterest.AverageChangeOverTime,
|
||||
stat => stat.Value = ResponsesProcessed,
|
||||
StatVerbosity.Debug));
|
||||
=======
|
||||
PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer();
|
||||
m_bycontext = new Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>>(preqCp);
|
||||
|
||||
STPStartInfo startInfo = new STPStartInfo();
|
||||
startInfo.IdleTimeout = 30000;
|
||||
startInfo.MaxWorkerThreads = 15;
|
||||
startInfo.MinWorkerThreads = 1;
|
||||
startInfo.ThreadPriority = ThreadPriority.Normal;
|
||||
startInfo.StartSuspended = true;
|
||||
startInfo.ThreadPoolName = "PoolService";
|
||||
|
||||
m_threadPool = new SmartThreadPool(startInfo);
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
IsRunning = true;
|
||||
|
||||
if (PerformResponsesAsync)
|
||||
|
@ -139,40 +165,100 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
null,
|
||||
1000 * 60 * 10);
|
||||
}
|
||||
=======
|
||||
m_threadPool.Start();
|
||||
//startup worker threads
|
||||
for (uint i = 0; i < m_WorkerThreadCount; i++)
|
||||
{
|
||||
m_workerThreads[i]
|
||||
= Watchdog.StartThread(
|
||||
PoolWorkerJob,
|
||||
string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
int.MaxValue);
|
||||
}
|
||||
|
||||
m_retrysThread = Watchdog.StartThread(
|
||||
this.CheckRetries,
|
||||
string.Format("PollServiceWatcherThread:{0}", m_server.Port),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
1000 * 60 * 10);
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
|
||||
private void ReQueueEvent(PollServiceHttpRequest req)
|
||||
{
|
||||
if (IsRunning)
|
||||
{
|
||||
// delay the enqueueing for 100ms. There's no need to have the event
|
||||
// actively on the queue
|
||||
Timer t = new Timer(self => {
|
||||
((Timer)self).Dispose();
|
||||
m_requests.Enqueue(req);
|
||||
});
|
||||
|
||||
t.Change(100, Timeout.Infinite);
|
||||
|
||||
lock (m_retryRequests)
|
||||
m_retryRequests.Enqueue(req);
|
||||
}
|
||||
}
|
||||
|
||||
public void Enqueue(PollServiceHttpRequest req)
|
||||
{
|
||||
if (IsRunning)
|
||||
lock (m_bycontext)
|
||||
{
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll)
|
||||
Queue<PollServiceHttpRequest> ctxQeueue;
|
||||
if (m_bycontext.TryGetValue(req, out ctxQeueue))
|
||||
{
|
||||
lock (m_longPollRequests)
|
||||
m_longPollRequests.Add(req);
|
||||
ctxQeueue.Enqueue(req);
|
||||
}
|
||||
else
|
||||
m_requests.Enqueue(req);
|
||||
{
|
||||
ctxQeueue = new Queue<PollServiceHttpRequest>();
|
||||
m_bycontext[req] = ctxQeueue;
|
||||
EnqueueInt(req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckLongPollThreads()
|
||||
public void byContextDequeue(PollServiceHttpRequest req)
|
||||
{
|
||||
Queue<PollServiceHttpRequest> ctxQeueue;
|
||||
lock (m_bycontext)
|
||||
{
|
||||
if (m_bycontext.TryGetValue(req, out ctxQeueue))
|
||||
{
|
||||
if (ctxQeueue.Count > 0)
|
||||
{
|
||||
PollServiceHttpRequest newreq = ctxQeueue.Dequeue();
|
||||
EnqueueInt(newreq);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bycontext.Remove(req);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void EnqueueInt(PollServiceHttpRequest req)
|
||||
{
|
||||
if (IsRunning)
|
||||
{
|
||||
if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll)
|
||||
{
|
||||
m_requests.Enqueue(req);
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (m_slowRequests)
|
||||
m_slowRequests.Enqueue(req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckRetries()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
// The only purpose of this thread is to check the EQs for events.
|
||||
// If there are events, that thread will be placed in the "ready-to-serve" queue, m_requests.
|
||||
// If there are no events, that thread will be back to its "waiting" queue, m_longPollRequests.
|
||||
|
@ -180,13 +266,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
// so if they aren't ready to be served by a worker thread (no events), they are placed
|
||||
// directly back in the "ready-to-serve" queue by the worker thread.
|
||||
while (IsRunning)
|
||||
=======
|
||||
while (m_running)
|
||||
>>>>>>> avn/ubitvar
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
Thread.Sleep(100); // let the world move .. back to faster rate
|
||||
Watchdog.UpdateThread();
|
||||
|
||||
// List<PollServiceHttpRequest> not_ready = new List<PollServiceHttpRequest>();
|
||||
lock (m_longPollRequests)
|
||||
lock (m_retryRequests)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if (m_longPollRequests.Count > 0 && IsRunning)
|
||||
{
|
||||
List<PollServiceHttpRequest> ready = m_longPollRequests.FindAll(req =>
|
||||
|
@ -199,28 +287,67 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
m_requests.Enqueue(req);
|
||||
m_longPollRequests.Remove(req);
|
||||
});
|
||||
=======
|
||||
while (m_retryRequests.Count > 0 && m_running)
|
||||
m_requests.Enqueue(m_retryRequests.Dequeue());
|
||||
}
|
||||
slowCount++;
|
||||
if (slowCount >= 10)
|
||||
{
|
||||
slowCount = 0;
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
lock (m_slowRequests)
|
||||
{
|
||||
while (m_slowRequests.Count > 0 && m_running)
|
||||
m_requests.Enqueue(m_slowRequests.Dequeue());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
IsRunning = false;
|
||||
// m_timeout = -10000; // cause all to expire
|
||||
=======
|
||||
m_running = false;
|
||||
>>>>>>> avn/ubitvar
|
||||
Thread.Sleep(1000); // let the world move
|
||||
|
||||
foreach (Thread t in m_workerThreads)
|
||||
Watchdog.AbortThread(t.ManagedThreadId);
|
||||
|
||||
PollServiceHttpRequest wreq;
|
||||
// any entry in m_bycontext should have a active request on the other queues
|
||||
// so just delete contents to easy GC
|
||||
foreach (Queue<PollServiceHttpRequest> qu in m_bycontext.Values)
|
||||
qu.Clear();
|
||||
m_bycontext.Clear();
|
||||
|
||||
lock (m_longPollRequests)
|
||||
try
|
||||
{
|
||||
foreach (PollServiceHttpRequest req in m_retryRequests)
|
||||
{
|
||||
req.DoHTTPstop(m_server);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
PollServiceHttpRequest wreq;
|
||||
m_retryRequests.Clear();
|
||||
|
||||
lock (m_slowRequests)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if (m_longPollRequests.Count > 0 && IsRunning)
|
||||
m_longPollRequests.ForEach(req => m_requests.Enqueue(req));
|
||||
=======
|
||||
while (m_slowRequests.Count > 0)
|
||||
m_requests.Enqueue(m_slowRequests.Dequeue());
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
|
||||
while (m_requests.Count() > 0)
|
||||
|
@ -228,16 +355,19 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
try
|
||||
{
|
||||
wreq = m_requests.Dequeue(0);
|
||||
<<<<<<< HEAD
|
||||
ResponsesProcessed++;
|
||||
wreq.DoHTTPGruntWork(
|
||||
m_server, wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id));
|
||||
=======
|
||||
wreq.DoHTTPstop(m_server);
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
m_longPollRequests.Clear();
|
||||
m_requests.Clear();
|
||||
}
|
||||
|
||||
|
@ -247,6 +377,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
{
|
||||
while (IsRunning)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
PollServiceHttpRequest req = m_requests.Dequeue(5000);
|
||||
|
||||
>>>>>>> avn/ubitvar
|
||||
Watchdog.UpdateThread();
|
||||
WaitPerformResponse();
|
||||
}
|
||||
|
@ -265,6 +400,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
{
|
||||
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (responsedata == null)
|
||||
return;
|
||||
|
||||
|
@ -287,11 +423,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
else
|
||||
{
|
||||
m_threadPool.QueueWorkItem(x =>
|
||||
=======
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
|
||||
>>>>>>> avn/ubitvar
|
||||
{
|
||||
try
|
||||
{
|
||||
ResponsesProcessed++;
|
||||
req.DoHTTPGruntWork(m_server, responsedata);
|
||||
byContextDequeue(req);
|
||||
}
|
||||
catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream
|
||||
{
|
||||
|
@ -300,6 +440,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
m_log.Error(e);
|
||||
}
|
||||
|
||||
|
@ -318,6 +459,34 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
else
|
||||
{
|
||||
ReQueueEvent(req);
|
||||
=======
|
||||
try
|
||||
{
|
||||
req.DoHTTPGruntWork(m_server, responsedata);
|
||||
byContextDequeue(req);
|
||||
}
|
||||
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
|
||||
{
|
||||
// Ignore it, no need to reply
|
||||
}
|
||||
|
||||
return null;
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
|
||||
{
|
||||
req.DoHTTPGruntWork(m_server,
|
||||
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
|
||||
byContextDequeue(req);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReQueueEvent(req);
|
||||
}
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,5 +496,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -871,7 +871,7 @@ namespace OpenSim.Framework.Servers
|
|||
}
|
||||
}
|
||||
|
||||
protected string GetVersionText()
|
||||
public string GetVersionText()
|
||||
{
|
||||
return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,331 @@ namespace OpenSim.Framework.Servers.Tests
|
|||
{
|
||||
[TestFixture]
|
||||
public class OSHttpTests : OpenSimTestCase
|
||||
<<<<<<< HEAD
|
||||
{
|
||||
=======
|
||||
{
|
||||
// we need an IHttpClientContext for our tests
|
||||
public class TestHttpClientContext: IHttpClientContext
|
||||
{
|
||||
private bool _secured;
|
||||
public bool IsSecured
|
||||
{
|
||||
get { return _secured; }
|
||||
}
|
||||
public bool Secured
|
||||
{
|
||||
get { return _secured; }
|
||||
}
|
||||
|
||||
public TestHttpClientContext(bool secured)
|
||||
{
|
||||
_secured = secured;
|
||||
}
|
||||
|
||||
public void Disconnect(SocketError error) {}
|
||||
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body) {}
|
||||
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason) {}
|
||||
public void Respond(string body) {}
|
||||
public void Send(byte[] buffer) {}
|
||||
public void Send(byte[] buffer, int offset, int size) {}
|
||||
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body, string contentType) {}
|
||||
public void Close() { }
|
||||
public bool EndWhenDone { get { return false;} set { return;}}
|
||||
|
||||
public HTTPNetworkContext GiveMeTheNetworkStreamIKnowWhatImDoing()
|
||||
{
|
||||
return new HTTPNetworkContext();
|
||||
}
|
||||
|
||||
public event EventHandler<DisconnectedEventArgs> Disconnected = delegate { };
|
||||
/// <summary>
|
||||
/// A request have been received in the context.
|
||||
/// </summary>
|
||||
public event EventHandler<RequestEventArgs> RequestReceived = delegate { };
|
||||
|
||||
public bool CanSend { get { return true; } }
|
||||
public string RemoteEndPoint { get { return ""; } }
|
||||
public string RemoteEndPointAddress { get { return ""; } }
|
||||
public string RemoteEndPointPort { get { return ""; } }
|
||||
}
|
||||
|
||||
public class TestHttpRequest: IHttpRequest
|
||||
{
|
||||
private string _uriPath;
|
||||
public bool BodyIsComplete
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
public string[] AcceptTypes
|
||||
{
|
||||
get {return _acceptTypes; }
|
||||
}
|
||||
private string[] _acceptTypes;
|
||||
public Stream Body
|
||||
{
|
||||
get { return _body; }
|
||||
set { _body = value;}
|
||||
}
|
||||
private Stream _body;
|
||||
public ConnectionType Connection
|
||||
{
|
||||
get { return _connection; }
|
||||
set { _connection = value; }
|
||||
}
|
||||
private ConnectionType _connection;
|
||||
public int ContentLength
|
||||
{
|
||||
get { return _contentLength; }
|
||||
set { _contentLength = value; }
|
||||
}
|
||||
private int _contentLength;
|
||||
public NameValueCollection Headers
|
||||
{
|
||||
get { return _headers; }
|
||||
}
|
||||
private NameValueCollection _headers = new NameValueCollection();
|
||||
public string HttpVersion
|
||||
{
|
||||
get { return _httpVersion; }
|
||||
set { _httpVersion = value; }
|
||||
}
|
||||
private string _httpVersion = null;
|
||||
public string Method
|
||||
{
|
||||
get { return _method; }
|
||||
set { _method = value; }
|
||||
}
|
||||
private string _method = null;
|
||||
public HttpInput QueryString
|
||||
{
|
||||
get { return _queryString; }
|
||||
}
|
||||
private HttpInput _queryString = null;
|
||||
public Uri Uri
|
||||
{
|
||||
get { return _uri; }
|
||||
set { _uri = value; }
|
||||
}
|
||||
private Uri _uri = null;
|
||||
public string[] UriParts
|
||||
{
|
||||
get { return _uri.Segments; }
|
||||
}
|
||||
public HttpParam Param
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
public HttpForm Form
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
public bool IsAjax
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
public RequestCookies Cookies
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public TestHttpRequest() {}
|
||||
|
||||
public TestHttpRequest(string contentEncoding, string contentType, string userAgent,
|
||||
string remoteAddr, string remotePort, string[] acceptTypes,
|
||||
ConnectionType connectionType, int contentLength, Uri uri)
|
||||
{
|
||||
_headers["content-encoding"] = contentEncoding;
|
||||
_headers["content-type"] = contentType;
|
||||
_headers["user-agent"] = userAgent;
|
||||
_headers["remote_addr"] = remoteAddr;
|
||||
_headers["remote_port"] = remotePort;
|
||||
|
||||
_acceptTypes = acceptTypes;
|
||||
_connection = connectionType;
|
||||
_contentLength = contentLength;
|
||||
_uri = uri;
|
||||
}
|
||||
|
||||
public void DecodeBody(FormDecoderProvider providers) {}
|
||||
public void SetCookies(RequestCookies cookies) {}
|
||||
public void AddHeader(string name, string value)
|
||||
{
|
||||
_headers.Add(name, value);
|
||||
}
|
||||
public int AddToBody(byte[] bytes, int offset, int length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public void Clear() {}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
TestHttpRequest clone = new TestHttpRequest();
|
||||
clone._acceptTypes = _acceptTypes;
|
||||
clone._connection = _connection;
|
||||
clone._contentLength = _contentLength;
|
||||
clone._uri = _uri;
|
||||
clone._headers = new NameValueCollection(_headers);
|
||||
|
||||
return clone;
|
||||
}
|
||||
public IHttpResponse CreateResponse(IHttpClientContext context)
|
||||
{
|
||||
return new HttpResponse(context, this);
|
||||
}
|
||||
/// <summary>
|
||||
/// Path and query (will be merged with the host header) and put in Uri
|
||||
/// </summary>
|
||||
/// <see cref="Uri"/>
|
||||
public string UriPath
|
||||
{
|
||||
get { return _uriPath; }
|
||||
set
|
||||
{
|
||||
_uriPath = value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TestHttpResponse: IHttpResponse
|
||||
{
|
||||
public Stream Body
|
||||
{
|
||||
get { return _body; }
|
||||
|
||||
set { _body = value; }
|
||||
}
|
||||
private Stream _body;
|
||||
|
||||
public string ProtocolVersion
|
||||
{
|
||||
get { return _protocolVersion; }
|
||||
set { _protocolVersion = value; }
|
||||
}
|
||||
private string _protocolVersion;
|
||||
|
||||
public bool Chunked
|
||||
{
|
||||
get { return _chunked; }
|
||||
|
||||
set { _chunked = value; }
|
||||
}
|
||||
private bool _chunked;
|
||||
|
||||
public ConnectionType Connection
|
||||
{
|
||||
get { return _connection; }
|
||||
|
||||
set { _connection = value; }
|
||||
}
|
||||
private ConnectionType _connection;
|
||||
|
||||
public Encoding Encoding
|
||||
{
|
||||
get { return _encoding; }
|
||||
|
||||
set { _encoding = value; }
|
||||
}
|
||||
private Encoding _encoding;
|
||||
|
||||
public int KeepAlive
|
||||
{
|
||||
get { return _keepAlive; }
|
||||
|
||||
set { _keepAlive = value; }
|
||||
}
|
||||
private int _keepAlive;
|
||||
|
||||
public HttpStatusCode Status
|
||||
{
|
||||
get { return _status; }
|
||||
|
||||
set { _status = value; }
|
||||
}
|
||||
private HttpStatusCode _status;
|
||||
|
||||
public string Reason
|
||||
{
|
||||
get { return _reason; }
|
||||
|
||||
set { _reason = value; }
|
||||
}
|
||||
private string _reason;
|
||||
|
||||
public long ContentLength
|
||||
{
|
||||
get { return _contentLength; }
|
||||
|
||||
set { _contentLength = value; }
|
||||
}
|
||||
private long _contentLength;
|
||||
|
||||
public string ContentType
|
||||
{
|
||||
get { return _contentType; }
|
||||
|
||||
set { _contentType = value; }
|
||||
}
|
||||
private string _contentType;
|
||||
|
||||
public bool HeadersSent
|
||||
{
|
||||
get { return _headersSent; }
|
||||
}
|
||||
private bool _headersSent;
|
||||
|
||||
public bool Sent
|
||||
{
|
||||
get { return _sent; }
|
||||
}
|
||||
private bool _sent;
|
||||
|
||||
public ResponseCookies Cookies
|
||||
{
|
||||
get { return _cookies; }
|
||||
}
|
||||
private ResponseCookies _cookies = null;
|
||||
|
||||
public TestHttpResponse()
|
||||
{
|
||||
_headersSent = false;
|
||||
_sent = false;
|
||||
}
|
||||
|
||||
public void AddHeader(string name, string value) {}
|
||||
public void Send()
|
||||
{
|
||||
if (!_headersSent) SendHeaders();
|
||||
if (_sent) throw new InvalidOperationException("stuff already sent");
|
||||
_sent = true;
|
||||
}
|
||||
|
||||
public void SendBody(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (!_headersSent) SendHeaders();
|
||||
_sent = true;
|
||||
}
|
||||
public void SendBody(byte[] buffer)
|
||||
{
|
||||
if (!_headersSent) SendHeaders();
|
||||
_sent = true;
|
||||
}
|
||||
|
||||
public void SendHeaders()
|
||||
{
|
||||
if (_headersSent) throw new InvalidOperationException("headers already sent");
|
||||
_headersSent = true;
|
||||
}
|
||||
|
||||
public void Redirect(Uri uri) {}
|
||||
public void Redirect(string url) {}
|
||||
}
|
||||
|
||||
|
||||
>>>>>>> avn/ubitvar
|
||||
public OSHttpRequest req0;
|
||||
public OSHttpRequest req1;
|
||||
|
||||
|
|
|
@ -27,9 +27,13 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
|
@ -47,6 +51,180 @@ namespace OpenSim.Framework
|
|||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem));
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Thread LockedByThread;
|
||||
// private string WriterStack;
|
||||
|
||||
// private Dictionary<Thread, string> ReadLockers =
|
||||
// new Dictionary<Thread, string>();
|
||||
|
||||
/// <value>
|
||||
/// An advanced lock for inventory data
|
||||
/// </value>
|
||||
private volatile System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Are we readlocked by the calling thread?
|
||||
/// </summary>
|
||||
public bool IsReadLockedByMe()
|
||||
{
|
||||
if (m_itemLock.RecursiveReadCount > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lock our inventory list for reading (many can read, one can write)
|
||||
/// </summary>
|
||||
public void LockItemsForRead(bool locked)
|
||||
{
|
||||
if (locked)
|
||||
{
|
||||
if (m_itemLock.IsWriteLockHeld && LockedByThread != null)
|
||||
{
|
||||
if (!LockedByThread.IsAlive)
|
||||
{
|
||||
//Locked by dead thread, reset.
|
||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_itemLock.RecursiveReadCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||
try
|
||||
{
|
||||
// That call stack is useful for end users only. RealProgrammers need a full dump. Commented.
|
||||
// StackTrace stackTrace = new StackTrace(); // get call stack
|
||||
// StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||
//
|
||||
// // write call stack method names
|
||||
// foreach (StackFrame stackFrame in stackFrames)
|
||||
// {
|
||||
// m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name
|
||||
// }
|
||||
|
||||
// The below is far more useful
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
|
||||
// {
|
||||
// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// }
|
||||
}
|
||||
catch
|
||||
{}
|
||||
m_itemLock.ExitReadLock();
|
||||
}
|
||||
if (m_itemLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||
// try
|
||||
// {
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// }
|
||||
// catch
|
||||
// {}
|
||||
m_itemLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
while (!m_itemLock.TryEnterReadLock(60000))
|
||||
{
|
||||
m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
//if (m_itemLock.IsWriteLockHeld)
|
||||
//{
|
||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// LockedByThread = null;
|
||||
// ReadLockers.Clear();
|
||||
//}
|
||||
}
|
||||
// ReadLockers[Thread.CurrentThread] = Environment.StackTrace;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_itemLock.RecursiveReadCount>0)
|
||||
{
|
||||
m_itemLock.ExitReadLock();
|
||||
}
|
||||
// if (m_itemLock.RecursiveReadCount == 0)
|
||||
// ReadLockers.Remove(Thread.CurrentThread);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lock our inventory list for writing (many can read, one can write)
|
||||
/// </summary>
|
||||
public void LockItemsForWrite(bool locked)
|
||||
{
|
||||
if (locked)
|
||||
{
|
||||
//Enter a write lock, wait indefinately for one to open.
|
||||
if (m_itemLock.RecursiveReadCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||
m_itemLock.ExitReadLock();
|
||||
}
|
||||
if (m_itemLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||
|
||||
m_itemLock.ExitWriteLock();
|
||||
}
|
||||
while (!m_itemLock.TryEnterWriteLock(60000))
|
||||
{
|
||||
if (m_itemLock.IsWriteLockHeld)
|
||||
{
|
||||
m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
|
||||
// {
|
||||
// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
|
||||
// System.Console.WriteLine("------------------------------------------");
|
||||
// }
|
||||
}
|
||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
// ReadLockers.Clear();
|
||||
}
|
||||
|
||||
LockedByThread = Thread.CurrentThread;
|
||||
// WriterStack = Environment.StackTrace;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_itemLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_itemLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
|
@ -54,13 +232,12 @@ namespace OpenSim.Framework
|
|||
{
|
||||
TaskInventoryDictionary clone = new TaskInventoryDictionary();
|
||||
|
||||
lock (this)
|
||||
m_itemLock.EnterReadLock();
|
||||
foreach (UUID uuid in Keys)
|
||||
{
|
||||
foreach (UUID uuid in Keys)
|
||||
{
|
||||
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
|
||||
}
|
||||
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
|
||||
}
|
||||
m_itemLock.ExitReadLock();
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
|
||||
using OpenMetaverse;
|
||||
|
@ -48,6 +49,7 @@ namespace OpenSim.Framework
|
|||
|
||||
public abstract float this[int x, int y] { get; set; }
|
||||
// Someday terrain will have caves
|
||||
// at most holes :p
|
||||
public abstract float this[int x, int y, int z] { get; set; }
|
||||
|
||||
public abstract bool IsTaintedAt(int xx, int yy);
|
||||
|
@ -72,8 +74,8 @@ namespace OpenSim.Framework
|
|||
return new HeightmapTerrainData(pSizeX, pSizeY, pSizeZ, pFormatCode, pBlob);
|
||||
}
|
||||
|
||||
// return a special compressed representation of the heightmap in ints
|
||||
public abstract int[] GetCompressedMap();
|
||||
// return a special compressed representation of the heightmap in ushort
|
||||
public abstract float[] GetCompressedMap();
|
||||
public abstract float CompressionFactor { get; }
|
||||
|
||||
public abstract float[] GetFloatsSerialized();
|
||||
|
@ -94,14 +96,18 @@ namespace OpenSim.Framework
|
|||
{
|
||||
// Terrain is 'double[256,256]'
|
||||
Legacy256 = 11,
|
||||
|
||||
// Terrain is 'int32, int32, float[,]' where the ints are X and Y dimensions
|
||||
// The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
|
||||
Variable2D = 22,
|
||||
Variable2DGzip = 23,
|
||||
|
||||
// Terrain is 'int32, int32, int32, int16[]' where the ints are X and Y dimensions
|
||||
// and third int is the 'compression factor'. The heights are compressed as
|
||||
// "int compressedHeight = (int)(height * compressionFactor);"
|
||||
// "ushort compressedHeight = (ushort)(height * compressionFactor);"
|
||||
// The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
|
||||
Compressed2D = 27,
|
||||
|
||||
// A revision that is not listed above or any revision greater than this value is 'Legacy256'.
|
||||
RevisionHigh = 1234
|
||||
}
|
||||
|
@ -109,7 +115,7 @@ namespace OpenSim.Framework
|
|||
// Version of terrain that is a heightmap.
|
||||
// This should really be 'LLOptimizedHeightmapTerrainData' as it includes knowledge
|
||||
// of 'patches' which are 16x16 terrain areas which can be sent separately to the viewer.
|
||||
// The heighmap is kept as an array of integers. The integer values are converted to
|
||||
// The heighmap is kept as an array of ushorts. The ushort values are converted to
|
||||
// and from floats by TerrainCompressionFactor.
|
||||
public class HeightmapTerrainData : TerrainData
|
||||
{
|
||||
|
@ -119,12 +125,12 @@ namespace OpenSim.Framework
|
|||
// TerrainData.this[x, y]
|
||||
public override float this[int x, int y]
|
||||
{
|
||||
get { return FromCompressedHeight(m_heightmap[x, y]); }
|
||||
set {
|
||||
int newVal = ToCompressedHeight(value);
|
||||
if (m_heightmap[x, y] != newVal)
|
||||
get { return m_heightmap[x, y]; }
|
||||
set
|
||||
{
|
||||
if (m_heightmap[x, y] != value)
|
||||
{
|
||||
m_heightmap[x, y] = newVal;
|
||||
m_heightmap[x, y] = value;
|
||||
m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true;
|
||||
}
|
||||
}
|
||||
|
@ -164,10 +170,9 @@ namespace OpenSim.Framework
|
|||
// TerrainData.ClearLand(float)
|
||||
public override void ClearLand(float pHeight)
|
||||
{
|
||||
int flatHeight = ToCompressedHeight(pHeight);
|
||||
for (int xx = 0; xx < SizeX; xx++)
|
||||
for (int yy = 0; yy < SizeY; yy++)
|
||||
m_heightmap[xx, yy] = flatHeight;
|
||||
m_heightmap[xx, yy] = pHeight;
|
||||
}
|
||||
|
||||
// Return 'true' of the patch that contains these region coordinates has been modified.
|
||||
|
@ -177,13 +182,15 @@ namespace OpenSim.Framework
|
|||
{
|
||||
int tx = xx / Constants.TerrainPatchSize;
|
||||
int ty = yy / Constants.TerrainPatchSize;
|
||||
bool ret = m_taint[tx, ty];
|
||||
bool ret = m_taint[tx, ty];
|
||||
if (ret && clearOnTest)
|
||||
m_taint[tx, ty] = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Old form that clears the taint flag when we check it.
|
||||
// ubit: this dangerus naming should be only check without clear
|
||||
// keeping for old modules outthere
|
||||
public override bool IsTaintedAt(int xx, int yy)
|
||||
{
|
||||
return IsTaintedAt(xx, yy, true /* clearOnTest */);
|
||||
|
@ -202,8 +209,10 @@ namespace OpenSim.Framework
|
|||
}
|
||||
else
|
||||
{
|
||||
DBRevisionCode = (int)DBTerrainRevision.Compressed2D;
|
||||
blob = ToCompressedTerrainSerialization();
|
||||
DBRevisionCode = (int)DBTerrainRevision.Variable2DGzip;
|
||||
// DBRevisionCode = (int)DBTerrainRevision.Variable2D;
|
||||
blob = ToCompressedTerrainSerializationV2DGzip();
|
||||
// blob = ToCompressedTerrainSerializationV2D();
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
|
@ -214,9 +223,9 @@ namespace OpenSim.Framework
|
|||
public override float CompressionFactor { get { return m_compressionFactor; } }
|
||||
|
||||
// TerrainData.GetCompressedMap
|
||||
public override int[] GetCompressedMap()
|
||||
public override float[] GetCompressedMap()
|
||||
{
|
||||
int[] newMap = new int[SizeX * SizeY];
|
||||
float[] newMap = new float[SizeX * SizeY];
|
||||
|
||||
int ind = 0;
|
||||
for (int xx = 0; xx < SizeX; xx++)
|
||||
|
@ -230,7 +239,7 @@ namespace OpenSim.Framework
|
|||
public override TerrainData Clone()
|
||||
{
|
||||
HeightmapTerrainData ret = new HeightmapTerrainData(SizeX, SizeY, SizeZ);
|
||||
ret.m_heightmap = (int[,])this.m_heightmap.Clone();
|
||||
ret.m_heightmap = (float[,])this.m_heightmap.Clone();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -247,7 +256,7 @@ namespace OpenSim.Framework
|
|||
for (int jj = 0; jj < SizeY; jj++)
|
||||
for (int ii = 0; ii < SizeX; ii++)
|
||||
{
|
||||
heights[idx++] = FromCompressedHeight(m_heightmap[ii, jj]);
|
||||
heights[idx++] = m_heightmap[ii, jj];
|
||||
}
|
||||
|
||||
return heights;
|
||||
|
@ -259,7 +268,7 @@ namespace OpenSim.Framework
|
|||
double[,] ret = new double[SizeX, SizeY];
|
||||
for (int xx = 0; xx < SizeX; xx++)
|
||||
for (int yy = 0; yy < SizeY; yy++)
|
||||
ret[xx, yy] = FromCompressedHeight(m_heightmap[xx, yy]);
|
||||
ret[xx, yy] = (double)m_heightmap[xx, yy];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -267,19 +276,40 @@ namespace OpenSim.Framework
|
|||
|
||||
// =============================================================
|
||||
|
||||
private int[,] m_heightmap;
|
||||
private float[,] m_heightmap;
|
||||
// Remember subregions of the heightmap that has changed.
|
||||
private bool[,] m_taint;
|
||||
|
||||
// To save space (especially for large regions), keep the height as a short integer
|
||||
// that is coded as the float height times the compression factor (usually '100'
|
||||
// to make for two decimal points).
|
||||
public int ToCompressedHeight(double pHeight)
|
||||
public short ToCompressedHeightshort(float pHeight)
|
||||
{
|
||||
return (int)(pHeight * CompressionFactor);
|
||||
// clamp into valid range
|
||||
pHeight *= CompressionFactor;
|
||||
if (pHeight < short.MinValue)
|
||||
return short.MinValue;
|
||||
else if (pHeight > short.MaxValue)
|
||||
return short.MaxValue;
|
||||
return (short)pHeight;
|
||||
}
|
||||
|
||||
public float FromCompressedHeight(int pHeight)
|
||||
public ushort ToCompressedHeightushort(float pHeight)
|
||||
{
|
||||
// clamp into valid range
|
||||
pHeight *= CompressionFactor;
|
||||
if (pHeight < ushort.MinValue)
|
||||
return ushort.MinValue;
|
||||
else if (pHeight > ushort.MaxValue)
|
||||
return ushort.MaxValue;
|
||||
return (ushort)pHeight;
|
||||
}
|
||||
|
||||
public float FromCompressedHeight(short pHeight)
|
||||
{
|
||||
return ((float)pHeight) / CompressionFactor;
|
||||
}
|
||||
|
||||
public float FromCompressedHeight(ushort pHeight)
|
||||
{
|
||||
return ((float)pHeight) / CompressionFactor;
|
||||
}
|
||||
|
@ -293,12 +323,12 @@ namespace OpenSim.Framework
|
|||
SizeZ = (int)Constants.RegionHeight;
|
||||
m_compressionFactor = 100.0f;
|
||||
|
||||
m_heightmap = new int[SizeX, SizeY];
|
||||
m_heightmap = new float[SizeX, SizeY];
|
||||
for (int ii = 0; ii < SizeX; ii++)
|
||||
{
|
||||
for (int jj = 0; jj < SizeY; jj++)
|
||||
{
|
||||
m_heightmap[ii, jj] = ToCompressedHeight(pTerrain[ii, jj]);
|
||||
m_heightmap[ii, jj] = (float)pTerrain[ii, jj];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -315,14 +345,15 @@ namespace OpenSim.Framework
|
|||
SizeY = pY;
|
||||
SizeZ = pZ;
|
||||
m_compressionFactor = 100.0f;
|
||||
m_heightmap = new int[SizeX, SizeY];
|
||||
m_heightmap = new float[SizeX, SizeY];
|
||||
m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize];
|
||||
// m_log.DebugFormat("{0} new by dimensions. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ);
|
||||
ClearTaint();
|
||||
ClearLand(0f);
|
||||
}
|
||||
|
||||
public HeightmapTerrainData(int[] cmap, float pCompressionFactor, int pX, int pY, int pZ) : this(pX, pY, pZ)
|
||||
public HeightmapTerrainData(float[] cmap, float pCompressionFactor, int pX, int pY, int pZ)
|
||||
: this(pX, pY, pZ)
|
||||
{
|
||||
m_compressionFactor = pCompressionFactor;
|
||||
int ind = 0;
|
||||
|
@ -333,12 +364,22 @@ namespace OpenSim.Framework
|
|||
}
|
||||
|
||||
// Create a heighmap from a database blob
|
||||
public HeightmapTerrainData(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob) : this(pSizeX, pSizeY, pSizeZ)
|
||||
public HeightmapTerrainData(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob)
|
||||
: this(pSizeX, pSizeY, pSizeZ)
|
||||
{
|
||||
switch ((DBTerrainRevision)pFormatCode)
|
||||
{
|
||||
case DBTerrainRevision.Variable2DGzip:
|
||||
FromCompressedTerrainSerializationV2DGZip(pBlob);
|
||||
m_log.DebugFormat("{0} HeightmapTerrainData create from Variable2DGzip serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
|
||||
break;
|
||||
|
||||
case DBTerrainRevision.Variable2D:
|
||||
FromCompressedTerrainSerializationV2D(pBlob);
|
||||
m_log.DebugFormat("{0} HeightmapTerrainData create from Variable2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
|
||||
break;
|
||||
case DBTerrainRevision.Compressed2D:
|
||||
FromCompressedTerrainSerialization(pBlob);
|
||||
FromCompressedTerrainSerialization2D(pBlob);
|
||||
m_log.DebugFormat("{0} HeightmapTerrainData create from Compressed2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
|
||||
break;
|
||||
default:
|
||||
|
@ -373,50 +414,116 @@ namespace OpenSim.Framework
|
|||
return ret;
|
||||
}
|
||||
|
||||
// Just create an array of doubles. Presumes the caller implicitly knows the size.
|
||||
// Presumes the caller implicitly knows the size.
|
||||
public void FromLegacyTerrainSerialization(byte[] pBlob)
|
||||
{
|
||||
// In case database info doesn't match real terrain size, initialize the whole terrain.
|
||||
ClearLand();
|
||||
|
||||
using (MemoryStream mstr = new MemoryStream(pBlob))
|
||||
try
|
||||
{
|
||||
using (BinaryReader br = new BinaryReader(mstr))
|
||||
using (MemoryStream mstr = new MemoryStream(pBlob))
|
||||
{
|
||||
for (int xx = 0; xx < (int)Constants.RegionSize; xx++)
|
||||
using (BinaryReader br = new BinaryReader(mstr))
|
||||
{
|
||||
for (int yy = 0; yy < (int)Constants.RegionSize; yy++)
|
||||
for (int xx = 0; xx < (int)Constants.RegionSize; xx++)
|
||||
{
|
||||
float val = (float)br.ReadDouble();
|
||||
if (xx < SizeX && yy < SizeY)
|
||||
m_heightmap[xx, yy] = ToCompressedHeight(val);
|
||||
for (int yy = 0; yy < (int)Constants.RegionSize; yy++)
|
||||
{
|
||||
float val = (float)br.ReadDouble();
|
||||
|
||||
if (xx < SizeX && yy < SizeY)
|
||||
m_heightmap[xx, yy] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ClearTaint();
|
||||
}
|
||||
catch
|
||||
{
|
||||
ClearLand();
|
||||
}
|
||||
ClearTaint();
|
||||
}
|
||||
|
||||
// See the reader below.
|
||||
public Array ToCompressedTerrainSerialization()
|
||||
|
||||
// stores as variable2D
|
||||
// int32 sizeX
|
||||
// int32 sizeY
|
||||
// float[,] array
|
||||
|
||||
public Array ToCompressedTerrainSerializationV2D()
|
||||
{
|
||||
Array ret = null;
|
||||
using (MemoryStream str = new MemoryStream((3 * sizeof(Int32)) + (SizeX * SizeY * sizeof(Int16))))
|
||||
try
|
||||
{
|
||||
using (BinaryWriter bw = new BinaryWriter(str))
|
||||
using (MemoryStream str = new MemoryStream((2 * sizeof(Int32)) + (SizeX * SizeY * sizeof(float))))
|
||||
{
|
||||
bw.Write((Int32)DBTerrainRevision.Compressed2D);
|
||||
bw.Write((Int32)SizeX);
|
||||
bw.Write((Int32)SizeY);
|
||||
bw.Write((Int32)CompressionFactor);
|
||||
for (int yy = 0; yy < SizeY; yy++)
|
||||
for (int xx = 0; xx < SizeX; xx++)
|
||||
{
|
||||
bw.Write((Int16)m_heightmap[xx, yy]);
|
||||
}
|
||||
using (BinaryWriter bw = new BinaryWriter(str))
|
||||
{
|
||||
bw.Write((Int32)SizeX);
|
||||
bw.Write((Int32)SizeY);
|
||||
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);
|
||||
bw.Write(val);
|
||||
}
|
||||
}
|
||||
ret = str.ToArray();
|
||||
}
|
||||
ret = str.ToArray();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
m_log.DebugFormat("{0} V2D {1} bytes",
|
||||
LogHeader, ret.Length);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// as above with Gzip compression
|
||||
public Array ToCompressedTerrainSerializationV2DGzip()
|
||||
{
|
||||
Array ret = null;
|
||||
try
|
||||
{
|
||||
using (MemoryStream inp = new MemoryStream((2 * sizeof(Int32)) + (SizeX * SizeY * sizeof(float))))
|
||||
{
|
||||
using (BinaryWriter bw = new BinaryWriter(inp))
|
||||
{
|
||||
bw.Write((Int32)SizeX);
|
||||
bw.Write((Int32)SizeY);
|
||||
for (int yy = 0; yy < SizeY; yy++)
|
||||
for (int xx = 0; xx < SizeX; xx++)
|
||||
{
|
||||
bw.Write((float)m_heightmap[xx, yy]);
|
||||
}
|
||||
|
||||
bw.Flush();
|
||||
inp.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using (MemoryStream outputStream = new MemoryStream())
|
||||
{
|
||||
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress))
|
||||
{
|
||||
inp.CopyStream(compressionStream, int.MaxValue);
|
||||
compressionStream.Close();
|
||||
ret = outputStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
m_log.DebugFormat("{0} V2DGzip {1} bytes",
|
||||
LogHeader, ret.Length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -426,7 +533,7 @@ namespace OpenSim.Framework
|
|||
// the forth int is the compression factor for the following int16s
|
||||
// This is just sets heightmap info. The actual size of the region was set on this instance's
|
||||
// creation and any heights not initialized by theis blob are set to the default height.
|
||||
public void FromCompressedTerrainSerialization(byte[] pBlob)
|
||||
public void FromCompressedTerrainSerialization2D(byte[] pBlob)
|
||||
{
|
||||
Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor;
|
||||
|
||||
|
@ -448,7 +555,7 @@ namespace OpenSim.Framework
|
|||
{
|
||||
for (int xx = 0; xx < hmSizeX; xx++)
|
||||
{
|
||||
Int16 val = br.ReadInt16();
|
||||
float val = FromCompressedHeight(br.ReadInt16());
|
||||
if (xx < SizeX && yy < SizeY)
|
||||
m_heightmap[xx, yy] = val;
|
||||
}
|
||||
|
@ -456,9 +563,112 @@ namespace OpenSim.Framework
|
|||
}
|
||||
ClearTaint();
|
||||
|
||||
m_log.InfoFormat("{0} Read compressed 2d heightmap. Heightmap size=<{1},{2}>. Region size=<{3},{4}>. CompFact={5}",
|
||||
m_log.DebugFormat("{0} Read (compressed2D) heightmap. Heightmap size=<{1},{2}>. Region size=<{3},{4}>. CompFact={5}",
|
||||
LogHeader, hmSizeX, hmSizeY, SizeX, SizeY, hmCompressionFactor);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize heightmap from blob consisting of:
|
||||
// int32, int32, int32, float[]
|
||||
// where the first int32 is format code, next two int32s are the X and y of heightmap data
|
||||
// This is just sets heightmap info. The actual size of the region was set on this instance's
|
||||
// creation and any heights not initialized by theis blob are set to the default height.
|
||||
public void FromCompressedTerrainSerializationV2D(byte[] pBlob)
|
||||
{
|
||||
Int32 hmSizeX, hmSizeY;
|
||||
try
|
||||
{
|
||||
using (MemoryStream mstr = new MemoryStream(pBlob))
|
||||
{
|
||||
using (BinaryReader br = new BinaryReader(mstr))
|
||||
{
|
||||
hmSizeX = br.ReadInt32();
|
||||
hmSizeY = br.ReadInt32();
|
||||
|
||||
// In case database info doesn't match real terrain size, initialize the whole terrain.
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ClearTaint();
|
||||
m_log.ErrorFormat("{0} 2D error: {1} - terrain may be damaged",
|
||||
LogHeader, e.Message);
|
||||
return;
|
||||
}
|
||||
ClearTaint();
|
||||
|
||||
m_log.DebugFormat("{0} V2D Heightmap size=<{1},{2}>. Region size=<{3},{4}>",
|
||||
LogHeader, hmSizeX, hmSizeY, SizeX, SizeY);
|
||||
|
||||
}
|
||||
|
||||
// as above but Gzip compressed
|
||||
public void FromCompressedTerrainSerializationV2DGZip(byte[] pBlob)
|
||||
{
|
||||
m_log.InfoFormat("{0} VD2Gzip {1} bytes input",
|
||||
LogHeader, pBlob.Length);
|
||||
|
||||
Int32 hmSizeX, hmSizeY;
|
||||
|
||||
try
|
||||
{
|
||||
using (MemoryStream outputStream = new MemoryStream())
|
||||
{
|
||||
using (MemoryStream inputStream = new MemoryStream(pBlob))
|
||||
{
|
||||
using (GZipStream decompressionStream = new GZipStream(inputStream, CompressionMode.Decompress))
|
||||
{
|
||||
decompressionStream.Flush();
|
||||
decompressionStream.CopyTo(outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
outputStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using (BinaryReader br = new BinaryReader(outputStream))
|
||||
{
|
||||
hmSizeX = br.ReadInt32();
|
||||
hmSizeY = br.ReadInt32();
|
||||
|
||||
// In case database info doesn't match real terrain size, initialize the whole terrain.
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception e)
|
||||
{
|
||||
ClearTaint();
|
||||
m_log.ErrorFormat("{0} V2DGzip error: {1} - terrain may be damaged",
|
||||
LogHeader, e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
ClearTaint();
|
||||
m_log.DebugFormat("{0} V2DGzip. Heightmap size=<{1},{2}>. Region size=<{3},{4}>",
|
||||
LogHeader, hmSizeX, hmSizeY, SizeX, SizeY);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,12 +218,12 @@ namespace OpenSim.Framework.Tests
|
|||
BannedHostNameMask = string.Empty,
|
||||
BannedUserID = bannedUserId}
|
||||
);
|
||||
Assert.IsTrue(es.IsBanned(bannedUserId), "User Should be banned but is not.");
|
||||
Assert.IsFalse(es.IsBanned(UUID.Zero), "User Should not be banned but is.");
|
||||
Assert.IsTrue(es.IsBanned(bannedUserId, 32), "User Should be banned but is not.");
|
||||
Assert.IsFalse(es.IsBanned(UUID.Zero, 32), "User Should not be banned but is.");
|
||||
|
||||
es.RemoveBan(bannedUserId);
|
||||
|
||||
Assert.IsFalse(es.IsBanned(bannedUserId), "User Should not be banned but is.");
|
||||
Assert.IsFalse(es.IsBanned(bannedUserId, 32), "User Should not be banned but is.");
|
||||
|
||||
es.AddEstateManager(UUID.Zero);
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ namespace OpenSim.Framework
|
|||
Texture = 5,
|
||||
/// <summary>Non-texture assets</summary>
|
||||
Asset = 6,
|
||||
|
||||
HighPriority = 128,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
|
|
@ -160,7 +160,11 @@ namespace OpenSim.Framework
|
|||
public virtual ulong HomeRegion
|
||||
{
|
||||
get
|
||||
<<<<<<< HEAD
|
||||
{
|
||||
=======
|
||||
{
|
||||
>>>>>>> avn/ubitvar
|
||||
return Util.RegionWorldLocToHandle(Util.RegionToWorldLoc(m_homeRegionX), Util.RegionToWorldLoc(m_homeRegionY));
|
||||
// return Utils.UIntsToLong( m_homeRegionX * (uint)Constants.RegionSize, m_homeRegionY * (uint)Constants.RegionSize);
|
||||
}
|
||||
|
|
|
@ -92,14 +92,6 @@ namespace OpenSim.Framework
|
|||
public string Notes;
|
||||
}
|
||||
|
||||
public class UserPreferences
|
||||
{
|
||||
public UUID UserId;
|
||||
public bool IMViaEmail = false;
|
||||
public bool Visible = false;
|
||||
public string EMail = string.Empty;
|
||||
}
|
||||
|
||||
public class UserAccountProperties
|
||||
{
|
||||
public string EmailAddress = string.Empty;
|
||||
|
|
|
@ -61,6 +61,15 @@ namespace OpenSim.Framework
|
|||
public enum PermissionMask : uint
|
||||
{
|
||||
None = 0,
|
||||
|
||||
// folded perms
|
||||
foldedTransfer = 1,
|
||||
foldedModify = 1 << 1,
|
||||
foldedCopy = 1 << 2,
|
||||
|
||||
foldedMask = 0x07,
|
||||
|
||||
//
|
||||
Transfer = 1 << 13,
|
||||
Modify = 1 << 14,
|
||||
Copy = 1 << 15,
|
||||
|
@ -267,14 +276,12 @@ namespace OpenSim.Framework
|
|||
/// </summary>
|
||||
/// <param name="a">A 3d vector</param>
|
||||
/// <returns>A new vector which is normalized form of the vector</returns>
|
||||
/// <remarks>The vector paramater cannot be <0,0,0></remarks>
|
||||
|
||||
public static Vector3 GetNormalizedVector(Vector3 a)
|
||||
{
|
||||
if (IsZeroVector(a))
|
||||
throw new ArgumentException("Vector paramater cannot be a zero vector.");
|
||||
|
||||
float Mag = (float) GetMagnitude(a);
|
||||
return new Vector3(a.X / Mag, a.Y / Mag, a.Z / Mag);
|
||||
Vector3 v = new Vector3(a.X, a.Y, a.Z);
|
||||
v.Normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -641,19 +648,25 @@ namespace OpenSim.Framework
|
|||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static string Md5Hash(string data)
|
||||
{
|
||||
byte[] dataMd5 = ComputeMD5Hash(data);
|
||||
return Md5Hash(data, Encoding.Default);
|
||||
}
|
||||
|
||||
public static string Md5Hash(string data, Encoding encoding)
|
||||
{
|
||||
byte[] dataMd5 = ComputeMD5Hash(data, encoding);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < dataMd5.Length; i++)
|
||||
sb.AppendFormat("{0:x2}", dataMd5[i]);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static byte[] ComputeMD5Hash(string data)
|
||||
private static byte[] ComputeMD5Hash(string data, Encoding encoding)
|
||||
{
|
||||
MD5 md5 = MD5.Create();
|
||||
return md5.ComputeHash(Encoding.Default.GetBytes(data));
|
||||
return md5.ComputeHash(encoding.GetBytes(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -661,6 +674,12 @@ namespace OpenSim.Framework
|
|||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static string SHA1Hash(string data, Encoding enc)
|
||||
{
|
||||
return SHA1Hash(enc.GetBytes(data));
|
||||
}
|
||||
|
||||
public static string SHA1Hash(string data)
|
||||
{
|
||||
return SHA1Hash(Encoding.Default.GetBytes(data));
|
||||
|
@ -714,17 +733,26 @@ namespace OpenSim.Framework
|
|||
/// <param name="oldy">Old region y-coord</param>
|
||||
/// <param name="newy">New region y-coord</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy)
|
||||
public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy,
|
||||
int oldsizex, int oldsizey, int newsizex, int newsizey)
|
||||
{
|
||||
int dd = (int)((drawdist + Constants.RegionSize - 1) / Constants.RegionSize);
|
||||
// we still need to make sure we see new region 1stNeighbors
|
||||
|
||||
int startX = (int)oldx - dd;
|
||||
int startY = (int)oldy - dd;
|
||||
oldx *= Constants.RegionSize;
|
||||
newx *= Constants.RegionSize;
|
||||
if (oldx + oldsizex + drawdist < newx)
|
||||
return true;
|
||||
if (newx + newsizex + drawdist < oldx)
|
||||
return true;
|
||||
|
||||
int endX = (int)oldx + dd;
|
||||
int endY = (int)oldy + dd;
|
||||
oldy *= Constants.RegionSize;
|
||||
newy *= Constants.RegionSize;
|
||||
if (oldy + oldsizey + drawdist < newy)
|
||||
return true;
|
||||
if (newy + newsizey + drawdist< oldy)
|
||||
return true;
|
||||
|
||||
return (newx < startX || endX < newx || newy < startY || endY < newy);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string FieldToString(byte[] bytes)
|
||||
|
@ -804,6 +832,16 @@ namespace OpenSim.Framework
|
|||
return output.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a URL to a IPAddress
|
||||
/// </summary>
|
||||
/// <param name="url">URL Standard Format</param>
|
||||
/// <returns>A resolved IP Address</returns>
|
||||
public static IPAddress GetHostFromURL(string url)
|
||||
{
|
||||
return GetHostFromDNS(url.Split(new char[] {'/', ':'})[3]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a IP address from a specified DNS, favouring IPv4 addresses.
|
||||
/// </summary>
|
||||
|
@ -1065,6 +1103,25 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
|
||||
public static string GetConfigVarWithDefaultSection(IConfigSource config, string varname, string section)
|
||||
{
|
||||
// First, check the Startup section, the default section
|
||||
IConfig cnf = config.Configs["Startup"];
|
||||
if (cnf == null)
|
||||
return string.Empty;
|
||||
string val = cnf.GetString(varname, string.Empty);
|
||||
|
||||
// Then check for an overwrite of the default in the given section
|
||||
if (!string.IsNullOrEmpty(section))
|
||||
{
|
||||
cnf = config.Configs[section];
|
||||
if (cnf != null)
|
||||
val = cnf.GetString(varname, val);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a configuration variable by looking into
|
||||
/// multiple sections in order. The latter sections overwrite
|
||||
|
@ -1388,6 +1445,46 @@ namespace OpenSim.Framework
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static string Compress(string text)
|
||||
{
|
||||
byte[] buffer = Util.UTF8.GetBytes(text);
|
||||
MemoryStream memory = new MemoryStream();
|
||||
using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true))
|
||||
{
|
||||
compressor.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
memory.Position = 0;
|
||||
|
||||
byte[] compressed = new byte[memory.Length];
|
||||
memory.Read(compressed, 0, compressed.Length);
|
||||
|
||||
byte[] compressedBuffer = new byte[compressed.Length + 4];
|
||||
Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4);
|
||||
return Convert.ToBase64String(compressedBuffer);
|
||||
}
|
||||
|
||||
public static string Decompress(string compressedText)
|
||||
{
|
||||
byte[] compressedBuffer = Convert.FromBase64String(compressedText);
|
||||
using (MemoryStream memory = new MemoryStream())
|
||||
{
|
||||
int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
|
||||
memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
|
||||
|
||||
byte[] buffer = new byte[msgLength];
|
||||
|
||||
memory.Position = 0;
|
||||
using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress))
|
||||
{
|
||||
decompressor.Read(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
return Util.UTF8.GetString(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy data from one stream to another, leaving the read position of both streams at the beginning.
|
||||
/// </summary>
|
||||
|
@ -1524,19 +1621,19 @@ namespace OpenSim.Framework
|
|||
{
|
||||
string os = String.Empty;
|
||||
|
||||
if (Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
{
|
||||
os = Environment.OSVersion.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
os = ReadEtcIssue();
|
||||
}
|
||||
|
||||
if (os.Length > 45)
|
||||
{
|
||||
os = os.Substring(0, 45);
|
||||
}
|
||||
// if (Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
// {
|
||||
// os = Environment.OSVersion.ToString();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// os = ReadEtcIssue();
|
||||
// }
|
||||
//
|
||||
// if (os.Length > 45)
|
||||
// {
|
||||
// os = os.Substring(0, 45);
|
||||
// }
|
||||
|
||||
return os;
|
||||
}
|
||||
|
@ -1591,6 +1688,69 @@ namespace OpenSim.Framework
|
|||
return displayConnectionString;
|
||||
}
|
||||
|
||||
public static T ReadSettingsFromIniFile<T>(IConfig config, T settingsClass)
|
||||
{
|
||||
Type settingsType = settingsClass.GetType();
|
||||
|
||||
FieldInfo[] fieldInfos = settingsType.GetFields();
|
||||
foreach (FieldInfo fieldInfo in fieldInfos)
|
||||
{
|
||||
if (!fieldInfo.IsStatic)
|
||||
{
|
||||
if (fieldInfo.FieldType == typeof(System.String))
|
||||
{
|
||||
fieldInfo.SetValue(settingsClass, config.Get(fieldInfo.Name, (string)fieldInfo.GetValue(settingsClass)));
|
||||
}
|
||||
else if (fieldInfo.FieldType == typeof(System.Boolean))
|
||||
{
|
||||
fieldInfo.SetValue(settingsClass, config.GetBoolean(fieldInfo.Name, (bool)fieldInfo.GetValue(settingsClass)));
|
||||
}
|
||||
else if (fieldInfo.FieldType == typeof(System.Int32))
|
||||
{
|
||||
fieldInfo.SetValue(settingsClass, config.GetInt(fieldInfo.Name, (int)fieldInfo.GetValue(settingsClass)));
|
||||
}
|
||||
else if (fieldInfo.FieldType == typeof(System.Single))
|
||||
{
|
||||
fieldInfo.SetValue(settingsClass, config.GetFloat(fieldInfo.Name, (float)fieldInfo.GetValue(settingsClass)));
|
||||
}
|
||||
else if (fieldInfo.FieldType == typeof(System.UInt32))
|
||||
{
|
||||
fieldInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(fieldInfo.Name, ((uint)fieldInfo.GetValue(settingsClass)).ToString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropertyInfo[] propertyInfos = settingsType.GetProperties();
|
||||
foreach (PropertyInfo propInfo in propertyInfos)
|
||||
{
|
||||
if ((propInfo.CanRead) && (propInfo.CanWrite))
|
||||
{
|
||||
if (propInfo.PropertyType == typeof(System.String))
|
||||
{
|
||||
propInfo.SetValue(settingsClass, config.Get(propInfo.Name, (string)propInfo.GetValue(settingsClass, null)), null);
|
||||
}
|
||||
else if (propInfo.PropertyType == typeof(System.Boolean))
|
||||
{
|
||||
propInfo.SetValue(settingsClass, config.GetBoolean(propInfo.Name, (bool)propInfo.GetValue(settingsClass, null)), null);
|
||||
}
|
||||
else if (propInfo.PropertyType == typeof(System.Int32))
|
||||
{
|
||||
propInfo.SetValue(settingsClass, config.GetInt(propInfo.Name, (int)propInfo.GetValue(settingsClass, null)), null);
|
||||
}
|
||||
else if (propInfo.PropertyType == typeof(System.Single))
|
||||
{
|
||||
propInfo.SetValue(settingsClass, config.GetFloat(propInfo.Name, (float)propInfo.GetValue(settingsClass, null)), null);
|
||||
}
|
||||
if (propInfo.PropertyType == typeof(System.UInt32))
|
||||
{
|
||||
propInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(propInfo.Name, ((uint)propInfo.GetValue(settingsClass, null)).ToString())), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return settingsClass;
|
||||
}
|
||||
|
||||
public static string Base64ToString(string str)
|
||||
{
|
||||
Decoder utf8Decode = Encoding.UTF8.GetDecoder();
|
||||
|
@ -1645,7 +1805,7 @@ namespace OpenSim.Framework
|
|||
|
||||
public static Guid GetHashGuid(string data, string salt)
|
||||
{
|
||||
byte[] hash = ComputeMD5Hash(data + salt);
|
||||
byte[] hash = ComputeMD5Hash(data + salt, Encoding.Default);
|
||||
|
||||
//string s = BitConverter.ToString(hash);
|
||||
|
||||
|
@ -1792,6 +1952,32 @@ namespace OpenSim.Framework
|
|||
return found.ToArray();
|
||||
}
|
||||
|
||||
public static string ServerURI(string uri)
|
||||
{
|
||||
if (uri == string.Empty)
|
||||
return string.Empty;
|
||||
|
||||
// Get rid of eventual slashes at the end
|
||||
uri = uri.TrimEnd('/');
|
||||
|
||||
IPAddress ipaddr1 = null;
|
||||
string port1 = "";
|
||||
try
|
||||
{
|
||||
ipaddr1 = Util.GetHostFromURL(uri);
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
port1 = uri.Split(new char[] { ':' })[2];
|
||||
}
|
||||
catch { }
|
||||
|
||||
// We tried our best to convert the domain names to IP addresses
|
||||
return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
|
||||
/// </summary>
|
||||
|
@ -1970,6 +2156,11 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
|
||||
public static void FireAndForget(System.Threading.WaitCallback callback)
|
||||
{
|
||||
FireAndForget(callback, null);
|
||||
}
|
||||
|
||||
public static void InitThreadPool(int minThreads, int maxThreads)
|
||||
{
|
||||
if (maxThreads < 2)
|
||||
|
@ -1986,7 +2177,7 @@ namespace OpenSim.Framework
|
|||
|
||||
STPStartInfo startInfo = new STPStartInfo();
|
||||
startInfo.ThreadPoolName = "Util";
|
||||
startInfo.IdleTimeout = 2000;
|
||||
startInfo.IdleTimeout = 20000;
|
||||
startInfo.MaxWorkerThreads = maxThreads;
|
||||
startInfo.MinWorkerThreads = minThreads;
|
||||
|
||||
|
|
|
@ -29,7 +29,11 @@ namespace OpenSim
|
|||
{
|
||||
public class VersionInfo
|
||||
{
|
||||
<<<<<<< HEAD:OpenSim/Framework/VersionInfo.cs
|
||||
public const string VersionNumber = "0.8.2.0";
|
||||
=======
|
||||
private const string VERSION_NUMBER = "0.8.0CM";
|
||||
>>>>>>> avn/ubitvar:OpenSim/Framework/Servers/VersionInfo.cs
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
|
||||
|
||||
public enum Flavour
|
||||
|
@ -51,7 +55,7 @@ namespace OpenSim
|
|||
|
||||
public static string GetVersionString(string versionNumber, Flavour flavour)
|
||||
{
|
||||
string versionString = "OpenSim " + versionNumber + " " + flavour;
|
||||
string versionString = "Careminster " + versionNumber + " " + flavour;
|
||||
return versionString.PadRight(VERSIONINFO_VERSION_LENGTH);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,12 +43,13 @@ namespace OpenSim.Framework
|
|||
|
||||
public static WearableCacheItem[] GetDefaultCacheItem()
|
||||
{
|
||||
int itemmax = 21;
|
||||
int itemmax = AvatarAppearance.TEXTURE_COUNT;
|
||||
WearableCacheItem[] retitems = new WearableCacheItem[itemmax];
|
||||
for (uint i=0;i<itemmax;i++)
|
||||
retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i + 1};
|
||||
retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i};
|
||||
return retitems;
|
||||
}
|
||||
|
||||
public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache)
|
||||
{
|
||||
List<WearableCacheItem> ret = new List<WearableCacheItem>();
|
||||
|
@ -98,6 +99,7 @@ namespace OpenSim.Framework
|
|||
return ret.ToArray();
|
||||
|
||||
}
|
||||
|
||||
public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache)
|
||||
{
|
||||
OSDArray arr = new OSDArray();
|
||||
|
@ -124,6 +126,68 @@ namespace OpenSim.Framework
|
|||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static OSDArray BakedToOSD(WearableCacheItem[] pcacheItems)
|
||||
{
|
||||
if (pcacheItems.Length < AvatarAppearance.BAKE_INDICES[AvatarAppearance.BAKE_INDICES.Length - 1])
|
||||
return null;
|
||||
|
||||
OSDArray arr = new OSDArray();
|
||||
|
||||
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
|
||||
{
|
||||
int idx = AvatarAppearance.BAKE_INDICES[i];
|
||||
|
||||
WearableCacheItem item = pcacheItems[idx];
|
||||
|
||||
OSDMap itemmap = new OSDMap();
|
||||
itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex));
|
||||
itemmap.Add("cacheid", OSD.FromUUID(item.CacheId));
|
||||
itemmap.Add("textureid", OSD.FromUUID(item.TextureID));
|
||||
/*
|
||||
if (item.TextureAsset != null)
|
||||
{
|
||||
itemmap.Add("assetdata", OSD.FromBinary(item.TextureAsset.Data));
|
||||
itemmap.Add("assetcreator", OSD.FromString(item.TextureAsset.CreatorID));
|
||||
itemmap.Add("assetname", OSD.FromString(item.TextureAsset.Name));
|
||||
}
|
||||
*/
|
||||
arr.Add(itemmap);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static WearableCacheItem[] BakedFromOSD(OSD pInput)
|
||||
{
|
||||
WearableCacheItem[] pcache = WearableCacheItem.GetDefaultCacheItem();
|
||||
|
||||
if (pInput.Type == OSDType.Array)
|
||||
{
|
||||
OSDArray itemarray = (OSDArray)pInput;
|
||||
foreach (OSDMap item in itemarray)
|
||||
{
|
||||
int idx = (int)item["textureindex"].AsUInteger();
|
||||
if (idx < 0 || idx > pcache.Length)
|
||||
continue;
|
||||
pcache[idx].CacheId = item["cacheid"].AsUUID();
|
||||
pcache[idx].TextureID = item["textureid"].AsUUID();
|
||||
/*
|
||||
if (item.ContainsKey("assetdata"))
|
||||
{
|
||||
AssetBase asset = new AssetBase(item["textureid"].AsUUID(), "BakedTexture", (sbyte)AssetType.Texture, UUID.Zero.ToString());
|
||||
asset.Temporary = true;
|
||||
asset.Local = true;
|
||||
asset.Data = item["assetdata"].AsBinary();
|
||||
pcache[idx].TextureAsset = asset;
|
||||
}
|
||||
else
|
||||
*/
|
||||
pcache[idx].TextureAsset = null;
|
||||
}
|
||||
}
|
||||
return pcache;
|
||||
}
|
||||
|
||||
public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems)
|
||||
{
|
||||
for (int i = 0; i < pcacheItems.Length; i++)
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace OpenSim.Framework
|
|||
/// Number of milliseconds a call can take before it is considered
|
||||
/// a "long" call for warning & debugging purposes
|
||||
/// </summary>
|
||||
public const int LongCallTime = 3000;
|
||||
public const int LongCallTime = 500;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum length of any data logged because of a long request time.
|
||||
|
@ -205,8 +205,16 @@ namespace OpenSim.Framework
|
|||
{
|
||||
if (DebugLevel == 5)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if (output.Length > MaxRequestDiagLength)
|
||||
output = output.Substring(0, MaxRequestDiagLength) + "...";
|
||||
=======
|
||||
int len = output.Length;
|
||||
if(len > 80)
|
||||
len = 80;
|
||||
output = output.Substring(0, len);
|
||||
output = output + "...";
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[LOGHTTP]: {0}{1}", context, Util.BinaryToASCII(output));
|
||||
|
@ -233,6 +241,9 @@ namespace OpenSim.Framework
|
|||
string errorMessage = "unknown error";
|
||||
int tickstart = Util.EnvironmentTickCount();
|
||||
int tickdata = 0;
|
||||
int tickcompressdata = 0;
|
||||
int tickJsondata = 0;
|
||||
int compsize = 0;
|
||||
string strBuffer = null;
|
||||
|
||||
try
|
||||
|
@ -250,6 +261,8 @@ namespace OpenSim.Framework
|
|||
{
|
||||
strBuffer = OSDParser.SerializeJsonString(data);
|
||||
|
||||
tickJsondata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
|
||||
if (DebugLevel >= 5)
|
||||
LogOutgoingDetail("SEND", reqnum, strBuffer);
|
||||
|
||||
|
@ -271,13 +284,23 @@ namespace OpenSim.Framework
|
|||
// gets written on the stream upon Dispose()
|
||||
}
|
||||
byte[] buf = ms.ToArray();
|
||||
|
||||
tickcompressdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
|
||||
request.ContentLength = buf.Length; //Count bytes to send
|
||||
compsize = buf.Length;
|
||||
using (Stream requestStream = request.GetRequestStream())
|
||||
requestStream.Write(buf, 0, (int)buf.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
tickcompressdata = tickJsondata;
|
||||
compsize = buffer.Length;
|
||||
request.ContentType = "application/json";
|
||||
>>>>>>> avn/ubitvar
|
||||
request.ContentLength = buffer.Length; //Count bytes to send
|
||||
using (Stream requestStream = request.GetRequestStream())
|
||||
requestStream.Write(buffer, 0, buffer.Length); //Send it
|
||||
|
@ -292,6 +315,7 @@ namespace OpenSim.Framework
|
|||
{
|
||||
using (Stream responseStream = response.GetResponseStream())
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
using (StreamReader reader = new StreamReader(responseStream))
|
||||
{
|
||||
string responseStr = reader.ReadToEnd();
|
||||
|
@ -299,6 +323,12 @@ namespace OpenSim.Framework
|
|||
WebUtil.LogResponseDetail(reqnum, responseStr);
|
||||
return CanonicalizeResults(responseStr);
|
||||
}
|
||||
=======
|
||||
string responseStr = null;
|
||||
responseStr = responseStream.GetStreamString();
|
||||
//m_log.DebugFormat("[WEB UTIL]: <{0}> response is <{1}>",reqnum,responseStr);
|
||||
return CanonicalizeResults(responseStr);
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,6 +344,7 @@ namespace OpenSim.Framework
|
|||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = ex.Message;
|
||||
m_log.Debug("[WEB UTIL]: Exception making request: " + ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -321,8 +352,21 @@ namespace OpenSim.Framework
|
|||
if (tickdiff > LongCallTime)
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
<<<<<<< HEAD
|
||||
"[LOGHTTP]: Slow JSON-RPC request {0} {1} to {2} took {3}ms, {4}ms writing, {5}",
|
||||
reqnum, method, url, tickdiff, tickdata,
|
||||
=======
|
||||
"[WEB UTIL]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing({5} at Json; {6} at comp), {7} bytes ({8} uncomp): {9}",
|
||||
reqnum,
|
||||
method,
|
||||
url,
|
||||
tickdiff,
|
||||
tickdata,
|
||||
tickJsondata,
|
||||
tickcompressdata,
|
||||
compsize,
|
||||
strBuffer != null ? strBuffer.Length : 0,
|
||||
>>>>>>> avn/ubitvar
|
||||
strBuffer != null
|
||||
? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
|
||||
: "");
|
||||
|
@ -396,7 +440,7 @@ namespace OpenSim.Framework
|
|||
/// </summary>
|
||||
public static OSDMap PostToService(string url, NameValueCollection data)
|
||||
{
|
||||
return ServiceFormRequest(url,data,10000);
|
||||
return ServiceFormRequest(url,data, 20000);
|
||||
}
|
||||
|
||||
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
|
||||
|
@ -790,7 +834,8 @@ namespace OpenSim.Framework
|
|||
reqnum, verb, requestUrl);
|
||||
|
||||
int tickstart = Util.EnvironmentTickCount();
|
||||
int tickdata = 0;
|
||||
// int tickdata = 0;
|
||||
int tickdiff = 0;
|
||||
|
||||
Type type = typeof(TRequest);
|
||||
|
||||
|
@ -831,10 +876,17 @@ namespace OpenSim.Framework
|
|||
request.ContentLength = length;
|
||||
byte[] data = buffer.ToArray();
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (WebUtil.DebugLevel >= 5)
|
||||
WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
|
||||
|
||||
request.BeginGetRequestStream(delegate(IAsyncResult res)
|
||||
=======
|
||||
// capture how much time was spent writing
|
||||
// useless in this async
|
||||
// tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
request.BeginGetResponse(delegate(IAsyncResult ar)
|
||||
>>>>>>> avn/ubitvar
|
||||
{
|
||||
using (Stream requestStream = request.EndGetRequestStream(res))
|
||||
requestStream.Write(data, 0, length);
|
||||
|
@ -844,6 +896,7 @@ namespace OpenSim.Framework
|
|||
|
||||
request.BeginGetResponse(delegate(IAsyncResult ar)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
using (WebResponse response = request.EndGetResponse(ar))
|
||||
{
|
||||
try
|
||||
|
@ -858,6 +911,14 @@ namespace OpenSim.Framework
|
|||
{
|
||||
}
|
||||
}
|
||||
=======
|
||||
// Let's not close this
|
||||
// yes do close it
|
||||
buffer.Close();
|
||||
respStream.Close();
|
||||
response.Close();
|
||||
}
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
action(deserial);
|
||||
|
||||
|
@ -919,6 +980,7 @@ namespace OpenSim.Framework
|
|||
"[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
|
||||
verb, requestUrl, e.Message, e.StackTrace);
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
|
||||
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
|
||||
|
||||
|
@ -942,12 +1004,36 @@ namespace OpenSim.Framework
|
|||
string originalRequest = null;
|
||||
|
||||
if (buffer != null)
|
||||
=======
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
|
||||
verb, requestUrl, e.Message, e.StackTrace);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
|
||||
try
|
||||
{
|
||||
action(deserial);
|
||||
}
|
||||
catch (Exception e)
|
||||
>>>>>>> avn/ubitvar
|
||||
{
|
||||
originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
|
||||
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
|
||||
}
|
||||
=======
|
||||
tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
if (tickdiff > WebUtil.LongCallTime)
|
||||
{
|
||||
/*
|
||||
string originalRequest = null;
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[LOGHTTP]: Slow AsynchronousRequestObject request {0} {1} to {2} took {3}ms, {4}ms writing, {5}",
|
||||
|
@ -959,11 +1045,36 @@ namespace OpenSim.Framework
|
|||
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing",
|
||||
reqnum, tickdiff, tickdata);
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (buffer != null)
|
||||
buffer.Dispose();
|
||||
=======
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[ASYNC REQUEST]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||
reqnum,
|
||||
verb,
|
||||
requestUrl,
|
||||
tickdiff,
|
||||
tickdata,
|
||||
originalRequest);
|
||||
*/
|
||||
m_log.InfoFormat(
|
||||
"[ASYNC REQUEST]: Slow WebRequest SETUP <{0}> {1} {2} took {3}ms",
|
||||
reqnum,
|
||||
verb,
|
||||
requestUrl,
|
||||
tickdiff);
|
||||
}
|
||||
else if (WebUtil.DebugLevel >= 4)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[WEB UTIL]: HTTP OUT {0} took {1}ms",
|
||||
reqnum, tickdiff);
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1004,6 +1115,8 @@ namespace OpenSim.Framework
|
|||
|
||||
string respstring = String.Empty;
|
||||
|
||||
int tickset = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
|
||||
using (MemoryStream buffer = new MemoryStream())
|
||||
{
|
||||
if ((verb == "POST") || (verb == "PUT"))
|
||||
|
@ -1015,14 +1128,19 @@ namespace OpenSim.Framework
|
|||
{
|
||||
writer.Write(obj);
|
||||
writer.Flush();
|
||||
if (WebUtil.DebugLevel >= 5)
|
||||
WebUtil.LogOutgoingDetail(buffer);
|
||||
}
|
||||
|
||||
length = (int)obj.Length;
|
||||
request.ContentLength = length;
|
||||
byte[] data = buffer.ToArray();
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (WebUtil.DebugLevel >= 5)
|
||||
WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
|
||||
=======
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
Stream requestStream = null;
|
||||
try
|
||||
|
@ -1070,8 +1188,18 @@ namespace OpenSim.Framework
|
|||
if (tickdiff > WebUtil.LongCallTime)
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
<<<<<<< HEAD
|
||||
"[LOGHTTP]: Slow SynchronousRestForms request {0} {1} to {2} took {3}ms, {4}ms writing, {5}",
|
||||
reqnum, verb, requestUrl, tickdiff, tickdata,
|
||||
=======
|
||||
"[FORMS]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||
reqnum,
|
||||
verb,
|
||||
requestUrl,
|
||||
tickdiff,
|
||||
tickset,
|
||||
tickdata,
|
||||
>>>>>>> avn/ubitvar
|
||||
obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
|
||||
}
|
||||
else if (WebUtil.DebugLevel >= 4)
|
||||
|
@ -1208,6 +1336,8 @@ namespace OpenSim.Framework
|
|||
ht.ServicePoint.ConnectionLimit = maxConnections;
|
||||
|
||||
request.Method = verb;
|
||||
if (pTimeout != 0)
|
||||
request.Timeout = pTimeout * 1000;
|
||||
MemoryStream buffer = null;
|
||||
|
||||
try
|
||||
|
@ -1221,17 +1351,29 @@ namespace OpenSim.Framework
|
|||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
<<<<<<< HEAD
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, obj);
|
||||
writer.Flush();
|
||||
}
|
||||
=======
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, obj);
|
||||
writer.Flush();
|
||||
if (WebUtil.DebugLevel >= 5)
|
||||
WebUtil.LogOutgoingDetail(buffer);
|
||||
}
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
int length = (int)buffer.Length;
|
||||
request.ContentLength = length;
|
||||
byte[] data = buffer.ToArray();
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (WebUtil.DebugLevel >= 5)
|
||||
WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
|
||||
|
||||
|
@ -1255,6 +1397,9 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
|
||||
=======
|
||||
Stream requestStream = null;
|
||||
>>>>>>> avn/ubitvar
|
||||
try
|
||||
{
|
||||
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
|
||||
|
|
|
@ -75,6 +75,7 @@ namespace OpenSim
|
|||
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
|
||||
|
||||
ServicePointManager.DefaultConnectionLimit = 12;
|
||||
ServicePointManager.UseNagleAlgorithm = false;
|
||||
|
||||
// Add the arguments supplied when running the application to the configuration
|
||||
ArgvConfigSource configSource = new ArgvConfigSource(args);
|
||||
|
|
|
@ -109,13 +109,19 @@ namespace OpenSim
|
|||
m_timeInterval = startupConfig.GetInt("timer_Interval", 1200);
|
||||
}
|
||||
|
||||
AvatarWearable.MAX_WEARABLES = startupConfig.GetInt("max_wearables", AvatarWearable.MAX_WEARABLES);
|
||||
string asyncCallMethodStr = startupConfig.GetString("async_call_method", String.Empty);
|
||||
FireAndForgetMethod asyncCallMethod;
|
||||
if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod))
|
||||
Util.FireAndForgetMethod = asyncCallMethod;
|
||||
|
||||
<<<<<<< HEAD
|
||||
stpMinThreads = startupConfig.GetInt("MinPoolThreads", 15);
|
||||
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 300);
|
||||
=======
|
||||
stpMinThreads = startupConfig.GetInt("MinPoolThreads", 2 );
|
||||
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 25);
|
||||
>>>>>>> avn/ubitvar
|
||||
m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
|
||||
}
|
||||
|
||||
|
@ -267,12 +273,20 @@ namespace OpenSim
|
|||
SavePrimsXml2);
|
||||
|
||||
m_console.Commands.AddCommand("Archiving", false, "load oar",
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
>>>>>>> avn/ubitvar
|
||||
"load oar [--merge] [--skip-assets]"
|
||||
+ " [--default-user \"User Name\"]"
|
||||
+ " [--force-terrain] [--force-parcels]"
|
||||
+ " [--no-objects]"
|
||||
+ " [--rotation degrees] [--rotation-center \"<x,y,z>\"]"
|
||||
<<<<<<< HEAD
|
||||
+ " [--displacement \"<x,y,z>\"]"
|
||||
=======
|
||||
+ " [--displacement \"<x,y,z>\"]"
|
||||
>>>>>>> avn/ubitvar
|
||||
+ " [<OAR path>]",
|
||||
"Load a region's data from an OAR archive.",
|
||||
"--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading).\n"
|
||||
|
@ -500,7 +514,7 @@ namespace OpenSim
|
|||
if (alert != null)
|
||||
presence.ControllingClient.Kick(alert);
|
||||
else
|
||||
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
|
||||
presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
|
||||
|
||||
presence.Scene.CloseAgent(presence.UUID, force);
|
||||
break;
|
||||
|
@ -1028,15 +1042,25 @@ namespace OpenSim
|
|||
cdt.AddColumn("Circuit code", 12);
|
||||
cdt.AddColumn("Endpoint", 23);
|
||||
cdt.AddColumn("Active?", 7);
|
||||
cdt.AddColumn("ChildAgent?", 7);
|
||||
cdt.AddColumn("ping(ms)", 8);
|
||||
|
||||
SceneManager.ForEachScene(
|
||||
s => s.ForEachClient(
|
||||
c => cdt.AddRow(
|
||||
s.Name,
|
||||
c.Name,
|
||||
c.CircuitCode.ToString(),
|
||||
c.RemoteEndPoint.ToString(),
|
||||
c.IsActive.ToString())));
|
||||
c =>
|
||||
{
|
||||
bool child = false;
|
||||
if(c.SceneAgent != null && c.SceneAgent.IsChildAgent)
|
||||
child = true;
|
||||
cdt.AddRow(
|
||||
s.Name,
|
||||
c.Name,
|
||||
c.CircuitCode.ToString(),
|
||||
c.RemoteEndPoint.ToString(),
|
||||
c.IsActive.ToString(),
|
||||
child.ToString(),
|
||||
c.PingTimeMS);
|
||||
}));
|
||||
|
||||
MainConsole.Instance.Output(cdt.ToString());
|
||||
}
|
||||
|
|
|
@ -112,6 +112,10 @@ namespace OpenSim
|
|||
|
||||
public List<IApplicationPlugin> m_plugins = new List<IApplicationPlugin>();
|
||||
|
||||
private List<string> m_permsModules;
|
||||
|
||||
private bool m_securePermissionsLoading = true;
|
||||
|
||||
/// <value>
|
||||
/// The config information passed into the OpenSimulator region server.
|
||||
/// </value>
|
||||
|
@ -228,6 +232,14 @@ namespace OpenSim
|
|||
CreatePIDFile(pidFile);
|
||||
|
||||
userStatsURI = startupConfig.GetString("Stats_URI", String.Empty);
|
||||
|
||||
m_securePermissionsLoading = startupConfig.GetBoolean("SecurePermissionsLoading", true);
|
||||
|
||||
string permissionModules = Util.GetConfigVarFromSections<string>(Config, "permissionmodules",
|
||||
new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule");
|
||||
|
||||
m_permsModules = new List<string>(permissionModules.Split(','));
|
||||
|
||||
managedStatsURI = startupConfig.GetString("ManagedStatsRemoteFetchURI", String.Empty);
|
||||
}
|
||||
|
||||
|
@ -264,11 +276,21 @@ namespace OpenSim
|
|||
|
||||
base.StartupSpecific();
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (EnableInitialPluginLoad)
|
||||
LoadPlugins();
|
||||
|
||||
// We still want to post initalize any plugins even if loading has been disabled since a test may have
|
||||
// inserted them manually.
|
||||
=======
|
||||
LoadPlugins();
|
||||
|
||||
if (m_plugins.Count == 0) // We failed to load any modules. Mono Addins glitch!
|
||||
{
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
>>>>>>> avn/ubitvar
|
||||
foreach (IApplicationPlugin plugin in m_plugins)
|
||||
plugin.PostInitialise();
|
||||
|
||||
|
@ -290,10 +312,10 @@ namespace OpenSim
|
|||
"help " + capitalizedTopic,
|
||||
"Get help on plugin command '" + topic + "'",
|
||||
HandleCommanderHelp);
|
||||
console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
|
||||
"help " + capitalizedTopic,
|
||||
"Get help on plugin command '" + topic + "'",
|
||||
HandleCommanderHelp);
|
||||
// console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
|
||||
// "help " + capitalizedTopic,
|
||||
// "Get help on plugin command '" + topic + "'",
|
||||
// HandleCommanderHelp);
|
||||
|
||||
ICommander commander = null;
|
||||
|
||||
|
@ -420,7 +442,32 @@ namespace OpenSim
|
|||
}
|
||||
else m_log.Error("[REGIONMODULES]: The new RegionModulesController is missing...");
|
||||
|
||||
if (m_securePermissionsLoading)
|
||||
{
|
||||
foreach (string s in m_permsModules)
|
||||
{
|
||||
if (!scene.RegionModules.ContainsKey(s))
|
||||
{
|
||||
m_log.Fatal("[MODULES]: Required module " + s + " not found.");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[SCENE]: Secure permissions loading enabled, modules loaded: {0}", String.Join(" ", m_permsModules.ToArray()));
|
||||
}
|
||||
|
||||
scene.SetModuleInterfaces();
|
||||
// First Step of bootreport sequence
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.ColdStart(1,scene);
|
||||
scene.SnmpService.LinkDown(scene);
|
||||
}
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("Loading prins", scene);
|
||||
}
|
||||
|
||||
while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
|
||||
SetUpEstateOwner(scene);
|
||||
|
@ -434,6 +481,11 @@ namespace OpenSim
|
|||
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
|
||||
scene.EventManager.TriggerParcelPrimCountUpdate();
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("Grid Registration in progress", scene);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
scene.RegisterRegionWithGrid();
|
||||
|
@ -444,15 +496,29 @@ namespace OpenSim
|
|||
"[STARTUP]: Registration of region with grid failed, aborting startup due to {0} {1}",
|
||||
e.Message, e.StackTrace);
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.Critical("Grid registration failed. Startup aborted.", scene);
|
||||
}
|
||||
// Carrying on now causes a lot of confusion down the
|
||||
// line - we need to get the user's attention
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("Grid Registration done", scene);
|
||||
}
|
||||
|
||||
// We need to do this after we've initialized the
|
||||
// scripting engines.
|
||||
scene.CreateScriptInstances();
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("ScriptEngine started", scene);
|
||||
}
|
||||
|
||||
SceneManager.Add(scene);
|
||||
|
||||
if (m_autoCreateClientStack)
|
||||
|
@ -464,10 +530,20 @@ namespace OpenSim
|
|||
}
|
||||
}
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("Initializing region modules", scene);
|
||||
}
|
||||
scene.EventManager.OnShutdown += delegate() { ShutdownRegion(scene); };
|
||||
|
||||
mscene = scene;
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("The region is operational", scene);
|
||||
scene.SnmpService.LinkUp(scene);
|
||||
}
|
||||
|
||||
return clientServers;
|
||||
}
|
||||
|
||||
|
@ -583,6 +659,11 @@ namespace OpenSim
|
|||
private void ShutdownRegion(Scene scene)
|
||||
{
|
||||
m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName);
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("The region is shutting down", scene);
|
||||
scene.SnmpService.LinkDown(scene);
|
||||
}
|
||||
IRegionModulesController controller;
|
||||
if (ApplicationRegistry.TryGet<IRegionModulesController>(out controller))
|
||||
{
|
||||
|
@ -751,7 +832,10 @@ namespace OpenSim
|
|||
{
|
||||
Vector3 regionExtent = new Vector3(regionInfo.RegionSizeX, regionInfo.RegionSizeY, regionInfo.RegionSizeZ);
|
||||
PhysicsScene physicsScene = GetPhysicsScene(regionInfo.RegionName, regionExtent);
|
||||
<<<<<<< HEAD
|
||||
|
||||
=======
|
||||
>>>>>>> avn/ubitvar
|
||||
SceneCommunicationService sceneGridService = new SceneCommunicationService();
|
||||
|
||||
return new Scene(
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,703 @@
|
|||
// Proprietary code of Avination Virtual Limited
|
||||
// (c) 2012 Melanie Thielker, Leal Duarte
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
|
||||
using ComponentAce.Compression.Libs.zlib;
|
||||
|
||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
public struct ModelPrimLimits
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class ModelCost
|
||||
{
|
||||
|
||||
// upload fee defaults
|
||||
// fees are normalized to 1.0
|
||||
// this parameters scale them to basic cost ( so 1.0 translates to 10 )
|
||||
|
||||
public float ModelMeshCostFactor = 0.0f; // scale total cost relative to basic (excluding textures)
|
||||
public float ModelTextureCostFactor = 1.0f; // scale textures fee to basic.
|
||||
public float ModelMinCostFactor = 0.0f; // 0.5f; // minimum total model free excluding textures
|
||||
|
||||
// itens costs in normalized values
|
||||
// ie will be multiplied by basicCost and factors above
|
||||
public float primCreationCost = 0.002f; // extra cost for each prim creation overhead
|
||||
// weigthed size to normalized cost
|
||||
public float bytecost = 1e-5f;
|
||||
|
||||
// mesh upload fees based on compressed data sizes
|
||||
// several data sections are counted more that once
|
||||
// to promote user optimization
|
||||
// following parameters control how many extra times they are added
|
||||
// to global size.
|
||||
// LOD meshs
|
||||
const float medSizeWth = 1f; // 2x
|
||||
const float lowSizeWth = 1.5f; // 2.5x
|
||||
const float lowestSizeWth = 2f; // 3x
|
||||
// favor potencially physical optimized meshs versus automatic decomposition
|
||||
const float physMeshSizeWth = 6f; // counts 7x
|
||||
const float physHullSizeWth = 8f; // counts 9x
|
||||
|
||||
// stream cost area factors
|
||||
// more or less like SL
|
||||
const float highLodFactor = 17.36f;
|
||||
const float midLodFactor = 277.78f;
|
||||
const float lowLodFactor = 1111.11f;
|
||||
|
||||
// physics cost is below, identical to SL, assuming shape type convex
|
||||
// server cost is below identical to SL assuming non scripted non physical object
|
||||
|
||||
// internal
|
||||
const int bytesPerCoord = 6; // 3 coords, 2 bytes per each
|
||||
|
||||
// control prims dimensions
|
||||
public float PrimScaleMin = 0.001f;
|
||||
public float NonPhysicalPrimScaleMax = 256f;
|
||||
public float PhysicalPrimScaleMax = 10f;
|
||||
public int ObjectLinkedPartsMax = 512;
|
||||
|
||||
// storage for a single mesh asset cost parameters
|
||||
private class ameshCostParam
|
||||
{
|
||||
// LOD sizes for size dependent streaming cost
|
||||
public int highLODSize;
|
||||
public int medLODSize;
|
||||
public int lowLODSize;
|
||||
public int lowestLODSize;
|
||||
// normalized fee based on compressed data sizes
|
||||
public float costFee;
|
||||
// physics cost
|
||||
public float physicsCost;
|
||||
}
|
||||
|
||||
// calculates a mesh model costs
|
||||
// returns false on error, with a reason on parameter error
|
||||
// resources input LLSD request
|
||||
// basicCost input region assets upload cost
|
||||
// totalcost returns model total upload fee
|
||||
// meshcostdata returns detailed costs for viewer
|
||||
// avatarSkeleton if mesh includes a avatar skeleton
|
||||
// useAvatarCollider if we should use physics mesh for avatar
|
||||
public bool MeshModelCost(LLSDAssetResource resources, int basicCost, out int totalcost,
|
||||
LLSDAssetUploadResponseData meshcostdata, out string error, ref string warning)
|
||||
{
|
||||
totalcost = 0;
|
||||
error = string.Empty;
|
||||
|
||||
bool avatarSkeleton = false;
|
||||
|
||||
if (resources == null ||
|
||||
resources.instance_list == null ||
|
||||
resources.instance_list.Array.Count == 0)
|
||||
{
|
||||
error = "missing model information.";
|
||||
return false;
|
||||
}
|
||||
|
||||
int numberInstances = resources.instance_list.Array.Count;
|
||||
|
||||
if( numberInstances > ObjectLinkedPartsMax )
|
||||
{
|
||||
error = "Model whould have more than " + ObjectLinkedPartsMax.ToString() + " linked prims";
|
||||
return false;
|
||||
}
|
||||
|
||||
meshcostdata.model_streaming_cost = 0.0;
|
||||
meshcostdata.simulation_cost = 0.0;
|
||||
meshcostdata.physics_cost = 0.0;
|
||||
meshcostdata.resource_cost = 0.0;
|
||||
|
||||
meshcostdata.upload_price_breakdown.mesh_instance = 0;
|
||||
meshcostdata.upload_price_breakdown.mesh_physics = 0;
|
||||
meshcostdata.upload_price_breakdown.mesh_streaming = 0;
|
||||
meshcostdata.upload_price_breakdown.model = 0;
|
||||
|
||||
int itmp;
|
||||
|
||||
// textures cost
|
||||
if (resources.texture_list != null && resources.texture_list.Array.Count > 0)
|
||||
{
|
||||
float textures_cost = (float)(resources.texture_list.Array.Count * basicCost);
|
||||
textures_cost *= ModelTextureCostFactor;
|
||||
|
||||
itmp = (int)(textures_cost + 0.5f); // round
|
||||
meshcostdata.upload_price_breakdown.texture = itmp;
|
||||
totalcost += itmp;
|
||||
}
|
||||
|
||||
// meshs assets cost
|
||||
float meshsfee = 0;
|
||||
int numberMeshs = 0;
|
||||
bool haveMeshs = false;
|
||||
|
||||
bool curskeleton;
|
||||
bool curAvatarPhys;
|
||||
|
||||
List<ameshCostParam> meshsCosts = new List<ameshCostParam>();
|
||||
|
||||
if (resources.mesh_list != null && resources.mesh_list.Array.Count > 0)
|
||||
{
|
||||
numberMeshs = resources.mesh_list.Array.Count;
|
||||
|
||||
for (int i = 0; i < numberMeshs; i++)
|
||||
{
|
||||
ameshCostParam curCost = new ameshCostParam();
|
||||
byte[] data = (byte[])resources.mesh_list.Array[i];
|
||||
|
||||
if (!MeshCost(data, curCost,out curskeleton, out curAvatarPhys, out error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curskeleton)
|
||||
{
|
||||
if (avatarSkeleton)
|
||||
{
|
||||
error = "model can only contain a avatar skeleton";
|
||||
return false;
|
||||
}
|
||||
avatarSkeleton = true;
|
||||
}
|
||||
meshsCosts.Add(curCost);
|
||||
meshsfee += curCost.costFee;
|
||||
}
|
||||
haveMeshs = true;
|
||||
}
|
||||
|
||||
// instances (prims) cost
|
||||
|
||||
|
||||
int mesh;
|
||||
int skipedSmall = 0;
|
||||
for (int i = 0; i < numberInstances; i++)
|
||||
{
|
||||
Hashtable inst = (Hashtable)resources.instance_list.Array[i];
|
||||
|
||||
ArrayList ascale = (ArrayList)inst["scale"];
|
||||
Vector3 scale;
|
||||
double tmp;
|
||||
tmp = (double)ascale[0];
|
||||
scale.X = (float)tmp;
|
||||
tmp = (double)ascale[1];
|
||||
scale.Y = (float)tmp;
|
||||
tmp = (double)ascale[2];
|
||||
scale.Z = (float)tmp;
|
||||
|
||||
if (scale.X < PrimScaleMin || scale.Y < PrimScaleMin || scale.Z < PrimScaleMin)
|
||||
{
|
||||
skipedSmall++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scale.X > NonPhysicalPrimScaleMax || scale.Y > NonPhysicalPrimScaleMax || scale.Z > NonPhysicalPrimScaleMax)
|
||||
{
|
||||
error = "Model contains parts with sides larger than " + NonPhysicalPrimScaleMax.ToString() + "m. Please ajust scale";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (haveMeshs && inst.ContainsKey("mesh"))
|
||||
{
|
||||
mesh = (int)inst["mesh"];
|
||||
|
||||
if (mesh >= numberMeshs)
|
||||
{
|
||||
error = "Incoerent model information.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// streamming cost
|
||||
|
||||
float sqdiam = scale.LengthSquared();
|
||||
|
||||
ameshCostParam curCost = meshsCosts[mesh];
|
||||
float mesh_streaming = streamingCost(curCost, sqdiam);
|
||||
|
||||
meshcostdata.model_streaming_cost += mesh_streaming;
|
||||
meshcostdata.physics_cost += curCost.physicsCost;
|
||||
}
|
||||
else // instance as no mesh ??
|
||||
{
|
||||
// to do later if needed
|
||||
meshcostdata.model_streaming_cost += 0.5f;
|
||||
meshcostdata.physics_cost += 1.0f;
|
||||
}
|
||||
|
||||
// assume unscripted and static prim server cost
|
||||
meshcostdata.simulation_cost += 0.5f;
|
||||
// charge for prims creation
|
||||
meshsfee += primCreationCost;
|
||||
}
|
||||
|
||||
if (skipedSmall > 0)
|
||||
{
|
||||
if (skipedSmall > numberInstances / 2)
|
||||
{
|
||||
error = "Model contains too many prims smaller than " + PrimScaleMin.ToString() +
|
||||
"m minimum allowed size. Please check scalling";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
warning += skipedSmall.ToString() + " of the requested " +numberInstances.ToString() +
|
||||
" model prims will not upload because they are smaller than " + PrimScaleMin.ToString() +
|
||||
"m minimum allowed size. Please check scalling ";
|
||||
}
|
||||
|
||||
if (meshcostdata.physics_cost <= meshcostdata.model_streaming_cost)
|
||||
meshcostdata.resource_cost = meshcostdata.model_streaming_cost;
|
||||
else
|
||||
meshcostdata.resource_cost = meshcostdata.physics_cost;
|
||||
|
||||
if (meshcostdata.resource_cost < meshcostdata.simulation_cost)
|
||||
meshcostdata.resource_cost = meshcostdata.simulation_cost;
|
||||
|
||||
// scale cost
|
||||
// at this point a cost of 1.0 whould mean basic cost
|
||||
meshsfee *= ModelMeshCostFactor;
|
||||
|
||||
if (meshsfee < ModelMinCostFactor)
|
||||
meshsfee = ModelMinCostFactor;
|
||||
|
||||
// actually scale it to basic cost
|
||||
meshsfee *= (float)basicCost;
|
||||
|
||||
meshsfee += 0.5f; // rounding
|
||||
|
||||
totalcost += (int)meshsfee;
|
||||
|
||||
// breakdown prices
|
||||
// don't seem to be in use so removed code for now
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// single mesh asset cost
|
||||
private bool MeshCost(byte[] data, ameshCostParam cost,out bool skeleton, out bool avatarPhys, out string error)
|
||||
{
|
||||
cost.highLODSize = 0;
|
||||
cost.medLODSize = 0;
|
||||
cost.lowLODSize = 0;
|
||||
cost.lowestLODSize = 0;
|
||||
cost.physicsCost = 0.0f;
|
||||
cost.costFee = 0.0f;
|
||||
|
||||
error = string.Empty;
|
||||
|
||||
skeleton = false;
|
||||
avatarPhys = false;
|
||||
|
||||
if (data == null || data.Length == 0)
|
||||
{
|
||||
error = "Missing model information.";
|
||||
return false;
|
||||
}
|
||||
|
||||
OSD meshOsd = null;
|
||||
int start = 0;
|
||||
|
||||
error = "Invalid model data";
|
||||
|
||||
using (MemoryStream ms = new MemoryStream(data))
|
||||
{
|
||||
try
|
||||
{
|
||||
OSD osd = OSDParser.DeserializeLLSDBinary(ms);
|
||||
if (osd is OSDMap)
|
||||
meshOsd = (OSDMap)osd;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
start = (int)ms.Position;
|
||||
}
|
||||
|
||||
OSDMap map = (OSDMap)meshOsd;
|
||||
OSDMap tmpmap;
|
||||
|
||||
int highlod_size = 0;
|
||||
int medlod_size = 0;
|
||||
int lowlod_size = 0;
|
||||
int lowestlod_size = 0;
|
||||
int skin_size = 0;
|
||||
|
||||
int hulls_size = 0;
|
||||
int phys_nhulls;
|
||||
int phys_hullsvertices = 0;
|
||||
|
||||
int physmesh_size = 0;
|
||||
int phys_ntriangles = 0;
|
||||
|
||||
int submesh_offset = -1;
|
||||
|
||||
if (map.ContainsKey("skeleton"))
|
||||
{
|
||||
tmpmap = (OSDMap)map["skeleton"];
|
||||
if (tmpmap.ContainsKey("offset") && tmpmap.ContainsKey("size"))
|
||||
{
|
||||
int sksize = tmpmap["size"].AsInteger();
|
||||
if(sksize > 0)
|
||||
skeleton = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (map.ContainsKey("physics_convex"))
|
||||
{
|
||||
tmpmap = (OSDMap)map["physics_convex"];
|
||||
if (tmpmap.ContainsKey("offset"))
|
||||
submesh_offset = tmpmap["offset"].AsInteger() + start;
|
||||
if (tmpmap.ContainsKey("size"))
|
||||
hulls_size = tmpmap["size"].AsInteger();
|
||||
}
|
||||
|
||||
if (submesh_offset < 0 || hulls_size == 0)
|
||||
{
|
||||
error = "Missing physics_convex block";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hulls(data, submesh_offset, hulls_size, out phys_hullsvertices, out phys_nhulls))
|
||||
{
|
||||
error = "Bad physics_convex block";
|
||||
return false;
|
||||
}
|
||||
|
||||
submesh_offset = -1;
|
||||
|
||||
// only look for LOD meshs sizes
|
||||
|
||||
if (map.ContainsKey("high_lod"))
|
||||
{
|
||||
tmpmap = (OSDMap)map["high_lod"];
|
||||
// see at least if there is a offset for this one
|
||||
if (tmpmap.ContainsKey("offset"))
|
||||
submesh_offset = tmpmap["offset"].AsInteger() + start;
|
||||
if (tmpmap.ContainsKey("size"))
|
||||
highlod_size = tmpmap["size"].AsInteger();
|
||||
}
|
||||
|
||||
if (submesh_offset < 0 || highlod_size <= 0)
|
||||
{
|
||||
error = "Missing high_lod block";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool haveprev = true;
|
||||
|
||||
if (map.ContainsKey("medium_lod"))
|
||||
{
|
||||
tmpmap = (OSDMap)map["medium_lod"];
|
||||
if (tmpmap.ContainsKey("size"))
|
||||
medlod_size = tmpmap["size"].AsInteger();
|
||||
else
|
||||
haveprev = false;
|
||||
}
|
||||
|
||||
if (haveprev && map.ContainsKey("low_lod"))
|
||||
{
|
||||
tmpmap = (OSDMap)map["low_lod"];
|
||||
if (tmpmap.ContainsKey("size"))
|
||||
lowlod_size = tmpmap["size"].AsInteger();
|
||||
else
|
||||
haveprev = false;
|
||||
}
|
||||
|
||||
if (haveprev && map.ContainsKey("lowest_lod"))
|
||||
{
|
||||
tmpmap = (OSDMap)map["lowest_lod"];
|
||||
if (tmpmap.ContainsKey("size"))
|
||||
lowestlod_size = tmpmap["size"].AsInteger();
|
||||
}
|
||||
|
||||
if (map.ContainsKey("skin"))
|
||||
{
|
||||
tmpmap = (OSDMap)map["skin"];
|
||||
if (tmpmap.ContainsKey("size"))
|
||||
skin_size = tmpmap["size"].AsInteger();
|
||||
}
|
||||
|
||||
cost.highLODSize = highlod_size;
|
||||
cost.medLODSize = medlod_size;
|
||||
cost.lowLODSize = lowlod_size;
|
||||
cost.lowestLODSize = lowestlod_size;
|
||||
|
||||
submesh_offset = -1;
|
||||
|
||||
tmpmap = null;
|
||||
if(map.ContainsKey("physics_mesh"))
|
||||
tmpmap = (OSDMap)map["physics_mesh"];
|
||||
else if (map.ContainsKey("physics_shape")) // old naming
|
||||
tmpmap = (OSDMap)map["physics_shape"];
|
||||
|
||||
if(tmpmap != null)
|
||||
{
|
||||
if (tmpmap.ContainsKey("offset"))
|
||||
submesh_offset = tmpmap["offset"].AsInteger() + start;
|
||||
if (tmpmap.ContainsKey("size"))
|
||||
physmesh_size = tmpmap["size"].AsInteger();
|
||||
|
||||
if (submesh_offset >= 0 || physmesh_size > 0)
|
||||
{
|
||||
|
||||
if (!submesh(data, submesh_offset, physmesh_size, out phys_ntriangles))
|
||||
{
|
||||
error = "Model data parsing error";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// upload is done in convex shape type so only one hull
|
||||
phys_hullsvertices++;
|
||||
cost.physicsCost = 0.04f * phys_hullsvertices;
|
||||
|
||||
float sfee;
|
||||
|
||||
sfee = data.Length; // start with total compressed data size
|
||||
|
||||
// penalize lod meshs that should be more builder optimized
|
||||
sfee += medSizeWth * medlod_size;
|
||||
sfee += lowSizeWth * lowlod_size;
|
||||
sfee += lowestSizeWth * lowlod_size;
|
||||
|
||||
// physics
|
||||
// favor potencial optimized meshs versus automatic decomposition
|
||||
if (physmesh_size != 0)
|
||||
sfee += physMeshSizeWth * (physmesh_size + hulls_size / 4); // reduce cost of mandatory convex hull
|
||||
else
|
||||
sfee += physHullSizeWth * hulls_size;
|
||||
|
||||
// bytes to money
|
||||
sfee *= bytecost;
|
||||
|
||||
cost.costFee = sfee;
|
||||
return true;
|
||||
}
|
||||
|
||||
// parses a LOD or physics mesh component
|
||||
private bool submesh(byte[] data, int offset, int size, out int ntriangles)
|
||||
{
|
||||
ntriangles = 0;
|
||||
|
||||
OSD decodedMeshOsd = new OSD();
|
||||
byte[] meshBytes = new byte[size];
|
||||
System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
|
||||
try
|
||||
{
|
||||
using (MemoryStream inMs = new MemoryStream(meshBytes))
|
||||
{
|
||||
using (MemoryStream outMs = new MemoryStream())
|
||||
{
|
||||
using (ZOutputStream zOut = new ZOutputStream(outMs))
|
||||
{
|
||||
byte[] readBuffer = new byte[4096];
|
||||
int readLen = 0;
|
||||
while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
|
||||
{
|
||||
zOut.Write(readBuffer, 0, readLen);
|
||||
}
|
||||
zOut.Flush();
|
||||
outMs.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
byte[] decompressedBuf = outMs.GetBuffer();
|
||||
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
OSDArray decodedMeshOsdArray = null;
|
||||
if ((!decodedMeshOsd is OSDArray))
|
||||
return false;
|
||||
|
||||
byte[] dummy;
|
||||
|
||||
decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
|
||||
foreach (OSD subMeshOsd in decodedMeshOsdArray)
|
||||
{
|
||||
if (subMeshOsd is OSDMap)
|
||||
{
|
||||
OSDMap subtmpmap = (OSDMap)subMeshOsd;
|
||||
if (subtmpmap.ContainsKey("NoGeometry") && ((OSDBoolean)subtmpmap["NoGeometry"]))
|
||||
continue;
|
||||
|
||||
if (!subtmpmap.ContainsKey("Position"))
|
||||
return false;
|
||||
|
||||
if (subtmpmap.ContainsKey("TriangleList"))
|
||||
{
|
||||
dummy = subtmpmap["TriangleList"].AsBinary();
|
||||
ntriangles += dummy.Length / bytesPerCoord;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// parses convex hulls component
|
||||
private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls)
|
||||
{
|
||||
nvertices = 0;
|
||||
nhulls = 1;
|
||||
|
||||
OSD decodedMeshOsd = new OSD();
|
||||
byte[] meshBytes = new byte[size];
|
||||
System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
|
||||
try
|
||||
{
|
||||
using (MemoryStream inMs = new MemoryStream(meshBytes))
|
||||
{
|
||||
using (MemoryStream outMs = new MemoryStream())
|
||||
{
|
||||
using (ZOutputStream zOut = new ZOutputStream(outMs))
|
||||
{
|
||||
byte[] readBuffer = new byte[4096];
|
||||
int readLen = 0;
|
||||
while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
|
||||
{
|
||||
zOut.Write(readBuffer, 0, readLen);
|
||||
}
|
||||
zOut.Flush();
|
||||
outMs.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
byte[] decompressedBuf = outMs.GetBuffer();
|
||||
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
OSDMap cmap = (OSDMap)decodedMeshOsd;
|
||||
if (cmap == null)
|
||||
return false;
|
||||
|
||||
byte[] dummy;
|
||||
|
||||
// must have one of this
|
||||
if (cmap.ContainsKey("BoundingVerts"))
|
||||
{
|
||||
dummy = cmap["BoundingVerts"].AsBinary();
|
||||
nvertices = dummy.Length / bytesPerCoord;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
/* upload is done with convex shape type
|
||||
if (cmap.ContainsKey("HullList"))
|
||||
{
|
||||
dummy = cmap["HullList"].AsBinary();
|
||||
nhulls += dummy.Length;
|
||||
}
|
||||
|
||||
|
||||
if (cmap.ContainsKey("Positions"))
|
||||
{
|
||||
dummy = cmap["Positions"].AsBinary();
|
||||
nvertices = dummy.Length / bytesPerCoord;
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns streaming cost from on mesh LODs sizes in curCost and square of prim size length
|
||||
private float streamingCost(ameshCostParam curCost, float sqdiam)
|
||||
{
|
||||
// compute efective areas
|
||||
float ma = 262144f;
|
||||
|
||||
float mh = sqdiam * highLodFactor;
|
||||
if (mh > ma)
|
||||
mh = ma;
|
||||
float mm = sqdiam * midLodFactor;
|
||||
if (mm > ma)
|
||||
mm = ma;
|
||||
|
||||
float ml = sqdiam * lowLodFactor;
|
||||
if (ml > ma)
|
||||
ml = ma;
|
||||
|
||||
float mlst = ma;
|
||||
|
||||
mlst -= ml;
|
||||
ml -= mm;
|
||||
mm -= mh;
|
||||
|
||||
if (mlst < 1.0f)
|
||||
mlst = 1.0f;
|
||||
if (ml < 1.0f)
|
||||
ml = 1.0f;
|
||||
if (mm < 1.0f)
|
||||
mm = 1.0f;
|
||||
if (mh < 1.0f)
|
||||
mh = 1.0f;
|
||||
|
||||
ma = mlst + ml + mm + mh;
|
||||
|
||||
// get LODs compressed sizes
|
||||
// giving 384 bytes bonus
|
||||
int lst = curCost.lowestLODSize - 384;
|
||||
int l = curCost.lowLODSize - 384;
|
||||
int m = curCost.medLODSize - 384;
|
||||
int h = curCost.highLODSize - 384;
|
||||
|
||||
// use previus higher LOD size on missing ones
|
||||
if (m <= 0)
|
||||
m = h;
|
||||
if (l <= 0)
|
||||
l = m;
|
||||
if (lst <= 0)
|
||||
lst = l;
|
||||
|
||||
// force minumum sizes
|
||||
if (lst < 16)
|
||||
lst = 16;
|
||||
if (l < 16)
|
||||
l = 16;
|
||||
if (m < 16)
|
||||
m = 16;
|
||||
if (h < 16)
|
||||
h = 16;
|
||||
|
||||
// compute cost weighted by relative effective areas
|
||||
float cost = (float)lst * mlst + (float)l * ml + (float)m * mm + (float)h * mh;
|
||||
cost /= ma;
|
||||
|
||||
cost *= 0.004f; // overall tunning parameter
|
||||
|
||||
return cost;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -78,7 +78,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
|
||||
|
||||
private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>();
|
||||
private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
|
||||
private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
|
||||
|
||||
#region INonSharedRegionModule methods
|
||||
|
@ -178,6 +177,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
<<<<<<< HEAD
|
||||
/// Always returns a valid queue
|
||||
/// </summary>
|
||||
/// <param name="agentId"></param>
|
||||
|
@ -201,6 +201,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
=======
|
||||
>>>>>>> avn/ubitvar
|
||||
/// May return a null queue
|
||||
/// </summary>
|
||||
/// <param name="agentId"></param>
|
||||
|
@ -263,28 +265,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
lock (queues)
|
||||
queues.Remove(agentID);
|
||||
|
||||
List<UUID> removeitems = new List<UUID>();
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
m_AvatarQueueUUIDMapping.Remove(agentID);
|
||||
|
||||
UUID searchval = UUID.Zero;
|
||||
|
||||
removeitems.Clear();
|
||||
|
||||
lock (m_QueueUUIDAvatarMapping)
|
||||
lock (m_ids)
|
||||
{
|
||||
foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys)
|
||||
{
|
||||
searchval = m_QueueUUIDAvatarMapping[ky];
|
||||
|
||||
if (searchval == agentID)
|
||||
{
|
||||
removeitems.Add(ky);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (UUID ky in removeitems)
|
||||
m_QueueUUIDAvatarMapping.Remove(ky);
|
||||
if (!m_ids.ContainsKey(agentID))
|
||||
m_ids.Remove(agentID);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
|
||||
|
@ -303,61 +290,107 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
public void OnRegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
// Register an event queue for the client
|
||||
<<<<<<< HEAD
|
||||
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat(
|
||||
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
|
||||
agentID, caps, m_scene.RegionInfo.RegionName);
|
||||
|
||||
// Let's instantiate a Queue for this agent right now
|
||||
TryGetQueue(agentID);
|
||||
=======
|
||||
m_log.DebugFormat(
|
||||
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
|
||||
agentID, caps, m_scene.RegionInfo.RegionName);
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
UUID eventQueueGetUUID;
|
||||
Queue<OSD> queue;
|
||||
Random rnd = new Random(Environment.TickCount);
|
||||
int nrnd = rnd.Next(30000000);
|
||||
if (nrnd < 0)
|
||||
nrnd = -nrnd;
|
||||
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
lock (queues)
|
||||
{
|
||||
// Reuse open queues. The client does!
|
||||
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||
if (queues.ContainsKey(agentID))
|
||||
queue = queues[agentID];
|
||||
else
|
||||
queue = null;
|
||||
|
||||
if (queue == null)
|
||||
{
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
||||
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||
queue = new Queue<OSD>();
|
||||
queues[agentID] = queue;
|
||||
|
||||
// push markers to handle old responses still waiting
|
||||
// this will cost at most viewer getting two forced noevents
|
||||
// even being a new queue better be safe
|
||||
queue.Enqueue(null);
|
||||
queue.Enqueue(null); // one should be enough
|
||||
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
{
|
||||
eventQueueGetUUID = UUID.Random();
|
||||
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||
{
|
||||
// oops this should not happen ?
|
||||
m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue");
|
||||
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||
}
|
||||
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||
}
|
||||
lock (m_ids)
|
||||
{
|
||||
if (!m_ids.ContainsKey(agentID))
|
||||
m_ids.Add(agentID, nrnd);
|
||||
else
|
||||
m_ids[agentID] = nrnd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eventQueueGetUUID = UUID.Random();
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
||||
// push markers to handle old responses still waiting
|
||||
// this will cost at most viewer getting two forced noevents
|
||||
// even being a new queue better be safe
|
||||
queue.Enqueue(null);
|
||||
queue.Enqueue(null); // one should be enough
|
||||
|
||||
// reuse or not to reuse TODO FIX
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
{
|
||||
// Reuse open queues. The client does!
|
||||
// Its reuse caps path not queues those are been reused already
|
||||
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||
{
|
||||
m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
||||
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||
}
|
||||
else
|
||||
{
|
||||
eventQueueGetUUID = UUID.Random();
|
||||
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||
m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
||||
}
|
||||
}
|
||||
lock (m_ids)
|
||||
{
|
||||
// change to negative numbers so they are changed at end of sending first marker
|
||||
// old data on a queue may be sent on a response for a new caps
|
||||
// but at least will be sent with coerent IDs
|
||||
if (!m_ids.ContainsKey(agentID))
|
||||
m_ids.Add(agentID, -nrnd); // should not happen
|
||||
else
|
||||
m_ids[agentID] = -m_ids[agentID];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_QueueUUIDAvatarMapping)
|
||||
{
|
||||
if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
|
||||
m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
|
||||
}
|
||||
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
{
|
||||
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||
}
|
||||
|
||||
caps.RegisterPollHandler(
|
||||
"EventQueueGet",
|
||||
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
|
||||
|
||||
Random rnd = new Random(Environment.TickCount);
|
||||
lock (m_ids)
|
||||
{
|
||||
if (!m_ids.ContainsKey(agentID))
|
||||
m_ids.Add(agentID, rnd.Next(30000000));
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasEvents(UUID requestID, UUID agentID)
|
||||
{
|
||||
// Don't use this, because of race conditions at agent closing time
|
||||
//Queue<OSD> queue = TryGetQueue(agentID);
|
||||
|
||||
Queue<OSD> queue = GetQueue(agentID);
|
||||
if (queue != null)
|
||||
lock (queue)
|
||||
|
@ -366,7 +399,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
return queue.Count > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
//m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -395,55 +429,65 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
return NoEvents(requestID, pAgentId);
|
||||
}
|
||||
|
||||
OSD element;
|
||||
OSD element = null;;
|
||||
OSDArray array = new OSDArray();
|
||||
int thisID = 0;
|
||||
bool negativeID = false;
|
||||
|
||||
lock (queue)
|
||||
{
|
||||
if (queue.Count == 0)
|
||||
return NoEvents(requestID, pAgentId);
|
||||
element = queue.Dequeue(); // 15s timeout
|
||||
}
|
||||
|
||||
int thisID = 0;
|
||||
lock (m_ids)
|
||||
thisID = m_ids[pAgentId];
|
||||
lock (m_ids)
|
||||
thisID = m_ids[pAgentId];
|
||||
|
||||
OSDArray array = new OSDArray();
|
||||
if (element == null) // didn't have an event in 15s
|
||||
{
|
||||
// Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
|
||||
array.Add(EventQueueHelper.KeepAliveEvent());
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DebugLevel > 0)
|
||||
LogOutboundDebugMessage(element, pAgentId);
|
||||
|
||||
array.Add(element);
|
||||
|
||||
lock (queue)
|
||||
if (thisID < 0)
|
||||
{
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
element = queue.Dequeue();
|
||||
negativeID = true;
|
||||
thisID = -thisID;
|
||||
}
|
||||
|
||||
if (DebugLevel > 0)
|
||||
LogOutboundDebugMessage(element, pAgentId);
|
||||
|
||||
array.Add(element);
|
||||
thisID++;
|
||||
}
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
element = queue.Dequeue();
|
||||
// add elements until a marker is found
|
||||
// so they get into a response
|
||||
if (element == null)
|
||||
break;
|
||||
if (DebugLevel > 0)
|
||||
LogOutboundDebugMessage(element, pAgentId);
|
||||
array.Add(element);
|
||||
thisID++;
|
||||
}
|
||||
}
|
||||
|
||||
OSDMap events = new OSDMap();
|
||||
events.Add("events", array);
|
||||
OSDMap events = null;
|
||||
|
||||
if (array.Count > 0)
|
||||
{
|
||||
events = new OSDMap();
|
||||
events.Add("events", array);
|
||||
events.Add("id", new OSDInteger(thisID));
|
||||
}
|
||||
|
||||
if (negativeID && element == null)
|
||||
{
|
||||
Random rnd = new Random(Environment.TickCount);
|
||||
thisID = rnd.Next(30000000);
|
||||
if (thisID < 0)
|
||||
thisID = -thisID;
|
||||
}
|
||||
|
||||
events.Add("id", new OSDInteger(thisID));
|
||||
lock (m_ids)
|
||||
{
|
||||
m_ids[pAgentId] = thisID + 1;
|
||||
}
|
||||
|
||||
// if there where no elements before a marker send a NoEvents
|
||||
if (array.Count == 0)
|
||||
return NoEvents(requestID, pAgentId);
|
||||
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 200;
|
||||
responsedata["content_type"] = "application/xml";
|
||||
|
@ -461,260 +505,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["str_response_string"] = "Upstream error: ";
|
||||
responsedata["error_status_text"] = "Upstream error:";
|
||||
responsedata["str_response_string"] = "<llsd></llsd>";
|
||||
responsedata["error_status_text"] = "<llsd></llsd>";
|
||||
responsedata["http_protocol_version"] = "HTTP/1.0";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
// public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
|
||||
// {
|
||||
// // TODO: this has to be redone to not busy-wait (and block the thread),
|
||||
// // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
|
||||
//
|
||||
//// if (m_log.IsDebugEnabled)
|
||||
//// {
|
||||
//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
|
||||
//// foreach (object key in request.Keys)
|
||||
//// {
|
||||
//// debug += key.ToString() + "=" + request[key].ToString() + " ";
|
||||
//// }
|
||||
//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
|
||||
//// }
|
||||
//
|
||||
// Queue<OSD> queue = TryGetQueue(agentID);
|
||||
// OSD element;
|
||||
//
|
||||
// lock (queue)
|
||||
// element = queue.Dequeue(); // 15s timeout
|
||||
//
|
||||
// Hashtable responsedata = new Hashtable();
|
||||
//
|
||||
// int thisID = 0;
|
||||
// lock (m_ids)
|
||||
// thisID = m_ids[agentID];
|
||||
//
|
||||
// if (element == null)
|
||||
// {
|
||||
// //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
|
||||
// if (thisID == -1) // close-request
|
||||
// {
|
||||
// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
|
||||
// responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
// responsedata["content_type"] = "text/plain";
|
||||
// responsedata["keepalive"] = false;
|
||||
// responsedata["str_response_string"] = "Closed EQG";
|
||||
// return responsedata;
|
||||
// }
|
||||
// responsedata["int_response_code"] = 502;
|
||||
// responsedata["content_type"] = "text/plain";
|
||||
// responsedata["keepalive"] = false;
|
||||
// responsedata["str_response_string"] = "Upstream error: ";
|
||||
// responsedata["error_status_text"] = "Upstream error:";
|
||||
// responsedata["http_protocol_version"] = "HTTP/1.0";
|
||||
// return responsedata;
|
||||
// }
|
||||
//
|
||||
// OSDArray array = new OSDArray();
|
||||
// if (element == null) // didn't have an event in 15s
|
||||
// {
|
||||
// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
|
||||
// array.Add(EventQueueHelper.KeepAliveEvent());
|
||||
// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// array.Add(element);
|
||||
//
|
||||
// if (element is OSDMap)
|
||||
// {
|
||||
// OSDMap ev = (OSDMap)element;
|
||||
// m_log.DebugFormat(
|
||||
// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||
// ev["message"], m_scene.GetScenePresence(agentID).Name);
|
||||
// }
|
||||
//
|
||||
// lock (queue)
|
||||
// {
|
||||
// while (queue.Count > 0)
|
||||
// {
|
||||
// element = queue.Dequeue();
|
||||
//
|
||||
// if (element is OSDMap)
|
||||
// {
|
||||
// OSDMap ev = (OSDMap)element;
|
||||
// m_log.DebugFormat(
|
||||
// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||
// ev["message"], m_scene.GetScenePresence(agentID).Name);
|
||||
// }
|
||||
//
|
||||
// array.Add(element);
|
||||
// thisID++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// OSDMap events = new OSDMap();
|
||||
// events.Add("events", array);
|
||||
//
|
||||
// events.Add("id", new OSDInteger(thisID));
|
||||
// lock (m_ids)
|
||||
// {
|
||||
// m_ids[agentID] = thisID + 1;
|
||||
// }
|
||||
//
|
||||
// responsedata["int_response_code"] = 200;
|
||||
// responsedata["content_type"] = "application/xml";
|
||||
// responsedata["keepalive"] = false;
|
||||
// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
|
||||
//
|
||||
// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
|
||||
//
|
||||
// return responsedata;
|
||||
// }
|
||||
|
||||
// public Hashtable EventQueuePath2(Hashtable request)
|
||||
// {
|
||||
// string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
|
||||
// // pull off the last "/" in the path.
|
||||
// Hashtable responsedata = new Hashtable();
|
||||
// capuuid = capuuid.Substring(0, capuuid.Length - 1);
|
||||
// capuuid = capuuid.Replace("/CAPS/EQG/", "");
|
||||
// UUID AvatarID = UUID.Zero;
|
||||
// UUID capUUID = UUID.Zero;
|
||||
//
|
||||
// // parse the path and search for the avatar with it registered
|
||||
// if (UUID.TryParse(capuuid, out capUUID))
|
||||
// {
|
||||
// lock (m_QueueUUIDAvatarMapping)
|
||||
// {
|
||||
// if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
|
||||
// {
|
||||
// AvatarID = m_QueueUUIDAvatarMapping[capUUID];
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (AvatarID != UUID.Zero)
|
||||
// {
|
||||
// return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// responsedata["int_response_code"] = 404;
|
||||
// responsedata["content_type"] = "text/plain";
|
||||
// responsedata["keepalive"] = false;
|
||||
// responsedata["str_response_string"] = "Not Found";
|
||||
// responsedata["error_status_text"] = "Not Found";
|
||||
// responsedata["http_protocol_version"] = "HTTP/1.0";
|
||||
// return responsedata;
|
||||
// // return 404
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// responsedata["int_response_code"] = 404;
|
||||
// responsedata["content_type"] = "text/plain";
|
||||
// responsedata["keepalive"] = false;
|
||||
// responsedata["str_response_string"] = "Not Found";
|
||||
// responsedata["error_status_text"] = "Not Found";
|
||||
// responsedata["http_protocol_version"] = "HTTP/1.0";
|
||||
// return responsedata;
|
||||
// // return 404
|
||||
// }
|
||||
// }
|
||||
|
||||
public OSD EventQueueFallBack(string path, OSD request, string endpoint)
|
||||
{
|
||||
// This is a fallback element to keep the client from loosing EventQueueGet
|
||||
// Why does CAPS fail sometimes!?
|
||||
m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!");
|
||||
string capuuid = path.Replace("/CAPS/EQG/","");
|
||||
capuuid = capuuid.Substring(0, capuuid.Length - 1);
|
||||
|
||||
// UUID AvatarID = UUID.Zero;
|
||||
UUID capUUID = UUID.Zero;
|
||||
if (UUID.TryParse(capuuid, out capUUID))
|
||||
{
|
||||
/* Don't remove this yet code cleaners!
|
||||
* Still testing this!
|
||||
*
|
||||
lock (m_QueueUUIDAvatarMapping)
|
||||
{
|
||||
if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
|
||||
{
|
||||
AvatarID = m_QueueUUIDAvatarMapping[capUUID];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (AvatarID != UUID.Zero)
|
||||
{
|
||||
// Repair the CAP!
|
||||
//OpenSim.Framework.Capabilities.Caps caps = m_scene.GetCapsHandlerForUser(AvatarID);
|
||||
//string capsBase = "/CAPS/EQG/";
|
||||
//caps.RegisterHandler("EventQueueGet",
|
||||
//new RestHTTPHandler("POST", capsBase + capUUID.ToString() + "/",
|
||||
//delegate(Hashtable m_dhttpMethod)
|
||||
//{
|
||||
// return ProcessQueue(m_dhttpMethod, AvatarID, caps);
|
||||
//}));
|
||||
// start new ID sequence.
|
||||
Random rnd = new Random(System.Environment.TickCount);
|
||||
lock (m_ids)
|
||||
{
|
||||
if (!m_ids.ContainsKey(AvatarID))
|
||||
m_ids.Add(AvatarID, rnd.Next(30000000));
|
||||
}
|
||||
|
||||
|
||||
int thisID = 0;
|
||||
lock (m_ids)
|
||||
thisID = m_ids[AvatarID];
|
||||
|
||||
BlockingLLSDQueue queue = GetQueue(AvatarID);
|
||||
OSDArray array = new OSDArray();
|
||||
LLSD element = queue.Dequeue(15000); // 15s timeout
|
||||
if (element == null)
|
||||
{
|
||||
|
||||
array.Add(EventQueueHelper.KeepAliveEvent());
|
||||
}
|
||||
else
|
||||
{
|
||||
array.Add(element);
|
||||
while (queue.Count() > 0)
|
||||
{
|
||||
array.Add(queue.Dequeue(1));
|
||||
thisID++;
|
||||
}
|
||||
}
|
||||
OSDMap events = new OSDMap();
|
||||
events.Add("events", array);
|
||||
|
||||
events.Add("id", new LLSDInteger(thisID));
|
||||
|
||||
lock (m_ids)
|
||||
{
|
||||
m_ids[AvatarID] = thisID + 1;
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new LLSD();
|
||||
}
|
||||
*
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
//return new LLSD();
|
||||
}
|
||||
|
||||
return new OSDString("shutdown404!");
|
||||
}
|
||||
|
||||
public void DisableSimulator(ulong handle, UUID avatarID)
|
||||
{
|
||||
OSD item = EventQueueHelper.DisableSimulator(handle);
|
||||
|
@ -723,9 +519,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}",
|
||||
LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY);
|
||||
=======
|
||||
m_log.DebugFormat("{0} EnableSimulator. handle={1}, avatarID={2}, regionSize={3},{4}>",
|
||||
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
|
||||
Enqueue(item, avatarID);
|
||||
|
@ -734,10 +535,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
|
||||
ulong regionHandle, int regionSizeX, int regionSizeY)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}",
|
||||
LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY);
|
||||
|
||||
=======
|
||||
m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, avatarID={2}, regionSize={3},{4}>",
|
||||
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
|
||||
>>>>>>> avn/ubitvar
|
||||
OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
|
@ -747,9 +553,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
uint locationID, uint flags, string capsURL,
|
||||
UUID avatarID, int regionSizeX, int regionSizeY)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}",
|
||||
LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY);
|
||||
=======
|
||||
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, avatarID={2}, regionSize={3},{4}>",
|
||||
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
|
||||
locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
|
||||
|
@ -760,9 +571,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
IPEndPoint newRegionExternalEndPoint,
|
||||
string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
|
||||
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
|
||||
=======
|
||||
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
|
||||
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
|
||||
capsURL, avatarID, sessionID, regionSizeX, regionSizeY);
|
||||
|
|
|
@ -77,8 +77,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle)));
|
||||
llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes()));
|
||||
llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port));
|
||||
<<<<<<< HEAD
|
||||
llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint) regionSizeX));
|
||||
llsdSimInfo.Add("RegionSizeY", OSD.FromUInteger((uint) regionSizeY));
|
||||
=======
|
||||
llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX));
|
||||
llsdSimInfo.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY));
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
OSDArray arr = new OSDArray(1);
|
||||
arr.Add(llsdSimInfo);
|
||||
|
@ -157,6 +162,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
uint locationID, uint flags, string capsURL, UUID agentID,
|
||||
int regionSizeX, int regionSizeY)
|
||||
{
|
||||
// not sure why flags get overwritten here
|
||||
if ((flags & (uint)TeleportFlags.IsFlying) != 0)
|
||||
flags = (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.IsFlying;
|
||||
else
|
||||
flags = (uint)TeleportFlags.ViaLocation;
|
||||
|
||||
OSDMap info = new OSDMap();
|
||||
info.Add("AgentID", OSD.FromUUID(agentID));
|
||||
info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this?
|
||||
|
@ -165,7 +176,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
info.Add("SimAccess", OSD.FromInteger(simAccess));
|
||||
info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes()));
|
||||
info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port));
|
||||
<<<<<<< HEAD
|
||||
info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
|
||||
=======
|
||||
// info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
|
||||
info.Add("TeleportFlags", OSD.FromUInteger(flags));
|
||||
>>>>>>> avn/ubitvar
|
||||
info.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX));
|
||||
info.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY));
|
||||
|
||||
|
@ -204,8 +220,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
{"sim-ip-and-port", new OSDString(simIpAndPort)},
|
||||
{"seed-capability", new OSDString(seedcap)},
|
||||
{"region-handle", OSD.FromULong(regionHandle)},
|
||||
{"region-size-x", OSD.FromInteger(regionSizeX)},
|
||||
{"region-size-y", OSD.FromInteger(regionSizeY)}
|
||||
{"region-size-x", OSD.FromUInteger((uint)regionSizeX)},
|
||||
{"region-size-y", OSD.FromUInteger((uint)regionSizeY)}
|
||||
};
|
||||
|
||||
return BuildEvent("EstablishAgentCommunication", body);
|
||||
|
|
|
@ -27,11 +27,14 @@
|
|||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using Mono.Addins;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
|
@ -57,12 +60,51 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
private IAssetService m_AssetService;
|
||||
private bool m_Enabled = true;
|
||||
private string m_URL;
|
||||
<<<<<<< HEAD
|
||||
private string m_URL2;
|
||||
private string m_RedirectURL = null;
|
||||
private string m_RedirectURL2 = null;
|
||||
=======
|
||||
|
||||
struct aPollRequest
|
||||
{
|
||||
public PollServiceMeshEventArgs thepoll;
|
||||
public UUID reqID;
|
||||
public Hashtable request;
|
||||
}
|
||||
|
||||
public class aPollResponse
|
||||
{
|
||||
public Hashtable response;
|
||||
public int bytes;
|
||||
public int lod;
|
||||
}
|
||||
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static GetMeshHandler m_getMeshHandler;
|
||||
|
||||
private IAssetService m_assetService = null;
|
||||
|
||||
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
||||
private static Thread[] m_workerThreads = null;
|
||||
|
||||
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
|
||||
new OpenMetaverse.BlockingQueue<aPollRequest>();
|
||||
|
||||
private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>();
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
#region Region Module interfaceBase Members
|
||||
|
||||
~GetMeshModule()
|
||||
{
|
||||
foreach (Thread t in m_workerThreads)
|
||||
Watchdog.AbortThread(t.ManagedThreadId);
|
||||
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
|
@ -87,8 +129,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
if (m_URL2 != string.Empty)
|
||||
{
|
||||
m_Enabled = true;
|
||||
<<<<<<< HEAD
|
||||
m_RedirectURL2 = config.GetString("GetMesh2RedirectURL");
|
||||
}
|
||||
=======
|
||||
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
|
||||
public void AddRegion(Scene pScene)
|
||||
|
@ -97,6 +143,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
return;
|
||||
|
||||
m_scene = pScene;
|
||||
|
||||
m_assetService = pScene.AssetService;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
|
@ -105,6 +153,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
return;
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
|
||||
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
|
||||
|
||||
m_scene = null;
|
||||
}
|
||||
|
||||
|
@ -115,6 +166,27 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
m_AssetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
// We'll reuse the same handler for all requests.
|
||||
m_getMeshHandler = new GetMeshHandler(m_assetService);
|
||||
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
|
||||
m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
|
||||
|
||||
if (m_workerThreads == null)
|
||||
{
|
||||
m_workerThreads = new Thread[2];
|
||||
|
||||
for (uint i = 0; i < 2; i++)
|
||||
{
|
||||
m_workerThreads[i] = Watchdog.StartThread(DoMeshRequests,
|
||||
String.Format("MeshWorkerThread{0}", i),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
int.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,9 +196,147 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
#endregion
|
||||
|
||||
private void DoMeshRequests()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
aPollRequest poolreq = m_queue.Dequeue();
|
||||
|
||||
poolreq.thepoll.Process(poolreq);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
|
||||
public void ThrottleUpdate(ScenePresence p)
|
||||
{
|
||||
UUID user = p.UUID;
|
||||
int imagethrottle = p.ControllingClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Asset);
|
||||
PollServiceMeshEventArgs args;
|
||||
if (m_pollservices.TryGetValue(user, out args))
|
||||
{
|
||||
args.UpdateThrottle(imagethrottle, p);
|
||||
}
|
||||
}
|
||||
|
||||
private class PollServiceMeshEventArgs : PollServiceEventArgs
|
||||
{
|
||||
private List<Hashtable> requests =
|
||||
new List<Hashtable>();
|
||||
private Dictionary<UUID, aPollResponse> responses =
|
||||
new Dictionary<UUID, aPollResponse>();
|
||||
|
||||
private Scene m_scene;
|
||||
private MeshCapsDataThrottler m_throttler;
|
||||
public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) :
|
||||
base(null, uri, null, null, null, pId, int.MaxValue)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId);
|
||||
// x is request id, y is userid
|
||||
HasEvents = (x, y) =>
|
||||
{
|
||||
lock (responses)
|
||||
{
|
||||
bool ret = m_throttler.hasEvents(x, responses);
|
||||
m_throttler.ProcessTime();
|
||||
return ret;
|
||||
|
||||
}
|
||||
};
|
||||
GetEvents = (x, y) =>
|
||||
{
|
||||
lock (responses)
|
||||
{
|
||||
try
|
||||
{
|
||||
return responses[x].response;
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_throttler.ProcessTime();
|
||||
responses.Remove(x);
|
||||
}
|
||||
}
|
||||
};
|
||||
// x is request id, y is request data hashtable
|
||||
Request = (x, y) =>
|
||||
{
|
||||
aPollRequest reqinfo = new aPollRequest();
|
||||
reqinfo.thepoll = this;
|
||||
reqinfo.reqID = x;
|
||||
reqinfo.request = y;
|
||||
|
||||
m_queue.Enqueue(reqinfo);
|
||||
};
|
||||
|
||||
// this should never happen except possible on shutdown
|
||||
NoEvents = (x, y) =>
|
||||
{
|
||||
/*
|
||||
lock (requests)
|
||||
{
|
||||
Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
|
||||
requests.Remove(request);
|
||||
}
|
||||
*/
|
||||
Hashtable response = new Hashtable();
|
||||
|
||||
response["int_response_code"] = 500;
|
||||
response["str_response_string"] = "Script timeout";
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
return response;
|
||||
};
|
||||
}
|
||||
|
||||
public void Process(aPollRequest requestinfo)
|
||||
{
|
||||
Hashtable response;
|
||||
|
||||
UUID requestID = requestinfo.reqID;
|
||||
|
||||
// If the avatar is gone, don't bother to get the texture
|
||||
if (m_scene.GetScenePresence(Id) == null)
|
||||
{
|
||||
response = new Hashtable();
|
||||
|
||||
response["int_response_code"] = 500;
|
||||
response["str_response_string"] = "Script timeout";
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
lock (responses)
|
||||
responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 };
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
response = m_getMeshHandler.Handle(requestinfo.request);
|
||||
lock (responses)
|
||||
{
|
||||
responses[requestID] = new aPollResponse()
|
||||
{
|
||||
bytes = (int)response["int_bytes"],
|
||||
lod = (int)response["int_lod"],
|
||||
response = response
|
||||
};
|
||||
|
||||
}
|
||||
m_throttler.ProcessTime();
|
||||
}
|
||||
|
||||
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
|
||||
{
|
||||
m_throttler.UpdateThrottle(pimagethrottle, p);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
UUID capID = UUID.Random();
|
||||
bool getMeshRegistered = false;
|
||||
|
||||
|
@ -140,6 +350,35 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
caps.RegisterHandler(
|
||||
"GetMesh",
|
||||
new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh", agentID.ToString(), m_RedirectURL));
|
||||
=======
|
||||
// UUID capID = UUID.Random();
|
||||
if (m_URL == "localhost")
|
||||
{
|
||||
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
||||
|
||||
// Register this as a poll service
|
||||
PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
|
||||
|
||||
args.Type = PollServiceEventArgs.EventType.Mesh;
|
||||
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||
|
||||
string hostName = m_scene.RegionInfo.ExternalHostName;
|
||||
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||
string protocol = "http";
|
||||
|
||||
if (MainServer.Instance.UseSSL)
|
||||
{
|
||||
hostName = MainServer.Instance.SSLCommonName;
|
||||
port = MainServer.Instance.SSLPort;
|
||||
protocol = "https";
|
||||
}
|
||||
caps.RegisterHandler("GetMesh", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||
m_pollservices[agentID] = args;
|
||||
m_capsDict[agentID] = capUrl;
|
||||
|
||||
|
||||
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -164,6 +403,177 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
caps.RegisterHandler("GetMesh2", m_URL2);
|
||||
}
|
||||
}
|
||||
private void DeregisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
string capUrl;
|
||||
PollServiceMeshEventArgs args;
|
||||
if (m_capsDict.TryGetValue(agentID, out capUrl))
|
||||
{
|
||||
MainServer.Instance.RemoveHTTPHandler("", capUrl);
|
||||
m_capsDict.Remove(agentID);
|
||||
}
|
||||
if (m_pollservices.TryGetValue(agentID, out args))
|
||||
{
|
||||
m_pollservices.Remove(agentID);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class MeshCapsDataThrottler
|
||||
{
|
||||
|
||||
private volatile int currenttime = 0;
|
||||
private volatile int lastTimeElapsed = 0;
|
||||
private volatile int BytesSent = 0;
|
||||
private int Lod3 = 0;
|
||||
private int Lod2 = 0;
|
||||
private int Lod1 = 0;
|
||||
private int UserSetThrottle = 0;
|
||||
private int UDPSetThrottle = 0;
|
||||
private int CapSetThrottle = 0;
|
||||
private float CapThrottleDistributon = 0.30f;
|
||||
private readonly Scene m_scene;
|
||||
private ThrottleOutPacketType Throttle;
|
||||
private readonly UUID User;
|
||||
|
||||
public MeshCapsDataThrottler(int pBytes, int max, int min, Scene pScene, UUID puser)
|
||||
{
|
||||
ThrottleBytes = pBytes;
|
||||
lastTimeElapsed = Util.EnvironmentTickCount();
|
||||
Throttle = ThrottleOutPacketType.Asset;
|
||||
m_scene = pScene;
|
||||
User = puser;
|
||||
}
|
||||
|
||||
|
||||
public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
|
||||
{
|
||||
const float ThirtyPercent = 0.30f;
|
||||
const float FivePercent = 0.05f;
|
||||
PassTime();
|
||||
// Note, this is called IN LOCK
|
||||
bool haskey = responses.ContainsKey(key);
|
||||
|
||||
if (responses.Count > 2)
|
||||
{
|
||||
SplitThrottle(ThirtyPercent);
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitThrottle(FivePercent);
|
||||
}
|
||||
|
||||
if (!haskey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
aPollResponse response;
|
||||
if (responses.TryGetValue(key, out response))
|
||||
{
|
||||
float LOD3Over = (((ThrottleBytes*CapThrottleDistributon)%50000) + 1);
|
||||
float LOD2Over = (((ThrottleBytes*CapThrottleDistributon)%10000) + 1);
|
||||
// Normal
|
||||
if (BytesSent + response.bytes <= ThrottleBytes)
|
||||
{
|
||||
BytesSent += response.bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
// Lod3 Over Throttle protection to keep things processing even when the throttle bandwidth is set too little.
|
||||
else if (response.bytes > ThrottleBytes && Lod3 <= ((LOD3Over < 1)? 1: LOD3Over) )
|
||||
{
|
||||
Interlocked.Increment(ref Lod3);
|
||||
BytesSent += response.bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
// Lod2 Over Throttle protection to keep things processing even when the throttle bandwidth is set too little.
|
||||
else if (response.bytes > ThrottleBytes && Lod2 <= ((LOD2Over < 1) ? 1 : LOD2Over))
|
||||
{
|
||||
Interlocked.Increment(ref Lod2);
|
||||
BytesSent += response.bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return haskey;
|
||||
}
|
||||
public void SubtractBytes(int bytes,int lod)
|
||||
{
|
||||
BytesSent -= bytes;
|
||||
}
|
||||
private void SplitThrottle(float percentMultiplier)
|
||||
{
|
||||
|
||||
if (CapThrottleDistributon != percentMultiplier) // don't switch it if it's already set at the % multipler
|
||||
{
|
||||
CapThrottleDistributon = percentMultiplier;
|
||||
ScenePresence p;
|
||||
if (m_scene.TryGetScenePresence(User, out p)) // If we don't get a user they're not here anymore.
|
||||
{
|
||||
// AlterThrottle(UserSetThrottle, p);
|
||||
UpdateThrottle(UserSetThrottle, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessTime()
|
||||
{
|
||||
PassTime();
|
||||
}
|
||||
|
||||
|
||||
private void PassTime()
|
||||
{
|
||||
currenttime = Util.EnvironmentTickCount();
|
||||
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
|
||||
//processTimeBasedActions(responses);
|
||||
if (currenttime - timeElapsed >= 1000)
|
||||
{
|
||||
lastTimeElapsed = Util.EnvironmentTickCount();
|
||||
BytesSent -= ThrottleBytes;
|
||||
if (BytesSent < 0) BytesSent = 0;
|
||||
if (BytesSent < ThrottleBytes)
|
||||
{
|
||||
Lod3 = 0;
|
||||
Lod2 = 0;
|
||||
Lod1 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void AlterThrottle(int setting, ScenePresence p)
|
||||
{
|
||||
p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
|
||||
}
|
||||
|
||||
public int ThrottleBytes
|
||||
{
|
||||
get { return CapSetThrottle; }
|
||||
set { CapSetThrottle = value; }
|
||||
}
|
||||
|
||||
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
|
||||
{
|
||||
// Client set throttle !
|
||||
UserSetThrottle = pimagethrottle;
|
||||
CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon);
|
||||
// UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon));
|
||||
|
||||
float udp = 1.0f - CapThrottleDistributon;
|
||||
if(udp < 0.7f)
|
||||
udp = 0.7f;
|
||||
UDPSetThrottle = (int) ((float)pimagethrottle * udp);
|
||||
if (CapSetThrottle < 4068)
|
||||
CapSetThrottle = 4068; // at least two discovery mesh
|
||||
p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle);
|
||||
ProcessTime();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,18 +27,13 @@
|
|||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse.Imaging;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
@ -47,6 +42,7 @@ using OpenSim.Region.Framework.Scenes;
|
|||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
using OpenSim.Capabilities.Handlers;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
|
@ -54,16 +50,44 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
|
||||
public class GetTextureModule : INonSharedRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
struct aPollRequest
|
||||
{
|
||||
public PollServiceTextureEventArgs thepoll;
|
||||
public UUID reqID;
|
||||
public Hashtable request;
|
||||
public bool send503;
|
||||
}
|
||||
|
||||
public class aPollResponse
|
||||
{
|
||||
public Hashtable response;
|
||||
public int bytes;
|
||||
}
|
||||
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
private IAssetService m_assetService;
|
||||
|
||||
private bool m_Enabled = false;
|
||||
private static GetTextureHandler m_getTextureHandler;
|
||||
|
||||
private IAssetService m_assetService = null;
|
||||
|
||||
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
||||
private static Thread[] m_workerThreads = null;
|
||||
|
||||
private string m_Url = "localhost";
|
||||
|
||||
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
|
||||
new OpenMetaverse.BlockingQueue<aPollRequest>();
|
||||
|
||||
<<<<<<< HEAD
|
||||
// TODO: Change this to a config option
|
||||
private string m_RedirectURL = null;
|
||||
=======
|
||||
private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
private string m_URL;
|
||||
|
||||
|
@ -72,6 +96,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig config = source.Configs["ClientStack.LindenCaps"];
|
||||
<<<<<<< HEAD
|
||||
if (config == null)
|
||||
return;
|
||||
|
||||
|
@ -82,32 +107,100 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
m_Enabled = true;
|
||||
m_RedirectURL = config.GetString("GetTextureRedirectURL");
|
||||
}
|
||||
=======
|
||||
if (config != null)
|
||||
m_Url = config.GetString("Cap_GetTexture", "localhost");
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
|
||||
public void AddRegion(Scene s)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_scene = s;
|
||||
m_assetService = s.AssetService;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene s)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
|
||||
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
|
||||
m_scene = null;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene s)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
// We'll reuse the same handler for all requests.
|
||||
m_getTextureHandler = new GetTextureHandler(m_assetService);
|
||||
|
||||
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
|
||||
m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
|
||||
|
||||
if (m_workerThreads == null)
|
||||
{
|
||||
m_workerThreads = new Thread[2];
|
||||
|
||||
for (uint i = 0; i < 2; i++)
|
||||
{
|
||||
m_workerThreads[i] = Watchdog.StartThread(DoTextureRequests,
|
||||
String.Format("TextureWorkerThread{0}", i),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
int.MaxValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
private int ExtractImageThrottle(byte[] pthrottles)
|
||||
{
|
||||
|
||||
byte[] adjData;
|
||||
int pos = 0;
|
||||
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
byte[] newData = new byte[7 * 4];
|
||||
Buffer.BlockCopy(pthrottles, 0, newData, 0, 7 * 4);
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
Array.Reverse(newData, i * 4, 4);
|
||||
|
||||
adjData = newData;
|
||||
}
|
||||
else
|
||||
{
|
||||
adjData = pthrottles;
|
||||
}
|
||||
|
||||
// 0.125f converts from bits to bytes
|
||||
//int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||
//pos += 4;
|
||||
// int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||
//pos += 4;
|
||||
// int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||
// pos += 4;
|
||||
// int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||
// pos += 4;
|
||||
// int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||
// pos += 4;
|
||||
pos = pos + 20;
|
||||
int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
|
||||
//int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
|
||||
public void ThrottleUpdate(ScenePresence p)
|
||||
{
|
||||
byte[] throttles = p.ControllingClient.GetThrottlesPacked(1);
|
||||
UUID user = p.UUID;
|
||||
int imagethrottle = ExtractImageThrottle(throttles);
|
||||
PollServiceTextureEventArgs args;
|
||||
if (m_pollservices.TryGetValue(user,out args))
|
||||
{
|
||||
args.UpdateThrottle(imagethrottle);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
|
@ -125,28 +218,306 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
|
||||
#endregion
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
~GetTextureModule()
|
||||
{
|
||||
UUID capID = UUID.Random();
|
||||
foreach (Thread t in m_workerThreads)
|
||||
Watchdog.AbortThread(t.ManagedThreadId);
|
||||
|
||||
//caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
|
||||
if (m_URL == "localhost")
|
||||
}
|
||||
|
||||
private class PollServiceTextureEventArgs : PollServiceEventArgs
|
||||
{
|
||||
private List<Hashtable> requests =
|
||||
new List<Hashtable>();
|
||||
private Dictionary<UUID, aPollResponse> responses =
|
||||
new Dictionary<UUID, aPollResponse>();
|
||||
|
||||
private Scene m_scene;
|
||||
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
|
||||
public PollServiceTextureEventArgs(UUID pId, Scene scene) :
|
||||
base(null, "", null, null, null, pId, int.MaxValue)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||
caps.RegisterHandler(
|
||||
"GetTexture",
|
||||
new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString(), m_RedirectURL));
|
||||
=======
|
||||
m_scene = scene;
|
||||
// x is request id, y is userid
|
||||
HasEvents = (x, y) =>
|
||||
{
|
||||
lock (responses)
|
||||
{
|
||||
bool ret = m_throttler.hasEvents(x, responses);
|
||||
m_throttler.ProcessTime();
|
||||
return ret;
|
||||
|
||||
}
|
||||
};
|
||||
GetEvents = (x, y) =>
|
||||
{
|
||||
lock (responses)
|
||||
{
|
||||
try
|
||||
{
|
||||
return responses[x].response;
|
||||
}
|
||||
finally
|
||||
{
|
||||
responses.Remove(x);
|
||||
}
|
||||
}
|
||||
};
|
||||
// x is request id, y is request data hashtable
|
||||
Request = (x, y) =>
|
||||
{
|
||||
aPollRequest reqinfo = new aPollRequest();
|
||||
reqinfo.thepoll = this;
|
||||
reqinfo.reqID = x;
|
||||
reqinfo.request = y;
|
||||
reqinfo.send503 = false;
|
||||
|
||||
lock (responses)
|
||||
{
|
||||
if (responses.Count > 0)
|
||||
{
|
||||
if (m_queue.Count >= 4)
|
||||
{
|
||||
// Never allow more than 4 fetches to wait
|
||||
reqinfo.send503 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_queue.Enqueue(reqinfo);
|
||||
};
|
||||
|
||||
// this should never happen except possible on shutdown
|
||||
NoEvents = (x, y) =>
|
||||
{
|
||||
/*
|
||||
lock (requests)
|
||||
{
|
||||
Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
|
||||
requests.Remove(request);
|
||||
}
|
||||
*/
|
||||
Hashtable response = new Hashtable();
|
||||
|
||||
response["int_response_code"] = 500;
|
||||
response["str_response_string"] = "Script timeout";
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
return response;
|
||||
};
|
||||
>>>>>>> avn/ubitvar
|
||||
}
|
||||
else
|
||||
|
||||
public void Process(aPollRequest requestinfo)
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
|
||||
IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
|
||||
if (handler != null)
|
||||
handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture", m_URL);
|
||||
else
|
||||
caps.RegisterHandler("GetTexture", m_URL);
|
||||
Hashtable response;
|
||||
|
||||
UUID requestID = requestinfo.reqID;
|
||||
|
||||
if (requestinfo.send503)
|
||||
{
|
||||
response = new Hashtable();
|
||||
|
||||
|
||||
response["int_response_code"] = 503;
|
||||
response["str_response_string"] = "Throttled";
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
Hashtable headers = new Hashtable();
|
||||
headers["Retry-After"] = 30;
|
||||
response["headers"] = headers;
|
||||
|
||||
lock (responses)
|
||||
responses[requestID] = new aPollResponse() {bytes = 0, response = response};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If the avatar is gone, don't bother to get the texture
|
||||
if (m_scene.GetScenePresence(Id) == null)
|
||||
{
|
||||
response = new Hashtable();
|
||||
|
||||
response["int_response_code"] = 500;
|
||||
response["str_response_string"] = "Script timeout";
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
lock (responses)
|
||||
responses[requestID] = new aPollResponse() {bytes = 0, response = response};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
response = m_getTextureHandler.Handle(requestinfo.request);
|
||||
lock (responses)
|
||||
{
|
||||
responses[requestID] = new aPollResponse()
|
||||
{
|
||||
bytes = (int) response["int_bytes"],
|
||||
response = response
|
||||
};
|
||||
|
||||
}
|
||||
m_throttler.ProcessTime();
|
||||
}
|
||||
|
||||
internal void UpdateThrottle(int pimagethrottle)
|
||||
{
|
||||
m_throttler.ThrottleBytes = pimagethrottle;
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
if (m_Url == "localhost")
|
||||
{
|
||||
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
||||
|
||||
// Register this as a poll service
|
||||
PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
|
||||
|
||||
args.Type = PollServiceEventArgs.EventType.Texture;
|
||||
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||
|
||||
string hostName = m_scene.RegionInfo.ExternalHostName;
|
||||
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||
string protocol = "http";
|
||||
|
||||
if (MainServer.Instance.UseSSL)
|
||||
{
|
||||
hostName = MainServer.Instance.SSLCommonName;
|
||||
port = MainServer.Instance.SSLPort;
|
||||
protocol = "https";
|
||||
}
|
||||
IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
|
||||
if (handler != null)
|
||||
<<<<<<< HEAD
|
||||
handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture", m_URL);
|
||||
=======
|
||||
handler.RegisterExternalUserCapsHandler(agentID, caps, "GetTexture", capUrl);
|
||||
>>>>>>> avn/ubitvar
|
||||
else
|
||||
caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||
m_pollservices[agentID] = args;
|
||||
m_capsDict[agentID] = capUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
caps.RegisterHandler("GetTexture", m_Url);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeregisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
PollServiceTextureEventArgs args;
|
||||
|
||||
MainServer.Instance.RemoveHTTPHandler("", m_URL);
|
||||
m_capsDict.Remove(agentID);
|
||||
|
||||
if (m_pollservices.TryGetValue(agentID, out args))
|
||||
{
|
||||
m_pollservices.Remove(agentID);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoTextureRequests()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
aPollRequest poolreq = m_queue.Dequeue();
|
||||
|
||||
poolreq.thepoll.Process(poolreq);
|
||||
}
|
||||
}
|
||||
internal sealed class CapsDataThrottler
|
||||
{
|
||||
|
||||
private volatile int currenttime = 0;
|
||||
private volatile int lastTimeElapsed = 0;
|
||||
private volatile int BytesSent = 0;
|
||||
private int oversizedImages = 0;
|
||||
public CapsDataThrottler(int pBytes, int max, int min)
|
||||
{
|
||||
ThrottleBytes = pBytes;
|
||||
lastTimeElapsed = Util.EnvironmentTickCount();
|
||||
}
|
||||
public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses)
|
||||
{
|
||||
PassTime();
|
||||
// Note, this is called IN LOCK
|
||||
bool haskey = responses.ContainsKey(key);
|
||||
if (!haskey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetTextureModule.aPollResponse response;
|
||||
if (responses.TryGetValue(key, out response))
|
||||
{
|
||||
// This is any error response
|
||||
if (response.bytes == 0)
|
||||
return true;
|
||||
|
||||
// Normal
|
||||
if (BytesSent + response.bytes <= ThrottleBytes)
|
||||
{
|
||||
BytesSent += response.bytes;
|
||||
//TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
|
||||
//m_actions.Add(timeBasedAction);
|
||||
return true;
|
||||
}
|
||||
// Big textures
|
||||
else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes % 50000) + 1))
|
||||
{
|
||||
Interlocked.Increment(ref oversizedImages);
|
||||
BytesSent += response.bytes;
|
||||
//TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
|
||||
//m_actions.Add(timeBasedAction);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return haskey;
|
||||
}
|
||||
|
||||
public void ProcessTime()
|
||||
{
|
||||
PassTime();
|
||||
}
|
||||
|
||||
private void PassTime()
|
||||
{
|
||||
currenttime = Util.EnvironmentTickCount();
|
||||
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
|
||||
//processTimeBasedActions(responses);
|
||||
if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
|
||||
{
|
||||
lastTimeElapsed = Util.EnvironmentTickCount();
|
||||
BytesSent -= ThrottleBytes;
|
||||
if (BytesSent < 0) BytesSent = 0;
|
||||
if (BytesSent < ThrottleBytes)
|
||||
{
|
||||
oversizedImages = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
public int ThrottleBytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -129,15 +129,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
|||
// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request");
|
||||
|
||||
OSDMap data = new OSDMap();
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentID);
|
||||
data["username"] = sp.Firstname + "." + sp.Lastname;
|
||||
data["display_name_next_update"] = new OSDDate(DateTime.Now);
|
||||
data["legacy_first_name"] = sp.Firstname;
|
||||
// ScenePresence sp = m_scene.GetScenePresence(m_agentID);
|
||||
// data["username"] = sp.Firstname + "." + sp.Lastname;
|
||||
// data["display_name_next_update"] = new OSDDate(DateTime.Now);
|
||||
// data["legacy_first_name"] = sp.Firstname;
|
||||
data["mesh_upload_status"] = "valid";
|
||||
data["display_name"] = sp.Firstname + " " + sp.Lastname;
|
||||
data["legacy_last_name"] = sp.Lastname;
|
||||
data["id"] = agentID;
|
||||
data["is_display_name_default"] = true;
|
||||
// data["display_name"] = sp.Firstname + " " + sp.Lastname;
|
||||
// data["legacy_last_name"] = sp.Lastname;
|
||||
// data["id"] = m_agentID;
|
||||
// data["is_display_name_default"] = true;
|
||||
|
||||
//Send back data
|
||||
Hashtable responsedata = new Hashtable();
|
||||
|
|
|
@ -1,297 +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;
|
||||
using System.Collections.Specialized;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using Mono.Addins;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
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.Framework.Capabilities;
|
||||
using PermissionMask = OpenSim.Framework.PermissionMask;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "NewFileAgentInventoryVariablePriceModule")]
|
||||
public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
// private IAssetService m_assetService;
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private bool m_enabled = true;
|
||||
private int m_levelUpload = 0;
|
||||
|
||||
#region Region Module interfaceBase Members
|
||||
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig meshConfig = source.Configs["Mesh"];
|
||||
if (meshConfig == null)
|
||||
return;
|
||||
|
||||
m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
|
||||
m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene pScene)
|
||||
{
|
||||
m_scene = pScene;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
m_scene = null;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
|
||||
// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Region Module interface
|
||||
|
||||
|
||||
|
||||
public void Close() { }
|
||||
|
||||
public string Name { get { return "NewFileAgentInventoryVariablePriceModule"; } }
|
||||
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
if(!m_enabled)
|
||||
return;
|
||||
|
||||
UUID capID = UUID.Random();
|
||||
|
||||
// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
|
||||
caps.RegisterHandler(
|
||||
"NewFileAgentInventoryVariablePrice",
|
||||
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
|
||||
"POST",
|
||||
"/CAPS/" + capID.ToString(),
|
||||
req => NewAgentInventoryRequest(req, agentID),
|
||||
"NewFileAgentInventoryVariablePrice",
|
||||
agentID.ToString()));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
|
||||
{
|
||||
//TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
|
||||
// you need to be aware of this
|
||||
|
||||
//if (llsdRequest.asset_type == "texture" ||
|
||||
// llsdRequest.asset_type == "animation" ||
|
||||
// llsdRequest.asset_type == "sound")
|
||||
// {
|
||||
// check user level
|
||||
|
||||
ScenePresence avatar = null;
|
||||
IClientAPI client = null;
|
||||
m_scene.TryGetScenePresence(agentID, out avatar);
|
||||
|
||||
if (avatar != null)
|
||||
{
|
||||
client = avatar.ControllingClient;
|
||||
|
||||
if (avatar.UserLevel < m_levelUpload)
|
||||
{
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
errorResponse.rsvp = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
// check funds
|
||||
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
|
||||
|
||||
if (mm != null)
|
||||
{
|
||||
if (!mm.UploadCovered(agentID, mm.UploadCharge))
|
||||
{
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
errorResponse.rsvp = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
string assetName = llsdRequest.name;
|
||||
string assetDes = llsdRequest.description;
|
||||
string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/";
|
||||
UUID newAsset = UUID.Random();
|
||||
UUID newInvItem = UUID.Random();
|
||||
UUID parentFolder = llsdRequest.folder_id;
|
||||
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/";
|
||||
|
||||
AssetUploader uploader =
|
||||
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
||||
llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
|
||||
|
||||
MainServer.Instance.AddStreamHandler(
|
||||
new BinaryStreamHandler(
|
||||
"POST",
|
||||
capsBase + uploaderPath,
|
||||
uploader.uploaderCaps,
|
||||
"NewFileAgentInventoryVariablePrice",
|
||||
agentID.ToString()));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
if (MainServer.Instance.UseSSL)
|
||||
protocol = "https://";
|
||||
|
||||
string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
|
||||
uploaderPath;
|
||||
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
|
||||
uploadResponse.rsvp = uploaderURL;
|
||||
uploadResponse.state = "upload";
|
||||
uploadResponse.resource_cost = 0;
|
||||
uploadResponse.upload_price = 0;
|
||||
|
||||
uploader.OnUpLoad += //UploadCompleteHandler;
|
||||
|
||||
delegate(
|
||||
string passetName, string passetDescription, UUID passetID,
|
||||
UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType,
|
||||
string passetType)
|
||||
{
|
||||
UploadCompleteHandler(passetName, passetDescription, passetID,
|
||||
pinventoryItem, pparentFolder, pdata, pinventoryType,
|
||||
passetType,agentID);
|
||||
};
|
||||
|
||||
return uploadResponse;
|
||||
}
|
||||
|
||||
public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
|
||||
UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
|
||||
string assetType,UUID AgentID)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[NEW FILE AGENT INVENTORY VARIABLE PRICE MODULE]: Upload complete for {0}", inventoryItem);
|
||||
|
||||
sbyte assType = 0;
|
||||
sbyte inType = 0;
|
||||
|
||||
if (inventoryType == "sound")
|
||||
{
|
||||
inType = 1;
|
||||
assType = 1;
|
||||
}
|
||||
else if (inventoryType == "animation")
|
||||
{
|
||||
inType = 19;
|
||||
assType = 20;
|
||||
}
|
||||
else if (inventoryType == "wearable")
|
||||
{
|
||||
inType = 18;
|
||||
switch (assetType)
|
||||
{
|
||||
case "bodypart":
|
||||
assType = 13;
|
||||
break;
|
||||
case "clothing":
|
||||
assType = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (inventoryType == "mesh")
|
||||
{
|
||||
inType = (sbyte)InventoryType.Mesh;
|
||||
assType = (sbyte)AssetType.Mesh;
|
||||
}
|
||||
|
||||
AssetBase asset;
|
||||
asset = new AssetBase(assetID, assetName, assType, AgentID.ToString());
|
||||
asset.Data = data;
|
||||
|
||||
if (m_scene.AssetService != null)
|
||||
m_scene.AssetService.Store(asset);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
item.Owner = AgentID;
|
||||
item.CreatorId = AgentID.ToString();
|
||||
item.ID = inventoryItem;
|
||||
item.AssetID = asset.FullID;
|
||||
item.Description = assetDescription;
|
||||
item.Name = assetName;
|
||||
item.AssetType = assType;
|
||||
item.InvType = inType;
|
||||
item.Folder = parentFolder;
|
||||
item.CurrentPermissions
|
||||
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
|
||||
item.BasePermissions = (uint)PermissionMask.All;
|
||||
item.EveryOnePermissions = 0;
|
||||
item.NextPermissions = (uint)PermissionMask.All;
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
m_scene.AddInventoryItem(item);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue