bad merge?

avinationmerge
UbitUmarov 2015-09-01 14:54:35 +01:00
commit 371c9dd2af
406 changed files with 62562 additions and 8067 deletions

3
.gitignore vendored
View File

@ -1,5 +1,6 @@
.project .project
.settings .settings
.gitignore
*.csproj *.csproj
*.csproj.user *.csproj.user
*.build *.build
@ -10,6 +11,7 @@
*.pidb *.pidb
*.dll.build *.dll.build
*.dll *.dll
*.log
# Ignore .user and .suo files as these are user preference specific # 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 # 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 */*/*/*/*/*/bin
*/*/*/*/*/*/*/bin */*/*/*/*/*/*/bin
addon-modules/
bin/Debug/*.dll bin/Debug/*.dll
bin/*.dll.mdb bin/*.dll.mdb
bin/*.db bin/*.db

View File

@ -75,6 +75,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
private string m_name = "RemoteAdminPlugin"; private string m_name = "RemoteAdminPlugin";
private string m_version = "0.0"; private string m_version = "0.0";
private string m_openSimVersion;
public string Version public string Version
{ {
@ -94,6 +95,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
public void Initialise(OpenSimBase openSim) public void Initialise(OpenSimBase openSim)
{ {
m_openSimVersion = openSim.GetVersionText();
m_configSource = openSim.ConfigSource.Source; m_configSource = openSim.ConfigSource.Source;
try try
{ {
@ -136,6 +139,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod); availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod);
availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod); availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod);
availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod); 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_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod);
availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod); availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod);
availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod); 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_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload); availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
// Land management // Misc
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand); 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 // Either enable full remote functionality or just selected features
string enabledMethods = m_config.GetString("enabled_methods", "all"); string enabledMethods = m_config.GetString("enabled_methods", "all");
@ -266,26 +273,106 @@ namespace OpenSim.ApplicationPlugins.RemoteController
try try
{ {
m_log.Info("[RADMIN]: Request to restart Region."); Scene rebootedScene = null;
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); CheckRegionParams(requestData, responseData);
Scene rebootedScene = null;
GetSceneFromRegionParams(requestData, responseData, out rebootedScene); GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
}
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
responseData["success"] = false; responseData["success"] = false;
responseData["accepted"] = true; responseData["accepted"] = true;
responseData["rebooting"] = true; responseData["rebooting"] = true;
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>(); string message;
List<int> times = new List<int>();
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) if (restartModule != null)
{ {
List<int> times = new List<int> { 30, 15 }; message = "Restart has been cancelled";
if (requestData.ContainsKey("message"))
message = requestData["message"].ToString();
restartModule.AbortRestart(message);
restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
responseData["success"] = true; 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) catch (Exception e)
{ {
// m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace); // m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
@ -321,6 +408,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
m_log.Info("[RADMIN]: Alert request complete"); 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) private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{ {
m_log.Info("[RADMIN]: Load height maps request started"); m_log.Info("[RADMIN]: Load height maps request started");
@ -424,6 +537,23 @@ namespace OpenSim.ApplicationPlugins.RemoteController
message = "Region is going down now."; message = "Region is going down now.";
} }
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( m_application.SceneManager.ForEachScene(
delegate(Scene scene) delegate(Scene scene)
{ {
@ -431,6 +561,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
if (dialogModule != null) if (dialogModule != null)
dialogModule.SendGeneralAlert(message); dialogModule.SendGeneralAlert(message);
}); });
}
}
// Perform shutdown // Perform shutdown
System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing 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>(); 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 (mergeOar) archiveOptions.Add("merge", null);
if (skipAssets) archiveOptions.Add("skipAssets", null); if (skipAssets) archiveOptions.Add("skipAssets", null);
if (archiver != null) if (archiver != null)
@ -1749,21 +1881,31 @@ namespace OpenSim.ApplicationPlugins.RemoteController
private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{ {
m_log.Info("[RADMIN]: Received Query XML Administrator Request");
Hashtable responseData = (Hashtable)response.Value; Hashtable responseData = (Hashtable)response.Value;
Hashtable requestData = (Hashtable)request.Params[0]; Hashtable requestData = (Hashtable)request.Params[0];
int flags = 0;
string text = String.Empty;
int health = 0;
responseData["success"] = true;
CheckRegionParams(requestData, responseData); CheckRegionParams(requestData, responseData);
Scene scene = null; Scene scene = null;
try
{
GetSceneFromRegionParams(requestData, responseData, out scene); GetSceneFromRegionParams(requestData, responseData, out scene);
health = scene.GetHealth(out flags, out text);
int health = scene.GetHealth(); }
responseData["health"] = health; catch (Exception e)
{
responseData["error"] = null;
}
responseData["success"] = true; 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) private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
@ -2068,55 +2210,97 @@ namespace OpenSim.ApplicationPlugins.RemoteController
responseData["success"] = true; responseData["success"] = true;
} }
private void XmlRpcResetLand(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{ {
m_log.Info("[RADMIN]: Received Refresh Search Request");
Hashtable responseData = (Hashtable)response.Value;
Hashtable requestData = (Hashtable)request.Params[0]; Hashtable requestData = (Hashtable)request.Params[0];
CheckRegionParams(requestData, responseData);
Scene scene = null;
GetSceneFromRegionParams(requestData, responseData, out scene);
ISearchModule searchModule = scene.RequestModuleInterface<ISearchModule>();
if (searchModule != null)
{
searchModule.Refresh();
responseData["success"] = true;
}
else
{
responseData["success"] = false;
}
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; Hashtable responseData = (Hashtable)response.Value;
string musicURL = string.Empty; responseData["version"] = m_openSimVersion;
UUID groupID = UUID.Zero;
uint flags = 0;
bool set_group = false, set_music = false, set_flags = false;
if (requestData.Contains("group") && requestData["group"] != null)
set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
if (requestData.Contains("music") && requestData["music"] != null)
{
musicURL = requestData["music"].ToString();
set_music = 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)
{
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"] = true; responseData["success"] = true;
m_log.Info("[RADMIN]: Reset Land Request complete"); 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> /// <summary>
/// Parse a float with the given parameter name from a request data hash table. /// Parse a float with the given parameter name from a request data hash table.
@ -2823,7 +3007,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
/// </summary> /// </summary>
private void ApplyNextOwnerPermissions(InventoryItemBase item) 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; uint perms = item.CurrentPermissions;
PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms); PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms);

View File

@ -30,6 +30,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
@ -71,6 +72,7 @@ namespace OpenSim.Framework.Capabilities
private IHttpServer m_httpListener; private IHttpServer m_httpListener;
private UUID m_agentID; private UUID m_agentID;
private string m_regionName; private string m_regionName;
private ManualResetEvent m_capsActive = new ManualResetEvent(false);
public UUID AgentID public UUID AgentID
{ {
@ -136,6 +138,7 @@ namespace OpenSim.Framework.Capabilities
m_agentID = agent; m_agentID = agent;
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
m_regionName = regionName; m_regionName = regionName;
m_capsActive.Reset();
} }
/// <summary> /// <summary>
@ -255,5 +258,16 @@ namespace OpenSim.Framework.Capabilities
return caps; 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);
}
} }
} }

View File

@ -90,6 +90,7 @@ namespace OpenSim.Framework.Capabilities
lock (m_capsHandlers) lock (m_capsHandlers)
{ {
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path); 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_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName); m_capsHandlers.Remove(capsName);
} }

View File

@ -114,7 +114,7 @@ namespace OpenSim.Capabilities.Handlers
llsdItem.asset_id = invItem.AssetID; llsdItem.asset_id = invItem.AssetID;
llsdItem.created_at = invItem.CreationDate; llsdItem.created_at = invItem.CreationDate;
llsdItem.desc = invItem.Description; llsdItem.desc = invItem.Description;
llsdItem.flags = (int)invItem.Flags; llsdItem.flags = ((int)invItem.Flags) & 0xff;
llsdItem.item_id = invItem.ID; llsdItem.item_id = invItem.ID;
llsdItem.name = invItem.Name; llsdItem.name = invItem.Name;
llsdItem.parent_id = invItem.Folder; llsdItem.parent_id = invItem.Folder;

View File

@ -45,25 +45,63 @@ namespace OpenSim.Capabilities.Handlers
{ {
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IAssetService m_assetService; private IAssetService m_assetService;
// TODO: Change this to a config option public const string DefaultFormat = "vnd.ll.mesh";
private string m_RedirectURL = null;
public GetMeshHandler(string path, IAssetService assService, string name, string description, string redirectURL) public GetMeshHandler(IAssetService assService)
: base("GET", path, name, description)
{ {
m_assetService = assService; m_assetService = assService;
m_RedirectURL = redirectURL; m_RedirectURL = redirectURL;
if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/")) if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
m_RedirectURL += "/"; 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 // Try to parse the texture ID from the request URL
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string textureStr = query.GetOne("mesh_id"); string textureStr = query.GetOne("mesh_id");
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 0;
responsedata["int_bytes"] = 0;
if (m_assetService == null) if (m_assetService == null)
{ {
@ -160,40 +198,121 @@ namespace OpenSim.Capabilities.Handlers
// sending back the last byte instead of an error status // sending back the last byte instead of an error status
if (start >= texture.Data.Length) if (start >= texture.Data.Length)
{ {
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response.ContentType = texture.Metadata.ContentType; Hashtable headers = new Hashtable();
responsedata["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)) // Mesh Asset LOD // Physics
{
// 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 else
{ {
// Handle the case where no second range value was given. This is equivalent to requesting end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
// 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); start = Utils.Clamp(start, 0, end);
int len = end - start + 1; int len = end - start + 1;
if (0 == start && len == texture.Data.Length) //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
if (start > 20000)
{ {
response.StatusCode = (int)System.Net.HttpStatusCode.OK; responsedata["int_lod"] = 3;
}
else if (start < 4097)
{
responsedata["int_lod"] = 1;
} }
else else
{ {
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; responsedata["int_lod"] = 2;
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
} }
response.ContentLength = len;
response.ContentType = "application/vnd.ll.mesh";
response.Body.Write(texture.Data, start, len); 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 else
{ {
m_log.Warn("[GETMESH]: Malformed Range header: " + range); m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; 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
{
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
{
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
{
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 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; start = end = 0;
return false; return false;
} }

View File

@ -47,10 +47,11 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Capabilities.Handlers namespace OpenSim.Capabilities.Handlers
{ {
public class GetTextureHandler : BaseStreamHandler public class GetTextureHandler
{ {
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IAssetService m_assetService; private IAssetService m_assetService;
public const string DefaultFormat = "x-j2c"; public const string DefaultFormat = "x-j2c";
@ -58,8 +59,8 @@ namespace OpenSim.Capabilities.Handlers
// TODO: Change this to a config option // TODO: Change this to a config option
private string m_RedirectURL = null; 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_assetService = assService;
m_RedirectURL = redirectURL; m_RedirectURL = redirectURL;
@ -67,19 +68,22 @@ namespace OpenSim.Capabilities.Handlers
m_RedirectURL += "/"; 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 Hashtable ret = new Hashtable();
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
string textureStr = query.GetOne("texture_id"); ret["content_type"] = "text/plain";
string format = query.GetOne("format"); 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); //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
if (m_assetService == null) if (m_assetService == null)
{ {
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
} }
UUID textureID; UUID textureID;
@ -94,30 +98,41 @@ namespace OpenSim.Capabilities.Handlers
} }
else 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) if (formats.Length == 0)
formats = new string[1] { DefaultFormat }; // default formats = new string[1] { DefaultFormat }; // default
} }
// OK, we have an array with preferred formats, possibly with only one entry // OK, we have an array with preferred formats, possibly with only one entry
bool foundtexture = false;
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
foreach (string f in formats) foreach (string f in formats)
{ {
if (FetchTexture(httpRequest, httpResponse, textureID, f)) foundtexture = FetchTexture(request, ret, textureID, f);
if (foundtexture)
break; 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 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( // m_log.DebugFormat(
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", // "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
// textureID, httpResponse.StatusCode, httpResponse.ContentLength); // textureID, httpResponse.StatusCode, httpResponse.ContentLength);
return ret;
return null;
} }
/// <summary> /// <summary>
@ -128,7 +143,7 @@ namespace OpenSim.Capabilities.Handlers
/// <param name="textureID"></param> /// <param name="textureID"></param>
/// <param name="format"></param> /// <param name="format"></param>
/// <returns>False for "caller try another codec"; true otherwise</returns> /// <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); // m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
AssetBase texture; AssetBase texture;
@ -137,37 +152,12 @@ namespace OpenSim.Capabilities.Handlers
if (format != DefaultFormat) if (format != DefaultFormat)
fullID = fullID + "-" + format; fullID = fullID + "-" + format;
if (!String.IsNullOrEmpty(m_RedirectURL))
{
// Only try to fetch locally cached textures. Misses are redirected
texture = m_assetService.GetCached(fullID);
if (texture != null)
{
if (texture.Type != (sbyte)AssetType.Texture)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
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 // try the cache
texture = m_assetService.GetCached(fullID); texture = m_assetService.GetCached(fullID);
if (texture == null) if (texture == null)
{ {
// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
// Fetch locally or remotely. Misses return a 404 // Fetch locally or remotely. Misses return a 404
texture = m_assetService.Get(textureID.ToString()); texture = m_assetService.Get(textureID.ToString());
@ -175,13 +165,11 @@ namespace OpenSim.Capabilities.Handlers
if (texture != null) if (texture != null)
{ {
if (texture.Type != (sbyte)AssetType.Texture) if (texture.Type != (sbyte)AssetType.Texture)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true; return true;
}
if (format == DefaultFormat) if (format == DefaultFormat)
{ {
WriteTextureData(httpRequest, httpResponse, texture, format); WriteTextureData(request, response, texture, format);
return true; return true;
} }
else else
@ -195,28 +183,39 @@ namespace OpenSim.Capabilities.Handlers
newTexture.Temporary = true; newTexture.Temporary = true;
newTexture.Local = true; newTexture.Local = true;
m_assetService.Store(newTexture); m_assetService.Store(newTexture);
WriteTextureData(httpRequest, httpResponse, newTexture, format); WriteTextureData(request, response, newTexture, format);
return true; return true;
} }
} }
} }
else // it was on the cache else // it was on the cache
{ {
// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
WriteTextureData(httpRequest, httpResponse, texture, format); WriteTextureData(request, response, texture, format);
return true; return true;
} }
}
//response = new Hashtable();
//WriteTextureData(request,response,null,format);
// not found // not found
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); //m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; return false;
return true;
} }
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 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. // However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; // response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length)); // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
// response.StatusCode = (int)System.Net.HttpStatusCode.OK; response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response.ContentType = texture.Metadata.ContentType;
} }
else 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); // 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 response["content-type"] = texture.Metadata.ContentType;
// 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.ContentLength = len; if (start == 0 && len == texture.Data.Length) // well redudante maybe
response.ContentType = texture.Metadata.ContentType; {
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); 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 else
{ {
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); 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 else // JP2's or other formats
{ {
// Full content request // Full content request
response.StatusCode = (int)System.Net.HttpStatusCode.OK; response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
response.ContentLength = texture.Data.Length;
if (format == DefaultFormat) if (format == DefaultFormat)
response.ContentType = texture.Metadata.ContentType; response["content_type"] = texture.Metadata.ContentType;
else else
response.ContentType = "image/" + format; response["content_type"] = "image/" + format;
response.Body.Write(texture.Data, 0, texture.Data.Length);
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) // if (response.StatusCode < 200 || response.StatusCode > 299)

View File

@ -33,6 +33,7 @@ using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base; using OpenSim.Server.Handlers.Base;
using OpenMetaverse; using OpenMetaverse;
/*
namespace OpenSim.Capabilities.Handlers namespace OpenSim.Capabilities.Handlers
{ {
public class GetTextureServerConnector : ServiceConnector public class GetTextureServerConnector : ServiceConnector
@ -69,3 +70,4 @@ namespace OpenSim.Capabilities.Handlers
} }
} }
} }
*/

View File

@ -38,6 +38,7 @@ using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
/*
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
{ {
[TestFixture] [TestFixture]
@ -60,3 +61,4 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
} }
} }
} }
*/

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
@ -50,6 +51,7 @@ namespace OpenSim.Capabilities.Handlers
{ {
public class UploadBakedTextureHandler public class UploadBakedTextureHandler
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Caps m_HostCapsObj; private Caps m_HostCapsObj;
@ -81,7 +83,7 @@ namespace OpenSim.Capabilities.Handlers
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
BakedTextureUploader uploader = BakedTextureUploader uploader =
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener); new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_HostCapsObj.AgentID);
uploader.OnUpLoad += BakedTextureUploaded; uploader.OnUpLoad += BakedTextureUploaded;
m_HostCapsObj.HttpListener.AddStreamHandler( m_HostCapsObj.HttpListener.AddStreamHandler(
@ -117,7 +119,7 @@ namespace OpenSim.Capabilities.Handlers
/// <param name="data"></param> /// <param name="data"></param>
private void BakedTextureUploaded(UUID assetID, byte[] data) 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; AssetBase asset;
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString()); 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.Temporary = true;
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
m_assetService.Store(asset); m_assetService.Store(asset);
} }
} }
@ -137,15 +140,19 @@ namespace OpenSim.Capabilities.Handlers
private string uploaderPath = String.Empty; private string uploaderPath = String.Empty;
private UUID newAssetID; private UUID newAssetID;
private IHttpServer httpListener; 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(); newAssetID = UUID.Random();
uploaderPath = path; uploaderPath = path;
httpListener = httpServer; httpListener = httpServer;
AgentId = uUID;
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID); // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
} }
/// <summary> /// <summary>
/// Handle raw uploaded baked texture data. /// Handle raw uploaded baked texture data.
/// </summary> /// </summary>

View File

@ -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;
}
}
}

View File

@ -30,12 +30,15 @@ using OpenMetaverse;
namespace OpenSim.Framework.Capabilities namespace OpenSim.Framework.Capabilities
{ {
[LLSDType("MAP")] [LLSDType("MAP")]
public class LLSDAssetUploadComplete public class LLSDAssetUploadComplete
{ {
public string new_asset = String.Empty; public string new_asset = String.Empty;
public UUID new_inventory_item = UUID.Zero; public UUID new_inventory_item = UUID.Zero;
// public UUID new_texture_folder_id = UUID.Zero;
public string state = String.Empty; public string state = String.Empty;
public LLSDAssetUploadError error = null;
//public bool success = false; //public bool success = false;
public LLSDAssetUploadComplete() public LLSDAssetUploadComplete()

View File

@ -30,15 +30,28 @@ using OpenMetaverse;
namespace OpenSim.Framework.Capabilities 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] [OSDMap]
public class LLSDAssetUploadRequest public class LLSDAssetUploadRequest
{ {
public string asset_type = String.Empty; public string asset_type = String.Empty;
public string description = String.Empty; public string description = String.Empty;
public UUID folder_id = UUID.Zero; 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 inventory_type = String.Empty;
public string name = String.Empty; public string name = String.Empty;
public LLSDAssetResource asset_resources = new LLSDAssetResource();
public LLSDAssetUploadRequest() public LLSDAssetUploadRequest()
{ {
} }

View File

@ -26,20 +26,51 @@
*/ */
using System; using System;
using OpenMetaverse;
namespace OpenSim.Framework.Capabilities 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] [OSDMap]
public class LLSDAssetUploadResponse public class LLSDAssetUploadResponse
{ {
public string uploader = String.Empty; public string uploader = String.Empty;
public string state = String.Empty; public string state = String.Empty;
public int upload_price = 0;
public LLSDAssetUploadResponseData data = null;
public LLSDAssetUploadError error = null;
public LLSDAssetUploadResponse() public LLSDAssetUploadResponse()
{ {
} }
} }
[OSDMap] [OSDMap]
public class LLSDNewFileAngentInventoryVariablePriceReplyResponse public class LLSDNewFileAngentInventoryVariablePriceReplyResponse
{ {

View File

@ -37,7 +37,7 @@ namespace OpenSim.Data
public abstract class AssetDataBase : IAssetDataPlugin public abstract class AssetDataBase : IAssetDataPlugin
{ {
public abstract AssetBase GetAsset(UUID uuid); 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 bool[] AssetsExist(UUID[] uuids);
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count); public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);

View File

@ -34,7 +34,7 @@ namespace OpenSim.Data
public interface IAssetDataPlugin : IPlugin public interface IAssetDataPlugin : IPlugin
{ {
AssetBase GetAsset(UUID uuid); AssetBase GetAsset(UUID uuid);
void StoreAsset(AssetBase asset); bool StoreAsset(AssetBase asset);
bool[] AssetsExist(UUID[] uuids); bool[] AssetsExist(UUID[] uuids);
List<AssetMetadata> FetchAssetMetadataSet(int start, int count); List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
void Initialise(string connect); void Initialise(string connect);

View File

@ -48,8 +48,6 @@ namespace OpenSim.Data
bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result); bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
bool UpdateAvatarInterests(UserProfileProperties up, ref string result); bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
bool GetClassifiedInfo(ref UserClassifiedAdd ad, 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 GetUserAppData(ref UserAppData props, ref string result);
bool SetUserAppData(UserAppData props, ref string result); bool SetUserAppData(UserAppData props, ref string result);
OSDArray GetUserImageAssets(UUID avatarId); OSDArray GetUserImageAssets(UUID avatarId);

View File

@ -50,5 +50,6 @@ namespace OpenSim.Data
bool Store(UserAccountData data); bool Store(UserAccountData data);
bool Delete(string field, string val); bool Delete(string field, string val);
UserAccountData[] GetUsers(UUID scopeID, string query); UserAccountData[] GetUsers(UUID scopeID, string query);
UserAccountData[] GetUsersWhere(UUID scopeID, string where);
} }
} }

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *

View File

@ -154,7 +154,7 @@ namespace OpenSim.Data.MySQL
/// </summary> /// </summary>
/// <param name="asset">Asset UUID to create</param> /// <param name="asset">Asset UUID to create</param>
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> /// <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)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -203,6 +203,43 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?data", asset.Data); cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery(); 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) catch (Exception e)
{ {

View File

@ -45,24 +45,43 @@ namespace OpenSim.Data.MySQL
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected string m_connectionString; protected string m_connectionString;
protected object m_dbLock = new object();
protected MySqlFramework(string connectionString) protected MySqlFramework(string connectionString)
{ {
m_connectionString = connectionString; m_connectionString = connectionString;
} }
//////////////////////////////////////////////////////////////
//
// All non queries are funneled through one connection
// to increase performance a little
//
protected int ExecuteNonQuery(MySqlCommand cmd) protected int ExecuteNonQuery(MySqlCommand cmd)
{ {
lock (m_dbLock)
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
dbcon.Open(); dbcon.Open();
cmd.Connection = dbcon; cmd.Connection = dbcon;
try
{
dbcon.Open();
cmd.Connection = dbcon;
try try
{ {
return cmd.ExecuteNonQuery(); return cmd.ExecuteNonQuery();
} }
catch (Exception e) catch (Exception e)
{
m_log.Error(e.Message, e);
m_log.Error(Environment.StackTrace.ToString());
return 0;
}
}
catch (Exception e)
{ {
m_log.Error(e.Message, e); m_log.Error(e.Message, e);
return 0; return 0;

View File

@ -175,6 +175,11 @@ namespace OpenSim.Data.MySQL
int v = Convert.ToInt32(reader[name]); int v = Convert.ToInt32(reader[name]);
m_Fields[name].SetValue(row, v); 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 else
{ {
m_Fields[name].SetValue(row, reader[name]); m_Fields[name].SetValue(row, reader[name]);

View File

@ -82,6 +82,7 @@ namespace OpenSim.Data.MySQL
public RegionData Get(int posX, int posY, UUID scopeID) public RegionData Get(int posX, int posY, UUID scopeID)
{ {
/* fixed size regions
string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY"; string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY";
if (scopeID != UUID.Zero) if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID"; command += " and ScopeID = ?scopeID";
@ -98,6 +99,45 @@ namespace OpenSim.Data.MySQL
return ret[0]; 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) 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) 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"; string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY";
if (scopeID != UUID.Zero) if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID"; command += " and ScopeID = ?scopeID";
@ -135,6 +176,38 @@ namespace OpenSim.Data.MySQL
return RunCommand(cmd); 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) public List<RegionData> RunCommand(MySqlCommand cmd)

View File

@ -76,7 +76,7 @@ namespace OpenSim.Data.MySQL
Initialise(connectionString); Initialise(connectionString);
} }
public void Initialise(string connectionString) public virtual void Initialise(string connectionString)
{ {
m_connectionString = connectionString; m_connectionString = connectionString;
@ -123,7 +123,7 @@ namespace OpenSim.Data.MySQL
public void Dispose() {} public void Dispose() {}
public void StoreObject(SceneObjectGroup obj, UUID regionUUID) public virtual void StoreObject(SceneObjectGroup obj, UUID regionUUID)
{ {
uint flags = obj.RootPart.GetEffectiveObjectFlags(); uint flags = obj.RootPart.GetEffectiveObjectFlags();
@ -183,10 +183,11 @@ namespace OpenSim.Data.MySQL
"ParticleSystem, ClickAction, Material, " + "ParticleSystem, ClickAction, Material, " +
"CollisionSound, CollisionSoundVolume, " + "CollisionSound, CollisionSoundVolume, " +
"PassTouches, " + "PassTouches, " +
"LinkNumber, MediaURL, AttachedPosX, " + "PassCollisions, " +
"AttachedPosY, AttachedPosZ, KeyframeMotion, " + "LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " +
"AttachedPosY, AttachedPosZ, " +
"PhysicsShapeType, Density, GravityModifier, " + "PhysicsShapeType, Density, GravityModifier, " +
"Friction, Restitution, DynAttrs " + "Friction, Restitution, Vehicle, DynAttrs " +
") values (" + "?UUID, " + ") values (" + "?UUID, " +
"?CreationDate, ?Name, ?Text, " + "?CreationDate, ?Name, ?Text, " +
"?Description, ?SitName, ?TouchName, " + "?Description, ?SitName, ?TouchName, " +
@ -218,11 +219,11 @@ namespace OpenSim.Data.MySQL
"?SaleType, ?ColorR, ?ColorG, " + "?SaleType, ?ColorR, ?ColorG, " +
"?ColorB, ?ColorA, ?ParticleSystem, " + "?ColorB, ?ColorA, ?ParticleSystem, " +
"?ClickAction, ?Material, ?CollisionSound, " + "?ClickAction, ?Material, ?CollisionSound, " +
"?CollisionSoundVolume, ?PassTouches, " + "?CollisionSoundVolume, ?PassTouches, ?PassCollisions, " +
"?LinkNumber, ?MediaURL, ?AttachedPosX, " + "?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " +
"?AttachedPosY, ?AttachedPosZ, ?KeyframeMotion, " + "?AttachedPosY, ?AttachedPosZ, " +
"?PhysicsShapeType, ?Density, ?GravityModifier, " + "?PhysicsShapeType, ?Density, ?GravityModifier, " +
"?Friction, ?Restitution, ?DynAttrs)"; "?Friction, ?Restitution, ?Vehicle, ?DynAttrs)";
FillPrimCommand(cmd, prim, obj.UUID, regionUUID); 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); // 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> /// <param name="uuid">the Item UUID</param>
private void RemoveItems(UUID uuid) private void RemoveItems(UUID uuid)
{ {
lock (m_dbLock) // locked by caller
// lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 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; const int ROWS_PER_QUERY = 5000;
@ -590,6 +592,10 @@ namespace OpenSim.Data.MySQL
public void StoreTerrain(TerrainData terrData, UUID regionID) public void StoreTerrain(TerrainData terrData, UUID regionID)
{ {
Util.FireAndForget(delegate(object x)
{
m_log.Info("[REGION DB]: Storing terrain");
lock (m_dbLock) lock (m_dbLock)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
@ -601,29 +607,38 @@ namespace OpenSim.Data.MySQL
cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID"; cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID";
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
ExecuteNonQuery(cmd); using (MySqlCommand cmd2 = dbcon.CreateCommand())
{
try
{
cmd2.CommandText = "insert into terrain (RegionUUID, " +
"Revision, Heightfield) values (?RegionUUID, " +
"?Revision, ?Heightfield)";
int terrainDBRevision; int terrainDBRevision;
Array terrainDBblob; Array terrainDBblob;
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
m_log.InfoFormat("{0} Storing terrain. X={1}, Y={2}, rev={3}", cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString());
LogHeader, terrData.SizeX, terrData.SizeY, terrainDBRevision); cmd2.Parameters.AddWithValue("Revision", terrainDBRevision);
cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob);
cmd.CommandText = "insert into terrain (RegionUUID, Revision, Heightfield)"
+ "values (?RegionUUID, ?Revision, ?Heightfield)";
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 // Legacy region loading
public double[,] LoadTerrain(UUID regionID) public virtual double[,] LoadTerrain(UUID regionID)
{ {
double[,] ret = null; double[,] ret = null;
TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
@ -655,6 +670,8 @@ namespace OpenSim.Data.MySQL
while (reader.Read()) while (reader.Read())
{ {
int rev = Convert.ToInt32(reader["Revision"]); int rev = Convert.ToInt32(reader["Revision"]);
if ((reader["Heightfield"] != DBNull.Value))
{
byte[] blob = (byte[])reader["Heightfield"]; byte[] blob = (byte[])reader["Heightfield"];
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
} }
@ -662,11 +679,12 @@ namespace OpenSim.Data.MySQL
} }
} }
} }
}
return terrData; return terrData;
} }
public void RemoveLandObject(UUID globalID) public virtual void RemoveLandObject(UUID globalID)
{ {
lock (m_dbLock) 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) lock (m_dbLock)
{ {
@ -705,7 +723,8 @@ namespace OpenSim.Data.MySQL
"UserLocationX, UserLocationY, UserLocationZ, " + "UserLocationX, UserLocationY, UserLocationZ, " +
"UserLookAtX, UserLookAtY, UserLookAtZ, " + "UserLookAtX, UserLookAtY, UserLookAtZ, " +
"AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " + "AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " +
"MediaSize, MediaLoop, ObscureMusic, ObscureMedia) values (" + "MediaSize, MediaLoop, ObscureMusic, ObscureMedia, " +
"SeeAVs, AnyAVSounds, GroupAVSounds) values (" +
"?UUID, ?RegionUUID, " + "?UUID, ?RegionUUID, " +
"?LocalLandID, ?Bitmap, ?Name, ?Description, " + "?LocalLandID, ?Bitmap, ?Name, ?Description, " +
"?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " + "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " +
@ -716,7 +735,8 @@ namespace OpenSim.Data.MySQL
"?UserLocationX, ?UserLocationY, ?UserLocationZ, " + "?UserLocationX, ?UserLocationY, ?UserLocationZ, " +
"?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " + "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " +
"?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+ "?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); 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(); RegionLightShareData nWP = new RegionLightShareData();
nWP.OnSave += StoreRegionWindlightSettings; nWP.OnSave += StoreRegionWindlightSettings;
@ -840,7 +860,7 @@ namespace OpenSim.Data.MySQL
return nWP; return nWP;
} }
public RegionSettings LoadRegionSettings(UUID regionUUID) public virtual RegionSettings LoadRegionSettings(UUID regionUUID)
{ {
RegionSettings rs = null; RegionSettings rs = null;
@ -880,7 +900,7 @@ namespace OpenSim.Data.MySQL
return rs; return rs;
} }
public void StoreRegionWindlightSettings(RegionLightShareData wl) public virtual void StoreRegionWindlightSettings(RegionLightShareData wl)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 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)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -1060,7 +1080,7 @@ namespace OpenSim.Data.MySQL
} }
#endregion #endregion
public void StoreRegionSettings(RegionSettings rs) public virtual void StoreRegionSettings(RegionSettings rs)
{ {
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{ {
@ -1105,7 +1125,44 @@ namespace OpenSim.Data.MySQL
"?TerrainImageID, " + "?TerrainImageID, " +
"?TelehubObject, ?ParcelImageID)"; "?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); ExecuteNonQuery(cmd);
} }
@ -1114,7 +1171,7 @@ namespace OpenSim.Data.MySQL
SaveSpawnPoints(rs); SaveSpawnPoints(rs);
} }
public List<LandData> LoadLandObjects(UUID regionUUID) public virtual List<LandData> LoadLandObjects(UUID regionUUID)
{ {
List<LandData> landData = new List<LandData>(); List<LandData> landData = new List<LandData>();
@ -1296,6 +1353,7 @@ namespace OpenSim.Data.MySQL
prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"]; prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"];
prim.PassTouches = ((sbyte)row["PassTouches"] != 0); prim.PassTouches = ((sbyte)row["PassTouches"] != 0);
prim.PassCollisions = ((sbyte)row["PassCollisions"] != 0);
prim.LinkNum = (int)row["LinkNumber"]; prim.LinkNum = (int)row["LinkNumber"];
if (!(row["MediaURL"] is System.DBNull)) if (!(row["MediaURL"] is System.DBNull))
@ -1334,6 +1392,15 @@ namespace OpenSim.Data.MySQL
prim.Friction = (float)(double)row["Friction"]; prim.Friction = (float)(double)row["Friction"];
prim.Restitution = (float)(double)row["Restitution"]; 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; return prim;
} }
@ -1343,6 +1410,8 @@ namespace OpenSim.Data.MySQL
/// <param name="row"></param> /// <param name="row"></param>
/// <returns></returns> /// <returns></returns>
private static TaskInventoryItem BuildItem(IDataReader row) private static TaskInventoryItem BuildItem(IDataReader row)
{
try
{ {
TaskInventoryItem taskItem = new TaskInventoryItem(); TaskInventoryItem taskItem = new TaskInventoryItem();
@ -1371,6 +1440,12 @@ namespace OpenSim.Data.MySQL
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) private static RegionSettings BuildRegionSettings(IDataReader row)
{ {
@ -1427,6 +1502,9 @@ namespace OpenSim.Data.MySQL
newSettings.ParcelImageID = DBGuid.FromDB(row["parcel_tile_ID"]); newSettings.ParcelImageID = DBGuid.FromDB(row["parcel_tile_ID"]);
newSettings.TelehubObject = DBGuid.FromDB(row["TelehubObject"]); newSettings.TelehubObject = DBGuid.FromDB(row["TelehubObject"]);
newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]);
newSettings.Casino = Convert.ToBoolean(row["casino"]);
return newSettings; return newSettings;
} }
@ -1503,6 +1581,13 @@ namespace OpenSim.Data.MySQL
newData.ParcelAccessList = new List<LandAccessEntry>(); 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; return newData;
} }
@ -1520,6 +1605,34 @@ namespace OpenSim.Data.MySQL
return entry; 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> /// <summary>
/// Fill the prim command with prim values /// Fill the prim command with prim values
/// </summary> /// </summary>
@ -1654,6 +1767,11 @@ namespace OpenSim.Data.MySQL
else else
cmd.Parameters.AddWithValue("PassTouches", 0); 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("LinkNumber", prim.LinkNum);
cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
if (prim.AttachedPos != null) if (prim.AttachedPos != null)
@ -1668,6 +1786,11 @@ namespace OpenSim.Data.MySQL
else else
cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]); 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) if (prim.DynAttrs.CountNamespaces > 0)
cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml()); cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml());
else else
@ -1756,6 +1879,8 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime); cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime);
cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID); cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID);
cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID); 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("ParcelImageID", settings.ParcelImageID);
cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject); cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject);
@ -1813,6 +1938,10 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop); cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop);
cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic); cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic);
cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia); 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> /// <summary>
@ -1919,7 +2048,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml()); 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) 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) private void LoadSpawnPoints(RegionSettings rs)
{ {
rs.ClearSpawnPoints(); rs.ClearSpawnPoints();

View File

@ -46,17 +46,21 @@ namespace OpenSim.Data.MySQL
{ {
string[] words = query.Split(new char[] {' '}); string[] words = query.Split(new char[] {' '});
bool valid = false;
for (int i = 0 ; i < words.Length ; i++) for (int i = 0 ; i < words.Length ; i++)
{ {
if (words[i].Length < 3) if (words[i].Length > 2)
{ valid = true;
if (i != words.Length - 1) // if (words[i].Length < 3)
Array.Copy(words, i + 1, words, i, words.Length - i - 1); // {
Array.Resize(ref words, words.Length - 1); // 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]; return new UserAccountData[0];
if (words.Length > 2) if (words.Length > 2)
@ -66,20 +70,36 @@ namespace OpenSim.Data.MySQL
{ {
if (words.Length == 1) 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.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("?search", words[0] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
} }
else 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.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("?searchFirst", words[0] + "%");
cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%"); cmd.Parameters.AddWithValue("?searchLast", words[1] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString()); cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
} }
return DoQuery(cmd); 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);
}
}
} }
} }

View File

@ -631,6 +631,8 @@ namespace OpenSim.Data.MySQL
{ {
if(reader.HasRows) if(reader.HasRows)
{ {
m_log.DebugFormat("[PROFILES_DATA]" +
": Getting data for {0}.", props.UserId);
reader.Read(); reader.Read();
props.WebUrl = (string)reader["profileURL"]; props.WebUrl = (string)reader["profileURL"];
UUID.TryParse((string)reader["profileImage"], out props.ImageId); UUID.TryParse((string)reader["profileImage"], out props.ImageId);
@ -646,6 +648,9 @@ namespace OpenSim.Data.MySQL
} }
else else
{ {
m_log.DebugFormat("[PROFILES_DATA]" +
": No data for {0}", props.UserId);
props.WebUrl = string.Empty; props.WebUrl = string.Empty;
props.ImageId = UUID.Zero; props.ImageId = UUID.Zero;
props.AboutText = string.Empty; props.AboutText = string.Empty;
@ -891,7 +896,7 @@ namespace OpenSim.Data.MySQL
} }
#region User Preferences #region User Preferences
public bool GetUserPreferences(ref UserPreferences pref, ref string result) public OSDArray GetUserPreferences(UUID avatarId)
{ {
string query = string.Empty; string query = string.Empty;
@ -908,16 +913,19 @@ namespace OpenSim.Data.MySQL
dbcon.Open(); dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) 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()) using (MySqlDataReader reader = cmd.ExecuteReader())
{ {
if(reader.HasRows) if(reader.HasRows)
{ {
reader.Read(); reader.Read();
bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail); OSDMap record = new OSDMap();
bool.TryParse((string)reader["visible"], out pref.Visible);
pref.EMail = (string)reader["email"]; 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 else
{ {
@ -930,8 +938,8 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand put = new MySqlCommand(query, dbcon)) using (MySqlCommand put = new MySqlCommand(query, dbcon))
{ {
put.Parameters.AddWithValue("?Email", pref.EMail); // put.Parameters.AddWithValue("?Email", pref.EMail);
put.Parameters.AddWithValue("?uuid", pref.UserId.ToString()); // put.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
put.ExecuteNonQuery(); put.ExecuteNonQuery();
} }
@ -944,17 +952,15 @@ namespace OpenSim.Data.MySQL
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]" +
": Get preferences exception {0}", e.Message); ": 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; string query = string.Empty;
query += "UPDATE usersettings SET "; query += "UPDATE userpsettings SET ";
query += "imviaemail=?ImViaEmail, "; query += "imviaemail=?ImViaEmail, ";
query += "visible=?Visible, "; query += "visible=?Visible, ";
query += "email=?EMail "; query += "email=?EMail ";
@ -980,7 +986,6 @@ namespace OpenSim.Data.MySQL
{ {
m_log.ErrorFormat("[PROFILES_DATA]" + m_log.ErrorFormat("[PROFILES_DATA]" +
": UserPreferencesUpdate exception {0} {1}", e.Message, e.InnerException); ": UserPreferencesUpdate exception {0} {1}", e.Message, e.InnerException);
result = e.Message;
return false; return false;
} }
return true; return true;

View File

@ -717,7 +717,7 @@ ALTER TABLE regionsettings ADD COLUMN loaded_creation_datetime int unsigned NOT
COMMIT; COMMIT;
:VERSION 32 :VERSION 32 #---------------------
BEGIN; BEGIN;
CREATE TABLE `regionwindlight` ( 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 prims ADD COLUMN AttachedPosZ double default 0;
ALTER TABLE primshapes ADD COLUMN LastAttachPoint int(4) not null default '0'; ALTER TABLE primshapes ADD COLUMN LastAttachPoint int(4) not null default '0';
COMMIT; COMMIT;
<<<<<<< HEAD
:VERSION 50 #---- Change LandFlags to unsigned :VERSION 50 #---- Change LandFlags to unsigned
@ -948,3 +949,5 @@ ALTER TABLE land CHANGE COLUMN LandFlags LandFlags int unsigned default null;
COMMIT; COMMIT;
=======
>>>>>>> avn/ubitvar

View File

@ -81,6 +81,7 @@ CREATE TABLE IF NOT EXISTS `userdata` (
commit; commit;
<<<<<<< HEAD
:VERSION 3 # ------------------------------- :VERSION 3 # -------------------------------
begin; begin;
CREATE TABLE IF NOT EXISTS `usersettings` ( CREATE TABLE IF NOT EXISTS `usersettings` (
@ -96,3 +97,5 @@ commit;
begin; begin;
ALTER TABLE userpicks ADD COLUMN gatekeeper varchar(255); ALTER TABLE userpicks ADD COLUMN gatekeeper varchar(255);
commit; commit;
=======
>>>>>>> avn/ubitvar

View File

@ -140,7 +140,8 @@ namespace OpenSim.Data.Null
{ {
foreach (RegionData r in m_regionData.Values) 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); ret.Add(r);
} }
} }
@ -176,7 +177,8 @@ namespace OpenSim.Data.Null
{ {
foreach (RegionData r in m_regionData.Values) foreach (RegionData r in m_regionData.Values)
{ {
if (r.posX >= startX && r.posX <= endX && r.posY >= startY && r.posY <= endY) if (r.posX + r.sizeX > startX && r.posX <= endX
&& r.posY + r.sizeX > startY && r.posY <= endY)
ret.Add(r); ret.Add(r);
} }
} }

View File

@ -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) public void SaveExtra(UUID regionID, string name, string value)
{ {
} }

View File

@ -193,5 +193,10 @@ namespace OpenSim.Data.Null
return false; return false;
} }
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
} }
} }

View File

@ -149,7 +149,7 @@ namespace OpenSim.Data.PGSQL
/// Create asset in m_database /// Create asset in m_database
/// </summary> /// </summary>
/// <param name="asset">the asset</param> /// <param name="asset">the asset</param>
override public void StoreAsset(AssetBase asset) override public bool StoreAsset(AssetBase asset)
{ {
string sql = string sql =
@ -208,6 +208,7 @@ namespace OpenSim.Data.PGSQL
m_log.Error("[ASSET DB]: Error storing item :" + e.Message + " sql "+sql); m_log.Error("[ASSET DB]: Error storing item :" + e.Message + " sql "+sql);
} }
} }
return true;
} }

View File

@ -325,5 +325,10 @@ namespace OpenSim.Data.PGSQL
return DoQuery(cmd); return DoQuery(cmd);
} }
} }
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
} }
} }

View File

@ -81,6 +81,7 @@ CREATE TABLE userdata (
commit; commit;
<<<<<<< HEAD
:VERSION 3 # ------------------------------- :VERSION 3 # -------------------------------
begin; begin;
CREATE TABLE usersettings ( 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; ALTER TABLE usersettings ALTER COLUMN imviaemail SET DATA TYPE boolean USING CASE WHEN false THEN false ELSE true END;
COMMIT; COMMIT;
=======
>>>>>>> avn/ubitvar

View File

@ -88,15 +88,3 @@ CREATE TABLE IF NOT EXISTS userdata (
commit; 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;

View File

@ -131,7 +131,7 @@ namespace OpenSim.Data.SQLite
/// Create an asset /// Create an asset
/// </summary> /// </summary>
/// <param name="asset">Asset Base</param> /// <param name="asset">Asset Base</param>
override public void StoreAsset(AssetBase asset) override public bool StoreAsset(AssetBase asset)
{ {
string assetName = asset.Name; string assetName = asset.Name;
if (asset.Name.Length > AssetBase.MAX_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.Parameters.Add(new SqliteParameter(":Data", asset.Data));
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
return true;
} }
} }
} }
@ -191,6 +192,7 @@ namespace OpenSim.Data.SQLite
cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
return true;
} }
} }
} }

View File

@ -2013,6 +2013,7 @@ namespace OpenSim.Data.SQLite
return entry; return entry;
} }
/*
/// <summary> /// <summary>
/// ///
/// </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) public void SaveExtra(UUID regionID, string name, string value)
{ {
} }

View File

@ -82,5 +82,10 @@ namespace OpenSim.Data.SQLite
return DoQuery(cmd); return DoQuery(cmd);
} }
} }
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
} }
} }

View File

@ -741,6 +741,7 @@ namespace OpenSim.Data.SQLite
return true; return true;
} }
/*
public bool UpdateUserPreferences(ref UserPreferences pref, ref string result) public bool UpdateUserPreferences(ref UserPreferences pref, ref string result)
{ {
string query = string.Empty; string query = string.Empty;
@ -825,6 +826,7 @@ namespace OpenSim.Data.SQLite
} }
return true; return true;
} }
*/
public bool GetUserAppData(ref UserAppData props, ref string result) public bool GetUserAppData(ref UserAppData props, ref string result)
{ {

View File

@ -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;
}
}
}

View File

@ -63,6 +63,8 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
private AssetMetadata m_metadata; private AssetMetadata m_metadata;
private int m_uploadAttempts;
// This is needed for .NET serialization!!! // This is needed for .NET serialization!!!
// Do NOT "Optimize" away! // Do NOT "Optimize" away!
public AssetBase() public AssetBase()
@ -148,7 +150,12 @@ namespace OpenSim.Framework
Type == (sbyte)AssetType.Folder || Type == (sbyte)AssetType.Folder ||
Type == (sbyte)AssetType.ImageJPEG || Type == (sbyte)AssetType.ImageJPEG ||
Type == (sbyte)AssetType.ImageTGA || Type == (sbyte)AssetType.ImageTGA ||
<<<<<<< HEAD
Type == (sbyte)AssetType.LSLBytecode); 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; } set { m_metadata.Type = value; }
} }
public int UploadAttempts
{
get { return m_uploadAttempts; }
set { m_uploadAttempts = value; }
}
/// <summary> /// <summary>
/// Is this a region only asset, or does this exist on the asset server also /// Is this a region only asset, or does this exist on the asset server also
/// </summary> /// </summary>

View File

@ -53,7 +53,11 @@ namespace OpenSim.Framework
// should be only used as initial default value ( V1 viewers ) // should be only used as initial default value ( V1 viewers )
public readonly static int VISUALPARAM_COUNT = 218; 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 }; public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
protected int m_serial = 0; protected int m_serial = 0;
@ -179,11 +183,16 @@ namespace OpenSim.Framework
m_attachments = new Dictionary<int, List<AvatarAttachment>>(); 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) 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"); // m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
@ -217,6 +226,10 @@ namespace OpenSim.Framework
{ {
byte[] tbytes = appearance.Texture.GetBytes(); byte[] tbytes = appearance.Texture.GetBytes();
m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length); 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; m_visualparams = null;
@ -458,7 +471,10 @@ namespace OpenSim.Framework
// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID); // m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
// DEBUG OFF // DEBUG OFF
m_wearables[wearableId].Clear(); 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); m_wearables[wearableId].Add(wearable[i].ItemID, wearable[i].AssetID);
} }
@ -722,6 +738,13 @@ namespace OpenSim.Framework
} }
data["textures"] = textures; data["textures"] = textures;
if (m_cacheitems != null)
{
OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems);
if (baked != null)
data["bakedcache"] = baked;
}
// Visual Parameters // Visual Parameters
OSDBinary visualparams = new OSDBinary(m_visualparams); OSDBinary visualparams = new OSDBinary(m_visualparams);
data["visualparams"] = visualparams; data["visualparams"] = visualparams;
@ -757,7 +780,12 @@ namespace OpenSim.Framework
if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array) if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
{ {
OSDArray wears = (OSDArray)(data["wearables"]); 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]); m_wearables[i] = new AvatarWearable((OSDArray)wears[i]);
} }
else else
@ -783,6 +811,12 @@ namespace OpenSim.Framework
m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures"); 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 // Visual Parameters
SetDefaultParams(); SetDefaultParams();
if ((data != null) && (data["visualparams"] != null)) if ((data != null) && (data["visualparams"] != null))
@ -1632,7 +1666,12 @@ namespace OpenSim.Framework
BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247, BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247,
BREAST_PHYSICS_LEFTRIGHT_SPRING= 248, BREAST_PHYSICS_LEFTRIGHT_SPRING= 248,
BREAST_PHYSICS_LEFTRIGHT_GAIN = 249, 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 #endregion
} }

View File

@ -62,10 +62,16 @@ namespace OpenSim.Framework
public static readonly int UNDERSHIRT = 10; public static readonly int UNDERSHIRT = 10;
public static readonly int UNDERPANTS = 11; public static readonly int UNDERPANTS = 11;
public static readonly int SKIRT = 12; public static readonly int SKIRT = 12;
public static readonly int MAX_BASICWEARABLES = 13;
public static readonly int ALPHA = 13; public static readonly int ALPHA = 13;
public static readonly int TATTOO = 14; 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_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9");
public static readonly UUID DEFAULT_BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73"); public static readonly UUID DEFAULT_BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
@ -219,7 +225,7 @@ namespace OpenSim.Framework
{ {
get 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++) for (int i = 0; i < MAX_WEARABLES; i++)
{ {
defaultWearables[i] = new AvatarWearable(); defaultWearables[i] = new AvatarWearable();
@ -243,8 +249,11 @@ namespace OpenSim.Framework
// // Alpha // // Alpha
// defaultWearables[ALPHA].Add(DEFAULT_ALPHA_ITEM, DEFAULT_ALPHA_ASSET); // defaultWearables[ALPHA].Add(DEFAULT_ALPHA_ITEM, DEFAULT_ALPHA_ASSET);
// // Tattoo // // Tattoo
// defaultWearables[TATTOO].Add(DEFAULT_TATTOO_ITEM, DEFAULT_TATTOO_ASSET); // defaultWearables[TATTOO].Add(DEFAULT_TATTOO_ITEM, DEFAULT_TATTOO_ASSET);
// // Physics
// defaultWearables[PHYSICS].Add(DEFAULT_TATTOO_ITEM, DEFAULT_TATTOO_ASSET);
return defaultWearables; return defaultWearables;
} }

View File

@ -76,10 +76,9 @@ namespace OpenSim.Framework
{ {
lock (m_queueSync) lock (m_queueSync)
{ {
bool success = true; if (m_queue.Count < 1 && m_pqueue.Count < 1)
while (m_queue.Count < 1 && m_pqueue.Count < 1 && success)
{ {
success = Monitor.Wait(m_queueSync, msTimeout); Monitor.Wait(m_queueSync, msTimeout);
} }
if (m_pqueue.Count > 0) if (m_pqueue.Count > 0)

View File

@ -94,6 +94,7 @@ namespace OpenSim.Framework
// This probably shouldn't be here // This probably shouldn't be here
public byte[] Throttles; public byte[] Throttles;
public Dictionary<ulong, string> ChildrenCapSeeds = null;
public OSDMap Pack() public OSDMap Pack()
{ {
@ -119,6 +120,19 @@ namespace OpenSim.Framework
if ((Throttles != null) && (Throttles.Length > 0)) if ((Throttles != null) && (Throttles.Length > 0))
args["throttles"] = OSD.FromBinary(Throttles); 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; return args;
} }
@ -165,6 +179,30 @@ namespace OpenSim.Framework
if (args["throttles"] != null) if (args["throttles"] != null)
Throttles = args["throttles"].AsBinary(); 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> /// <summary>
@ -317,9 +355,11 @@ namespace OpenSim.Framework
public UUID ActiveGroupID; public UUID ActiveGroupID;
public AgentGroupData[] Groups; public AgentGroupData[] Groups;
public Dictionary<ulong, string> ChildrenCapSeeds = null;
public Animation[] Anims; public Animation[] Anims;
public Animation DefaultAnim = null; public Animation DefaultAnim = null;
public Animation AnimState = null; public Animation AnimState = null;
public Byte MotionState = 0;
public UUID GranterID; public UUID GranterID;
public UUID ParentPart; public UUID ParentPart;
@ -349,6 +389,8 @@ namespace OpenSim.Framework
public List<ISceneObject> AttachmentObjects; public List<ISceneObject> AttachmentObjects;
public List<string> AttachmentObjectStates; public List<string> AttachmentObjectStates;
public Dictionary<string, UUID> MovementAnimationOverRides = new Dictionary<string, UUID>();
public virtual OSDMap Pack() public virtual OSDMap Pack()
{ {
// m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); // m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
@ -399,6 +441,19 @@ namespace OpenSim.Framework
args["groups"] = groups; 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)) if ((Anims != null) && (Anims.Length > 0))
{ {
OSDArray anims = new OSDArray(Anims.Length); OSDArray anims = new OSDArray(Anims.Length);
@ -417,6 +472,26 @@ namespace OpenSim.Framework
args["animation_state"] = AnimState.PackUpdateMessage(); 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) if (Appearance != null)
args["packed_appearance"] = Appearance.Pack(); args["packed_appearance"] = Appearance.Pack();
@ -431,6 +506,8 @@ namespace OpenSim.Framework
// The code to pack textures, visuals, wearables and attachments // The code to pack textures, visuals, wearables and attachments
// should be removed; packed appearance contains the full appearance // should be removed; packed appearance contains the full appearance
// This is retained for backward compatibility only // This is retained for backward compatibility only
/* then lets remove
if (Appearance.Texture != null) if (Appearance.Texture != null)
{ {
byte[] rawtextures = Appearance.Texture.GetBytes(); byte[] rawtextures = Appearance.Texture.GetBytes();
@ -459,7 +536,7 @@ namespace OpenSim.Framework
args["attachments"] = attachs; args["attachments"] = attachs;
} }
// End of code to remove // End of code to remove
*/
if ((Controllers != null) && (Controllers.Length > 0)) if ((Controllers != null) && (Controllers.Length > 0))
{ {
OSDArray controls = new OSDArray(Controllers.Length); 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) if ((args["animations"] != null) && (args["animations"]).Type == OSDType.Array)
{ {
OSDArray anims = (OSDArray)(args["animations"]); 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) //if ((args["agent_textures"] != null) && (args["agent_textures"]).Type == OSDType.Array)
//{ //{
// OSDArray textures = (OSDArray)(args["agent_textures"]); // OSDArray textures = (OSDArray)(args["agent_textures"]);
@ -647,6 +769,18 @@ namespace OpenSim.Framework
// AgentTextures[i++] = o.AsUUID(); // AgentTextures[i++] = o.AsUUID();
//} //}
// packed_appearence should contain all appearance information
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
{
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance");
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
}
else
{
// if missing try the old pack method
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance, checking old method");
Appearance = new AvatarAppearance(); Appearance = new AvatarAppearance();
// The code to unpack textures, visuals, wearables and attachments // The code to unpack textures, visuals, wearables and attachments
@ -655,7 +789,7 @@ namespace OpenSim.Framework
if (args["texture_entry"] != null) if (args["texture_entry"] != null)
{ {
byte[] rawtextures = args["texture_entry"].AsBinary(); byte[] rawtextures = args["texture_entry"].AsBinary();
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length); Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures, 0, rawtextures.Length);
Appearance.SetTextureEntries(textures); Appearance.SetTextureEntries(textures);
} }
@ -665,10 +799,15 @@ namespace OpenSim.Framework
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
{ {
OSDArray wears = (OSDArray)(args["wearables"]); OSDArray wears = (OSDArray)(args["wearables"]);
for (int i = 0; i < wears.Count / 2; i++)
int count = wears.Count;
if (count > AvatarWearable.MAX_WEARABLES)
count = AvatarWearable.MAX_WEARABLES;
for (int i = 0; i < count / 2; i++)
{ {
AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]); AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]);
Appearance.SetWearable(i,awear); Appearance.SetWearable(i, awear);
} }
} }
@ -682,18 +821,19 @@ namespace OpenSim.Framework
// We know all of these must end up as attachments so we // We know all of these must end up as attachments so we
// append rather than replace to ensure multiple attachments // append rather than replace to ensure multiple attachments
// per point continues to work // per point continues to work
// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID); // m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID);
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o)); Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
} }
} }
} }
// end of code to remove // end of code to remove
}
/* moved above
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]); Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
else else
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
*/
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
{ {
OSDArray controls = (OSDArray)(args["controllers"]); OSDArray controls = (OSDArray)(args["controllers"]);

View File

@ -42,6 +42,7 @@ namespace OpenSim.Framework
public Vector3 velVector = Vector3.Zero; public Vector3 velVector = Vector3.Zero;
public string nameStr = String.Empty; public string nameStr = String.Empty;
public int colliderType = 0; public int colliderType = 0;
public int linkNumber;
} }
public class ColliderArgs : EventArgs public class ColliderArgs : EventArgs

View File

@ -389,9 +389,32 @@ namespace OpenSim.Framework.Communications
} }
} }
if (_response != null)
_response.Close();
return null; 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) if (_asyncException != null)
throw _asyncException; throw _asyncException;
@ -413,7 +436,7 @@ namespace OpenSim.Framework.Communications
_request = (HttpWebRequest) WebRequest.Create(buildUri()); _request = (HttpWebRequest) WebRequest.Create(buildUri());
_request.KeepAlive = false; _request.KeepAlive = false;
_request.ContentType = "application/xml"; _request.ContentType = "application/xml";
_request.Timeout = 900000; _request.Timeout = 30000;
_request.Method = RequestMethod; _request.Method = RequestMethod;
_asyncException = null; _asyncException = null;
_request.ContentLength = src.Length; _request.ContentLength = src.Length;
@ -421,6 +444,7 @@ namespace OpenSim.Framework.Communications
auth.AddAuthorization(_request.Headers); auth.AddAuthorization(_request.Headers);
src.Seek(0, SeekOrigin.Begin); src.Seek(0, SeekOrigin.Begin);
<<<<<<< HEAD
int reqnum = WebUtil.RequestNumber++; int reqnum = WebUtil.RequestNumber++;
if (WebUtil.DebugLevel >= 3) if (WebUtil.DebugLevel >= 3)
@ -433,10 +457,23 @@ namespace OpenSim.Framework.Communications
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
int length = src.Read(buf, 0, 1024); int length = src.Read(buf, 0, 1024);
while (length > 0) while (length > 0)
=======
m_log.Info("[REST]: Seek is ok");
using (Stream dst = _request.GetRequestStream())
>>>>>>> avn/ubitvar
{
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); dst.Write(buf, 0, length);
length = src.Read(buf, 0, 1024); length = src.Read(buf, 0, 1024);
} }
}
try try
{ {
@ -470,6 +507,9 @@ namespace OpenSim.Framework.Communications
_response.Close(); _response.Close();
if (_response != null)
_response.Close();
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); // IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
// TODO! Implement timeout, without killing the server // TODO! Implement timeout, without killing the server

View File

@ -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"; = "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 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:"; or type help <item>' where <item> is one of the following:";
/// <value> /// <value>
@ -115,14 +115,16 @@ namespace OpenSim.Framework.Console
// General help // General help
if (helpParts.Count == 0) 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(GeneralHelpText);
help.Add(ItemHelpText); help.Add(ItemHelpText);
help.AddRange(CollectModulesHelp(tree)); help.AddRange(CollectModulesHelp(tree));
} }
else if (helpParts.Count == 1 && helpParts[0] == "all")
{
help.AddRange(CollectAllCommandsHelp());
}
else else
{ {
help.AddRange(CollectHelp(helpParts)); help.AddRange(CollectHelp(helpParts));
@ -145,8 +147,11 @@ namespace OpenSim.Framework.Console
{ {
foreach (List<CommandInfo> commands in m_modulesCommands.Values) foreach (List<CommandInfo> commands in m_modulesCommands.Values)
{ {
var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help)); foreach (CommandInfo c in commands)
help.AddRange(ourHelpText); {
if (c.long_help != String.Empty)
help.Add(string.Format("{0} - {1}", c.help_text, c.long_help));
}
} }
} }

View File

@ -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,
}
}

View File

@ -363,11 +363,30 @@ namespace OpenSim.Framework
return false; return false;
} }
public bool IsBanned(UUID avatarID) public bool IsBanned(UUID avatarID, int userFlags)
{ {
foreach (EstateBan ban in l_EstateBans) foreach (EstateBan ban in l_EstateBans)
if (ban.BannedUserID == avatarID) if (ban.BannedUserID == avatarID)
return true; 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; return false;
} }
@ -375,7 +394,7 @@ namespace OpenSim.Framework
{ {
if (ban == null) if (ban == null)
return; return;
if (!IsBanned(ban.BannedUserID)) if (!IsBanned(ban.BannedUserID, 32)) //Ignore age-based bans
l_EstateBans.Add(ban); l_EstateBans.Add(ban);
} }

View File

@ -64,14 +64,15 @@ namespace OpenSim.Framework
public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); 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 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 StartAnim(IClientAPI remoteClient, UUID animID);
public delegate void StopAnim(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 LinkObjects(IClientAPI remoteClient, uint parent, List<uint> children);
public delegate void DelinkObjects(List<uint> primIds, IClientAPI client); 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 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 UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient);
public delegate void UpdatePrimSingleRotation(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( public delegate void MoveInventoryItem(
IClientAPI remoteClient, List<InventoryItemBase> items); IClientAPI remoteClient, List<InventoryItemBase> items);
public delegate void MoveItemsAndLeaveCopy(
IClientAPI remoteClient, List<InventoryItemBase> items, UUID destFolder);
public delegate void RemoveInventoryItem( public delegate void RemoveInventoryItem(
IClientAPI remoteClient, List<UUID> itemIDs); IClientAPI remoteClient, List<UUID> itemIDs);
@ -443,6 +449,7 @@ namespace OpenSim.Framework
public delegate void ClassifiedInfoRequest(UUID classifiedID, IClientAPI client); 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 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 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 EventNotificationAddRequest(uint EventID, IClientAPI client);
public delegate void EventNotificationRemoveRequest(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 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); 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 SimWideDeletesDelegate(IClientAPI client,UUID agentID, int flags, UUID targetID);
public delegate void SendPostcard(IClientAPI client); public delegate void SendPostcard(IClientAPI client);
public delegate void ChangeInventoryItemFlags(IClientAPI client, UUID itemID, uint flags);
#endregion #endregion
@ -734,6 +742,8 @@ namespace OpenSim.Framework
IScene Scene { get; } IScene Scene { get; }
List<uint> SelectedObjects { get; }
// [Obsolete("LLClientView Specific - Replace with ???")] // [Obsolete("LLClientView Specific - Replace with ???")]
int NextAnimationSequenceNumber { get; } int NextAnimationSequenceNumber { get; }
@ -747,6 +757,8 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
bool IsActive { get; set; } bool IsActive { get; set; }
int PingTimeMS { get; }
/// <summary> /// <summary>
/// Set if the client is closing due to a logout request /// Set if the client is closing due to a logout request
/// </summary> /// </summary>
@ -794,6 +806,7 @@ namespace OpenSim.Framework
event ObjectDrop OnObjectDrop; event ObjectDrop OnObjectDrop;
event StartAnim OnStartAnim; event StartAnim OnStartAnim;
event StopAnim OnStopAnim; event StopAnim OnStopAnim;
event ChangeAnim OnChangeAnim;
event LinkObjects OnLinkObjects; event LinkObjects OnLinkObjects;
event DelinkObjects OnDelinkObjects; event DelinkObjects OnDelinkObjects;
event RequestMapBlocks OnRequestMapBlocks; event RequestMapBlocks OnRequestMapBlocks;
@ -860,6 +873,7 @@ namespace OpenSim.Framework
event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
event UpdatePrimFlags OnUpdatePrimFlags; event UpdatePrimFlags OnUpdatePrimFlags;
event UpdatePrimTexture OnUpdatePrimTexture; event UpdatePrimTexture OnUpdatePrimTexture;
event ClientChangeObject onClientChangeObject;
event UpdateVector OnUpdatePrimGroupPosition; event UpdateVector OnUpdatePrimGroupPosition;
event UpdateVector OnUpdatePrimSinglePosition; event UpdateVector OnUpdatePrimSinglePosition;
event UpdatePrimRotation OnUpdatePrimGroupRotation; event UpdatePrimRotation OnUpdatePrimGroupRotation;
@ -884,6 +898,7 @@ namespace OpenSim.Framework
event RequestTaskInventory OnRequestTaskInventory; event RequestTaskInventory OnRequestTaskInventory;
event UpdateInventoryItem OnUpdateInventoryItem; event UpdateInventoryItem OnUpdateInventoryItem;
event CopyInventoryItem OnCopyInventoryItem; event CopyInventoryItem OnCopyInventoryItem;
event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
event MoveInventoryItem OnMoveInventoryItem; event MoveInventoryItem OnMoveInventoryItem;
event RemoveInventoryFolder OnRemoveInventoryFolder; event RemoveInventoryFolder OnRemoveInventoryFolder;
event RemoveInventoryItem OnRemoveInventoryItem; event RemoveInventoryItem OnRemoveInventoryItem;
@ -1002,7 +1017,7 @@ namespace OpenSim.Framework
event ClassifiedInfoRequest OnClassifiedInfoRequest; event ClassifiedInfoRequest OnClassifiedInfoRequest;
event ClassifiedInfoUpdate OnClassifiedInfoUpdate; event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
event ClassifiedDelete OnClassifiedDelete; event ClassifiedDelete OnClassifiedDelete;
event ClassifiedDelete OnClassifiedGodDelete; event ClassifiedGodDelete OnClassifiedGodDelete;
event EventNotificationAddRequest OnEventNotificationAddRequest; event EventNotificationAddRequest OnEventNotificationAddRequest;
event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
@ -1041,11 +1056,12 @@ namespace OpenSim.Framework
event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
event SimWideDeletesDelegate OnSimWideDeletes; event SimWideDeletesDelegate OnSimWideDeletes;
event SendPostcard OnSendPostcard; event SendPostcard OnSendPostcard;
event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
event MuteListEntryUpdate OnUpdateMuteListEntry; event MuteListEntryUpdate OnUpdateMuteListEntry;
event MuteListEntryRemove OnRemoveMuteListEntry; event MuteListEntryRemove OnRemoveMuteListEntry;
event GodlikeMessage onGodlikeMessage; event GodlikeMessage onGodlikeMessage;
event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
event GenericCall2 OnUpdateThrottles;
/// <summary> /// <summary>
/// Set the debug level at which packet output should be printed to console. /// Set the debug level at which packet output should be printed to console.
/// </summary> /// </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 /// 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. /// ditch attempt where Active == false but the ScenePresence still exists.
/// </param> /// </param>
void Close(bool force); void Close(bool sendStop, bool force);
void Kick(string message); void Kick(string message);
@ -1102,6 +1118,8 @@ namespace OpenSim.Framework
/// <param name="localID"></param> /// <param name="localID"></param>
void SendKillObject(List<uint> localID); void SendKillObject(List<uint> localID);
void SendPartFullUpdate(ISceneEntity ent, uint? parentID);
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs); void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args); 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<string> message);
void SendGenericMessage(string method, UUID invoice, List<byte[]> message); void SendGenericMessage(string method, UUID invoice, List<byte[]> message);
bool CanSendLayerData();
void SendLayerData(float[] map); void SendLayerData(float[] map);
void SendLayerData(int px, int py, 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 SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations);
void SetChildAgentThrottle(byte[] throttle); void SetChildAgentThrottle(byte[] throttle);
void SetChildAgentThrottle(byte[] throttle,float factor);
void SetAgentThrottleSilent(int throttle, int setting);
int GetAgentThrottleSilent(int throttle);
void SendAvatarDataImmediate(ISceneEntity avatar); void SendAvatarDataImmediate(ISceneEntity avatar);
@ -1192,6 +1216,7 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
/// <param name="Item"></param> /// <param name="Item"></param>
void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId); void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId);
void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId);
void SendRemoveInventoryItem(UUID itemID); void SendRemoveInventoryItem(UUID itemID);
@ -1211,7 +1236,7 @@ namespace OpenSim.Framework
/// <param name="node"></param> /// <param name="node"></param>
void SendBulkUpdateInventory(InventoryNodeBase node); 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); void SendAbortXferPacket(ulong xferID);

View File

@ -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 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 Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
void sendClientInitialLandInfo(IClientAPI remoteClient);
} }
} }

View File

@ -68,7 +68,7 @@ namespace OpenSim.Framework
void SendLandUpdateToAvatarsOverMe(); void SendLandUpdateToAvatarsOverMe();
void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client); 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 IsEitherBannedOrRestricted(UUID avatar);
bool IsBannedFromLand(UUID avatar); bool IsBannedFromLand(UUID avatar);
bool CanBeOnThisLand(UUID avatar, float posHeight); bool CanBeOnThisLand(UUID avatar, float posHeight);

View File

@ -33,7 +33,7 @@ namespace OpenSim.Framework
public interface IMoneyModule public interface IMoneyModule
{ {
bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID, bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID,
int amount); int amount, UUID txn, out string reason);
int GetBalance(UUID agentID); int GetBalance(UUID agentID);
bool UploadCovered(UUID agentID, int amount); 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);
void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData); void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData);
void ApplyUploadCharge(UUID agentID, int amount, string text); void ApplyUploadCharge(UUID agentID, int amount, string text);
void MoveMoney(UUID fromUser, UUID toUser, int amount, string text);
int UploadCharge { get; } int UploadCharge { get; }
int GroupCreationCharge { get; } int GroupCreationCharge { get; }

View File

@ -67,9 +67,9 @@ namespace OpenSim.Framework
private uint _flags = (uint)ParcelFlags.AllowFly | (uint)ParcelFlags.AllowLandmark | private uint _flags = (uint)ParcelFlags.AllowFly | (uint)ParcelFlags.AllowLandmark |
(uint)ParcelFlags.AllowAPrimitiveEntry | (uint)ParcelFlags.AllowAPrimitiveEntry |
(uint)ParcelFlags.AllowDeedToGroup | (uint)ParcelFlags.AllowTerraform | (uint)ParcelFlags.AllowDeedToGroup |
(uint)ParcelFlags.CreateObjects | (uint)ParcelFlags.AllowOtherScripts | (uint)ParcelFlags.CreateObjects | (uint)ParcelFlags.AllowOtherScripts |
(uint)ParcelFlags.SoundLocal | (uint)ParcelFlags.AllowVoiceChat; (uint)ParcelFlags.AllowVoiceChat;
private byte _landingType = 0; private byte _landingType = 0;
private string _name = "Your Parcel"; private string _name = "Your Parcel";
@ -99,6 +99,10 @@ namespace OpenSim.Framework
private bool _obscureMedia = false; private bool _obscureMedia = false;
private float _dwell = 0; private float _dwell = 0;
public bool SeeAVs { get; set; }
public bool AnyAVSounds { get; set; }
public bool GroupAVSounds { get; set; }
/// <summary> /// <summary>
/// Traffic count of parcel /// Traffic count of parcel
/// </summary> /// </summary>
@ -728,6 +732,9 @@ namespace OpenSim.Framework
public LandData() public LandData()
{ {
_globalID = UUID.Random(); _globalID = UUID.Random();
SeeAVs = true;
AnyAVSounds = true;
GroupAVSounds = true;
} }
/// <summary> /// <summary>
@ -778,6 +785,9 @@ namespace OpenSim.Framework
landData._simwideArea = _simwideArea; landData._simwideArea = _simwideArea;
landData._simwidePrims = _simwidePrims; landData._simwidePrims = _simwidePrims;
landData._dwell = _dwell; landData._dwell = _dwell;
landData.SeeAVs = SeeAVs;
landData.AnyAVSounds = AnyAVSounds;
landData.GroupAVSounds = GroupAVSounds;
landData._parcelAccessList.Clear(); landData._parcelAccessList.Clear();
foreach (LandAccessEntry entry in _parcelAccessList) foreach (LandAccessEntry entry in _parcelAccessList)
@ -793,21 +803,21 @@ namespace OpenSim.Framework
return landData; return landData;
} }
public void ToXml(XmlWriter xmlWriter) // public void ToXml(XmlWriter xmlWriter)
{ // {
serializer.Serialize(xmlWriter, this); // serializer.Serialize(xmlWriter, this);
} // }
/// <summary> /// <summary>
/// Restore a LandData object from the serialized xml representation. /// Restore a LandData object from the serialized xml representation.
/// </summary> /// </summary>
/// <param name="xmlReader"></param> /// <param name="xmlReader"></param>
/// <returns></returns> /// <returns></returns>
public static LandData FromXml(XmlReader xmlReader) // public static LandData FromXml(XmlReader xmlReader)
{ // {
LandData land = (LandData)serializer.Deserialize(xmlReader); // LandData land = (LandData)serializer.Deserialize(xmlReader);
//
return land; // return land;
} // }
} }
} }

View File

@ -56,5 +56,8 @@ namespace OpenSim.Framework
public bool MediaLoop; public bool MediaLoop;
public bool ObscureMusic; public bool ObscureMusic;
public bool ObscureMedia; public bool ObscureMedia;
public bool SeeAVs;
public bool AnyAVSounds;
public bool GroupAVSounds;
} }
} }

View File

@ -29,7 +29,7 @@ using System.Threading;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
public sealed class LocklessQueue<T> public class LocklessQueue<T>
{ {
private sealed class SingleLinkNode private sealed class SingleLinkNode
{ {
@ -41,7 +41,7 @@ namespace OpenSim.Framework
SingleLinkNode tail; SingleLinkNode tail;
int count; int count;
public int Count { get { return count; } } public virtual int Count { get { return count; } }
public LocklessQueue() public LocklessQueue()
{ {
@ -76,7 +76,7 @@ namespace OpenSim.Framework
Interlocked.Increment(ref count); Interlocked.Increment(ref count);
} }
public bool Dequeue(out T item) public virtual bool Dequeue(out T item)
{ {
item = default(T); item = default(T);
SingleLinkNode oldHead = null; SingleLinkNode oldHead = null;

View File

@ -43,7 +43,6 @@ namespace OpenSim.Framework.Monitoring
StringBuilder sb = new StringBuilder(Environment.NewLine); StringBuilder sb = new StringBuilder(Environment.NewLine);
sb.Append("MEMORY STATISTICS"); sb.Append("MEMORY STATISTICS");
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);
sb.AppendFormat( sb.AppendFormat(
"Heap allocated to OpenSim : {0} MB\n", "Heap allocated to OpenSim : {0} MB\n",
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)); 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", "Average heap allocation rate: {0} MB/s\n",
Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1024.0 / 1024, 3)); Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1024.0 / 1024, 3));
Process myprocess = Process.GetCurrentProcess();
if (!myprocess.HasExited)
{
myprocess.Refresh();
sb.AppendFormat( sb.AppendFormat(
"Process memory : {0} MB\n", "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().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(); return sb.ToString();
} }

View File

@ -249,6 +249,49 @@ namespace OpenSim.Framework.Monitoring
(s) => { s.Value = Math.Round(MemoryWatchdog.LastHeapAllocationRate * 1000d / 1024d / 1024d, 3); }); (s) => { s.Value = Math.Round(MemoryWatchdog.LastHeapAllocationRate * 1000d / 1024d / 1024d, 3); });
MakeStat("AverageHeapAllocationRate", null, "MB/sec", ContainerMemory, MakeStat("AverageHeapAllocationRate", null, "MB/sec", ContainerMemory,
(s) => { s.Value = Math.Round(MemoryWatchdog.AverageHeapAllocationRate * 1000d / 1024d / 1024d, 3); }); (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: // Notes on performance counters:

View File

@ -239,6 +239,17 @@ namespace OpenSim.Framework.Monitoring
return sb.ToString(); 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() public virtual OSDMap ToOSDMap()
{ {
OSDMap ret = new OSDMap(); OSDMap ret = new OSDMap();

View File

@ -283,7 +283,7 @@ namespace OpenSim.Framework.Monitoring
if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName)) if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName))
continue; continue;
statMap.Add(statName, theStats[statName].ToOSDMap()); statMap.Add(statName, theStats[statName].ToBriefOSDMap());
} }
contMap.Add(contName, statMap); contMap.Add(contName, statMap);
@ -305,6 +305,17 @@ namespace OpenSim.Framework.Monitoring
string pContainerName = StatsManager.AllSubCommand; string pContainerName = StatsManager.AllSubCommand;
string pStatName = 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("cat")) pCategoryName = request["cat"].ToString();
if (request.ContainsKey("cont")) pContainerName = request["cat"].ToString(); if (request.ContainsKey("cont")) pContainerName = request["cat"].ToString();
if (request.ContainsKey("stat")) pStatName = request["stat"].ToString(); if (request.ContainsKey("stat")) pStatName = request["stat"].ToString();

View File

@ -41,6 +41,7 @@ namespace OpenSim.Framework
// "Out of band" managemnt https // "Out of band" managemnt https
public bool ssl_listener = false; public bool ssl_listener = false;
public bool ssl_external = false;
public uint https_port = 0; public uint https_port = 0;
public string cert_path = String.Empty; public string cert_path = String.Empty;
public string cert_pass = String.Empty; public string cert_pass = String.Empty;
@ -64,6 +65,7 @@ namespace OpenSim.Framework
// "Out of band management https" // "Out of band management https"
ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false); ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false);
ssl_external = config.Configs["Network"].GetBoolean("https_external",false);
if( ssl_listener) if( ssl_listener)
{ {
cert_path = config.Configs["Network"].GetString("cert_path",String.Empty); cert_path = config.Configs["Network"].GetString("cert_path",String.Empty);

View File

@ -51,12 +51,11 @@ namespace OpenSim.Framework
protected object m_senderObject; protected object m_senderObject;
protected ChatTypeEnum m_type; protected ChatTypeEnum m_type;
protected UUID m_fromID; protected UUID m_fromID;
protected UUID m_toID; protected UUID m_destination = UUID.Zero;
public OSChatMessage() public OSChatMessage()
{ {
m_position = new Vector3(); m_position = new Vector3();
m_toID = UUID.Zero;
} }
/// <summary> /// <summary>
@ -104,15 +103,6 @@ namespace OpenSim.Framework
set { m_from = value; } 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 #region IEventArgs Members
/// TODO: Sender and SenderObject should just be Sender and of /// TODO: Sender and SenderObject should just be Sender and of
@ -142,13 +132,10 @@ namespace OpenSim.Framework
set { m_fromID = value; } set { m_fromID = value; }
} }
/// <summary> public UUID Destination
/// The single recipient or all if not set.
/// </summary>
public UUID TargetUUID
{ {
get { return m_toID; } get { return m_destination; }
set { m_toID = value; } set { m_destination = value; }
} }
/// <summary> /// <summary>

View File

@ -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;
}
}

View File

@ -27,7 +27,7 @@
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
public enum ParcelMediaCommandEnum public enum ParcelMediaCommandEnum : int
{ {
Stop = 0, Stop = 0,
Pause = 1, Pause = 1,

View File

@ -72,8 +72,8 @@ namespace OpenSim.Framework
/// <param name="mainPerms">The permissions variable to modify.</param> /// <param name="mainPerms">The permissions variable to modify.</param>
public static void ApplyFoldedPermissions(uint foldedPerms, ref uint mainPerms) public static void ApplyFoldedPermissions(uint foldedPerms, ref uint mainPerms)
{ {
if ((foldedPerms & 7) == 0) // if ((foldedPerms & 7) == 0)
return; // assume that if the folded permissions are 0 then this means that they weren't actually recorded // 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) if ((foldedPerms & ((uint)PermissionMask.Copy >> 13)) == 0)
mainPerms &= ~(uint)PermissionMask.Copy; mainPerms &= ~(uint)PermissionMask.Copy;

View File

@ -245,6 +245,7 @@ namespace OpenSim.Framework
// occasionally seems to corrupt its addin cache // occasionally seems to corrupt its addin cache
// Hence, as a temporary solution we'll remove it before each startup // Hence, as a temporary solution we'll remove it before each startup
<<<<<<< HEAD
try try
{ {
if (Directory.Exists(dir + "/addin-db-000")) if (Directory.Exists(dir + "/addin-db-000"))
@ -252,6 +253,23 @@ namespace OpenSim.Framework
if (Directory.Exists(dir + "/addin-db-001")) if (Directory.Exists(dir + "/addin-db-001"))
Directory.Delete(dir + "/addin-db-001", true); 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) catch (IOException)
{ {

View File

@ -728,6 +728,11 @@ namespace OpenSim.Framework
return _lightColorR; return _lightColorR;
} }
set { set {
if (value < 0)
_lightColorR = 0;
else if (value > 1.0f)
_lightColorR = 1.0f;
else
_lightColorR = value; _lightColorR = value;
} }
} }
@ -737,6 +742,11 @@ namespace OpenSim.Framework
return _lightColorG; return _lightColorG;
} }
set { set {
if (value < 0)
_lightColorG = 0;
else if (value > 1.0f)
_lightColorG = 1.0f;
else
_lightColorG = value; _lightColorG = value;
} }
} }
@ -746,6 +756,11 @@ namespace OpenSim.Framework
return _lightColorB; return _lightColorB;
} }
set { set {
if (value < 0)
_lightColorB = 0;
else if (value > 1.0f)
_lightColorB = 1.0f;
else
_lightColorB = value; _lightColorB = value;
} }
} }
@ -755,6 +770,11 @@ namespace OpenSim.Framework
return _lightColorA; return _lightColorA;
} }
set { set {
if (value < 0)
_lightColorA = 0;
else if (value > 1.0f)
_lightColorA = 1.0f;
else
_lightColorA = value; _lightColorA = value;
} }
} }
@ -868,6 +888,11 @@ namespace OpenSim.Framework
} }
public ulong GetMeshKey(Vector3 size, float lod) public ulong GetMeshKey(Vector3 size, float lod)
{
return GetMeshKey(size, lod, false);
}
public ulong GetMeshKey(Vector3 size, float lod, bool convex)
{ {
ulong hash = 5381; ulong hash = 5381;
@ -914,6 +939,9 @@ namespace OpenSim.Framework
hash = djb2(hash, scaleBytes[i]); hash = djb2(hash, scaleBytes[i]);
} }
if(convex)
hash = djb2(hash, 0xa5);
return hash; return hash;
} }
@ -1417,7 +1445,7 @@ namespace OpenSim.Framework
prim.Textures = this.Textures; prim.Textures = this.Textures;
prim.Properties = new Primitive.ObjectProperties(); prim.Properties = new Primitive.ObjectProperties();
prim.Properties.Name = "Primitive"; prim.Properties.Name = "Object";
prim.Properties.Description = ""; prim.Properties.Description = "";
prim.Properties.CreatorID = UUID.Zero; prim.Properties.CreatorID = UUID.Zero;
prim.Properties.GroupID = UUID.Zero; prim.Properties.GroupID = UUID.Zero;

View File

@ -45,7 +45,8 @@ namespace OpenSim.Framework
/// <summary> /// <summary>
/// Total number of queues (priorities) available /// Total number of queues (priorities) available
/// </summary> /// </summary>
public const uint NumberOfQueues = 12;
public const uint NumberOfQueues = 12; // includes immediate queues, m_queueCounts need to be set acording
/// <summary> /// <summary>
/// Number of queuest (priorities) that are processed immediately /// Number of queuest (priorities) that are processed immediately
@ -60,7 +61,10 @@ namespace OpenSim.Framework
// each pass. weighted towards the higher priority queues // each pass. weighted towards the higher priority queues
private uint m_nextQueue = 0; private uint m_nextQueue = 0;
private uint m_countFromQueue = 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 // 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 // a total ordering on the updates coming through the queue and is more
@ -130,6 +134,21 @@ namespace OpenSim.Framework
return true; 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> /// <summary>
/// Remove an item from one of the queues. Specifically, it removes the /// 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 /// oldest item from the next queue in order to provide fair access to
@ -137,7 +156,7 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) 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. // matter what else. Breaks fairness. But very useful.
for (int iq = 0; iq < NumberOfImmediateQueues; iq++) for (int iq = 0; iq < NumberOfImmediateQueues; iq++)
{ {
@ -172,14 +191,13 @@ namespace OpenSim.Framework
} }
// Find the next non-immediate queue with updates in it // 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_nextQueue++;
m_countFromQueue = m_queueCounts[m_nextQueue]; if(m_nextQueue >= NumberOfQueues)
m_nextQueue = NumberOfImmediateQueues;
// if this is one of the immediate queues, just skip it m_countFromQueue = m_queueCounts[m_nextQueue];
if (m_nextQueue < NumberOfImmediateQueues)
continue;
if (m_heaps[m_nextQueue].Count > 0) if (m_heaps[m_nextQueue].Count > 0)
{ {
@ -189,7 +207,6 @@ namespace OpenSim.Framework
m_lookupTable.Remove(item.Value.Entity.LocalId); m_lookupTable.Remove(item.Value.Entity.LocalId);
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
value = item.Value; value = item.Value;
return true; return true;
} }
} }

View File

@ -40,6 +40,7 @@ using OpenMetaverse.StructuredData;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
[Serializable]
public class RegionLightShareData : ICloneable public class RegionLightShareData : ICloneable
{ {
public bool valid = false; 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 ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[REGION INFO]"; 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 string RegionFile = String.Empty;
public bool isSandbox = false; public bool isSandbox = false;
public bool Persistent = true; public bool Persistent = true;
@ -527,7 +534,11 @@ namespace OpenSim.Framework
return null; return null;
} }
<<<<<<< HEAD
private void SetExtraSetting(string key, string value) private void SetExtraSetting(string key, string value)
=======
public void SetExtraSetting(string key, string value)
>>>>>>> avn/ubitvar
{ {
string keylower = key.ToLower(); string keylower = key.ToLower();
m_extraSettings[keylower] = value; m_extraSettings[keylower] = value;
@ -823,7 +834,15 @@ namespace OpenSim.Framework
string location = String.Format("{0},{1}", RegionLocX, RegionLocY); string location = String.Format("{0},{1}", RegionLocX, RegionLocY);
config.Set("Location", location); config.Set("Location", location);
<<<<<<< HEAD
if (RegionSizeX > 0) if (RegionSizeX > 0)
=======
if (DataStore != String.Empty)
config.Set("Datastore", DataStore);
if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize)
{
>>>>>>> avn/ubitvar
config.Set("SizeX", RegionSizeX); config.Set("SizeX", RegionSizeX);
if (RegionSizeY > 0) if (RegionSizeY > 0)
@ -901,6 +920,234 @@ namespace OpenSim.Framework
throw new Exception("Invalid file type for region persistence."); 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) public void SaveLastMapUUID(UUID mapUUID)
{ {
lastMapUUID = mapUUID; lastMapUUID = mapUUID;
@ -1004,5 +1251,28 @@ namespace OpenSim.Framework
regionInfo.ServerURI = serverURI; regionInfo.ServerURI = serverURI;
return regionInfo; 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;
}
} }
} }

View File

@ -48,6 +48,9 @@ namespace OpenSim.Framework.RegionLoader.Web
public RegionInfo[] LoadRegions() public RegionInfo[] LoadRegions()
{ {
int tries = 3;
int wait = 2000;
if (m_configSource == null) if (m_configSource == null)
{ {
m_log.Error("[WEBLOADER]: Unable to load configuration source!"); m_log.Error("[WEBLOADER]: Unable to load configuration source!");
@ -65,6 +68,8 @@ namespace OpenSim.Framework.RegionLoader.Web
return null; return null;
} }
else else
{
while(tries > 0)
{ {
RegionInfo[] regionInfos = new RegionInfo[] {}; RegionInfo[] regionInfos = new RegionInfo[] {};
int regionCount = 0; int regionCount = 0;
@ -74,26 +79,49 @@ namespace OpenSim.Framework.RegionLoader.Web
try try
{ {
string xmlSource = String.Empty; HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse();
using (HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse())
{
m_log.Debug("[WEBLOADER]: Downloading region information..."); m_log.Debug("[WEBLOADER]: Downloading region information...");
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
using (Stream s = webResponse.GetResponseStream()) string xmlSource = String.Empty;
{
using (StreamReader reader = new StreamReader(s))
{
string tempStr = reader.ReadLine(); string tempStr = reader.ReadLine();
while (tempStr != null) while (tempStr != null)
{ {
xmlSource = xmlSource + tempStr; xmlSource = xmlSource + tempStr;
tempStr = reader.ReadLine(); 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")
{
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: " + m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
xmlSource.Length); xmlSource.Length);
XmlDocument xmlDoc = new XmlDocument(); XmlDocument xmlDoc = new XmlDocument();
@ -118,30 +146,24 @@ namespace OpenSim.Framework.RegionLoader.Web
catch (WebException ex) catch (WebException ex)
{ {
using (HttpWebResponse response = (HttpWebResponse)ex.Response) using (HttpWebResponse response = (HttpWebResponse)ex.Response)
=======
if (regionCount > 0 | allowRegionless)
return regionInfos;
m_log.Debug("[WEBLOADER]: Request yielded no regions.");
tries--;
if (tries > 0)
>>>>>>> avn/ubitvar
{ {
if (response.StatusCode == HttpStatusCode.NotFound) m_log.Debug("[WEBLOADER]: Retrying");
{ System.Threading.Thread.Sleep(wait);
if (!allowRegionless)
throw ex;
}
else
{
throw ex;
}
} }
} }
if (regionCount > 0 | allowRegionless)
{
return regionInfos;
}
else
{
m_log.Error("[WEBLOADER]: No region configs were available."); m_log.Error("[WEBLOADER]: No region configs were available.");
return null; return null;
} }
} }
} }
} }
}
} }

View File

@ -482,6 +482,28 @@ namespace OpenSim.Framework
set { m_LoadedCreationID = value; } 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> /// <summary>
/// Connected Telehub object /// Connected Telehub object
/// </summary> /// </summary>

View File

@ -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 /// This will control a periodic log printout of the current 'show stats' (if they are active) for this
/// server. /// server.
/// </summary> /// </summary>
<<<<<<< HEAD
private int m_periodDiagnosticTimerMS = 60 * 60 * 1000; 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);
=======
// private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
>>>>>>> avn/ubitvar
/// <summary> /// <summary>
/// Random uuid for private data /// Random uuid for private data
@ -84,6 +88,11 @@ namespace OpenSim.Framework.Servers
// Random uuid for private data // Random uuid for private data
m_osSecret = UUID.Random().ToString(); m_osSecret = UUID.Random().ToString();
<<<<<<< HEAD
=======
// m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
// m_periodicDiagnosticsTimer.Enabled = true;
>>>>>>> avn/ubitvar
} }
/// <summary> /// <summary>
@ -147,13 +156,23 @@ namespace OpenSim.Framework.Servers
/// </summary> /// </summary>
public virtual void Startup() 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(); StartupSpecific();
TimeSpan timeTaken = DateTime.Now - m_startuptime; TimeSpan timeTaken = DateTime.Now - m_startuptime;
MainConsole.Instance.OutputFormat( // 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.", // "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); // timeTaken.Minutes, timeTaken.Seconds);
} }
public string osSecret public string osSecret

View File

@ -403,6 +403,7 @@ namespace OpenSim.Framework.Servers.HttpServer
StreamReader reader = new StreamReader(requestStream, encoding); StreamReader reader = new StreamReader(requestStream, encoding);
string requestBody = reader.ReadToEnd(); string requestBody = reader.ReadToEnd();
reader.Close();
Hashtable keysvals = new Hashtable(); Hashtable keysvals = new Hashtable();
Hashtable headervals = new Hashtable(); Hashtable headervals = new Hashtable();
@ -460,7 +461,7 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
resp.ReuseContext = true; resp.ReuseContext = false;
HandleRequest(req, resp); HandleRequest(req, resp);
// !!!HACK ALERT!!! // !!!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 // Every month or so this will wrap and give bad numbers, not really a problem
// since its just for reporting // since its just for reporting
int tickdiff = requestEndTick - requestStartTick; 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( m_log.InfoFormat(
"[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms", "[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; string responseString = String.Empty;
XmlRpcRequest xmlRprcRequest = null; 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 try
{ {
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody); xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
@ -1081,6 +1095,8 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3] xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3]
if (gridproxy)
xmlRprcRequest.Params.Add("gridproxy"); // Param[4]
try try
{ {
xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint);
@ -1731,11 +1747,41 @@ namespace OpenSim.Framework.Servers.HttpServer
} }
internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
{
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"); //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
int responsecode = (int)responsedata["int_response_code"]; responsecode = (int)responsedata["int_response_code"];
string responseString = (string)responsedata["str_response_string"]; if (responsedata["bin_response_data"] != null)
string contentType = (string)responsedata["content_type"]; 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")) if (responsedata.ContainsKey("error_status_text"))
{ {
@ -1780,8 +1826,22 @@ namespace OpenSim.Framework.Servers.HttpServer
response.AddHeader("Content-Type", contentType); 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; byte[] buffer;
if (responseData != null)
{
buffer = responseData;
}
else
{
if (!(contentType.Contains("image") if (!(contentType.Contains("image")
|| contentType.Contains("x-shockwave-flash") || contentType.Contains("x-shockwave-flash")
|| contentType.Contains("application/x-oar") || contentType.Contains("application/x-oar")
@ -1799,6 +1859,7 @@ namespace OpenSim.Framework.Servers.HttpServer
response.SendChunked = false; response.SendChunked = false;
response.ContentLength64 = buffer.Length; response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8; response.ContentEncoding = Encoding.UTF8;
}
return buffer; return buffer;
} }
@ -1886,9 +1947,14 @@ namespace OpenSim.Framework.Servers.HttpServer
m_httpListener2.Start(64); m_httpListener2.Start(64);
// Long Poll Service Manager with 3 worker threads a 25 second timeout for no events // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
<<<<<<< HEAD
PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000); PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000);
PollServiceRequestManager.Start(); PollServiceRequestManager.Start();
=======
m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000);
m_PollServiceManager.Start();
>>>>>>> avn/ubitvar
HTTPDRunning = true; HTTPDRunning = true;
//HttpListenerContext context; //HttpListenerContext context;
@ -1937,7 +2003,9 @@ namespace OpenSim.Framework.Servers.HttpServer
public void httpServerException(object source, Exception exception) 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) if (HTTPDRunning)// && NotSocketErrors > 5)
{ {
@ -1984,6 +2052,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public void RemoveHTTPHandler(string httpMethod, string path) 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) lock (m_HTTPHandlers)
{ {
if (httpMethod != null && httpMethod.Length == 0) if (httpMethod != null && httpMethod.Length == 0)

View File

@ -52,7 +52,9 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
LongPoll = 0, LongPoll = 0,
LslHttp = 1, LslHttp = 1,
Inventory = 2 Inventory = 2,
Texture = 3,
Mesh = 4
} }
public string Url { get; set; } public string Url { get; set; }

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using HttpServer; using HttpServer;
@ -44,6 +45,24 @@ namespace OpenSim.Framework.Servers.HttpServer
public readonly IHttpRequest Request; public readonly IHttpRequest Request;
public readonly int RequestTime; public readonly int RequestTime;
public readonly UUID RequestID; 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( public PollServiceHttpRequest(
PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
@ -53,6 +72,7 @@ namespace OpenSim.Framework.Servers.HttpServer
Request = pRequest; Request = pRequest;
RequestTime = System.Environment.TickCount; RequestTime = System.Environment.TickCount;
RequestID = UUID.Random(); RequestID = UUID.Random();
GenContextHash();
} }
internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
@ -65,6 +85,7 @@ namespace OpenSim.Framework.Servers.HttpServer
response.SendChunked = false; response.SendChunked = false;
response.ContentLength64 = buffer.Length; response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8; response.ContentEncoding = Encoding.UTF8;
response.ReuseContext = false;
try try
{ {
@ -93,5 +114,44 @@ namespace OpenSim.Framework.Servers.HttpServer
PollServiceArgs.RequestsHandled++; 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;
}
} }
} }

View File

@ -65,15 +65,25 @@ namespace OpenSim.Framework.Servers.HttpServer
private readonly BaseHttpServer m_server; private readonly BaseHttpServer m_server;
private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext;
private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); 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 uint m_WorkerThreadCount = 0;
private Thread[] m_workerThreads; private Thread[] m_workerThreads;
private Thread m_retrysThread;
<<<<<<< HEAD
private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2); private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2);
// private int m_timeout = 1000; // increase timeout 250; now use the event one // 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( public PollServiceRequestManager(
BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout) BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout)
@ -83,6 +93,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_WorkerThreadCount = pWorkerThreadCount; m_WorkerThreadCount = pWorkerThreadCount;
m_workerThreads = new Thread[m_WorkerThreadCount]; m_workerThreads = new Thread[m_WorkerThreadCount];
<<<<<<< HEAD
StatsManager.RegisterStat( StatsManager.RegisterStat(
new Stat( new Stat(
"QueuedPollResponses", "QueuedPollResponses",
@ -108,10 +119,25 @@ namespace OpenSim.Framework.Servers.HttpServer
MeasuresOfInterest.AverageChangeOverTime, MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = ResponsesProcessed, stat => stat.Value = ResponsesProcessed,
StatVerbosity.Debug)); 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() public void Start()
{ {
<<<<<<< HEAD
IsRunning = true; IsRunning = true;
if (PerformResponsesAsync) if (PerformResponsesAsync)
@ -139,40 +165,100 @@ namespace OpenSim.Framework.Servers.HttpServer
null, null,
1000 * 60 * 10); 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) private void ReQueueEvent(PollServiceHttpRequest req)
{ {
if (IsRunning) if (IsRunning)
{ {
// delay the enqueueing for 100ms. There's no need to have the event lock (m_retryRequests)
// actively on the queue m_retryRequests.Enqueue(req);
Timer t = new Timer(self => {
((Timer)self).Dispose();
m_requests.Enqueue(req);
});
t.Change(100, Timeout.Infinite);
} }
} }
public void Enqueue(PollServiceHttpRequest 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) ctxQeueue.Enqueue(req);
m_longPollRequests.Add(req);
} }
else 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. // 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 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. // 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 // 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. // directly back in the "ready-to-serve" queue by the worker thread.
while (IsRunning) while (IsRunning)
=======
while (m_running)
>>>>>>> avn/ubitvar
{ {
Thread.Sleep(500); Thread.Sleep(100); // let the world move .. back to faster rate
Watchdog.UpdateThread(); Watchdog.UpdateThread();
lock (m_retryRequests)
// List<PollServiceHttpRequest> not_ready = new List<PollServiceHttpRequest>();
lock (m_longPollRequests)
{ {
<<<<<<< HEAD
if (m_longPollRequests.Count > 0 && IsRunning) if (m_longPollRequests.Count > 0 && IsRunning)
{ {
List<PollServiceHttpRequest> ready = m_longPollRequests.FindAll(req => List<PollServiceHttpRequest> ready = m_longPollRequests.FindAll(req =>
@ -199,28 +287,67 @@ namespace OpenSim.Framework.Servers.HttpServer
m_requests.Enqueue(req); m_requests.Enqueue(req);
m_longPollRequests.Remove(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() public void Stop()
{ {
<<<<<<< HEAD
IsRunning = false; IsRunning = false;
// m_timeout = -10000; // cause all to expire // m_timeout = -10000; // cause all to expire
=======
m_running = false;
>>>>>>> avn/ubitvar
Thread.Sleep(1000); // let the world move Thread.Sleep(1000); // let the world move
foreach (Thread t in m_workerThreads) foreach (Thread t in m_workerThreads)
Watchdog.AbortThread(t.ManagedThreadId); 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) if (m_longPollRequests.Count > 0 && IsRunning)
m_longPollRequests.ForEach(req => m_requests.Enqueue(req)); 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) while (m_requests.Count() > 0)
@ -228,16 +355,19 @@ namespace OpenSim.Framework.Servers.HttpServer
try try
{ {
wreq = m_requests.Dequeue(0); wreq = m_requests.Dequeue(0);
<<<<<<< HEAD
ResponsesProcessed++; ResponsesProcessed++;
wreq.DoHTTPGruntWork( wreq.DoHTTPGruntWork(
m_server, wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id)); m_server, wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id));
=======
wreq.DoHTTPstop(m_server);
>>>>>>> avn/ubitvar
} }
catch catch
{ {
} }
} }
m_longPollRequests.Clear();
m_requests.Clear(); m_requests.Clear();
} }
@ -247,6 +377,11 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
while (IsRunning) while (IsRunning)
{ {
<<<<<<< HEAD
=======
PollServiceHttpRequest req = m_requests.Dequeue(5000);
>>>>>>> avn/ubitvar
Watchdog.UpdateThread(); Watchdog.UpdateThread();
WaitPerformResponse(); WaitPerformResponse();
} }
@ -265,6 +400,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
<<<<<<< HEAD
if (responsedata == null) if (responsedata == null)
return; return;
@ -287,11 +423,15 @@ namespace OpenSim.Framework.Servers.HttpServer
else else
{ {
m_threadPool.QueueWorkItem(x => m_threadPool.QueueWorkItem(x =>
=======
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
>>>>>>> avn/ubitvar
{ {
try try
{ {
ResponsesProcessed++; ResponsesProcessed++;
req.DoHTTPGruntWork(m_server, responsedata); req.DoHTTPGruntWork(m_server, responsedata);
byContextDequeue(req);
} }
catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream 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) catch (Exception e)
{ {
<<<<<<< HEAD
m_log.Error(e); m_log.Error(e);
} }
@ -318,6 +459,34 @@ namespace OpenSim.Framework.Servers.HttpServer
else else
{ {
ReQueueEvent(req); 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
} }
} }
} }
} }
} }

View File

@ -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); return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion);
} }

View File

@ -41,7 +41,331 @@ namespace OpenSim.Framework.Servers.Tests
{ {
[TestFixture] [TestFixture]
public class OSHttpTests : OpenSimTestCase 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 req0;
public OSHttpRequest req1; public OSHttpRequest req1;

View File

@ -27,9 +27,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Reflection;
using System.Xml; using System.Xml;
using System.Diagnostics;
using System.Xml.Schema; using System.Xml.Schema;
using System.Xml.Serialization; using System.Xml.Serialization;
using log4net;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Framework namespace OpenSim.Framework
@ -47,6 +51,180 @@ namespace OpenSim.Framework
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem)); 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 #region ICloneable Members
@ -54,13 +232,12 @@ namespace OpenSim.Framework
{ {
TaskInventoryDictionary clone = new TaskInventoryDictionary(); 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; return clone;
} }

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression;
using System.Reflection; using System.Reflection;
using OpenMetaverse; using OpenMetaverse;
@ -48,6 +49,7 @@ namespace OpenSim.Framework
public abstract float this[int x, int y] { get; set; } public abstract float this[int x, int y] { get; set; }
// Someday terrain will have caves // Someday terrain will have caves
// at most holes :p
public abstract float this[int x, int y, int z] { get; set; } public abstract float this[int x, int y, int z] { get; set; }
public abstract bool IsTaintedAt(int xx, int yy); public abstract bool IsTaintedAt(int xx, int yy);
@ -72,8 +74,8 @@ namespace OpenSim.Framework
return new HeightmapTerrainData(pSizeX, pSizeY, pSizeZ, pFormatCode, pBlob); return new HeightmapTerrainData(pSizeX, pSizeY, pSizeZ, pFormatCode, pBlob);
} }
// return a special compressed representation of the heightmap in ints // return a special compressed representation of the heightmap in ushort
public abstract int[] GetCompressedMap(); public abstract float[] GetCompressedMap();
public abstract float CompressionFactor { get; } public abstract float CompressionFactor { get; }
public abstract float[] GetFloatsSerialized(); public abstract float[] GetFloatsSerialized();
@ -94,14 +96,18 @@ namespace OpenSim.Framework
{ {
// Terrain is 'double[256,256]' // Terrain is 'double[256,256]'
Legacy256 = 11, Legacy256 = 11,
// Terrain is 'int32, int32, float[,]' where the ints are X and Y dimensions // 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. // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
Variable2D = 22, Variable2D = 22,
Variable2DGzip = 23,
// Terrain is 'int32, int32, int32, int16[]' where the ints are X and Y dimensions // 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 // 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. // The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
Compressed2D = 27, Compressed2D = 27,
// A revision that is not listed above or any revision greater than this value is 'Legacy256'. // A revision that is not listed above or any revision greater than this value is 'Legacy256'.
RevisionHigh = 1234 RevisionHigh = 1234
} }
@ -109,7 +115,7 @@ namespace OpenSim.Framework
// Version of terrain that is a heightmap. // Version of terrain that is a heightmap.
// This should really be 'LLOptimizedHeightmapTerrainData' as it includes knowledge // This should really be 'LLOptimizedHeightmapTerrainData' as it includes knowledge
// of 'patches' which are 16x16 terrain areas which can be sent separately to the viewer. // 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. // and from floats by TerrainCompressionFactor.
public class HeightmapTerrainData : TerrainData public class HeightmapTerrainData : TerrainData
{ {
@ -119,12 +125,12 @@ namespace OpenSim.Framework
// TerrainData.this[x, y] // TerrainData.this[x, y]
public override float this[int x, int y] public override float this[int x, int y]
{ {
get { return FromCompressedHeight(m_heightmap[x, y]); } get { return m_heightmap[x, y]; }
set { set
int newVal = ToCompressedHeight(value);
if (m_heightmap[x, y] != newVal)
{ {
m_heightmap[x, y] = newVal; if (m_heightmap[x, y] != value)
{
m_heightmap[x, y] = value;
m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true; m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true;
} }
} }
@ -164,10 +170,9 @@ namespace OpenSim.Framework
// TerrainData.ClearLand(float) // TerrainData.ClearLand(float)
public override void ClearLand(float pHeight) public override void ClearLand(float pHeight)
{ {
int flatHeight = ToCompressedHeight(pHeight);
for (int xx = 0; xx < SizeX; xx++) for (int xx = 0; xx < SizeX; xx++)
for (int yy = 0; yy < SizeY; yy++) 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. // Return 'true' of the patch that contains these region coordinates has been modified.
@ -184,6 +189,8 @@ namespace OpenSim.Framework
} }
// Old form that clears the taint flag when we check it. // 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) public override bool IsTaintedAt(int xx, int yy)
{ {
return IsTaintedAt(xx, yy, true /* clearOnTest */); return IsTaintedAt(xx, yy, true /* clearOnTest */);
@ -202,8 +209,10 @@ namespace OpenSim.Framework
} }
else else
{ {
DBRevisionCode = (int)DBTerrainRevision.Compressed2D; DBRevisionCode = (int)DBTerrainRevision.Variable2DGzip;
blob = ToCompressedTerrainSerialization(); // DBRevisionCode = (int)DBTerrainRevision.Variable2D;
blob = ToCompressedTerrainSerializationV2DGzip();
// blob = ToCompressedTerrainSerializationV2D();
ret = true; ret = true;
} }
return ret; return ret;
@ -214,9 +223,9 @@ namespace OpenSim.Framework
public override float CompressionFactor { get { return m_compressionFactor; } } public override float CompressionFactor { get { return m_compressionFactor; } }
// TerrainData.GetCompressedMap // 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; int ind = 0;
for (int xx = 0; xx < SizeX; xx++) for (int xx = 0; xx < SizeX; xx++)
@ -230,7 +239,7 @@ namespace OpenSim.Framework
public override TerrainData Clone() public override TerrainData Clone()
{ {
HeightmapTerrainData ret = new HeightmapTerrainData(SizeX, SizeY, SizeZ); 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; return ret;
} }
@ -247,7 +256,7 @@ namespace OpenSim.Framework
for (int jj = 0; jj < SizeY; jj++) for (int jj = 0; jj < SizeY; jj++)
for (int ii = 0; ii < SizeX; ii++) for (int ii = 0; ii < SizeX; ii++)
{ {
heights[idx++] = FromCompressedHeight(m_heightmap[ii, jj]); heights[idx++] = m_heightmap[ii, jj];
} }
return heights; return heights;
@ -259,7 +268,7 @@ namespace OpenSim.Framework
double[,] ret = new double[SizeX, SizeY]; double[,] ret = new double[SizeX, SizeY];
for (int xx = 0; xx < SizeX; xx++) for (int xx = 0; xx < SizeX; xx++)
for (int yy = 0; yy < SizeY; yy++) 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; 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. // Remember subregions of the heightmap that has changed.
private bool[,] m_taint; 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' // that is coded as the float height times the compression factor (usually '100'
// to make for two decimal points). // 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; return ((float)pHeight) / CompressionFactor;
} }
@ -293,12 +323,12 @@ namespace OpenSim.Framework
SizeZ = (int)Constants.RegionHeight; SizeZ = (int)Constants.RegionHeight;
m_compressionFactor = 100.0f; 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 ii = 0; ii < SizeX; ii++)
{ {
for (int jj = 0; jj < SizeY; jj++) 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; SizeY = pY;
SizeZ = pZ; SizeZ = pZ;
m_compressionFactor = 100.0f; 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_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); // m_log.DebugFormat("{0} new by dimensions. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ);
ClearTaint(); ClearTaint();
ClearLand(0f); 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; m_compressionFactor = pCompressionFactor;
int ind = 0; int ind = 0;
@ -333,12 +364,22 @@ namespace OpenSim.Framework
} }
// Create a heighmap from a database blob // 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) 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: case DBTerrainRevision.Compressed2D:
FromCompressedTerrainSerialization(pBlob); FromCompressedTerrainSerialization2D(pBlob);
m_log.DebugFormat("{0} HeightmapTerrainData create from Compressed2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY); m_log.DebugFormat("{0} HeightmapTerrainData create from Compressed2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
break; break;
default: default:
@ -373,12 +414,14 @@ namespace OpenSim.Framework
return ret; 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) public void FromLegacyTerrainSerialization(byte[] pBlob)
{ {
// In case database info doesn't match real terrain size, initialize the whole terrain. // In case database info doesn't match real terrain size, initialize the whole terrain.
ClearLand(); ClearLand();
try
{
using (MemoryStream mstr = new MemoryStream(pBlob)) using (MemoryStream mstr = new MemoryStream(pBlob))
{ {
using (BinaryReader br = new BinaryReader(mstr)) using (BinaryReader br = new BinaryReader(mstr))
@ -388,35 +431,99 @@ namespace OpenSim.Framework
for (int yy = 0; yy < (int)Constants.RegionSize; yy++) for (int yy = 0; yy < (int)Constants.RegionSize; yy++)
{ {
float val = (float)br.ReadDouble(); float val = (float)br.ReadDouble();
if (xx < SizeX && yy < SizeY) if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = ToCompressedHeight(val); m_heightmap[xx, yy] = val;
} }
} }
} }
}
}
catch
{
ClearLand();
}
ClearTaint(); ClearTaint();
} }
}
// See the reader below.
public Array ToCompressedTerrainSerialization() // stores as variable2D
// int32 sizeX
// int32 sizeY
// float[,] array
public Array ToCompressedTerrainSerializationV2D()
{ {
Array ret = null; Array ret = null;
using (MemoryStream str = new MemoryStream((3 * sizeof(Int32)) + (SizeX * SizeY * sizeof(Int16)))) try
{
using (MemoryStream str = new MemoryStream((2 * sizeof(Int32)) + (SizeX * SizeY * sizeof(float))))
{ {
using (BinaryWriter bw = new BinaryWriter(str)) using (BinaryWriter bw = new BinaryWriter(str))
{ {
bw.Write((Int32)DBTerrainRevision.Compressed2D);
bw.Write((Int32)SizeX); bw.Write((Int32)SizeX);
bw.Write((Int32)SizeY); bw.Write((Int32)SizeY);
bw.Write((Int32)CompressionFactor);
for (int yy = 0; yy < SizeY; yy++) for (int yy = 0; yy < SizeY; yy++)
for (int xx = 0; xx < SizeX; xx++) for (int xx = 0; xx < SizeX; xx++)
{ {
bw.Write((Int16)m_heightmap[xx, yy]); // 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; return ret;
} }
@ -426,7 +533,7 @@ namespace OpenSim.Framework
// the forth int is the compression factor for the following int16s // 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 // 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. // 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; Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor;
@ -448,7 +555,7 @@ namespace OpenSim.Framework
{ {
for (int xx = 0; xx < hmSizeX; xx++) for (int xx = 0; xx < hmSizeX; xx++)
{ {
Int16 val = br.ReadInt16(); float val = FromCompressedHeight(br.ReadInt16());
if (xx < SizeX && yy < SizeY) if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = val; m_heightmap[xx, yy] = val;
} }
@ -456,9 +563,112 @@ namespace OpenSim.Framework
} }
ClearTaint(); 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); 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);
}
} }
} }

View File

@ -218,12 +218,12 @@ namespace OpenSim.Framework.Tests
BannedHostNameMask = string.Empty, BannedHostNameMask = string.Empty,
BannedUserID = bannedUserId} BannedUserID = bannedUserId}
); );
Assert.IsTrue(es.IsBanned(bannedUserId), "User Should be banned but is not."); Assert.IsTrue(es.IsBanned(bannedUserId, 32), "User Should be banned but is not.");
Assert.IsFalse(es.IsBanned(UUID.Zero), "User Should not be banned but is."); Assert.IsFalse(es.IsBanned(UUID.Zero, 32), "User Should not be banned but is.");
es.RemoveBan(bannedUserId); 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); es.AddEstateManager(UUID.Zero);

View File

@ -47,6 +47,8 @@ namespace OpenSim.Framework
Texture = 5, Texture = 5,
/// <summary>Non-texture assets</summary> /// <summary>Non-texture assets</summary>
Asset = 6, Asset = 6,
HighPriority = 128,
} }
[Flags] [Flags]

View File

@ -160,7 +160,11 @@ namespace OpenSim.Framework
public virtual ulong HomeRegion public virtual ulong HomeRegion
{ {
get get
<<<<<<< HEAD
{ {
=======
{
>>>>>>> avn/ubitvar
return Util.RegionWorldLocToHandle(Util.RegionToWorldLoc(m_homeRegionX), Util.RegionToWorldLoc(m_homeRegionY)); return Util.RegionWorldLocToHandle(Util.RegionToWorldLoc(m_homeRegionX), Util.RegionToWorldLoc(m_homeRegionY));
// return Utils.UIntsToLong( m_homeRegionX * (uint)Constants.RegionSize, m_homeRegionY * (uint)Constants.RegionSize); // return Utils.UIntsToLong( m_homeRegionX * (uint)Constants.RegionSize, m_homeRegionY * (uint)Constants.RegionSize);
} }

View File

@ -92,14 +92,6 @@ namespace OpenSim.Framework
public string Notes; 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 class UserAccountProperties
{ {
public string EmailAddress = string.Empty; public string EmailAddress = string.Empty;

View File

@ -61,6 +61,15 @@ namespace OpenSim.Framework
public enum PermissionMask : uint public enum PermissionMask : uint
{ {
None = 0, None = 0,
// folded perms
foldedTransfer = 1,
foldedModify = 1 << 1,
foldedCopy = 1 << 2,
foldedMask = 0x07,
//
Transfer = 1 << 13, Transfer = 1 << 13,
Modify = 1 << 14, Modify = 1 << 14,
Copy = 1 << 15, Copy = 1 << 15,
@ -267,14 +276,12 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
/// <param name="a">A 3d vector</param> /// <param name="a">A 3d vector</param>
/// <returns>A new vector which is normalized form of the vector</returns> /// <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) public static Vector3 GetNormalizedVector(Vector3 a)
{ {
if (IsZeroVector(a)) Vector3 v = new Vector3(a.X, a.Y, a.Z);
throw new ArgumentException("Vector paramater cannot be a zero vector."); v.Normalize();
return v;
float Mag = (float) GetMagnitude(a);
return new Vector3(a.X / Mag, a.Y / Mag, a.Z / Mag);
} }
/// <summary> /// <summary>
@ -641,19 +648,25 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <returns></returns> /// <returns></returns>
public static string Md5Hash(string data) 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(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < dataMd5.Length; i++) for (int i = 0; i < dataMd5.Length; i++)
sb.AppendFormat("{0:x2}", dataMd5[i]); sb.AppendFormat("{0:x2}", dataMd5[i]);
return sb.ToString(); return sb.ToString();
} }
private static byte[] ComputeMD5Hash(string data) private static byte[] ComputeMD5Hash(string data, Encoding encoding)
{ {
MD5 md5 = MD5.Create(); MD5 md5 = MD5.Create();
return md5.ComputeHash(Encoding.Default.GetBytes(data)); return md5.ComputeHash(encoding.GetBytes(data));
} }
/// <summary> /// <summary>
@ -661,6 +674,12 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <returns></returns> /// <returns></returns>
public static string SHA1Hash(string data, Encoding enc)
{
return SHA1Hash(enc.GetBytes(data));
}
public static string SHA1Hash(string data) public static string SHA1Hash(string data)
{ {
return SHA1Hash(Encoding.Default.GetBytes(data)); return SHA1Hash(Encoding.Default.GetBytes(data));
@ -714,17 +733,26 @@ namespace OpenSim.Framework
/// <param name="oldy">Old region y-coord</param> /// <param name="oldy">Old region y-coord</param>
/// <param name="newy">New region y-coord</param> /// <param name="newy">New region y-coord</param>
/// <returns></returns> /// <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; oldx *= Constants.RegionSize;
int startY = (int)oldy - dd; newx *= Constants.RegionSize;
if (oldx + oldsizex + drawdist < newx)
return true;
if (newx + newsizex + drawdist < oldx)
return true;
int endX = (int)oldx + dd; oldy *= Constants.RegionSize;
int endY = (int)oldy + dd; 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) public static string FieldToString(byte[] bytes)
@ -804,6 +832,16 @@ namespace OpenSim.Framework
return output.ToString(); 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> /// <summary>
/// Returns a IP address from a specified DNS, favouring IPv4 addresses. /// Returns a IP address from a specified DNS, favouring IPv4 addresses.
/// </summary> /// </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> /// <summary>
/// Gets the value of a configuration variable by looking into /// Gets the value of a configuration variable by looking into
/// multiple sections in order. The latter sections overwrite /// multiple sections in order. The latter sections overwrite
@ -1388,6 +1445,46 @@ namespace OpenSim.Framework
return ret; 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> /// <summary>
/// Copy data from one stream to another, leaving the read position of both streams at the beginning. /// Copy data from one stream to another, leaving the read position of both streams at the beginning.
/// </summary> /// </summary>
@ -1524,19 +1621,19 @@ namespace OpenSim.Framework
{ {
string os = String.Empty; string os = String.Empty;
if (Environment.OSVersion.Platform != PlatformID.Unix) // if (Environment.OSVersion.Platform != PlatformID.Unix)
{ // {
os = Environment.OSVersion.ToString(); // os = Environment.OSVersion.ToString();
} // }
else // else
{ // {
os = ReadEtcIssue(); // os = ReadEtcIssue();
} // }
//
if (os.Length > 45) // if (os.Length > 45)
{ // {
os = os.Substring(0, 45); // os = os.Substring(0, 45);
} // }
return os; return os;
} }
@ -1591,6 +1688,69 @@ namespace OpenSim.Framework
return displayConnectionString; 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) public static string Base64ToString(string str)
{ {
Decoder utf8Decode = Encoding.UTF8.GetDecoder(); Decoder utf8Decode = Encoding.UTF8.GetDecoder();
@ -1645,7 +1805,7 @@ namespace OpenSim.Framework
public static Guid GetHashGuid(string data, string salt) 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); //string s = BitConverter.ToString(hash);
@ -1792,6 +1952,32 @@ namespace OpenSim.Framework
return found.ToArray(); 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> /// <summary>
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary. /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
/// </summary> /// </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) public static void InitThreadPool(int minThreads, int maxThreads)
{ {
if (maxThreads < 2) if (maxThreads < 2)
@ -1986,7 +2177,7 @@ namespace OpenSim.Framework
STPStartInfo startInfo = new STPStartInfo(); STPStartInfo startInfo = new STPStartInfo();
startInfo.ThreadPoolName = "Util"; startInfo.ThreadPoolName = "Util";
startInfo.IdleTimeout = 2000; startInfo.IdleTimeout = 20000;
startInfo.MaxWorkerThreads = maxThreads; startInfo.MaxWorkerThreads = maxThreads;
startInfo.MinWorkerThreads = minThreads; startInfo.MinWorkerThreads = minThreads;

View File

@ -29,7 +29,11 @@ namespace OpenSim
{ {
public class VersionInfo public class VersionInfo
{ {
<<<<<<< HEAD:OpenSim/Framework/VersionInfo.cs
public const string VersionNumber = "0.8.2.0"; 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; private const Flavour VERSION_FLAVOUR = Flavour.Dev;
public enum Flavour public enum Flavour
@ -51,7 +55,7 @@ namespace OpenSim
public static string GetVersionString(string versionNumber, Flavour flavour) public static string GetVersionString(string versionNumber, Flavour flavour)
{ {
string versionString = "OpenSim " + versionNumber + " " + flavour; string versionString = "Careminster " + versionNumber + " " + flavour;
return versionString.PadRight(VERSIONINFO_VERSION_LENGTH); return versionString.PadRight(VERSIONINFO_VERSION_LENGTH);
} }

View File

@ -43,12 +43,13 @@ namespace OpenSim.Framework
public static WearableCacheItem[] GetDefaultCacheItem() public static WearableCacheItem[] GetDefaultCacheItem()
{ {
int itemmax = 21; int itemmax = AvatarAppearance.TEXTURE_COUNT;
WearableCacheItem[] retitems = new WearableCacheItem[itemmax]; WearableCacheItem[] retitems = new WearableCacheItem[itemmax];
for (uint i=0;i<itemmax;i++) 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; return retitems;
} }
public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache) public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache)
{ {
List<WearableCacheItem> ret = new List<WearableCacheItem>(); List<WearableCacheItem> ret = new List<WearableCacheItem>();
@ -98,6 +99,7 @@ namespace OpenSim.Framework
return ret.ToArray(); return ret.ToArray();
} }
public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache) public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache)
{ {
OSDArray arr = new OSDArray(); OSDArray arr = new OSDArray();
@ -124,6 +126,68 @@ namespace OpenSim.Framework
} }
return arr; 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) public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems)
{ {
for (int i = 0; i < pcacheItems.Length; i++) for (int i = 0; i < pcacheItems.Length; i++)

View File

@ -86,7 +86,7 @@ namespace OpenSim.Framework
/// Number of milliseconds a call can take before it is considered /// Number of milliseconds a call can take before it is considered
/// a "long" call for warning & debugging purposes /// a "long" call for warning & debugging purposes
/// </summary> /// </summary>
public const int LongCallTime = 3000; public const int LongCallTime = 500;
/// <summary> /// <summary>
/// The maximum length of any data logged because of a long request time. /// The maximum length of any data logged because of a long request time.
@ -205,8 +205,16 @@ namespace OpenSim.Framework
{ {
if (DebugLevel == 5) if (DebugLevel == 5)
{ {
<<<<<<< HEAD
if (output.Length > MaxRequestDiagLength) if (output.Length > MaxRequestDiagLength)
output = output.Substring(0, 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)); m_log.DebugFormat("[LOGHTTP]: {0}{1}", context, Util.BinaryToASCII(output));
@ -233,6 +241,9 @@ namespace OpenSim.Framework
string errorMessage = "unknown error"; string errorMessage = "unknown error";
int tickstart = Util.EnvironmentTickCount(); int tickstart = Util.EnvironmentTickCount();
int tickdata = 0; int tickdata = 0;
int tickcompressdata = 0;
int tickJsondata = 0;
int compsize = 0;
string strBuffer = null; string strBuffer = null;
try try
@ -250,6 +261,8 @@ namespace OpenSim.Framework
{ {
strBuffer = OSDParser.SerializeJsonString(data); strBuffer = OSDParser.SerializeJsonString(data);
tickJsondata = Util.EnvironmentTickCountSubtract(tickstart);
if (DebugLevel >= 5) if (DebugLevel >= 5)
LogOutgoingDetail("SEND", reqnum, strBuffer); LogOutgoingDetail("SEND", reqnum, strBuffer);
@ -271,13 +284,23 @@ namespace OpenSim.Framework
// gets written on the stream upon Dispose() // gets written on the stream upon Dispose()
} }
byte[] buf = ms.ToArray(); byte[] buf = ms.ToArray();
tickcompressdata = Util.EnvironmentTickCountSubtract(tickstart);
request.ContentLength = buf.Length; //Count bytes to send request.ContentLength = buf.Length; //Count bytes to send
compsize = buf.Length;
using (Stream requestStream = request.GetRequestStream()) using (Stream requestStream = request.GetRequestStream())
requestStream.Write(buf, 0, (int)buf.Length); requestStream.Write(buf, 0, (int)buf.Length);
} }
} }
else else
{ {
<<<<<<< HEAD
=======
tickcompressdata = tickJsondata;
compsize = buffer.Length;
request.ContentType = "application/json";
>>>>>>> avn/ubitvar
request.ContentLength = buffer.Length; //Count bytes to send request.ContentLength = buffer.Length; //Count bytes to send
using (Stream requestStream = request.GetRequestStream()) using (Stream requestStream = request.GetRequestStream())
requestStream.Write(buffer, 0, buffer.Length); //Send it requestStream.Write(buffer, 0, buffer.Length); //Send it
@ -292,6 +315,7 @@ namespace OpenSim.Framework
{ {
using (Stream responseStream = response.GetResponseStream()) using (Stream responseStream = response.GetResponseStream())
{ {
<<<<<<< HEAD
using (StreamReader reader = new StreamReader(responseStream)) using (StreamReader reader = new StreamReader(responseStream))
{ {
string responseStr = reader.ReadToEnd(); string responseStr = reader.ReadToEnd();
@ -299,6 +323,12 @@ namespace OpenSim.Framework
WebUtil.LogResponseDetail(reqnum, responseStr); WebUtil.LogResponseDetail(reqnum, responseStr);
return CanonicalizeResults(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) catch (Exception ex)
{ {
errorMessage = ex.Message; errorMessage = ex.Message;
m_log.Debug("[WEB UTIL]: Exception making request: " + ex.ToString());
} }
finally finally
{ {
@ -321,8 +352,21 @@ namespace OpenSim.Framework
if (tickdiff > LongCallTime) if (tickdiff > LongCallTime)
{ {
m_log.InfoFormat( m_log.InfoFormat(
<<<<<<< HEAD
"[LOGHTTP]: Slow JSON-RPC request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", "[LOGHTTP]: Slow JSON-RPC request {0} {1} to {2} took {3}ms, {4}ms writing, {5}",
reqnum, method, url, tickdiff, tickdata, 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 != null
? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
: ""); : "");
@ -396,7 +440,7 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
public static OSDMap PostToService(string url, NameValueCollection data) 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) public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
@ -790,7 +834,8 @@ namespace OpenSim.Framework
reqnum, verb, requestUrl); reqnum, verb, requestUrl);
int tickstart = Util.EnvironmentTickCount(); int tickstart = Util.EnvironmentTickCount();
int tickdata = 0; // int tickdata = 0;
int tickdiff = 0;
Type type = typeof(TRequest); Type type = typeof(TRequest);
@ -831,10 +876,17 @@ namespace OpenSim.Framework
request.ContentLength = length; request.ContentLength = length;
byte[] data = buffer.ToArray(); byte[] data = buffer.ToArray();
<<<<<<< HEAD
if (WebUtil.DebugLevel >= 5) if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
request.BeginGetRequestStream(delegate(IAsyncResult res) 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)) using (Stream requestStream = request.EndGetRequestStream(res))
requestStream.Write(data, 0, length); requestStream.Write(data, 0, length);
@ -844,6 +896,7 @@ namespace OpenSim.Framework
request.BeginGetResponse(delegate(IAsyncResult ar) request.BeginGetResponse(delegate(IAsyncResult ar)
{ {
<<<<<<< HEAD
using (WebResponse response = request.EndGetResponse(ar)) using (WebResponse response = request.EndGetResponse(ar))
{ {
try 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); action(deserial);
@ -919,6 +980,7 @@ namespace OpenSim.Framework
"[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
verb, requestUrl, e.Message, e.StackTrace); verb, requestUrl, e.Message, e.StackTrace);
} }
<<<<<<< HEAD
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
@ -942,12 +1004,36 @@ namespace OpenSim.Framework
string originalRequest = null; string originalRequest = null;
if (buffer != 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()); originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
<<<<<<< HEAD
if (originalRequest.Length > WebUtil.MaxRequestDiagLength) if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
} }
=======
tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
if (tickdiff > WebUtil.LongCallTime)
{
/*
string originalRequest = null;
>>>>>>> avn/ubitvar
m_log.InfoFormat( m_log.InfoFormat(
"[LOGHTTP]: Slow AsynchronousRequestObject request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", "[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", m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing",
reqnum, tickdiff, tickdata); reqnum, tickdiff, tickdata);
} }
<<<<<<< HEAD
} }
finally finally
{ {
if (buffer != null) if (buffer != null)
buffer.Dispose(); 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; string respstring = String.Empty;
int tickset = Util.EnvironmentTickCountSubtract(tickstart);
using (MemoryStream buffer = new MemoryStream()) using (MemoryStream buffer = new MemoryStream())
{ {
if ((verb == "POST") || (verb == "PUT")) if ((verb == "POST") || (verb == "PUT"))
@ -1015,14 +1128,19 @@ namespace OpenSim.Framework
{ {
writer.Write(obj); writer.Write(obj);
writer.Flush(); writer.Flush();
if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail(buffer);
} }
length = (int)obj.Length; length = (int)obj.Length;
request.ContentLength = length; request.ContentLength = length;
byte[] data = buffer.ToArray(); byte[] data = buffer.ToArray();
<<<<<<< HEAD
if (WebUtil.DebugLevel >= 5) if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
=======
>>>>>>> avn/ubitvar
Stream requestStream = null; Stream requestStream = null;
try try
@ -1070,8 +1188,18 @@ namespace OpenSim.Framework
if (tickdiff > WebUtil.LongCallTime) if (tickdiff > WebUtil.LongCallTime)
{ {
m_log.InfoFormat( m_log.InfoFormat(
<<<<<<< HEAD
"[LOGHTTP]: Slow SynchronousRestForms request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", "[LOGHTTP]: Slow SynchronousRestForms request {0} {1} to {2} took {3}ms, {4}ms writing, {5}",
reqnum, verb, requestUrl, tickdiff, tickdata, 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); obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
} }
else if (WebUtil.DebugLevel >= 4) else if (WebUtil.DebugLevel >= 4)
@ -1208,6 +1336,8 @@ namespace OpenSim.Framework
ht.ServicePoint.ConnectionLimit = maxConnections; ht.ServicePoint.ConnectionLimit = maxConnections;
request.Method = verb; request.Method = verb;
if (pTimeout != 0)
request.Timeout = pTimeout * 1000;
MemoryStream buffer = null; MemoryStream buffer = null;
try try
@ -1221,17 +1351,29 @@ namespace OpenSim.Framework
XmlWriterSettings settings = new XmlWriterSettings(); XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8; settings.Encoding = Encoding.UTF8;
<<<<<<< HEAD
using (XmlWriter writer = XmlWriter.Create(buffer, settings)) using (XmlWriter writer = XmlWriter.Create(buffer, settings))
{ {
XmlSerializer serializer = new XmlSerializer(type); XmlSerializer serializer = new XmlSerializer(type);
serializer.Serialize(writer, obj); serializer.Serialize(writer, obj);
writer.Flush(); 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; int length = (int)buffer.Length;
request.ContentLength = length; request.ContentLength = length;
byte[] data = buffer.ToArray(); byte[] data = buffer.ToArray();
<<<<<<< HEAD
if (WebUtil.DebugLevel >= 5) if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
@ -1255,6 +1397,9 @@ namespace OpenSim.Framework
} }
} }
=======
Stream requestStream = null;
>>>>>>> avn/ubitvar
try try
{ {
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())

View File

@ -75,6 +75,7 @@ namespace OpenSim
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
ServicePointManager.DefaultConnectionLimit = 12; ServicePointManager.DefaultConnectionLimit = 12;
ServicePointManager.UseNagleAlgorithm = false;
// Add the arguments supplied when running the application to the configuration // Add the arguments supplied when running the application to the configuration
ArgvConfigSource configSource = new ArgvConfigSource(args); ArgvConfigSource configSource = new ArgvConfigSource(args);

View File

@ -109,13 +109,19 @@ namespace OpenSim
m_timeInterval = startupConfig.GetInt("timer_Interval", 1200); 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); string asyncCallMethodStr = startupConfig.GetString("async_call_method", String.Empty);
FireAndForgetMethod asyncCallMethod; FireAndForgetMethod asyncCallMethod;
if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod)) if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod))
Util.FireAndForgetMethod = asyncCallMethod; Util.FireAndForgetMethod = asyncCallMethod;
<<<<<<< HEAD
stpMinThreads = startupConfig.GetInt("MinPoolThreads", 15); stpMinThreads = startupConfig.GetInt("MinPoolThreads", 15);
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 300); stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 300);
=======
stpMinThreads = startupConfig.GetInt("MinPoolThreads", 2 );
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 25);
>>>>>>> avn/ubitvar
m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) "); m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
} }
@ -267,12 +273,20 @@ namespace OpenSim
SavePrimsXml2); SavePrimsXml2);
m_console.Commands.AddCommand("Archiving", false, "load oar", m_console.Commands.AddCommand("Archiving", false, "load oar",
<<<<<<< HEAD
=======
>>>>>>> avn/ubitvar
"load oar [--merge] [--skip-assets]" "load oar [--merge] [--skip-assets]"
+ " [--default-user \"User Name\"]" + " [--default-user \"User Name\"]"
+ " [--force-terrain] [--force-parcels]" + " [--force-terrain] [--force-parcels]"
+ " [--no-objects]" + " [--no-objects]"
+ " [--rotation degrees] [--rotation-center \"<x,y,z>\"]" + " [--rotation degrees] [--rotation-center \"<x,y,z>\"]"
<<<<<<< HEAD
+ " [--displacement \"<x,y,z>\"]" + " [--displacement \"<x,y,z>\"]"
=======
+ " [--displacement \"<x,y,z>\"]"
>>>>>>> avn/ubitvar
+ " [<OAR path>]", + " [<OAR path>]",
"Load a region's data from an OAR archive.", "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" "--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) if (alert != null)
presence.ControllingClient.Kick(alert); presence.ControllingClient.Kick(alert);
else 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); presence.Scene.CloseAgent(presence.UUID, force);
break; break;
@ -1028,15 +1042,25 @@ namespace OpenSim
cdt.AddColumn("Circuit code", 12); cdt.AddColumn("Circuit code", 12);
cdt.AddColumn("Endpoint", 23); cdt.AddColumn("Endpoint", 23);
cdt.AddColumn("Active?", 7); cdt.AddColumn("Active?", 7);
cdt.AddColumn("ChildAgent?", 7);
cdt.AddColumn("ping(ms)", 8);
SceneManager.ForEachScene( SceneManager.ForEachScene(
s => s.ForEachClient( s => s.ForEachClient(
c => cdt.AddRow( c =>
{
bool child = false;
if(c.SceneAgent != null && c.SceneAgent.IsChildAgent)
child = true;
cdt.AddRow(
s.Name, s.Name,
c.Name, c.Name,
c.CircuitCode.ToString(), c.CircuitCode.ToString(),
c.RemoteEndPoint.ToString(), c.RemoteEndPoint.ToString(),
c.IsActive.ToString()))); c.IsActive.ToString(),
child.ToString(),
c.PingTimeMS);
}));
MainConsole.Instance.Output(cdt.ToString()); MainConsole.Instance.Output(cdt.ToString());
} }

View File

@ -112,6 +112,10 @@ namespace OpenSim
public List<IApplicationPlugin> m_plugins = new List<IApplicationPlugin>(); public List<IApplicationPlugin> m_plugins = new List<IApplicationPlugin>();
private List<string> m_permsModules;
private bool m_securePermissionsLoading = true;
/// <value> /// <value>
/// The config information passed into the OpenSimulator region server. /// The config information passed into the OpenSimulator region server.
/// </value> /// </value>
@ -228,6 +232,14 @@ namespace OpenSim
CreatePIDFile(pidFile); CreatePIDFile(pidFile);
userStatsURI = startupConfig.GetString("Stats_URI", String.Empty); 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); managedStatsURI = startupConfig.GetString("ManagedStatsRemoteFetchURI", String.Empty);
} }
@ -264,11 +276,21 @@ namespace OpenSim
base.StartupSpecific(); base.StartupSpecific();
<<<<<<< HEAD
if (EnableInitialPluginLoad) if (EnableInitialPluginLoad)
LoadPlugins(); LoadPlugins();
// We still want to post initalize any plugins even if loading has been disabled since a test may have // We still want to post initalize any plugins even if loading has been disabled since a test may have
// inserted them manually. // 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) foreach (IApplicationPlugin plugin in m_plugins)
plugin.PostInitialise(); plugin.PostInitialise();
@ -290,10 +312,10 @@ namespace OpenSim
"help " + capitalizedTopic, "help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'", "Get help on plugin command '" + topic + "'",
HandleCommanderHelp); HandleCommanderHelp);
console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic, // console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
"help " + capitalizedTopic, // "help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'", // "Get help on plugin command '" + topic + "'",
HandleCommanderHelp); // HandleCommanderHelp);
ICommander commander = null; ICommander commander = null;
@ -420,7 +442,32 @@ namespace OpenSim
} }
else m_log.Error("[REGIONMODULES]: The new RegionModulesController is missing..."); 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(); 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) while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
SetUpEstateOwner(scene); SetUpEstateOwner(scene);
@ -434,6 +481,11 @@ namespace OpenSim
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID); scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
scene.EventManager.TriggerParcelPrimCountUpdate(); scene.EventManager.TriggerParcelPrimCountUpdate();
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("Grid Registration in progress", scene);
}
try try
{ {
scene.RegisterRegionWithGrid(); scene.RegisterRegionWithGrid();
@ -444,15 +496,29 @@ namespace OpenSim
"[STARTUP]: Registration of region with grid failed, aborting startup due to {0} {1}", "[STARTUP]: Registration of region with grid failed, aborting startup due to {0} {1}",
e.Message, e.StackTrace); 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 // Carrying on now causes a lot of confusion down the
// line - we need to get the user's attention // line - we need to get the user's attention
Environment.Exit(1); Environment.Exit(1);
} }
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("Grid Registration done", scene);
}
// We need to do this after we've initialized the // We need to do this after we've initialized the
// scripting engines. // scripting engines.
scene.CreateScriptInstances(); scene.CreateScriptInstances();
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("ScriptEngine started", scene);
}
SceneManager.Add(scene); SceneManager.Add(scene);
if (m_autoCreateClientStack) 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); }; scene.EventManager.OnShutdown += delegate() { ShutdownRegion(scene); };
mscene = scene; mscene = scene;
if (scene.SnmpService != null)
{
scene.SnmpService.BootInfo("The region is operational", scene);
scene.SnmpService.LinkUp(scene);
}
return clientServers; return clientServers;
} }
@ -583,6 +659,11 @@ namespace OpenSim
private void ShutdownRegion(Scene scene) private void ShutdownRegion(Scene scene)
{ {
m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName); 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; IRegionModulesController controller;
if (ApplicationRegistry.TryGet<IRegionModulesController>(out controller)) if (ApplicationRegistry.TryGet<IRegionModulesController>(out controller))
{ {
@ -751,7 +832,10 @@ namespace OpenSim
{ {
Vector3 regionExtent = new Vector3(regionInfo.RegionSizeX, regionInfo.RegionSizeY, regionInfo.RegionSizeZ); Vector3 regionExtent = new Vector3(regionInfo.RegionSizeX, regionInfo.RegionSizeY, regionInfo.RegionSizeZ);
PhysicsScene physicsScene = GetPhysicsScene(regionInfo.RegionName, regionExtent); PhysicsScene physicsScene = GetPhysicsScene(regionInfo.RegionName, regionExtent);
<<<<<<< HEAD
=======
>>>>>>> avn/ubitvar
SceneCommunicationService sceneGridService = new SceneCommunicationService(); SceneCommunicationService sceneGridService = new SceneCommunicationService();
return new Scene( return new Scene(

View File

@ -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;
}
}
}

View File

@ -78,7 +78,6 @@ namespace OpenSim.Region.ClientStack.Linden
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>(); 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>(); private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
#region INonSharedRegionModule methods #region INonSharedRegionModule methods
@ -178,6 +177,7 @@ namespace OpenSim.Region.ClientStack.Linden
} }
/// <summary> /// <summary>
<<<<<<< HEAD
/// Always returns a valid queue /// Always returns a valid queue
/// </summary> /// </summary>
/// <param name="agentId"></param> /// <param name="agentId"></param>
@ -201,6 +201,8 @@ namespace OpenSim.Region.ClientStack.Linden
} }
/// <summary> /// <summary>
=======
>>>>>>> avn/ubitvar
/// May return a null queue /// May return a null queue
/// </summary> /// </summary>
/// <param name="agentId"></param> /// <param name="agentId"></param>
@ -263,28 +265,13 @@ namespace OpenSim.Region.ClientStack.Linden
lock (queues) lock (queues)
queues.Remove(agentID); queues.Remove(agentID);
List<UUID> removeitems = new List<UUID>();
lock (m_AvatarQueueUUIDMapping) lock (m_AvatarQueueUUIDMapping)
m_AvatarQueueUUIDMapping.Remove(agentID); m_AvatarQueueUUIDMapping.Remove(agentID);
UUID searchval = UUID.Zero; lock (m_ids)
removeitems.Clear();
lock (m_QueueUUIDAvatarMapping)
{ {
foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys) if (!m_ids.ContainsKey(agentID))
{ m_ids.Remove(agentID);
searchval = m_QueueUUIDAvatarMapping[ky];
if (searchval == agentID)
{
removeitems.Add(ky);
}
}
foreach (UUID ky in removeitems)
m_QueueUUIDAvatarMapping.Remove(ky);
} }
// m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); // 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) public void OnRegisterCaps(UUID agentID, Caps caps)
{ {
// Register an event queue for the client // Register an event queue for the client
<<<<<<< HEAD
if (DebugLevel > 0) if (DebugLevel > 0)
m_log.DebugFormat( m_log.DebugFormat(
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
agentID, caps, m_scene.RegionInfo.RegionName); agentID, caps, m_scene.RegionInfo.RegionName);
=======
// Let's instantiate a Queue for this agent right now m_log.DebugFormat(
TryGetQueue(agentID); "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
agentID, caps, m_scene.RegionInfo.RegionName);
>>>>>>> avn/ubitvar
UUID eventQueueGetUUID; UUID eventQueueGetUUID;
Queue<OSD> queue;
Random rnd = new Random(Environment.TickCount);
int nrnd = rnd.Next(30000000);
if (nrnd < 0)
nrnd = -nrnd;
lock (queues)
{
if (queues.ContainsKey(agentID))
queue = queues[agentID];
else
queue = null;
if (queue == null)
{
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) lock (m_AvatarQueueUUIDMapping)
{ {
// Reuse open queues. The client does! eventQueueGetUUID = UUID.Random();
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
{ {
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); // 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
{
// 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]; eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
} }
else else
{ {
eventQueueGetUUID = UUID.Random(); eventQueueGetUUID = UUID.Random();
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
}
}
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); 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];
}
}
} }
caps.RegisterPollHandler( caps.RegisterPollHandler(
"EventQueueGet", "EventQueueGet",
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); 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) 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); Queue<OSD> queue = GetQueue(agentID);
if (queue != null) if (queue != null)
lock (queue) lock (queue)
@ -366,7 +399,8 @@ namespace OpenSim.Region.ClientStack.Linden
return queue.Count > 0; return queue.Count > 0;
} }
return false; //m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID);
return true;
} }
/// <summary> /// <summary>
@ -395,55 +429,65 @@ namespace OpenSim.Region.ClientStack.Linden
return NoEvents(requestID, pAgentId); return NoEvents(requestID, pAgentId);
} }
OSD element; OSD element = null;;
OSDArray array = new OSDArray();
int thisID = 0;
bool negativeID = false;
lock (queue) lock (queue)
{ {
if (queue.Count == 0) if (queue.Count == 0)
return NoEvents(requestID, pAgentId); return NoEvents(requestID, pAgentId);
element = queue.Dequeue(); // 15s timeout
}
int thisID = 0;
lock (m_ids) lock (m_ids)
thisID = m_ids[pAgentId]; thisID = m_ids[pAgentId];
OSDArray array = new OSDArray(); if (thisID < 0)
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! negativeID = true;
array.Add(EventQueueHelper.KeepAliveEvent()); thisID = -thisID;
//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)
{
while (queue.Count > 0) while (queue.Count > 0)
{ {
element = queue.Dequeue(); element = queue.Dequeue();
// add elements until a marker is found
// so they get into a response
if (element == null)
break;
if (DebugLevel > 0) if (DebugLevel > 0)
LogOutboundDebugMessage(element, pAgentId); LogOutboundDebugMessage(element, pAgentId);
array.Add(element); array.Add(element);
thisID++; thisID++;
} }
} }
OSDMap events = null;
if (array.Count > 0)
{
events = new OSDMap();
events.Add("events", array);
events.Add("id", new OSDInteger(thisID));
} }
OSDMap events = new OSDMap(); if (negativeID && element == null)
events.Add("events", array); {
Random rnd = new Random(Environment.TickCount);
thisID = rnd.Next(30000000);
if (thisID < 0)
thisID = -thisID;
}
events.Add("id", new OSDInteger(thisID));
lock (m_ids) lock (m_ids)
{ {
m_ids[pAgentId] = thisID + 1; 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(); Hashtable responsedata = new Hashtable();
responsedata["int_response_code"] = 200; responsedata["int_response_code"] = 200;
responsedata["content_type"] = "application/xml"; responsedata["content_type"] = "application/xml";
@ -461,260 +505,12 @@ namespace OpenSim.Region.ClientStack.Linden
responsedata["content_type"] = "text/plain"; responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false; responsedata["keepalive"] = false;
responsedata["reusecontext"] = false; responsedata["reusecontext"] = false;
responsedata["str_response_string"] = "Upstream error: "; responsedata["str_response_string"] = "<llsd></llsd>";
responsedata["error_status_text"] = "Upstream error:"; responsedata["error_status_text"] = "<llsd></llsd>";
responsedata["http_protocol_version"] = "HTTP/1.0"; responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata; 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) public void DisableSimulator(ulong handle, UUID avatarID)
{ {
OSD item = EventQueueHelper.DisableSimulator(handle); 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) public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
{ {
<<<<<<< HEAD
if (DebugLevel > 0) if (DebugLevel > 0)
m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}", m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY); 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); OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
Enqueue(item, avatarID); Enqueue(item, avatarID);
@ -734,10 +535,15 @@ namespace OpenSim.Region.ClientStack.Linden
public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath, public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
ulong regionHandle, int regionSizeX, int regionSizeY) ulong regionHandle, int regionSizeX, int regionSizeY)
{ {
<<<<<<< HEAD
if (DebugLevel > 0) if (DebugLevel > 0)
m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}", m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY); 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); OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
Enqueue(item, avatarID); Enqueue(item, avatarID);
} }
@ -747,9 +553,14 @@ namespace OpenSim.Region.ClientStack.Linden
uint locationID, uint flags, string capsURL, uint locationID, uint flags, string capsURL,
UUID avatarID, int regionSizeX, int regionSizeY) UUID avatarID, int regionSizeX, int regionSizeY)
{ {
<<<<<<< HEAD
if (DebugLevel > 0) if (DebugLevel > 0)
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}", m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY); 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, OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY); locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
@ -760,9 +571,14 @@ namespace OpenSim.Region.ClientStack.Linden
IPEndPoint newRegionExternalEndPoint, IPEndPoint newRegionExternalEndPoint,
string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY) string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
{ {
<<<<<<< HEAD
if (DebugLevel > 0) if (DebugLevel > 0)
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>", m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, handle, avatarID, regionSizeX, regionSizeY); 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, OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
capsURL, avatarID, sessionID, regionSizeX, regionSizeY); capsURL, avatarID, sessionID, regionSizeX, regionSizeY);

View File

@ -77,8 +77,13 @@ namespace OpenSim.Region.ClientStack.Linden
llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle))); llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle)));
llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes())); llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes()));
llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port)); llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port));
<<<<<<< HEAD
llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint) regionSizeX)); llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint) regionSizeX));
llsdSimInfo.Add("RegionSizeY", OSD.FromUInteger((uint) regionSizeY)); 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); OSDArray arr = new OSDArray(1);
arr.Add(llsdSimInfo); arr.Add(llsdSimInfo);
@ -157,6 +162,12 @@ namespace OpenSim.Region.ClientStack.Linden
uint locationID, uint flags, string capsURL, UUID agentID, uint locationID, uint flags, string capsURL, UUID agentID,
int regionSizeX, int regionSizeY) 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(); OSDMap info = new OSDMap();
info.Add("AgentID", OSD.FromUUID(agentID)); info.Add("AgentID", OSD.FromUUID(agentID));
info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this? 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("SimAccess", OSD.FromInteger(simAccess));
info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes())); info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes()));
info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port)); 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.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
info.Add("TeleportFlags", OSD.FromUInteger(flags));
>>>>>>> avn/ubitvar
info.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX)); info.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX));
info.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY)); info.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY));
@ -204,8 +220,8 @@ namespace OpenSim.Region.ClientStack.Linden
{"sim-ip-and-port", new OSDString(simIpAndPort)}, {"sim-ip-and-port", new OSDString(simIpAndPort)},
{"seed-capability", new OSDString(seedcap)}, {"seed-capability", new OSDString(seedcap)},
{"region-handle", OSD.FromULong(regionHandle)}, {"region-handle", OSD.FromULong(regionHandle)},
{"region-size-x", OSD.FromInteger(regionSizeX)}, {"region-size-x", OSD.FromUInteger((uint)regionSizeX)},
{"region-size-y", OSD.FromInteger(regionSizeY)} {"region-size-y", OSD.FromUInteger((uint)regionSizeY)}
}; };
return BuildEvent("EstablishAgentCommunication", body); return BuildEvent("EstablishAgentCommunication", body);

View File

@ -27,11 +27,14 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Reflection; using System.Reflection;
using System.IO; using System.IO;
using System.Threading;
using System.Web; using System.Web;
using Mono.Addins; using Mono.Addins;
using OpenSim.Framework.Monitoring;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
@ -57,12 +60,51 @@ namespace OpenSim.Region.ClientStack.Linden
private IAssetService m_AssetService; private IAssetService m_AssetService;
private bool m_Enabled = true; private bool m_Enabled = true;
private string m_URL; private string m_URL;
<<<<<<< HEAD
private string m_URL2; private string m_URL2;
private string m_RedirectURL = null; private string m_RedirectURL = null;
private string m_RedirectURL2 = 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 #region Region Module interfaceBase Members
~GetMeshModule()
{
foreach (Thread t in m_workerThreads)
Watchdog.AbortThread(t.ManagedThreadId);
}
public Type ReplaceableInterface public Type ReplaceableInterface
{ {
get { return null; } get { return null; }
@ -87,8 +129,12 @@ namespace OpenSim.Region.ClientStack.Linden
if (m_URL2 != string.Empty) if (m_URL2 != string.Empty)
{ {
m_Enabled = true; m_Enabled = true;
<<<<<<< HEAD
m_RedirectURL2 = config.GetString("GetMesh2RedirectURL"); m_RedirectURL2 = config.GetString("GetMesh2RedirectURL");
} }
=======
>>>>>>> avn/ubitvar
} }
public void AddRegion(Scene pScene) public void AddRegion(Scene pScene)
@ -97,6 +143,8 @@ namespace OpenSim.Region.ClientStack.Linden
return; return;
m_scene = pScene; m_scene = pScene;
m_assetService = pScene.AssetService;
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -105,6 +153,9 @@ namespace OpenSim.Region.ClientStack.Linden
return; return;
m_scene.EventManager.OnRegisterCaps -= RegisterCaps; m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
m_scene = null; m_scene = null;
} }
@ -115,6 +166,27 @@ namespace OpenSim.Region.ClientStack.Linden
m_AssetService = m_scene.RequestModuleInterface<IAssetService>(); m_AssetService = m_scene.RequestModuleInterface<IAssetService>();
m_scene.EventManager.OnRegisterCaps += RegisterCaps; 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 #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) public void RegisterCaps(UUID agentID, Caps caps)
{ {
<<<<<<< HEAD
UUID capID = UUID.Random(); UUID capID = UUID.Random();
bool getMeshRegistered = false; bool getMeshRegistered = false;
@ -140,6 +350,35 @@ namespace OpenSim.Region.ClientStack.Linden
caps.RegisterHandler( caps.RegisterHandler(
"GetMesh", "GetMesh",
new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh", agentID.ToString(), m_RedirectURL)); 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 else
{ {
@ -164,6 +403,177 @@ namespace OpenSim.Region.ClientStack.Linden
caps.RegisterHandler("GetMesh2", m_URL2); 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();
}
}
} }
} }

View File

@ -27,18 +27,13 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Specialized; using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection; using System.Reflection;
using System.IO; using System.Threading;
using System.Web;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using Mono.Addins; using Mono.Addins;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenMetaverse.Imaging;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
@ -47,6 +42,7 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps; using Caps = OpenSim.Framework.Capabilities.Caps;
using OpenSim.Capabilities.Handlers; using OpenSim.Capabilities.Handlers;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.ClientStack.Linden namespace OpenSim.Region.ClientStack.Linden
{ {
@ -54,16 +50,44 @@ namespace OpenSim.Region.ClientStack.Linden
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
public class GetTextureModule : INonSharedRegionModule 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 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 // TODO: Change this to a config option
private string m_RedirectURL = null; private string m_RedirectURL = null;
=======
private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
>>>>>>> avn/ubitvar
private string m_URL; private string m_URL;
@ -72,6 +96,7 @@ namespace OpenSim.Region.ClientStack.Linden
public void Initialise(IConfigSource source) public void Initialise(IConfigSource source)
{ {
IConfig config = source.Configs["ClientStack.LindenCaps"]; IConfig config = source.Configs["ClientStack.LindenCaps"];
<<<<<<< HEAD
if (config == null) if (config == null)
return; return;
@ -82,32 +107,100 @@ namespace OpenSim.Region.ClientStack.Linden
m_Enabled = true; m_Enabled = true;
m_RedirectURL = config.GetString("GetTextureRedirectURL"); m_RedirectURL = config.GetString("GetTextureRedirectURL");
} }
=======
if (config != null)
m_Url = config.GetString("Cap_GetTexture", "localhost");
>>>>>>> avn/ubitvar
} }
public void AddRegion(Scene s) public void AddRegion(Scene s)
{ {
if (!m_Enabled)
return;
m_scene = s; m_scene = s;
m_assetService = s.AssetService;
} }
public void RemoveRegion(Scene s) public void RemoveRegion(Scene s)
{ {
if (!m_Enabled)
return;
m_scene.EventManager.OnRegisterCaps -= RegisterCaps; m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
m_scene = null; m_scene = null;
} }
public void RegionLoaded(Scene s) public void RegionLoaded(Scene s)
{ {
if (!m_Enabled) // We'll reuse the same handler for all requests.
return; m_getTextureHandler = new GetTextureHandler(m_assetService);
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
m_scene.EventManager.OnRegisterCaps += RegisterCaps; 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() public void PostInitialise()
@ -125,28 +218,306 @@ namespace OpenSim.Region.ClientStack.Linden
#endregion #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); // m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
caps.RegisterHandler( caps.RegisterHandler(
"GetTexture", "GetTexture",
new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString(), m_RedirectURL)); new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString(), m_RedirectURL));
} =======
else m_scene = scene;
// x is request id, y is userid
HasEvents = (x, y) =>
{ {
// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); lock (responses)
IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>(); {
if (handler != null) bool ret = m_throttler.hasEvents(x, responses);
handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture", m_URL); m_throttler.ProcessTime();
else return ret;
caps.RegisterHandler("GetTexture", m_URL);
}
};
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
}
public void Process(aPollRequest requestinfo)
{
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;
}
}
} }

View File

@ -129,15 +129,15 @@ namespace OpenSim.Region.ClientStack.Linden
// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request"); // m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request");
OSDMap data = new OSDMap(); OSDMap data = new OSDMap();
ScenePresence sp = m_scene.GetScenePresence(agentID); // ScenePresence sp = m_scene.GetScenePresence(m_agentID);
data["username"] = sp.Firstname + "." + sp.Lastname; // data["username"] = sp.Firstname + "." + sp.Lastname;
data["display_name_next_update"] = new OSDDate(DateTime.Now); // data["display_name_next_update"] = new OSDDate(DateTime.Now);
data["legacy_first_name"] = sp.Firstname; // data["legacy_first_name"] = sp.Firstname;
data["mesh_upload_status"] = "valid"; data["mesh_upload_status"] = "valid";
data["display_name"] = sp.Firstname + " " + sp.Lastname; // data["display_name"] = sp.Firstname + " " + sp.Lastname;
data["legacy_last_name"] = sp.Lastname; // data["legacy_last_name"] = sp.Lastname;
data["id"] = agentID; // data["id"] = m_agentID;
data["is_display_name_default"] = true; // data["is_display_name_default"] = true;
//Send back data //Send back data
Hashtable responsedata = new Hashtable(); Hashtable responsedata = new Hashtable();

View File

@ -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