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
.settings
.gitignore
*.csproj
*.csproj.user
*.build
@ -10,6 +11,7 @@
*.pidb
*.dll.build
*.dll
*.log
# Ignore .user and .suo files as these are user preference specific
# http://stackoverflow.com/questions/72298/should-i-add-the-visual-studio-suo-and-user-files-to-source-control
@ -29,6 +31,7 @@
*/*/*/*/*/bin
*/*/*/*/*/*/bin
*/*/*/*/*/*/*/bin
addon-modules/
bin/Debug/*.dll
bin/*.dll.mdb
bin/*.db

View File

@ -75,6 +75,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
private string m_name = "RemoteAdminPlugin";
private string m_version = "0.0";
private string m_openSimVersion;
public string Version
{
@ -94,6 +95,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
public void Initialise(OpenSimBase openSim)
{
m_openSimVersion = openSim.GetVersionText();
m_configSource = openSim.ConfigSource.Source;
try
{
@ -136,6 +139,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod);
availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod);
availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod);
availableMethods["admin_dialog"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDialogMethod);
availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod);
availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod);
availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod);
@ -164,8 +168,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
// Land management
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
// Misc
availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch);
availableMethods["admin_refresh_map"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshMap);
availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion);
availableMethods["admin_get_agent_count"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentCount);
// Either enable full remote functionality or just selected features
string enabledMethods = m_config.GetString("enabled_methods", "all");
@ -266,25 +273,105 @@ namespace OpenSim.ApplicationPlugins.RemoteController
try
{
m_log.Info("[RADMIN]: Request to restart Region.");
CheckRegionParams(requestData, responseData);
Scene rebootedScene = null;
GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
bool restartAll = false;
IConfig startupConfig = m_configSource.Configs["Startup"];
if (startupConfig != null)
{
if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
{
rebootedScene = m_application.SceneManager.CurrentOrFirstScene;
restartAll = true;
}
}
if (rebootedScene == null)
{
CheckRegionParams(requestData, responseData);
GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
}
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
responseData["success"] = false;
responseData["accepted"] = true;
responseData["rebooting"] = true;
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
if (restartModule != null)
{
List<int> times = new List<int> { 30, 15 };
string message;
List<int> times = new List<int>();
restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
responseData["success"] = true;
if (requestData.ContainsKey("alerts"))
{
string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','});
if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1)
{
m_log.Info("[RADMIN]: Request to cancel restart.");
if (restartModule != null)
{
message = "Restart has been cancelled";
if (requestData.ContainsKey("message"))
message = requestData["message"].ToString();
restartModule.AbortRestart(message);
responseData["success"] = true;
responseData["rebooting"] = false;
return;
}
}
foreach (string a in alertTimes)
times.Add(Convert.ToInt32(a));
}
else
{
int timeout = 30;
if (requestData.ContainsKey("milliseconds"))
timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000;
while (timeout > 0)
{
times.Add(timeout);
if (timeout > 300)
timeout -= 120;
else if (timeout > 30)
timeout -= 30;
else
timeout -= 15;
}
}
m_log.Info("[RADMIN]: Request to restart Region.");
message = "Region is restarting in {0}. Please save what you are doing and log out.";
if (requestData.ContainsKey("message"))
message = requestData["message"].ToString();
bool notice = true;
if (requestData.ContainsKey("noticetype")
&& ((string)requestData["noticetype"] == "dialog"))
{
notice = false;
}
List<Scene> restartList;
if (restartAll)
restartList = m_application.SceneManager.Scenes;
else
restartList = new List<Scene>() { rebootedScene };
foreach (Scene s in m_application.SceneManager.Scenes)
{
restartModule = s.RequestModuleInterface<IRestartModule>();
if (restartModule != null)
restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice);
}
responseData["success"] = true;
}
catch (Exception e)
{
@ -321,6 +408,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
m_log.Info("[RADMIN]: Alert request complete");
}
public void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
Hashtable responseData = (Hashtable)response.Value;
m_log.Info("[RADMIN]: Dialog request started");
Hashtable requestData = (Hashtable)request.Params[0];
string message = (string)requestData["message"];
string fromuuid = (string)requestData["from"];
m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
responseData["accepted"] = true;
responseData["success"] = true;
m_application.SceneManager.ForEachScene(
delegate(Scene scene)
{
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
if (dialogModule != null)
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
});
m_log.Info("[RADMIN]: Dialog request complete");
}
private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
m_log.Info("[RADMIN]: Load height maps request started");
@ -424,13 +537,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
message = "Region is going down now.";
}
m_application.SceneManager.ForEachScene(
if (requestData.ContainsKey("noticetype")
&& ((string) requestData["noticetype"] == "dialog"))
{
m_application.SceneManager.ForEachScene(
delegate(Scene scene)
{
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
if (dialogModule != null)
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
});
}
else
{
if (!requestData.ContainsKey("noticetype")
|| ((string)requestData["noticetype"] != "none"))
{
m_application.SceneManager.ForEachScene(
delegate(Scene scene)
{
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
if (dialogModule != null)
dialogModule.SendGeneralAlert(message);
});
}
}
// Perform shutdown
System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
@ -1489,7 +1621,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
}
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
Dictionary<string, object> archiveOptions = new Dictionary<string,object>();
Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
if (mergeOar) archiveOptions.Add("merge", null);
if (skipAssets) archiveOptions.Add("skipAssets", null);
if (archiver != null)
@ -1749,21 +1881,31 @@ namespace OpenSim.ApplicationPlugins.RemoteController
private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
m_log.Info("[RADMIN]: Received Query XML Administrator Request");
Hashtable responseData = (Hashtable)response.Value;
Hashtable requestData = (Hashtable)request.Params[0];
int flags = 0;
string text = String.Empty;
int health = 0;
responseData["success"] = true;
CheckRegionParams(requestData, responseData);
Scene scene = null;
GetSceneFromRegionParams(requestData, responseData, out scene);
int health = scene.GetHealth();
responseData["health"] = health;
try
{
GetSceneFromRegionParams(requestData, responseData, out scene);
health = scene.GetHealth(out flags, out text);
}
catch (Exception e)
{
responseData["error"] = null;
}
responseData["success"] = true;
m_log.Info("[RADMIN]: Query XML Administrator Request complete");
responseData["health"] = health;
responseData["flags"] = flags;
responseData["message"] = text;
}
private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
@ -2068,55 +2210,97 @@ namespace OpenSim.ApplicationPlugins.RemoteController
responseData["success"] = true;
}
private void XmlRpcResetLand(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
Hashtable requestData = (Hashtable)request.Params[0];
m_log.Info("[RADMIN]: Received Refresh Search Request");
Hashtable responseData = (Hashtable)response.Value;
Hashtable requestData = (Hashtable)request.Params[0];
string musicURL = string.Empty;
UUID groupID = UUID.Zero;
uint flags = 0;
bool set_group = false, set_music = false, set_flags = false;
CheckRegionParams(requestData, responseData);
if (requestData.Contains("group") && requestData["group"] != null)
set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
if (requestData.Contains("music") && requestData["music"] != null)
Scene scene = null;
GetSceneFromRegionParams(requestData, responseData, out scene);
ISearchModule searchModule = scene.RequestModuleInterface<ISearchModule>();
if (searchModule != null)
{
musicURL = requestData["music"].ToString();
set_music = true;
searchModule.Refresh();
responseData["success"] = true;
}
if (requestData.Contains("flags") && requestData["flags"] != null)
set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags);
m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}",
(set_group ? groupID.ToString() : "unchanged"),
(set_music ? musicURL : "unchanged"),
(set_flags ? flags.ToString() : "unchanged"));
m_application.SceneManager.ForEachScene(delegate(Scene s)
else
{
List<ILandObject> parcels = s.LandChannel.AllParcels();
foreach (ILandObject p in parcels)
{
if (set_music)
p.LandData.MusicURL = musicURL;
if (set_group)
p.LandData.GroupID = groupID;
if (set_flags)
p.LandData.Flags = flags;
s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData);
}
responseData["success"] = false;
}
);
responseData["success"] = true;
m_log.Info("[RADMIN]: Reset Land Request complete");
m_log.Info("[RADMIN]: Refresh Search Request complete");
}
private void XmlRpcRefreshMap(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
m_log.Info("[RADMIN]: Received Refresh Map Request");
Hashtable responseData = (Hashtable)response.Value;
Hashtable requestData = (Hashtable)request.Params[0];
CheckRegionParams(requestData, responseData);
Scene scene = null;
GetSceneFromRegionParams(requestData, responseData, out scene);
IMapImageUploadModule mapTileModule = scene.RequestModuleInterface<IMapImageUploadModule>();
if (mapTileModule != null)
{
Util.FireAndForget((x) =>
{
mapTileModule.UploadMapTile(scene);
});
responseData["success"] = true;
}
else
{
responseData["success"] = false;
}
m_log.Info("[RADMIN]: Refresh Map Request complete");
}
private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
m_log.Info("[RADMIN]: Received Get OpenSim Version Request");
Hashtable responseData = (Hashtable)response.Value;
responseData["version"] = m_openSimVersion;
responseData["success"] = true;
m_log.Info("[RADMIN]: Get OpenSim Version Request complete");
}
private void XmlRpcGetAgentCount(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
{
m_log.Info("[RADMIN]: Received Get Agent Count Request");
Hashtable responseData = (Hashtable)response.Value;
Hashtable requestData = (Hashtable)request.Params[0];
CheckRegionParams(requestData, responseData);
Scene scene = null;
GetSceneFromRegionParams(requestData, responseData, out scene);
if (scene == null)
{
responseData["success"] = false;
}
else
{
responseData["count"] = scene.GetRootAgentCount();
responseData["success"] = true;
}
m_log.Info("[RADMIN]: Get Agent Count Request complete");
}
/// <summary>
/// Parse a float with the given parameter name from a request data hash table.
@ -2823,7 +3007,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
/// </summary>
private void ApplyNextOwnerPermissions(InventoryItemBase item)
{
if (item.InvType == (int)InventoryType.Object)
if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
{
uint perms = item.CurrentPermissions;
PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms);

View File

@ -30,6 +30,7 @@ using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using log4net;
using Nini.Config;
using OpenMetaverse;
@ -71,6 +72,7 @@ namespace OpenSim.Framework.Capabilities
private IHttpServer m_httpListener;
private UUID m_agentID;
private string m_regionName;
private ManualResetEvent m_capsActive = new ManualResetEvent(false);
public UUID AgentID
{
@ -136,6 +138,7 @@ namespace OpenSim.Framework.Capabilities
m_agentID = agent;
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
m_regionName = regionName;
m_capsActive.Reset();
}
/// <summary>
@ -255,5 +258,16 @@ namespace OpenSim.Framework.Capabilities
return caps;
}
public void Activate()
{
m_capsActive.Set();
}
public bool WaitForActivation()
{
// Wait for 30s. If that elapses, return false and run without caps
return m_capsActive.WaitOne(120000);
}
}
}

View File

@ -90,6 +90,7 @@ namespace OpenSim.Framework.Capabilities
lock (m_capsHandlers)
{
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName);
}

View File

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

View File

@ -44,26 +44,64 @@ namespace OpenSim.Capabilities.Handlers
public class GetMeshHandler : BaseStreamHandler
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IAssetService m_assetService;
// TODO: Change this to a config option
private string m_RedirectURL = null;
public const string DefaultFormat = "vnd.ll.mesh";
public GetMeshHandler(string path, IAssetService assService, string name, string description, string redirectURL)
: base("GET", path, name, description)
public GetMeshHandler(IAssetService assService)
{
m_assetService = assService;
m_RedirectURL = redirectURL;
if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
m_RedirectURL += "/";
}
public Hashtable Handle(Hashtable request)
{
Hashtable ret = new Hashtable();
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
ret["content_type"] = "text/plain";
ret["keepalive"] = false;
ret["reusecontext"] = false;
ret["int_bytes"] = 0;
ret["int_lod"] = 0;
string MeshStr = (string)request["mesh_id"];
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
//m_log.DebugFormat("[GETMESH]: called {0}", MeshStr);
if (m_assetService == null)
{
m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service");
}
UUID meshID;
if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID))
{
// m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID);
ret = ProcessGetMesh(request, UUID.Zero, null);
}
else
{
m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]);
}
return ret;
}
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
{
// Try to parse the texture ID from the request URL
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string textureStr = query.GetOne("mesh_id");
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 0;
responsedata["int_bytes"] = 0;
if (m_assetService == null)
{
@ -160,40 +198,121 @@ namespace OpenSim.Capabilities.Handlers
// sending back the last byte instead of an error status
if (start >= texture.Data.Length)
{
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response.ContentType = texture.Metadata.ContentType;
}
else
{
// Handle the case where no second range value was given. This is equivalent to requesting
// the rest of the entity.
if (end == -1)
end = int.MaxValue;
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
start = Utils.Clamp(start, 0, end);
int len = end - start + 1;
Hashtable headers = new Hashtable();
responsedata["headers"] = headers;
if (0 == start && len == texture.Data.Length)
string range = String.Empty;
if (((Hashtable)request["headers"])["range"] != null)
range = (string)((Hashtable)request["headers"])["range"];
else if (((Hashtable)request["headers"])["Range"] != null)
range = (string)((Hashtable)request["headers"])["Range"];
if (!String.IsNullOrEmpty(range)) // Mesh Asset LOD // Physics
{
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
// Range request
int start, end;
if (TryParseRange(range, out start, out end))
{
// Before clamping start make sure we can satisfy it in order to avoid
// sending back the last byte instead of an error status
if (start >= mesh.Data.Length)
{
responsedata["int_response_code"] = 404; //501; //410; //404;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "This range doesnt exist.";
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
return responsedata;
}
else
{
end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
start = Utils.Clamp(start, 0, end);
int len = end - start + 1;
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
if (start > 20000)
{
responsedata["int_lod"] = 3;
}
else if (start < 4097)
{
responsedata["int_lod"] = 1;
}
else
{
responsedata["int_lod"] = 2;
}
if (start == 0 && len == mesh.Data.Length) // well redudante maybe
{
responsedata["int_response_code"] = (int) System.Net.HttpStatusCode.OK;
responsedata["bin_response_data"] = mesh.Data;
responsedata["int_bytes"] = mesh.Data.Length;
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
}
else
{
responsedata["int_response_code"] =
(int) System.Net.HttpStatusCode.PartialContent;
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end,
mesh.Data.Length);
byte[] d = new byte[len];
Array.Copy(mesh.Data, start, d, 0, len);
responsedata["bin_response_data"] = d;
responsedata["int_bytes"] = len;
responsedata["reusecontext"] = false;
}
}
}
else
{
m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
responsedata["content_type"] = "application/vnd.ll.mesh";
responsedata["int_response_code"] = 200;
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
}
}
else
{
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
responsedata["content_type"] = "application/vnd.ll.mesh";
responsedata["int_response_code"] = 200;
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 3;
}
response.ContentLength = len;
response.ContentType = "application/vnd.ll.mesh";
response.Body.Write(texture.Data, start, len);
}
else
{
responsedata["int_response_code"] = 404; //501; //410; //404;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 1;
return responsedata;
}
}
else
{
m_log.Warn("[GETMESH]: Malformed Range header: " + range);
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
responsedata["int_response_code"] = 404; //501; //410; //404;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
responsedata["reusecontext"] = false;
responsedata["int_lod"] = 0;
return responsedata;
}
}
else
@ -246,6 +365,21 @@ namespace OpenSim.Capabilities.Handlers
}
}
start = end = 0;
return false;
}
private bool TryParseRange(string header, out int start, out int end)
{
if (header.StartsWith("bytes="))
{
string[] rangeValues = header.Substring(6).Split('-');
if (rangeValues.Length == 2)
{
if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end))
return true;
}
}
start = end = 0;
return false;
}

View File

@ -47,10 +47,11 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Capabilities.Handlers
{
public class GetTextureHandler : BaseStreamHandler
public class GetTextureHandler
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IAssetService m_assetService;
public const string DefaultFormat = "x-j2c";
@ -58,8 +59,8 @@ namespace OpenSim.Capabilities.Handlers
// TODO: Change this to a config option
private string m_RedirectURL = null;
public GetTextureHandler(string path, IAssetService assService, string name, string description, string redirectURL)
: base("GET", path, name, description)
public GetTextureHandler(IAssetService assService)
{
m_assetService = assService;
m_RedirectURL = redirectURL;
@ -67,19 +68,22 @@ namespace OpenSim.Capabilities.Handlers
m_RedirectURL += "/";
}
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
public Hashtable Handle(Hashtable request)
{
// Try to parse the texture ID from the request URL
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string textureStr = query.GetOne("texture_id");
string format = query.GetOne("format");
Hashtable ret = new Hashtable();
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
ret["content_type"] = "text/plain";
ret["keepalive"] = false;
ret["reusecontext"] = false;
ret["int_bytes"] = 0;
string textureStr = (string)request["texture_id"];
string format = (string)request["format"];
//m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
if (m_assetService == null)
{
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
}
UUID textureID;
@ -94,30 +98,41 @@ namespace OpenSim.Capabilities.Handlers
}
else
{
formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
formats = new string[1] { DefaultFormat }; // default
if (((Hashtable)request["headers"])["Accept"] != null)
formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
if (formats.Length == 0)
formats = new string[1] { DefaultFormat }; // default
}
// OK, we have an array with preferred formats, possibly with only one entry
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
bool foundtexture = false;
foreach (string f in formats)
{
if (FetchTexture(httpRequest, httpResponse, textureID, f))
foundtexture = FetchTexture(request, ret, textureID, f);
if (foundtexture)
break;
}
if (!foundtexture)
{
ret["int_response_code"] = 404;
ret["error_status_text"] = "not found";
ret["str_response_string"] = "not found";
ret["content_type"] = "text/plain";
ret["keepalive"] = false;
ret["reusecontext"] = false;
ret["int_bytes"] = 0;
}
}
else
{
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]);
}
// m_log.DebugFormat(
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
return null;
return ret;
}
/// <summary>
@ -128,7 +143,7 @@ namespace OpenSim.Capabilities.Handlers
/// <param name="textureID"></param>
/// <param name="format"></param>
/// <returns>False for "caller try another codec"; true otherwise</returns>
private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
private bool FetchTexture(Hashtable request, Hashtable response, UUID textureID, string format)
{
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
AssetBase texture;
@ -137,86 +152,70 @@ namespace OpenSim.Capabilities.Handlers
if (format != DefaultFormat)
fullID = fullID + "-" + format;
if (!String.IsNullOrEmpty(m_RedirectURL))
// try the cache
texture = m_assetService.GetCached(fullID);
if (texture == null)
{
// Only try to fetch locally cached textures. Misses are redirected
texture = m_assetService.GetCached(fullID);
//m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
// Fetch locally or remotely. Misses return a 404
texture = m_assetService.Get(textureID.ToString());
if (texture != null)
{
if (texture.Type != (sbyte)AssetType.Texture)
return true;
if (format == DefaultFormat)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
WriteTextureData(request, response, texture, format);
return true;
}
WriteTextureData(httpRequest, httpResponse, texture, format);
}
else
{
string textureUrl = m_RedirectURL + "?texture_id="+ textureID.ToString();
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently;
httpResponse.RedirectLocation = textureUrl;
return true;
}
}
else // no redirect
{
// try the cache
texture = m_assetService.GetCached(fullID);
if (texture == null)
{
// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
// Fetch locally or remotely. Misses return a 404
texture = m_assetService.Get(textureID.ToString());
if (texture != null)
else
{
if (texture.Type != (sbyte)AssetType.Texture)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true;
}
if (format == DefaultFormat)
{
WriteTextureData(httpRequest, httpResponse, texture, format);
return true;
}
else
{
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
newTexture.Data = ConvertTextureData(texture, format);
if (newTexture.Data.Length == 0)
return false; // !!! Caller try another codec, please!
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
newTexture.Data = ConvertTextureData(texture, format);
if (newTexture.Data.Length == 0)
return false; // !!! Caller try another codec, please!
newTexture.Flags = AssetFlags.Collectable;
newTexture.Temporary = true;
newTexture.Local = true;
m_assetService.Store(newTexture);
WriteTextureData(httpRequest, httpResponse, newTexture, format);
return true;
}
newTexture.Flags = AssetFlags.Collectable;
newTexture.Temporary = true;
newTexture.Local = true;
m_assetService.Store(newTexture);
WriteTextureData(request, response, newTexture, format);
return true;
}
}
else // it was on the cache
{
// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
WriteTextureData(httpRequest, httpResponse, texture, format);
return true;
}
}
}
}
else // it was on the cache
{
//m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
WriteTextureData(request, response, texture, format);
return true;
}
//response = new Hashtable();
//WriteTextureData(request,response,null,format);
// not found
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return true;
//m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
return false;
}
private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
{
string range = request.Headers.GetOne("Range");
Hashtable headers = new Hashtable();
response["headers"] = headers;
string range = String.Empty;
if (((Hashtable)request["headers"])["range"] != null)
range = (string)((Hashtable)request["headers"])["range"];
else if (((Hashtable)request["headers"])["Range"] != null)
range = (string)((Hashtable)request["headers"])["Range"];
if (!String.IsNullOrEmpty(range)) // JP2's only
{
@ -244,10 +243,8 @@ namespace OpenSim.Capabilities.Handlers
// However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response.ContentType = texture.Metadata.ContentType;
// viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
}
else
{
@ -262,41 +259,46 @@ namespace OpenSim.Capabilities.Handlers
// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
// Always return PartialContent, even if the range covered the entire data length
// We were accidentally sending back 404 before in this situation
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
//
// We also do not want to send back OK even if the whole range was satisfiable since this causes
// HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
// if (end > maxEnd)
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
// else
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
response["content-type"] = texture.Metadata.ContentType;
response.ContentLength = len;
response.ContentType = texture.Metadata.ContentType;
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
if (start == 0 && len == texture.Data.Length) // well redudante maybe
{
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
response["bin_response_data"] = texture.Data;
response["int_bytes"] = texture.Data.Length;
}
else
{
response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
response.Body.Write(texture.Data, start, len);
byte[] d = new byte[len];
Array.Copy(texture.Data, start, d, 0, len);
response["bin_response_data"] = d;
response["int_bytes"] = len;
}
// response.Body.Write(texture.Data, start, len);
}
}
else
{
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
}
}
else // JP2's or other formats
{
// Full content request
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
response.ContentLength = texture.Data.Length;
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
if (format == DefaultFormat)
response.ContentType = texture.Metadata.ContentType;
response["content_type"] = texture.Metadata.ContentType;
else
response.ContentType = "image/" + format;
response.Body.Write(texture.Data, 0, texture.Data.Length);
response["content_type"] = "image/" + format;
response["bin_response_data"] = texture.Data;
response["int_bytes"] = texture.Data.Length;
// response.Body.Write(texture.Data, 0, texture.Data.Length);
}
// if (response.StatusCode < 200 || response.StatusCode > 299)

View File

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

View File

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

View File

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

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
{
[LLSDType("MAP")]
public class LLSDAssetUploadComplete
{
public string new_asset = String.Empty;
public UUID new_inventory_item = UUID.Zero;
// public UUID new_texture_folder_id = UUID.Zero;
public string state = String.Empty;
public LLSDAssetUploadError error = null;
//public bool success = false;
public LLSDAssetUploadComplete()

View File

@ -30,15 +30,28 @@ using OpenMetaverse;
namespace OpenSim.Framework.Capabilities
{
[OSDMap]
public class LLSDAssetResource
{
public OSDArray instance_list = new OSDArray();
public OSDArray texture_list = new OSDArray();
public OSDArray mesh_list = new OSDArray();
public string metric = String.Empty;
}
[OSDMap]
public class LLSDAssetUploadRequest
{
public string asset_type = String.Empty;
public string description = String.Empty;
public UUID folder_id = UUID.Zero;
public UUID texture_folder_id = UUID.Zero;
public int next_owner_mask = 0;
public int group_mask = 0;
public int everyone_mask = 0;
public string inventory_type = String.Empty;
public string name = String.Empty;
public LLSDAssetResource asset_resources = new LLSDAssetResource();
public LLSDAssetUploadRequest()
{
}

View File

@ -26,20 +26,51 @@
*/
using System;
using OpenMetaverse;
namespace OpenSim.Framework.Capabilities
{
[OSDMap]
public class LLSDAssetUploadError
{
public string message = String.Empty;
public UUID identifier = UUID.Zero;
}
[OSDMap]
public class LLSDAssetUploadResponsePricebrkDown
{
public int mesh_streaming;
public int mesh_physics;
public int mesh_instance;
public int texture;
public int model;
}
[OSDMap]
public class LLSDAssetUploadResponseData
{
public double resource_cost;
public double model_streaming_cost;
public double simulation_cost;
public double physics_cost;
public LLSDAssetUploadResponsePricebrkDown upload_price_breakdown = new LLSDAssetUploadResponsePricebrkDown();
}
[OSDMap]
public class LLSDAssetUploadResponse
{
public string uploader = String.Empty;
public string state = String.Empty;
public int upload_price = 0;
public LLSDAssetUploadResponseData data = null;
public LLSDAssetUploadError error = null;
public LLSDAssetUploadResponse()
{
}
}
[OSDMap]
public class LLSDNewFileAngentInventoryVariablePriceReplyResponse
{

View File

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

View File

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

View File

@ -48,8 +48,6 @@ namespace OpenSim.Data
bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result);
bool UpdateUserPreferences(ref UserPreferences pref, ref string result);
bool GetUserPreferences(ref UserPreferences pref, ref string result);
bool GetUserAppData(ref UserAppData props, ref string result);
bool SetUserAppData(UserAppData props, ref string result);
OSDArray GetUserImageAssets(UUID avatarId);

View File

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

View File

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

View File

@ -154,7 +154,7 @@ namespace OpenSim.Data.MySQL
/// </summary>
/// <param name="asset">Asset UUID to create</param>
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
override public void StoreAsset(AssetBase asset)
override public bool StoreAsset(AssetBase asset)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
@ -203,6 +203,43 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
}
string assetDescription = asset.Description;
if (asset.Description.Length > 64)
{
assetDescription = asset.Description.Substring(0, 64);
m_log.WarnFormat(
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
}
try
{
using (cmd)
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?name", assetName);
cmd.Parameters.AddWithValue("?description", assetDescription);
cmd.Parameters.AddWithValue("?assetType", asset.Type);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?create_time", now);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
return true;
}
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
return false;
}
}
catch (Exception e)
{

View File

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

View File

@ -175,6 +175,11 @@ namespace OpenSim.Data.MySQL
int v = Convert.ToInt32(reader[name]);
m_Fields[name].SetValue(row, v);
}
else if (m_Fields[name].FieldType == typeof(uint))
{
uint v = Convert.ToUInt32(reader[name]);
m_Fields[name].SetValue(row, v);
}
else
{
m_Fields[name].SetValue(row, reader[name]);

View File

@ -82,6 +82,7 @@ namespace OpenSim.Data.MySQL
public RegionData Get(int posX, int posY, UUID scopeID)
{
/* fixed size regions
string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY";
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
@ -98,6 +99,45 @@ namespace OpenSim.Data.MySQL
return ret[0];
}
*/
// extend database search for maximum region size area
string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
int startX = posX - (int)Constants.MaximumRegionSize;
int startY = posY - (int)Constants.MaximumRegionSize;
int endX = posX;
int endY = posY;
List<RegionData> ret;
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?startX", startX.ToString());
cmd.Parameters.AddWithValue("?startY", startY.ToString());
cmd.Parameters.AddWithValue("?endX", endX.ToString());
cmd.Parameters.AddWithValue("?endY", endY.ToString());
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
ret = RunCommand(cmd);
}
if (ret.Count == 0)
return null;
// find the first that contains pos
RegionData rg = null;
foreach (RegionData r in ret)
{
if (posX >= r.posX && posX < r.posX + r.sizeX
&& posY >= r.posY && posY < r.posY + r.sizeY)
{
rg = r;
break;
}
}
return rg;
}
public RegionData Get(UUID regionID, UUID scopeID)
@ -121,6 +161,7 @@ namespace OpenSim.Data.MySQL
public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
{
/* fix size regions
string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY";
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
@ -135,6 +176,38 @@ namespace OpenSim.Data.MySQL
return RunCommand(cmd);
}
*/
string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
if (scopeID != UUID.Zero)
command += " and ScopeID = ?scopeID";
int qstartX = startX - (int)Constants.MaximumRegionSize;
int qstartY = startY - (int)Constants.MaximumRegionSize;
List<RegionData> dbret;
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?startX", qstartX.ToString());
cmd.Parameters.AddWithValue("?startY", qstartY.ToString());
cmd.Parameters.AddWithValue("?endX", endX.ToString());
cmd.Parameters.AddWithValue("?endY", endY.ToString());
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
dbret = RunCommand(cmd);
}
List<RegionData> ret = new List<RegionData>();
if (dbret.Count == 0)
return ret;
foreach (RegionData r in dbret)
{
if (r.posX + r.sizeX > startX && r.posX <= endX
&& r.posY + r.sizeX > startY && r.posY <= endY)
ret.Add(r);
}
return ret;
}
public List<RegionData> RunCommand(MySqlCommand cmd)

View File

@ -76,7 +76,7 @@ namespace OpenSim.Data.MySQL
Initialise(connectionString);
}
public void Initialise(string connectionString)
public virtual void Initialise(string connectionString)
{
m_connectionString = connectionString;
@ -123,7 +123,7 @@ namespace OpenSim.Data.MySQL
public void Dispose() {}
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
public virtual void StoreObject(SceneObjectGroup obj, UUID regionUUID)
{
uint flags = obj.RootPart.GetEffectiveObjectFlags();
@ -183,10 +183,11 @@ namespace OpenSim.Data.MySQL
"ParticleSystem, ClickAction, Material, " +
"CollisionSound, CollisionSoundVolume, " +
"PassTouches, " +
"LinkNumber, MediaURL, AttachedPosX, " +
"AttachedPosY, AttachedPosZ, KeyframeMotion, " +
"PassCollisions, " +
"LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " +
"AttachedPosY, AttachedPosZ, " +
"PhysicsShapeType, Density, GravityModifier, " +
"Friction, Restitution, DynAttrs " +
"Friction, Restitution, Vehicle, DynAttrs " +
") values (" + "?UUID, " +
"?CreationDate, ?Name, ?Text, " +
"?Description, ?SitName, ?TouchName, " +
@ -218,11 +219,11 @@ namespace OpenSim.Data.MySQL
"?SaleType, ?ColorR, ?ColorG, " +
"?ColorB, ?ColorA, ?ParticleSystem, " +
"?ClickAction, ?Material, ?CollisionSound, " +
"?CollisionSoundVolume, ?PassTouches, " +
"?LinkNumber, ?MediaURL, ?AttachedPosX, " +
"?AttachedPosY, ?AttachedPosZ, ?KeyframeMotion, " +
"?CollisionSoundVolume, ?PassTouches, ?PassCollisions, " +
"?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " +
"?AttachedPosY, ?AttachedPosZ, " +
"?PhysicsShapeType, ?Density, ?GravityModifier, " +
"?Friction, ?Restitution, ?DynAttrs)";
"?Friction, ?Restitution, ?Vehicle, ?DynAttrs)";
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
@ -262,7 +263,7 @@ namespace OpenSim.Data.MySQL
}
}
public void RemoveObject(UUID obj, UUID regionUUID)
public virtual void RemoveObject(UUID obj, UUID regionUUID)
{
// m_log.DebugFormat("[REGION DB]: Deleting scene object {0} from {1} in database", obj, regionUUID);
@ -317,7 +318,8 @@ namespace OpenSim.Data.MySQL
/// <param name="uuid">the Item UUID</param>
private void RemoveItems(UUID uuid)
{
lock (m_dbLock)
// locked by caller
// lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
@ -411,7 +413,7 @@ namespace OpenSim.Data.MySQL
}
}
public List<SceneObjectGroup> LoadObjects(UUID regionID)
public virtual List<SceneObjectGroup> LoadObjects(UUID regionID)
{
const int ROWS_PER_QUERY = 5000;
@ -590,40 +592,53 @@ namespace OpenSim.Data.MySQL
public void StoreTerrain(TerrainData terrData, UUID regionID)
{
lock (m_dbLock)
Util.FireAndForget(delegate(object x)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
m_log.Info("[REGION DB]: Storing terrain");
lock (m_dbLock)
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID";
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
dbcon.Open();
ExecuteNonQuery(cmd);
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from terrain where RegionUUID = ?RegionUUID";
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
int terrainDBRevision;
Array terrainDBblob;
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
using (MySqlCommand cmd2 = dbcon.CreateCommand())
{
try
{
cmd2.CommandText = "insert into terrain (RegionUUID, " +
"Revision, Heightfield) values (?RegionUUID, " +
"?Revision, ?Heightfield)";
m_log.InfoFormat("{0} Storing terrain. X={1}, Y={2}, rev={3}",
LogHeader, terrData.SizeX, terrData.SizeY, terrainDBRevision);
int terrainDBRevision;
Array terrainDBblob;
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
cmd.CommandText = "insert into terrain (RegionUUID, Revision, Heightfield)"
+ "values (?RegionUUID, ?Revision, ?Heightfield)";
cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString());
cmd2.Parameters.AddWithValue("Revision", terrainDBRevision);
cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob);
cmd.Parameters.AddWithValue("Revision", terrainDBRevision);
cmd.Parameters.AddWithValue("Heightfield", terrainDBblob);
ExecuteNonQuery(cmd);
ExecuteNonQuery(cmd);
ExecuteNonQuery(cmd2);
}
catch (Exception e)
{
m_log.ErrorFormat(e.ToString());
}
}
}
}
}
}
});
}
// Legacy region loading
public double[,] LoadTerrain(UUID regionID)
public virtual double[,] LoadTerrain(UUID regionID)
{
double[,] ret = null;
TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
@ -655,8 +670,11 @@ namespace OpenSim.Data.MySQL
while (reader.Read())
{
int rev = Convert.ToInt32(reader["Revision"]);
byte[] blob = (byte[])reader["Heightfield"];
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
if ((reader["Heightfield"] != DBNull.Value))
{
byte[] blob = (byte[])reader["Heightfield"];
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
}
}
}
}
@ -666,7 +684,7 @@ namespace OpenSim.Data.MySQL
return terrData;
}
public void RemoveLandObject(UUID globalID)
public virtual void RemoveLandObject(UUID globalID)
{
lock (m_dbLock)
{
@ -685,7 +703,7 @@ namespace OpenSim.Data.MySQL
}
}
public void StoreLandObject(ILandObject parcel)
public virtual void StoreLandObject(ILandObject parcel)
{
lock (m_dbLock)
{
@ -705,7 +723,8 @@ namespace OpenSim.Data.MySQL
"UserLocationX, UserLocationY, UserLocationZ, " +
"UserLookAtX, UserLookAtY, UserLookAtZ, " +
"AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " +
"MediaSize, MediaLoop, ObscureMusic, ObscureMedia) values (" +
"MediaSize, MediaLoop, ObscureMusic, ObscureMedia, " +
"SeeAVs, AnyAVSounds, GroupAVSounds) values (" +
"?UUID, ?RegionUUID, " +
"?LocalLandID, ?Bitmap, ?Name, ?Description, " +
"?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " +
@ -716,7 +735,8 @@ namespace OpenSim.Data.MySQL
"?UserLocationX, ?UserLocationY, ?UserLocationZ, " +
"?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " +
"?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+
"CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia)";
"CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia, " +
"?SeeAVs, ?AnyAVSounds, ?GroupAVSounds)";
FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID);
@ -742,7 +762,7 @@ namespace OpenSim.Data.MySQL
}
}
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
public virtual RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
{
RegionLightShareData nWP = new RegionLightShareData();
nWP.OnSave += StoreRegionWindlightSettings;
@ -840,7 +860,7 @@ namespace OpenSim.Data.MySQL
return nWP;
}
public RegionSettings LoadRegionSettings(UUID regionUUID)
public virtual RegionSettings LoadRegionSettings(UUID regionUUID)
{
RegionSettings rs = null;
@ -880,7 +900,7 @@ namespace OpenSim.Data.MySQL
return rs;
}
public void StoreRegionWindlightSettings(RegionLightShareData wl)
public virtual void StoreRegionWindlightSettings(RegionLightShareData wl)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
@ -983,7 +1003,7 @@ namespace OpenSim.Data.MySQL
}
}
public void RemoveRegionWindlightSettings(UUID regionID)
public virtual void RemoveRegionWindlightSettings(UUID regionID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
@ -1060,7 +1080,7 @@ namespace OpenSim.Data.MySQL
}
#endregion
public void StoreRegionSettings(RegionSettings rs)
public virtual void StoreRegionSettings(RegionSettings rs)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
@ -1105,7 +1125,44 @@ namespace OpenSim.Data.MySQL
"?TerrainImageID, " +
"?TelehubObject, ?ParcelImageID)";
FillRegionSettingsCommand(cmd, rs);
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "replace into regionsettings (regionUUID, " +
"block_terraform, block_fly, allow_damage, " +
"restrict_pushing, allow_land_resell, " +
"allow_land_join_divide, block_show_in_search, " +
"agent_limit, object_bonus, maturity, " +
"disable_scripts, disable_collisions, " +
"disable_physics, terrain_texture_1, " +
"terrain_texture_2, terrain_texture_3, " +
"terrain_texture_4, elevation_1_nw, " +
"elevation_2_nw, elevation_1_ne, " +
"elevation_2_ne, elevation_1_se, " +
"elevation_2_se, elevation_1_sw, " +
"elevation_2_sw, water_height, " +
"terrain_raise_limit, terrain_lower_limit, " +
"use_estate_sun, fixed_sun, sun_position, " +
"covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " +
"sunvectorz, loaded_creation_datetime, " +
"loaded_creation_id, map_tile_ID, block_search, casino, " +
"TelehubObject, parcel_tile_ID) " +
"values (?RegionUUID, ?BlockTerraform, " +
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
"?AllowLandResell, ?AllowLandJoinDivide, " +
"?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
"?Maturity, ?DisableScripts, ?DisableCollisions, " +
"?DisablePhysics, ?TerrainTexture1, " +
"?TerrainTexture2, ?TerrainTexture3, " +
"?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " +
"?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " +
"?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " +
"?WaterHeight, ?TerrainRaiseLimit, " +
"?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " +
"?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " +
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
"?LoadedCreationDateTime, ?LoadedCreationID, " +
"?TerrainImageID, ?block_search, ?casino, " +
"?TelehubObject, ?ParcelImageID)";
ExecuteNonQuery(cmd);
}
@ -1114,7 +1171,7 @@ namespace OpenSim.Data.MySQL
SaveSpawnPoints(rs);
}
public List<LandData> LoadLandObjects(UUID regionUUID)
public virtual List<LandData> LoadLandObjects(UUID regionUUID)
{
List<LandData> landData = new List<LandData>();
@ -1296,6 +1353,7 @@ namespace OpenSim.Data.MySQL
prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"];
prim.PassTouches = ((sbyte)row["PassTouches"] != 0);
prim.PassCollisions = ((sbyte)row["PassCollisions"] != 0);
prim.LinkNum = (int)row["LinkNumber"];
if (!(row["MediaURL"] is System.DBNull))
@ -1334,6 +1392,15 @@ namespace OpenSim.Data.MySQL
prim.Friction = (float)(double)row["Friction"];
prim.Restitution = (float)(double)row["Restitution"];
SOPVehicle vehicle = null;
if (row["Vehicle"].ToString() != String.Empty)
{
vehicle = SOPVehicle.FromXml2(row["Vehicle"].ToString());
if (vehicle != null)
prim.VehicleParams = vehicle;
}
return prim;
}
@ -1344,32 +1411,40 @@ namespace OpenSim.Data.MySQL
/// <returns></returns>
private static TaskInventoryItem BuildItem(IDataReader row)
{
TaskInventoryItem taskItem = new TaskInventoryItem();
try
{
TaskInventoryItem taskItem = new TaskInventoryItem();
taskItem.ItemID = DBGuid.FromDB(row["itemID"]);
taskItem.ParentPartID = DBGuid.FromDB(row["primID"]);
taskItem.AssetID = DBGuid.FromDB(row["assetID"]);
taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]);
taskItem.ItemID = DBGuid.FromDB(row["itemID"]);
taskItem.ParentPartID = DBGuid.FromDB(row["primID"]);
taskItem.AssetID = DBGuid.FromDB(row["assetID"]);
taskItem.ParentID = DBGuid.FromDB(row["parentFolderID"]);
taskItem.InvType = Convert.ToInt32(row["invType"]);
taskItem.Type = Convert.ToInt32(row["assetType"]);
taskItem.InvType = Convert.ToInt32(row["invType"]);
taskItem.Type = Convert.ToInt32(row["assetType"]);
taskItem.Name = (String)row["name"];
taskItem.Description = (String)row["description"];
taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
taskItem.CreatorIdentification = (String)row["creatorID"];
taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]);
taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]);
taskItem.GroupID = DBGuid.FromDB(row["groupID"]);
taskItem.Name = (String)row["name"];
taskItem.Description = (String)row["description"];
taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
taskItem.CreatorIdentification = (String)row["creatorID"];
taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]);
taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]);
taskItem.GroupID = DBGuid.FromDB(row["groupID"]);
taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]);
taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]);
taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]);
taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]);
taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]);
taskItem.Flags = Convert.ToUInt32(row["flags"]);
taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]);
taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]);
taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]);
taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]);
taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]);
taskItem.Flags = Convert.ToUInt32(row["flags"]);
return taskItem;
return taskItem;
}
catch
{
m_log.ErrorFormat("[MYSQL DB]: Error reading task inventory: itemID was {0}, primID was {1}", row["itemID"].ToString(), row["primID"].ToString());
throw;
}
}
private static RegionSettings BuildRegionSettings(IDataReader row)
@ -1427,6 +1502,9 @@ namespace OpenSim.Data.MySQL
newSettings.ParcelImageID = DBGuid.FromDB(row["parcel_tile_ID"]);
newSettings.TelehubObject = DBGuid.FromDB(row["TelehubObject"]);
newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]);
newSettings.Casino = Convert.ToBoolean(row["casino"]);
return newSettings;
}
@ -1503,6 +1581,13 @@ namespace OpenSim.Data.MySQL
newData.ParcelAccessList = new List<LandAccessEntry>();
if (!(row["SeeAVs"] is System.DBNull))
newData.SeeAVs = Convert.ToInt32(row["SeeAVs"]) != 0 ? true : false;
if (!(row["AnyAVSounds"] is System.DBNull))
newData.AnyAVSounds = Convert.ToInt32(row["AnyAVSounds"]) != 0 ? true : false;
if (!(row["GroupAVSounds"] is System.DBNull))
newData.GroupAVSounds = Convert.ToInt32(row["GroupAVSounds"]) != 0 ? true : false;
return newData;
}
@ -1520,6 +1605,34 @@ namespace OpenSim.Data.MySQL
return entry;
}
/// <summary>
///
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
private static Array SerializeTerrain(double[,] val, double[,] oldTerrain)
{
MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double));
BinaryWriter bw = new BinaryWriter(str);
// TODO: COMPATIBILITY - Add byte-order conversions
for (int x = 0; x < (int)Constants.RegionSize; x++)
for (int y = 0; y < (int)Constants.RegionSize; y++)
{
double height = 20.0;
if (oldTerrain != null)
height = oldTerrain[x, y];
if (!double.IsNaN(val[x, y]))
height = val[x, y];
if (height == 0.0)
height = double.Epsilon;
bw.Write(height);
}
return str.ToArray();
}
/// <summary>
/// Fill the prim command with prim values
/// </summary>
@ -1654,6 +1767,11 @@ namespace OpenSim.Data.MySQL
else
cmd.Parameters.AddWithValue("PassTouches", 0);
if (prim.PassCollisions)
cmd.Parameters.AddWithValue("PassCollisions", 1);
else
cmd.Parameters.AddWithValue("PassCollisions", 0);
cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
if (prim.AttachedPos != null)
@ -1668,6 +1786,11 @@ namespace OpenSim.Data.MySQL
else
cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]);
if (prim.VehicleParams != null)
cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2());
else
cmd.Parameters.AddWithValue("Vehicle", String.Empty);
if (prim.DynAttrs.CountNamespaces > 0)
cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml());
else
@ -1756,6 +1879,8 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime);
cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID);
cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID);
cmd.Parameters.AddWithValue("block_search", settings.GodBlockSearch);
cmd.Parameters.AddWithValue("casino", settings.Casino);
cmd.Parameters.AddWithValue("ParcelImageID", settings.ParcelImageID);
cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject);
@ -1813,6 +1938,10 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop);
cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic);
cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia);
cmd.Parameters.AddWithValue("SeeAVs", land.SeeAVs ? 1 : 0);
cmd.Parameters.AddWithValue("AnyAVSounds", land.AnyAVSounds ? 1 : 0);
cmd.Parameters.AddWithValue("GroupAVSounds", land.GroupAVSounds ? 1 : 0);
}
/// <summary>
@ -1919,7 +2048,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml());
}
public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
public virtual void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
{
lock (m_dbLock)
{
@ -1963,6 +2092,37 @@ namespace OpenSim.Data.MySQL
}
}
public UUID[] GetObjectIDs(UUID regionID)
{
List<UUID> uuids = new List<UUID>();
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "select UUID from prims where RegionUUID = ?RegionUUID and SceneGroupID = UUID";
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
using (IDataReader reader = ExecuteReader(cmd))
{
while (reader.Read())
{
UUID id = new UUID(reader["UUID"].ToString());
uuids.Add(id);
}
}
}
}
}
return uuids.ToArray();
}
private void LoadSpawnPoints(RegionSettings rs)
{
rs.ClearSpawnPoints();

View File

@ -46,17 +46,21 @@ namespace OpenSim.Data.MySQL
{
string[] words = query.Split(new char[] {' '});
bool valid = false;
for (int i = 0 ; i < words.Length ; i++)
{
if (words[i].Length < 3)
{
if (i != words.Length - 1)
Array.Copy(words, i + 1, words, i, words.Length - i - 1);
Array.Resize(ref words, words.Length - 1);
}
if (words[i].Length > 2)
valid = true;
// if (words[i].Length < 3)
// {
// if (i != words.Length - 1)
// Array.Copy(words, i + 1, words, i, words.Length - i - 1);
// Array.Resize(ref words, words.Length - 1);
// }
}
if (words.Length == 0)
if ((!valid) || words.Length == 0)
return new UserAccountData[0];
if (words.Length > 2)
@ -66,20 +70,36 @@ namespace OpenSim.Data.MySQL
{
if (words.Length == 1)
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm);
cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%");
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search) and active=1", m_Realm);
cmd.Parameters.AddWithValue("?search", words[0] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
else
{
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm);
cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%");
cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst and LastName like ?searchLast) and active=1", m_Realm);
cmd.Parameters.AddWithValue("?searchFirst", words[0] + "%");
cmd.Parameters.AddWithValue("?searchLast", words[1] + "%");
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
return DoQuery(cmd);
}
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
using (MySqlCommand cmd = new MySqlCommand())
{
if (scopeID != UUID.Zero)
{
where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")";
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
cmd.CommandText = String.Format("select * from {0} where " + where, m_Realm);
return DoQuery(cmd);
}
}
}
}

View File

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

View File

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

View File

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

View File

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

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)
{
}

View File

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

View File

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

View File

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

View File

@ -88,15 +88,3 @@ CREATE TABLE IF NOT EXISTS userdata (
commit;
:VERSION 3 # -------------------------------
begin;
CREATE TABLE IF NOT EXISTS usersettings (
useruuid char(36) NOT NULL,
imviaemail binary(1) NOT NULL,
visible binary(1) NOT NULL,
email varchar(254) NOT NULL,
PRIMARY KEY (useruuid)
)
commit;

View File

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

View File

@ -2013,6 +2013,7 @@ namespace OpenSim.Data.SQLite
return entry;
}
/*
/// <summary>
///
/// </summary>
@ -2944,6 +2945,11 @@ namespace OpenSim.Data.SQLite
}
}
public UUID[] GetObjectIDs(UUID regionID)
{
return new UUID[0];
}
public void SaveExtra(UUID regionID, string name, string value)
{
}

View File

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

View File

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

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

View File

@ -53,7 +53,11 @@ namespace OpenSim.Framework
// should be only used as initial default value ( V1 viewers )
public readonly static int VISUALPARAM_COUNT = 218;
public readonly static int TEXTURE_COUNT = 21;
// public readonly static int TEXTURE_COUNT = 21
// 21 bad, make it be updated as libovm gets update
// also keeping in sync with it
public readonly static int TEXTURE_COUNT = Primitive.TextureEntry.MAX_FACES;
public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
protected int m_serial = 0;
@ -179,11 +183,16 @@ namespace OpenSim.Framework
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
}
public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true)
public AvatarAppearance(AvatarAppearance appearance): this(appearance, true,true)
{
}
public AvatarAppearance(AvatarAppearance appearance, bool copyWearables)
: this(appearance, copyWearables, true)
{
}
public AvatarAppearance(AvatarAppearance appearance, bool copyWearables, bool copyBaked)
{
// m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
@ -217,6 +226,10 @@ namespace OpenSim.Framework
{
byte[] tbytes = appearance.Texture.GetBytes();
m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
if (copyBaked && appearance.m_cacheitems != null)
m_cacheitems = (WearableCacheItem[])appearance.m_cacheitems.Clone();
else
m_cacheitems = null;
}
m_visualparams = null;
@ -458,7 +471,10 @@ namespace OpenSim.Framework
// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
// DEBUG OFF
m_wearables[wearableId].Clear();
for (int i = 0; i < wearable.Count; i++)
int count = wearable.Count;
if (count > AvatarWearable.MAX_WEARABLES)
count = AvatarWearable.MAX_WEARABLES;
for (int i = 0; i < count; i++)
m_wearables[wearableId].Add(wearable[i].ItemID, wearable[i].AssetID);
}
@ -722,6 +738,13 @@ namespace OpenSim.Framework
}
data["textures"] = textures;
if (m_cacheitems != null)
{
OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems);
if (baked != null)
data["bakedcache"] = baked;
}
// Visual Parameters
OSDBinary visualparams = new OSDBinary(m_visualparams);
data["visualparams"] = visualparams;
@ -757,7 +780,12 @@ namespace OpenSim.Framework
if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
{
OSDArray wears = (OSDArray)(data["wearables"]);
for (int i = 0; i < wears.Count; i++)
int count = wears.Count;
if (count > AvatarWearable.MAX_WEARABLES)
count = AvatarWearable.MAX_WEARABLES;
for (int i = 0; i < count; i++)
m_wearables[i] = new AvatarWearable((OSDArray)wears[i]);
}
else
@ -783,6 +811,12 @@ namespace OpenSim.Framework
m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures");
}
if ((data != null) && (data["bakedcache"] != null) && (data["bakedcache"]).Type == OSDType.Array)
{
OSDArray bakedOSDArray = (OSDArray)(data["bakedcache"]);
m_cacheitems = WearableCacheItem.BakedFromOSD(bakedOSDArray);
}
// Visual Parameters
SetDefaultParams();
if ((data != null) && (data["visualparams"] != null))
@ -1632,7 +1666,12 @@ namespace OpenSim.Framework
BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247,
BREAST_PHYSICS_LEFTRIGHT_SPRING= 248,
BREAST_PHYSICS_LEFTRIGHT_GAIN = 249,
BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250
BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250,
// Ubit: 07/96/2013 new parameters
_APPEARANCEMESSAGE_VERSION = 251, //ID 11000
SHAPE_HOVER = 252, //ID 11001
}
#endregion
}

View File

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

View File

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

View File

@ -94,6 +94,7 @@ namespace OpenSim.Framework
// This probably shouldn't be here
public byte[] Throttles;
public Dictionary<ulong, string> ChildrenCapSeeds = null;
public OSDMap Pack()
{
@ -119,6 +120,19 @@ namespace OpenSim.Framework
if ((Throttles != null) && (Throttles.Length > 0))
args["throttles"] = OSD.FromBinary(Throttles);
if (ChildrenCapSeeds != null && ChildrenCapSeeds.Count > 0)
{
OSDArray childrenSeeds = new OSDArray(ChildrenCapSeeds.Count);
foreach (KeyValuePair<ulong, string> kvp in ChildrenCapSeeds)
{
OSDMap pair = new OSDMap();
pair["handle"] = OSD.FromString(kvp.Key.ToString());
pair["seed"] = OSD.FromString(kvp.Value);
childrenSeeds.Add(pair);
}
args["children_seeds"] = childrenSeeds;
}
return args;
}
@ -165,6 +179,30 @@ namespace OpenSim.Framework
if (args["throttles"] != null)
Throttles = args["throttles"].AsBinary();
if (args.ContainsKey("children_seeds") && (args["children_seeds"] != null) &&
(args["children_seeds"].Type == OSDType.Array))
{
OSDArray childrenSeeds = (OSDArray)(args["children_seeds"]);
ChildrenCapSeeds = new Dictionary<ulong, string>();
foreach (OSD o in childrenSeeds)
{
if (o.Type == OSDType.Map)
{
ulong handle = 0;
string seed = "";
OSDMap pair = (OSDMap)o;
if (pair["handle"] != null)
if (!UInt64.TryParse(pair["handle"].AsString(), out handle))
continue;
if (pair["seed"] != null)
seed = pair["seed"].AsString();
if (!ChildrenCapSeeds.ContainsKey(handle))
ChildrenCapSeeds.Add(handle, seed);
}
}
}
}
/// <summary>
@ -317,9 +355,11 @@ namespace OpenSim.Framework
public UUID ActiveGroupID;
public AgentGroupData[] Groups;
public Dictionary<ulong, string> ChildrenCapSeeds = null;
public Animation[] Anims;
public Animation DefaultAnim = null;
public Animation AnimState = null;
public Byte MotionState = 0;
public UUID GranterID;
public UUID ParentPart;
@ -349,6 +389,8 @@ namespace OpenSim.Framework
public List<ISceneObject> AttachmentObjects;
public List<string> AttachmentObjectStates;
public Dictionary<string, UUID> MovementAnimationOverRides = new Dictionary<string, UUID>();
public virtual OSDMap Pack()
{
// m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
@ -399,6 +441,19 @@ namespace OpenSim.Framework
args["groups"] = groups;
}
if (ChildrenCapSeeds != null && ChildrenCapSeeds.Count > 0)
{
OSDArray childrenSeeds = new OSDArray(ChildrenCapSeeds.Count);
foreach (KeyValuePair<ulong, string> kvp in ChildrenCapSeeds)
{
OSDMap pair = new OSDMap();
pair["handle"] = OSD.FromString(kvp.Key.ToString());
pair["seed"] = OSD.FromString(kvp.Value);
childrenSeeds.Add(pair);
}
args["children_seeds"] = childrenSeeds;
}
if ((Anims != null) && (Anims.Length > 0))
{
OSDArray anims = new OSDArray(Anims.Length);
@ -417,6 +472,26 @@ namespace OpenSim.Framework
args["animation_state"] = AnimState.PackUpdateMessage();
}
if (MovementAnimationOverRides.Count > 0)
{
OSDArray AOs = new OSDArray(MovementAnimationOverRides.Count);
{
foreach (KeyValuePair<string, UUID> kvp in MovementAnimationOverRides)
{
OSDMap ao = new OSDMap(2);
ao["state"] = OSD.FromString(kvp.Key);
ao["uuid"] = OSD.FromUUID(kvp.Value);
AOs.Add(ao);
}
}
args["movementAO"] = AOs;
}
if (MotionState != 0)
{
args["motion_state"] = OSD.FromInteger(MotionState);
}
if (Appearance != null)
args["packed_appearance"] = Appearance.Pack();
@ -431,6 +506,8 @@ namespace OpenSim.Framework
// The code to pack textures, visuals, wearables and attachments
// should be removed; packed appearance contains the full appearance
// This is retained for backward compatibility only
/* then lets remove
if (Appearance.Texture != null)
{
byte[] rawtextures = Appearance.Texture.GetBytes();
@ -459,7 +536,7 @@ namespace OpenSim.Framework
args["attachments"] = attachs;
}
// End of code to remove
*/
if ((Controllers != null) && (Controllers.Length > 0))
{
OSDArray controls = new OSDArray(Controllers.Length);
@ -600,6 +677,29 @@ namespace OpenSim.Framework
}
}
if (args.ContainsKey("children_seeds") && (args["children_seeds"] != null) &&
(args["children_seeds"].Type == OSDType.Array))
{
OSDArray childrenSeeds = (OSDArray)(args["children_seeds"]);
ChildrenCapSeeds = new Dictionary<ulong, string>();
foreach (OSD o in childrenSeeds)
{
if (o.Type == OSDType.Map)
{
ulong handle = 0;
string seed = "";
OSDMap pair = (OSDMap)o;
if (pair["handle"] != null)
if (!UInt64.TryParse(pair["handle"].AsString(), out handle))
continue;
if (pair["seed"] != null)
seed = pair["seed"].AsString();
if (!ChildrenCapSeeds.ContainsKey(handle))
ChildrenCapSeeds.Add(handle, seed);
}
}
}
if ((args["animations"] != null) && (args["animations"]).Type == OSDType.Array)
{
OSDArray anims = (OSDArray)(args["animations"]);
@ -638,6 +738,28 @@ namespace OpenSim.Framework
}
}
MovementAnimationOverRides.Clear();
if (args["movementAO"] != null && args["movementAO"].Type == OSDType.Array)
{
OSDArray AOs = (OSDArray)(args["movementAO"]);
int count = AOs.Count;
for (int i = 0; i < count; i++)
{
OSDMap ao = (OSDMap)AOs[i];
if (ao["state"] != null && ao["uuid"] != null)
{
string state = ao["state"].AsString();
UUID id = ao["uuid"].AsUUID();
MovementAnimationOverRides[state] = id;
}
}
}
if (args.ContainsKey("motion_state"))
MotionState = (byte)args["motion_state"].AsInteger();
//if ((args["agent_textures"] != null) && (args["agent_textures"]).Type == OSDType.Array)
//{
// OSDArray textures = (OSDArray)(args["agent_textures"]);
@ -647,53 +769,71 @@ namespace OpenSim.Framework
// AgentTextures[i++] = o.AsUUID();
//}
Appearance = new AvatarAppearance();
// The code to unpack textures, visuals, wearables and attachments
// should be removed; packed appearance contains the full appearance
// This is retained for backward compatibility only
if (args["texture_entry"] != null)
// packed_appearence should contain all appearance information
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
{
byte[] rawtextures = args["texture_entry"].AsBinary();
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length);
Appearance.SetTextureEntries(textures);
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance");
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
}
if (args["visual_params"] != null)
Appearance.SetVisualParams(args["visual_params"].AsBinary());
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
else
{
OSDArray wears = (OSDArray)(args["wearables"]);
for (int i = 0; i < wears.Count / 2; i++)
// if missing try the old pack method
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance, checking old method");
Appearance = new AvatarAppearance();
// The code to unpack textures, visuals, wearables and attachments
// should be removed; packed appearance contains the full appearance
// This is retained for backward compatibility only
if (args["texture_entry"] != null)
{
AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]);
Appearance.SetWearable(i,awear);
byte[] rawtextures = args["texture_entry"].AsBinary();
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures, 0, rawtextures.Length);
Appearance.SetTextureEntries(textures);
}
}
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
{
OSDArray attachs = (OSDArray)(args["attachments"]);
foreach (OSD o in attachs)
if (args["visual_params"] != null)
Appearance.SetVisualParams(args["visual_params"].AsBinary());
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
{
if (o.Type == OSDType.Map)
OSDArray wears = (OSDArray)(args["wearables"]);
int count = wears.Count;
if (count > AvatarWearable.MAX_WEARABLES)
count = AvatarWearable.MAX_WEARABLES;
for (int i = 0; i < count / 2; i++)
{
// We know all of these must end up as attachments so we
// append rather than replace to ensure multiple attachments
// per point continues to work
// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID);
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]);
Appearance.SetWearable(i, awear);
}
}
}
// end of code to remove
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
{
OSDArray attachs = (OSDArray)(args["attachments"]);
foreach (OSD o in attachs)
{
if (o.Type == OSDType.Map)
{
// We know all of these must end up as attachments so we
// append rather than replace to ensure multiple attachments
// per point continues to work
// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID);
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
}
}
}
// end of code to remove
}
/* moved above
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
else
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
*/
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
{
OSDArray controls = (OSDArray)(args["controllers"]);

View File

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

View File

@ -389,9 +389,32 @@ namespace OpenSim.Framework.Communications
}
}
if (_response != null)
_response.Close();
return null;
}
<<<<<<< HEAD
=======
using (Stream src = _response.GetResponseStream())
{
int length = src.Read(_readbuf, 0, BufferSize);
while (length > 0)
{
_resource.Write(_readbuf, 0, length);
length = src.Read(_readbuf, 0, BufferSize);
}
}
// TODO! Implement timeout, without killing the server
// this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
//ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
// _allDone.WaitOne();
if (_response != null)
_response.Close();
>>>>>>> avn/ubitvar
if (_asyncException != null)
throw _asyncException;
@ -413,7 +436,7 @@ namespace OpenSim.Framework.Communications
_request = (HttpWebRequest) WebRequest.Create(buildUri());
_request.KeepAlive = false;
_request.ContentType = "application/xml";
_request.Timeout = 900000;
_request.Timeout = 30000;
_request.Method = RequestMethod;
_asyncException = null;
_request.ContentLength = src.Length;
@ -421,6 +444,7 @@ namespace OpenSim.Framework.Communications
auth.AddAuthorization(_request.Headers);
src.Seek(0, SeekOrigin.Begin);
<<<<<<< HEAD
int reqnum = WebUtil.RequestNumber++;
if (WebUtil.DebugLevel >= 3)
@ -433,9 +457,22 @@ namespace OpenSim.Framework.Communications
byte[] buf = new byte[1024];
int length = src.Read(buf, 0, 1024);
while (length > 0)
=======
m_log.Info("[REST]: Seek is ok");
using (Stream dst = _request.GetRequestStream())
>>>>>>> avn/ubitvar
{
dst.Write(buf, 0, length);
length = src.Read(buf, 0, 1024);
m_log.Info("[REST]: GetRequestStream is ok");
byte[] buf = new byte[1024];
int length = src.Read(buf, 0, 1024);
m_log.Info("[REST]: First Read is ok");
while (length > 0)
{
dst.Write(buf, 0, length);
length = src.Read(buf, 0, 1024);
}
}
try
@ -470,6 +507,9 @@ namespace OpenSim.Framework.Communications
_response.Close();
if (_response != null)
_response.Close();
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
// TODO! Implement timeout, without killing the server

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

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

View File

@ -64,14 +64,15 @@ namespace OpenSim.Framework
public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes);
public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest);
public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize, WearableCacheItem[] CacheItems);
public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest);
public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
public delegate void StopAnim(IClientAPI remoteClient, UUID animID);
public delegate void ChangeAnim(UUID animID, bool addOrRemove, bool sendPack);
public delegate void LinkObjects(IClientAPI remoteClient, uint parent, List<uint> children);
public delegate void DelinkObjects(List<uint> primIds, IClientAPI client);
@ -132,6 +133,8 @@ namespace OpenSim.Framework
public delegate void UpdateVector(uint localID, Vector3 pos, IClientAPI remoteClient);
public delegate void ClientChangeObject(uint localID, object data ,IClientAPI remoteClient);
public delegate void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient);
public delegate void UpdatePrimSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient);
@ -268,6 +271,9 @@ namespace OpenSim.Framework
public delegate void MoveInventoryItem(
IClientAPI remoteClient, List<InventoryItemBase> items);
public delegate void MoveItemsAndLeaveCopy(
IClientAPI remoteClient, List<InventoryItemBase> items, UUID destFolder);
public delegate void RemoveInventoryItem(
IClientAPI remoteClient, List<UUID> itemIDs);
@ -443,6 +449,7 @@ namespace OpenSim.Framework
public delegate void ClassifiedInfoRequest(UUID classifiedID, IClientAPI client);
public delegate void ClassifiedInfoUpdate(UUID classifiedID, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags, int price, IClientAPI client);
public delegate void ClassifiedDelete(UUID classifiedID, IClientAPI client);
public delegate void ClassifiedGodDelete(UUID classifiedID, UUID queryID, IClientAPI client);
public delegate void EventNotificationAddRequest(uint EventID, IClientAPI client);
public delegate void EventNotificationRemoveRequest(uint EventID, IClientAPI client);
@ -465,9 +472,9 @@ namespace OpenSim.Framework
public delegate void AgentFOV(IClientAPI client, float verticalAngle);
public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int Flags,UUID AgentID);
public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int type, uint flags);
public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name, UUID AgentID);
public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name);
public delegate void AvatarInterestReply(IClientAPI client,UUID target, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
@ -505,6 +512,7 @@ namespace OpenSim.Framework
public delegate void SimWideDeletesDelegate(IClientAPI client,UUID agentID, int flags, UUID targetID);
public delegate void SendPostcard(IClientAPI client);
public delegate void ChangeInventoryItemFlags(IClientAPI client, UUID itemID, uint flags);
#endregion
@ -734,6 +742,8 @@ namespace OpenSim.Framework
IScene Scene { get; }
List<uint> SelectedObjects { get; }
// [Obsolete("LLClientView Specific - Replace with ???")]
int NextAnimationSequenceNumber { get; }
@ -747,6 +757,8 @@ namespace OpenSim.Framework
/// </summary>
bool IsActive { get; set; }
int PingTimeMS { get; }
/// <summary>
/// Set if the client is closing due to a logout request
/// </summary>
@ -794,6 +806,7 @@ namespace OpenSim.Framework
event ObjectDrop OnObjectDrop;
event StartAnim OnStartAnim;
event StopAnim OnStopAnim;
event ChangeAnim OnChangeAnim;
event LinkObjects OnLinkObjects;
event DelinkObjects OnDelinkObjects;
event RequestMapBlocks OnRequestMapBlocks;
@ -860,6 +873,7 @@ namespace OpenSim.Framework
event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
event UpdatePrimFlags OnUpdatePrimFlags;
event UpdatePrimTexture OnUpdatePrimTexture;
event ClientChangeObject onClientChangeObject;
event UpdateVector OnUpdatePrimGroupPosition;
event UpdateVector OnUpdatePrimSinglePosition;
event UpdatePrimRotation OnUpdatePrimGroupRotation;
@ -884,6 +898,7 @@ namespace OpenSim.Framework
event RequestTaskInventory OnRequestTaskInventory;
event UpdateInventoryItem OnUpdateInventoryItem;
event CopyInventoryItem OnCopyInventoryItem;
event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
event MoveInventoryItem OnMoveInventoryItem;
event RemoveInventoryFolder OnRemoveInventoryFolder;
event RemoveInventoryItem OnRemoveInventoryItem;
@ -1002,7 +1017,7 @@ namespace OpenSim.Framework
event ClassifiedInfoRequest OnClassifiedInfoRequest;
event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
event ClassifiedDelete OnClassifiedDelete;
event ClassifiedDelete OnClassifiedGodDelete;
event ClassifiedGodDelete OnClassifiedGodDelete;
event EventNotificationAddRequest OnEventNotificationAddRequest;
event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
@ -1041,11 +1056,12 @@ namespace OpenSim.Framework
event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
event SimWideDeletesDelegate OnSimWideDeletes;
event SendPostcard OnSendPostcard;
event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
event MuteListEntryUpdate OnUpdateMuteListEntry;
event MuteListEntryRemove OnRemoveMuteListEntry;
event GodlikeMessage onGodlikeMessage;
event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
event GenericCall2 OnUpdateThrottles;
/// <summary>
/// Set the debug level at which packet output should be printed to console.
/// </summary>
@ -1066,7 +1082,7 @@ namespace OpenSim.Framework
/// If true, attempts the close without checking active status. You do not want to try this except as a last
/// ditch attempt where Active == false but the ScenePresence still exists.
/// </param>
void Close(bool force);
void Close(bool sendStop, bool force);
void Kick(string message);
@ -1102,6 +1118,8 @@ namespace OpenSim.Framework
/// <param name="localID"></param>
void SendKillObject(List<uint> localID);
void SendPartFullUpdate(ISceneEntity ent, uint? parentID);
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
@ -1125,6 +1143,8 @@ namespace OpenSim.Framework
void SendGenericMessage(string method, UUID invoice, List<string> message);
void SendGenericMessage(string method, UUID invoice, List<byte[]> message);
bool CanSendLayerData();
void SendLayerData(float[] map);
void SendLayerData(int px, int py, float[] map);
@ -1168,6 +1188,10 @@ namespace OpenSim.Framework
void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations);
void SetChildAgentThrottle(byte[] throttle);
void SetChildAgentThrottle(byte[] throttle,float factor);
void SetAgentThrottleSilent(int throttle, int setting);
int GetAgentThrottleSilent(int throttle);
void SendAvatarDataImmediate(ISceneEntity avatar);
@ -1192,6 +1216,7 @@ namespace OpenSim.Framework
/// </summary>
/// <param name="Item"></param>
void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId);
void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId);
void SendRemoveInventoryItem(UUID itemID);
@ -1211,7 +1236,7 @@ namespace OpenSim.Framework
/// <param name="node"></param>
void SendBulkUpdateInventory(InventoryNodeBase node);
void SendXferPacket(ulong xferID, uint packet, byte[] data);
void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory);
void SendAbortXferPacket(ulong xferID);

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 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 SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client);
void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client);
bool UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client, out bool snap_selection, out bool needOverlay);
bool IsEitherBannedOrRestricted(UUID avatar);
bool IsBannedFromLand(UUID avatar);
bool CanBeOnThisLand(UUID avatar, float posHeight);

View File

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

View File

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

View File

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

View File

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

View File

@ -43,7 +43,6 @@ namespace OpenSim.Framework.Monitoring
StringBuilder sb = new StringBuilder(Environment.NewLine);
sb.Append("MEMORY STATISTICS");
sb.Append(Environment.NewLine);
sb.AppendFormat(
"Heap allocated to OpenSim : {0} MB\n",
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
@ -56,9 +55,23 @@ namespace OpenSim.Framework.Monitoring
"Average heap allocation rate: {0} MB/s\n",
Math.Round((MemoryWatchdog.AverageHeapAllocationRate * 1000) / 1024.0 / 1024, 3));
sb.AppendFormat(
"Process memory : {0} MB\n",
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
Process myprocess = Process.GetCurrentProcess();
if (!myprocess.HasExited)
{
myprocess.Refresh();
sb.AppendFormat(
"Process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0),
Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0),
Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0));
sb.AppendFormat(
"Peak process memory: Physical {0} MB \t Paged {1} MB \t Virtual {2} MB\n",
Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0),
Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0),
Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0));
}
else
sb.Append("Process reported as Exited \n");
return sb.ToString();
}

View File

@ -249,6 +249,49 @@ namespace OpenSim.Framework.Monitoring
(s) => { s.Value = Math.Round(MemoryWatchdog.LastHeapAllocationRate * 1000d / 1024d / 1024d, 3); });
MakeStat("AverageHeapAllocationRate", null, "MB/sec", ContainerMemory,
(s) => { s.Value = Math.Round(MemoryWatchdog.AverageHeapAllocationRate * 1000d / 1024d / 1024d, 3); });
MakeStat("ProcessResident", null, "MB", ContainerProcess,
(s) =>
{
Process myprocess = Process.GetCurrentProcess();
myprocess.Refresh();
s.Value = Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0);
});
MakeStat("ProcessPaged", null, "MB", ContainerProcess,
(s) =>
{
Process myprocess = Process.GetCurrentProcess();
myprocess.Refresh();
s.Value = Math.Round(Process.GetCurrentProcess().PagedMemorySize64 / 1024.0 / 1024.0);
});
MakeStat("ProcessVirtual", null, "MB", ContainerProcess,
(s) =>
{
Process myprocess = Process.GetCurrentProcess();
myprocess.Refresh();
s.Value = Math.Round(Process.GetCurrentProcess().VirtualMemorySize64 / 1024.0 / 1024.0);
});
MakeStat("PeakProcessResident", null, "MB", ContainerProcess,
(s) =>
{
Process myprocess = Process.GetCurrentProcess();
myprocess.Refresh();
s.Value = Math.Round(Process.GetCurrentProcess().PeakWorkingSet64 / 1024.0 / 1024.0);
});
MakeStat("PeakProcessPaged", null, "MB", ContainerProcess,
(s) =>
{
Process myprocess = Process.GetCurrentProcess();
myprocess.Refresh();
s.Value = Math.Round(Process.GetCurrentProcess().PeakPagedMemorySize64 / 1024.0 / 1024.0);
});
MakeStat("PeakProcessVirtual", null, "MB", ContainerProcess,
(s) =>
{
Process myprocess = Process.GetCurrentProcess();
myprocess.Refresh();
s.Value = Math.Round(Process.GetCurrentProcess().PeakVirtualMemorySize64 / 1024.0 / 1024.0);
});
}
// Notes on performance counters:

View File

@ -239,6 +239,17 @@ namespace OpenSim.Framework.Monitoring
return sb.ToString();
}
public virtual OSDMap ToBriefOSDMap()
{
OSDMap ret = new OSDMap();
ret.Add("Value", OSD.FromReal(Value));
double lastChangeOverTime, averageChangeOverTime;
return ret;
}
public virtual OSDMap ToOSDMap()
{
OSDMap ret = new OSDMap();

View File

@ -283,7 +283,7 @@ namespace OpenSim.Framework.Monitoring
if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName))
continue;
statMap.Add(statName, theStats[statName].ToOSDMap());
statMap.Add(statName, theStats[statName].ToBriefOSDMap());
}
contMap.Add(contName, statMap);
@ -305,6 +305,17 @@ namespace OpenSim.Framework.Monitoring
string pContainerName = StatsManager.AllSubCommand;
string pStatName = StatsManager.AllSubCommand;
if (!request.ContainsKey("pass") || request["pass"].ToString() != "l0st4nge1s")
{
responsedata["int_response_code"] = response_code;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = "Access denied";
responsedata["access_control_allow_origin"] = "*";
return responsedata;
}
if (request.ContainsKey("cat")) pCategoryName = request["cat"].ToString();
if (request.ContainsKey("cont")) pContainerName = request["cat"].ToString();
if (request.ContainsKey("stat")) pStatName = request["stat"].ToString();

View File

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

View File

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

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
{
public enum ParcelMediaCommandEnum
public enum ParcelMediaCommandEnum : int
{
Stop = 0,
Pause = 1,

View File

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

View File

@ -245,6 +245,7 @@ namespace OpenSim.Framework
// occasionally seems to corrupt its addin cache
// Hence, as a temporary solution we'll remove it before each startup
<<<<<<< HEAD
try
{
if (Directory.Exists(dir + "/addin-db-000"))
@ -252,6 +253,23 @@ namespace OpenSim.Framework
if (Directory.Exists(dir + "/addin-db-001"))
Directory.Delete(dir + "/addin-db-001", true);
=======
string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY");
string v0 = "addin-db-000";
string v1 = "addin-db-001";
if (customDir != null && customDir != String.Empty)
{
v0 = Path.Combine(customDir, v0);
v1 = Path.Combine(customDir, v1);
}
try
{
if (Directory.Exists(v0))
Directory.Delete(v0, true);
if (Directory.Exists(v1))
Directory.Delete(v1, true);
>>>>>>> avn/ubitvar
}
catch (IOException)
{

View File

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

View File

@ -45,7 +45,8 @@ namespace OpenSim.Framework
/// <summary>
/// Total number of queues (priorities) available
/// </summary>
public const uint NumberOfQueues = 12;
public const uint NumberOfQueues = 12; // includes immediate queues, m_queueCounts need to be set acording
/// <summary>
/// Number of queuest (priorities) that are processed immediately
@ -60,7 +61,10 @@ namespace OpenSim.Framework
// each pass. weighted towards the higher priority queues
private uint m_nextQueue = 0;
private uint m_countFromQueue = 0;
private uint[] m_queueCounts = { 8, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1 };
// first queues are imediate, so no counts
// private uint[] m_queueCounts = { 0, 0, 8, 4, 4, 2, 2, 2, 2, 1, 1, 1 };
private uint[] m_queueCounts = {0, 0, 8, 8, 5, 4, 3, 2, 1, 1, 1, 1};
// this is ava, ava, attach, <10m, 20,40,80,160m,320,640,1280, +
// next request is a counter of the number of updates queued, it provides
// a total ordering on the updates coming through the queue and is more
@ -130,6 +134,21 @@ namespace OpenSim.Framework
return true;
}
public void Remove(List<uint> ids)
{
LookupItem lookup;
foreach (uint localid in ids)
{
if (m_lookupTable.TryGetValue(localid, out lookup))
{
lookup.Heap.Remove(lookup.Handle);
m_lookupTable.Remove(localid);
}
}
}
/// <summary>
/// Remove an item from one of the queues. Specifically, it removes the
/// oldest item from the next queue in order to provide fair access to
@ -137,7 +156,7 @@ namespace OpenSim.Framework
/// </summary>
public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue)
{
// If there is anything in priority queue 0, return it first no
// If there is anything in imediate queues, return it first no
// matter what else. Breaks fairness. But very useful.
for (int iq = 0; iq < NumberOfImmediateQueues; iq++)
{
@ -172,14 +191,13 @@ namespace OpenSim.Framework
}
// Find the next non-immediate queue with updates in it
for (int i = 0; i < NumberOfQueues; ++i)
for (uint i = NumberOfImmediateQueues; i < NumberOfQueues; ++i)
{
m_nextQueue = (uint)((m_nextQueue + 1) % NumberOfQueues);
m_countFromQueue = m_queueCounts[m_nextQueue];
m_nextQueue++;
if(m_nextQueue >= NumberOfQueues)
m_nextQueue = NumberOfImmediateQueues;
// if this is one of the immediate queues, just skip it
if (m_nextQueue < NumberOfImmediateQueues)
continue;
m_countFromQueue = m_queueCounts[m_nextQueue];
if (m_heaps[m_nextQueue].Count > 0)
{
@ -189,7 +207,6 @@ namespace OpenSim.Framework
m_lookupTable.Remove(item.Value.Entity.LocalId);
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
value = item.Value;
return true;
}
}

View File

@ -40,6 +40,7 @@ using OpenMetaverse.StructuredData;
namespace OpenSim.Framework
{
[Serializable]
public class RegionLightShareData : ICloneable
{
public bool valid = false;
@ -101,6 +102,12 @@ namespace OpenSim.Framework
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[REGION INFO]";
<<<<<<< HEAD
=======
public bool commFailTF = false;
public ConfigurationMember configMember;
public string DataStore = String.Empty;
>>>>>>> avn/ubitvar
public string RegionFile = String.Empty;
public bool isSandbox = false;
public bool Persistent = true;
@ -527,7 +534,11 @@ namespace OpenSim.Framework
return null;
}
<<<<<<< HEAD
private void SetExtraSetting(string key, string value)
=======
public void SetExtraSetting(string key, string value)
>>>>>>> avn/ubitvar
{
string keylower = key.ToLower();
m_extraSettings[keylower] = value;
@ -823,7 +834,15 @@ namespace OpenSim.Framework
string location = String.Format("{0},{1}", RegionLocX, RegionLocY);
config.Set("Location", location);
<<<<<<< HEAD
if (RegionSizeX > 0)
=======
if (DataStore != String.Empty)
config.Set("Datastore", DataStore);
if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize)
{
>>>>>>> avn/ubitvar
config.Set("SizeX", RegionSizeX);
if (RegionSizeY > 0)
@ -901,6 +920,234 @@ namespace OpenSim.Framework
throw new Exception("Invalid file type for region persistence.");
}
<<<<<<< HEAD
=======
public void loadConfigurationOptionsFromMe()
{
configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID_NULL_FREE,
"UUID of Region (Default is recommended, random UUID)",
RegionID.ToString(), true);
configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"Region Name", RegionName, true);
configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Grid Location (X Axis)", RegionLocX.ToString(), true);
configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Grid Location (Y Axis)", RegionLocY.ToString(), true);
configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Size of region in X dimension", RegionSizeX.ToString(), true);
configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Size of region in Y dimension", RegionSizeY.ToString(), true);
configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Size of region in Z dimension", RegionSizeZ.ToString(), true);
//m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
configMember.addConfigurationOption("internal_ip_address",
ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
"Internal IP Address for incoming UDP client connections",
m_internalEndPoint.Address.ToString(),
true);
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Internal IP Port for incoming UDP client connections",
m_internalEndPoint.Port.ToString(), true);
configMember.addConfigurationOption("allow_alternate_ports",
ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
"Allow sim to find alternate UDP ports when ports are in use?",
m_allow_alternate_ports.ToString(), true);
configMember.addConfigurationOption("external_host_name",
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"External Host Name", m_externalHostName, true);
configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
"Last Map UUID", lastMapUUID.ToString(), true);
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
"Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
"Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for physical prims", m_physPrimMax.ToString(), true);
configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
"Clamp prims to max size", m_clampPrimSize.ToString(), true);
configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Max objects this sim will hold", m_objectCapacity.ToString(), true);
configMember.addConfigurationOption("linkset_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Max prims an object will hold", m_linksetCapacity.ToString(), true);
configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Max avatars this sim will hold", m_agentCapacity.ToString(), true);
configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
"Scope ID for this region", ScopeID.ToString(), true);
configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING,
"Free form string describing the type of region", String.Empty, true);
configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
"UUID of a texture to use as the map for this region", m_maptileStaticUUID.ToString(), true);
}
public void loadConfigurationOptions()
{
configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
"UUID of Region (Default is recommended, random UUID)",
UUID.Random().ToString(), true);
configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"Region Name", "OpenSim Test", false);
configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Grid Location (X Axis)", "1000", false);
configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Grid Location (Y Axis)", "1000", false);
configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Size of region in X dimension", Constants.RegionSize.ToString(), false);
configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Size of region in Y dimension", Constants.RegionSize.ToString(), false);
configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Size of region in Z dimension", Constants.RegionHeight.ToString(), false);
//m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
configMember.addConfigurationOption("internal_ip_address",
ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
"Internal IP Address for incoming UDP client connections", "0.0.0.0",
false);
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Internal IP Port for incoming UDP client connections",
ConfigSettings.DefaultRegionHttpPort.ToString(), false);
configMember.addConfigurationOption("allow_alternate_ports", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
"Allow sim to find alternate UDP ports when ports are in use?",
"false", true);
configMember.addConfigurationOption("external_host_name",
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"External Host Name", "127.0.0.1", false);
configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
"Last Map UUID", lastMapUUID.ToString(), true);
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for nonphysical prims", "0", true);
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for physical prims", "0", true);
configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
"Clamp prims to max size", "false", true);
configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Max objects this sim will hold", "15000", true);
configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Max avatars this sim will hold", "100", true);
configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
"Scope ID for this region", UUID.Zero.ToString(), true);
configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING,
"Region Type", String.Empty, true);
configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
"UUID of a texture to use as the map for this region", String.Empty, true);
}
public bool handleIncomingConfiguration(string configuration_key, object configuration_result)
{
switch (configuration_key)
{
case "sim_UUID":
RegionID = (UUID) configuration_result;
originRegionID = (UUID) configuration_result;
break;
case "sim_name":
RegionName = (string) configuration_result;
break;
case "sim_location_x":
RegionLocX = (uint) configuration_result;
break;
case "sim_location_y":
RegionLocY = (uint) configuration_result;
break;
case "sim_size_x":
RegionSizeX = (uint) configuration_result;
break;
case "sim_size_y":
RegionSizeY = (uint) configuration_result;
break;
case "sim_size_z":
RegionSizeZ = (uint) configuration_result;
break;
case "datastore":
DataStore = (string) configuration_result;
break;
case "internal_ip_address":
IPAddress address = (IPAddress) configuration_result;
m_internalEndPoint = new IPEndPoint(address, 0);
break;
case "internal_ip_port":
m_internalEndPoint.Port = (int) configuration_result;
break;
case "allow_alternate_ports":
m_allow_alternate_ports = (bool) configuration_result;
break;
case "external_host_name":
if ((string) configuration_result != "SYSTEMIP")
{
m_externalHostName = (string) configuration_result;
}
else
{
m_externalHostName = Util.GetLocalHost().ToString();
}
break;
case "lastmap_uuid":
lastMapUUID = (UUID)configuration_result;
break;
case "lastmap_refresh":
lastMapRefresh = (string)configuration_result;
break;
case "nonphysical_prim_max":
m_nonphysPrimMax = (int)configuration_result;
break;
case "physical_prim_max":
m_physPrimMax = (int)configuration_result;
break;
case "clamp_prim_size":
m_clampPrimSize = (bool)configuration_result;
break;
case "object_capacity":
m_objectCapacity = (int)configuration_result;
break;
case "linkset_capacity":
m_linksetCapacity = (int)configuration_result;
break;
case "agent_capacity":
m_agentCapacity = (int)configuration_result;
break;
case "scope_id":
ScopeID = (UUID)configuration_result;
break;
case "region_type":
m_regionType = (string)configuration_result;
break;
case "region_static_maptile":
m_maptileStaticUUID = (UUID)configuration_result;
break;
}
return true;
}
>>>>>>> avn/ubitvar
public void SaveLastMapUUID(UUID mapUUID)
{
lastMapUUID = mapUUID;
@ -1004,5 +1251,28 @@ namespace OpenSim.Framework
regionInfo.ServerURI = serverURI;
return regionInfo;
}
public int getInternalEndPointPort()
{
return m_internalEndPoint.Port;
}
public Dictionary<string, object> ToKeyValuePairs()
{
Dictionary<string, object> kvp = new Dictionary<string, object>();
kvp["uuid"] = RegionID.ToString();
kvp["locX"] = RegionLocX.ToString();
kvp["locY"] = RegionLocY.ToString();
kvp["external_ip_address"] = ExternalEndPoint.Address.ToString();
kvp["external_port"] = ExternalEndPoint.Port.ToString();
kvp["external_host_name"] = ExternalHostName;
kvp["http_port"] = HttpPort.ToString();
kvp["internal_ip_address"] = InternalEndPoint.Address.ToString();
kvp["internal_port"] = InternalEndPoint.Port.ToString();
kvp["alternate_ports"] = m_allow_alternate_ports.ToString();
kvp["server_uri"] = ServerURI;
return kvp;
}
}
}

View File

@ -48,6 +48,9 @@ namespace OpenSim.Framework.RegionLoader.Web
public RegionInfo[] LoadRegions()
{
int tries = 3;
int wait = 2000;
if (m_configSource == null)
{
m_log.Error("[WEBLOADER]: Unable to load configuration source!");
@ -66,34 +69,59 @@ namespace OpenSim.Framework.RegionLoader.Web
}
else
{
RegionInfo[] regionInfos = new RegionInfo[] {};
int regionCount = 0;
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
webRequest.Timeout = 30000; //30 Second Timeout
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
while(tries > 0)
{
RegionInfo[] regionInfos = new RegionInfo[] {};
int regionCount = 0;
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
webRequest.Timeout = 30000; //30 Second Timeout
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
try
{
string xmlSource = String.Empty;
using (HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse())
{
m_log.Debug("[WEBLOADER]: Downloading region information...");
using (Stream s = webResponse.GetResponseStream())
try
{
HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse();
m_log.Debug("[WEBLOADER]: Downloading region information...");
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
string xmlSource = String.Empty;
string tempStr = reader.ReadLine();
while (tempStr != null)
{
xmlSource = xmlSource + tempStr;
tempStr = reader.ReadLine();
}
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
xmlSource.Length);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlSource);
if (xmlDoc.FirstChild.Name == "Nini")
{
using (StreamReader reader = new StreamReader(s))
{
string tempStr = reader.ReadLine();
while (tempStr != null)
{
xmlSource = xmlSource + tempStr;
tempStr = reader.ReadLine();
}
}
}
}
regionCount = xmlDoc.FirstChild.ChildNodes.Count;
if (regionCount > 0)
{
regionInfos = new RegionInfo[regionCount];
int i;
for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
{
m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
regionInfos[i] =
new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource);
}
}
}
}
catch (WebException ex)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
{
if (!allowRegionless)
throw ex;
}
else
throw ex;
}
<<<<<<< HEAD
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
xmlSource.Length);
XmlDocument xmlDoc = new XmlDocument();
@ -118,28 +146,22 @@ namespace OpenSim.Framework.RegionLoader.Web
catch (WebException ex)
{
using (HttpWebResponse response = (HttpWebResponse)ex.Response)
{
if (response.StatusCode == HttpStatusCode.NotFound)
{
if (!allowRegionless)
throw ex;
}
else
{
throw ex;
}
}
}
=======
if (regionCount > 0 | allowRegionless)
return regionInfos;
if (regionCount > 0 | allowRegionless)
{
return regionInfos;
}
else
{
m_log.Error("[WEBLOADER]: No region configs were available.");
return null;
}
m_log.Debug("[WEBLOADER]: Request yielded no regions.");
tries--;
if (tries > 0)
>>>>>>> avn/ubitvar
{
m_log.Debug("[WEBLOADER]: Retrying");
System.Threading.Thread.Sleep(wait);
}
}
m_log.Error("[WEBLOADER]: No region configs were available.");
return null;
}
}
}

View File

@ -482,6 +482,28 @@ namespace OpenSim.Framework
set { m_LoadedCreationID = value; }
}
private bool m_GodBlockSearch = false;
public bool GodBlockSearch
{
get { return m_GodBlockSearch; }
set { m_GodBlockSearch = value; }
}
private bool m_Casino = false;
public bool Casino
{
get { return m_Casino; }
set { m_Casino = value; }
}
// Telehub support
private bool m_TelehubEnabled = false;
public bool HasTelehub
{
get { return m_TelehubEnabled; }
set { m_TelehubEnabled = value; }
}
/// <summary>
/// Connected Telehub object
/// </summary>

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
/// server.
/// </summary>
<<<<<<< HEAD
private int m_periodDiagnosticTimerMS = 60 * 60 * 1000;
private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
=======
// private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
>>>>>>> avn/ubitvar
/// <summary>
/// Random uuid for private data
@ -84,6 +88,11 @@ namespace OpenSim.Framework.Servers
// Random uuid for private data
m_osSecret = UUID.Random().ToString();
<<<<<<< HEAD
=======
// m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
// m_periodicDiagnosticsTimer.Enabled = true;
>>>>>>> avn/ubitvar
}
/// <summary>
@ -147,13 +156,23 @@ namespace OpenSim.Framework.Servers
/// </summary>
public virtual void Startup()
{
m_log.Info("[STARTUP]: Beginning startup processing");
m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine);
// clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
// the clr version number doesn't match the project version number under Mono.
//m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);
m_log.InfoFormat(
"[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n",
Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32");
StartupSpecific();
TimeSpan timeTaken = DateTime.Now - m_startuptime;
MainConsole.Instance.OutputFormat(
"PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED. Non-script portion of startup took {0}m {1}s.",
timeTaken.Minutes, timeTaken.Seconds);
// MainConsole.Instance.OutputFormat(
// "PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED. Non-script portion of startup took {0}m {1}s.",
// timeTaken.Minutes, timeTaken.Seconds);
}
public string osSecret

View File

@ -403,6 +403,7 @@ namespace OpenSim.Framework.Servers.HttpServer
StreamReader reader = new StreamReader(requestStream, encoding);
string requestBody = reader.ReadToEnd();
reader.Close();
Hashtable keysvals = new Hashtable();
Hashtable headervals = new Hashtable();
@ -460,7 +461,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
resp.ReuseContext = true;
resp.ReuseContext = false;
HandleRequest(req, resp);
// !!!HACK ALERT!!!
@ -759,7 +760,7 @@ namespace OpenSim.Framework.Servers.HttpServer
// Every month or so this will wrap and give bad numbers, not really a problem
// since its just for reporting
int tickdiff = requestEndTick - requestStartTick;
if (tickdiff > 3000 && requestHandler != null && requestHandler.Name != "GetTexture")
if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture"))
{
m_log.InfoFormat(
"[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
@ -1024,6 +1025,19 @@ namespace OpenSim.Framework.Servers.HttpServer
string responseString = String.Empty;
XmlRpcRequest xmlRprcRequest = null;
bool gridproxy = false;
if (requestBody.Contains("encoding=\"utf-8"))
{
int channelindx = -1;
int optionsindx = requestBody.IndexOf(">options<");
if(optionsindx >0)
{
channelindx = requestBody.IndexOf(">channel<");
if (optionsindx < channelindx)
gridproxy = true;
}
}
try
{
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
@ -1081,6 +1095,8 @@ namespace OpenSim.Framework.Servers.HttpServer
}
xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3]
if (gridproxy)
xmlRprcRequest.Params.Add("gridproxy"); // Param[4]
try
{
xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint);
@ -1732,10 +1748,40 @@ namespace OpenSim.Framework.Servers.HttpServer
internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
{
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
int responsecode = (int)responsedata["int_response_code"];
string responseString = (string)responsedata["str_response_string"];
string contentType = (string)responsedata["content_type"];
int responsecode;
string responseString = String.Empty;
byte[] responseData = null;
string contentType;
if (responsedata == null)
{
responsecode = 500;
responseString = "No response could be obtained";
contentType = "text/plain";
responsedata = new Hashtable();
}
else
{
try
{
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
responsecode = (int)responsedata["int_response_code"];
if (responsedata["bin_response_data"] != null)
responseData = (byte[])responsedata["bin_response_data"];
else
responseString = (string)responsedata["str_response_string"];
contentType = (string)responsedata["content_type"];
if (responseString == null)
responseString = String.Empty;
}
catch
{
responsecode = 500;
responseString = "No response could be obtained";
contentType = "text/plain";
responsedata = new Hashtable();
}
}
if (responsedata.ContainsKey("error_status_text"))
{
@ -1780,25 +1826,40 @@ namespace OpenSim.Framework.Servers.HttpServer
response.AddHeader("Content-Type", contentType);
if (responsedata.ContainsKey("headers"))
{
Hashtable headerdata = (Hashtable)responsedata["headers"];
foreach (string header in headerdata.Keys)
response.AddHeader(header, (string)headerdata[header]);
}
byte[] buffer;
if (!(contentType.Contains("image")
|| contentType.Contains("x-shockwave-flash")
|| contentType.Contains("application/x-oar")
|| contentType.Contains("application/vnd.ll.mesh")))
if (responseData != null)
{
// Text
buffer = Encoding.UTF8.GetBytes(responseString);
buffer = responseData;
}
else
{
// Binary!
buffer = Convert.FromBase64String(responseString);
}
if (!(contentType.Contains("image")
|| contentType.Contains("x-shockwave-flash")
|| contentType.Contains("application/x-oar")
|| contentType.Contains("application/vnd.ll.mesh")))
{
// Text
buffer = Encoding.UTF8.GetBytes(responseString);
}
else
{
// Binary!
buffer = Convert.FromBase64String(responseString);
}
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
}
return buffer;
}
@ -1886,9 +1947,14 @@ namespace OpenSim.Framework.Servers.HttpServer
m_httpListener2.Start(64);
// Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
<<<<<<< HEAD
PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000);
PollServiceRequestManager.Start();
=======
m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000);
m_PollServiceManager.Start();
>>>>>>> avn/ubitvar
HTTPDRunning = true;
//HttpListenerContext context;
@ -1937,7 +2003,9 @@ namespace OpenSim.Framework.Servers.HttpServer
public void httpServerException(object source, Exception exception)
{
m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception);
if (source.ToString() == "HttpServer.HttpListener" && exception.ToString().StartsWith("Mono.Security.Protocol.Tls.TlsException"))
return;
m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
/*
if (HTTPDRunning)// && NotSocketErrors > 5)
{
@ -1984,6 +2052,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public void RemoveHTTPHandler(string httpMethod, string path)
{
if (path == null) return; // Caps module isn't loaded, tries to remove handler where path = null
lock (m_HTTPHandlers)
{
if (httpMethod != null && httpMethod.Length == 0)

View File

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

View File

@ -27,6 +27,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using HttpServer;
@ -44,6 +45,24 @@ namespace OpenSim.Framework.Servers.HttpServer
public readonly IHttpRequest Request;
public readonly int RequestTime;
public readonly UUID RequestID;
public int contextHash;
private void GenContextHash()
{
Random rnd = new Random();
contextHash = 0;
if (Request.Headers["remote_addr"] != null)
contextHash = (Request.Headers["remote_addr"]).GetHashCode() << 16;
else
contextHash = rnd.Next() << 16;
if (Request.Headers["remote_port"] != null)
{
string[] strPorts = Request.Headers["remote_port"].Split(new char[] { ',' });
contextHash += Int32.Parse(strPorts[0]);
}
else
contextHash += rnd.Next() & 0xffff;
}
public PollServiceHttpRequest(
PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
@ -53,6 +72,7 @@ namespace OpenSim.Framework.Servers.HttpServer
Request = pRequest;
RequestTime = System.Environment.TickCount;
RequestID = UUID.Random();
GenContextHash();
}
internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
@ -65,6 +85,7 @@ namespace OpenSim.Framework.Servers.HttpServer
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
response.ReuseContext = false;
try
{
@ -93,5 +114,44 @@ namespace OpenSim.Framework.Servers.HttpServer
PollServiceArgs.RequestsHandled++;
}
}
internal void DoHTTPstop(BaseHttpServer server)
{
OSHttpResponse response
= new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
response.SendChunked = false;
response.ContentLength64 = 0;
response.ContentEncoding = Encoding.UTF8;
response.ReuseContext = false;
response.KeepAlive = false;
response.SendChunked = false;
response.StatusCode = 503;
try
{
response.OutputStream.Flush();
response.Send();
}
catch (Exception e)
{
}
}
}
class PollServiceHttpRequestComparer : IEqualityComparer<PollServiceHttpRequest>
{
public bool Equals(PollServiceHttpRequest b1, PollServiceHttpRequest b2)
{
if (b1.contextHash != b2.contextHash)
return false;
bool b = Object.ReferenceEquals(b1.HttpContext, b2.HttpContext);
return b;
}
public int GetHashCode(PollServiceHttpRequest b2)
{
return (int)b2.contextHash;
}
}
}

View File

@ -65,15 +65,25 @@ namespace OpenSim.Framework.Servers.HttpServer
private readonly BaseHttpServer m_server;
private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext;
private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
private static List<PollServiceHttpRequest> m_longPollRequests = new List<PollServiceHttpRequest>();
private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>();
private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>();
private uint m_WorkerThreadCount = 0;
private Thread[] m_workerThreads;
private Thread m_retrysThread;
<<<<<<< HEAD
private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2);
// private int m_timeout = 1000; // increase timeout 250; now use the event one
=======
private bool m_running = true;
private int slowCount = 0;
private SmartThreadPool m_threadPool;
>>>>>>> avn/ubitvar
public PollServiceRequestManager(
BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout)
@ -83,6 +93,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_WorkerThreadCount = pWorkerThreadCount;
m_workerThreads = new Thread[m_WorkerThreadCount];
<<<<<<< HEAD
StatsManager.RegisterStat(
new Stat(
"QueuedPollResponses",
@ -108,10 +119,25 @@ namespace OpenSim.Framework.Servers.HttpServer
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = ResponsesProcessed,
StatVerbosity.Debug));
=======
PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer();
m_bycontext = new Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>>(preqCp);
STPStartInfo startInfo = new STPStartInfo();
startInfo.IdleTimeout = 30000;
startInfo.MaxWorkerThreads = 15;
startInfo.MinWorkerThreads = 1;
startInfo.ThreadPriority = ThreadPriority.Normal;
startInfo.StartSuspended = true;
startInfo.ThreadPoolName = "PoolService";
m_threadPool = new SmartThreadPool(startInfo);
>>>>>>> avn/ubitvar
}
public void Start()
{
<<<<<<< HEAD
IsRunning = true;
if (PerformResponsesAsync)
@ -139,40 +165,100 @@ namespace OpenSim.Framework.Servers.HttpServer
null,
1000 * 60 * 10);
}
=======
m_threadPool.Start();
//startup worker threads
for (uint i = 0; i < m_WorkerThreadCount; i++)
{
m_workerThreads[i]
= Watchdog.StartThread(
PoolWorkerJob,
string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port),
ThreadPriority.Normal,
false,
false,
null,
int.MaxValue);
}
m_retrysThread = Watchdog.StartThread(
this.CheckRetries,
string.Format("PollServiceWatcherThread:{0}", m_server.Port),
ThreadPriority.Normal,
false,
true,
null,
1000 * 60 * 10);
>>>>>>> avn/ubitvar
}
private void ReQueueEvent(PollServiceHttpRequest req)
{
if (IsRunning)
{
// delay the enqueueing for 100ms. There's no need to have the event
// actively on the queue
Timer t = new Timer(self => {
((Timer)self).Dispose();
m_requests.Enqueue(req);
});
t.Change(100, Timeout.Infinite);
lock (m_retryRequests)
m_retryRequests.Enqueue(req);
}
}
public void Enqueue(PollServiceHttpRequest req)
{
if (IsRunning)
lock (m_bycontext)
{
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll)
Queue<PollServiceHttpRequest> ctxQeueue;
if (m_bycontext.TryGetValue(req, out ctxQeueue))
{
lock (m_longPollRequests)
m_longPollRequests.Add(req);
ctxQeueue.Enqueue(req);
}
else
m_requests.Enqueue(req);
{
ctxQeueue = new Queue<PollServiceHttpRequest>();
m_bycontext[req] = ctxQeueue;
EnqueueInt(req);
}
}
}
private void CheckLongPollThreads()
public void byContextDequeue(PollServiceHttpRequest req)
{
Queue<PollServiceHttpRequest> ctxQeueue;
lock (m_bycontext)
{
if (m_bycontext.TryGetValue(req, out ctxQeueue))
{
if (ctxQeueue.Count > 0)
{
PollServiceHttpRequest newreq = ctxQeueue.Dequeue();
EnqueueInt(newreq);
}
else
{
m_bycontext.Remove(req);
}
}
}
}
public void EnqueueInt(PollServiceHttpRequest req)
{
if (IsRunning)
{
if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll)
{
m_requests.Enqueue(req);
}
else
{
lock (m_slowRequests)
m_slowRequests.Enqueue(req);
}
}
}
private void CheckRetries()
{
<<<<<<< HEAD
// The only purpose of this thread is to check the EQs for events.
// If there are events, that thread will be placed in the "ready-to-serve" queue, m_requests.
// If there are no events, that thread will be back to its "waiting" queue, m_longPollRequests.
@ -180,13 +266,15 @@ namespace OpenSim.Framework.Servers.HttpServer
// so if they aren't ready to be served by a worker thread (no events), they are placed
// directly back in the "ready-to-serve" queue by the worker thread.
while (IsRunning)
=======
while (m_running)
>>>>>>> avn/ubitvar
{
Thread.Sleep(500);
Thread.Sleep(100); // let the world move .. back to faster rate
Watchdog.UpdateThread();
// List<PollServiceHttpRequest> not_ready = new List<PollServiceHttpRequest>();
lock (m_longPollRequests)
lock (m_retryRequests)
{
<<<<<<< HEAD
if (m_longPollRequests.Count > 0 && IsRunning)
{
List<PollServiceHttpRequest> ready = m_longPollRequests.FindAll(req =>
@ -199,28 +287,67 @@ namespace OpenSim.Framework.Servers.HttpServer
m_requests.Enqueue(req);
m_longPollRequests.Remove(req);
});
=======
while (m_retryRequests.Count > 0 && m_running)
m_requests.Enqueue(m_retryRequests.Dequeue());
}
slowCount++;
if (slowCount >= 10)
{
slowCount = 0;
>>>>>>> avn/ubitvar
lock (m_slowRequests)
{
while (m_slowRequests.Count > 0 && m_running)
m_requests.Enqueue(m_slowRequests.Dequeue());
}
}
}
}
public void Stop()
{
<<<<<<< HEAD
IsRunning = false;
// m_timeout = -10000; // cause all to expire
=======
m_running = false;
>>>>>>> avn/ubitvar
Thread.Sleep(1000); // let the world move
foreach (Thread t in m_workerThreads)
Watchdog.AbortThread(t.ManagedThreadId);
PollServiceHttpRequest wreq;
// any entry in m_bycontext should have a active request on the other queues
// so just delete contents to easy GC
foreach (Queue<PollServiceHttpRequest> qu in m_bycontext.Values)
qu.Clear();
m_bycontext.Clear();
lock (m_longPollRequests)
try
{
foreach (PollServiceHttpRequest req in m_retryRequests)
{
req.DoHTTPstop(m_server);
}
}
catch
{
}
PollServiceHttpRequest wreq;
m_retryRequests.Clear();
lock (m_slowRequests)
{
<<<<<<< HEAD
if (m_longPollRequests.Count > 0 && IsRunning)
m_longPollRequests.ForEach(req => m_requests.Enqueue(req));
=======
while (m_slowRequests.Count > 0)
m_requests.Enqueue(m_slowRequests.Dequeue());
>>>>>>> avn/ubitvar
}
while (m_requests.Count() > 0)
@ -228,16 +355,19 @@ namespace OpenSim.Framework.Servers.HttpServer
try
{
wreq = m_requests.Dequeue(0);
<<<<<<< HEAD
ResponsesProcessed++;
wreq.DoHTTPGruntWork(
m_server, wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id));
=======
wreq.DoHTTPstop(m_server);
>>>>>>> avn/ubitvar
}
catch
{
}
}
m_longPollRequests.Clear();
m_requests.Clear();
}
@ -247,6 +377,11 @@ namespace OpenSim.Framework.Servers.HttpServer
{
while (IsRunning)
{
<<<<<<< HEAD
=======
PollServiceHttpRequest req = m_requests.Dequeue(5000);
>>>>>>> avn/ubitvar
Watchdog.UpdateThread();
WaitPerformResponse();
}
@ -265,6 +400,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
<<<<<<< HEAD
if (responsedata == null)
return;
@ -287,11 +423,15 @@ namespace OpenSim.Framework.Servers.HttpServer
else
{
m_threadPool.QueueWorkItem(x =>
=======
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
>>>>>>> avn/ubitvar
{
try
{
ResponsesProcessed++;
req.DoHTTPGruntWork(m_server, responsedata);
byContextDequeue(req);
}
catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream
{
@ -300,6 +440,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
catch (Exception e)
{
<<<<<<< HEAD
m_log.Error(e);
}
@ -318,6 +459,34 @@ namespace OpenSim.Framework.Servers.HttpServer
else
{
ReQueueEvent(req);
=======
try
{
req.DoHTTPGruntWork(m_server, responsedata);
byContextDequeue(req);
}
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
{
// Ignore it, no need to reply
}
return null;
}, null);
}
}
else
{
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
{
req.DoHTTPGruntWork(m_server,
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
byContextDequeue(req);
}
else
{
ReQueueEvent(req);
}
>>>>>>> avn/ubitvar
}
}
}
@ -327,5 +496,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
}
}
}
}

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

View File

@ -41,7 +41,331 @@ namespace OpenSim.Framework.Servers.Tests
{
[TestFixture]
public class OSHttpTests : OpenSimTestCase
<<<<<<< HEAD
{
=======
{
// we need an IHttpClientContext for our tests
public class TestHttpClientContext: IHttpClientContext
{
private bool _secured;
public bool IsSecured
{
get { return _secured; }
}
public bool Secured
{
get { return _secured; }
}
public TestHttpClientContext(bool secured)
{
_secured = secured;
}
public void Disconnect(SocketError error) {}
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body) {}
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason) {}
public void Respond(string body) {}
public void Send(byte[] buffer) {}
public void Send(byte[] buffer, int offset, int size) {}
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body, string contentType) {}
public void Close() { }
public bool EndWhenDone { get { return false;} set { return;}}
public HTTPNetworkContext GiveMeTheNetworkStreamIKnowWhatImDoing()
{
return new HTTPNetworkContext();
}
public event EventHandler<DisconnectedEventArgs> Disconnected = delegate { };
/// <summary>
/// A request have been received in the context.
/// </summary>
public event EventHandler<RequestEventArgs> RequestReceived = delegate { };
public bool CanSend { get { return true; } }
public string RemoteEndPoint { get { return ""; } }
public string RemoteEndPointAddress { get { return ""; } }
public string RemoteEndPointPort { get { return ""; } }
}
public class TestHttpRequest: IHttpRequest
{
private string _uriPath;
public bool BodyIsComplete
{
get { return true; }
}
public string[] AcceptTypes
{
get {return _acceptTypes; }
}
private string[] _acceptTypes;
public Stream Body
{
get { return _body; }
set { _body = value;}
}
private Stream _body;
public ConnectionType Connection
{
get { return _connection; }
set { _connection = value; }
}
private ConnectionType _connection;
public int ContentLength
{
get { return _contentLength; }
set { _contentLength = value; }
}
private int _contentLength;
public NameValueCollection Headers
{
get { return _headers; }
}
private NameValueCollection _headers = new NameValueCollection();
public string HttpVersion
{
get { return _httpVersion; }
set { _httpVersion = value; }
}
private string _httpVersion = null;
public string Method
{
get { return _method; }
set { _method = value; }
}
private string _method = null;
public HttpInput QueryString
{
get { return _queryString; }
}
private HttpInput _queryString = null;
public Uri Uri
{
get { return _uri; }
set { _uri = value; }
}
private Uri _uri = null;
public string[] UriParts
{
get { return _uri.Segments; }
}
public HttpParam Param
{
get { return null; }
}
public HttpForm Form
{
get { return null; }
}
public bool IsAjax
{
get { return false; }
}
public RequestCookies Cookies
{
get { return null; }
}
public TestHttpRequest() {}
public TestHttpRequest(string contentEncoding, string contentType, string userAgent,
string remoteAddr, string remotePort, string[] acceptTypes,
ConnectionType connectionType, int contentLength, Uri uri)
{
_headers["content-encoding"] = contentEncoding;
_headers["content-type"] = contentType;
_headers["user-agent"] = userAgent;
_headers["remote_addr"] = remoteAddr;
_headers["remote_port"] = remotePort;
_acceptTypes = acceptTypes;
_connection = connectionType;
_contentLength = contentLength;
_uri = uri;
}
public void DecodeBody(FormDecoderProvider providers) {}
public void SetCookies(RequestCookies cookies) {}
public void AddHeader(string name, string value)
{
_headers.Add(name, value);
}
public int AddToBody(byte[] bytes, int offset, int length)
{
return 0;
}
public void Clear() {}
public object Clone()
{
TestHttpRequest clone = new TestHttpRequest();
clone._acceptTypes = _acceptTypes;
clone._connection = _connection;
clone._contentLength = _contentLength;
clone._uri = _uri;
clone._headers = new NameValueCollection(_headers);
return clone;
}
public IHttpResponse CreateResponse(IHttpClientContext context)
{
return new HttpResponse(context, this);
}
/// <summary>
/// Path and query (will be merged with the host header) and put in Uri
/// </summary>
/// <see cref="Uri"/>
public string UriPath
{
get { return _uriPath; }
set
{
_uriPath = value;
}
}
}
public class TestHttpResponse: IHttpResponse
{
public Stream Body
{
get { return _body; }
set { _body = value; }
}
private Stream _body;
public string ProtocolVersion
{
get { return _protocolVersion; }
set { _protocolVersion = value; }
}
private string _protocolVersion;
public bool Chunked
{
get { return _chunked; }
set { _chunked = value; }
}
private bool _chunked;
public ConnectionType Connection
{
get { return _connection; }
set { _connection = value; }
}
private ConnectionType _connection;
public Encoding Encoding
{
get { return _encoding; }
set { _encoding = value; }
}
private Encoding _encoding;
public int KeepAlive
{
get { return _keepAlive; }
set { _keepAlive = value; }
}
private int _keepAlive;
public HttpStatusCode Status
{
get { return _status; }
set { _status = value; }
}
private HttpStatusCode _status;
public string Reason
{
get { return _reason; }
set { _reason = value; }
}
private string _reason;
public long ContentLength
{
get { return _contentLength; }
set { _contentLength = value; }
}
private long _contentLength;
public string ContentType
{
get { return _contentType; }
set { _contentType = value; }
}
private string _contentType;
public bool HeadersSent
{
get { return _headersSent; }
}
private bool _headersSent;
public bool Sent
{
get { return _sent; }
}
private bool _sent;
public ResponseCookies Cookies
{
get { return _cookies; }
}
private ResponseCookies _cookies = null;
public TestHttpResponse()
{
_headersSent = false;
_sent = false;
}
public void AddHeader(string name, string value) {}
public void Send()
{
if (!_headersSent) SendHeaders();
if (_sent) throw new InvalidOperationException("stuff already sent");
_sent = true;
}
public void SendBody(byte[] buffer, int offset, int count)
{
if (!_headersSent) SendHeaders();
_sent = true;
}
public void SendBody(byte[] buffer)
{
if (!_headersSent) SendHeaders();
_sent = true;
}
public void SendHeaders()
{
if (_headersSent) throw new InvalidOperationException("headers already sent");
_headersSent = true;
}
public void Redirect(Uri uri) {}
public void Redirect(string url) {}
}
>>>>>>> avn/ubitvar
public OSHttpRequest req0;
public OSHttpRequest req1;

View File

@ -27,9 +27,13 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Reflection;
using System.Xml;
using System.Diagnostics;
using System.Xml.Schema;
using System.Xml.Serialization;
using log4net;
using OpenMetaverse;
namespace OpenSim.Framework
@ -47,6 +51,180 @@ namespace OpenSim.Framework
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem));
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Thread LockedByThread;
// private string WriterStack;
// private Dictionary<Thread, string> ReadLockers =
// new Dictionary<Thread, string>();
/// <value>
/// An advanced lock for inventory data
/// </value>
private volatile System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
/// <summary>
/// Are we readlocked by the calling thread?
/// </summary>
public bool IsReadLockedByMe()
{
if (m_itemLock.RecursiveReadCount > 0)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// Lock our inventory list for reading (many can read, one can write)
/// </summary>
public void LockItemsForRead(bool locked)
{
if (locked)
{
if (m_itemLock.IsWriteLockHeld && LockedByThread != null)
{
if (!LockedByThread.IsAlive)
{
//Locked by dead thread, reset.
m_itemLock = new System.Threading.ReaderWriterLockSlim();
}
}
if (m_itemLock.RecursiveReadCount > 0)
{
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
try
{
// That call stack is useful for end users only. RealProgrammers need a full dump. Commented.
// StackTrace stackTrace = new StackTrace(); // get call stack
// StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
//
// // write call stack method names
// foreach (StackFrame stackFrame in stackFrames)
// {
// m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name
// }
// The below is far more useful
// System.Console.WriteLine("------------------------------------------");
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
// System.Console.WriteLine("------------------------------------------");
// foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
// {
// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
// System.Console.WriteLine("------------------------------------------");
// }
}
catch
{}
m_itemLock.ExitReadLock();
}
if (m_itemLock.RecursiveWriteCount > 0)
{
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
// try
// {
// System.Console.WriteLine("------------------------------------------");
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
// System.Console.WriteLine("------------------------------------------");
// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
// System.Console.WriteLine("------------------------------------------");
// }
// catch
// {}
m_itemLock.ExitWriteLock();
}
while (!m_itemLock.TryEnterReadLock(60000))
{
m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
//if (m_itemLock.IsWriteLockHeld)
//{
m_itemLock = new System.Threading.ReaderWriterLockSlim();
// System.Console.WriteLine("------------------------------------------");
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
// System.Console.WriteLine("------------------------------------------");
// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
// System.Console.WriteLine("------------------------------------------");
// LockedByThread = null;
// ReadLockers.Clear();
//}
}
// ReadLockers[Thread.CurrentThread] = Environment.StackTrace;
}
else
{
if (m_itemLock.RecursiveReadCount>0)
{
m_itemLock.ExitReadLock();
}
// if (m_itemLock.RecursiveReadCount == 0)
// ReadLockers.Remove(Thread.CurrentThread);
}
}
/// <summary>
/// Lock our inventory list for writing (many can read, one can write)
/// </summary>
public void LockItemsForWrite(bool locked)
{
if (locked)
{
//Enter a write lock, wait indefinately for one to open.
if (m_itemLock.RecursiveReadCount > 0)
{
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
m_itemLock.ExitReadLock();
}
if (m_itemLock.RecursiveWriteCount > 0)
{
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
m_itemLock.ExitWriteLock();
}
while (!m_itemLock.TryEnterWriteLock(60000))
{
if (m_itemLock.IsWriteLockHeld)
{
m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
// System.Console.WriteLine("------------------------------------------");
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
// System.Console.WriteLine("------------------------------------------");
// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
// System.Console.WriteLine("------------------------------------------");
}
else
{
m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
// System.Console.WriteLine("------------------------------------------");
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
// System.Console.WriteLine("------------------------------------------");
// foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
// {
// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
// System.Console.WriteLine("------------------------------------------");
// }
}
m_itemLock = new System.Threading.ReaderWriterLockSlim();
// ReadLockers.Clear();
}
LockedByThread = Thread.CurrentThread;
// WriterStack = Environment.StackTrace;
}
else
{
if (m_itemLock.RecursiveWriteCount > 0)
{
m_itemLock.ExitWriteLock();
}
}
}
#region ICloneable Members
@ -54,13 +232,12 @@ namespace OpenSim.Framework
{
TaskInventoryDictionary clone = new TaskInventoryDictionary();
lock (this)
m_itemLock.EnterReadLock();
foreach (UUID uuid in Keys)
{
foreach (UUID uuid in Keys)
{
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
}
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
}
m_itemLock.ExitReadLock();
return clone;
}

View File

@ -28,6 +28,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using OpenMetaverse;
@ -48,6 +49,7 @@ namespace OpenSim.Framework
public abstract float this[int x, int y] { get; set; }
// Someday terrain will have caves
// at most holes :p
public abstract float this[int x, int y, int z] { get; set; }
public abstract bool IsTaintedAt(int xx, int yy);
@ -72,8 +74,8 @@ namespace OpenSim.Framework
return new HeightmapTerrainData(pSizeX, pSizeY, pSizeZ, pFormatCode, pBlob);
}
// return a special compressed representation of the heightmap in ints
public abstract int[] GetCompressedMap();
// return a special compressed representation of the heightmap in ushort
public abstract float[] GetCompressedMap();
public abstract float CompressionFactor { get; }
public abstract float[] GetFloatsSerialized();
@ -94,14 +96,18 @@ namespace OpenSim.Framework
{
// Terrain is 'double[256,256]'
Legacy256 = 11,
// Terrain is 'int32, int32, float[,]' where the ints are X and Y dimensions
// The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
Variable2D = 22,
Variable2DGzip = 23,
// Terrain is 'int32, int32, int32, int16[]' where the ints are X and Y dimensions
// and third int is the 'compression factor'. The heights are compressed as
// "int compressedHeight = (int)(height * compressionFactor);"
// "ushort compressedHeight = (ushort)(height * compressionFactor);"
// The dimensions are presumed to be multiples of 16 and, more likely, multiples of 256.
Compressed2D = 27,
// A revision that is not listed above or any revision greater than this value is 'Legacy256'.
RevisionHigh = 1234
}
@ -109,7 +115,7 @@ namespace OpenSim.Framework
// Version of terrain that is a heightmap.
// This should really be 'LLOptimizedHeightmapTerrainData' as it includes knowledge
// of 'patches' which are 16x16 terrain areas which can be sent separately to the viewer.
// The heighmap is kept as an array of integers. The integer values are converted to
// The heighmap is kept as an array of ushorts. The ushort values are converted to
// and from floats by TerrainCompressionFactor.
public class HeightmapTerrainData : TerrainData
{
@ -119,12 +125,12 @@ namespace OpenSim.Framework
// TerrainData.this[x, y]
public override float this[int x, int y]
{
get { return FromCompressedHeight(m_heightmap[x, y]); }
set {
int newVal = ToCompressedHeight(value);
if (m_heightmap[x, y] != newVal)
get { return m_heightmap[x, y]; }
set
{
if (m_heightmap[x, y] != value)
{
m_heightmap[x, y] = newVal;
m_heightmap[x, y] = value;
m_taint[x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize] = true;
}
}
@ -164,10 +170,9 @@ namespace OpenSim.Framework
// TerrainData.ClearLand(float)
public override void ClearLand(float pHeight)
{
int flatHeight = ToCompressedHeight(pHeight);
for (int xx = 0; xx < SizeX; xx++)
for (int yy = 0; yy < SizeY; yy++)
m_heightmap[xx, yy] = flatHeight;
m_heightmap[xx, yy] = pHeight;
}
// Return 'true' of the patch that contains these region coordinates has been modified.
@ -177,13 +182,15 @@ namespace OpenSim.Framework
{
int tx = xx / Constants.TerrainPatchSize;
int ty = yy / Constants.TerrainPatchSize;
bool ret = m_taint[tx, ty];
bool ret = m_taint[tx, ty];
if (ret && clearOnTest)
m_taint[tx, ty] = false;
return ret;
}
// Old form that clears the taint flag when we check it.
// ubit: this dangerus naming should be only check without clear
// keeping for old modules outthere
public override bool IsTaintedAt(int xx, int yy)
{
return IsTaintedAt(xx, yy, true /* clearOnTest */);
@ -202,8 +209,10 @@ namespace OpenSim.Framework
}
else
{
DBRevisionCode = (int)DBTerrainRevision.Compressed2D;
blob = ToCompressedTerrainSerialization();
DBRevisionCode = (int)DBTerrainRevision.Variable2DGzip;
// DBRevisionCode = (int)DBTerrainRevision.Variable2D;
blob = ToCompressedTerrainSerializationV2DGzip();
// blob = ToCompressedTerrainSerializationV2D();
ret = true;
}
return ret;
@ -214,9 +223,9 @@ namespace OpenSim.Framework
public override float CompressionFactor { get { return m_compressionFactor; } }
// TerrainData.GetCompressedMap
public override int[] GetCompressedMap()
public override float[] GetCompressedMap()
{
int[] newMap = new int[SizeX * SizeY];
float[] newMap = new float[SizeX * SizeY];
int ind = 0;
for (int xx = 0; xx < SizeX; xx++)
@ -230,7 +239,7 @@ namespace OpenSim.Framework
public override TerrainData Clone()
{
HeightmapTerrainData ret = new HeightmapTerrainData(SizeX, SizeY, SizeZ);
ret.m_heightmap = (int[,])this.m_heightmap.Clone();
ret.m_heightmap = (float[,])this.m_heightmap.Clone();
return ret;
}
@ -247,7 +256,7 @@ namespace OpenSim.Framework
for (int jj = 0; jj < SizeY; jj++)
for (int ii = 0; ii < SizeX; ii++)
{
heights[idx++] = FromCompressedHeight(m_heightmap[ii, jj]);
heights[idx++] = m_heightmap[ii, jj];
}
return heights;
@ -259,7 +268,7 @@ namespace OpenSim.Framework
double[,] ret = new double[SizeX, SizeY];
for (int xx = 0; xx < SizeX; xx++)
for (int yy = 0; yy < SizeY; yy++)
ret[xx, yy] = FromCompressedHeight(m_heightmap[xx, yy]);
ret[xx, yy] = (double)m_heightmap[xx, yy];
return ret;
}
@ -267,19 +276,40 @@ namespace OpenSim.Framework
// =============================================================
private int[,] m_heightmap;
private float[,] m_heightmap;
// Remember subregions of the heightmap that has changed.
private bool[,] m_taint;
// To save space (especially for large regions), keep the height as a short integer
// that is coded as the float height times the compression factor (usually '100'
// to make for two decimal points).
public int ToCompressedHeight(double pHeight)
public short ToCompressedHeightshort(float pHeight)
{
return (int)(pHeight * CompressionFactor);
// clamp into valid range
pHeight *= CompressionFactor;
if (pHeight < short.MinValue)
return short.MinValue;
else if (pHeight > short.MaxValue)
return short.MaxValue;
return (short)pHeight;
}
public float FromCompressedHeight(int pHeight)
public ushort ToCompressedHeightushort(float pHeight)
{
// clamp into valid range
pHeight *= CompressionFactor;
if (pHeight < ushort.MinValue)
return ushort.MinValue;
else if (pHeight > ushort.MaxValue)
return ushort.MaxValue;
return (ushort)pHeight;
}
public float FromCompressedHeight(short pHeight)
{
return ((float)pHeight) / CompressionFactor;
}
public float FromCompressedHeight(ushort pHeight)
{
return ((float)pHeight) / CompressionFactor;
}
@ -293,12 +323,12 @@ namespace OpenSim.Framework
SizeZ = (int)Constants.RegionHeight;
m_compressionFactor = 100.0f;
m_heightmap = new int[SizeX, SizeY];
m_heightmap = new float[SizeX, SizeY];
for (int ii = 0; ii < SizeX; ii++)
{
for (int jj = 0; jj < SizeY; jj++)
{
m_heightmap[ii, jj] = ToCompressedHeight(pTerrain[ii, jj]);
m_heightmap[ii, jj] = (float)pTerrain[ii, jj];
}
}
@ -315,14 +345,15 @@ namespace OpenSim.Framework
SizeY = pY;
SizeZ = pZ;
m_compressionFactor = 100.0f;
m_heightmap = new int[SizeX, SizeY];
m_heightmap = new float[SizeX, SizeY];
m_taint = new bool[SizeX / Constants.TerrainPatchSize, SizeY / Constants.TerrainPatchSize];
// m_log.DebugFormat("{0} new by dimensions. sizeX={1}, sizeY={2}, sizeZ={3}", LogHeader, SizeX, SizeY, SizeZ);
ClearTaint();
ClearLand(0f);
}
public HeightmapTerrainData(int[] cmap, float pCompressionFactor, int pX, int pY, int pZ) : this(pX, pY, pZ)
public HeightmapTerrainData(float[] cmap, float pCompressionFactor, int pX, int pY, int pZ)
: this(pX, pY, pZ)
{
m_compressionFactor = pCompressionFactor;
int ind = 0;
@ -333,12 +364,22 @@ namespace OpenSim.Framework
}
// Create a heighmap from a database blob
public HeightmapTerrainData(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob) : this(pSizeX, pSizeY, pSizeZ)
public HeightmapTerrainData(int pSizeX, int pSizeY, int pSizeZ, int pFormatCode, byte[] pBlob)
: this(pSizeX, pSizeY, pSizeZ)
{
switch ((DBTerrainRevision)pFormatCode)
{
case DBTerrainRevision.Variable2DGzip:
FromCompressedTerrainSerializationV2DGZip(pBlob);
m_log.DebugFormat("{0} HeightmapTerrainData create from Variable2DGzip serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
break;
case DBTerrainRevision.Variable2D:
FromCompressedTerrainSerializationV2D(pBlob);
m_log.DebugFormat("{0} HeightmapTerrainData create from Variable2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
break;
case DBTerrainRevision.Compressed2D:
FromCompressedTerrainSerialization(pBlob);
FromCompressedTerrainSerialization2D(pBlob);
m_log.DebugFormat("{0} HeightmapTerrainData create from Compressed2D serialization. Size=<{1},{2}>", LogHeader, SizeX, SizeY);
break;
default:
@ -373,50 +414,116 @@ namespace OpenSim.Framework
return ret;
}
// Just create an array of doubles. Presumes the caller implicitly knows the size.
// Presumes the caller implicitly knows the size.
public void FromLegacyTerrainSerialization(byte[] pBlob)
{
// In case database info doesn't match real terrain size, initialize the whole terrain.
ClearLand();
using (MemoryStream mstr = new MemoryStream(pBlob))
try
{
using (BinaryReader br = new BinaryReader(mstr))
using (MemoryStream mstr = new MemoryStream(pBlob))
{
for (int xx = 0; xx < (int)Constants.RegionSize; xx++)
using (BinaryReader br = new BinaryReader(mstr))
{
for (int yy = 0; yy < (int)Constants.RegionSize; yy++)
for (int xx = 0; xx < (int)Constants.RegionSize; xx++)
{
float val = (float)br.ReadDouble();
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = ToCompressedHeight(val);
for (int yy = 0; yy < (int)Constants.RegionSize; yy++)
{
float val = (float)br.ReadDouble();
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = val;
}
}
}
}
ClearTaint();
}
catch
{
ClearLand();
}
ClearTaint();
}
// See the reader below.
public Array ToCompressedTerrainSerialization()
// stores as variable2D
// int32 sizeX
// int32 sizeY
// float[,] array
public Array ToCompressedTerrainSerializationV2D()
{
Array ret = null;
using (MemoryStream str = new MemoryStream((3 * sizeof(Int32)) + (SizeX * SizeY * sizeof(Int16))))
try
{
using (BinaryWriter bw = new BinaryWriter(str))
using (MemoryStream str = new MemoryStream((2 * sizeof(Int32)) + (SizeX * SizeY * sizeof(float))))
{
bw.Write((Int32)DBTerrainRevision.Compressed2D);
bw.Write((Int32)SizeX);
bw.Write((Int32)SizeY);
bw.Write((Int32)CompressionFactor);
for (int yy = 0; yy < SizeY; yy++)
for (int xx = 0; xx < SizeX; xx++)
{
bw.Write((Int16)m_heightmap[xx, yy]);
}
using (BinaryWriter bw = new BinaryWriter(str))
{
bw.Write((Int32)SizeX);
bw.Write((Int32)SizeY);
for (int yy = 0; yy < SizeY; yy++)
for (int xx = 0; xx < SizeX; xx++)
{
// reduce to 1cm resolution
float val = (float)Math.Round(m_heightmap[xx, yy],2,MidpointRounding.ToEven);
bw.Write(val);
}
}
ret = str.ToArray();
}
ret = str.ToArray();
}
catch
{
}
m_log.DebugFormat("{0} V2D {1} bytes",
LogHeader, ret.Length);
return ret;
}
// as above with Gzip compression
public Array ToCompressedTerrainSerializationV2DGzip()
{
Array ret = null;
try
{
using (MemoryStream inp = new MemoryStream((2 * sizeof(Int32)) + (SizeX * SizeY * sizeof(float))))
{
using (BinaryWriter bw = new BinaryWriter(inp))
{
bw.Write((Int32)SizeX);
bw.Write((Int32)SizeY);
for (int yy = 0; yy < SizeY; yy++)
for (int xx = 0; xx < SizeX; xx++)
{
bw.Write((float)m_heightmap[xx, yy]);
}
bw.Flush();
inp.Seek(0, SeekOrigin.Begin);
using (MemoryStream outputStream = new MemoryStream())
{
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress))
{
inp.CopyStream(compressionStream, int.MaxValue);
compressionStream.Close();
ret = outputStream.ToArray();
}
}
}
}
}
catch
{
}
m_log.DebugFormat("{0} V2DGzip {1} bytes",
LogHeader, ret.Length);
return ret;
}
@ -426,7 +533,7 @@ namespace OpenSim.Framework
// the forth int is the compression factor for the following int16s
// This is just sets heightmap info. The actual size of the region was set on this instance's
// creation and any heights not initialized by theis blob are set to the default height.
public void FromCompressedTerrainSerialization(byte[] pBlob)
public void FromCompressedTerrainSerialization2D(byte[] pBlob)
{
Int32 hmFormatCode, hmSizeX, hmSizeY, hmCompressionFactor;
@ -448,7 +555,7 @@ namespace OpenSim.Framework
{
for (int xx = 0; xx < hmSizeX; xx++)
{
Int16 val = br.ReadInt16();
float val = FromCompressedHeight(br.ReadInt16());
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = val;
}
@ -456,9 +563,112 @@ namespace OpenSim.Framework
}
ClearTaint();
m_log.InfoFormat("{0} Read compressed 2d heightmap. Heightmap size=<{1},{2}>. Region size=<{3},{4}>. CompFact={5}",
m_log.DebugFormat("{0} Read (compressed2D) heightmap. Heightmap size=<{1},{2}>. Region size=<{3},{4}>. CompFact={5}",
LogHeader, hmSizeX, hmSizeY, SizeX, SizeY, hmCompressionFactor);
}
}
// Initialize heightmap from blob consisting of:
// int32, int32, int32, float[]
// where the first int32 is format code, next two int32s are the X and y of heightmap data
// This is just sets heightmap info. The actual size of the region was set on this instance's
// creation and any heights not initialized by theis blob are set to the default height.
public void FromCompressedTerrainSerializationV2D(byte[] pBlob)
{
Int32 hmSizeX, hmSizeY;
try
{
using (MemoryStream mstr = new MemoryStream(pBlob))
{
using (BinaryReader br = new BinaryReader(mstr))
{
hmSizeX = br.ReadInt32();
hmSizeY = br.ReadInt32();
// In case database info doesn't match real terrain size, initialize the whole terrain.
ClearLand();
for (int yy = 0; yy < hmSizeY; yy++)
{
for (int xx = 0; xx < hmSizeX; xx++)
{
float val = br.ReadSingle();
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = val;
}
}
}
}
}
catch (Exception e)
{
ClearTaint();
m_log.ErrorFormat("{0} 2D error: {1} - terrain may be damaged",
LogHeader, e.Message);
return;
}
ClearTaint();
m_log.DebugFormat("{0} V2D Heightmap size=<{1},{2}>. Region size=<{3},{4}>",
LogHeader, hmSizeX, hmSizeY, SizeX, SizeY);
}
// as above but Gzip compressed
public void FromCompressedTerrainSerializationV2DGZip(byte[] pBlob)
{
m_log.InfoFormat("{0} VD2Gzip {1} bytes input",
LogHeader, pBlob.Length);
Int32 hmSizeX, hmSizeY;
try
{
using (MemoryStream outputStream = new MemoryStream())
{
using (MemoryStream inputStream = new MemoryStream(pBlob))
{
using (GZipStream decompressionStream = new GZipStream(inputStream, CompressionMode.Decompress))
{
decompressionStream.Flush();
decompressionStream.CopyTo(outputStream);
}
}
outputStream.Seek(0, SeekOrigin.Begin);
using (BinaryReader br = new BinaryReader(outputStream))
{
hmSizeX = br.ReadInt32();
hmSizeY = br.ReadInt32();
// In case database info doesn't match real terrain size, initialize the whole terrain.
ClearLand();
for (int yy = 0; yy < hmSizeY; yy++)
{
for (int xx = 0; xx < hmSizeX; xx++)
{
float val = br.ReadSingle();
if (xx < SizeX && yy < SizeY)
m_heightmap[xx, yy] = val;
}
}
}
}
}
catch( Exception e)
{
ClearTaint();
m_log.ErrorFormat("{0} V2DGzip error: {1} - terrain may be damaged",
LogHeader, e.Message);
return;
}
ClearTaint();
m_log.DebugFormat("{0} V2DGzip. Heightmap size=<{1},{2}>. Region size=<{3},{4}>",
LogHeader, hmSizeX, hmSizeY, SizeX, SizeY);
}
}
}

View File

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

View File

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

View File

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

View File

@ -92,14 +92,6 @@ namespace OpenSim.Framework
public string Notes;
}
public class UserPreferences
{
public UUID UserId;
public bool IMViaEmail = false;
public bool Visible = false;
public string EMail = string.Empty;
}
public class UserAccountProperties
{
public string EmailAddress = string.Empty;

View File

@ -61,6 +61,15 @@ namespace OpenSim.Framework
public enum PermissionMask : uint
{
None = 0,
// folded perms
foldedTransfer = 1,
foldedModify = 1 << 1,
foldedCopy = 1 << 2,
foldedMask = 0x07,
//
Transfer = 1 << 13,
Modify = 1 << 14,
Copy = 1 << 15,
@ -267,14 +276,12 @@ namespace OpenSim.Framework
/// </summary>
/// <param name="a">A 3d vector</param>
/// <returns>A new vector which is normalized form of the vector</returns>
/// <remarks>The vector paramater cannot be <0,0,0></remarks>
public static Vector3 GetNormalizedVector(Vector3 a)
{
if (IsZeroVector(a))
throw new ArgumentException("Vector paramater cannot be a zero vector.");
float Mag = (float) GetMagnitude(a);
return new Vector3(a.X / Mag, a.Y / Mag, a.Z / Mag);
Vector3 v = new Vector3(a.X, a.Y, a.Z);
v.Normalize();
return v;
}
/// <summary>
@ -641,19 +648,25 @@ namespace OpenSim.Framework
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string Md5Hash(string data)
{
byte[] dataMd5 = ComputeMD5Hash(data);
return Md5Hash(data, Encoding.Default);
}
public static string Md5Hash(string data, Encoding encoding)
{
byte[] dataMd5 = ComputeMD5Hash(data, encoding);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < dataMd5.Length; i++)
sb.AppendFormat("{0:x2}", dataMd5[i]);
return sb.ToString();
}
private static byte[] ComputeMD5Hash(string data)
private static byte[] ComputeMD5Hash(string data, Encoding encoding)
{
MD5 md5 = MD5.Create();
return md5.ComputeHash(Encoding.Default.GetBytes(data));
return md5.ComputeHash(encoding.GetBytes(data));
}
/// <summary>
@ -661,6 +674,12 @@ namespace OpenSim.Framework
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string SHA1Hash(string data, Encoding enc)
{
return SHA1Hash(enc.GetBytes(data));
}
public static string SHA1Hash(string data)
{
return SHA1Hash(Encoding.Default.GetBytes(data));
@ -714,17 +733,26 @@ namespace OpenSim.Framework
/// <param name="oldy">Old region y-coord</param>
/// <param name="newy">New region y-coord</param>
/// <returns></returns>
public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy)
public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy,
int oldsizex, int oldsizey, int newsizex, int newsizey)
{
int dd = (int)((drawdist + Constants.RegionSize - 1) / Constants.RegionSize);
// we still need to make sure we see new region 1stNeighbors
int startX = (int)oldx - dd;
int startY = (int)oldy - dd;
oldx *= Constants.RegionSize;
newx *= Constants.RegionSize;
if (oldx + oldsizex + drawdist < newx)
return true;
if (newx + newsizex + drawdist < oldx)
return true;
int endX = (int)oldx + dd;
int endY = (int)oldy + dd;
oldy *= Constants.RegionSize;
newy *= Constants.RegionSize;
if (oldy + oldsizey + drawdist < newy)
return true;
if (newy + newsizey + drawdist< oldy)
return true;
return (newx < startX || endX < newx || newy < startY || endY < newy);
return false;
}
public static string FieldToString(byte[] bytes)
@ -804,6 +832,16 @@ namespace OpenSim.Framework
return output.ToString();
}
/// <summary>
/// Converts a URL to a IPAddress
/// </summary>
/// <param name="url">URL Standard Format</param>
/// <returns>A resolved IP Address</returns>
public static IPAddress GetHostFromURL(string url)
{
return GetHostFromDNS(url.Split(new char[] {'/', ':'})[3]);
}
/// <summary>
/// Returns a IP address from a specified DNS, favouring IPv4 addresses.
/// </summary>
@ -1065,6 +1103,25 @@ namespace OpenSim.Framework
}
}
public static string GetConfigVarWithDefaultSection(IConfigSource config, string varname, string section)
{
// First, check the Startup section, the default section
IConfig cnf = config.Configs["Startup"];
if (cnf == null)
return string.Empty;
string val = cnf.GetString(varname, string.Empty);
// Then check for an overwrite of the default in the given section
if (!string.IsNullOrEmpty(section))
{
cnf = config.Configs[section];
if (cnf != null)
val = cnf.GetString(varname, val);
}
return val;
}
/// <summary>
/// Gets the value of a configuration variable by looking into
/// multiple sections in order. The latter sections overwrite
@ -1388,6 +1445,46 @@ namespace OpenSim.Framework
return ret;
}
public static string Compress(string text)
{
byte[] buffer = Util.UTF8.GetBytes(text);
MemoryStream memory = new MemoryStream();
using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true))
{
compressor.Write(buffer, 0, buffer.Length);
}
memory.Position = 0;
byte[] compressed = new byte[memory.Length];
memory.Read(compressed, 0, compressed.Length);
byte[] compressedBuffer = new byte[compressed.Length + 4];
Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4);
return Convert.ToBase64String(compressedBuffer);
}
public static string Decompress(string compressedText)
{
byte[] compressedBuffer = Convert.FromBase64String(compressedText);
using (MemoryStream memory = new MemoryStream())
{
int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
byte[] buffer = new byte[msgLength];
memory.Position = 0;
using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress))
{
decompressor.Read(buffer, 0, buffer.Length);
}
return Util.UTF8.GetString(buffer);
}
}
/// <summary>
/// Copy data from one stream to another, leaving the read position of both streams at the beginning.
/// </summary>
@ -1524,19 +1621,19 @@ namespace OpenSim.Framework
{
string os = String.Empty;
if (Environment.OSVersion.Platform != PlatformID.Unix)
{
os = Environment.OSVersion.ToString();
}
else
{
os = ReadEtcIssue();
}
if (os.Length > 45)
{
os = os.Substring(0, 45);
}
// if (Environment.OSVersion.Platform != PlatformID.Unix)
// {
// os = Environment.OSVersion.ToString();
// }
// else
// {
// os = ReadEtcIssue();
// }
//
// if (os.Length > 45)
// {
// os = os.Substring(0, 45);
// }
return os;
}
@ -1591,6 +1688,69 @@ namespace OpenSim.Framework
return displayConnectionString;
}
public static T ReadSettingsFromIniFile<T>(IConfig config, T settingsClass)
{
Type settingsType = settingsClass.GetType();
FieldInfo[] fieldInfos = settingsType.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
if (!fieldInfo.IsStatic)
{
if (fieldInfo.FieldType == typeof(System.String))
{
fieldInfo.SetValue(settingsClass, config.Get(fieldInfo.Name, (string)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.Boolean))
{
fieldInfo.SetValue(settingsClass, config.GetBoolean(fieldInfo.Name, (bool)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.Int32))
{
fieldInfo.SetValue(settingsClass, config.GetInt(fieldInfo.Name, (int)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.Single))
{
fieldInfo.SetValue(settingsClass, config.GetFloat(fieldInfo.Name, (float)fieldInfo.GetValue(settingsClass)));
}
else if (fieldInfo.FieldType == typeof(System.UInt32))
{
fieldInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(fieldInfo.Name, ((uint)fieldInfo.GetValue(settingsClass)).ToString())));
}
}
}
PropertyInfo[] propertyInfos = settingsType.GetProperties();
foreach (PropertyInfo propInfo in propertyInfos)
{
if ((propInfo.CanRead) && (propInfo.CanWrite))
{
if (propInfo.PropertyType == typeof(System.String))
{
propInfo.SetValue(settingsClass, config.Get(propInfo.Name, (string)propInfo.GetValue(settingsClass, null)), null);
}
else if (propInfo.PropertyType == typeof(System.Boolean))
{
propInfo.SetValue(settingsClass, config.GetBoolean(propInfo.Name, (bool)propInfo.GetValue(settingsClass, null)), null);
}
else if (propInfo.PropertyType == typeof(System.Int32))
{
propInfo.SetValue(settingsClass, config.GetInt(propInfo.Name, (int)propInfo.GetValue(settingsClass, null)), null);
}
else if (propInfo.PropertyType == typeof(System.Single))
{
propInfo.SetValue(settingsClass, config.GetFloat(propInfo.Name, (float)propInfo.GetValue(settingsClass, null)), null);
}
if (propInfo.PropertyType == typeof(System.UInt32))
{
propInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(propInfo.Name, ((uint)propInfo.GetValue(settingsClass, null)).ToString())), null);
}
}
}
return settingsClass;
}
public static string Base64ToString(string str)
{
Decoder utf8Decode = Encoding.UTF8.GetDecoder();
@ -1645,7 +1805,7 @@ namespace OpenSim.Framework
public static Guid GetHashGuid(string data, string salt)
{
byte[] hash = ComputeMD5Hash(data + salt);
byte[] hash = ComputeMD5Hash(data + salt, Encoding.Default);
//string s = BitConverter.ToString(hash);
@ -1792,6 +1952,32 @@ namespace OpenSim.Framework
return found.ToArray();
}
public static string ServerURI(string uri)
{
if (uri == string.Empty)
return string.Empty;
// Get rid of eventual slashes at the end
uri = uri.TrimEnd('/');
IPAddress ipaddr1 = null;
string port1 = "";
try
{
ipaddr1 = Util.GetHostFromURL(uri);
}
catch { }
try
{
port1 = uri.Split(new char[] { ':' })[2];
}
catch { }
// We tried our best to convert the domain names to IP addresses
return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri;
}
/// <summary>
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
/// </summary>
@ -1970,6 +2156,11 @@ namespace OpenSim.Framework
}
}
public static void FireAndForget(System.Threading.WaitCallback callback)
{
FireAndForget(callback, null);
}
public static void InitThreadPool(int minThreads, int maxThreads)
{
if (maxThreads < 2)
@ -1986,7 +2177,7 @@ namespace OpenSim.Framework
STPStartInfo startInfo = new STPStartInfo();
startInfo.ThreadPoolName = "Util";
startInfo.IdleTimeout = 2000;
startInfo.IdleTimeout = 20000;
startInfo.MaxWorkerThreads = maxThreads;
startInfo.MinWorkerThreads = minThreads;

View File

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

View File

@ -43,12 +43,13 @@ namespace OpenSim.Framework
public static WearableCacheItem[] GetDefaultCacheItem()
{
int itemmax = 21;
int itemmax = AvatarAppearance.TEXTURE_COUNT;
WearableCacheItem[] retitems = new WearableCacheItem[itemmax];
for (uint i=0;i<itemmax;i++)
retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i + 1};
retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i};
return retitems;
}
public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache)
{
List<WearableCacheItem> ret = new List<WearableCacheItem>();
@ -98,6 +99,7 @@ namespace OpenSim.Framework
return ret.ToArray();
}
public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache)
{
OSDArray arr = new OSDArray();
@ -124,6 +126,68 @@ namespace OpenSim.Framework
}
return arr;
}
public static OSDArray BakedToOSD(WearableCacheItem[] pcacheItems)
{
if (pcacheItems.Length < AvatarAppearance.BAKE_INDICES[AvatarAppearance.BAKE_INDICES.Length - 1])
return null;
OSDArray arr = new OSDArray();
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
WearableCacheItem item = pcacheItems[idx];
OSDMap itemmap = new OSDMap();
itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex));
itemmap.Add("cacheid", OSD.FromUUID(item.CacheId));
itemmap.Add("textureid", OSD.FromUUID(item.TextureID));
/*
if (item.TextureAsset != null)
{
itemmap.Add("assetdata", OSD.FromBinary(item.TextureAsset.Data));
itemmap.Add("assetcreator", OSD.FromString(item.TextureAsset.CreatorID));
itemmap.Add("assetname", OSD.FromString(item.TextureAsset.Name));
}
*/
arr.Add(itemmap);
}
return arr;
}
public static WearableCacheItem[] BakedFromOSD(OSD pInput)
{
WearableCacheItem[] pcache = WearableCacheItem.GetDefaultCacheItem();
if (pInput.Type == OSDType.Array)
{
OSDArray itemarray = (OSDArray)pInput;
foreach (OSDMap item in itemarray)
{
int idx = (int)item["textureindex"].AsUInteger();
if (idx < 0 || idx > pcache.Length)
continue;
pcache[idx].CacheId = item["cacheid"].AsUUID();
pcache[idx].TextureID = item["textureid"].AsUUID();
/*
if (item.ContainsKey("assetdata"))
{
AssetBase asset = new AssetBase(item["textureid"].AsUUID(), "BakedTexture", (sbyte)AssetType.Texture, UUID.Zero.ToString());
asset.Temporary = true;
asset.Local = true;
asset.Data = item["assetdata"].AsBinary();
pcache[idx].TextureAsset = asset;
}
else
*/
pcache[idx].TextureAsset = null;
}
}
return pcache;
}
public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems)
{
for (int i = 0; i < pcacheItems.Length; i++)

View File

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

View File

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

View File

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

View File

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

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, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>();
private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
#region INonSharedRegionModule methods
@ -178,6 +177,7 @@ namespace OpenSim.Region.ClientStack.Linden
}
/// <summary>
<<<<<<< HEAD
/// Always returns a valid queue
/// </summary>
/// <param name="agentId"></param>
@ -201,6 +201,8 @@ namespace OpenSim.Region.ClientStack.Linden
}
/// <summary>
=======
>>>>>>> avn/ubitvar
/// May return a null queue
/// </summary>
/// <param name="agentId"></param>
@ -263,28 +265,13 @@ namespace OpenSim.Region.ClientStack.Linden
lock (queues)
queues.Remove(agentID);
List<UUID> removeitems = new List<UUID>();
lock (m_AvatarQueueUUIDMapping)
m_AvatarQueueUUIDMapping.Remove(agentID);
UUID searchval = UUID.Zero;
removeitems.Clear();
lock (m_QueueUUIDAvatarMapping)
lock (m_ids)
{
foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys)
{
searchval = m_QueueUUIDAvatarMapping[ky];
if (searchval == agentID)
{
removeitems.Add(ky);
}
}
foreach (UUID ky in removeitems)
m_QueueUUIDAvatarMapping.Remove(ky);
if (!m_ids.ContainsKey(agentID))
m_ids.Remove(agentID);
}
// m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
@ -303,61 +290,107 @@ namespace OpenSim.Region.ClientStack.Linden
public void OnRegisterCaps(UUID agentID, Caps caps)
{
// Register an event queue for the client
<<<<<<< HEAD
if (DebugLevel > 0)
m_log.DebugFormat(
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
agentID, caps, m_scene.RegionInfo.RegionName);
// Let's instantiate a Queue for this agent right now
TryGetQueue(agentID);
=======
m_log.DebugFormat(
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
agentID, caps, m_scene.RegionInfo.RegionName);
>>>>>>> avn/ubitvar
UUID eventQueueGetUUID;
Queue<OSD> queue;
Random rnd = new Random(Environment.TickCount);
int nrnd = rnd.Next(30000000);
if (nrnd < 0)
nrnd = -nrnd;
lock (m_AvatarQueueUUIDMapping)
lock (queues)
{
// Reuse open queues. The client does!
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
if (queues.ContainsKey(agentID))
queue = queues[agentID];
else
queue = null;
if (queue == null)
{
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
queue = new Queue<OSD>();
queues[agentID] = queue;
// push markers to handle old responses still waiting
// this will cost at most viewer getting two forced noevents
// even being a new queue better be safe
queue.Enqueue(null);
queue.Enqueue(null); // one should be enough
lock (m_AvatarQueueUUIDMapping)
{
eventQueueGetUUID = UUID.Random();
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
{
// oops this should not happen ?
m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue");
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
}
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
}
lock (m_ids)
{
if (!m_ids.ContainsKey(agentID))
m_ids.Add(agentID, nrnd);
else
m_ids[agentID] = nrnd;
}
}
else
{
eventQueueGetUUID = UUID.Random();
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
// push markers to handle old responses still waiting
// this will cost at most viewer getting two forced noevents
// even being a new queue better be safe
queue.Enqueue(null);
queue.Enqueue(null); // one should be enough
// reuse or not to reuse TODO FIX
lock (m_AvatarQueueUUIDMapping)
{
// Reuse open queues. The client does!
// Its reuse caps path not queues those are been reused already
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
{
m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
}
else
{
eventQueueGetUUID = UUID.Random();
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
}
}
lock (m_ids)
{
// change to negative numbers so they are changed at end of sending first marker
// old data on a queue may be sent on a response for a new caps
// but at least will be sent with coerent IDs
if (!m_ids.ContainsKey(agentID))
m_ids.Add(agentID, -nrnd); // should not happen
else
m_ids[agentID] = -m_ids[agentID];
}
}
}
lock (m_QueueUUIDAvatarMapping)
{
if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
}
lock (m_AvatarQueueUUIDMapping)
{
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
}
caps.RegisterPollHandler(
"EventQueueGet",
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
Random rnd = new Random(Environment.TickCount);
lock (m_ids)
{
if (!m_ids.ContainsKey(agentID))
m_ids.Add(agentID, rnd.Next(30000000));
}
}
public bool HasEvents(UUID requestID, UUID agentID)
{
// Don't use this, because of race conditions at agent closing time
//Queue<OSD> queue = TryGetQueue(agentID);
Queue<OSD> queue = GetQueue(agentID);
if (queue != null)
lock (queue)
@ -366,7 +399,8 @@ namespace OpenSim.Region.ClientStack.Linden
return queue.Count > 0;
}
return false;
//m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID);
return true;
}
/// <summary>
@ -395,55 +429,65 @@ namespace OpenSim.Region.ClientStack.Linden
return NoEvents(requestID, pAgentId);
}
OSD element;
OSD element = null;;
OSDArray array = new OSDArray();
int thisID = 0;
bool negativeID = false;
lock (queue)
{
if (queue.Count == 0)
return NoEvents(requestID, pAgentId);
element = queue.Dequeue(); // 15s timeout
}
int thisID = 0;
lock (m_ids)
thisID = m_ids[pAgentId];
lock (m_ids)
thisID = m_ids[pAgentId];
OSDArray array = new OSDArray();
if (element == null) // didn't have an event in 15s
{
// Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
array.Add(EventQueueHelper.KeepAliveEvent());
//m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
}
else
{
if (DebugLevel > 0)
LogOutboundDebugMessage(element, pAgentId);
array.Add(element);
lock (queue)
if (thisID < 0)
{
while (queue.Count > 0)
{
element = queue.Dequeue();
negativeID = true;
thisID = -thisID;
}
if (DebugLevel > 0)
LogOutboundDebugMessage(element, pAgentId);
array.Add(element);
thisID++;
}
while (queue.Count > 0)
{
element = queue.Dequeue();
// add elements until a marker is found
// so they get into a response
if (element == null)
break;
if (DebugLevel > 0)
LogOutboundDebugMessage(element, pAgentId);
array.Add(element);
thisID++;
}
}
OSDMap events = new OSDMap();
events.Add("events", array);
OSDMap events = null;
if (array.Count > 0)
{
events = new OSDMap();
events.Add("events", array);
events.Add("id", new OSDInteger(thisID));
}
if (negativeID && element == null)
{
Random rnd = new Random(Environment.TickCount);
thisID = rnd.Next(30000000);
if (thisID < 0)
thisID = -thisID;
}
events.Add("id", new OSDInteger(thisID));
lock (m_ids)
{
m_ids[pAgentId] = thisID + 1;
}
// if there where no elements before a marker send a NoEvents
if (array.Count == 0)
return NoEvents(requestID, pAgentId);
Hashtable responsedata = new Hashtable();
responsedata["int_response_code"] = 200;
responsedata["content_type"] = "application/xml";
@ -461,260 +505,12 @@ namespace OpenSim.Region.ClientStack.Linden
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["reusecontext"] = false;
responsedata["str_response_string"] = "Upstream error: ";
responsedata["error_status_text"] = "Upstream error:";
responsedata["str_response_string"] = "<llsd></llsd>";
responsedata["error_status_text"] = "<llsd></llsd>";
responsedata["http_protocol_version"] = "HTTP/1.0";
return responsedata;
}
// public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
// {
// // TODO: this has to be redone to not busy-wait (and block the thread),
// // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
//
//// if (m_log.IsDebugEnabled)
//// {
//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
//// foreach (object key in request.Keys)
//// {
//// debug += key.ToString() + "=" + request[key].ToString() + " ";
//// }
//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
//// }
//
// Queue<OSD> queue = TryGetQueue(agentID);
// OSD element;
//
// lock (queue)
// element = queue.Dequeue(); // 15s timeout
//
// Hashtable responsedata = new Hashtable();
//
// int thisID = 0;
// lock (m_ids)
// thisID = m_ids[agentID];
//
// if (element == null)
// {
// //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
// if (thisID == -1) // close-request
// {
// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
// responsedata["int_response_code"] = 404; //501; //410; //404;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Closed EQG";
// return responsedata;
// }
// responsedata["int_response_code"] = 502;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Upstream error: ";
// responsedata["error_status_text"] = "Upstream error:";
// responsedata["http_protocol_version"] = "HTTP/1.0";
// return responsedata;
// }
//
// OSDArray array = new OSDArray();
// if (element == null) // didn't have an event in 15s
// {
// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
// array.Add(EventQueueHelper.KeepAliveEvent());
// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
// }
// else
// {
// array.Add(element);
//
// if (element is OSDMap)
// {
// OSDMap ev = (OSDMap)element;
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
// ev["message"], m_scene.GetScenePresence(agentID).Name);
// }
//
// lock (queue)
// {
// while (queue.Count > 0)
// {
// element = queue.Dequeue();
//
// if (element is OSDMap)
// {
// OSDMap ev = (OSDMap)element;
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
// ev["message"], m_scene.GetScenePresence(agentID).Name);
// }
//
// array.Add(element);
// thisID++;
// }
// }
// }
//
// OSDMap events = new OSDMap();
// events.Add("events", array);
//
// events.Add("id", new OSDInteger(thisID));
// lock (m_ids)
// {
// m_ids[agentID] = thisID + 1;
// }
//
// responsedata["int_response_code"] = 200;
// responsedata["content_type"] = "application/xml";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
//
// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
//
// return responsedata;
// }
// public Hashtable EventQueuePath2(Hashtable request)
// {
// string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
// // pull off the last "/" in the path.
// Hashtable responsedata = new Hashtable();
// capuuid = capuuid.Substring(0, capuuid.Length - 1);
// capuuid = capuuid.Replace("/CAPS/EQG/", "");
// UUID AvatarID = UUID.Zero;
// UUID capUUID = UUID.Zero;
//
// // parse the path and search for the avatar with it registered
// if (UUID.TryParse(capuuid, out capUUID))
// {
// lock (m_QueueUUIDAvatarMapping)
// {
// if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
// {
// AvatarID = m_QueueUUIDAvatarMapping[capUUID];
// }
// }
//
// if (AvatarID != UUID.Zero)
// {
// return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
// }
// else
// {
// responsedata["int_response_code"] = 404;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Not Found";
// responsedata["error_status_text"] = "Not Found";
// responsedata["http_protocol_version"] = "HTTP/1.0";
// return responsedata;
// // return 404
// }
// }
// else
// {
// responsedata["int_response_code"] = 404;
// responsedata["content_type"] = "text/plain";
// responsedata["keepalive"] = false;
// responsedata["str_response_string"] = "Not Found";
// responsedata["error_status_text"] = "Not Found";
// responsedata["http_protocol_version"] = "HTTP/1.0";
// return responsedata;
// // return 404
// }
// }
public OSD EventQueueFallBack(string path, OSD request, string endpoint)
{
// This is a fallback element to keep the client from loosing EventQueueGet
// Why does CAPS fail sometimes!?
m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!");
string capuuid = path.Replace("/CAPS/EQG/","");
capuuid = capuuid.Substring(0, capuuid.Length - 1);
// UUID AvatarID = UUID.Zero;
UUID capUUID = UUID.Zero;
if (UUID.TryParse(capuuid, out capUUID))
{
/* Don't remove this yet code cleaners!
* Still testing this!
*
lock (m_QueueUUIDAvatarMapping)
{
if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
{
AvatarID = m_QueueUUIDAvatarMapping[capUUID];
}
}
if (AvatarID != UUID.Zero)
{
// Repair the CAP!
//OpenSim.Framework.Capabilities.Caps caps = m_scene.GetCapsHandlerForUser(AvatarID);
//string capsBase = "/CAPS/EQG/";
//caps.RegisterHandler("EventQueueGet",
//new RestHTTPHandler("POST", capsBase + capUUID.ToString() + "/",
//delegate(Hashtable m_dhttpMethod)
//{
// return ProcessQueue(m_dhttpMethod, AvatarID, caps);
//}));
// start new ID sequence.
Random rnd = new Random(System.Environment.TickCount);
lock (m_ids)
{
if (!m_ids.ContainsKey(AvatarID))
m_ids.Add(AvatarID, rnd.Next(30000000));
}
int thisID = 0;
lock (m_ids)
thisID = m_ids[AvatarID];
BlockingLLSDQueue queue = GetQueue(AvatarID);
OSDArray array = new OSDArray();
LLSD element = queue.Dequeue(15000); // 15s timeout
if (element == null)
{
array.Add(EventQueueHelper.KeepAliveEvent());
}
else
{
array.Add(element);
while (queue.Count() > 0)
{
array.Add(queue.Dequeue(1));
thisID++;
}
}
OSDMap events = new OSDMap();
events.Add("events", array);
events.Add("id", new LLSDInteger(thisID));
lock (m_ids)
{
m_ids[AvatarID] = thisID + 1;
}
return events;
}
else
{
return new LLSD();
}
*
*/
}
else
{
//return new LLSD();
}
return new OSDString("shutdown404!");
}
public void DisableSimulator(ulong handle, UUID avatarID)
{
OSD item = EventQueueHelper.DisableSimulator(handle);
@ -723,9 +519,14 @@ namespace OpenSim.Region.ClientStack.Linden
public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
{
<<<<<<< HEAD
if (DebugLevel > 0)
m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY);
=======
m_log.DebugFormat("{0} EnableSimulator. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
>>>>>>> avn/ubitvar
OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
Enqueue(item, avatarID);
@ -734,10 +535,15 @@ namespace OpenSim.Region.ClientStack.Linden
public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
ulong regionHandle, int regionSizeX, int regionSizeY)
{
<<<<<<< HEAD
if (DebugLevel > 0)
m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY);
=======
m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
>>>>>>> avn/ubitvar
OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
Enqueue(item, avatarID);
}
@ -747,9 +553,14 @@ namespace OpenSim.Region.ClientStack.Linden
uint locationID, uint flags, string capsURL,
UUID avatarID, int regionSizeX, int regionSizeY)
{
<<<<<<< HEAD
if (DebugLevel > 0)
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}",
LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY);
=======
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
>>>>>>> avn/ubitvar
OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
@ -760,9 +571,14 @@ namespace OpenSim.Region.ClientStack.Linden
IPEndPoint newRegionExternalEndPoint,
string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
{
<<<<<<< HEAD
if (DebugLevel > 0)
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
=======
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
>>>>>>> avn/ubitvar
OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
capsURL, avatarID, sessionID, regionSizeX, regionSizeY);

View File

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

View File

@ -27,11 +27,14 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using System.Threading;
using System.Web;
using Mono.Addins;
using OpenSim.Framework.Monitoring;
using log4net;
using Nini.Config;
using OpenMetaverse;
@ -57,12 +60,51 @@ namespace OpenSim.Region.ClientStack.Linden
private IAssetService m_AssetService;
private bool m_Enabled = true;
private string m_URL;
<<<<<<< HEAD
private string m_URL2;
private string m_RedirectURL = null;
private string m_RedirectURL2 = null;
=======
struct aPollRequest
{
public PollServiceMeshEventArgs thepoll;
public UUID reqID;
public Hashtable request;
}
public class aPollResponse
{
public Hashtable response;
public int bytes;
public int lod;
}
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static GetMeshHandler m_getMeshHandler;
private IAssetService m_assetService = null;
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
private static Thread[] m_workerThreads = null;
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
new OpenMetaverse.BlockingQueue<aPollRequest>();
private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>();
>>>>>>> avn/ubitvar
#region Region Module interfaceBase Members
~GetMeshModule()
{
foreach (Thread t in m_workerThreads)
Watchdog.AbortThread(t.ManagedThreadId);
}
public Type ReplaceableInterface
{
get { return null; }
@ -87,8 +129,12 @@ namespace OpenSim.Region.ClientStack.Linden
if (m_URL2 != string.Empty)
{
m_Enabled = true;
<<<<<<< HEAD
m_RedirectURL2 = config.GetString("GetMesh2RedirectURL");
}
=======
>>>>>>> avn/ubitvar
}
public void AddRegion(Scene pScene)
@ -97,6 +143,8 @@ namespace OpenSim.Region.ClientStack.Linden
return;
m_scene = pScene;
m_assetService = pScene.AssetService;
}
public void RemoveRegion(Scene scene)
@ -105,6 +153,9 @@ namespace OpenSim.Region.ClientStack.Linden
return;
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
m_scene = null;
}
@ -115,6 +166,27 @@ namespace OpenSim.Region.ClientStack.Linden
m_AssetService = m_scene.RequestModuleInterface<IAssetService>();
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
// We'll reuse the same handler for all requests.
m_getMeshHandler = new GetMeshHandler(m_assetService);
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
if (m_workerThreads == null)
{
m_workerThreads = new Thread[2];
for (uint i = 0; i < 2; i++)
{
m_workerThreads[i] = Watchdog.StartThread(DoMeshRequests,
String.Format("MeshWorkerThread{0}", i),
ThreadPriority.Normal,
false,
false,
null,
int.MaxValue);
}
}
}
@ -124,9 +196,147 @@ namespace OpenSim.Region.ClientStack.Linden
#endregion
private void DoMeshRequests()
{
while (true)
{
aPollRequest poolreq = m_queue.Dequeue();
poolreq.thepoll.Process(poolreq);
}
}
// Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
public void ThrottleUpdate(ScenePresence p)
{
UUID user = p.UUID;
int imagethrottle = p.ControllingClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Asset);
PollServiceMeshEventArgs args;
if (m_pollservices.TryGetValue(user, out args))
{
args.UpdateThrottle(imagethrottle, p);
}
}
private class PollServiceMeshEventArgs : PollServiceEventArgs
{
private List<Hashtable> requests =
new List<Hashtable>();
private Dictionary<UUID, aPollResponse> responses =
new Dictionary<UUID, aPollResponse>();
private Scene m_scene;
private MeshCapsDataThrottler m_throttler;
public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) :
base(null, uri, null, null, null, pId, int.MaxValue)
{
m_scene = scene;
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId);
// x is request id, y is userid
HasEvents = (x, y) =>
{
lock (responses)
{
bool ret = m_throttler.hasEvents(x, responses);
m_throttler.ProcessTime();
return ret;
}
};
GetEvents = (x, y) =>
{
lock (responses)
{
try
{
return responses[x].response;
}
finally
{
m_throttler.ProcessTime();
responses.Remove(x);
}
}
};
// x is request id, y is request data hashtable
Request = (x, y) =>
{
aPollRequest reqinfo = new aPollRequest();
reqinfo.thepoll = this;
reqinfo.reqID = x;
reqinfo.request = y;
m_queue.Enqueue(reqinfo);
};
// this should never happen except possible on shutdown
NoEvents = (x, y) =>
{
/*
lock (requests)
{
Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
requests.Remove(request);
}
*/
Hashtable response = new Hashtable();
response["int_response_code"] = 500;
response["str_response_string"] = "Script timeout";
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
return response;
};
}
public void Process(aPollRequest requestinfo)
{
Hashtable response;
UUID requestID = requestinfo.reqID;
// If the avatar is gone, don't bother to get the texture
if (m_scene.GetScenePresence(Id) == null)
{
response = new Hashtable();
response["int_response_code"] = 500;
response["str_response_string"] = "Script timeout";
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
lock (responses)
responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 };
return;
}
response = m_getMeshHandler.Handle(requestinfo.request);
lock (responses)
{
responses[requestID] = new aPollResponse()
{
bytes = (int)response["int_bytes"],
lod = (int)response["int_lod"],
response = response
};
}
m_throttler.ProcessTime();
}
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
{
m_throttler.UpdateThrottle(pimagethrottle, p);
}
}
public void RegisterCaps(UUID agentID, Caps caps)
{
<<<<<<< HEAD
UUID capID = UUID.Random();
bool getMeshRegistered = false;
@ -140,6 +350,35 @@ namespace OpenSim.Region.ClientStack.Linden
caps.RegisterHandler(
"GetMesh",
new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh", agentID.ToString(), m_RedirectURL));
=======
// UUID capID = UUID.Random();
if (m_URL == "localhost")
{
string capUrl = "/CAPS/" + UUID.Random() + "/";
// Register this as a poll service
PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
args.Type = PollServiceEventArgs.EventType.Mesh;
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
string hostName = m_scene.RegionInfo.ExternalHostName;
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
string protocol = "http";
if (MainServer.Instance.UseSSL)
{
hostName = MainServer.Instance.SSLCommonName;
port = MainServer.Instance.SSLPort;
protocol = "https";
}
caps.RegisterHandler("GetMesh", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
m_pollservices[agentID] = args;
m_capsDict[agentID] = capUrl;
>>>>>>> avn/ubitvar
}
else
{
@ -164,6 +403,177 @@ namespace OpenSim.Region.ClientStack.Linden
caps.RegisterHandler("GetMesh2", m_URL2);
}
}
private void DeregisterCaps(UUID agentID, Caps caps)
{
string capUrl;
PollServiceMeshEventArgs args;
if (m_capsDict.TryGetValue(agentID, out capUrl))
{
MainServer.Instance.RemoveHTTPHandler("", capUrl);
m_capsDict.Remove(agentID);
}
if (m_pollservices.TryGetValue(agentID, out args))
{
m_pollservices.Remove(agentID);
}
}
internal sealed class MeshCapsDataThrottler
{
private volatile int currenttime = 0;
private volatile int lastTimeElapsed = 0;
private volatile int BytesSent = 0;
private int Lod3 = 0;
private int Lod2 = 0;
private int Lod1 = 0;
private int UserSetThrottle = 0;
private int UDPSetThrottle = 0;
private int CapSetThrottle = 0;
private float CapThrottleDistributon = 0.30f;
private readonly Scene m_scene;
private ThrottleOutPacketType Throttle;
private readonly UUID User;
public MeshCapsDataThrottler(int pBytes, int max, int min, Scene pScene, UUID puser)
{
ThrottleBytes = pBytes;
lastTimeElapsed = Util.EnvironmentTickCount();
Throttle = ThrottleOutPacketType.Asset;
m_scene = pScene;
User = puser;
}
public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
{
const float ThirtyPercent = 0.30f;
const float FivePercent = 0.05f;
PassTime();
// Note, this is called IN LOCK
bool haskey = responses.ContainsKey(key);
if (responses.Count > 2)
{
SplitThrottle(ThirtyPercent);
}
else
{
SplitThrottle(FivePercent);
}
if (!haskey)
{
return false;
}
aPollResponse response;
if (responses.TryGetValue(key, out response))
{
float LOD3Over = (((ThrottleBytes*CapThrottleDistributon)%50000) + 1);
float LOD2Over = (((ThrottleBytes*CapThrottleDistributon)%10000) + 1);
// Normal
if (BytesSent + response.bytes <= ThrottleBytes)
{
BytesSent += response.bytes;
return true;
}
// Lod3 Over Throttle protection to keep things processing even when the throttle bandwidth is set too little.
else if (response.bytes > ThrottleBytes && Lod3 <= ((LOD3Over < 1)? 1: LOD3Over) )
{
Interlocked.Increment(ref Lod3);
BytesSent += response.bytes;
return true;
}
// Lod2 Over Throttle protection to keep things processing even when the throttle bandwidth is set too little.
else if (response.bytes > ThrottleBytes && Lod2 <= ((LOD2Over < 1) ? 1 : LOD2Over))
{
Interlocked.Increment(ref Lod2);
BytesSent += response.bytes;
return true;
}
else
{
return false;
}
}
return haskey;
}
public void SubtractBytes(int bytes,int lod)
{
BytesSent -= bytes;
}
private void SplitThrottle(float percentMultiplier)
{
if (CapThrottleDistributon != percentMultiplier) // don't switch it if it's already set at the % multipler
{
CapThrottleDistributon = percentMultiplier;
ScenePresence p;
if (m_scene.TryGetScenePresence(User, out p)) // If we don't get a user they're not here anymore.
{
// AlterThrottle(UserSetThrottle, p);
UpdateThrottle(UserSetThrottle, p);
}
}
}
public void ProcessTime()
{
PassTime();
}
private void PassTime()
{
currenttime = Util.EnvironmentTickCount();
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
//processTimeBasedActions(responses);
if (currenttime - timeElapsed >= 1000)
{
lastTimeElapsed = Util.EnvironmentTickCount();
BytesSent -= ThrottleBytes;
if (BytesSent < 0) BytesSent = 0;
if (BytesSent < ThrottleBytes)
{
Lod3 = 0;
Lod2 = 0;
Lod1 = 0;
}
}
}
private void AlterThrottle(int setting, ScenePresence p)
{
p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
}
public int ThrottleBytes
{
get { return CapSetThrottle; }
set { CapSetThrottle = value; }
}
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
{
// Client set throttle !
UserSetThrottle = pimagethrottle;
CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon);
// UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon));
float udp = 1.0f - CapThrottleDistributon;
if(udp < 0.7f)
udp = 0.7f;
UDPSetThrottle = (int) ((float)pimagethrottle * udp);
if (CapSetThrottle < 4068)
CapSetThrottle = 4068; // at least two discovery mesh
p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle);
ProcessTime();
}
}
}
}

View File

@ -27,18 +27,13 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using System.Web;
using System.Threading;
using log4net;
using Nini.Config;
using Mono.Addins;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenMetaverse.Imaging;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
@ -47,6 +42,7 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OpenSim.Capabilities.Handlers;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.ClientStack.Linden
{
@ -54,16 +50,44 @@ namespace OpenSim.Region.ClientStack.Linden
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
public class GetTextureModule : INonSharedRegionModule
{
// private static readonly ILog m_log =
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
struct aPollRequest
{
public PollServiceTextureEventArgs thepoll;
public UUID reqID;
public Hashtable request;
public bool send503;
}
public class aPollResponse
{
public Hashtable response;
public int bytes;
}
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
private IAssetService m_assetService;
private bool m_Enabled = false;
private static GetTextureHandler m_getTextureHandler;
private IAssetService m_assetService = null;
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
private static Thread[] m_workerThreads = null;
private string m_Url = "localhost";
private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
new OpenMetaverse.BlockingQueue<aPollRequest>();
<<<<<<< HEAD
// TODO: Change this to a config option
private string m_RedirectURL = null;
=======
private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
>>>>>>> avn/ubitvar
private string m_URL;
@ -72,6 +96,7 @@ namespace OpenSim.Region.ClientStack.Linden
public void Initialise(IConfigSource source)
{
IConfig config = source.Configs["ClientStack.LindenCaps"];
<<<<<<< HEAD
if (config == null)
return;
@ -82,32 +107,100 @@ namespace OpenSim.Region.ClientStack.Linden
m_Enabled = true;
m_RedirectURL = config.GetString("GetTextureRedirectURL");
}
=======
if (config != null)
m_Url = config.GetString("Cap_GetTexture", "localhost");
>>>>>>> avn/ubitvar
}
public void AddRegion(Scene s)
{
if (!m_Enabled)
return;
m_scene = s;
m_assetService = s.AssetService;
}
public void RemoveRegion(Scene s)
{
if (!m_Enabled)
return;
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
m_scene = null;
}
public void RegionLoaded(Scene s)
{
if (!m_Enabled)
return;
// We'll reuse the same handler for all requests.
m_getTextureHandler = new GetTextureHandler(m_assetService);
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
if (m_workerThreads == null)
{
m_workerThreads = new Thread[2];
for (uint i = 0; i < 2; i++)
{
m_workerThreads[i] = Watchdog.StartThread(DoTextureRequests,
String.Format("TextureWorkerThread{0}", i),
ThreadPriority.Normal,
false,
false,
null,
int.MaxValue);
}
}
}
private int ExtractImageThrottle(byte[] pthrottles)
{
byte[] adjData;
int pos = 0;
if (!BitConverter.IsLittleEndian)
{
byte[] newData = new byte[7 * 4];
Buffer.BlockCopy(pthrottles, 0, newData, 0, 7 * 4);
for (int i = 0; i < 7; i++)
Array.Reverse(newData, i * 4, 4);
adjData = newData;
}
else
{
adjData = pthrottles;
}
// 0.125f converts from bits to bytes
//int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
//pos += 4;
// int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
//pos += 4;
// int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
// pos += 4;
// int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
// pos += 4;
// int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
// pos += 4;
pos = pos + 20;
int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
//int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
return texture;
}
// Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
public void ThrottleUpdate(ScenePresence p)
{
byte[] throttles = p.ControllingClient.GetThrottlesPacked(1);
UUID user = p.UUID;
int imagethrottle = ExtractImageThrottle(throttles);
PollServiceTextureEventArgs args;
if (m_pollservices.TryGetValue(user,out args))
{
args.UpdateThrottle(imagethrottle);
}
}
public void PostInitialise()
@ -125,28 +218,306 @@ namespace OpenSim.Region.ClientStack.Linden
#endregion
public void RegisterCaps(UUID agentID, Caps caps)
~GetTextureModule()
{
UUID capID = UUID.Random();
foreach (Thread t in m_workerThreads)
Watchdog.AbortThread(t.ManagedThreadId);
//caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
if (m_URL == "localhost")
}
private class PollServiceTextureEventArgs : PollServiceEventArgs
{
private List<Hashtable> requests =
new List<Hashtable>();
private Dictionary<UUID, aPollResponse> responses =
new Dictionary<UUID, aPollResponse>();
private Scene m_scene;
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
public PollServiceTextureEventArgs(UUID pId, Scene scene) :
base(null, "", null, null, null, pId, int.MaxValue)
{
<<<<<<< HEAD
// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
caps.RegisterHandler(
"GetTexture",
new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString(), m_RedirectURL));
=======
m_scene = scene;
// x is request id, y is userid
HasEvents = (x, y) =>
{
lock (responses)
{
bool ret = m_throttler.hasEvents(x, responses);
m_throttler.ProcessTime();
return ret;
}
};
GetEvents = (x, y) =>
{
lock (responses)
{
try
{
return responses[x].response;
}
finally
{
responses.Remove(x);
}
}
};
// x is request id, y is request data hashtable
Request = (x, y) =>
{
aPollRequest reqinfo = new aPollRequest();
reqinfo.thepoll = this;
reqinfo.reqID = x;
reqinfo.request = y;
reqinfo.send503 = false;
lock (responses)
{
if (responses.Count > 0)
{
if (m_queue.Count >= 4)
{
// Never allow more than 4 fetches to wait
reqinfo.send503 = true;
}
}
}
m_queue.Enqueue(reqinfo);
};
// this should never happen except possible on shutdown
NoEvents = (x, y) =>
{
/*
lock (requests)
{
Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
requests.Remove(request);
}
*/
Hashtable response = new Hashtable();
response["int_response_code"] = 500;
response["str_response_string"] = "Script timeout";
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
return response;
};
>>>>>>> avn/ubitvar
}
else
public void Process(aPollRequest requestinfo)
{
// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
if (handler != null)
handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture", m_URL);
else
caps.RegisterHandler("GetTexture", m_URL);
Hashtable response;
UUID requestID = requestinfo.reqID;
if (requestinfo.send503)
{
response = new Hashtable();
response["int_response_code"] = 503;
response["str_response_string"] = "Throttled";
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
Hashtable headers = new Hashtable();
headers["Retry-After"] = 30;
response["headers"] = headers;
lock (responses)
responses[requestID] = new aPollResponse() {bytes = 0, response = response};
return;
}
// If the avatar is gone, don't bother to get the texture
if (m_scene.GetScenePresence(Id) == null)
{
response = new Hashtable();
response["int_response_code"] = 500;
response["str_response_string"] = "Script timeout";
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
lock (responses)
responses[requestID] = new aPollResponse() {bytes = 0, response = response};
return;
}
response = m_getTextureHandler.Handle(requestinfo.request);
lock (responses)
{
responses[requestID] = new aPollResponse()
{
bytes = (int) response["int_bytes"],
response = response
};
}
m_throttler.ProcessTime();
}
internal void UpdateThrottle(int pimagethrottle)
{
m_throttler.ThrottleBytes = pimagethrottle;
}
}
private void RegisterCaps(UUID agentID, Caps caps)
{
if (m_Url == "localhost")
{
string capUrl = "/CAPS/" + UUID.Random() + "/";
// Register this as a poll service
PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
args.Type = PollServiceEventArgs.EventType.Texture;
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
string hostName = m_scene.RegionInfo.ExternalHostName;
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
string protocol = "http";
if (MainServer.Instance.UseSSL)
{
hostName = MainServer.Instance.SSLCommonName;
port = MainServer.Instance.SSLPort;
protocol = "https";
}
IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
if (handler != null)
<<<<<<< HEAD
handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture", m_URL);
=======
handler.RegisterExternalUserCapsHandler(agentID, caps, "GetTexture", capUrl);
>>>>>>> avn/ubitvar
else
caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
m_pollservices[agentID] = args;
m_capsDict[agentID] = capUrl;
}
else
{
caps.RegisterHandler("GetTexture", m_Url);
}
}
private void DeregisterCaps(UUID agentID, Caps caps)
{
PollServiceTextureEventArgs args;
MainServer.Instance.RemoveHTTPHandler("", m_URL);
m_capsDict.Remove(agentID);
if (m_pollservices.TryGetValue(agentID, out args))
{
m_pollservices.Remove(agentID);
}
}
private void DoTextureRequests()
{
while (true)
{
aPollRequest poolreq = m_queue.Dequeue();
poolreq.thepoll.Process(poolreq);
}
}
internal sealed class CapsDataThrottler
{
private volatile int currenttime = 0;
private volatile int lastTimeElapsed = 0;
private volatile int BytesSent = 0;
private int oversizedImages = 0;
public CapsDataThrottler(int pBytes, int max, int min)
{
ThrottleBytes = pBytes;
lastTimeElapsed = Util.EnvironmentTickCount();
}
public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses)
{
PassTime();
// Note, this is called IN LOCK
bool haskey = responses.ContainsKey(key);
if (!haskey)
{
return false;
}
GetTextureModule.aPollResponse response;
if (responses.TryGetValue(key, out response))
{
// This is any error response
if (response.bytes == 0)
return true;
// Normal
if (BytesSent + response.bytes <= ThrottleBytes)
{
BytesSent += response.bytes;
//TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
//m_actions.Add(timeBasedAction);
return true;
}
// Big textures
else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes % 50000) + 1))
{
Interlocked.Increment(ref oversizedImages);
BytesSent += response.bytes;
//TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
//m_actions.Add(timeBasedAction);
return true;
}
else
{
return false;
}
}
return haskey;
}
public void ProcessTime()
{
PassTime();
}
private void PassTime()
{
currenttime = Util.EnvironmentTickCount();
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
//processTimeBasedActions(responses);
if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
{
lastTimeElapsed = Util.EnvironmentTickCount();
BytesSent -= ThrottleBytes;
if (BytesSent < 0) BytesSent = 0;
if (BytesSent < ThrottleBytes)
{
oversizedImages = 0;
}
}
}
public int ThrottleBytes;
}
}
}

View File

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

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