Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork
commit
e925b0654d
|
@ -143,7 +143,11 @@ what it is today.
|
||||||
* sempuki
|
* sempuki
|
||||||
* SignpostMarv
|
* SignpostMarv
|
||||||
* SpotOn3D
|
* SpotOn3D
|
||||||
|
* Stefan_Boom / stoehr
|
||||||
* Strawberry Fride
|
* Strawberry Fride
|
||||||
|
* Talun
|
||||||
|
* TechplexEngineer (Blake Bourque)
|
||||||
|
* TBG Renfold
|
||||||
* tglion
|
* tglion
|
||||||
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
||||||
* tyre
|
* tyre
|
||||||
|
@ -202,3 +206,4 @@ In addition, we would like to thank:
|
||||||
* The Mono Project
|
* The Mono Project
|
||||||
* The NANT Developers
|
* The NANT Developers
|
||||||
* Microsoft (.NET, MSSQL-Adapters)
|
* Microsoft (.NET, MSSQL-Adapters)
|
||||||
|
*x
|
||||||
|
|
|
@ -122,8 +122,9 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||||
Thread.CurrentThread.ManagedThreadId.ToString() +
|
Thread.CurrentThread.ManagedThreadId.ToString() +
|
||||||
")");
|
")");
|
||||||
|
|
||||||
m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
|
bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
|
||||||
m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
|
m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
|
||||||
|
if (changed)
|
||||||
regionsToLoad[i].EstateSettings.Save();
|
regionsToLoad[i].EstateSettings.Save();
|
||||||
|
|
||||||
if (scene != null)
|
if (scene != null)
|
||||||
|
|
|
@ -539,7 +539,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||||
/// path has not already been registered, the method is added to the active
|
/// path has not already been registered, the method is added to the active
|
||||||
/// handler table.
|
/// handler table.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public void AddStreamHandler(string httpMethod, string path, RestMethod method)
|
public void AddStreamHandler(string httpMethod, string path, RestMethod method)
|
||||||
{
|
{
|
||||||
if (!IsEnabled)
|
if (!IsEnabled)
|
||||||
|
|
|
@ -101,18 +101,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdItem.item_id = invItem.ID;
|
llsdItem.item_id = invItem.ID;
|
||||||
llsdItem.name = invItem.Name;
|
llsdItem.name = invItem.Name;
|
||||||
llsdItem.parent_id = invItem.Folder;
|
llsdItem.parent_id = invItem.Folder;
|
||||||
|
llsdItem.type = invItem.AssetType;
|
||||||
try
|
llsdItem.inv_type = invItem.InvType;
|
||||||
{
|
|
||||||
llsdItem.type = Utils.AssetTypeToString((AssetType)invItem.AssetType);
|
|
||||||
llsdItem.inv_type = Utils.InventoryTypeToString((InventoryType)invItem.InvType);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[WEB FETCH INV DESC HANDLER]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}",
|
|
||||||
invItem.AssetType, invItem.InvType, invItem.Name, e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
llsdItem.permissions = new LLSDPermissions();
|
llsdItem.permissions = new LLSDPermissions();
|
||||||
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||||
|
@ -126,21 +116,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||||
llsdItem.sale_info = new LLSDSaleInfo();
|
llsdItem.sale_info = new LLSDSaleInfo();
|
||||||
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||||
switch (invItem.SaleType)
|
llsdItem.sale_info.sale_type = invItem.SaleType;
|
||||||
{
|
|
||||||
default:
|
|
||||||
llsdItem.sale_info.sale_type = "not";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
llsdItem.sale_info.sale_type = "original";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
llsdItem.sale_info.sale_type = "copy";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
llsdItem.sale_info.sale_type = "contents";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return llsdItem;
|
return llsdItem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
|
|
||||||
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService);
|
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService);
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestStreamHandler("POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest);
|
= new RestStreamHandler(
|
||||||
|
"POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
|
||||||
server.AddStreamHandler(reqHandler);
|
server.AddStreamHandler(reqHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,13 +66,14 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||||
|
|
||||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
||||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
|
IRequestHandler reqHandler
|
||||||
delegate(Hashtable m_dhttpMethod)
|
= new RestHTTPHandler(
|
||||||
{
|
"GET",
|
||||||
return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null);
|
"/CAPS/" + UUID.Random(),
|
||||||
});
|
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
||||||
|
"GetMesh",
|
||||||
|
null);
|
||||||
server.AddStreamHandler(reqHandler);
|
server.AddStreamHandler(reqHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -58,8 +58,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
// TODO: Change this to a config option
|
// TODO: Change this to a config option
|
||||||
const string REDIRECT_URL = null;
|
const string REDIRECT_URL = null;
|
||||||
|
|
||||||
public GetTextureHandler(string path, IAssetService assService) :
|
public GetTextureHandler(string path, IAssetService assService, string name, string description)
|
||||||
base("GET", path)
|
: base("GET", path, name, description)
|
||||||
{
|
{
|
||||||
m_assetService = assService;
|
m_assetService = assService;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
||||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID textureID;
|
UUID textureID;
|
||||||
|
@ -115,7 +114,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
||||||
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
||||||
|
|
||||||
httpResponse.Send();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,8 +62,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
if (m_AssetService == null)
|
if (m_AssetService == null)
|
||||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||||
|
|
||||||
server.AddStreamHandler(new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService));
|
server.AddStreamHandler(
|
||||||
|
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -50,9 +50,9 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
|
|
||||||
// Overkill - we only really need the asset service, not a whole scene.
|
// Overkill - we only really need the asset service, not a whole scene.
|
||||||
Scene scene = SceneHelpers.SetupScene();
|
Scene scene = new SceneHelpers().SetupScene();
|
||||||
|
|
||||||
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService);
|
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null);
|
||||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||||
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
||||||
|
|
|
@ -85,8 +85,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
uploader.OnUpLoad += BakedTextureUploaded;
|
uploader.OnUpLoad += BakedTextureUploaded;
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
new BinaryStreamHandler("POST", capsBase + uploaderPath,
|
new BinaryStreamHandler(
|
||||||
uploader.uploaderCaps));
|
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
|
|
@ -156,11 +156,12 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
inv.Folders = new List<InventoryFolderBase>();
|
inv.Folders = new List<InventoryFolderBase>();
|
||||||
inv.Items = new List<InventoryItemBase>();
|
inv.Items = new List<InventoryItemBase>();
|
||||||
int version = 0;
|
int version = 0;
|
||||||
|
int descendents = 0;
|
||||||
|
|
||||||
inv
|
inv
|
||||||
= Fetch(
|
= Fetch(
|
||||||
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
|
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
|
||||||
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
|
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
|
||||||
|
|
||||||
if (inv != null && inv.Folders != null)
|
if (inv != null && inv.Folders != null)
|
||||||
{
|
{
|
||||||
|
@ -168,6 +169,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
|
contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
descendents += inv.Folders.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inv != null && inv.Items != null)
|
if (inv != null && inv.Items != null)
|
||||||
|
@ -178,7 +181,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
|
contents.descendents = descendents;
|
||||||
contents.version = version;
|
contents.version = version;
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
|
@ -206,7 +209,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
/// <returns>An empty InventoryCollection if the inventory look up failed</returns>
|
/// <returns>An empty InventoryCollection if the inventory look up failed</returns>
|
||||||
private InventoryCollection Fetch(
|
private InventoryCollection Fetch(
|
||||||
UUID agentID, UUID folderID, UUID ownerID,
|
UUID agentID, UUID folderID, UUID ownerID,
|
||||||
bool fetchFolders, bool fetchItems, int sortOrder, out int version)
|
bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
// "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
||||||
|
@ -215,6 +218,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
// FIXME MAYBE: We're not handling sortOrder!
|
// FIXME MAYBE: We're not handling sortOrder!
|
||||||
|
|
||||||
version = 0;
|
version = 0;
|
||||||
|
descendents = 0;
|
||||||
|
|
||||||
InventoryFolderImpl fold;
|
InventoryFolderImpl fold;
|
||||||
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
|
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
|
||||||
{
|
{
|
||||||
|
@ -223,6 +228,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
InventoryCollection ret = new InventoryCollection();
|
InventoryCollection ret = new InventoryCollection();
|
||||||
ret.Folders = new List<InventoryFolderBase>();
|
ret.Folders = new List<InventoryFolderBase>();
|
||||||
ret.Items = fold.RequestListOfItems();
|
ret.Items = fold.RequestListOfItems();
|
||||||
|
descendents = ret.Folders.Count + ret.Items.Count;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -246,24 +252,72 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
|
|
||||||
version = containingFolder.Version;
|
version = containingFolder.Version;
|
||||||
|
|
||||||
// if (fetchItems)
|
if (fetchItems)
|
||||||
// {
|
{
|
||||||
// List<InventoryItemBase> linkedItemsToAdd = new List<InventoryItemBase>();
|
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)
|
// foreach (InventoryItemBase item in contents.Items)
|
||||||
// {
|
// {
|
||||||
// if (item.AssetType == (int)AssetType.Link)
|
// m_log.DebugFormat(
|
||||||
// {
|
// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
|
||||||
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
|
||||||
//
|
|
||||||
// // 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)
|
|
||||||
// linkedItemsToAdd.Insert(0, linkedItem);
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// =====
|
||||||
|
|
||||||
//
|
//
|
||||||
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
|
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
|
||||||
// {
|
// {
|
||||||
|
@ -340,12 +394,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdFolder.folder_id = invFolder.ID;
|
llsdFolder.folder_id = invFolder.ID;
|
||||||
llsdFolder.parent_id = invFolder.ParentID;
|
llsdFolder.parent_id = invFolder.ParentID;
|
||||||
llsdFolder.name = invFolder.Name;
|
llsdFolder.name = invFolder.Name;
|
||||||
|
llsdFolder.type = invFolder.Type;
|
||||||
if (invFolder.Type == (short)AssetType.Unknown || !Enum.IsDefined(typeof(AssetType), (sbyte)invFolder.Type))
|
llsdFolder.preferred_type = -1;
|
||||||
llsdFolder.type = "-1";
|
|
||||||
else
|
|
||||||
llsdFolder.type = Utils.AssetTypeToString((AssetType)invFolder.Type);
|
|
||||||
llsdFolder.preferred_type = "-1";
|
|
||||||
|
|
||||||
return llsdFolder;
|
return llsdFolder;
|
||||||
}
|
}
|
||||||
|
@ -365,18 +415,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdItem.item_id = invItem.ID;
|
llsdItem.item_id = invItem.ID;
|
||||||
llsdItem.name = invItem.Name;
|
llsdItem.name = invItem.Name;
|
||||||
llsdItem.parent_id = invItem.Folder;
|
llsdItem.parent_id = invItem.Folder;
|
||||||
|
llsdItem.type = invItem.AssetType;
|
||||||
try
|
llsdItem.inv_type = invItem.InvType;
|
||||||
{
|
|
||||||
llsdItem.type = Utils.AssetTypeToString((AssetType)invItem.AssetType);
|
|
||||||
llsdItem.inv_type = Utils.InventoryTypeToString((InventoryType)invItem.InvType);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[WEB FETCH INV DESC HANDLER]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}",
|
|
||||||
invItem.AssetType, invItem.InvType, invItem.Name, e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
llsdItem.permissions = new LLSDPermissions();
|
llsdItem.permissions = new LLSDPermissions();
|
||||||
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||||
|
@ -390,21 +430,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||||
llsdItem.sale_info = new LLSDSaleInfo();
|
llsdItem.sale_info = new LLSDSaleInfo();
|
||||||
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||||
switch (invItem.SaleType)
|
llsdItem.sale_info.sale_type = invItem.SaleType;
|
||||||
{
|
|
||||||
default:
|
|
||||||
llsdItem.sale_info.sale_type = "not";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
llsdItem.sale_info.sale_type = "original";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
llsdItem.sale_info.sale_type = "copy";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
llsdItem.sale_info.sale_type = "contents";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return llsdItem;
|
return llsdItem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,13 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
|
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
|
||||||
|
|
||||||
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
|
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
|
||||||
IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, webFetchHandler.FetchInventoryDescendentsRequest);
|
IRequestHandler reqHandler
|
||||||
|
= new RestStreamHandler(
|
||||||
|
"POST",
|
||||||
|
"/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
|
||||||
|
webFetchHandler.FetchInventoryDescendentsRequest,
|
||||||
|
"WebFetchInvDesc",
|
||||||
|
null);
|
||||||
server.AddStreamHandler(reqHandler);
|
server.AddStreamHandler(reqHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* 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.Capabilities
|
||||||
|
{
|
||||||
|
[OSDMap]
|
||||||
|
public class LLSDEnvironmentRequest
|
||||||
|
{
|
||||||
|
public UUID messageID;
|
||||||
|
public UUID regionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
[OSDMap]
|
||||||
|
public class LLSDEnvironmentSetResponse
|
||||||
|
{
|
||||||
|
public UUID regionID;
|
||||||
|
public UUID messageID;
|
||||||
|
public Boolean success;
|
||||||
|
public String fail_reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EnvironmentSettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// generates a empty llsd settings response for viewer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageID">the message UUID</param>
|
||||||
|
/// <param name="regionID">the region UUID</param>
|
||||||
|
public static string EmptySettings(UUID messageID, UUID regionID)
|
||||||
|
{
|
||||||
|
OSDArray arr = new OSDArray();
|
||||||
|
LLSDEnvironmentRequest msg = new LLSDEnvironmentRequest();
|
||||||
|
msg.messageID = messageID;
|
||||||
|
msg.regionID = regionID;
|
||||||
|
arr.Array.Add(msg);
|
||||||
|
return LLSDHelpers.SerialiseLLSDReply(arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -35,7 +35,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public UUID folder_id;
|
public UUID folder_id;
|
||||||
public UUID parent_id;
|
public UUID parent_id;
|
||||||
public string name;
|
public string name;
|
||||||
public string type;
|
public int type;
|
||||||
public string preferred_type;
|
public int preferred_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public UUID asset_id;
|
public UUID asset_id;
|
||||||
public UUID item_id;
|
public UUID item_id;
|
||||||
public LLSDPermissions permissions;
|
public LLSDPermissions permissions;
|
||||||
public string type;
|
public int type;
|
||||||
public string inv_type;
|
public int inv_type;
|
||||||
public int flags;
|
public int flags;
|
||||||
|
|
||||||
public LLSDSaleInfo sale_info;
|
public LLSDSaleInfo sale_info;
|
||||||
|
@ -65,7 +65,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public class LLSDSaleInfo
|
public class LLSDSaleInfo
|
||||||
{
|
{
|
||||||
public int sale_price;
|
public int sale_price;
|
||||||
public string sale_type;
|
public int sale_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
[OSDMap]
|
[OSDMap]
|
||||||
|
|
|
@ -39,7 +39,11 @@ namespace OpenSim.Framework.Capabilities
|
||||||
private LLSDMethod<TRequest, TResponse> m_method;
|
private LLSDMethod<TRequest, TResponse> m_method;
|
||||||
|
|
||||||
public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method)
|
public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method)
|
||||||
: base(httpMethod, path)
|
: this(httpMethod, path, method, null, null) {}
|
||||||
|
|
||||||
|
public LLSDStreamhandler(
|
||||||
|
string httpMethod, string path, LLSDMethod<TRequest, TResponse> method, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
{
|
{
|
||||||
m_method = method;
|
m_method = method;
|
||||||
}
|
}
|
||||||
|
@ -62,9 +66,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
|
|
||||||
TResponse response = m_method(llsdRequest);
|
TResponse response = m_method(llsdRequest);
|
||||||
|
|
||||||
Encoding encoding = new UTF8Encoding(false);
|
return Util.UTF8NoBomEncoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
|
||||||
|
|
||||||
return encoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace OpenSim.ConsoleClient
|
||||||
|
|
||||||
request.ContentType = "application/x-www-form-urlencoded";
|
request.ContentType = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
byte[] buffer = new System.Text.ASCIIEncoding().GetBytes(data);
|
byte[] buffer = Encoding.ASCII.GetBytes(data);
|
||||||
int length = (int) buffer.Length;
|
int length = (int) buffer.Length;
|
||||||
request.ContentLength = length;
|
request.ContentLength = length;
|
||||||
|
|
||||||
|
|
|
@ -1181,6 +1181,72 @@ VALUES
|
||||||
// }
|
// }
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Environment Settings
|
||||||
|
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
||||||
|
{
|
||||||
|
string sql = "select * from [regionenvironment] where region_id = @region_id";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
|
||||||
|
conn.Open();
|
||||||
|
using (SqlDataReader result = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
if (!result.Read())
|
||||||
|
{
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Convert.ToString(result["llsd_settings"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
string sql = "DELETE FROM [regionenvironment] WHERE region_id = @region_id";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
|
||||||
|
conn.Open();
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = "INSERT INTO [regionenvironment] (region_id, llsd_settings) VALUES (@region_id, @llsd_settings)";
|
||||||
|
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@llsd_settings", settings));
|
||||||
|
|
||||||
|
conn.Open();
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
||||||
|
{
|
||||||
|
string sql = "delete from [regionenvironment] where region_id = @region_id";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
|
||||||
|
|
||||||
|
conn.Open();
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the settings of a region.
|
/// Loads the settings of a region.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1134,3 +1134,17 @@ ALTER TABLE landaccesslist ADD Expires integer NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 37 #---------------- Environment Settings
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
CREATE TABLE [dbo].[regionenvironment](
|
||||||
|
[region_id] [uniqueidentifier] NOT NULL,
|
||||||
|
[llsd_settings] [varchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[region_id] ASC
|
||||||
|
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
|
@ -163,12 +163,12 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
MySqlCommand cmd =
|
using (MySqlCommand cmd =
|
||||||
new MySqlCommand(
|
new MySqlCommand(
|
||||||
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
|
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
|
||||||
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
|
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
|
||||||
dbcon);
|
dbcon))
|
||||||
|
{
|
||||||
string assetName = asset.Name;
|
string assetName = asset.Name;
|
||||||
if (asset.Name.Length > 64)
|
if (asset.Name.Length > 64)
|
||||||
{
|
{
|
||||||
|
@ -183,7 +183,6 @@ namespace OpenSim.Data.MySQL
|
||||||
m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
|
m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to ensure we dispose
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (cmd)
|
using (cmd)
|
||||||
|
@ -202,7 +201,6 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
||||||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
cmd.Dispose();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,6 +213,7 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateAccessTime(AssetBase asset)
|
private void UpdateAccessTime(AssetBase asset)
|
||||||
{
|
{
|
||||||
|
@ -223,11 +222,10 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
MySqlCommand cmd =
|
|
||||||
new MySqlCommand("update assets set access_time=?access_time where id=?id",
|
|
||||||
dbcon);
|
|
||||||
|
|
||||||
// need to ensure we dispose
|
using (MySqlCommand cmd
|
||||||
|
= new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon))
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (cmd)
|
using (cmd)
|
||||||
|
@ -237,7 +235,6 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||||
cmd.Parameters.AddWithValue("?access_time", now);
|
cmd.Parameters.AddWithValue("?access_time", now);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
cmd.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -249,7 +246,7 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -312,7 +309,12 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
MySqlCommand cmd = new MySqlCommand("SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count", dbcon);
|
|
||||||
|
using (MySqlCommand cmd
|
||||||
|
= new MySqlCommand(
|
||||||
|
"SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count",
|
||||||
|
dbcon))
|
||||||
|
{
|
||||||
cmd.Parameters.AddWithValue("?start", start);
|
cmd.Parameters.AddWithValue("?start", start);
|
||||||
cmd.Parameters.AddWithValue("?count", count);
|
cmd.Parameters.AddWithValue("?count", count);
|
||||||
|
|
||||||
|
@ -344,6 +346,7 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return retList;
|
return retList;
|
||||||
}
|
}
|
||||||
|
@ -355,11 +358,12 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon);
|
|
||||||
|
using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon))
|
||||||
|
{
|
||||||
cmd.Parameters.AddWithValue("?id", id);
|
cmd.Parameters.AddWithValue("?id", id);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
cmd.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,10 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
MySqlCommand cmd = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon);
|
|
||||||
|
using (MySqlCommand cmd
|
||||||
|
= new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon))
|
||||||
|
{
|
||||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||||
|
|
||||||
IDataReader result = cmd.ExecuteReader();
|
IDataReader result = cmd.ExecuteReader();
|
||||||
|
@ -79,14 +82,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
ret.PrincipalID = principalID;
|
ret.PrincipalID = principalID;
|
||||||
|
|
||||||
if (m_ColumnNames == null)
|
CheckColumnNames(result);
|
||||||
{
|
|
||||||
m_ColumnNames = new List<string>();
|
|
||||||
|
|
||||||
DataTable schemaTable = result.GetSchemaTable();
|
|
||||||
foreach (DataRow row in schemaTable.Rows)
|
|
||||||
m_ColumnNames.Add(row["ColumnName"].ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string s in m_ColumnNames)
|
foreach (string s in m_ColumnNames)
|
||||||
{
|
{
|
||||||
|
@ -104,6 +100,21 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckColumnNames(IDataReader result)
|
||||||
|
{
|
||||||
|
if (m_ColumnNames != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
List<string> columnNames = new List<string>();
|
||||||
|
|
||||||
|
DataTable schemaTable = result.GetSchemaTable();
|
||||||
|
foreach (DataRow row in schemaTable.Rows)
|
||||||
|
columnNames.Add(row["ColumnName"].ToString());
|
||||||
|
|
||||||
|
m_ColumnNames = columnNames;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Store(AuthenticationData data)
|
public bool Store(AuthenticationData data)
|
||||||
{
|
{
|
||||||
|
@ -112,8 +123,8 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
string[] fields = new List<string>(data.Data.Keys).ToArray();
|
string[] fields = new List<string>(data.Data.Keys).ToArray();
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
string update = "update `"+m_Realm+"` set ";
|
string update = "update `"+m_Realm+"` set ";
|
||||||
bool first = true;
|
bool first = true;
|
||||||
foreach (string field in fields)
|
foreach (string field in fields)
|
||||||
|
@ -141,28 +152,24 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.CommandText = insert;
|
cmd.CommandText = insert;
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) < 1)
|
if (ExecuteNonQuery(cmd) < 1)
|
||||||
{
|
|
||||||
cmd.Dispose();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Dispose();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetDataItem(UUID principalID, string item, string value)
|
public bool SetDataItem(UUID principalID, string item, string value)
|
||||||
{
|
{
|
||||||
MySqlCommand cmd = new MySqlCommand("update `" + m_Realm +
|
using (MySqlCommand cmd
|
||||||
"` set `" + item + "` = ?" + item + " where UUID = ?UUID");
|
= new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where UUID = ?UUID"))
|
||||||
|
{
|
||||||
|
|
||||||
cmd.Parameters.AddWithValue("?"+item, value);
|
cmd.Parameters.AddWithValue("?"+item, value);
|
||||||
cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) > 0)
|
if (ExecuteNonQuery(cmd) > 0)
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -172,18 +179,18 @@ namespace OpenSim.Data.MySQL
|
||||||
if (System.Environment.TickCount - m_LastExpire > 30000)
|
if (System.Environment.TickCount - m_LastExpire > 30000)
|
||||||
DoExpire();
|
DoExpire();
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand("insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))");
|
using (MySqlCommand cmd
|
||||||
|
= new MySqlCommand(
|
||||||
|
"insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))"))
|
||||||
|
{
|
||||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?token", token);
|
cmd.Parameters.AddWithValue("?token", token);
|
||||||
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) > 0)
|
if (ExecuteNonQuery(cmd) > 0)
|
||||||
{
|
|
||||||
cmd.Dispose();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Dispose();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,28 +199,27 @@ namespace OpenSim.Data.MySQL
|
||||||
if (System.Environment.TickCount - m_LastExpire > 30000)
|
if (System.Environment.TickCount - m_LastExpire > 30000)
|
||||||
DoExpire();
|
DoExpire();
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand("update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()");
|
using (MySqlCommand cmd
|
||||||
|
= new MySqlCommand(
|
||||||
|
"update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()"))
|
||||||
|
{
|
||||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?token", token);
|
cmd.Parameters.AddWithValue("?token", token);
|
||||||
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) > 0)
|
if (ExecuteNonQuery(cmd) > 0)
|
||||||
{
|
|
||||||
cmd.Dispose();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Dispose();
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoExpire()
|
private void DoExpire()
|
||||||
{
|
{
|
||||||
MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()");
|
using (MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()"))
|
||||||
|
{
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
|
}
|
||||||
cmd.Dispose();
|
|
||||||
|
|
||||||
m_LastExpire = System.Environment.TickCount;
|
m_LastExpire = System.Environment.TickCount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,14 +52,15 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public bool Delete(UUID principalID, string name)
|
public bool Delete(UUID principalID, string name)
|
||||||
{
|
{
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
|
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
|
||||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?Name", name);
|
cmd.Parameters.AddWithValue("?Name", name);
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) > 0)
|
if (ExecuteNonQuery(cmd) > 0)
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,34 +49,38 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public bool Delete(string principalID, string friend)
|
public bool Delete(string principalID, string friend)
|
||||||
{
|
{
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
|
cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
|
||||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?Friend", friend);
|
cmd.Parameters.AddWithValue("?Friend", friend);
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FriendsData[] GetFriends(UUID principalID)
|
public FriendsData[] GetFriends(UUID principalID)
|
||||||
{
|
{
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm);
|
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm);
|
||||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||||
|
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public FriendsData[] GetFriends(string principalID)
|
public FriendsData[] GetFriends(string principalID)
|
||||||
{
|
{
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
|
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
|
||||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
|
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
|
||||||
|
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -91,15 +91,17 @@ namespace OpenSim.Data.MySQL
|
||||||
if (m_ColumnNames != null)
|
if (m_ColumnNames != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_ColumnNames = new List<string>();
|
List<string> columnNames = new List<string>();
|
||||||
|
|
||||||
DataTable schemaTable = reader.GetSchemaTable();
|
DataTable schemaTable = reader.GetSchemaTable();
|
||||||
foreach (DataRow row in schemaTable.Rows)
|
foreach (DataRow row in schemaTable.Rows)
|
||||||
{
|
{
|
||||||
if (row["ColumnName"] != null &&
|
if (row["ColumnName"] != null &&
|
||||||
(!m_Fields.ContainsKey(row["ColumnName"].ToString())))
|
(!m_Fields.ContainsKey(row["ColumnName"].ToString())))
|
||||||
m_ColumnNames.Add(row["ColumnName"].ToString());
|
columnNames.Add(row["ColumnName"].ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_ColumnNames = columnNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual T[] Get(string field, string key)
|
public virtual T[] Get(string field, string key)
|
||||||
|
|
|
@ -467,7 +467,8 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
MySqlCommand result = new MySqlCommand(sql, dbcon);
|
using (MySqlCommand result = new MySqlCommand(sql, dbcon))
|
||||||
|
{
|
||||||
result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
|
result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
|
||||||
result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
|
result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
|
||||||
result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
|
result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
|
||||||
|
@ -491,19 +492,18 @@ namespace OpenSim.Data.MySQL
|
||||||
result.Parameters.AddWithValue("?flags", item.Flags);
|
result.Parameters.AddWithValue("?flags", item.Flags);
|
||||||
|
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
{
|
|
||||||
result.ExecuteNonQuery();
|
result.ExecuteNonQuery();
|
||||||
}
|
|
||||||
|
|
||||||
result.Dispose();
|
result.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon);
|
using (MySqlCommand result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon))
|
||||||
|
{
|
||||||
result.Parameters.AddWithValue("?folderID", item.Folder.ToString());
|
result.Parameters.AddWithValue("?folderID", item.Folder.ToString());
|
||||||
|
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
{
|
|
||||||
result.ExecuteNonQuery();
|
result.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
result.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
|
@ -533,11 +533,11 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon);
|
using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon))
|
||||||
|
{
|
||||||
cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
|
cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
|
||||||
|
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
{
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -579,7 +579,8 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand(sql, dbcon);
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||||
|
{
|
||||||
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
|
cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
|
||||||
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
||||||
|
@ -600,6 +601,7 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates an inventory folder
|
/// Updates an inventory folder
|
||||||
|
@ -624,7 +626,8 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand(sql, dbcon);
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||||
|
{
|
||||||
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
||||||
|
|
||||||
|
@ -641,6 +644,7 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Append a list of all the child folders of a parent folder
|
/// Append a list of all the child folders of a parent folder
|
||||||
|
|
|
@ -63,14 +63,15 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public void LogoutRegionAgents(UUID regionID)
|
public void LogoutRegionAgents(UUID regionID)
|
||||||
{
|
{
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
|
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
|
||||||
|
|
||||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool ReportAgent(UUID sessionID, UUID regionID)
|
public bool ReportAgent(UUID sessionID, UUID regionID)
|
||||||
{
|
{
|
||||||
|
@ -81,8 +82,8 @@ namespace OpenSim.Data.MySQL
|
||||||
if (regionID == UUID.Zero)
|
if (regionID == UUID.Zero)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
|
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
|
||||||
|
|
||||||
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
|
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
|
||||||
|
@ -90,6 +91,7 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) == 0)
|
if (ExecuteNonQuery(cmd) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,17 +162,7 @@ namespace OpenSim.Data.MySQL
|
||||||
ret.sizeX = Convert.ToInt32(result["sizeX"]);
|
ret.sizeX = Convert.ToInt32(result["sizeX"]);
|
||||||
ret.sizeY = Convert.ToInt32(result["sizeY"]);
|
ret.sizeY = Convert.ToInt32(result["sizeY"]);
|
||||||
|
|
||||||
if (m_ColumnNames == null)
|
CheckColumnNames(result);
|
||||||
{
|
|
||||||
m_ColumnNames = new List<string>();
|
|
||||||
|
|
||||||
DataTable schemaTable = result.GetSchemaTable();
|
|
||||||
foreach (DataRow row in schemaTable.Rows)
|
|
||||||
{
|
|
||||||
if (row["ColumnName"] != null)
|
|
||||||
m_ColumnNames.Add(row["ColumnName"].ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string s in m_ColumnNames)
|
foreach (string s in m_ColumnNames)
|
||||||
{
|
{
|
||||||
|
@ -187,6 +177,10 @@ namespace OpenSim.Data.MySQL
|
||||||
if (s == "locY")
|
if (s == "locY")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
object value = result[s];
|
||||||
|
if (value is DBNull)
|
||||||
|
ret.Data[s] = null;
|
||||||
|
else
|
||||||
ret.Data[s] = result[s].ToString();
|
ret.Data[s] = result[s].ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +192,23 @@ namespace OpenSim.Data.MySQL
|
||||||
return retList;
|
return retList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CheckColumnNames(IDataReader result)
|
||||||
|
{
|
||||||
|
if (m_ColumnNames != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
List<string> columnNames = new List<string>();
|
||||||
|
|
||||||
|
DataTable schemaTable = result.GetSchemaTable();
|
||||||
|
foreach (DataRow row in schemaTable.Rows)
|
||||||
|
{
|
||||||
|
if (row["ColumnName"] != null)
|
||||||
|
columnNames.Add(row["ColumnName"].ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ColumnNames = columnNames;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Store(RegionData data)
|
public bool Store(RegionData data)
|
||||||
{
|
{
|
||||||
if (data.Data.ContainsKey("uuid"))
|
if (data.Data.ContainsKey("uuid"))
|
||||||
|
@ -318,11 +329,12 @@ namespace OpenSim.Data.MySQL
|
||||||
if (scopeID != UUID.Zero)
|
if (scopeID != UUID.Zero)
|
||||||
command += " and ScopeID = ?scopeID";
|
command += " and ScopeID = ?scopeID";
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand(command);
|
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||||
|
{
|
||||||
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
||||||
|
|
||||||
return RunCommand(cmd);
|
return RunCommand(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -131,8 +131,9 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
MySqlCommand cmd = dbcon.CreateCommand();
|
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
|
{
|
||||||
foreach (SceneObjectPart prim in obj.Parts)
|
foreach (SceneObjectPart prim in obj.Parts)
|
||||||
{
|
{
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
|
@ -244,8 +245,7 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
cmd.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -997,6 +997,68 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region RegionEnvironmentSettings
|
||||||
|
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
||||||
|
{
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
|
||||||
|
string command = "select * from `regionenvironment` where region_id = ?region_id";
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||||
|
{
|
||||||
|
cmd.Connection = dbcon;
|
||||||
|
|
||||||
|
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||||
|
|
||||||
|
IDataReader result = ExecuteReader(cmd);
|
||||||
|
if (!result.Read())
|
||||||
|
{
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Convert.ToString(result["llsd_settings"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
||||||
|
{
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
|
||||||
|
|
||||||
|
cmd.Parameters.AddWithValue("region_id", regionUUID);
|
||||||
|
cmd.Parameters.AddWithValue("llsd_settings", settings);
|
||||||
|
|
||||||
|
ExecuteNonQuery(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
||||||
|
{
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
|
||||||
|
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||||
|
ExecuteNonQuery(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public virtual void StoreRegionSettings(RegionSettings rs)
|
public virtual void StoreRegionSettings(RegionSettings rs)
|
||||||
{
|
{
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
|
@ -1897,15 +1959,15 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
RemoveItems(primID);
|
RemoveItems(primID);
|
||||||
|
|
||||||
|
if (items.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
MySqlCommand cmd = dbcon.CreateCommand();
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
|
{
|
||||||
if (items.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cmd.CommandText = "insert into primitems (" +
|
cmd.CommandText = "insert into primitems (" +
|
||||||
"invType, assetType, name, " +
|
"invType, assetType, name, " +
|
||||||
"description, creationDate, nextPermissions, " +
|
"description, creationDate, nextPermissions, " +
|
||||||
|
@ -1930,8 +1992,7 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
cmd.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,8 @@ namespace OpenSim.Data.MySQL
|
||||||
if (words.Length > 2)
|
if (words.Length > 2)
|
||||||
return new UserAccountData[0];
|
return new UserAccountData[0];
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
if (words.Length == 1)
|
if (words.Length == 1)
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search) and active=1", m_Realm);
|
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search) and active=1", m_Realm);
|
||||||
|
@ -84,11 +84,12 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
||||||
{
|
{
|
||||||
MySqlCommand cmd = new MySqlCommand();
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
if (scopeID != UUID.Zero)
|
if (scopeID != UUID.Zero)
|
||||||
{
|
{
|
||||||
where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")";
|
where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")";
|
||||||
|
@ -100,4 +101,5 @@ namespace OpenSim.Data.MySQL
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -883,3 +883,15 @@ ALTER TABLE `regionsettings` MODIFY COLUMN `TelehubObject` VARCHAR(36) NOT NULL
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
:VERSION 44 #--------------------- Environment Settings
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE `regionenvironment` (
|
||||||
|
`region_id` varchar(36) NOT NULL,
|
||||||
|
`llsd_settings` TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (`region_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,24 @@ namespace OpenSim.Data.Null
|
||||||
//This connector doesn't support the windlight module yet
|
//This connector doesn't support the windlight module yet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Environment Settings
|
||||||
|
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
||||||
|
{
|
||||||
|
//This connector doesn't support the Environment module yet
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
||||||
|
{
|
||||||
|
//This connector doesn't support the Environment module yet
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
||||||
|
{
|
||||||
|
//This connector doesn't support the Environment module yet
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||||
{
|
{
|
||||||
RegionSettings rs = new RegionSettings();
|
RegionSettings rs = new RegionSettings();
|
||||||
|
|
|
@ -564,3 +564,14 @@ COMMIT;
|
||||||
BEGIN;
|
BEGIN;
|
||||||
ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
:VERSION 26
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE `regionenvironment` (
|
||||||
|
`region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY,
|
||||||
|
`llsd_settings` TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
|
@ -61,6 +61,7 @@ namespace OpenSim.Data.SQLite
|
||||||
private const string regionbanListSelect = "select * from regionban";
|
private const string regionbanListSelect = "select * from regionban";
|
||||||
private const string regionSettingsSelect = "select * from regionsettings";
|
private const string regionSettingsSelect = "select * from regionsettings";
|
||||||
private const string regionWindlightSelect = "select * from regionwindlight";
|
private const string regionWindlightSelect = "select * from regionwindlight";
|
||||||
|
private const string regionEnvironmentSelect = "select * from regionenvironment";
|
||||||
private const string regionSpawnPointsSelect = "select * from spawn_points";
|
private const string regionSpawnPointsSelect = "select * from spawn_points";
|
||||||
|
|
||||||
private DataSet ds;
|
private DataSet ds;
|
||||||
|
@ -72,6 +73,7 @@ namespace OpenSim.Data.SQLite
|
||||||
private SqliteDataAdapter landAccessListDa;
|
private SqliteDataAdapter landAccessListDa;
|
||||||
private SqliteDataAdapter regionSettingsDa;
|
private SqliteDataAdapter regionSettingsDa;
|
||||||
private SqliteDataAdapter regionWindlightDa;
|
private SqliteDataAdapter regionWindlightDa;
|
||||||
|
private SqliteDataAdapter regionEnvironmentDa;
|
||||||
private SqliteDataAdapter regionSpawnPointsDa;
|
private SqliteDataAdapter regionSpawnPointsDa;
|
||||||
|
|
||||||
private SqliteConnection m_conn;
|
private SqliteConnection m_conn;
|
||||||
|
@ -146,6 +148,9 @@ namespace OpenSim.Data.SQLite
|
||||||
SqliteCommand regionWindlightSelectCmd = new SqliteCommand(regionWindlightSelect, m_conn);
|
SqliteCommand regionWindlightSelectCmd = new SqliteCommand(regionWindlightSelect, m_conn);
|
||||||
regionWindlightDa = new SqliteDataAdapter(regionWindlightSelectCmd);
|
regionWindlightDa = new SqliteDataAdapter(regionWindlightSelectCmd);
|
||||||
|
|
||||||
|
SqliteCommand regionEnvironmentSelectCmd = new SqliteCommand(regionEnvironmentSelect, m_conn);
|
||||||
|
regionEnvironmentDa = new SqliteDataAdapter(regionEnvironmentSelectCmd);
|
||||||
|
|
||||||
SqliteCommand regionSpawnPointsSelectCmd = new SqliteCommand(regionSpawnPointsSelect, m_conn);
|
SqliteCommand regionSpawnPointsSelectCmd = new SqliteCommand(regionSpawnPointsSelect, m_conn);
|
||||||
regionSpawnPointsDa = new SqliteDataAdapter(regionSpawnPointsSelectCmd);
|
regionSpawnPointsDa = new SqliteDataAdapter(regionSpawnPointsSelectCmd);
|
||||||
|
|
||||||
|
@ -179,6 +184,9 @@ namespace OpenSim.Data.SQLite
|
||||||
ds.Tables.Add(createRegionWindlightTable());
|
ds.Tables.Add(createRegionWindlightTable());
|
||||||
setupRegionWindlightCommands(regionWindlightDa, m_conn);
|
setupRegionWindlightCommands(regionWindlightDa, m_conn);
|
||||||
|
|
||||||
|
ds.Tables.Add(createRegionEnvironmentTable());
|
||||||
|
setupRegionEnvironmentCommands(regionEnvironmentDa, m_conn);
|
||||||
|
|
||||||
ds.Tables.Add(createRegionSpawnPointsTable());
|
ds.Tables.Add(createRegionSpawnPointsTable());
|
||||||
setupRegionSpawnPointsCommands(regionSpawnPointsDa, m_conn);
|
setupRegionSpawnPointsCommands(regionSpawnPointsDa, m_conn);
|
||||||
|
|
||||||
|
@ -258,6 +266,15 @@ namespace OpenSim.Data.SQLite
|
||||||
m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionwindlight table :{0}", e.Message);
|
m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionwindlight table :{0}", e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
regionEnvironmentDa.Fill(ds.Tables["regionenvironment"]);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionenvironment table :{0}", e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
regionSpawnPointsDa.Fill(ds.Tables["spawn_points"]);
|
regionSpawnPointsDa.Fill(ds.Tables["spawn_points"]);
|
||||||
|
@ -278,12 +295,13 @@ namespace OpenSim.Data.SQLite
|
||||||
CreateDataSetMapping(landAccessListDa, "landaccesslist");
|
CreateDataSetMapping(landAccessListDa, "landaccesslist");
|
||||||
CreateDataSetMapping(regionSettingsDa, "regionsettings");
|
CreateDataSetMapping(regionSettingsDa, "regionsettings");
|
||||||
CreateDataSetMapping(regionWindlightDa, "regionwindlight");
|
CreateDataSetMapping(regionWindlightDa, "regionwindlight");
|
||||||
|
CreateDataSetMapping(regionEnvironmentDa, "regionenvironment");
|
||||||
CreateDataSetMapping(regionSpawnPointsDa, "spawn_points");
|
CreateDataSetMapping(regionSpawnPointsDa, "spawn_points");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[SQLITE REGION DB]: ", e);
|
m_log.ErrorFormat("[SQLITE REGION DB]: {0} - {1}", e.Message, e.StackTrace);
|
||||||
Environment.Exit(23);
|
Environment.Exit(23);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -341,6 +359,11 @@ namespace OpenSim.Data.SQLite
|
||||||
regionWindlightDa.Dispose();
|
regionWindlightDa.Dispose();
|
||||||
regionWindlightDa = null;
|
regionWindlightDa = null;
|
||||||
}
|
}
|
||||||
|
if (regionEnvironmentDa != null)
|
||||||
|
{
|
||||||
|
regionEnvironmentDa.Dispose();
|
||||||
|
regionEnvironmentDa = null;
|
||||||
|
}
|
||||||
if (regionSpawnPointsDa != null)
|
if (regionSpawnPointsDa != null)
|
||||||
{
|
{
|
||||||
regionSpawnPointsDa.Dispose();
|
regionSpawnPointsDa.Dispose();
|
||||||
|
@ -474,6 +497,63 @@ namespace OpenSim.Data.SQLite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Region Environment Settings
|
||||||
|
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
||||||
|
{
|
||||||
|
lock (ds)
|
||||||
|
{
|
||||||
|
DataTable environmentTable = ds.Tables["regionenvironment"];
|
||||||
|
DataRow row = environmentTable.Rows.Find(regionUUID.ToString());
|
||||||
|
if (row == null)
|
||||||
|
{
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (String)row["llsd_settings"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
||||||
|
{
|
||||||
|
lock (ds)
|
||||||
|
{
|
||||||
|
DataTable environmentTable = ds.Tables["regionenvironment"];
|
||||||
|
DataRow row = environmentTable.Rows.Find(regionUUID.ToString());
|
||||||
|
|
||||||
|
if (row == null)
|
||||||
|
{
|
||||||
|
row = environmentTable.NewRow();
|
||||||
|
row["region_id"] = regionUUID.ToString();
|
||||||
|
row["llsd_settings"] = settings;
|
||||||
|
environmentTable.Rows.Add(row);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
row["llsd_settings"] = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
regionEnvironmentDa.Update(ds, "regionenvironment");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
||||||
|
{
|
||||||
|
lock (ds)
|
||||||
|
{
|
||||||
|
DataTable environmentTable = ds.Tables["regionenvironment"];
|
||||||
|
DataRow row = environmentTable.Rows.Find(regionUUID.ToString());
|
||||||
|
|
||||||
|
if (row != null)
|
||||||
|
{
|
||||||
|
row.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
regionEnvironmentDa.Update(ds, "regionenvironment");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||||
{
|
{
|
||||||
lock (ds)
|
lock (ds)
|
||||||
|
@ -1430,6 +1510,17 @@ namespace OpenSim.Data.SQLite
|
||||||
return regionwindlight;
|
return regionwindlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DataTable createRegionEnvironmentTable()
|
||||||
|
{
|
||||||
|
DataTable regionEnvironment = new DataTable("regionenvironment");
|
||||||
|
createCol(regionEnvironment, "region_id", typeof(String));
|
||||||
|
createCol(regionEnvironment, "llsd_settings", typeof(String));
|
||||||
|
|
||||||
|
regionEnvironment.PrimaryKey = new DataColumn[] { regionEnvironment.Columns["region_id"] };
|
||||||
|
|
||||||
|
return regionEnvironment;
|
||||||
|
}
|
||||||
|
|
||||||
private static DataTable createRegionSpawnPointsTable()
|
private static DataTable createRegionSpawnPointsTable()
|
||||||
{
|
{
|
||||||
DataTable spawn_points = new DataTable("spawn_points");
|
DataTable spawn_points = new DataTable("spawn_points");
|
||||||
|
@ -2691,6 +2782,14 @@ namespace OpenSim.Data.SQLite
|
||||||
da.UpdateCommand.Connection = conn;
|
da.UpdateCommand.Connection = conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupRegionEnvironmentCommands(SqliteDataAdapter da, SqliteConnection conn)
|
||||||
|
{
|
||||||
|
da.InsertCommand = createInsertCommand("regionenvironment", ds.Tables["regionenvironment"]);
|
||||||
|
da.InsertCommand.Connection = conn;
|
||||||
|
da.UpdateCommand = createUpdateCommand("regionenvironment", "region_id=:region_id", ds.Tables["regionenvironment"]);
|
||||||
|
da.UpdateCommand.Connection = conn;
|
||||||
|
}
|
||||||
|
|
||||||
private void setupRegionSpawnPointsCommands(SqliteDataAdapter da, SqliteConnection conn)
|
private void setupRegionSpawnPointsCommands(SqliteDataAdapter da, SqliteConnection conn)
|
||||||
{
|
{
|
||||||
da.InsertCommand = createInsertCommand("spawn_points", ds.Tables["spawn_points"]);
|
da.InsertCommand = createInsertCommand("spawn_points", ds.Tables["spawn_points"]);
|
||||||
|
|
|
@ -1069,8 +1069,6 @@ namespace OpenSim.Data.Tests
|
||||||
regionInfo.RegionLocX = 0;
|
regionInfo.RegionLocX = 0;
|
||||||
regionInfo.RegionLocY = 0;
|
regionInfo.RegionLocY = 0;
|
||||||
|
|
||||||
Scene scene = new Scene(regionInfo);
|
|
||||||
|
|
||||||
SceneObjectPart sop = new SceneObjectPart();
|
SceneObjectPart sop = new SceneObjectPart();
|
||||||
sop.Name = name;
|
sop.Name = name;
|
||||||
sop.Description = name;
|
sop.Description = name;
|
||||||
|
@ -1081,7 +1079,7 @@ namespace OpenSim.Data.Tests
|
||||||
sop.Shape = PrimitiveBaseShape.Default;
|
sop.Shape = PrimitiveBaseShape.Default;
|
||||||
|
|
||||||
SceneObjectGroup sog = new SceneObjectGroup(sop);
|
SceneObjectGroup sog = new SceneObjectGroup(sop);
|
||||||
sog.SetScene(scene);
|
// sog.SetScene(scene);
|
||||||
|
|
||||||
return sog;
|
return sog;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,11 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string lastname;
|
public string lastname;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Agent's full name.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get { return string.Format("{0} {1}", firstname, lastname); } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Random Unique GUID for this session. Client gets this at login and it's
|
/// Random Unique GUID for this session. Client gets this at login and it's
|
||||||
/// only supposed to be disclosed over secure channels
|
/// only supposed to be disclosed over secure channels
|
||||||
|
|
|
@ -79,7 +79,11 @@ namespace OpenSim.Framework.Console
|
||||||
public List<CommandDelegate> fn;
|
public List<CommandDelegate> fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public const string GeneralHelpText = "For more information, type 'help <item>' where <item> is one of the following categories:";
|
public const string GeneralHelpText
|
||||||
|
= "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 <item>' where <item> is one of the following:";
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Commands organized by keyword in a tree
|
/// Commands organized by keyword in a tree
|
||||||
|
@ -108,7 +112,9 @@ namespace OpenSim.Framework.Console
|
||||||
// General help
|
// General help
|
||||||
if (helpParts.Count == 0)
|
if (helpParts.Count == 0)
|
||||||
{
|
{
|
||||||
|
help.Add(""); // Will become a newline.
|
||||||
help.Add(GeneralHelpText);
|
help.Add(GeneralHelpText);
|
||||||
|
help.Add(ItemHelpText);
|
||||||
help.AddRange(CollectModulesHelp(tree));
|
help.AddRange(CollectModulesHelp(tree));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -132,7 +138,7 @@ namespace OpenSim.Framework.Console
|
||||||
// Check modules first to see if we just need to display a list of those commands
|
// Check modules first to see if we just need to display a list of those commands
|
||||||
if (TryCollectModuleHelp(originalHelpRequest, help))
|
if (TryCollectModuleHelp(originalHelpRequest, help))
|
||||||
{
|
{
|
||||||
help.Insert(0, GeneralHelpText);
|
help.Insert(0, ItemHelpText);
|
||||||
return help;
|
return help;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Used to generated a formatted table for the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Currently subject to change. If you use this, be prepared to change your code when this class changes.
|
||||||
|
/// </remarks>
|
||||||
|
public class ConsoleDisplayList
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The default divider between key and value for a list item.
|
||||||
|
/// </summary>
|
||||||
|
public const string DefaultKeyValueDivider = " : ";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The divider used between key and value for a list item.
|
||||||
|
/// </summary>
|
||||||
|
public string KeyValueDivider { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Table rows
|
||||||
|
/// </summary>
|
||||||
|
public List<KeyValuePair<string, string>> Rows { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of spaces to indent the list.
|
||||||
|
/// </summary>
|
||||||
|
public int Indent { get; set; }
|
||||||
|
|
||||||
|
public ConsoleDisplayList()
|
||||||
|
{
|
||||||
|
Rows = new List<KeyValuePair<string, string>>();
|
||||||
|
KeyValueDivider = DefaultKeyValueDivider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
AddToStringBuilder(sb);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddToStringBuilder(StringBuilder sb)
|
||||||
|
{
|
||||||
|
string formatString = GetFormatString();
|
||||||
|
// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
|
||||||
|
|
||||||
|
// rows
|
||||||
|
foreach (KeyValuePair<string, string> row in Rows)
|
||||||
|
sb.AppendFormat(formatString, row.Key, row.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the format string for the table.
|
||||||
|
/// </summary>
|
||||||
|
private string GetFormatString()
|
||||||
|
{
|
||||||
|
StringBuilder formatSb = new StringBuilder();
|
||||||
|
|
||||||
|
int longestKey = -1;
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> row in Rows)
|
||||||
|
if (row.Key.Length > longestKey)
|
||||||
|
longestKey = row.Key.Length;
|
||||||
|
|
||||||
|
formatSb.Append(' ', Indent);
|
||||||
|
|
||||||
|
// Can only do left formatting for now
|
||||||
|
formatSb.AppendFormat("{{0,-{0}}}{1}{{1}}\n", longestKey, KeyValueDivider);
|
||||||
|
|
||||||
|
return formatSb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRow(object key, object value)
|
||||||
|
{
|
||||||
|
Rows.Add(new KeyValuePair<string, string>(key.ToString(), value.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Used to generated a formatted table for the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Currently subject to change. If you use this, be prepared to change your code when this class changes.
|
||||||
|
/// </remarks>
|
||||||
|
public class ConsoleDisplayTable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Default number of spaces between table columns.
|
||||||
|
/// </summary>
|
||||||
|
public const int DefaultTableSpacing = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Table columns.
|
||||||
|
/// </summary>
|
||||||
|
public List<ConsoleDisplayTableColumn> Columns { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Table rows
|
||||||
|
/// </summary>
|
||||||
|
public List<ConsoleDisplayTableRow> Rows { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of spaces to indent the table.
|
||||||
|
/// </summary>
|
||||||
|
public int Indent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spacing between table columns
|
||||||
|
/// </summary>
|
||||||
|
public int TableSpacing { get; set; }
|
||||||
|
|
||||||
|
public ConsoleDisplayTable()
|
||||||
|
{
|
||||||
|
TableSpacing = DefaultTableSpacing;
|
||||||
|
Columns = new List<ConsoleDisplayTableColumn>();
|
||||||
|
Rows = new List<ConsoleDisplayTableRow>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
AddToStringBuilder(sb);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddColumn(string name, int width)
|
||||||
|
{
|
||||||
|
Columns.Add(new ConsoleDisplayTableColumn(name, width));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRow(params string[] cells)
|
||||||
|
{
|
||||||
|
Rows.Add(new ConsoleDisplayTableRow(cells));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddToStringBuilder(StringBuilder sb)
|
||||||
|
{
|
||||||
|
string formatString = GetFormatString();
|
||||||
|
// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
|
||||||
|
|
||||||
|
// columns
|
||||||
|
sb.AppendFormat(formatString, Columns.ConvertAll(c => c.Header).ToArray());
|
||||||
|
|
||||||
|
// rows
|
||||||
|
foreach (ConsoleDisplayTableRow row in Rows)
|
||||||
|
sb.AppendFormat(formatString, row.Cells.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the format string for the table.
|
||||||
|
/// </summary>
|
||||||
|
private string GetFormatString()
|
||||||
|
{
|
||||||
|
StringBuilder formatSb = new StringBuilder();
|
||||||
|
|
||||||
|
formatSb.Append(' ', Indent);
|
||||||
|
|
||||||
|
for (int i = 0; i < Columns.Count; i++)
|
||||||
|
{
|
||||||
|
formatSb.Append(' ', TableSpacing);
|
||||||
|
|
||||||
|
// Can only do left formatting for now
|
||||||
|
formatSb.AppendFormat("{{{0},-{1}}}", i, Columns[i].Width);
|
||||||
|
}
|
||||||
|
|
||||||
|
formatSb.Append('\n');
|
||||||
|
|
||||||
|
return formatSb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ConsoleDisplayTableColumn
|
||||||
|
{
|
||||||
|
public string Header { get; set; }
|
||||||
|
public int Width { get; set; }
|
||||||
|
|
||||||
|
public ConsoleDisplayTableColumn(string header, int width) : this()
|
||||||
|
{
|
||||||
|
Header = header;
|
||||||
|
Width = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ConsoleDisplayTableRow
|
||||||
|
{
|
||||||
|
public List<string> Cells { get; private set; }
|
||||||
|
|
||||||
|
public ConsoleDisplayTableRow(List<string> cells) : this()
|
||||||
|
{
|
||||||
|
Cells = cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConsoleDisplayTableRow(params string[] cells) : this()
|
||||||
|
{
|
||||||
|
Cells = new List<string>(cells);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -296,6 +296,10 @@ namespace OpenSim.Framework.Console
|
||||||
matches[0].Groups["Category"].Value);
|
matches[0].Groups["Category"].Value);
|
||||||
System.Console.Write("]:");
|
System.Console.Write("]:");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outText = outText.Trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level == "error")
|
if (level == "error")
|
||||||
|
|
|
@ -346,7 +346,7 @@ namespace OpenSim.Framework
|
||||||
l_EstateManagers.Remove(avatarID);
|
l_EstateManagers.Remove(avatarID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsEstateManager(UUID avatarID)
|
public bool IsEstateManagerOrOwner(UUID avatarID)
|
||||||
{
|
{
|
||||||
if (IsEstateOwner(avatarID))
|
if (IsEstateOwner(avatarID))
|
||||||
return true;
|
return true;
|
||||||
|
@ -368,7 +368,7 @@ namespace OpenSim.Framework
|
||||||
if (ban.BannedUserID == avatarID)
|
if (ban.BannedUserID == avatarID)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!IsEstateManager(avatarID) && !HasAccess(avatarID))
|
if (!IsEstateManagerOrOwner(avatarID) && !HasAccess(avatarID))
|
||||||
{
|
{
|
||||||
if (DenyMinors)
|
if (DenyMinors)
|
||||||
{
|
{
|
||||||
|
@ -411,7 +411,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public bool HasAccess(UUID user)
|
public bool HasAccess(UUID user)
|
||||||
{
|
{
|
||||||
if (IsEstateManager(user))
|
if (IsEstateManagerOrOwner(user))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return l_EstateAccess.Contains(user);
|
return l_EstateAccess.Contains(user);
|
||||||
|
|
|
@ -749,14 +749,21 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
|
|
||||||
/// <value>
|
/// <summary>
|
||||||
/// Determines whether the client thread is doing anything or not.
|
/// True if the client is active (sending and receiving new UDP messages). False if the client is being closed.
|
||||||
/// </value>
|
/// </summary>
|
||||||
bool IsActive { get; set; }
|
bool IsActive { get; set; }
|
||||||
|
|
||||||
/// <value>
|
/// <summary>
|
||||||
/// Determines whether the client is or has been removed from a given scene
|
/// Set if the client is closing due to a logout request
|
||||||
/// </value>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Do not use this flag if you want to know if the client is closing, since it will not be set in other
|
||||||
|
/// circumstances (e.g. if a child agent is closed or the agent is kicked off the simulator). Use IsActive
|
||||||
|
/// instead with a IClientAPI.SceneAgent.IsChildAgent check if necessary.
|
||||||
|
///
|
||||||
|
/// Only set for root agents.
|
||||||
|
/// </remarks>
|
||||||
bool IsLoggingOut { get; set; }
|
bool IsLoggingOut { get; set; }
|
||||||
|
|
||||||
bool SendLogoutPacketWhenClosing { set; }
|
bool SendLogoutPacketWhenClosing { set; }
|
||||||
|
@ -1362,7 +1369,6 @@ namespace OpenSim.Framework
|
||||||
void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message);
|
void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message);
|
||||||
|
|
||||||
void SendLogoutPacket();
|
void SendLogoutPacket();
|
||||||
EndPoint GetClientEP();
|
|
||||||
|
|
||||||
// WARNING WARNING WARNING
|
// WARNING WARNING WARNING
|
||||||
//
|
//
|
||||||
|
@ -1423,8 +1429,6 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes);
|
void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes);
|
||||||
|
|
||||||
void KillEndDone();
|
|
||||||
|
|
||||||
bool AddGenericPacketHandler(string MethodName, GenericMessage handler);
|
bool AddGenericPacketHandler(string MethodName, GenericMessage handler);
|
||||||
|
|
||||||
void SendRebakeAvatarTextures(UUID textureID);
|
void SendRebakeAvatarTextures(UUID textureID);
|
||||||
|
|
|
@ -56,6 +56,11 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public interface IScene
|
public interface IScene
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The name of this scene.
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
RegionInfo RegionInfo { get; }
|
RegionInfo RegionInfo { get; }
|
||||||
RegionStatus RegionStatus { get; set; }
|
RegionStatus RegionStatus { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
@ -71,5 +72,11 @@ namespace OpenSim.Framework
|
||||||
/// This includes scene object data and the appearance data of other avatars.
|
/// This includes scene object data and the appearance data of other avatars.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
void SendInitialDataToMe();
|
void SendInitialDataToMe();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Direction in which the scene presence is looking.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Will be Vector3.Zero for a child agent.</remarks>
|
||||||
|
Vector3 Lookat { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -241,11 +241,15 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
m_textureEntry = prim.Textures.GetBytes();
|
m_textureEntry = prim.Textures.GetBytes();
|
||||||
|
|
||||||
|
if (prim.Sculpt != null)
|
||||||
|
{
|
||||||
SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None);
|
SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None);
|
||||||
SculptData = prim.Sculpt.GetBytes();
|
SculptData = prim.Sculpt.GetBytes();
|
||||||
SculptTexture = prim.Sculpt.SculptTexture;
|
SculptTexture = prim.Sculpt.SculptTexture;
|
||||||
SculptType = (byte)prim.Sculpt.Type;
|
SculptType = (byte)prim.Sculpt.Type;
|
||||||
}
|
}
|
||||||
|
else SculptType = (byte)OpenMetaverse.SculptType.None;
|
||||||
|
}
|
||||||
|
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public Primitive.TextureEntry Textures
|
public Primitive.TextureEntry Textures
|
||||||
|
|
|
@ -29,6 +29,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
@ -71,6 +72,32 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
return pos + offset;
|
return pos + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a string representation of this SpawnPoint.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("{0},{1},{2}", Yaw, Pitch, Distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate a SpawnPoint from a string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
public static SpawnPoint Parse(string str)
|
||||||
|
{
|
||||||
|
string[] parts = str.Split(',');
|
||||||
|
if (parts.Length != 3)
|
||||||
|
throw new ArgumentException("Invalid string: " + str);
|
||||||
|
|
||||||
|
SpawnPoint sp = new SpawnPoint();
|
||||||
|
sp.Yaw = float.Parse(parts[0]);
|
||||||
|
sp.Pitch = float.Parse(parts[1]);
|
||||||
|
sp.Distance = float.Parse(parts[2]);
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RegionSettings
|
public class RegionSettings
|
||||||
|
@ -478,7 +505,7 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connected Telehub object
|
// Connected Telehub object
|
||||||
private UUID m_TelehubObject;
|
private UUID m_TelehubObject = UUID.Zero;
|
||||||
public UUID TelehubObject
|
public UUID TelehubObject
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -41,236 +41,186 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
#region SL / file extension / content-type conversions
|
#region SL / file extension / content-type conversions
|
||||||
|
|
||||||
|
private class TypeMapping
|
||||||
|
{
|
||||||
|
private sbyte assetType;
|
||||||
|
private InventoryType inventoryType;
|
||||||
|
private string contentType;
|
||||||
|
private string contentType2;
|
||||||
|
private string extension;
|
||||||
|
|
||||||
|
public sbyte AssetTypeCode
|
||||||
|
{
|
||||||
|
get { return assetType; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public object AssetType
|
||||||
|
{
|
||||||
|
get {
|
||||||
|
if (Enum.IsDefined(typeof(OpenMetaverse.AssetType), assetType))
|
||||||
|
return (OpenMetaverse.AssetType)assetType;
|
||||||
|
else
|
||||||
|
return OpenMetaverse.AssetType.Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public InventoryType InventoryType
|
||||||
|
{
|
||||||
|
get { return inventoryType; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ContentType
|
||||||
|
{
|
||||||
|
get { return contentType; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ContentType2
|
||||||
|
{
|
||||||
|
get { return contentType2; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Extension
|
||||||
|
{
|
||||||
|
get { return extension; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private TypeMapping(sbyte assetType, InventoryType inventoryType, string contentType, string contentType2, string extension)
|
||||||
|
{
|
||||||
|
this.assetType = assetType;
|
||||||
|
this.inventoryType = inventoryType;
|
||||||
|
this.contentType = contentType;
|
||||||
|
this.contentType2 = contentType2;
|
||||||
|
this.extension = extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string contentType2, string extension)
|
||||||
|
: this((sbyte)assetType, inventoryType, contentType, contentType2, extension)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string extension)
|
||||||
|
: this((sbyte)assetType, inventoryType, contentType, null, extension)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps between AssetType, InventoryType and Content-Type.
|
||||||
|
/// Where more than one possibility exists, the first one takes precedence. E.g.:
|
||||||
|
/// AssetType "AssetType.Texture" -> Content-Type "image-xj2c"
|
||||||
|
/// Content-Type "image/x-j2c" -> InventoryType "InventoryType.Texture"
|
||||||
|
/// </summary>
|
||||||
|
private static TypeMapping[] MAPPINGS = new TypeMapping[] {
|
||||||
|
new TypeMapping(AssetType.Unknown, InventoryType.Unknown, "application/octet-stream", "bin"),
|
||||||
|
new TypeMapping(AssetType.Texture, InventoryType.Texture, "image/x-j2c", "image/jp2", "j2c"),
|
||||||
|
new TypeMapping(AssetType.Texture, InventoryType.Snapshot, "image/x-j2c", "image/jp2", "j2c"),
|
||||||
|
new TypeMapping(AssetType.TextureTGA, InventoryType.Texture, "image/tga", "tga"),
|
||||||
|
new TypeMapping(AssetType.ImageTGA, InventoryType.Texture, "image/tga", "tga"),
|
||||||
|
new TypeMapping(AssetType.ImageJPEG, InventoryType.Texture, "image/jpeg", "jpg"),
|
||||||
|
new TypeMapping(AssetType.Sound, InventoryType.Sound, "audio/ogg", "application/ogg", "ogg"),
|
||||||
|
new TypeMapping(AssetType.SoundWAV, InventoryType.Sound, "audio/x-wav", "wav"),
|
||||||
|
new TypeMapping(AssetType.CallingCard, InventoryType.CallingCard, "application/vnd.ll.callingcard", "application/x-metaverse-callingcard", "callingcard"),
|
||||||
|
new TypeMapping(AssetType.Landmark, InventoryType.Landmark, "application/vnd.ll.landmark", "application/x-metaverse-landmark", "landmark"),
|
||||||
|
new TypeMapping(AssetType.Clothing, InventoryType.Wearable, "application/vnd.ll.clothing", "application/x-metaverse-clothing", "clothing"),
|
||||||
|
new TypeMapping(AssetType.Object, InventoryType.Object, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"),
|
||||||
|
new TypeMapping(AssetType.Object, InventoryType.Attachment, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"),
|
||||||
|
new TypeMapping(AssetType.Notecard, InventoryType.Notecard, "application/vnd.ll.notecard", "application/x-metaverse-notecard", "notecard"),
|
||||||
|
new TypeMapping(AssetType.Folder, InventoryType.Folder, "application/vnd.ll.folder", "folder"),
|
||||||
|
new TypeMapping(AssetType.RootFolder, InventoryType.RootCategory, "application/vnd.ll.rootfolder", "rootfolder"),
|
||||||
|
new TypeMapping(AssetType.LSLText, InventoryType.LSL, "application/vnd.ll.lsltext", "application/x-metaverse-lsl", "lsl"),
|
||||||
|
new TypeMapping(AssetType.LSLBytecode, InventoryType.LSL, "application/vnd.ll.lslbyte", "application/x-metaverse-lso", "lso"),
|
||||||
|
new TypeMapping(AssetType.Bodypart, InventoryType.Wearable, "application/vnd.ll.bodypart", "application/x-metaverse-bodypart", "bodypart"),
|
||||||
|
new TypeMapping(AssetType.TrashFolder, InventoryType.Folder, "application/vnd.ll.trashfolder", "trashfolder"),
|
||||||
|
new TypeMapping(AssetType.SnapshotFolder, InventoryType.Folder, "application/vnd.ll.snapshotfolder", "snapshotfolder"),
|
||||||
|
new TypeMapping(AssetType.LostAndFoundFolder, InventoryType.Folder, "application/vnd.ll.lostandfoundfolder", "lostandfoundfolder"),
|
||||||
|
new TypeMapping(AssetType.Animation, InventoryType.Animation, "application/vnd.ll.animation", "application/x-metaverse-animation", "animation"),
|
||||||
|
new TypeMapping(AssetType.Gesture, InventoryType.Gesture, "application/vnd.ll.gesture", "application/x-metaverse-gesture", "gesture"),
|
||||||
|
new TypeMapping(AssetType.Simstate, InventoryType.Snapshot, "application/x-metaverse-simstate", "simstate"),
|
||||||
|
new TypeMapping(AssetType.FavoriteFolder, InventoryType.Unknown, "application/vnd.ll.favoritefolder", "favoritefolder"),
|
||||||
|
new TypeMapping(AssetType.Link, InventoryType.Unknown, "application/vnd.ll.link", "link"),
|
||||||
|
new TypeMapping(AssetType.LinkFolder, InventoryType.Unknown, "application/vnd.ll.linkfolder", "linkfolder"),
|
||||||
|
new TypeMapping(AssetType.CurrentOutfitFolder, InventoryType.Unknown, "application/vnd.ll.currentoutfitfolder", "currentoutfitfolder"),
|
||||||
|
new TypeMapping(AssetType.OutfitFolder, InventoryType.Unknown, "application/vnd.ll.outfitfolder", "outfitfolder"),
|
||||||
|
new TypeMapping(AssetType.MyOutfitsFolder, InventoryType.Unknown, "application/vnd.ll.myoutfitsfolder", "myoutfitsfolder"),
|
||||||
|
new TypeMapping(AssetType.Mesh, InventoryType.Mesh, "application/vnd.ll.mesh", "llm")
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Dictionary<sbyte, string> asset2Content;
|
||||||
|
private static Dictionary<sbyte, string> asset2Extension;
|
||||||
|
private static Dictionary<InventoryType, string> inventory2Content;
|
||||||
|
private static Dictionary<string, sbyte> content2Asset;
|
||||||
|
private static Dictionary<string, InventoryType> content2Inventory;
|
||||||
|
|
||||||
|
static SLUtil()
|
||||||
|
{
|
||||||
|
asset2Content = new Dictionary<sbyte, string>();
|
||||||
|
asset2Extension = new Dictionary<sbyte, string>();
|
||||||
|
inventory2Content = new Dictionary<InventoryType, string>();
|
||||||
|
content2Asset = new Dictionary<string, sbyte>();
|
||||||
|
content2Inventory = new Dictionary<string, InventoryType>();
|
||||||
|
|
||||||
|
foreach (TypeMapping mapping in MAPPINGS)
|
||||||
|
{
|
||||||
|
sbyte assetType = mapping.AssetTypeCode;
|
||||||
|
if (!asset2Content.ContainsKey(assetType))
|
||||||
|
asset2Content.Add(assetType, mapping.ContentType);
|
||||||
|
if (!asset2Extension.ContainsKey(assetType))
|
||||||
|
asset2Extension.Add(assetType, mapping.Extension);
|
||||||
|
if (!inventory2Content.ContainsKey(mapping.InventoryType))
|
||||||
|
inventory2Content.Add(mapping.InventoryType, mapping.ContentType);
|
||||||
|
if (!content2Asset.ContainsKey(mapping.ContentType))
|
||||||
|
content2Asset.Add(mapping.ContentType, assetType);
|
||||||
|
if (!content2Inventory.ContainsKey(mapping.ContentType))
|
||||||
|
content2Inventory.Add(mapping.ContentType, mapping.InventoryType);
|
||||||
|
|
||||||
|
if (mapping.ContentType2 != null)
|
||||||
|
{
|
||||||
|
if (!content2Asset.ContainsKey(mapping.ContentType2))
|
||||||
|
content2Asset.Add(mapping.ContentType2, assetType);
|
||||||
|
if (!content2Inventory.ContainsKey(mapping.ContentType2))
|
||||||
|
content2Inventory.Add(mapping.ContentType2, mapping.InventoryType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static string SLAssetTypeToContentType(int assetType)
|
public static string SLAssetTypeToContentType(int assetType)
|
||||||
{
|
{
|
||||||
switch ((AssetType)assetType)
|
string contentType;
|
||||||
{
|
if (!asset2Content.TryGetValue((sbyte)assetType, out contentType))
|
||||||
case AssetType.Texture:
|
contentType = asset2Content[(sbyte)AssetType.Unknown];
|
||||||
return "image/x-j2c";
|
return contentType;
|
||||||
case AssetType.Sound:
|
|
||||||
return "audio/ogg";
|
|
||||||
case AssetType.CallingCard:
|
|
||||||
return "application/vnd.ll.callingcard";
|
|
||||||
case AssetType.Landmark:
|
|
||||||
return "application/vnd.ll.landmark";
|
|
||||||
case AssetType.Clothing:
|
|
||||||
return "application/vnd.ll.clothing";
|
|
||||||
case AssetType.Object:
|
|
||||||
return "application/vnd.ll.primitive";
|
|
||||||
case AssetType.Notecard:
|
|
||||||
return "application/vnd.ll.notecard";
|
|
||||||
case AssetType.Folder:
|
|
||||||
return "application/vnd.ll.folder";
|
|
||||||
case AssetType.RootFolder:
|
|
||||||
return "application/vnd.ll.rootfolder";
|
|
||||||
case AssetType.LSLText:
|
|
||||||
return "application/vnd.ll.lsltext";
|
|
||||||
case AssetType.LSLBytecode:
|
|
||||||
return "application/vnd.ll.lslbyte";
|
|
||||||
case AssetType.TextureTGA:
|
|
||||||
case AssetType.ImageTGA:
|
|
||||||
return "image/tga";
|
|
||||||
case AssetType.Bodypart:
|
|
||||||
return "application/vnd.ll.bodypart";
|
|
||||||
case AssetType.TrashFolder:
|
|
||||||
return "application/vnd.ll.trashfolder";
|
|
||||||
case AssetType.SnapshotFolder:
|
|
||||||
return "application/vnd.ll.snapshotfolder";
|
|
||||||
case AssetType.LostAndFoundFolder:
|
|
||||||
return "application/vnd.ll.lostandfoundfolder";
|
|
||||||
case AssetType.SoundWAV:
|
|
||||||
return "audio/x-wav";
|
|
||||||
case AssetType.ImageJPEG:
|
|
||||||
return "image/jpeg";
|
|
||||||
case AssetType.Animation:
|
|
||||||
return "application/vnd.ll.animation";
|
|
||||||
case AssetType.Gesture:
|
|
||||||
return "application/vnd.ll.gesture";
|
|
||||||
case AssetType.Simstate:
|
|
||||||
return "application/x-metaverse-simstate";
|
|
||||||
case AssetType.FavoriteFolder:
|
|
||||||
return "application/vnd.ll.favoritefolder";
|
|
||||||
case AssetType.Link:
|
|
||||||
return "application/vnd.ll.link";
|
|
||||||
case AssetType.LinkFolder:
|
|
||||||
return "application/vnd.ll.linkfolder";
|
|
||||||
case AssetType.CurrentOutfitFolder:
|
|
||||||
return "application/vnd.ll.currentoutfitfolder";
|
|
||||||
case AssetType.OutfitFolder:
|
|
||||||
return "application/vnd.ll.outfitfolder";
|
|
||||||
case AssetType.MyOutfitsFolder:
|
|
||||||
return "application/vnd.ll.myoutfitsfolder";
|
|
||||||
case AssetType.Unknown:
|
|
||||||
default:
|
|
||||||
return "application/octet-stream";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string SLInvTypeToContentType(int invType)
|
public static string SLInvTypeToContentType(int invType)
|
||||||
{
|
{
|
||||||
switch ((InventoryType)invType)
|
string contentType;
|
||||||
{
|
if (!inventory2Content.TryGetValue((InventoryType)invType, out contentType))
|
||||||
case InventoryType.Animation:
|
contentType = inventory2Content[InventoryType.Unknown];
|
||||||
return "application/vnd.ll.animation";
|
return contentType;
|
||||||
case InventoryType.CallingCard:
|
|
||||||
return "application/vnd.ll.callingcard";
|
|
||||||
case InventoryType.Folder:
|
|
||||||
return "application/vnd.ll.folder";
|
|
||||||
case InventoryType.Gesture:
|
|
||||||
return "application/vnd.ll.gesture";
|
|
||||||
case InventoryType.Landmark:
|
|
||||||
return "application/vnd.ll.landmark";
|
|
||||||
case InventoryType.LSL:
|
|
||||||
return "application/vnd.ll.lsltext";
|
|
||||||
case InventoryType.Notecard:
|
|
||||||
return "application/vnd.ll.notecard";
|
|
||||||
case InventoryType.Attachment:
|
|
||||||
case InventoryType.Object:
|
|
||||||
return "application/vnd.ll.primitive";
|
|
||||||
case InventoryType.Sound:
|
|
||||||
return "audio/ogg";
|
|
||||||
case InventoryType.Snapshot:
|
|
||||||
case InventoryType.Texture:
|
|
||||||
return "image/x-j2c";
|
|
||||||
case InventoryType.Wearable:
|
|
||||||
return "application/vnd.ll.clothing";
|
|
||||||
default:
|
|
||||||
return "application/octet-stream";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static sbyte ContentTypeToSLAssetType(string contentType)
|
public static sbyte ContentTypeToSLAssetType(string contentType)
|
||||||
{
|
{
|
||||||
switch (contentType)
|
sbyte assetType;
|
||||||
{
|
if (!content2Asset.TryGetValue(contentType, out assetType))
|
||||||
case "image/x-j2c":
|
assetType = (sbyte)AssetType.Unknown;
|
||||||
case "image/jp2":
|
return (sbyte)assetType;
|
||||||
return (sbyte)AssetType.Texture;
|
|
||||||
case "application/ogg":
|
|
||||||
case "audio/ogg":
|
|
||||||
return (sbyte)AssetType.Sound;
|
|
||||||
case "application/vnd.ll.callingcard":
|
|
||||||
case "application/x-metaverse-callingcard":
|
|
||||||
return (sbyte)AssetType.CallingCard;
|
|
||||||
case "application/vnd.ll.landmark":
|
|
||||||
case "application/x-metaverse-landmark":
|
|
||||||
return (sbyte)AssetType.Landmark;
|
|
||||||
case "application/vnd.ll.clothing":
|
|
||||||
case "application/x-metaverse-clothing":
|
|
||||||
return (sbyte)AssetType.Clothing;
|
|
||||||
case "application/vnd.ll.primitive":
|
|
||||||
case "application/x-metaverse-primitive":
|
|
||||||
return (sbyte)AssetType.Object;
|
|
||||||
case "application/vnd.ll.notecard":
|
|
||||||
case "application/x-metaverse-notecard":
|
|
||||||
return (sbyte)AssetType.Notecard;
|
|
||||||
case "application/vnd.ll.folder":
|
|
||||||
return (sbyte)AssetType.Folder;
|
|
||||||
case "application/vnd.ll.rootfolder":
|
|
||||||
return (sbyte)AssetType.RootFolder;
|
|
||||||
case "application/vnd.ll.lsltext":
|
|
||||||
case "application/x-metaverse-lsl":
|
|
||||||
return (sbyte)AssetType.LSLText;
|
|
||||||
case "application/vnd.ll.lslbyte":
|
|
||||||
case "application/x-metaverse-lso":
|
|
||||||
return (sbyte)AssetType.LSLBytecode;
|
|
||||||
case "image/tga":
|
|
||||||
// Note that AssetType.TextureTGA will be converted to AssetType.ImageTGA
|
|
||||||
return (sbyte)AssetType.ImageTGA;
|
|
||||||
case "application/vnd.ll.bodypart":
|
|
||||||
case "application/x-metaverse-bodypart":
|
|
||||||
return (sbyte)AssetType.Bodypart;
|
|
||||||
case "application/vnd.ll.trashfolder":
|
|
||||||
return (sbyte)AssetType.TrashFolder;
|
|
||||||
case "application/vnd.ll.snapshotfolder":
|
|
||||||
return (sbyte)AssetType.SnapshotFolder;
|
|
||||||
case "application/vnd.ll.lostandfoundfolder":
|
|
||||||
return (sbyte)AssetType.LostAndFoundFolder;
|
|
||||||
case "audio/x-wav":
|
|
||||||
return (sbyte)AssetType.SoundWAV;
|
|
||||||
case "image/jpeg":
|
|
||||||
return (sbyte)AssetType.ImageJPEG;
|
|
||||||
case "application/vnd.ll.animation":
|
|
||||||
case "application/x-metaverse-animation":
|
|
||||||
return (sbyte)AssetType.Animation;
|
|
||||||
case "application/vnd.ll.gesture":
|
|
||||||
case "application/x-metaverse-gesture":
|
|
||||||
return (sbyte)AssetType.Gesture;
|
|
||||||
case "application/x-metaverse-simstate":
|
|
||||||
return (sbyte)AssetType.Simstate;
|
|
||||||
case "application/vnd.ll.favoritefolder":
|
|
||||||
return (sbyte)AssetType.FavoriteFolder;
|
|
||||||
case "application/vnd.ll.link":
|
|
||||||
return (sbyte)AssetType.Link;
|
|
||||||
case "application/vnd.ll.linkfolder":
|
|
||||||
return (sbyte)AssetType.LinkFolder;
|
|
||||||
case "application/vnd.ll.currentoutfitfolder":
|
|
||||||
return (sbyte)AssetType.CurrentOutfitFolder;
|
|
||||||
case "application/vnd.ll.outfitfolder":
|
|
||||||
return (sbyte)AssetType.OutfitFolder;
|
|
||||||
case "application/vnd.ll.myoutfitsfolder":
|
|
||||||
return (sbyte)AssetType.MyOutfitsFolder;
|
|
||||||
case "application/octet-stream":
|
|
||||||
default:
|
|
||||||
return (sbyte)AssetType.Unknown;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static sbyte ContentTypeToSLInvType(string contentType)
|
public static sbyte ContentTypeToSLInvType(string contentType)
|
||||||
{
|
{
|
||||||
switch (contentType)
|
InventoryType invType;
|
||||||
{
|
if (!content2Inventory.TryGetValue(contentType, out invType))
|
||||||
case "image/x-j2c":
|
invType = InventoryType.Unknown;
|
||||||
case "image/jp2":
|
return (sbyte)invType;
|
||||||
case "image/tga":
|
|
||||||
case "image/jpeg":
|
|
||||||
return (sbyte)InventoryType.Texture;
|
|
||||||
case "application/ogg":
|
|
||||||
case "audio/ogg":
|
|
||||||
case "audio/x-wav":
|
|
||||||
return (sbyte)InventoryType.Sound;
|
|
||||||
case "application/vnd.ll.callingcard":
|
|
||||||
case "application/x-metaverse-callingcard":
|
|
||||||
return (sbyte)InventoryType.CallingCard;
|
|
||||||
case "application/vnd.ll.landmark":
|
|
||||||
case "application/x-metaverse-landmark":
|
|
||||||
return (sbyte)InventoryType.Landmark;
|
|
||||||
case "application/vnd.ll.clothing":
|
|
||||||
case "application/x-metaverse-clothing":
|
|
||||||
case "application/vnd.ll.bodypart":
|
|
||||||
case "application/x-metaverse-bodypart":
|
|
||||||
return (sbyte)InventoryType.Wearable;
|
|
||||||
case "application/vnd.ll.primitive":
|
|
||||||
case "application/x-metaverse-primitive":
|
|
||||||
return (sbyte)InventoryType.Object;
|
|
||||||
case "application/vnd.ll.notecard":
|
|
||||||
case "application/x-metaverse-notecard":
|
|
||||||
return (sbyte)InventoryType.Notecard;
|
|
||||||
case "application/vnd.ll.folder":
|
|
||||||
return (sbyte)InventoryType.Folder;
|
|
||||||
case "application/vnd.ll.rootfolder":
|
|
||||||
return (sbyte)InventoryType.RootCategory;
|
|
||||||
case "application/vnd.ll.lsltext":
|
|
||||||
case "application/x-metaverse-lsl":
|
|
||||||
case "application/vnd.ll.lslbyte":
|
|
||||||
case "application/x-metaverse-lso":
|
|
||||||
return (sbyte)InventoryType.LSL;
|
|
||||||
case "application/vnd.ll.trashfolder":
|
|
||||||
case "application/vnd.ll.snapshotfolder":
|
|
||||||
case "application/vnd.ll.lostandfoundfolder":
|
|
||||||
return (sbyte)InventoryType.Folder;
|
|
||||||
case "application/vnd.ll.animation":
|
|
||||||
case "application/x-metaverse-animation":
|
|
||||||
return (sbyte)InventoryType.Animation;
|
|
||||||
case "application/vnd.ll.gesture":
|
|
||||||
case "application/x-metaverse-gesture":
|
|
||||||
return (sbyte)InventoryType.Gesture;
|
|
||||||
case "application/x-metaverse-simstate":
|
|
||||||
return (sbyte)InventoryType.Snapshot;
|
|
||||||
case "application/octet-stream":
|
|
||||||
default:
|
|
||||||
return (sbyte)InventoryType.Unknown;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string SLAssetTypeToExtension(int assetType)
|
||||||
|
{
|
||||||
|
string extension;
|
||||||
|
if (!asset2Extension.TryGetValue((sbyte)assetType, out extension))
|
||||||
|
extension = asset2Extension[(sbyte)AssetType.Unknown];
|
||||||
|
return extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion SL / file extension / content-type conversions
|
#endregion SL / file extension / content-type conversions
|
||||||
|
|
|
@ -42,9 +42,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LandDataSerializer
|
public class LandDataSerializer
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding();
|
|
||||||
|
|
||||||
private static Dictionary<string, Action<LandData, XmlTextReader>> m_ldProcessors
|
private static Dictionary<string, Action<LandData, XmlTextReader>> m_ldProcessors
|
||||||
= new Dictionary<string, Action<LandData, XmlTextReader>>();
|
= new Dictionary<string, Action<LandData, XmlTextReader>>();
|
||||||
|
@ -163,7 +161,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
/// <exception cref="System.Xml.XmlException"></exception>
|
/// <exception cref="System.Xml.XmlException"></exception>
|
||||||
public static LandData Deserialize(byte[] serializedLandData)
|
public static LandData Deserialize(byte[] serializedLandData)
|
||||||
{
|
{
|
||||||
return Deserialize(m_utf8Encoding.GetString(serializedLandData, 0, serializedLandData.Length));
|
return Deserialize(Encoding.UTF8.GetString(serializedLandData, 0, serializedLandData.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -30,6 +30,8 @@ using System.Text;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using log4net;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Serialization.External
|
namespace OpenSim.Framework.Serialization.External
|
||||||
{
|
{
|
||||||
|
@ -38,8 +40,6 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RegionSettingsSerializer
|
public class RegionSettingsSerializer
|
||||||
{
|
{
|
||||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deserialize settings
|
/// Deserialize settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -48,7 +48,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
/// <exception cref="System.Xml.XmlException"></exception>
|
/// <exception cref="System.Xml.XmlException"></exception>
|
||||||
public static RegionSettings Deserialize(byte[] serializedSettings)
|
public static RegionSettings Deserialize(byte[] serializedSettings)
|
||||||
{
|
{
|
||||||
return Deserialize(m_asciiEncoding.GetString(serializedSettings, 0, serializedSettings.Length));
|
return Deserialize(Encoding.ASCII.GetString(serializedSettings, 0, serializedSettings.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -188,6 +188,28 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xtr.ReadEndElement();
|
||||||
|
|
||||||
|
if (xtr.IsStartElement("Telehub"))
|
||||||
|
{
|
||||||
|
xtr.ReadStartElement("Telehub");
|
||||||
|
|
||||||
|
while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
|
||||||
|
{
|
||||||
|
switch (xtr.Name)
|
||||||
|
{
|
||||||
|
case "TelehubObject":
|
||||||
|
settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString());
|
||||||
|
break;
|
||||||
|
case "SpawnPoint":
|
||||||
|
string str = xtr.ReadElementContentAsString();
|
||||||
|
SpawnPoint sp = SpawnPoint.Parse(str);
|
||||||
|
settings.AddSpawnPoint(sp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xtr.Close();
|
xtr.Close();
|
||||||
sr.Close();
|
sr.Close();
|
||||||
|
|
||||||
|
@ -245,6 +267,15 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
// calculates it automatically according to the date and other factors.
|
// calculates it automatically according to the date and other factors.
|
||||||
xtw.WriteEndElement();
|
xtw.WriteEndElement();
|
||||||
|
|
||||||
|
xtw.WriteStartElement("Telehub");
|
||||||
|
if (settings.TelehubObject != UUID.Zero)
|
||||||
|
{
|
||||||
|
xtw.WriteElementString("TelehubObject", settings.TelehubObject.ToString());
|
||||||
|
foreach (SpawnPoint sp in settings.SpawnPoints())
|
||||||
|
xtw.WriteElementString("SpawnPoint", sp.ToString());
|
||||||
|
}
|
||||||
|
xtw.WriteEndElement();
|
||||||
|
|
||||||
xtw.WriteEndElement();
|
xtw.WriteEndElement();
|
||||||
|
|
||||||
xtw.Close();
|
xtw.Close();
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UserInventoryItemSerializer
|
public class UserInventoryItemSerializer
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static Dictionary<string, Action<InventoryItemBase, XmlTextReader>> m_InventoryItemXmlProcessors
|
private static Dictionary<string, Action<InventoryItemBase, XmlTextReader>> m_InventoryItemXmlProcessors
|
||||||
= new Dictionary<string, Action<InventoryItemBase, XmlTextReader>>();
|
= new Dictionary<string, Action<InventoryItemBase, XmlTextReader>>();
|
||||||
|
|
|
@ -53,8 +53,6 @@ namespace OpenSim.Framework.Serialization
|
||||||
TYPE_CONTIGUOUS_FILE = 8,
|
TYPE_CONTIGUOUS_FILE = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Binary reader for the underlying stream
|
/// Binary reader for the underlying stream
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -120,13 +118,13 @@ namespace OpenSim.Framework.Serialization
|
||||||
if (header[156] == (byte)'L')
|
if (header[156] == (byte)'L')
|
||||||
{
|
{
|
||||||
int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11);
|
int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11);
|
||||||
tarHeader.FilePath = m_asciiEncoding.GetString(ReadData(longNameLength));
|
tarHeader.FilePath = Encoding.ASCII.GetString(ReadData(longNameLength));
|
||||||
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath);
|
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath);
|
||||||
header = m_br.ReadBytes(512);
|
header = m_br.ReadBytes(512);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tarHeader.FilePath = m_asciiEncoding.GetString(header, 0, 100);
|
tarHeader.FilePath = Encoding.ASCII.GetString(header, 0, 100);
|
||||||
tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray);
|
tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray);
|
||||||
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath);
|
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath);
|
||||||
}
|
}
|
||||||
|
@ -205,7 +203,7 @@ namespace OpenSim.Framework.Serialization
|
||||||
{
|
{
|
||||||
// Trim leading white space: ancient tars do that instead
|
// Trim leading white space: ancient tars do that instead
|
||||||
// of leading 0s :-( don't ask. really.
|
// of leading 0s :-( don't ask. really.
|
||||||
string oString = m_asciiEncoding.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray);
|
string oString = Encoding.ASCII.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray);
|
||||||
|
|
||||||
int d = 0;
|
int d = 0;
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,6 @@ namespace OpenSim.Framework.Serialization
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
|
||||||
protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Binary writer for the underlying stream
|
/// Binary writer for the underlying stream
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -74,7 +71,7 @@ namespace OpenSim.Framework.Serialization
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
public void WriteFile(string filePath, string data)
|
public void WriteFile(string filePath, string data)
|
||||||
{
|
{
|
||||||
WriteFile(filePath, m_utf8Encoding.GetBytes(data));
|
WriteFile(filePath, Util.UTF8NoBomEncoding.GetBytes(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -85,7 +82,7 @@ namespace OpenSim.Framework.Serialization
|
||||||
public void WriteFile(string filePath, byte[] data)
|
public void WriteFile(string filePath, byte[] data)
|
||||||
{
|
{
|
||||||
if (filePath.Length > 100)
|
if (filePath.Length > 100)
|
||||||
WriteEntry("././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L');
|
WriteEntry("././@LongLink", Encoding.ASCII.GetBytes(filePath), 'L');
|
||||||
|
|
||||||
char fileType;
|
char fileType;
|
||||||
|
|
||||||
|
@ -137,7 +134,7 @@ namespace OpenSim.Framework.Serialization
|
||||||
oString = "0" + oString;
|
oString = "0" + oString;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] oBytes = m_asciiEncoding.GetBytes(oString);
|
byte[] oBytes = Encoding.ASCII.GetBytes(oString);
|
||||||
|
|
||||||
return oBytes;
|
return oBytes;
|
||||||
}
|
}
|
||||||
|
@ -156,20 +153,20 @@ namespace OpenSim.Framework.Serialization
|
||||||
byte[] header = new byte[512];
|
byte[] header = new byte[512];
|
||||||
|
|
||||||
// file path field (100)
|
// file path field (100)
|
||||||
byte[] nameBytes = m_asciiEncoding.GetBytes(filePath);
|
byte[] nameBytes = Encoding.ASCII.GetBytes(filePath);
|
||||||
int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length;
|
int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length;
|
||||||
Array.Copy(nameBytes, header, nameSize);
|
Array.Copy(nameBytes, header, nameSize);
|
||||||
|
|
||||||
// file mode (8)
|
// file mode (8)
|
||||||
byte[] modeBytes = m_asciiEncoding.GetBytes("0000777");
|
byte[] modeBytes = Encoding.ASCII.GetBytes("0000777");
|
||||||
Array.Copy(modeBytes, 0, header, 100, 7);
|
Array.Copy(modeBytes, 0, header, 100, 7);
|
||||||
|
|
||||||
// owner user id (8)
|
// owner user id (8)
|
||||||
byte[] ownerIdBytes = m_asciiEncoding.GetBytes("0000764");
|
byte[] ownerIdBytes = Encoding.ASCII.GetBytes("0000764");
|
||||||
Array.Copy(ownerIdBytes, 0, header, 108, 7);
|
Array.Copy(ownerIdBytes, 0, header, 108, 7);
|
||||||
|
|
||||||
// group user id (8)
|
// group user id (8)
|
||||||
byte[] groupIdBytes = m_asciiEncoding.GetBytes("0000764");
|
byte[] groupIdBytes = Encoding.ASCII.GetBytes("0000764");
|
||||||
Array.Copy(groupIdBytes, 0, header, 116, 7);
|
Array.Copy(groupIdBytes, 0, header, 116, 7);
|
||||||
|
|
||||||
// file size in bytes (12)
|
// file size in bytes (12)
|
||||||
|
@ -181,17 +178,17 @@ namespace OpenSim.Framework.Serialization
|
||||||
Array.Copy(fileSizeBytes, 0, header, 124, 11);
|
Array.Copy(fileSizeBytes, 0, header, 124, 11);
|
||||||
|
|
||||||
// last modification time (12)
|
// last modification time (12)
|
||||||
byte[] lastModTimeBytes = m_asciiEncoding.GetBytes("11017037332");
|
byte[] lastModTimeBytes = Encoding.ASCII.GetBytes("11017037332");
|
||||||
Array.Copy(lastModTimeBytes, 0, header, 136, 11);
|
Array.Copy(lastModTimeBytes, 0, header, 136, 11);
|
||||||
|
|
||||||
// entry type indicator (1)
|
// entry type indicator (1)
|
||||||
header[156] = m_asciiEncoding.GetBytes(new char[] { fileType })[0];
|
header[156] = Encoding.ASCII.GetBytes(new char[] { fileType })[0];
|
||||||
|
|
||||||
Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 329, 7);
|
Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 329, 7);
|
||||||
Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 337, 7);
|
Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 337, 7);
|
||||||
|
|
||||||
// check sum for header block (8) [calculated last]
|
// check sum for header block (8) [calculated last]
|
||||||
Array.Copy(m_asciiEncoding.GetBytes(" "), 0, header, 148, 8);
|
Array.Copy(Encoding.ASCII.GetBytes(" "), 0, header, 148, 8);
|
||||||
|
|
||||||
int checksum = 0;
|
int checksum = 0;
|
||||||
foreach (byte b in header)
|
foreach (byte b in header)
|
||||||
|
|
|
@ -78,6 +78,10 @@ namespace OpenSim.Framework.Serialization.Tests
|
||||||
<FixedSun>true</FixedSun>
|
<FixedSun>true</FixedSun>
|
||||||
<SunPosition>12</SunPosition>
|
<SunPosition>12</SunPosition>
|
||||||
</Terrain>
|
</Terrain>
|
||||||
|
<Telehub>
|
||||||
|
<TelehubObject>00000000-0000-0000-0000-111111111111</TelehubObject>
|
||||||
|
<SpawnPoint>1,-2,0.33</SpawnPoint>
|
||||||
|
</Telehub>
|
||||||
</RegionSettings>";
|
</RegionSettings>";
|
||||||
|
|
||||||
private RegionSettings m_rs;
|
private RegionSettings m_rs;
|
||||||
|
@ -116,6 +120,8 @@ namespace OpenSim.Framework.Serialization.Tests
|
||||||
m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080");
|
m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080");
|
||||||
m_rs.UseEstateSun = true;
|
m_rs.UseEstateSun = true;
|
||||||
m_rs.WaterHeight = 23;
|
m_rs.WaterHeight = 23;
|
||||||
|
m_rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111");
|
||||||
|
m_rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -129,6 +135,8 @@ namespace OpenSim.Framework.Serialization.Tests
|
||||||
Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2));
|
Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2));
|
||||||
Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics));
|
Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics));
|
||||||
Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit));
|
Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit));
|
||||||
|
Assert.That(deserRs.TelehubObject, Is.EqualTo(m_rs.TelehubObject));
|
||||||
|
Assert.That(deserRs.SpawnPoints()[0].ToString(), Is.EqualTo(m_rs.SpawnPoints()[0].ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,7 +320,9 @@ namespace OpenSim.Framework.Servers
|
||||||
|
|
||||||
TimeSpan timeTaken = DateTime.Now - m_startuptime;
|
TimeSpan timeTaken = DateTime.Now - m_startuptime;
|
||||||
|
|
||||||
m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds);
|
m_log.InfoFormat(
|
||||||
|
"[STARTUP]: Non-script portion of startup took {0}m {1}s. PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED.",
|
||||||
|
timeTaken.Minutes, timeTaken.Seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -589,8 +591,8 @@ namespace OpenSim.Framework.Servers
|
||||||
{
|
{
|
||||||
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
|
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
|
||||||
FileStream fs = File.Create(path);
|
FileStream fs = File.Create(path);
|
||||||
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
|
|
||||||
Byte[] buf = enc.GetBytes(pidstring);
|
Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
|
||||||
fs.Write(buf, 0, buf.Length);
|
fs.Write(buf, 0, buf.Length);
|
||||||
fs.Close();
|
fs.Close();
|
||||||
m_pidFile = path;
|
m_pidFile = path;
|
||||||
|
|
|
@ -33,9 +33,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
public abstract Hashtable Handle(string path, Hashtable Request);
|
public abstract Hashtable Handle(string path, Hashtable Request);
|
||||||
|
|
||||||
protected BaseHTTPHandler(string httpMethod, string path)
|
protected BaseHTTPHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||||
: base(httpMethod, path)
|
|
||||||
{
|
protected BaseHTTPHandler(string httpMethod, string path, string name, string description)
|
||||||
}
|
: base(httpMethod, path, name, description) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -53,6 +53,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
|
private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
|
||||||
|
|
||||||
|
public int DebugLevel { get; set; }
|
||||||
|
|
||||||
private volatile int NotSocketErrors = 0;
|
private volatile int NotSocketErrors = 0;
|
||||||
public volatile bool HTTPDRunning = false;
|
public volatile bool HTTPDRunning = false;
|
||||||
|
|
||||||
|
@ -79,11 +81,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
private PollServiceRequestManager m_PollServiceManager;
|
private PollServiceRequestManager m_PollServiceManager;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Control the printing of certain debug messages.
|
|
||||||
/// </summary>
|
|
||||||
public int DebugLevel { get; set; }
|
|
||||||
|
|
||||||
public uint SSLPort
|
public uint SSLPort
|
||||||
{
|
{
|
||||||
get { return m_sslport; }
|
get { return m_sslport; }
|
||||||
|
@ -356,7 +353,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace);
|
m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0} ", e.Message), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +405,12 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
string uriString = request.RawUrl;
|
string uriString = request.RawUrl;
|
||||||
|
|
||||||
// string reqnum = "unknown";
|
// string reqnum = "unknown";
|
||||||
int tickstart = Environment.TickCount;
|
int requestStartTick = Environment.TickCount;
|
||||||
|
|
||||||
|
// Will be adjusted later on.
|
||||||
|
int requestEndTick = requestStartTick;
|
||||||
|
|
||||||
|
IRequestHandler requestHandler = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -431,6 +433,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
if (HandleAgentRequest(agentHandler, request, response))
|
if (HandleAgentRequest(agentHandler, request, response))
|
||||||
{
|
{
|
||||||
|
requestEndTick = Environment.TickCount;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,20 +441,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
//response.KeepAlive = true;
|
//response.KeepAlive = true;
|
||||||
response.SendChunked = false;
|
response.SendChunked = false;
|
||||||
|
|
||||||
IRequestHandler requestHandler;
|
|
||||||
|
|
||||||
string path = request.RawUrl;
|
string path = request.RawUrl;
|
||||||
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
||||||
|
byte[] buffer = null;
|
||||||
|
|
||||||
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
||||||
{
|
{
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[BASE HTTP SERVER]: Found stream handler for {0} {1}",
|
"[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
|
||||||
request.HttpMethod, request.Url.PathAndQuery);
|
request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
|
||||||
|
|
||||||
// Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
|
|
||||||
byte[] buffer = null;
|
|
||||||
|
|
||||||
response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
|
response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
|
||||||
|
|
||||||
|
@ -507,8 +506,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
//m_log.Warn("[HTTP]: " + requestBody);
|
//m_log.Warn("[HTTP]: " + requestBody);
|
||||||
|
|
||||||
}
|
}
|
||||||
DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response);
|
|
||||||
return;
|
buffer = DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -521,88 +520,33 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
buffer = memoryStream.ToArray();
|
buffer = memoryStream.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
request.InputStream.Close();
|
else
|
||||||
|
|
||||||
// HTTP IN support. The script engine takes it from here
|
|
||||||
// Nothing to worry about for us.
|
|
||||||
//
|
|
||||||
if (buffer == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!response.SendChunked)
|
|
||||||
response.ContentLength64 = buffer.LongLength;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
}
|
|
||||||
catch (HttpListenerException)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: HTTP request abnormally terminated.");
|
|
||||||
}
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.AcceptTypes != null && request.AcceptTypes.Length > 0)
|
|
||||||
{
|
|
||||||
foreach (string strAccept in request.AcceptTypes)
|
|
||||||
{
|
|
||||||
if (strAccept.Contains("application/llsd+xml") ||
|
|
||||||
strAccept.Contains("application/llsd+json"))
|
|
||||||
{
|
|
||||||
if (DebugLevel >= 1)
|
|
||||||
m_log.DebugFormat(
|
|
||||||
"[BASE HTTP SERVER]: Found application/llsd+xml accept header handler for {0} {1}",
|
|
||||||
request.HttpMethod, request.Url.PathAndQuery);
|
|
||||||
|
|
||||||
HandleLLSDRequests(request, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (request.ContentType)
|
switch (request.ContentType)
|
||||||
{
|
{
|
||||||
case null:
|
case null:
|
||||||
case "text/html":
|
case "text/html":
|
||||||
|
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleHTTPRequest(request, response);
|
buffer = HandleHTTPRequest(request, response);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case "application/llsd+xml":
|
case "application/llsd+xml":
|
||||||
case "application/xml+llsd":
|
case "application/xml+llsd":
|
||||||
case "application/llsd+json":
|
case "application/llsd+json":
|
||||||
|
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleLLSDRequests(request, response);
|
buffer = HandleLLSDRequests(request, response);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case "text/xml":
|
case "text/xml":
|
||||||
case "application/xml":
|
case "application/xml":
|
||||||
|
@ -617,37 +561,58 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
|
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
|
||||||
if (DoWeHaveALLSDHandler(request.RawUrl))
|
if (DoWeHaveALLSDHandler(request.RawUrl))
|
||||||
{
|
{
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleLLSDRequests(request, response);
|
buffer = HandleLLSDRequests(request, response);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
|
||||||
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
|
else if (DoWeHaveAHTTPHandler(request.RawUrl))
|
||||||
if (DoWeHaveAHTTPHandler(request.RawUrl))
|
|
||||||
{
|
{
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleHTTPRequest(request, response);
|
buffer = HandleHTTPRequest(request, response);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (DebugLevel >= 1)
|
{
|
||||||
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
|
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
|
||||||
request.HttpMethod, request.Url.PathAndQuery);
|
request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
// generic login request.
|
// generic login request.
|
||||||
HandleXmlRpcRequests(request, response);
|
buffer = HandleXmlRpcRequests(request, response);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request.InputStream.Close();
|
||||||
|
|
||||||
|
if (buffer != null)
|
||||||
|
{
|
||||||
|
if (!response.SendChunked)
|
||||||
|
response.ContentLength64 = buffer.LongLength;
|
||||||
|
|
||||||
|
response.OutputStream.Write(buffer, 0, buffer.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not include the time taken to actually send the response to the caller in the measurement
|
||||||
|
// time. This is to avoid logging when it's the client that is slow to process rather than the
|
||||||
|
// server
|
||||||
|
requestEndTick = Environment.TickCount;
|
||||||
|
|
||||||
|
response.Send();
|
||||||
|
|
||||||
|
//response.OutputStream.Close();
|
||||||
|
|
||||||
|
//response.FreeContext();
|
||||||
}
|
}
|
||||||
catch (SocketException e)
|
catch (SocketException e)
|
||||||
{
|
{
|
||||||
|
@ -658,25 +623,33 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
//
|
//
|
||||||
// An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
|
// An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
|
||||||
// with the minimum first
|
// with the minimum first
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e);
|
m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux ", e.Message), e);
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
|
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.StackTrace);
|
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
|
||||||
SendHTML500(response);
|
SendHTML500(response);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Every month or so this will wrap and give bad numbers, not really a problem
|
// Every month or so this will wrap and give bad numbers, not really a problem
|
||||||
// since its just for reporting, tickdiff limit can be adjusted
|
// since its just for reporting
|
||||||
int tickdiff = Environment.TickCount - tickstart;
|
int tickdiff = requestEndTick - requestStartTick;
|
||||||
if (tickdiff > 3000)
|
if (tickdiff > 3000)
|
||||||
|
{
|
||||||
m_log.InfoFormat(
|
m_log.InfoFormat(
|
||||||
"[BASE HTTP SERVER]: slow {0} request for {1} from {2} took {3} ms", requestMethod, uriString, request.RemoteIPEndPoint.ToString(), tickdiff);
|
"[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
|
||||||
|
requestMethod,
|
||||||
|
uriString,
|
||||||
|
requestHandler != null ? requestHandler.Name : "",
|
||||||
|
requestHandler != null ? requestHandler.Description : "",
|
||||||
|
request.RemoteIPEndPoint.ToString(),
|
||||||
|
tickdiff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,7 +770,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <param name="response"></param>
|
/// <param name="response"></param>
|
||||||
private void HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
|
private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
Stream requestStream = request.InputStream;
|
Stream requestStream = request.InputStream;
|
||||||
|
|
||||||
|
@ -816,8 +789,23 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
|
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
|
||||||
}
|
}
|
||||||
catch (XmlException)
|
catch (XmlException e)
|
||||||
{
|
{
|
||||||
|
if (DebugLevel >= 1)
|
||||||
|
{
|
||||||
|
if (DebugLevel >= 2)
|
||||||
|
m_log.Warn(
|
||||||
|
string.Format(
|
||||||
|
"[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}. XML was '{1}'. Sending blank response. Exception ",
|
||||||
|
request.RemoteIPEndPoint, requestBody),
|
||||||
|
e);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}, length {1}. Sending blank response.",
|
||||||
|
request.RemoteIPEndPoint, requestBody.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmlRprcRequest != null)
|
if (xmlRprcRequest != null)
|
||||||
|
@ -887,6 +875,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
String.Format("Requested method [{0}] not found", methodName));
|
String.Format("Requested method [{0}] not found", methodName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.ContentType = "text/xml";
|
||||||
responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
|
responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -896,82 +885,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.StatusCode = 404;
|
response.StatusCode = 404;
|
||||||
response.StatusDescription = "Not Found";
|
response.StatusDescription = "Not Found";
|
||||||
response.ProtocolVersion = "HTTP/1.0";
|
response.ProtocolVersion = "HTTP/1.0";
|
||||||
byte[] buf = Encoding.UTF8.GetBytes("Not found");
|
responseString = "Not found";
|
||||||
response.KeepAlive = false;
|
response.KeepAlive = false;
|
||||||
|
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[BASE HTTP SERVER]: Handler not found for http request {0} {1}",
|
"[BASE HTTP SERVER]: Handler not found for http request {0} {1}",
|
||||||
request.HttpMethod, request.Url.PathAndQuery);
|
request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
response.SendChunked = false;
|
|
||||||
response.ContentLength64 = buf.Length;
|
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.OutputStream.Write(buf, 0, buf.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
//responseString = "Error";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.ContentType = "text/xml";
|
|
||||||
|
|
||||||
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
|
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
|
||||||
|
|
||||||
response.SendChunked = false;
|
response.SendChunked = false;
|
||||||
response.ContentLength64 = buffer.Length;
|
response.ContentLength64 = buffer.Length;
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
try
|
|
||||||
{
|
return buffer;
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response)
|
private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
//m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
|
//m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
|
||||||
Stream requestStream = request.InputStream;
|
Stream requestStream = request.InputStream;
|
||||||
|
@ -1057,34 +989,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
response.KeepAlive = true;
|
response.KeepAlive = true;
|
||||||
|
|
||||||
try
|
return buffer;
|
||||||
{
|
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
response.OutputStream.Flush();
|
|
||||||
//response.FreeContext();
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: LLSD IOException {0}.", e);
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse)
|
private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse)
|
||||||
|
@ -1334,8 +1239,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
catch (SocketException f)
|
catch (SocketException f)
|
||||||
{
|
{
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
// This has to be here to prevent a Linux/Mono crash
|
||||||
m_log.WarnFormat(
|
m_log.Warn(
|
||||||
"[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f);
|
String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception)
|
catch(Exception)
|
||||||
|
@ -1349,7 +1254,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
|
public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}",
|
// "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}",
|
||||||
|
@ -1359,15 +1264,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
case "OPTIONS":
|
case "OPTIONS":
|
||||||
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
|
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
HandleContentVerbs(request, response);
|
return HandleContentVerbs(request, response);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleContentVerbs(OSHttpRequest request, OSHttpResponse response)
|
private byte[] HandleContentVerbs(OSHttpRequest request, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl);
|
// m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl);
|
||||||
|
|
||||||
|
@ -1383,6 +1287,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
// to display the form, or process it.
|
// to display the form, or process it.
|
||||||
// a better way would be nifty.
|
// a better way would be nifty.
|
||||||
|
|
||||||
|
byte[] buffer;
|
||||||
|
|
||||||
Stream requestStream = request.InputStream;
|
Stream requestStream = request.InputStream;
|
||||||
|
|
||||||
Encoding encoding = Encoding.UTF8;
|
Encoding encoding = Encoding.UTF8;
|
||||||
|
@ -1443,14 +1349,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
if (foundHandler)
|
if (foundHandler)
|
||||||
{
|
{
|
||||||
Hashtable responsedata1 = requestprocessor(keysvals);
|
Hashtable responsedata1 = requestprocessor(keysvals);
|
||||||
DoHTTPGruntWork(responsedata1,response);
|
buffer = DoHTTPGruntWork(responsedata1,response);
|
||||||
|
|
||||||
//SendHTML500(response);
|
//SendHTML500(response);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found");
|
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found");
|
||||||
SendHTML404(response, host);
|
buffer = SendHTML404(response, host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1460,16 +1366,18 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
if (foundHandler)
|
if (foundHandler)
|
||||||
{
|
{
|
||||||
Hashtable responsedata2 = requestprocessor(keysvals);
|
Hashtable responsedata2 = requestprocessor(keysvals);
|
||||||
DoHTTPGruntWork(responsedata2, response);
|
buffer = DoHTTPGruntWork(responsedata2, response);
|
||||||
|
|
||||||
//SendHTML500(response);
|
//SendHTML500(response);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2");
|
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2");
|
||||||
SendHTML404(response, host);
|
buffer = SendHTML404(response, host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler)
|
private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler)
|
||||||
|
@ -1537,7 +1445,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
|
internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
int responsecode;
|
int responsecode;
|
||||||
string responseString;
|
string responseString;
|
||||||
|
@ -1631,38 +1539,10 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.ContentLength64 = buffer.Length;
|
response.ContentLength64 = buffer.Length;
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
try
|
return buffer;
|
||||||
{
|
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[HTTPD]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.OutputStream.Flush();
|
|
||||||
response.Send();
|
|
||||||
|
|
||||||
//if (!response.KeepAlive && response.ReuseContext)
|
|
||||||
// response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendHTML404(OSHttpResponse response, string host)
|
public byte[] SendHTML404(OSHttpResponse response, string host)
|
||||||
{
|
{
|
||||||
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
|
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
|
||||||
response.StatusCode = 404;
|
response.StatusCode = 404;
|
||||||
|
@ -1675,31 +1555,10 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.ContentLength64 = buffer.Length;
|
response.ContentLength64 = buffer.Length;
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
try
|
return buffer;
|
||||||
{
|
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendHTML500(OSHttpResponse response)
|
public byte[] SendHTML500(OSHttpResponse response)
|
||||||
{
|
{
|
||||||
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
|
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
|
||||||
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
|
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
|
||||||
|
@ -1711,28 +1570,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.SendChunked = false;
|
response.SendChunked = false;
|
||||||
response.ContentLength64 = buffer.Length;
|
response.ContentLength64 = buffer.Length;
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
try
|
|
||||||
{
|
return buffer;
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
|
@ -1742,6 +1581,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
private void StartHTTP()
|
private void StartHTTP()
|
||||||
{
|
{
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//m_httpListener = new HttpListener();
|
//m_httpListener = new HttpListener();
|
||||||
|
|
|
@ -45,8 +45,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
private readonly string m_path;
|
private readonly string m_path;
|
||||||
|
|
||||||
protected BaseRequestHandler(string httpMethod, string path)
|
public string Name { get; private set; }
|
||||||
|
|
||||||
|
public string Description { get; private set; }
|
||||||
|
|
||||||
|
protected BaseRequestHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||||
|
|
||||||
|
protected BaseRequestHandler(string httpMethod, string path, string name, string description)
|
||||||
{
|
{
|
||||||
|
Name = name;
|
||||||
|
Description = description;
|
||||||
m_httpMethod = httpMethod;
|
m_httpMethod = httpMethod;
|
||||||
m_path = path;
|
m_path = path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
public abstract byte[] Handle(string path, Stream request,
|
public abstract byte[] Handle(string path, Stream request,
|
||||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
|
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
|
||||||
|
|
||||||
protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path)
|
protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||||
{
|
|
||||||
}
|
protected BaseStreamHandler(string httpMethod, string path, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,6 +36,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
private BinaryMethod m_method;
|
private BinaryMethod m_method;
|
||||||
|
|
||||||
|
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
|
||||||
|
: this(httpMethod, path, binaryMethod, null, null) {}
|
||||||
|
|
||||||
|
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
|
{
|
||||||
|
m_method = binaryMethod;
|
||||||
|
}
|
||||||
|
|
||||||
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
{
|
{
|
||||||
byte[] data = ReadFully(request);
|
byte[] data = ReadFully(request);
|
||||||
|
@ -45,12 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
return Encoding.UTF8.GetBytes(responseString);
|
return Encoding.UTF8.GetBytes(responseString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
|
|
||||||
: base(httpMethod, path)
|
|
||||||
{
|
|
||||||
m_method = binaryMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] ReadFully(Stream stream)
|
private static byte[] ReadFully(Stream stream)
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
|
|
|
@ -128,11 +128,5 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
/// <param name="value">string containing the header field
|
/// <param name="value">string containing the header field
|
||||||
/// value</param>
|
/// value</param>
|
||||||
void AddHeader(string key, string value);
|
void AddHeader(string key, string value);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Send the response back to the remote client
|
|
||||||
/// </summary>
|
|
||||||
void Send();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
public interface IRequestHandler
|
public interface IRequestHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name for this handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
|
||||||
|
/// specified.
|
||||||
|
/// </remarks>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Description for this handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
|
||||||
|
/// specified.
|
||||||
|
/// </remarks>
|
||||||
|
string Description { get; }
|
||||||
|
|
||||||
// Return response content type
|
// Return response content type
|
||||||
string ContentType { get; }
|
string ContentType { get; }
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
public bool IsSecured
|
public bool IsSecured
|
||||||
{
|
{
|
||||||
get { return _context.Secured; }
|
get { return _context.IsSecured; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool KeepAlive
|
public bool KeepAlive
|
||||||
|
|
|
@ -321,13 +321,12 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
_httpResponse.Body.Flush();
|
_httpResponse.Body.Flush();
|
||||||
_httpResponse.Send();
|
_httpResponse.Send();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FreeContext()
|
public void FreeContext()
|
||||||
{
|
{
|
||||||
if (_httpClientContext != null)
|
if (_httpClientContext != null)
|
||||||
_httpClientContext.Close();
|
_httpClientContext.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,143 +28,252 @@
|
||||||
namespace OpenSim.Framework.Servers.HttpServer
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// HTTP status codes (almost) as defined by W3C in
|
/// HTTP status codes (almost) as defined by W3C in http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html and IETF in http://tools.ietf.org/html/rfc6585
|
||||||
/// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum OSHttpStatusCode: int
|
public enum OSHttpStatusCode : int
|
||||||
{
|
{
|
||||||
// 1xx Informational status codes providing a provisional
|
#region 1xx Informational status codes providing a provisional response.
|
||||||
// response.
|
|
||||||
// 100 Tells client that to keep on going sending its request
|
/// <summary>
|
||||||
|
/// 100 Tells client that to keep on going sending its request
|
||||||
|
/// </summary>
|
||||||
InfoContinue = 100,
|
InfoContinue = 100,
|
||||||
// 101 Server understands request, proposes to switch to different
|
|
||||||
// application level protocol
|
/// <summary>
|
||||||
|
/// 101 Server understands request, proposes to switch to different application level protocol
|
||||||
|
/// </summary>
|
||||||
InfoSwitchingProtocols = 101,
|
InfoSwitchingProtocols = 101,
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
// 2xx Success codes
|
#region 2xx Success codes
|
||||||
// 200 Request successful
|
|
||||||
|
/// <summary>
|
||||||
|
/// 200 Request successful
|
||||||
|
/// </summary>
|
||||||
SuccessOk = 200,
|
SuccessOk = 200,
|
||||||
// 201 Request successful, new resource created
|
|
||||||
|
/// <summary>
|
||||||
|
/// 201 Request successful, new resource created
|
||||||
|
/// </summary>
|
||||||
SuccessOkCreated = 201,
|
SuccessOkCreated = 201,
|
||||||
// 202 Request accepted, processing still on-going
|
|
||||||
|
/// <summary>
|
||||||
|
/// 202 Request accepted, processing still on-going
|
||||||
|
/// </summary>
|
||||||
SuccessOkAccepted = 202,
|
SuccessOkAccepted = 202,
|
||||||
// 203 Request successful, meta information not authoritative
|
|
||||||
|
/// <summary>
|
||||||
|
/// 203 Request successful, meta information not authoritative
|
||||||
|
/// </summary>
|
||||||
SuccessOkNonAuthoritativeInformation = 203,
|
SuccessOkNonAuthoritativeInformation = 203,
|
||||||
// 204 Request successful, nothing to return in the body
|
|
||||||
|
/// <summary>
|
||||||
|
/// 204 Request successful, nothing to return in the body
|
||||||
|
/// </summary>
|
||||||
SuccessOkNoContent = 204,
|
SuccessOkNoContent = 204,
|
||||||
// 205 Request successful, reset displayed content
|
|
||||||
|
/// <summary>
|
||||||
|
/// 205 Request successful, reset displayed content
|
||||||
|
/// </summary>
|
||||||
SuccessOkResetContent = 205,
|
SuccessOkResetContent = 205,
|
||||||
// 206 Request successful, partial content returned
|
|
||||||
|
/// <summary>
|
||||||
|
/// 206 Request successful, partial content returned
|
||||||
|
/// </summary>
|
||||||
SuccessOkPartialContent = 206,
|
SuccessOkPartialContent = 206,
|
||||||
|
|
||||||
// 3xx Redirect code: user agent needs to go somewhere else
|
#endregion
|
||||||
// 300 Redirect: different presentation forms available, take
|
|
||||||
// a pick
|
#region 3xx Redirect code: user agent needs to go somewhere else
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 300 Redirect: different presentation forms available, take a pick
|
||||||
|
/// </summary>
|
||||||
RedirectMultipleChoices = 300,
|
RedirectMultipleChoices = 300,
|
||||||
// 301 Redirect: requested resource has moved and now lives
|
|
||||||
// somewhere else
|
/// <summary>
|
||||||
|
/// 301 Redirect: requested resource has moved and now lives somewhere else
|
||||||
|
/// </summary>
|
||||||
RedirectMovedPermanently = 301,
|
RedirectMovedPermanently = 301,
|
||||||
// 302 Redirect: Resource temporarily somewhere else, location
|
|
||||||
// might change
|
/// <summary>
|
||||||
|
/// 302 Redirect: Resource temporarily somewhere else, location might change
|
||||||
|
/// </summary>
|
||||||
RedirectFound = 302,
|
RedirectFound = 302,
|
||||||
// 303 Redirect: See other as result of a POST
|
|
||||||
|
/// <summary>
|
||||||
|
/// 303 Redirect: See other as result of a POST
|
||||||
|
/// </summary>
|
||||||
RedirectSeeOther = 303,
|
RedirectSeeOther = 303,
|
||||||
// 304 Redirect: Resource still the same as before
|
|
||||||
|
/// <summary>
|
||||||
|
/// 304 Redirect: Resource still the same as before
|
||||||
|
/// </summary>
|
||||||
RedirectNotModified = 304,
|
RedirectNotModified = 304,
|
||||||
// 305 Redirect: Resource must be accessed via proxy provided
|
|
||||||
// in location field
|
/// <summary>
|
||||||
|
/// 305 Redirect: Resource must be accessed via proxy provided in location field
|
||||||
|
/// </summary>
|
||||||
RedirectUseProxy = 305,
|
RedirectUseProxy = 305,
|
||||||
// 307 Redirect: Resource temporarily somewhere else, location
|
|
||||||
// might change
|
/// <summary>
|
||||||
|
/// 307 Redirect: Resource temporarily somewhere else, location might change
|
||||||
|
/// </summary>
|
||||||
RedirectMovedTemporarily = 307,
|
RedirectMovedTemporarily = 307,
|
||||||
|
|
||||||
// 4xx Client error: the client borked the request
|
#endregion
|
||||||
// 400 Client error: bad request, server does not grok what
|
|
||||||
// the client wants
|
#region 4xx Client error: the client borked the request
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 400 Client error: bad request, server does not grok what the client wants
|
||||||
|
/// </summary>
|
||||||
ClientErrorBadRequest = 400,
|
ClientErrorBadRequest = 400,
|
||||||
// 401 Client error: the client is not authorized, response
|
|
||||||
// provides WWW-Authenticate header field with a challenge
|
/// <summary>
|
||||||
|
/// 401 Client error: the client is not authorized, response provides WWW-Authenticate header field with a challenge
|
||||||
|
/// </summary>
|
||||||
ClientErrorUnauthorized = 401,
|
ClientErrorUnauthorized = 401,
|
||||||
// 402 Client error: Payment required (reserved for future use)
|
|
||||||
|
/// <summary>
|
||||||
|
/// 402 Client error: Payment required (reserved for future use)
|
||||||
|
/// </summary>
|
||||||
ClientErrorPaymentRequired = 402,
|
ClientErrorPaymentRequired = 402,
|
||||||
// 403 Client error: Server understood request, will not
|
|
||||||
// deliver, do not try again.
|
/// <summary>
|
||||||
|
/// 403 Client error: Server understood request, will not deliver, do not try again.
|
||||||
ClientErrorForbidden = 403,
|
ClientErrorForbidden = 403,
|
||||||
// 404 Client error: Server cannot find anything matching the
|
|
||||||
// client request.
|
/// <summary>
|
||||||
|
/// 404 Client error: Server cannot find anything matching the client request.
|
||||||
|
/// </summary>
|
||||||
ClientErrorNotFound = 404,
|
ClientErrorNotFound = 404,
|
||||||
// 405 Client error: The method specified by the client in the
|
|
||||||
// request is not allowed for the resource requested
|
/// <summary>
|
||||||
|
/// 405 Client error: The method specified by the client in the request is not allowed for the resource requested
|
||||||
|
/// </summary>
|
||||||
ClientErrorMethodNotAllowed = 405,
|
ClientErrorMethodNotAllowed = 405,
|
||||||
// 406 Client error: Server cannot generate suitable response
|
|
||||||
// for the resource and content characteristics requested by
|
/// <summary>
|
||||||
// the client
|
/// 406 Client error: Server cannot generate suitable response for the resource and content characteristics requested by the client
|
||||||
|
/// </summary>
|
||||||
ClientErrorNotAcceptable = 406,
|
ClientErrorNotAcceptable = 406,
|
||||||
// 407 Client error: Similar to 401, Server requests that
|
|
||||||
// client authenticate itself with the proxy first
|
/// <summary>
|
||||||
|
/// 407 Client error: Similar to 401, Server requests that client authenticate itself with the proxy first
|
||||||
|
/// </summary>
|
||||||
ClientErrorProxyAuthRequired = 407,
|
ClientErrorProxyAuthRequired = 407,
|
||||||
// 408 Client error: Server got impatient with client and
|
|
||||||
// decided to give up waiting for the client's request to
|
/// <summary>
|
||||||
// arrive
|
/// 408 Client error: Server got impatient with client and decided to give up waiting for the client's request to arrive
|
||||||
|
/// </summary>
|
||||||
ClientErrorRequestTimeout = 408,
|
ClientErrorRequestTimeout = 408,
|
||||||
// 409 Client error: Server could not fulfill the request for
|
|
||||||
// a resource as there is a conflict with the current state of
|
/// <summary>
|
||||||
// the resource but thinks client can do something about this
|
/// 409 Client error: Server could not fulfill the request for a resource as there is a conflict with the current state of the resource but thinks client can do something about this
|
||||||
|
/// </summary>
|
||||||
ClientErrorConflict = 409,
|
ClientErrorConflict = 409,
|
||||||
// 410 Client error: The resource has moved somewhere else,
|
|
||||||
// but server has no clue where.
|
/// <summary>
|
||||||
|
/// 410 Client error: The resource has moved somewhere else, but server has no clue where.
|
||||||
|
/// </summary>
|
||||||
ClientErrorGone = 410,
|
ClientErrorGone = 410,
|
||||||
// 411 Client error: The server is picky again and insists on
|
|
||||||
// having a content-length header field in the request
|
/// <summary>
|
||||||
|
/// 411 Client error: The server is picky again and insists on having a content-length header field in the request
|
||||||
|
/// </summary>
|
||||||
ClientErrorLengthRequired = 411,
|
ClientErrorLengthRequired = 411,
|
||||||
// 412 Client error: one or more preconditions supplied in the
|
|
||||||
// client's request is false
|
/// <summary>
|
||||||
|
/// 412 Client error: one or more preconditions supplied in the client's request is false
|
||||||
|
/// </summary>
|
||||||
ClientErrorPreconditionFailed = 412,
|
ClientErrorPreconditionFailed = 412,
|
||||||
// 413 Client error: For fear of reflux, the server refuses to
|
|
||||||
// swallow that much data.
|
/// <summary>
|
||||||
|
/// 413 Client error: For fear of reflux, the server refuses to swallow that much data.
|
||||||
|
/// </summary>
|
||||||
ClientErrorRequestEntityToLarge = 413,
|
ClientErrorRequestEntityToLarge = 413,
|
||||||
// 414 Client error: The server considers the Request-URI to
|
|
||||||
// be indecently long and refuses to even look at it.
|
/// <summary>
|
||||||
|
/// 414 Client error: The server considers the Request-URI to be indecently long and refuses to even look at it.
|
||||||
|
/// </summary>
|
||||||
ClientErrorRequestURITooLong = 414,
|
ClientErrorRequestURITooLong = 414,
|
||||||
// 415 Client error: The server has no clue about the media
|
|
||||||
// type requested by the client (contrary to popular belief it
|
/// <summary>
|
||||||
// is not a warez server)
|
/// 415 Client error: The server has no clue about the media type requested by the client (contrary to popular belief it is not a warez server)
|
||||||
|
/// </summary>
|
||||||
ClientErrorUnsupportedMediaType = 415,
|
ClientErrorUnsupportedMediaType = 415,
|
||||||
// 416 Client error: The requested range cannot be delivered
|
|
||||||
// by the server.
|
/// <summary>
|
||||||
|
/// 416 Client error: The requested range cannot be delivered by the server.
|
||||||
|
/// </summary>
|
||||||
ClientErrorRequestRangeNotSatisfiable = 416,
|
ClientErrorRequestRangeNotSatisfiable = 416,
|
||||||
// 417 Client error: The expectations of the client as
|
|
||||||
// expressed in one or more Expect header fields cannot be met
|
/// <summary>
|
||||||
// by the server, the server is awfully sorry about this.
|
/// 417 Client error: The expectations of the client as expressed in one or more Expect header fields cannot be met by the server, the server is awfully sorry about this.
|
||||||
|
/// </summary>
|
||||||
ClientErrorExpectationFailed = 417,
|
ClientErrorExpectationFailed = 417,
|
||||||
// 499 Client error: Wildcard error.
|
|
||||||
|
/// <summary>
|
||||||
|
/// 428 Client error :The 428 status code indicates that the origin server requires the request to be conditional.
|
||||||
|
/// </summary>
|
||||||
|
ClientErrorPreconditionRequired = 428,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 429 Client error: The 429 status code indicates that the user has sent too many requests in a given amount of time ("rate limiting").
|
||||||
|
/// </summary>
|
||||||
|
ClientErrorTooManyRequests = 429,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 431 Client error: The 431 status code indicates that the server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields.
|
||||||
|
/// </summary>
|
||||||
|
ClientErrorRequestHeaderFieldsTooLarge = 431,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 499 Client error: Wildcard error.
|
||||||
|
/// </summary>
|
||||||
ClientErrorJoker = 499,
|
ClientErrorJoker = 499,
|
||||||
|
|
||||||
// 5xx Server errors (rare)
|
#endregion
|
||||||
// 500 Server error: something really strange and unexpected
|
|
||||||
// happened
|
#region 5xx Server errors (rare)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 500 Server error: something really strange and unexpected happened
|
||||||
|
/// </summary>
|
||||||
ServerErrorInternalError = 500,
|
ServerErrorInternalError = 500,
|
||||||
// 501 Server error: The server does not do the functionality
|
|
||||||
// required to carry out the client request. not at
|
/// <summary>
|
||||||
// all. certainly not before breakfast. but also not after
|
/// 501 Server error: The server does not do the functionality required to carry out the client request. not at all. certainly not before breakfast. but also not after breakfast.
|
||||||
// breakfast.
|
/// </summary>
|
||||||
ServerErrorNotImplemented = 501,
|
ServerErrorNotImplemented = 501,
|
||||||
// 502 Server error: While acting as a proxy or a gateway, the
|
|
||||||
// server got ditched by the upstream server and as a
|
/// <summary>
|
||||||
// consequence regretfully cannot fulfill the client's request
|
/// 502 Server error: While acting as a proxy or a gateway, the server got ditched by the upstream server and as a consequence regretfully cannot fulfill the client's request
|
||||||
|
/// </summary>
|
||||||
ServerErrorBadGateway = 502,
|
ServerErrorBadGateway = 502,
|
||||||
// 503 Server error: Due to unforseen circumstances the server
|
|
||||||
// cannot currently deliver the service requested. Retry-After
|
/// <summary>
|
||||||
// header might indicate when to try again.
|
/// 503 Server error: Due to unforseen circumstances the server cannot currently deliver the service requested. Retry-After header might indicate when to try again.
|
||||||
|
/// </summary>
|
||||||
ServerErrorServiceUnavailable = 503,
|
ServerErrorServiceUnavailable = 503,
|
||||||
// 504 Server error: The server blames the upstream server
|
|
||||||
// for not being able to deliver the service requested and
|
/// <summary>
|
||||||
// claims that the upstream server is too slow delivering the
|
/// 504 Server error: The server blames the upstream server for not being able to deliver the service requested and claims that the upstream server is too slow delivering the goods.
|
||||||
// goods.
|
/// </summary>
|
||||||
ServerErrorGatewayTimeout = 504,
|
ServerErrorGatewayTimeout = 504,
|
||||||
// 505 Server error: The server does not support the HTTP
|
|
||||||
// version conveyed in the client's request.
|
/// <summary>
|
||||||
|
/// 505 Server error: The server does not support the HTTP version conveyed in the client's request.
|
||||||
|
/// </summary>
|
||||||
ServerErrorHttpVersionNotSupported = 505,
|
ServerErrorHttpVersionNotSupported = 505,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 511 Server error: The 511 status code indicates that the client needs to authenticate to gain network access.
|
||||||
|
/// </summary>
|
||||||
|
ServerErrorNetworkAuthenticationRequired = 511,
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Servers.HttpServer
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
public delegate void RequestMethod(UUID requestID, Hashtable request);
|
public delegate void RequestMethod(UUID requestID, Hashtable request);
|
||||||
|
@ -53,7 +54,10 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
LslHttp = 1
|
LslHttp = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
public PollServiceEventArgs(RequestMethod pRequest, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, UUID pId, int pTimeOutms)
|
public PollServiceEventArgs(
|
||||||
|
RequestMethod pRequest,
|
||||||
|
HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
|
||||||
|
UUID pId, int pTimeOutms)
|
||||||
{
|
{
|
||||||
Request = pRequest;
|
Request = pRequest;
|
||||||
HasEvents = pHasEvents;
|
HasEvents = pHasEvents;
|
||||||
|
|
|
@ -31,7 +31,6 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Servers.HttpServer
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
|
|
||||||
public class PollServiceHttpRequest
|
public class PollServiceHttpRequest
|
||||||
{
|
{
|
||||||
public readonly PollServiceEventArgs PollServiceArgs;
|
public readonly PollServiceEventArgs PollServiceArgs;
|
||||||
|
@ -39,7 +38,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
public readonly IHttpRequest Request;
|
public readonly IHttpRequest Request;
|
||||||
public readonly int RequestTime;
|
public readonly int RequestTime;
|
||||||
public readonly UUID RequestID;
|
public readonly UUID RequestID;
|
||||||
public PollServiceHttpRequest(PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
|
|
||||||
|
public PollServiceHttpRequest(
|
||||||
|
PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
|
||||||
{
|
{
|
||||||
PollServiceArgs = pPollServiceArgs;
|
PollServiceArgs = pPollServiceArgs;
|
||||||
HttpContext = pHttpContext;
|
HttpContext = pHttpContext;
|
||||||
|
|
|
@ -70,6 +70,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
ThreadPriority.Normal,
|
ThreadPriority.Normal,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
null,
|
||||||
int.MaxValue);
|
int.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
ThreadPriority.Normal,
|
ThreadPriority.Normal,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
null,
|
||||||
1000 * 60 * 10);
|
1000 * 60 * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,9 +146,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
foreach (object o in m_requests)
|
foreach (object o in m_requests)
|
||||||
{
|
{
|
||||||
PollServiceHttpRequest req = (PollServiceHttpRequest) o;
|
PollServiceHttpRequest req = (PollServiceHttpRequest) o;
|
||||||
m_server.DoHTTPGruntWork(
|
PollServiceWorkerThread.DoHTTPGruntWork(
|
||||||
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
|
m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
|
||||||
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_requests.Clear();
|
m_requests.Clear();
|
||||||
|
@ -155,6 +156,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
t.Abort();
|
t.Abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_running = false;
|
m_running = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +186,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
private bool m_running = true;
|
private bool m_running = true;
|
||||||
private int slowCount = 0;
|
private int slowCount = 0;
|
||||||
|
|
||||||
// private int m_timeout = 1000; // increase timeout 250; now use the event one
|
// private int m_timeout = 250; // increase timeout 250; now use the event one
|
||||||
|
|
||||||
public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
|
public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
|
||||||
{
|
{
|
||||||
|
@ -202,6 +204,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
ThreadPriority.Normal,
|
ThreadPriority.Normal,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
null,
|
||||||
int.MaxValue);
|
int.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +214,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
ThreadPriority.Normal,
|
ThreadPriority.Normal,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
null,
|
||||||
1000 * 60 * 10);
|
1000 * 60 * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,8 +372,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if ((Environment.TickCount - req.RequestTime) > m_timeout)
|
// if ((Environment.TickCount - req.RequestTime) > m_timeout)
|
||||||
|
|
||||||
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
|
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
|
||||||
{
|
{
|
||||||
m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
|
m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
|
||||||
|
|
|
@ -94,8 +94,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
|
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
|
||||||
m_server.DoHTTPGruntWork(responsedata,
|
DoHTTPGruntWork(m_server, req, responsedata);
|
||||||
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext));
|
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
|
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
|
||||||
{
|
{
|
||||||
|
@ -106,8 +105,10 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
if ((Environment.TickCount - req.RequestTime) > m_timeout)
|
if ((Environment.TickCount - req.RequestTime) > m_timeout)
|
||||||
{
|
{
|
||||||
m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
|
DoHTTPGruntWork(
|
||||||
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext));
|
m_server,
|
||||||
|
req,
|
||||||
|
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -128,6 +129,46 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
m_request.Enqueue(pPollServiceHttpRequest);
|
m_request.Enqueue(pPollServiceHttpRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FIXME: This should be part of BaseHttpServer
|
||||||
|
/// </summary>
|
||||||
|
internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata)
|
||||||
|
{
|
||||||
|
OSHttpResponse response
|
||||||
|
= new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext);
|
||||||
|
|
||||||
|
byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
|
||||||
|
|
||||||
|
response.SendChunked = false;
|
||||||
|
response.ContentLength64 = buffer.Length;
|
||||||
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response.OutputStream.Write(buffer, 0, buffer.Length);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
//response.OutputStream.Close();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response.OutputStream.Flush();
|
||||||
|
response.Send();
|
||||||
|
|
||||||
|
//if (!response.KeepAlive && response.ReuseContext)
|
||||||
|
// response.FreeContext();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
|
@ -39,7 +39,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
private RestDeserialiseMethod<TRequest, TResponse> m_method;
|
private RestDeserialiseMethod<TRequest, TResponse> m_method;
|
||||||
|
|
||||||
public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
|
public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
|
||||||
: base(httpMethod, path)
|
: this(httpMethod, path, method, null, null) {}
|
||||||
|
|
||||||
|
public RestDeserialiseHandler(
|
||||||
|
string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
{
|
{
|
||||||
m_method = method;
|
m_method = method;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,19 +38,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
get { return m_dhttpMethod; }
|
get { return m_dhttpMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Hashtable Handle(string path, Hashtable request)
|
|
||||||
{
|
|
||||||
|
|
||||||
string param = GetParam(path);
|
|
||||||
request.Add("param", param);
|
|
||||||
request.Add("path", path);
|
|
||||||
return m_dhttpMethod(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
|
public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
|
||||||
: base(httpMethod, path)
|
: base(httpMethod, path)
|
||||||
{
|
{
|
||||||
m_dhttpMethod = dhttpMethod;
|
m_dhttpMethod = dhttpMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RestHTTPHandler(
|
||||||
|
string httpMethod, string path, GenericHTTPMethod dhttpMethod, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
|
{
|
||||||
|
m_dhttpMethod = dhttpMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Hashtable Handle(string path, Hashtable request)
|
||||||
|
{
|
||||||
|
string param = GetParam(path);
|
||||||
|
request.Add("param", param);
|
||||||
|
request.Add("path", path);
|
||||||
|
return m_dhttpMethod(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
get { return m_restMethod; }
|
get { return m_restMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod)
|
||||||
|
: this(httpMethod, path, restMethod, null, null) {}
|
||||||
|
|
||||||
|
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
|
{
|
||||||
|
m_restMethod = restMethod;
|
||||||
|
}
|
||||||
|
|
||||||
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
{
|
{
|
||||||
Encoding encoding = Encoding.UTF8;
|
Encoding encoding = Encoding.UTF8;
|
||||||
|
@ -52,10 +61,5 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
return Encoding.UTF8.GetBytes(responseString);
|
return Encoding.UTF8.GetBytes(responseString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path)
|
|
||||||
{
|
|
||||||
m_restMethod = restMethod;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,45 +25,197 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Servers
|
namespace OpenSim.Framework.Servers
|
||||||
{
|
{
|
||||||
public class MainServer
|
public class MainServer
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static BaseHttpServer instance = null;
|
private static BaseHttpServer instance = null;
|
||||||
private static Dictionary<uint, BaseHttpServer> m_Servers =
|
private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>();
|
||||||
new Dictionary<uint, BaseHttpServer>();
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Control the printing of certain debug messages.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If DebugLevel >= 1, then short warnings are logged when receiving bad input data.
|
||||||
|
/// If DebugLevel >= 2, then long warnings are logged when receiving bad input data.
|
||||||
|
/// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged.
|
||||||
|
/// </remarks>
|
||||||
|
public static int DebugLevel
|
||||||
|
{
|
||||||
|
get { return s_debugLevel; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
s_debugLevel = value;
|
||||||
|
|
||||||
|
lock (m_Servers)
|
||||||
|
foreach (BaseHttpServer server in m_Servers.Values)
|
||||||
|
server.DebugLevel = s_debugLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int s_debugLevel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the main HTTP server instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This will be used to register all handlers that listen to the default port.
|
||||||
|
/// </remarks>
|
||||||
|
/// <exception cref='Exception'>
|
||||||
|
/// Thrown if the HTTP server has not already been registered via AddHttpServer()
|
||||||
|
/// </exception>
|
||||||
public static BaseHttpServer Instance
|
public static BaseHttpServer Instance
|
||||||
{
|
{
|
||||||
get { return instance; }
|
get { return instance; }
|
||||||
set { instance = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IHttpServer GetHttpServer(uint port)
|
set
|
||||||
{
|
{
|
||||||
return GetHttpServer(port,null);
|
lock (m_Servers)
|
||||||
|
if (!m_Servers.ContainsValue(value))
|
||||||
|
throw new Exception("HTTP server must already have been registered to be set as the main instance");
|
||||||
|
|
||||||
|
instance = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get all the registered servers.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Returns a copy of the dictionary so this can be iterated through without locking.
|
||||||
|
/// </remarks>
|
||||||
|
/// <value></value>
|
||||||
|
public static Dictionary<uint, BaseHttpServer> Servers
|
||||||
|
{
|
||||||
|
get { return new Dictionary<uint, BaseHttpServer>(m_Servers); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void RegisterHttpConsoleCommands(ICommandConsole console)
|
||||||
|
{
|
||||||
|
console.Commands.AddCommand(
|
||||||
|
"Debug", false, "debug http", "debug http [<level>]",
|
||||||
|
"Turn on inbound non-poll http request debugging.",
|
||||||
|
"If level <= 0, then no extra logging is done.\n"
|
||||||
|
+ "If level >= 1, then short warnings are logged when receiving bad input data.\n"
|
||||||
|
+ "If level >= 2, then long warnings are logged when receiving bad input data.\n"
|
||||||
|
+ "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n"
|
||||||
|
+ "If no level is specified then the current level is returned.",
|
||||||
|
HandleDebugHttpCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on some debugging values for OpenSim.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args"></param>
|
||||||
|
private static void HandleDebugHttpCommand(string module, string[] args)
|
||||||
|
{
|
||||||
|
if (args.Length == 3)
|
||||||
|
{
|
||||||
|
int newDebug;
|
||||||
|
if (int.TryParse(args[2], out newDebug))
|
||||||
|
{
|
||||||
|
MainServer.DebugLevel = newDebug;
|
||||||
|
MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (args.Length == 2)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MainConsole.Instance.Output("Usage: debug http 0..3");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register an already started HTTP server to the collection of known servers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='server'></param>
|
||||||
public static void AddHttpServer(BaseHttpServer server)
|
public static void AddHttpServer(BaseHttpServer server)
|
||||||
{
|
{
|
||||||
|
lock (m_Servers)
|
||||||
|
{
|
||||||
|
if (m_Servers.ContainsKey(server.Port))
|
||||||
|
throw new Exception(string.Format("HTTP server for port {0} already exists.", server.Port));
|
||||||
|
|
||||||
m_Servers.Add(server.Port, server);
|
m_Servers.Add(server.Port, server);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the http server listening on the given port.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// It is the responsibility of the caller to do clean up.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name='port'></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool RemoveHttpServer(uint port)
|
||||||
|
{
|
||||||
|
lock (m_Servers)
|
||||||
|
return m_Servers.Remove(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does this collection of servers contain one with the given port?
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Unlike GetHttpServer, this will not instantiate a server if one does not exist on that port.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name='port'></param>
|
||||||
|
/// <returns>true if a server with the given port is registered, false otherwise.</returns>
|
||||||
|
public static bool ContainsHttpServer(uint port)
|
||||||
|
{
|
||||||
|
lock (m_Servers)
|
||||||
|
return m_Servers.ContainsKey(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the default http server or an http server for a specific port.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <param name='port'>If 0 then the default HTTP server is returned.</param>
|
||||||
|
public static IHttpServer GetHttpServer(uint port)
|
||||||
|
{
|
||||||
|
return GetHttpServer(port, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the default http server, an http server for a specific port
|
||||||
|
/// and/or an http server bound to a specific address
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <param name='port'>If 0 then the default HTTP server is returned.</param>
|
||||||
|
/// <param name='ipaddr'>A specific IP address to bind to. If null then the default IP address is used.</param>
|
||||||
public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
|
public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
|
||||||
{
|
{
|
||||||
if (port == 0)
|
if (port == 0)
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
||||||
if (instance != null && port == Instance.Port)
|
if (instance != null && port == Instance.Port)
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
||||||
|
lock (m_Servers)
|
||||||
|
{
|
||||||
if (m_Servers.ContainsKey(port))
|
if (m_Servers.ContainsKey(port))
|
||||||
return m_Servers[port];
|
return m_Servers[port];
|
||||||
|
|
||||||
|
@ -72,10 +224,10 @@ namespace OpenSim.Framework.Servers
|
||||||
if (ipaddr != null)
|
if (ipaddr != null)
|
||||||
m_Servers[port].ListenIPAddress = ipaddr;
|
m_Servers[port].ListenIPAddress = ipaddr;
|
||||||
|
|
||||||
m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port);
|
|
||||||
m_Servers[port].Start();
|
m_Servers[port].Start();
|
||||||
|
|
||||||
return m_Servers[port];
|
return m_Servers[port];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -34,14 +34,12 @@ namespace OpenSim.Framework.Statistics
|
||||||
{
|
{
|
||||||
private static AssetStatsCollector assetStats;
|
private static AssetStatsCollector assetStats;
|
||||||
private static UserStatsCollector userStats;
|
private static UserStatsCollector userStats;
|
||||||
private static SimExtraStatsCollector simExtraStats;
|
private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
|
||||||
|
|
||||||
public static AssetStatsCollector AssetStats { get { return assetStats; } }
|
public static AssetStatsCollector AssetStats { get { return assetStats; } }
|
||||||
public static UserStatsCollector UserStats { get { return userStats; } }
|
public static UserStatsCollector UserStats { get { return userStats; } }
|
||||||
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
|
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
|
||||||
|
|
||||||
private StatsManager() {}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start collecting statistics related to assets.
|
/// Start collecting statistics related to assets.
|
||||||
/// Should only be called once.
|
/// Should only be called once.
|
||||||
|
@ -63,16 +61,5 @@ namespace OpenSim.Framework.Statistics
|
||||||
|
|
||||||
return userStats;
|
return userStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start collecting extra sim statistics apart from those collected for the client.
|
|
||||||
/// Should only be called once.
|
|
||||||
/// </summary>
|
|
||||||
public static SimExtraStatsCollector StartCollectingSimExtraStats()
|
|
||||||
{
|
|
||||||
simExtraStats = new SimExtraStatsCollector();
|
|
||||||
|
|
||||||
return simExtraStats;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -52,10 +52,10 @@ namespace OpenSim.Framework
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private Thread LockedByThread;
|
private Thread LockedByThread;
|
||||||
private string WriterStack;
|
// private string WriterStack;
|
||||||
|
|
||||||
private Dictionary<Thread, string> ReadLockers =
|
// private Dictionary<Thread, string> ReadLockers =
|
||||||
new Dictionary<Thread, string>();
|
// new Dictionary<Thread, string>();
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// An advanced lock for inventory data
|
/// An advanced lock for inventory data
|
||||||
|
@ -98,14 +98,25 @@ namespace OpenSim.Framework
|
||||||
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_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
|
try
|
||||||
{
|
{
|
||||||
StackTrace stackTrace = new StackTrace(); // get call stack
|
// That call stack is useful for end users only. RealProgrammers need a full dump. Commented.
|
||||||
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
// 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
|
||||||
|
// }
|
||||||
|
|
||||||
// write call stack method names
|
// The below is far more useful
|
||||||
foreach (StackFrame stackFrame in stackFrames)
|
// System.Console.WriteLine("------------------------------------------");
|
||||||
{
|
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||||
m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name
|
// 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
|
catch
|
||||||
{}
|
{}
|
||||||
|
@ -114,6 +125,16 @@ namespace OpenSim.Framework
|
||||||
if (m_itemLock.RecursiveWriteCount > 0)
|
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_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();
|
m_itemLock.ExitWriteLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,15 +144,16 @@ namespace OpenSim.Framework
|
||||||
if (m_itemLock.IsWriteLockHeld)
|
if (m_itemLock.IsWriteLockHeld)
|
||||||
{
|
{
|
||||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||||
System.Console.WriteLine("------------------------------------------");
|
// System.Console.WriteLine("------------------------------------------");
|
||||||
System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||||
System.Console.WriteLine("------------------------------------------");
|
// System.Console.WriteLine("------------------------------------------");
|
||||||
System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
|
// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
|
||||||
System.Console.WriteLine("------------------------------------------");
|
// System.Console.WriteLine("------------------------------------------");
|
||||||
LockedByThread = null;
|
// LockedByThread = null;
|
||||||
ReadLockers.Clear();
|
// ReadLockers.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ReadLockers[Thread.CurrentThread] = Environment.StackTrace;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -139,6 +161,8 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
m_itemLock.ExitReadLock();
|
m_itemLock.ExitReadLock();
|
||||||
}
|
}
|
||||||
|
// if (m_itemLock.RecursiveReadCount == 0)
|
||||||
|
// ReadLockers.Remove(Thread.CurrentThread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +182,7 @@ namespace OpenSim.Framework
|
||||||
if (m_itemLock.RecursiveWriteCount > 0)
|
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_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||||
|
|
||||||
m_itemLock.ExitWriteLock();
|
m_itemLock.ExitWriteLock();
|
||||||
}
|
}
|
||||||
while (!m_itemLock.TryEnterWriteLock(60000))
|
while (!m_itemLock.TryEnterWriteLock(60000))
|
||||||
|
@ -165,30 +190,30 @@ namespace OpenSim.Framework
|
||||||
if (m_itemLock.IsWriteLockHeld)
|
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.");
|
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("------------------------------------------");
|
||||||
System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||||
System.Console.WriteLine("------------------------------------------");
|
// System.Console.WriteLine("------------------------------------------");
|
||||||
System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
|
// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
|
||||||
System.Console.WriteLine("------------------------------------------");
|
// System.Console.WriteLine("------------------------------------------");
|
||||||
}
|
}
|
||||||
else
|
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.");
|
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("------------------------------------------");
|
||||||
System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||||
System.Console.WriteLine("------------------------------------------");
|
// System.Console.WriteLine("------------------------------------------");
|
||||||
foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
|
// foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
|
||||||
{
|
// {
|
||||||
System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
|
// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
|
||||||
System.Console.WriteLine("------------------------------------------");
|
// System.Console.WriteLine("------------------------------------------");
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||||
ReadLockers.Clear();
|
// ReadLockers.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
LockedByThread = Thread.CurrentThread;
|
LockedByThread = Thread.CurrentThread;
|
||||||
WriterStack = Environment.StackTrace;
|
// WriterStack = Environment.StackTrace;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
|
@ -35,6 +37,8 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TaskInventoryItem : ICloneable
|
public class TaskInventoryItem : ICloneable
|
||||||
{
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// XXX This should really be factored out into some constants class.
|
/// XXX This should really be factored out into some constants class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -334,12 +338,18 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OwnerChanged {
|
public bool OwnerChanged
|
||||||
get {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
return _ownerChanged;
|
return _ownerChanged;
|
||||||
}
|
}
|
||||||
set {
|
set
|
||||||
|
{
|
||||||
_ownerChanged = value;
|
_ownerChanged = value;
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[TASK INVENTORY ITEM]: Owner changed set {0} for {1} {2} owned by {3}",
|
||||||
|
// _ownerChanged, Name, ItemID, OwnerID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,10 +227,10 @@ namespace OpenSim.Framework.Tests
|
||||||
es.AddEstateManager(UUID.Zero);
|
es.AddEstateManager(UUID.Zero);
|
||||||
|
|
||||||
es.AddEstateManager(bannedUserId);
|
es.AddEstateManager(bannedUserId);
|
||||||
Assert.IsTrue(es.IsEstateManager(bannedUserId), "bannedUserId should be EstateManager but isn't.");
|
Assert.IsTrue(es.IsEstateManagerOrOwner(bannedUserId), "bannedUserId should be EstateManager but isn't.");
|
||||||
|
|
||||||
es.RemoveEstateManager(bannedUserId);
|
es.RemoveEstateManager(bannedUserId);
|
||||||
Assert.IsFalse(es.IsEstateManager(bannedUserId), "bannedUserID is estateManager but shouldn't be");
|
Assert.IsFalse(es.IsEstateManagerOrOwner(bannedUserId), "bannedUserID is estateManager but shouldn't be");
|
||||||
|
|
||||||
Assert.IsFalse(es.HasAccess(bannedUserId), "bannedUserID has access but shouldn't");
|
Assert.IsFalse(es.HasAccess(bannedUserId), "bannedUserID has access but shouldn't");
|
||||||
|
|
||||||
|
|
|
@ -214,16 +214,13 @@ namespace OpenSim.Framework.Tests
|
||||||
|
|
||||||
for (int i = 0; i < contenttypes.Length; i++)
|
for (int i = 0; i < contenttypes.Length; i++)
|
||||||
{
|
{
|
||||||
if (SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == 18)
|
int expected;
|
||||||
{
|
if (contenttypes[i] == "image/tga")
|
||||||
Assert.That(contenttypes[i] == "image/tga");
|
expected = 12; // if we know only the content-type "image/tga", then we assume the asset type is TextureTGA; not ImageTGA
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
expected = assettypes[i];
|
||||||
Assert.That(SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == assettypes[i],
|
Assert.AreEqual(expected, SLUtil.ContentTypeToSLAssetType(contenttypes[i]),
|
||||||
"Expecting {0} but got {1}", assettypes[i],
|
String.Format("Incorrect AssetType mapped from Content-Type {0}", contenttypes[i]));
|
||||||
SLUtil.ContentTypeToSLAssetType(contenttypes[i]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] inventorytypes = new int[] {-1,0,1,2,3,6,7,8,9,10,15,17,18,20};
|
int[] inventorytypes = new int[] {-1,0,1,2,3,6,7,8,9,10,15,17,18,20};
|
||||||
|
@ -237,7 +234,7 @@ namespace OpenSim.Framework.Tests
|
||||||
"application/vnd.ll.primitive",
|
"application/vnd.ll.primitive",
|
||||||
"application/vnd.ll.notecard",
|
"application/vnd.ll.notecard",
|
||||||
"application/vnd.ll.folder",
|
"application/vnd.ll.folder",
|
||||||
"application/octet-stream",
|
"application/vnd.ll.rootfolder",
|
||||||
"application/vnd.ll.lsltext",
|
"application/vnd.ll.lsltext",
|
||||||
"image/x-j2c",
|
"image/x-j2c",
|
||||||
"application/vnd.ll.primitive",
|
"application/vnd.ll.primitive",
|
||||||
|
@ -247,7 +244,8 @@ namespace OpenSim.Framework.Tests
|
||||||
|
|
||||||
for (int i=0;i<inventorytypes.Length;i++)
|
for (int i=0;i<inventorytypes.Length;i++)
|
||||||
{
|
{
|
||||||
Assert.That(SLUtil.SLInvTypeToContentType(inventorytypes[i]) == invcontenttypes[i], "Expected {0}, Got {1}", invcontenttypes[i], SLUtil.SLInvTypeToContentType(inventorytypes[i]));
|
Assert.AreEqual(invcontenttypes[i], SLUtil.SLInvTypeToContentType(inventorytypes[i]),
|
||||||
|
String.Format("Incorrect Content-Type mapped from InventoryType {0}", inventorytypes[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
invcontenttypes = new string[]
|
invcontenttypes = new string[]
|
||||||
|
@ -280,7 +278,8 @@ namespace OpenSim.Framework.Tests
|
||||||
|
|
||||||
for (int i = 0; i < invtypes.Length; i++)
|
for (int i = 0; i < invtypes.Length; i++)
|
||||||
{
|
{
|
||||||
Assert.That(SLUtil.ContentTypeToSLInvType(invcontenttypes[i]) == invtypes[i], "Expected {0}, Got {1}", invtypes[i], SLUtil.ContentTypeToSLInvType(invcontenttypes[i]));
|
Assert.AreEqual(invtypes[i], SLUtil.ContentTypeToSLInvType(invcontenttypes[i]),
|
||||||
|
String.Format("Incorrect InventoryType mapped from Content-Type {0}", invcontenttypes[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,7 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Encoding UTF8 = Encoding.UTF8;
|
public static Encoding UTF8 = Encoding.UTF8;
|
||||||
|
public static Encoding UTF8NoBomEncoding = new UTF8Encoding(false);
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards)
|
/// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards)
|
||||||
|
@ -1248,8 +1249,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public static string Base64ToString(string str)
|
public static string Base64ToString(string str)
|
||||||
{
|
{
|
||||||
UTF8Encoding encoder = new UTF8Encoding();
|
Decoder utf8Decode = Encoding.UTF8.GetDecoder();
|
||||||
Decoder utf8Decode = encoder.GetDecoder();
|
|
||||||
|
|
||||||
byte[] todecode_byte = Convert.FromBase64String(str);
|
byte[] todecode_byte = Convert.FromBase64String(str);
|
||||||
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
|
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
|
||||||
|
|
|
@ -41,8 +41,8 @@ namespace OpenSim.Framework
|
||||||
/// <summary>Timer interval in milliseconds for the watchdog timer</summary>
|
/// <summary>Timer interval in milliseconds for the watchdog timer</summary>
|
||||||
const double WATCHDOG_INTERVAL_MS = 2500.0d;
|
const double WATCHDOG_INTERVAL_MS = 2500.0d;
|
||||||
|
|
||||||
/// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
|
/// <summary>Default timeout in milliseconds before a thread is considered dead</summary>
|
||||||
const int WATCHDOG_TIMEOUT_MS = 5000;
|
public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
|
[System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
|
||||||
public class ThreadWatchdogInfo
|
public class ThreadWatchdogInfo
|
||||||
|
@ -58,7 +58,7 @@ namespace OpenSim.Framework
|
||||||
public int FirstTick { get; private set; }
|
public int FirstTick { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// First time this heartbeat update was invoked
|
/// Last time this heartbeat update was invoked
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int LastTick { get; set; }
|
public int LastTick { get; set; }
|
||||||
|
|
||||||
|
@ -77,6 +77,11 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AlarmIfTimeout { get; set; }
|
public bool AlarmIfTimeout { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method execute if alarm goes off. If null then no alarm method is fired.
|
||||||
|
/// </summary>
|
||||||
|
public Func<string> AlarmMethod { get; set; }
|
||||||
|
|
||||||
public ThreadWatchdogInfo(Thread thread, int timeout)
|
public ThreadWatchdogInfo(Thread thread, int timeout)
|
||||||
{
|
{
|
||||||
Thread = thread;
|
Thread = thread;
|
||||||
|
@ -87,27 +92,33 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This event is called whenever a tracked thread is stopped or
|
/// This event is called whenever a tracked thread is
|
||||||
/// has not called UpdateThread() in time
|
/// stopped or has not called UpdateThread() in time<
|
||||||
/// </summary>
|
/// /summary>
|
||||||
/// <param name="thread">The thread that has been identified as dead</param>
|
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
|
||||||
/// <param name="lastTick">The last time this thread called UpdateThread()</param>
|
|
||||||
public delegate void WatchdogTimeout(Thread thread, int lastTick);
|
|
||||||
|
|
||||||
/// <summary>This event is called whenever a tracked thread is
|
|
||||||
/// stopped or has not called UpdateThread() in time</summary>
|
|
||||||
public static event WatchdogTimeout OnWatchdogTimeout;
|
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private static Dictionary<int, ThreadWatchdogInfo> m_threads;
|
private static Dictionary<int, ThreadWatchdogInfo> m_threads;
|
||||||
private static System.Timers.Timer m_watchdogTimer;
|
private static System.Timers.Timer m_watchdogTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Last time the watchdog thread ran.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Should run every WATCHDOG_INTERVAL_MS
|
||||||
|
/// </remarks>
|
||||||
|
public static int LastWatchdogThreadTick { get; private set; }
|
||||||
|
|
||||||
static Watchdog()
|
static Watchdog()
|
||||||
{
|
{
|
||||||
m_threads = new Dictionary<int, ThreadWatchdogInfo>();
|
m_threads = new Dictionary<int, ThreadWatchdogInfo>();
|
||||||
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
|
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
|
||||||
m_watchdogTimer.AutoReset = false;
|
m_watchdogTimer.AutoReset = false;
|
||||||
m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
|
m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
|
||||||
|
|
||||||
|
// Set now so we don't get alerted on the first run
|
||||||
|
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
|
||||||
|
|
||||||
m_watchdogTimer.Start();
|
m_watchdogTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +134,7 @@ namespace OpenSim.Framework
|
||||||
public static Thread StartThread(
|
public static Thread StartThread(
|
||||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
|
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
|
||||||
{
|
{
|
||||||
return StartThread(start, name, priority, isBackground, alarmIfTimeout, WATCHDOG_TIMEOUT_MS);
|
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -135,17 +146,24 @@ namespace OpenSim.Framework
|
||||||
/// <param name="isBackground">True to run this thread as a background
|
/// <param name="isBackground">True to run this thread as a background
|
||||||
/// thread, otherwise false</param>
|
/// thread, otherwise false</param>
|
||||||
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
|
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
|
||||||
|
/// <param name="alarmMethod">
|
||||||
|
/// Alarm method to call if alarmIfTimeout is true and there is a timeout.
|
||||||
|
/// Normally, this will just return some useful debugging information.
|
||||||
|
/// </param>
|
||||||
/// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
|
/// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
|
||||||
/// <returns>The newly created Thread object</returns>
|
/// <returns>The newly created Thread object</returns>
|
||||||
public static Thread StartThread(
|
public static Thread StartThread(
|
||||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout)
|
ThreadStart start, string name, ThreadPriority priority, bool isBackground,
|
||||||
|
bool alarmIfTimeout, Func<string> alarmMethod, int timeout)
|
||||||
{
|
{
|
||||||
Thread thread = new Thread(start);
|
Thread thread = new Thread(start);
|
||||||
thread.Name = name;
|
thread.Name = name;
|
||||||
thread.Priority = priority;
|
thread.Priority = priority;
|
||||||
thread.IsBackground = isBackground;
|
thread.IsBackground = isBackground;
|
||||||
|
|
||||||
ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout };
|
ThreadWatchdogInfo twi
|
||||||
|
= new ThreadWatchdogInfo(thread, timeout)
|
||||||
|
{ AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
|
"[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
|
||||||
|
@ -258,7 +276,17 @@ namespace OpenSim.Framework
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
|
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
WatchdogTimeout callback = OnWatchdogTimeout;
|
int now = Environment.TickCount & Int32.MaxValue;
|
||||||
|
int msElapsed = now - LastWatchdogThreadTick;
|
||||||
|
|
||||||
|
if (msElapsed > WATCHDOG_INTERVAL_MS * 2)
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[WATCHDOG]: {0} ms since Watchdog last ran. Interval should be approximately {1} ms",
|
||||||
|
msElapsed, WATCHDOG_INTERVAL_MS);
|
||||||
|
|
||||||
|
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
|
||||||
|
|
||||||
|
Action<ThreadWatchdogInfo> callback = OnWatchdogTimeout;
|
||||||
|
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
|
@ -266,8 +294,6 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
lock (m_threads)
|
lock (m_threads)
|
||||||
{
|
{
|
||||||
int now = Environment.TickCount;
|
|
||||||
|
|
||||||
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
|
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
|
||||||
{
|
{
|
||||||
if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
|
if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
|
||||||
|
@ -296,7 +322,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
if (callbackInfos != null)
|
if (callbackInfos != null)
|
||||||
foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
|
foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
|
||||||
callback(callbackInfo.Thread, callbackInfo.LastTick);
|
callback(callbackInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_watchdogTimer.Start();
|
m_watchdogTimer.Start();
|
||||||
|
|
|
@ -53,20 +53,37 @@ namespace OpenSim.Framework
|
||||||
LogManager.GetLogger(
|
LogManager.GetLogger(
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static int m_requestNumber = 0;
|
/// <summary>
|
||||||
|
/// Request number for diagnostic purposes.
|
||||||
|
/// </summary>
|
||||||
|
public static int RequestNumber = 0;
|
||||||
|
|
||||||
// this is the header field used to communicate the local request id
|
/// <summary>
|
||||||
// used for performance and debugging
|
/// this is the header field used to communicate the local request id
|
||||||
|
/// used for performance and debugging
|
||||||
|
/// </summary>
|
||||||
public const string OSHeaderRequestID = "opensim-request-id";
|
public const string OSHeaderRequestID = "opensim-request-id";
|
||||||
|
|
||||||
// number of milliseconds a call can take before it is considered
|
/// <summary>
|
||||||
// a "long" call for warning & debugging purposes
|
/// Number of milliseconds a call can take before it is considered
|
||||||
public const int LongCallTime = 500;
|
/// a "long" call for warning & debugging purposes
|
||||||
|
/// </summary>
|
||||||
|
public const int LongCallTime = 3000;
|
||||||
|
|
||||||
// dictionary of end points
|
/// <summary>
|
||||||
|
/// The maximum length of any data logged because of a long request time.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is to truncate any really large post data, such as an asset. In theory, the first section should
|
||||||
|
/// give us useful information about the call (which agent it relates to if applicable, etc.).
|
||||||
|
/// </remarks>
|
||||||
|
public const int MaxRequestDiagLength = 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dictionary of end points
|
||||||
|
/// </summary>
|
||||||
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
|
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
|
||||||
|
|
||||||
|
|
||||||
private static object EndPointLock(string url)
|
private static object EndPointLock(string url)
|
||||||
{
|
{
|
||||||
System.Uri uri = new System.Uri(url);
|
System.Uri uri = new System.Uri(url);
|
||||||
|
@ -87,7 +104,6 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region JSONRequest
|
#region JSONRequest
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -129,12 +145,13 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
|
private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
|
||||||
{
|
{
|
||||||
int reqnum = m_requestNumber++;
|
int reqnum = RequestNumber++;
|
||||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
string errorMessage = "unknown error";
|
string errorMessage = "unknown error";
|
||||||
int tickstart = Util.EnvironmentTickCount();
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
int tickdata = 0;
|
int tickdata = 0;
|
||||||
|
string strBuffer = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -149,7 +166,7 @@ namespace OpenSim.Framework
|
||||||
// If there is some input, write it into the request
|
// If there is some input, write it into the request
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
string strBuffer = OSDParser.SerializeJsonString(data);
|
strBuffer = OSDParser.SerializeJsonString(data);
|
||||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
|
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
|
||||||
|
|
||||||
if (compressed)
|
if (compressed)
|
||||||
|
@ -210,14 +227,23 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// This just dumps a warning for any operation that takes more than 100 ms
|
|
||||||
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
if (tickdiff > LongCallTime)
|
if (tickdiff > LongCallTime)
|
||||||
m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
|
m_log.InfoFormat(
|
||||||
reqnum,url,method,tickdiff,tickdata);
|
"[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
strBuffer != null
|
||||||
|
? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
|
||||||
|
: "");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
|
m_log.DebugFormat(
|
||||||
|
"[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
|
||||||
|
|
||||||
return ErrorResponseMap(errorMessage);
|
return ErrorResponseMap(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,17 +316,17 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout)
|
private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout)
|
||||||
{
|
{
|
||||||
int reqnum = m_requestNumber++;
|
int reqnum = RequestNumber++;
|
||||||
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
|
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
|
||||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
string errorMessage = "unknown error";
|
string errorMessage = "unknown error";
|
||||||
int tickstart = Util.EnvironmentTickCount();
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
int tickdata = 0;
|
int tickdata = 0;
|
||||||
|
string queryString = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
|
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
|
||||||
request.Method = "POST";
|
request.Method = "POST";
|
||||||
request.Timeout = timeout;
|
request.Timeout = timeout;
|
||||||
|
@ -311,7 +337,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
string queryString = BuildQueryString(data);
|
queryString = BuildQueryString(data);
|
||||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
|
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
|
||||||
|
|
||||||
request.ContentLength = buffer.Length;
|
request.ContentLength = buffer.Length;
|
||||||
|
@ -354,11 +380,20 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
if (tickdiff > LongCallTime)
|
if (tickdiff > LongCallTime)
|
||||||
m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
|
m_log.InfoFormat(
|
||||||
reqnum,url,method,tickdiff,tickdata);
|
"[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
queryString != null
|
||||||
|
? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString
|
||||||
|
: "");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.WarnFormat("[WEB UTIL]: <{0}> form request failed: {1}",reqnum,errorMessage);
|
m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage);
|
||||||
|
|
||||||
return ErrorResponseMap(errorMessage);
|
return ErrorResponseMap(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,8 +673,6 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
return new string[0];
|
return new string[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AsynchronousRestObjectRequester
|
public static class AsynchronousRestObjectRequester
|
||||||
|
@ -662,6 +695,12 @@ namespace OpenSim.Framework
|
||||||
public static void MakeRequest<TRequest, TResponse>(string verb,
|
public static void MakeRequest<TRequest, TResponse>(string verb,
|
||||||
string requestUrl, TRequest obj, Action<TResponse> action)
|
string requestUrl, TRequest obj, Action<TResponse> action)
|
||||||
{
|
{
|
||||||
|
int reqnum = WebUtil.RequestNumber++;
|
||||||
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
|
int tickdata = 0;
|
||||||
|
|
||||||
// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
|
// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
|
||||||
|
|
||||||
Type type = typeof(TRequest);
|
Type type = typeof(TRequest);
|
||||||
|
@ -672,12 +711,13 @@ namespace OpenSim.Framework
|
||||||
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
|
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
|
||||||
|
|
||||||
request.Method = verb;
|
request.Method = verb;
|
||||||
|
MemoryStream buffer = null;
|
||||||
|
|
||||||
if (verb == "POST")
|
if (verb == "POST")
|
||||||
{
|
{
|
||||||
request.ContentType = "text/xml";
|
request.ContentType = "text/xml";
|
||||||
|
|
||||||
MemoryStream buffer = new MemoryStream();
|
buffer = new MemoryStream();
|
||||||
|
|
||||||
XmlWriterSettings settings = new XmlWriterSettings();
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
settings.Encoding = Encoding.UTF8;
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
@ -699,6 +739,9 @@ namespace OpenSim.Framework
|
||||||
requestStream.Write(buffer.ToArray(), 0, length);
|
requestStream.Write(buffer.ToArray(), 0, length);
|
||||||
requestStream.Close();
|
requestStream.Close();
|
||||||
|
|
||||||
|
// capture how much time was spent writing
|
||||||
|
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
|
|
||||||
request.BeginGetResponse(delegate(IAsyncResult ar)
|
request.BeginGetResponse(delegate(IAsyncResult ar)
|
||||||
{
|
{
|
||||||
response = request.EndGetResponse(ar);
|
response = request.EndGetResponse(ar);
|
||||||
|
@ -724,11 +767,9 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
}, null);
|
}, null);
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
request.BeginGetResponse(delegate(IAsyncResult res2)
|
request.BeginGetResponse(delegate(IAsyncResult res2)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -772,12 +813,16 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", verb, requestUrl, e.Status, e.Message);
|
m_log.ErrorFormat(
|
||||||
|
"[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}",
|
||||||
|
verb, requestUrl, e.Status, e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with exception {2}", verb, requestUrl, 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());
|
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
|
||||||
|
@ -789,18 +834,41 @@ namespace OpenSim.Framework
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}", verb, requestUrl, e);
|
"[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}",
|
||||||
|
verb, requestUrl, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
|
if (tickdiff > WebUtil.LongCallTime)
|
||||||
|
{
|
||||||
|
string originalRequest = null;
|
||||||
|
|
||||||
|
if (buffer != null)
|
||||||
|
{
|
||||||
|
originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
|
||||||
|
|
||||||
|
if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
|
||||||
|
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
verb,
|
||||||
|
requestUrl,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
originalRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SynchronousRestFormsRequester
|
public static class SynchronousRestFormsRequester
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
LogManager.GetLogger(
|
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform a synchronous REST request.
|
/// Perform a synchronous REST request.
|
||||||
|
@ -814,6 +882,12 @@ namespace OpenSim.Framework
|
||||||
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
||||||
public static string MakeRequest(string verb, string requestUrl, string obj)
|
public static string MakeRequest(string verb, string requestUrl, string obj)
|
||||||
{
|
{
|
||||||
|
int reqnum = WebUtil.RequestNumber++;
|
||||||
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
|
int tickdata = 0;
|
||||||
|
|
||||||
WebRequest request = WebRequest.Create(requestUrl);
|
WebRequest request = WebRequest.Create(requestUrl);
|
||||||
request.Method = verb;
|
request.Method = verb;
|
||||||
string respstring = String.Empty;
|
string respstring = String.Empty;
|
||||||
|
@ -842,12 +916,16 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl);
|
m_log.DebugFormat(
|
||||||
|
"[FORMS]: exception occured {0} {1}: {2}{3}", verb, requestUrl, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (requestStream != null)
|
if (requestStream != null)
|
||||||
requestStream.Close();
|
requestStream.Close();
|
||||||
|
|
||||||
|
// capture how much time was spent writing
|
||||||
|
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,7 +946,9 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString());
|
m_log.DebugFormat(
|
||||||
|
"[FORMS]: Exception occured on receiving {0} {1}: {2}{3}",
|
||||||
|
verb, requestUrl, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -881,9 +961,21 @@ namespace OpenSim.Framework
|
||||||
catch (System.InvalidOperationException)
|
catch (System.InvalidOperationException)
|
||||||
{
|
{
|
||||||
// This is what happens when there is invalid XML
|
// This is what happens when there is invalid XML
|
||||||
m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request");
|
m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
|
if (tickdiff > WebUtil.LongCallTime)
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
verb,
|
||||||
|
requestUrl,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
|
||||||
|
|
||||||
return respstring;
|
return respstring;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -911,6 +1003,12 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout)
|
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout)
|
||||||
{
|
{
|
||||||
|
int reqnum = WebUtil.RequestNumber++;
|
||||||
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
|
int tickdata = 0;
|
||||||
|
|
||||||
Type type = typeof(TRequest);
|
Type type = typeof(TRequest);
|
||||||
TResponse deserial = default(TResponse);
|
TResponse deserial = default(TResponse);
|
||||||
|
|
||||||
|
@ -918,12 +1016,13 @@ namespace OpenSim.Framework
|
||||||
request.Method = verb;
|
request.Method = verb;
|
||||||
if (pTimeout != 0)
|
if (pTimeout != 0)
|
||||||
request.Timeout = pTimeout * 1000;
|
request.Timeout = pTimeout * 1000;
|
||||||
|
MemoryStream buffer = null;
|
||||||
|
|
||||||
if ((verb == "POST") || (verb == "PUT"))
|
if ((verb == "POST") || (verb == "PUT"))
|
||||||
{
|
{
|
||||||
request.ContentType = "text/xml";
|
request.ContentType = "text/xml";
|
||||||
|
|
||||||
MemoryStream buffer = new MemoryStream();
|
buffer = new MemoryStream();
|
||||||
|
|
||||||
XmlWriterSettings settings = new XmlWriterSettings();
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
settings.Encoding = Encoding.UTF8;
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
@ -946,13 +1045,19 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e);
|
m_log.DebugFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Exception in making request {0} {1}: {2}{3}",
|
||||||
|
verb, requestUrl, e.Message, e.StackTrace);
|
||||||
|
|
||||||
return deserial;
|
return deserial;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (requestStream != null)
|
if (requestStream != null)
|
||||||
requestStream.Close();
|
requestStream.Close();
|
||||||
|
|
||||||
|
// capture how much time was spent writing
|
||||||
|
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,7 +1073,11 @@ namespace OpenSim.Framework
|
||||||
respStream.Close();
|
respStream.Close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb);
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}",
|
||||||
|
verb, requestUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (WebException e)
|
catch (WebException e)
|
||||||
|
@ -979,17 +1088,44 @@ namespace OpenSim.Framework
|
||||||
return deserial;
|
return deserial;
|
||||||
else
|
else
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[SynchronousRestObjectRequester]: WebException {0} {1} {2} {3}",
|
"[SynchronousRestObjectRequester]: WebException for {0} {1} {2}: {3} {4}",
|
||||||
requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
|
verb, requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
catch (System.InvalidOperationException)
|
catch (System.InvalidOperationException)
|
||||||
{
|
{
|
||||||
// This is what happens when there is invalid XML
|
// This is what happens when there is invalid XML
|
||||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString());
|
m_log.DebugFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Invalid XML from {0} {1} {2}",
|
||||||
|
verb, requestUrl, typeof(TResponse).ToString());
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e);
|
m_log.DebugFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Exception on response from {0} {1}: {2}{3}",
|
||||||
|
verb, requestUrl, e.Message, e.StackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
|
if (tickdiff > WebUtil.LongCallTime)
|
||||||
|
{
|
||||||
|
string originalRequest = null;
|
||||||
|
|
||||||
|
if (buffer != null)
|
||||||
|
{
|
||||||
|
originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
|
||||||
|
|
||||||
|
if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
|
||||||
|
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
verb,
|
||||||
|
requestUrl,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
originalRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
return deserial;
|
return deserial;
|
||||||
|
|
|
@ -92,9 +92,14 @@ namespace OpenSim
|
||||||
m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
|
m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.InfoFormat(
|
||||||
"[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
|
"[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
|
||||||
|
|
||||||
|
string monoThreadsPerCpu = System.Environment.GetEnvironmentVariable("MONO_THREADS_PER_CPU");
|
||||||
|
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset");
|
||||||
|
|
||||||
// Increase the number of IOCP threads available. Mono defaults to a tragically low number
|
// Increase the number of IOCP threads available. Mono defaults to a tragically low number
|
||||||
int workerThreads, iocpThreads;
|
int workerThreads, iocpThreads;
|
||||||
System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
|
System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
|
||||||
|
@ -109,7 +114,6 @@ namespace OpenSim
|
||||||
|
|
||||||
// Check if the system is compatible with OpenSimulator.
|
// Check if the system is compatible with OpenSimulator.
|
||||||
// Ensures that the minimum system requirements are met
|
// Ensures that the minimum system requirements are met
|
||||||
m_log.Info("Performing compatibility checks... \n");
|
|
||||||
string supported = String.Empty;
|
string supported = String.Empty;
|
||||||
if (Util.IsEnvironmentSupported(ref supported))
|
if (Util.IsEnvironmentSupported(ref supported))
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -69,6 +70,7 @@ namespace OpenSim
|
||||||
private Regex m_consolePromptRegex = new Regex(@"([^\\])\\(\w)", RegexOptions.Compiled);
|
private Regex m_consolePromptRegex = new Regex(@"([^\\])\\(\w)", RegexOptions.Compiled);
|
||||||
|
|
||||||
private string m_timedScript = "disabled";
|
private string m_timedScript = "disabled";
|
||||||
|
private int m_timeInterval = 1200;
|
||||||
private Timer m_scriptTimer;
|
private Timer m_scriptTimer;
|
||||||
|
|
||||||
public OpenSim(IConfigSource configSource) : base(configSource)
|
public OpenSim(IConfigSource configSource) : base(configSource)
|
||||||
|
@ -98,6 +100,10 @@ namespace OpenSim
|
||||||
m_consolePort = (uint)networkConfig.GetInt("console_port", 0);
|
m_consolePort = (uint)networkConfig.GetInt("console_port", 0);
|
||||||
|
|
||||||
m_timedScript = startupConfig.GetString("timer_Script", "disabled");
|
m_timedScript = startupConfig.GetString("timer_Script", "disabled");
|
||||||
|
if (m_timedScript != "disabled")
|
||||||
|
{
|
||||||
|
m_timeInterval = startupConfig.GetInt("timer_Interval", 1200);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_logFileAppender != null)
|
if (m_logFileAppender != null)
|
||||||
{
|
{
|
||||||
|
@ -215,7 +221,7 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
m_scriptTimer = new Timer();
|
m_scriptTimer = new Timer();
|
||||||
m_scriptTimer.Enabled = true;
|
m_scriptTimer.Enabled = true;
|
||||||
m_scriptTimer.Interval = 1200*1000;
|
m_scriptTimer.Interval = m_timeInterval*1000;
|
||||||
m_scriptTimer.Elapsed += RunAutoTimerScript;
|
m_scriptTimer.Elapsed += RunAutoTimerScript;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,12 +231,14 @@ namespace OpenSim
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void RegisterConsoleCommands()
|
private void RegisterConsoleCommands()
|
||||||
{
|
{
|
||||||
m_console.Commands.AddCommand("Regions", false, "force update",
|
MainServer.RegisterHttpConsoleCommands(m_console);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("Objects", false, "force update",
|
||||||
"force update",
|
"force update",
|
||||||
"Force the update of all objects on clients",
|
"Force the update of all objects on clients",
|
||||||
HandleForceUpdate);
|
HandleForceUpdate);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("Comms", false, "debug packet",
|
m_console.Commands.AddCommand("Debug", false, "debug packet",
|
||||||
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
|
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
|
||||||
"Turn on packet debugging",
|
"Turn on packet debugging",
|
||||||
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
||||||
|
@ -242,17 +250,9 @@ namespace OpenSim
|
||||||
+ "If an avatar name is given then only packets from that avatar are logged",
|
+ "If an avatar name is given then only packets from that avatar are logged",
|
||||||
Debug);
|
Debug);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("Comms", false, "debug http",
|
m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
||||||
"debug http <level>",
|
|
||||||
"Turn on inbound http request debugging for everything except the event queue (see debug eq).",
|
|
||||||
"If level >= 2 then the handler used to service the request is logged.\n"
|
|
||||||
+ "If level >= 1 then incoming HTTP requests are logged.\n"
|
|
||||||
+ "If level <= 0 then no extra http logging is done.\n",
|
|
||||||
Debug);
|
|
||||||
|
|
||||||
m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
m_console.Commands.AddCommand("Debug", false, "debug scene",
|
||||||
|
|
||||||
m_console.Commands.AddCommand("Regions", false, "debug scene",
|
|
||||||
"debug scene <scripting> <collisions> <physics>",
|
"debug scene <scripting> <collisions> <physics>",
|
||||||
"Turn on scene debugging", Debug);
|
"Turn on scene debugging", Debug);
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ namespace OpenSim
|
||||||
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
||||||
SaveOar);
|
SaveOar);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("Regions", false, "edit scale",
|
m_console.Commands.AddCommand("Objects", false, "edit scale",
|
||||||
"edit scale <name> <x> <y> <z>",
|
"edit scale <name> <x> <y> <z>",
|
||||||
"Change the scale of a named prim", HandleEditScale);
|
"Change the scale of a named prim", HandleEditScale);
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ namespace OpenSim
|
||||||
"show ratings",
|
"show ratings",
|
||||||
"Show rating data", HandleShow);
|
"Show rating data", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("Regions", false, "backup",
|
m_console.Commands.AddCommand("Objects", false, "backup",
|
||||||
"backup",
|
"backup",
|
||||||
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
|
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
|
||||||
|
|
||||||
|
@ -409,10 +409,6 @@ namespace OpenSim
|
||||||
m_console.Commands.AddCommand("General", false, "modules unload",
|
m_console.Commands.AddCommand("General", false, "modules unload",
|
||||||
"modules unload <name>",
|
"modules unload <name>",
|
||||||
"Unload a module", HandleModules);
|
"Unload a module", HandleModules);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("Regions", false, "kill uuid",
|
|
||||||
"kill uuid <UUID>",
|
|
||||||
"Kill an object by UUID", KillUUID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ShutdownSpecific()
|
public override void ShutdownSpecific()
|
||||||
|
@ -437,12 +433,16 @@ namespace OpenSim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WatchdogTimeoutHandler(System.Threading.Thread thread, int lastTick)
|
private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi)
|
||||||
{
|
{
|
||||||
int now = Environment.TickCount & Int32.MaxValue;
|
int now = Environment.TickCount & Int32.MaxValue;
|
||||||
|
|
||||||
m_log.ErrorFormat("[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago",
|
m_log.ErrorFormat(
|
||||||
thread.Name, thread.ThreadState, now - lastTick);
|
"[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}",
|
||||||
|
twi.Thread.Name,
|
||||||
|
twi.Thread.ThreadState,
|
||||||
|
now - twi.LastTick,
|
||||||
|
twi.AlarmMethod != null ? string.Format("Data: {0}", twi.AlarmMethod()) : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Console Commands
|
#region Console Commands
|
||||||
|
@ -481,10 +481,10 @@ namespace OpenSim
|
||||||
else
|
else
|
||||||
presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
|
presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
|
||||||
|
|
||||||
// ...and close on our side
|
|
||||||
presence.Scene.IncomingCloseAgent(presence.UUID);
|
presence.Scene.IncomingCloseAgent(presence.UUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainConsole.Instance.Output("");
|
MainConsole.Instance.Output("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,9 +618,10 @@ namespace OpenSim
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PopulateRegionEstateInfo(regInfo);
|
bool changed = PopulateRegionEstateInfo(regInfo);
|
||||||
IScene scene;
|
IScene scene;
|
||||||
CreateRegion(regInfo, true, out scene);
|
CreateRegion(regInfo, true, out scene);
|
||||||
|
if (changed)
|
||||||
regInfo.EstateSettings.Save();
|
regInfo.EstateSettings.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,21 +904,6 @@ namespace OpenSim
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "http":
|
|
||||||
if (args.Length == 3)
|
|
||||||
{
|
|
||||||
int newDebug;
|
|
||||||
if (int.TryParse(args[2], out newDebug))
|
|
||||||
{
|
|
||||||
MainServer.Instance.DebugLevel = newDebug;
|
|
||||||
MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MainConsole.Instance.Output("Usage: debug http 0..2");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "scene":
|
case "scene":
|
||||||
if (args.Length == 4)
|
if (args.Length == 4)
|
||||||
{
|
{
|
||||||
|
@ -969,8 +955,7 @@ namespace OpenSim
|
||||||
if (showParams.Length > 1 && showParams[1] == "full")
|
if (showParams.Length > 1 && showParams[1] == "full")
|
||||||
{
|
{
|
||||||
agents = m_sceneManager.GetCurrentScenePresences();
|
agents = m_sceneManager.GetCurrentScenePresences();
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
{
|
{
|
||||||
agents = m_sceneManager.GetCurrentSceneAvatars();
|
agents = m_sceneManager.GetCurrentSceneAvatars();
|
||||||
}
|
}
|
||||||
|
@ -979,7 +964,8 @@ namespace OpenSim
|
||||||
|
|
||||||
MainConsole.Instance.Output(
|
MainConsole.Instance.Output(
|
||||||
String.Format("{0,-16} {1,-16} {2,-37} {3,-11} {4,-16} {5,-30}", "Firstname", "Lastname",
|
String.Format("{0,-16} {1,-16} {2,-37} {3,-11} {4,-16} {5,-30}", "Firstname", "Lastname",
|
||||||
"Agent ID", "Root/Child", "Region", "Position"));
|
"Agent ID", "Root/Child", "Region", "Position")
|
||||||
|
);
|
||||||
|
|
||||||
foreach (ScenePresence presence in agents)
|
foreach (ScenePresence presence in agents)
|
||||||
{
|
{
|
||||||
|
@ -989,8 +975,7 @@ namespace OpenSim
|
||||||
if (regionInfo == null)
|
if (regionInfo == null)
|
||||||
{
|
{
|
||||||
regionName = "Unresolvable";
|
regionName = "Unresolvable";
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
{
|
{
|
||||||
regionName = regionInfo.RegionName;
|
regionName = regionInfo.RegionName;
|
||||||
}
|
}
|
||||||
|
@ -1003,43 +988,19 @@ namespace OpenSim
|
||||||
presence.UUID,
|
presence.UUID,
|
||||||
presence.IsChildAgent ? "Child" : "Root",
|
presence.IsChildAgent ? "Child" : "Root",
|
||||||
regionName,
|
regionName,
|
||||||
presence.AbsolutePosition.ToString()));
|
presence.AbsolutePosition.ToString())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainConsole.Instance.Output(String.Empty);
|
MainConsole.Instance.Output(String.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "connections":
|
case "connections":
|
||||||
System.Text.StringBuilder connections = new System.Text.StringBuilder("Connections:\n");
|
HandleShowConnections();
|
||||||
m_sceneManager.ForEachScene(
|
|
||||||
delegate(Scene scene)
|
|
||||||
{
|
|
||||||
scene.ForEachClient(
|
|
||||||
delegate(IClientAPI client)
|
|
||||||
{
|
|
||||||
connections.AppendFormat("{0}: {1} ({2}) from {3} on circuit {4}\n",
|
|
||||||
scene.RegionInfo.RegionName, client.Name, client.AgentId, client.RemoteEndPoint, client.CircuitCode);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
MainConsole.Instance.Output(connections.ToString());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "circuits":
|
case "circuits":
|
||||||
System.Text.StringBuilder acd = new System.Text.StringBuilder("Agent Circuits:\n");
|
HandleShowCircuits();
|
||||||
m_sceneManager.ForEachScene(
|
|
||||||
delegate(Scene scene)
|
|
||||||
{
|
|
||||||
//this.HttpServer.
|
|
||||||
acd.AppendFormat("{0}:\n", scene.RegionInfo.RegionName);
|
|
||||||
foreach (AgentCircuitData aCircuit in scene.AuthenticateHandler.GetAgentCircuits().Values)
|
|
||||||
acd.AppendFormat("\t{0} {1} ({2})\n", aCircuit.firstname, aCircuit.lastname, (aCircuit.child ? "Child" : "Root"));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
MainConsole.Instance.Output(acd.ToString());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "http-handlers":
|
case "http-handlers":
|
||||||
|
@ -1077,8 +1038,7 @@ namespace OpenSim
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sceneManager.ForEachScene(
|
m_sceneManager.ForEachScene(
|
||||||
delegate(Scene scene)
|
delegate(Scene scene) {
|
||||||
{
|
|
||||||
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
|
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
|
||||||
foreach (IRegionModule module in scene.Modules.Values)
|
foreach (IRegionModule module in scene.Modules.Values)
|
||||||
{
|
{
|
||||||
|
@ -1087,7 +1047,20 @@ namespace OpenSim
|
||||||
m_log.Error("Region Module: " + module.Name);
|
m_log.Error("Region Module: " + module.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
m_sceneManager.ForEachScene(
|
||||||
|
delegate(Scene scene) {
|
||||||
|
MainConsole.Instance.Output("Loaded new region modules in" + scene.RegionInfo.RegionName + " are:");
|
||||||
|
foreach (IRegionModuleBase module in scene.RegionModules.Values)
|
||||||
|
{
|
||||||
|
Type type = module.GetType().GetInterface("ISharedRegionModule");
|
||||||
|
string module_type = type != null ? "Shared" : "Non-Shared";
|
||||||
|
MainConsole.Instance.OutputFormat("New Region Module ({0}): {1}", module_type, module.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
MainConsole.Instance.Output("");
|
MainConsole.Instance.Output("");
|
||||||
break;
|
break;
|
||||||
|
@ -1132,6 +1105,53 @@ namespace OpenSim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleShowCircuits()
|
||||||
|
{
|
||||||
|
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||||
|
cdt.AddColumn("Region", 20);
|
||||||
|
cdt.AddColumn("Avatar name", 24);
|
||||||
|
cdt.AddColumn("Type", 5);
|
||||||
|
cdt.AddColumn("Code", 10);
|
||||||
|
cdt.AddColumn("IP", 16);
|
||||||
|
cdt.AddColumn("Viewer Name", 24);
|
||||||
|
|
||||||
|
m_sceneManager.ForEachScene(
|
||||||
|
s =>
|
||||||
|
{
|
||||||
|
foreach (AgentCircuitData aCircuit in s.AuthenticateHandler.GetAgentCircuits().Values)
|
||||||
|
cdt.AddRow(
|
||||||
|
s.Name,
|
||||||
|
aCircuit.Name,
|
||||||
|
aCircuit.child ? "child" : "root",
|
||||||
|
aCircuit.circuitcode.ToString(),
|
||||||
|
aCircuit.IPAddress.ToString(),
|
||||||
|
aCircuit.Viewer);
|
||||||
|
});
|
||||||
|
|
||||||
|
MainConsole.Instance.Output(cdt.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleShowConnections()
|
||||||
|
{
|
||||||
|
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||||
|
cdt.AddColumn("Region", 20);
|
||||||
|
cdt.AddColumn("Avatar name", 24);
|
||||||
|
cdt.AddColumn("Circuit code", 12);
|
||||||
|
cdt.AddColumn("Endpoint", 23);
|
||||||
|
cdt.AddColumn("Active?", 7);
|
||||||
|
|
||||||
|
m_sceneManager.ForEachScene(
|
||||||
|
s => s.ForEachClient(
|
||||||
|
c => cdt.AddRow(
|
||||||
|
s.Name,
|
||||||
|
c.Name,
|
||||||
|
c.RemoteEndPoint.ToString(),
|
||||||
|
c.CircuitCode.ToString(),
|
||||||
|
c.IsActive.ToString())));
|
||||||
|
|
||||||
|
MainConsole.Instance.Output(cdt.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use XML2 format to serialize data to a file
|
/// Use XML2 format to serialize data to a file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1299,58 +1319,6 @@ namespace OpenSim
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Kill an object given its UUID.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cmdparams"></param>
|
|
||||||
protected void KillUUID(string module, string[] cmdparams)
|
|
||||||
{
|
|
||||||
if (cmdparams.Length > 2)
|
|
||||||
{
|
|
||||||
UUID id = UUID.Zero;
|
|
||||||
SceneObjectGroup grp = null;
|
|
||||||
Scene sc = null;
|
|
||||||
|
|
||||||
if (!UUID.TryParse(cmdparams[2], out id))
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("[KillUUID]: Error bad UUID format!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sceneManager.ForEachScene(
|
|
||||||
delegate(Scene scene)
|
|
||||||
{
|
|
||||||
SceneObjectPart part = scene.GetSceneObjectPart(id);
|
|
||||||
if (part == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
grp = part.ParentGroup;
|
|
||||||
sc = scene;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (grp == null)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output(String.Format("[KillUUID]: Given UUID {0} not found!", id));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output(String.Format("[KillUUID]: Found UUID {0} in scene {1}", id, sc.RegionInfo.RegionName));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
sc.DeleteSceneObject(grp, false);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[KillUUID]: Error while removing objects from scene: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("[KillUUID]: Usage: kill uuid <UUID>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,7 +232,7 @@ namespace OpenSim
|
||||||
|
|
||||||
base.StartupSpecific();
|
base.StartupSpecific();
|
||||||
|
|
||||||
m_stats = StatsManager.StartCollectingSimExtraStats();
|
m_stats = StatsManager.SimExtraStats;
|
||||||
|
|
||||||
// Create a ModuleLoader instance
|
// Create a ModuleLoader instance
|
||||||
m_moduleLoader = new ModuleLoader(m_config.Source);
|
m_moduleLoader = new ModuleLoader(m_config.Source);
|
||||||
|
@ -437,7 +437,7 @@ namespace OpenSim
|
||||||
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
|
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
|
||||||
|
|
||||||
// TODO : Try setting resource for region xstats here on scene
|
// TODO : Try setting resource for region xstats here on scene
|
||||||
MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo));
|
MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo));
|
||||||
|
|
||||||
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
|
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
|
||||||
scene.EventManager.TriggerParcelPrimCountUpdate();
|
scene.EventManager.TriggerParcelPrimCountUpdate();
|
||||||
|
@ -856,6 +856,9 @@ namespace OpenSim
|
||||||
return Util.UTF8.GetBytes("OK");
|
return Util.UTF8.GetBytes("OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Name { get { return "SimStatus"; } }
|
||||||
|
public string Description { get { return "Simulator Status"; } }
|
||||||
|
|
||||||
public string ContentType
|
public string ContentType
|
||||||
{
|
{
|
||||||
get { return "text/plain"; }
|
get { return "text/plain"; }
|
||||||
|
@ -881,6 +884,9 @@ namespace OpenSim
|
||||||
OpenSimBase m_opensim;
|
OpenSimBase m_opensim;
|
||||||
string osXStatsURI = String.Empty;
|
string osXStatsURI = String.Empty;
|
||||||
|
|
||||||
|
public string Name { get { return "XSimStatus"; } }
|
||||||
|
public string Description { get { return "Simulator XStatus"; } }
|
||||||
|
|
||||||
public XSimStatusHandler(OpenSimBase sim)
|
public XSimStatusHandler(OpenSimBase sim)
|
||||||
{
|
{
|
||||||
m_opensim = sim;
|
m_opensim = sim;
|
||||||
|
@ -921,6 +927,9 @@ namespace OpenSim
|
||||||
OpenSimBase m_opensim;
|
OpenSimBase m_opensim;
|
||||||
string osUXStatsURI = String.Empty;
|
string osUXStatsURI = String.Empty;
|
||||||
|
|
||||||
|
public string Name { get { return "UXSimStatus"; } }
|
||||||
|
public string Description { get { return "Simulator UXStatus"; } }
|
||||||
|
|
||||||
public UXSimStatusHandler(OpenSimBase sim)
|
public UXSimStatusHandler(OpenSimBase sim)
|
||||||
{
|
{
|
||||||
m_opensim = sim;
|
m_opensim = sim;
|
||||||
|
@ -1051,13 +1060,13 @@ namespace OpenSim
|
||||||
/// Load the estate information for the provided RegionInfo object.
|
/// Load the estate information for the provided RegionInfo object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="regInfo"></param>
|
/// <param name="regInfo"></param>
|
||||||
public void PopulateRegionEstateInfo(RegionInfo regInfo)
|
public bool PopulateRegionEstateInfo(RegionInfo regInfo)
|
||||||
{
|
{
|
||||||
if (EstateDataService != null)
|
if (EstateDataService != null)
|
||||||
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
|
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
|
||||||
|
|
||||||
if (regInfo.EstateSettings.EstateID != 0)
|
if (regInfo.EstateSettings.EstateID != 0)
|
||||||
return;
|
return false; // estate info in the database did not change
|
||||||
|
|
||||||
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
|
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
|
||||||
|
|
||||||
|
@ -1092,7 +1101,7 @@ namespace OpenSim
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultEstateJoined)
|
if (defaultEstateJoined)
|
||||||
return;
|
return true; // need to update the database
|
||||||
else
|
else
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName);
|
"[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName);
|
||||||
|
@ -1155,6 +1164,8 @@ namespace OpenSim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true; // need to update the database
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// the root of all evil
|
// the root of all evil
|
||||||
m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest));
|
m_HostCapsObj.RegisterHandler(
|
||||||
|
"SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
|
"[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
|
||||||
|
|
||||||
|
@ -166,7 +168,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
|
// new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
|
||||||
// capsBase + m_mapLayerPath,
|
// capsBase + m_mapLayerPath,
|
||||||
// GetMapLayer);
|
// GetMapLayer);
|
||||||
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
|
IRequestHandler req
|
||||||
|
= new RestStreamHandler(
|
||||||
|
"POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null);
|
||||||
|
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
|
||||||
}
|
}
|
||||||
|
@ -181,14 +186,22 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// I don't think this one works...
|
// I don't think this one works...
|
||||||
m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
|
m_HostCapsObj.RegisterHandler(
|
||||||
|
"NewFileAgentInventory",
|
||||||
|
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
|
||||||
|
"POST",
|
||||||
capsBase + m_newInventory,
|
capsBase + m_newInventory,
|
||||||
NewAgentInventoryRequest));
|
NewAgentInventoryRequest,
|
||||||
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory);
|
"NewFileAgentInventory",
|
||||||
|
null));
|
||||||
|
|
||||||
|
IRequestHandler req
|
||||||
|
= new RestStreamHandler(
|
||||||
|
"POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null);
|
||||||
|
|
||||||
m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
|
m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
|
||||||
m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard));
|
|
||||||
IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData);
|
IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData);
|
||||||
m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
|
m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
|
||||||
IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
|
IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
|
||||||
|
@ -197,6 +210,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
|
m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
m_HostCapsObj.RegisterHandler(
|
||||||
|
"CopyInventoryFromNotecard",
|
||||||
|
new RestStreamHandler(
|
||||||
|
"POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null));
|
||||||
|
|
||||||
// As of RC 1.22.9 of the Linden client this is
|
// As of RC 1.22.9 of the Linden client this is
|
||||||
// supported
|
// supported
|
||||||
|
|
||||||
|
@ -245,7 +264,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
|
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[CAPS]: Unauthorized CAPS client");
|
m_log.DebugFormat(
|
||||||
|
"[CAPS]: Unauthorized CAPS client {0} from {1}",
|
||||||
|
m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +318,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_dumpAssetsToFile);
|
m_dumpAssetsToFile);
|
||||||
uploader.OnUpLoad += TaskScriptUpdated;
|
uploader.OnUpLoad += TaskScriptUpdated;
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
|
new BinaryStreamHandler(
|
||||||
|
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
@ -423,8 +447,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
AssetUploader uploader =
|
AssetUploader uploader =
|
||||||
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
||||||
llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
|
llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
new BinaryStreamHandler(
|
||||||
|
"POST",
|
||||||
|
capsBase + uploaderPath,
|
||||||
|
uploader.uploaderCaps,
|
||||||
|
"NewAgentInventoryRequest",
|
||||||
|
m_HostCapsObj.AgentID.ToString()));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
@ -740,7 +770,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
uploader.OnUpLoad += ItemUpdated;
|
uploader.OnUpLoad += ItemUpdated;
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
new BinaryStreamHandler(
|
||||||
|
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
|
|
@ -106,13 +106,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||||
|
|
||||||
MainConsole.Instance.Commands.AddCommand(
|
MainConsole.Instance.Commands.AddCommand(
|
||||||
"Comms",
|
"Debug",
|
||||||
false,
|
false,
|
||||||
"debug eq",
|
"debug eq",
|
||||||
"debug eq [0|1]",
|
"debug eq [0|1|2]",
|
||||||
"Turn on event queue debugging",
|
"Turn on event queue debugging"
|
||||||
"debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n"
|
+ "<= 0 - turns off all event queue logging"
|
||||||
+ "debug eq 0 will turn off event queue debugging.",
|
+ ">= 1 - turns on outgoing event logging"
|
||||||
|
+ ">= 2 - turns on poll notification",
|
||||||
HandleDebugEq);
|
HandleDebugEq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -235,19 +236,19 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// ClientClosed(client.AgentId);
|
// ClientClosed(client.AgentId);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private void ClientClosed(UUID AgentID, Scene scene)
|
private void ClientClosed(UUID agentID, Scene scene)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5)
|
while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
|
||||||
{
|
{
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (queues)
|
lock (queues)
|
||||||
{
|
{
|
||||||
queues.Remove(AgentID);
|
queues.Remove(agentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<UUID> removeitems = new List<UUID>();
|
List<UUID> removeitems = new List<UUID>();
|
||||||
|
@ -256,7 +257,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
|
foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
|
// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
|
||||||
if (ky == AgentID)
|
if (ky == agentID)
|
||||||
{
|
{
|
||||||
removeitems.Add(ky);
|
removeitems.Add(ky);
|
||||||
}
|
}
|
||||||
|
@ -267,7 +268,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
||||||
m_AvatarQueueUUIDMapping.Remove(ky);
|
m_AvatarQueueUUIDMapping.Remove(ky);
|
||||||
|
|
||||||
MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/");
|
string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
|
||||||
|
MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
|
||||||
|
// eqgPath, agentID, m_scene.RegionInfo.RegionName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +287,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
searchval = m_QueueUUIDAvatarMapping[ky];
|
searchval = m_QueueUUIDAvatarMapping[ky];
|
||||||
|
|
||||||
if (searchval == AgentID)
|
if (searchval == agentID)
|
||||||
{
|
{
|
||||||
removeitems.Add(ky);
|
removeitems.Add(ky);
|
||||||
}
|
}
|
||||||
|
@ -305,6 +311,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate an Event Queue Get handler path for the given eqg uuid.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='eqgUuid'></param>
|
||||||
|
private string GenerateEqgCapPath(UUID eqgUuid)
|
||||||
|
{
|
||||||
|
return string.Format("/CAPS/EQG/{0}/", eqgUuid);
|
||||||
|
}
|
||||||
|
|
||||||
public void OnRegisterCaps(UUID agentID, Caps caps)
|
public void OnRegisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
// Register an event queue for the client
|
// Register an event queue for the client
|
||||||
|
@ -316,8 +331,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// Let's instantiate a Queue for this agent right now
|
// Let's instantiate a Queue for this agent right now
|
||||||
TryGetQueue(agentID);
|
TryGetQueue(agentID);
|
||||||
|
|
||||||
string capsBase = "/CAPS/EQG/";
|
UUID eventQueueGetUUID;
|
||||||
UUID EventQueueGetUUID = UUID.Zero;
|
|
||||||
|
|
||||||
lock (m_AvatarQueueUUIDMapping)
|
lock (m_AvatarQueueUUIDMapping)
|
||||||
{
|
{
|
||||||
|
@ -325,43 +339,49 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
||||||
EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EventQueueGetUUID = UUID.Random();
|
eventQueueGetUUID = UUID.Random();
|
||||||
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_QueueUUIDAvatarMapping)
|
lock (m_QueueUUIDAvatarMapping)
|
||||||
{
|
{
|
||||||
if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID))
|
if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
|
||||||
m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID);
|
m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_AvatarQueueUUIDMapping)
|
lock (m_AvatarQueueUUIDMapping)
|
||||||
{
|
{
|
||||||
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||||
m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID);
|
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
|
||||||
|
|
||||||
// Register this as a caps handler
|
// Register this as a caps handler
|
||||||
// FIXME: Confusingly, we need to register separate as a capability so that the client is told about
|
// FIXME: Confusingly, we need to register separate as a capability so that the client is told about
|
||||||
// EventQueueGet when it receive capability information, but then we replace the rest handler immediately
|
// EventQueueGet when it receive capability information, but then we replace the rest handler immediately
|
||||||
// afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
|
// afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
|
||||||
// really it should be possible to directly register the poll handler as a capability.
|
// really it should be possible to directly register the poll handler as a capability.
|
||||||
caps.RegisterHandler("EventQueueGet",
|
caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null));
|
||||||
new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null));
|
|
||||||
// delegate(Hashtable m_dhttpMethod)
|
// delegate(Hashtable m_dhttpMethod)
|
||||||
// {
|
// {
|
||||||
// return ProcessQueue(m_dhttpMethod, agentID, caps);
|
// return ProcessQueue(m_dhttpMethod, agentID, caps);
|
||||||
// }));
|
// }));
|
||||||
|
|
||||||
// This will persist this beyond the expiry of the caps handlers
|
// This will persist this beyond the expiry of the caps handlers
|
||||||
|
// TODO: Add EventQueueGet name/description for diagnostics
|
||||||
MainServer.Instance.AddPollServiceHTTPHandler(
|
MainServer.Instance.AddPollServiceHTTPHandler(
|
||||||
capsBase + EventQueueGetUUID.ToString() + "/",
|
eventQueueGetPath,
|
||||||
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID,1000)); // 1 sec timeout
|
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 1000));
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
|
||||||
|
// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
Random rnd = new Random(Environment.TickCount);
|
Random rnd = new Random(Environment.TickCount);
|
||||||
lock (m_ids)
|
lock (m_ids)
|
||||||
|
@ -384,9 +404,25 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logs a debug line for an outbound event queue message if appropriate.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='element'>Element containing message</param>
|
||||||
|
private void LogOutboundDebugMessage(OSD element, UUID agentId)
|
||||||
|
{
|
||||||
|
if (element is OSDMap)
|
||||||
|
{
|
||||||
|
OSDMap ev = (OSDMap)element;
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"Eq OUT {0,-30} to {1,-20} {2,-20}",
|
||||||
|
ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
|
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId);
|
if (DebugLevel >= 2)
|
||||||
|
m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
Queue<OSD> queue = TryGetQueue(pAgentId);
|
Queue<OSD> queue = TryGetQueue(pAgentId);
|
||||||
OSD element;
|
OSD element;
|
||||||
|
@ -410,13 +446,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (DebugLevel > 0 && element is OSDMap)
|
if (DebugLevel > 0)
|
||||||
{
|
LogOutboundDebugMessage(element, pAgentId);
|
||||||
OSDMap ev = (OSDMap)element;
|
|
||||||
m_log.DebugFormat(
|
|
||||||
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
|
||||||
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
array.Add(element);
|
array.Add(element);
|
||||||
|
|
||||||
|
@ -426,13 +457,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
element = queue.Dequeue();
|
element = queue.Dequeue();
|
||||||
|
|
||||||
if (DebugLevel > 0 && element is OSDMap)
|
if (DebugLevel > 0)
|
||||||
{
|
LogOutboundDebugMessage(element, pAgentId);
|
||||||
OSDMap ev = (OSDMap)element;
|
|
||||||
m_log.DebugFormat(
|
|
||||||
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
|
||||||
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
array.Add(element);
|
array.Add(element);
|
||||||
thisID++;
|
thisID++;
|
||||||
|
|
|
@ -51,7 +51,16 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp()
|
||||||
{
|
{
|
||||||
MainServer.Instance = new BaseHttpServer(9999, false, 9998, "");
|
uint port = 9999;
|
||||||
|
uint sslPort = 9998;
|
||||||
|
|
||||||
|
// This is an unfortunate bit of clean up we have to do because MainServer manages things through static
|
||||||
|
// variables and the VM is not restarted between tests.
|
||||||
|
MainServer.RemoveHttpServer(port);
|
||||||
|
|
||||||
|
BaseHttpServer server = new BaseHttpServer(port, false, sslPort, "");
|
||||||
|
MainServer.AddHttpServer(server);
|
||||||
|
MainServer.Instance = server;
|
||||||
|
|
||||||
IConfigSource config = new IniConfigSource();
|
IConfigSource config = new IniConfigSource();
|
||||||
config.AddConfig("Startup");
|
config.AddConfig("Startup");
|
||||||
|
@ -60,7 +69,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||||
CapabilitiesModule capsModule = new CapabilitiesModule();
|
CapabilitiesModule capsModule = new CapabilitiesModule();
|
||||||
EventQueueGetModule eqgModule = new EventQueueGetModule();
|
EventQueueGetModule eqgModule = new EventQueueGetModule();
|
||||||
|
|
||||||
m_scene = SceneHelpers.SetupScene();
|
m_scene = new SceneHelpers().SetupScene();
|
||||||
SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule);
|
SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
capUrl = "/CAPS/" + UUID.Random();
|
capUrl = "/CAPS/" + UUID.Random();
|
||||||
|
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestStreamHandler("POST", capUrl, m_fetchHandler.FetchInventoryRequest);
|
= new RestStreamHandler(
|
||||||
|
"POST", capUrl, m_fetchHandler.FetchInventoryRequest, capName, agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler(capName, reqHandler);
|
caps.RegisterHandler(capName, reqHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,11 +120,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
||||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
|
IRequestHandler reqHandler
|
||||||
delegate(Hashtable m_dhttpMethod)
|
= new RestHTTPHandler(
|
||||||
{
|
"GET",
|
||||||
return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null);
|
"/CAPS/" + UUID.Random(),
|
||||||
});
|
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
||||||
|
"GetMesh",
|
||||||
|
agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler("GetMesh", reqHandler);
|
caps.RegisterHandler("GetMesh", reqHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
if (m_URL == "localhost")
|
if (m_URL == "localhost")
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||||
caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService));
|
caps.RegisterHandler(
|
||||||
|
"GetTexture",
|
||||||
|
new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -117,7 +117,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
public void RegisterCaps(UUID agentID, Caps caps)
|
public void RegisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag);
|
IRequestHandler reqHandler
|
||||||
|
= new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag, "MeshUploadFlag", agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler("MeshUploadFlag", reqHandler);
|
caps.RegisterHandler("MeshUploadFlag", reqHandler);
|
||||||
m_agentID = agentID;
|
m_agentID = agentID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,31 +115,29 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
UUID capID = UUID.Random();
|
UUID capID = UUID.Random();
|
||||||
|
|
||||||
// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
|
// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
|
||||||
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
caps.RegisterHandler(
|
||||||
|
"NewFileAgentInventoryVariablePrice",
|
||||||
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
|
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
|
||||||
|
"POST",
|
||||||
"/CAPS/" + capID.ToString(),
|
"/CAPS/" + capID.ToString(),
|
||||||
delegate(LLSDAssetUploadRequest req)
|
req => NewAgentInventoryRequest(req, agentID),
|
||||||
{
|
"NewFileAgentInventoryVariablePrice",
|
||||||
return NewAgentInventoryRequest(req,agentID);
|
agentID.ToString()));
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
|
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
|
//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 and
|
// you need to be aware of this
|
||||||
|
|
||||||
|
|
||||||
//if (llsdRequest.asset_type == "texture" ||
|
//if (llsdRequest.asset_type == "texture" ||
|
||||||
// llsdRequest.asset_type == "animation" ||
|
// llsdRequest.asset_type == "animation" ||
|
||||||
// llsdRequest.asset_type == "sound")
|
// llsdRequest.asset_type == "sound")
|
||||||
// {
|
// {
|
||||||
// check user level
|
// check user level
|
||||||
|
|
||||||
ScenePresence avatar = null;
|
ScenePresence avatar = null;
|
||||||
IClientAPI client = null;
|
IClientAPI client = null;
|
||||||
m_scene.TryGetScenePresence(agentID, out avatar);
|
m_scene.TryGetScenePresence(agentID, out avatar);
|
||||||
|
@ -176,6 +174,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
return errorResponse;
|
return errorResponse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
string assetName = llsdRequest.name;
|
string assetName = llsdRequest.name;
|
||||||
|
@ -189,8 +188,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
AssetUploader uploader =
|
AssetUploader uploader =
|
||||||
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
||||||
llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
|
llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
|
||||||
|
|
||||||
MainServer.Instance.AddStreamHandler(
|
MainServer.Instance.AddStreamHandler(
|
||||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
new BinaryStreamHandler(
|
||||||
|
"POST",
|
||||||
|
capsBase + uploaderPath,
|
||||||
|
uploader.uploaderCaps,
|
||||||
|
"NewFileAgentInventoryVariablePrice",
|
||||||
|
agentID.ToString()));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
@ -203,7 +208,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||||
|
|
||||||
|
|
||||||
uploadResponse.rsvp = uploaderURL;
|
uploadResponse.rsvp = uploaderURL;
|
||||||
uploadResponse.state = "upload";
|
uploadResponse.state = "upload";
|
||||||
uploadResponse.resource_cost = 0;
|
uploadResponse.resource_cost = 0;
|
||||||
|
@ -220,6 +224,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
pinventoryItem, pparentFolder, pdata, pinventoryType,
|
pinventoryItem, pparentFolder, pdata, pinventoryType,
|
||||||
passetType,agentID);
|
passetType,agentID);
|
||||||
};
|
};
|
||||||
|
|
||||||
return uploadResponse;
|
return uploadResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,12 +66,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
|
// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
|
||||||
|
|
||||||
caps.RegisterHandler("ObjectAdd",
|
caps.RegisterHandler(
|
||||||
new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/",
|
"ObjectAdd",
|
||||||
delegate(Hashtable m_dhttpMethod)
|
new RestHTTPHandler(
|
||||||
{
|
"POST",
|
||||||
return ProcessAdd(m_dhttpMethod, agentID, caps);
|
"/CAPS/OA/" + capuuid + "/",
|
||||||
}));
|
httpMethod => ProcessAdd(httpMethod, agentID, caps),
|
||||||
|
"ObjectAdd",
|
||||||
|
agentID.ToString()));;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
|
public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
|
||||||
|
|
|
@ -106,12 +106,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
UUID capID = UUID.Random();
|
UUID capID = UUID.Random();
|
||||||
|
|
||||||
// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
|
// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
|
||||||
caps.RegisterHandler("UploadObjectAsset",
|
caps.RegisterHandler(
|
||||||
new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/",
|
"UploadObjectAsset",
|
||||||
delegate(Hashtable m_dhttpMethod)
|
new RestHTTPHandler(
|
||||||
{
|
"POST",
|
||||||
return ProcessAdd(m_dhttpMethod, agentID, caps);
|
"/CAPS/OA/" + capID + "/",
|
||||||
}));
|
httpMethod => ProcessAdd(httpMethod, agentID, caps),
|
||||||
|
"UploadObjectAsset",
|
||||||
|
agentID.ToString()));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
||||||
|
|
||||||
|
@ -330,7 +333,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
grp.AbsolutePosition = obj.Position;
|
grp.AbsolutePosition = obj.Position;
|
||||||
prim.RotationOffset = obj.Rotation;
|
prim.RotationOffset = obj.Rotation;
|
||||||
|
|
||||||
grp.IsAttachment = false;
|
|
||||||
// Required for linking
|
// Required for linking
|
||||||
grp.RootPart.ClearUpdateSchedule();
|
grp.RootPart.ClearUpdateSchedule();
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
public void RegisterCaps(UUID agentID, Caps caps)
|
public void RegisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest);
|
= new RestHTTPHandler(
|
||||||
|
"GET", "/CAPS/" + UUID.Random(),
|
||||||
|
HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler("SimulatorFeatures", reqHandler);
|
caps.RegisterHandler("SimulatorFeatures", reqHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
"POST",
|
"POST",
|
||||||
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
||||||
new UploadBakedTextureHandler(
|
new UploadBakedTextureHandler(
|
||||||
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture));
|
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture,
|
||||||
|
"UploadBakedTexture",
|
||||||
|
agentID.ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -144,7 +144,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
capUrl = "/CAPS/" + UUID.Random();
|
capUrl = "/CAPS/" + UUID.Random();
|
||||||
|
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestStreamHandler("POST", capUrl, m_webFetchHandler.FetchInventoryDescendentsRequest);
|
= new RestStreamHandler(
|
||||||
|
"POST",
|
||||||
|
capUrl,
|
||||||
|
m_webFetchHandler.FetchInventoryDescendentsRequest,
|
||||||
|
"FetchInventoryDescendents2",
|
||||||
|
agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler(capName, reqHandler);
|
caps.RegisterHandler(capName, reqHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public sealed class IncomingPacket
|
public sealed class IncomingPacket
|
||||||
{
|
{
|
||||||
/// <summary>Client this packet came from</summary>
|
/// <summary>Client this packet came from</summary>
|
||||||
public LLUDPClient Client;
|
public LLClientView Client;
|
||||||
|
|
||||||
/// <summary>Packet data that has been received</summary>
|
/// <summary>Packet data that has been received</summary>
|
||||||
public Packet Packet;
|
public Packet Packet;
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="client">Reference to the client this packet came from</param>
|
/// <param name="client">Reference to the client this packet came from</param>
|
||||||
/// <param name="packet">Packet data</param>
|
/// <param name="packet">Packet data</param>
|
||||||
public IncomingPacket(LLUDPClient client, Packet packet)
|
public IncomingPacket(LLClientView client, Packet packet)
|
||||||
{
|
{
|
||||||
Client = client;
|
Client = client;
|
||||||
Packet = packet;
|
Packet = packet;
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// Handles new client connections
|
/// Handles new client connections
|
||||||
/// Constructor takes a single Packet and authenticates everything
|
/// Constructor takes a single Packet and authenticates everything
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IClientIPEndpoint, IStatsCollector
|
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector
|
||||||
{
|
{
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
|
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
|
||||||
|
@ -365,7 +365,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
protected string m_lastName;
|
protected string m_lastName;
|
||||||
protected Thread m_clientThread;
|
protected Thread m_clientThread;
|
||||||
protected Vector3 m_startpos;
|
protected Vector3 m_startpos;
|
||||||
protected EndPoint m_userEndPoint;
|
|
||||||
protected UUID m_activeGroupID;
|
protected UUID m_activeGroupID;
|
||||||
protected string m_activeGroupName = String.Empty;
|
protected string m_activeGroupName = String.Empty;
|
||||||
protected ulong m_activeGroupPowers;
|
protected ulong m_activeGroupPowers;
|
||||||
|
@ -458,7 +457,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
|
public LLClientView(Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
|
||||||
UUID agentId, UUID sessionId, uint circuitCode)
|
UUID agentId, UUID sessionId, uint circuitCode)
|
||||||
{
|
{
|
||||||
// DebugPacketLevel = 1;
|
// DebugPacketLevel = 1;
|
||||||
|
@ -466,7 +465,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
RegisterInterface<IClientIM>(this);
|
RegisterInterface<IClientIM>(this);
|
||||||
RegisterInterface<IClientInventory>(this);
|
RegisterInterface<IClientInventory>(this);
|
||||||
RegisterInterface<IClientChat>(this);
|
RegisterInterface<IClientChat>(this);
|
||||||
RegisterInterface<IClientIPEndpoint>(this);
|
|
||||||
|
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
|
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
|
||||||
|
@ -483,7 +481,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_sessionId = sessionId;
|
m_sessionId = sessionId;
|
||||||
m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
|
m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
|
||||||
m_circuitCode = circuitCode;
|
m_circuitCode = circuitCode;
|
||||||
m_userEndPoint = remoteEP;
|
|
||||||
m_firstName = sessionInfo.LoginInfo.First;
|
m_firstName = sessionInfo.LoginInfo.First;
|
||||||
m_lastName = sessionInfo.LoginInfo.Last;
|
m_lastName = sessionInfo.LoginInfo.Last;
|
||||||
m_startpos = sessionInfo.LoginInfo.StartPos;
|
m_startpos = sessionInfo.LoginInfo.StartPos;
|
||||||
|
@ -515,6 +512,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Close(bool sendStop)
|
public void Close(bool sendStop)
|
||||||
{
|
{
|
||||||
|
IsActive = false;
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[CLIENT]: Close has been called for {0} attached to scene {1}",
|
"[CLIENT]: Close has been called for {0} attached to scene {1}",
|
||||||
Name, m_scene.RegionInfo.RegionName);
|
Name, m_scene.RegionInfo.RegionName);
|
||||||
|
@ -11866,7 +11865,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect))
|
if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect))
|
||||||
logPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (DebugPacketLevel <= 50 && packet.Type == PacketType.ImprovedTerseObjectUpdate)
|
if (DebugPacketLevel <= 50
|
||||||
|
& (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
|
||||||
logPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
|
if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
|
||||||
|
@ -11979,7 +11979,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
ClientInfo info = m_udpClient.GetClientInfo();
|
ClientInfo info = m_udpClient.GetClientInfo();
|
||||||
|
|
||||||
info.userEP = m_userEndPoint;
|
|
||||||
info.proxyEP = null;
|
info.proxyEP = null;
|
||||||
info.agentcircuit = RequestClientInfo();
|
info.agentcircuit = RequestClientInfo();
|
||||||
|
|
||||||
|
@ -11991,11 +11990,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_udpClient.SetClientInfo(info);
|
m_udpClient.SetClientInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EndPoint GetClientEP()
|
|
||||||
{
|
|
||||||
return m_userEndPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Media Parcel Members
|
#region Media Parcel Members
|
||||||
|
|
||||||
public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
|
public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
|
||||||
|
@ -12076,10 +12070,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void KillEndDone()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IClientCore
|
#region IClientCore
|
||||||
|
|
||||||
private readonly Dictionary<Type, object> m_clientInterfaces = new Dictionary<Type, object>();
|
private readonly Dictionary<Type, object> m_clientInterfaces = new Dictionary<Type, object>();
|
||||||
|
@ -12167,21 +12157,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID)
|
protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID)
|
||||||
{
|
{
|
||||||
UUID requestID = UUID.Zero;
|
UUID requestID = UUID.Zero;
|
||||||
if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
|
int sourceType = transferRequest.TransferInfo.SourceType;
|
||||||
|
|
||||||
|
if (sourceType == (int)SourceType.Asset)
|
||||||
{
|
{
|
||||||
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
|
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
|
||||||
}
|
}
|
||||||
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
|
else if (sourceType == (int)SourceType.SimInventoryItem)
|
||||||
{
|
{
|
||||||
requestID = new UUID(transferRequest.TransferInfo.Params, 80);
|
requestID = new UUID(transferRequest.TransferInfo.Params, 80);
|
||||||
}
|
}
|
||||||
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate)
|
else if (sourceType == (int)SourceType.SimEstate)
|
||||||
{
|
{
|
||||||
requestID = taskID;
|
requestID = taskID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
|
// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
|
||||||
|
// requestID, taskID, (SourceType)sourceType, Name);
|
||||||
|
|
||||||
|
|
||||||
//Note, the bool returned from the below function is useless since it is always false.
|
//Note, the bool returned from the below function is useless since it is always false.
|
||||||
|
@ -12270,24 +12263,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return numPackets;
|
return numPackets;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IClientIPEndpoint Members
|
|
||||||
|
|
||||||
public IPAddress EndPoint
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (m_userEndPoint is IPEndPoint)
|
|
||||||
{
|
|
||||||
IPEndPoint ep = (IPEndPoint)m_userEndPoint;
|
|
||||||
|
|
||||||
return ep.Address;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public void SendRebakeAvatarTextures(UUID textureID)
|
public void SendRebakeAvatarTextures(UUID textureID)
|
||||||
{
|
{
|
||||||
RebakeAvatarTexturesPacket pack =
|
RebakeAvatarTexturesPacket pack =
|
||||||
|
|
|
@ -147,23 +147,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private int m_elapsed500MSOutgoingPacketHandler;
|
private int m_elapsed500MSOutgoingPacketHandler;
|
||||||
|
|
||||||
/// <summary>Flag to signal when clients should check for resends</summary>
|
/// <summary>Flag to signal when clients should check for resends</summary>
|
||||||
private bool m_resendUnacked;
|
protected bool m_resendUnacked;
|
||||||
|
|
||||||
/// <summary>Flag to signal when clients should send ACKs</summary>
|
/// <summary>Flag to signal when clients should send ACKs</summary>
|
||||||
private bool m_sendAcks;
|
protected bool m_sendAcks;
|
||||||
|
|
||||||
/// <summary>Flag to signal when clients should send pings</summary>
|
/// <summary>Flag to signal when clients should send pings</summary>
|
||||||
private bool m_sendPing;
|
protected bool m_sendPing;
|
||||||
|
|
||||||
private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
|
private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
|
||||||
|
|
||||||
private int m_defaultRTO = 0;
|
private int m_defaultRTO = 0;
|
||||||
private int m_maxRTO = 0;
|
private int m_maxRTO = 0;
|
||||||
|
private int m_ackTimeout = 0;
|
||||||
|
private int m_pausedAckTimeout = 0;
|
||||||
private bool m_disableFacelights = false;
|
private bool m_disableFacelights = false;
|
||||||
|
|
||||||
public Socket Server { get { return null; } }
|
public Socket Server { get { return null; } }
|
||||||
|
|
||||||
private int m_malformedCount = 0; // Guard against a spamming attack
|
private int m_malformedCount = 0; // Guard against a spamming attack
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Record current outgoing client for monitoring purposes.
|
||||||
|
/// </summary>
|
||||||
|
private IClientAPI m_currentOutgoingClient;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Recording current incoming client for monitoring purposes.
|
||||||
|
/// </summary>
|
||||||
|
private IClientAPI m_currentIncomingClient;
|
||||||
|
|
||||||
public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
|
public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
|
||||||
: base(listenIP, (int)port)
|
: base(listenIP, (int)port)
|
||||||
{
|
{
|
||||||
|
@ -200,11 +213,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_defaultRTO = config.GetInt("DefaultRTO", 0);
|
m_defaultRTO = config.GetInt("DefaultRTO", 0);
|
||||||
m_maxRTO = config.GetInt("MaxRTO", 0);
|
m_maxRTO = config.GetInt("MaxRTO", 0);
|
||||||
m_disableFacelights = config.GetBoolean("DisableFacelights", false);
|
m_disableFacelights = config.GetBoolean("DisableFacelights", false);
|
||||||
|
m_ackTimeout = 1000 * config.GetInt("AckTimeout", 60);
|
||||||
|
m_pausedAckTimeout = 1000 * config.GetInt("PausedAckTimeout", 300);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrimUpdatesPerCallback = 100;
|
PrimUpdatesPerCallback = 100;
|
||||||
TextureSendLimit = 20;
|
TextureSendLimit = 20;
|
||||||
|
m_ackTimeout = 1000 * 60; // 1 minute
|
||||||
|
m_pausedAckTimeout = 1000 * 300; // 5 minutes
|
||||||
}
|
}
|
||||||
|
|
||||||
#region BinaryStats
|
#region BinaryStats
|
||||||
|
@ -241,19 +258,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (m_scene == null)
|
if (m_scene == null)
|
||||||
throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
|
throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
|
||||||
|
|
||||||
m_log.Info("[LLUDPSERVER]: Starting the LLUDP server in " + (m_asyncPacketHandling ? "asynchronous" : "synchronous") + " mode");
|
m_log.InfoFormat(
|
||||||
|
"[LLUDPSERVER]: Starting the LLUDP server in {0} mode",
|
||||||
|
m_asyncPacketHandling ? "asynchronous" : "synchronous");
|
||||||
|
|
||||||
base.Start(m_recvBufferSize, m_asyncPacketHandling);
|
base.Start(m_recvBufferSize, m_asyncPacketHandling);
|
||||||
|
|
||||||
// Start the packet processing threads
|
// Start the packet processing threads
|
||||||
Watchdog.StartThread(
|
Watchdog.StartThread(
|
||||||
IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
|
IncomingPacketHandler,
|
||||||
|
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
|
||||||
|
ThreadPriority.Normal,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
GetWatchdogIncomingAlarmData,
|
||||||
|
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||||
|
|
||||||
Watchdog.StartThread(
|
Watchdog.StartThread(
|
||||||
OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
|
OutgoingPacketHandler,
|
||||||
|
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
|
||||||
|
ThreadPriority.Normal,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
GetWatchdogOutgoingAlarmData,
|
||||||
|
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||||
|
|
||||||
m_elapsedMSSinceLastStatReport = Environment.TickCount;
|
m_elapsedMSSinceLastStatReport = Environment.TickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string GetWatchdogIncomingAlarmData()
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
"Client is {0}",
|
||||||
|
m_currentIncomingClient != null ? m_currentIncomingClient.Name : "none");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string GetWatchdogOutgoingAlarmData()
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
"Client is {0}",
|
||||||
|
m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none");
|
||||||
|
}
|
||||||
|
|
||||||
public new void Stop()
|
public new void Stop()
|
||||||
{
|
{
|
||||||
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
|
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
|
||||||
|
@ -487,19 +541,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
|
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleUnacked(LLUDPClient udpClient)
|
public void HandleUnacked(LLClientView client)
|
||||||
{
|
{
|
||||||
|
LLUDPClient udpClient = client.UDPClient;
|
||||||
|
|
||||||
if (!udpClient.IsConnected)
|
if (!udpClient.IsConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Disconnect an agent if no packets are received for some time
|
// Disconnect an agent if no packets are received for some time
|
||||||
//FIXME: Make 60 an .ini setting
|
int timeoutTicks = m_ackTimeout;
|
||||||
if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
|
|
||||||
{
|
// Allow more slack if the client is "paused" eg file upload dialogue is open
|
||||||
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
|
// Some sort of limit is needed in case the client crashes, loses its network connection
|
||||||
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
// or some other disaster prevents it from sendung the AgentResume
|
||||||
|
if (udpClient.IsPaused)
|
||||||
|
timeoutTicks = m_pausedAckTimeout;
|
||||||
|
|
||||||
|
if (client.IsActive &&
|
||||||
|
(Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
|
||||||
|
{
|
||||||
|
// We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
|
||||||
|
// though it's set later on by LLClientView.Close()
|
||||||
|
client.IsActive = false;
|
||||||
|
|
||||||
|
// Fire this out on a different thread so that we don't hold up outgoing packet processing for
|
||||||
|
// everybody else if this is being called due to an ack timeout.
|
||||||
|
// This is the same as processing as the async process of a logout request.
|
||||||
|
Util.FireAndForget(o => DeactivateClientDueToTimeout(client));
|
||||||
|
|
||||||
RemoveClient(udpClient);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +919,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
#endregion Ping Check Handling
|
#endregion Ping Check Handling
|
||||||
|
|
||||||
// Inbox insertion
|
// Inbox insertion
|
||||||
packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
|
packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region BinaryStats
|
#region BinaryStats
|
||||||
|
@ -946,7 +1015,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
||||||
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
|
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
|
||||||
|
|
||||||
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
|
m_log.DebugFormat(
|
||||||
|
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
|
||||||
|
uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint);
|
||||||
|
|
||||||
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||||
|
|
||||||
|
@ -1001,8 +1072,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
// Don't create clients for unauthorized requesters.
|
// Don't create clients for unauthorized requesters.
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
"[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
|
||||||
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
|
uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint);
|
||||||
lock (m_pendingCache)
|
lock (m_pendingCache)
|
||||||
m_pendingCache.Remove(remoteEndPoint);
|
m_pendingCache.Remove(remoteEndPoint);
|
||||||
}
|
}
|
||||||
|
@ -1090,7 +1161,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
||||||
|
|
||||||
client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||||
client.OnLogout += LogoutHandler;
|
client.OnLogout += LogoutHandler;
|
||||||
|
|
||||||
((LLClientView)client).DisableFacelights = m_disableFacelights;
|
((LLClientView)client).DisableFacelights = m_disableFacelights;
|
||||||
|
@ -1102,15 +1173,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveClient(LLUDPClient udpClient)
|
/// <summary>
|
||||||
|
/// Deactivates the client if we don't receive any packets within a certain amount of time (default 60 seconds).
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If a connection is active then we will always receive packets even if nothing else is happening, due to
|
||||||
|
/// regular client pings.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name='client'></param>
|
||||||
|
private void DeactivateClientDueToTimeout(IClientAPI client)
|
||||||
{
|
{
|
||||||
// Remove this client from the scene
|
// We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
|
||||||
IClientAPI client;
|
// though it's set later on by LLClientView.Close()
|
||||||
if (m_scene.TryGetClient(udpClient.AgentID, out client))
|
client.IsActive = false;
|
||||||
{
|
|
||||||
client.IsLoggingOut = true;
|
m_log.WarnFormat(
|
||||||
client.Close(false);
|
"[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}",
|
||||||
}
|
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
||||||
|
|
||||||
|
if (!client.SceneAgent.IsChildAgent)
|
||||||
|
client.Kick("Simulator logged you out due to connection timeout");
|
||||||
|
|
||||||
|
Util.FireAndForget(o => client.Close());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IncomingPacketHandler()
|
private void IncomingPacketHandler()
|
||||||
|
@ -1219,6 +1305,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// client. m_packetSent will be set to true if a packet is sent
|
// client. m_packetSent will be set to true if a packet is sent
|
||||||
m_scene.ForEachClient(clientPacketHandler);
|
m_scene.ForEachClient(clientPacketHandler);
|
||||||
|
|
||||||
|
m_currentOutgoingClient = null;
|
||||||
|
|
||||||
// If nothing was sent, sleep for the minimum amount of time before a
|
// If nothing was sent, sleep for the minimum amount of time before a
|
||||||
// token bucket could get more tokens
|
// token bucket could get more tokens
|
||||||
if (!m_packetSent)
|
if (!m_packetSent)
|
||||||
|
@ -1235,18 +1323,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
Watchdog.RemoveThread();
|
Watchdog.RemoveThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClientOutgoingPacketHandler(IClientAPI client)
|
protected void ClientOutgoingPacketHandler(IClientAPI client)
|
||||||
{
|
{
|
||||||
|
m_currentOutgoingClient = client;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (client is LLClientView)
|
if (client is LLClientView)
|
||||||
{
|
{
|
||||||
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
|
LLClientView llClient = (LLClientView)client;
|
||||||
|
LLUDPClient udpClient = llClient.UDPClient;
|
||||||
|
|
||||||
if (udpClient.IsConnected)
|
if (udpClient.IsConnected)
|
||||||
{
|
{
|
||||||
if (m_resendUnacked)
|
if (m_resendUnacked)
|
||||||
HandleUnacked(udpClient);
|
HandleUnacked(llClient);
|
||||||
|
|
||||||
if (m_sendAcks)
|
if (m_sendAcks)
|
||||||
SendAcks(udpClient);
|
SendAcks(udpClient);
|
||||||
|
@ -1262,8 +1353,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
|
m_log.Error(
|
||||||
" threw an exception: " + ex.Message, ex);
|
string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,11 +1380,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
nticks++;
|
nticks++;
|
||||||
watch1.Start();
|
watch1.Start();
|
||||||
|
m_currentOutgoingClient = client;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (client is LLClientView)
|
if (client is LLClientView)
|
||||||
{
|
{
|
||||||
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
|
LLClientView llClient = (LLClientView)client;
|
||||||
|
LLUDPClient udpClient = llClient.UDPClient;
|
||||||
|
|
||||||
if (udpClient.IsConnected)
|
if (udpClient.IsConnected)
|
||||||
{
|
{
|
||||||
|
@ -1302,7 +1396,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
nticksUnack++;
|
nticksUnack++;
|
||||||
watch2.Start();
|
watch2.Start();
|
||||||
|
|
||||||
HandleUnacked(udpClient);
|
HandleUnacked(llClient);
|
||||||
|
|
||||||
watch2.Stop();
|
watch2.Stop();
|
||||||
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
|
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
|
||||||
|
@ -1373,23 +1467,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void ProcessInPacket(object state)
|
private void ProcessInPacket(IncomingPacket incomingPacket)
|
||||||
{
|
{
|
||||||
IncomingPacket incomingPacket = (IncomingPacket)state;
|
|
||||||
Packet packet = incomingPacket.Packet;
|
Packet packet = incomingPacket.Packet;
|
||||||
LLUDPClient udpClient = incomingPacket.Client;
|
LLClientView client = incomingPacket.Client;
|
||||||
IClientAPI client;
|
|
||||||
|
|
||||||
// Sanity check
|
if (client.IsActive)
|
||||||
if (packet == null || udpClient == null)
|
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", UDPClient=\"{1}\"",
|
m_currentIncomingClient = client;
|
||||||
packet, udpClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure this client is still alive
|
|
||||||
if (m_scene.TryGetClient(udpClient.AgentID, out client))
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Process this packet
|
// Process this packet
|
||||||
|
@ -1404,21 +1490,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// Don't let a failure in an individual client thread crash the whole sim.
|
// Don't let a failure in an individual client thread crash the whole sim.
|
||||||
m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type);
|
m_log.Error(
|
||||||
m_log.Error(e.Message, e);
|
string.Format(
|
||||||
|
"[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw ",
|
||||||
|
client.Name, packet.Type),
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
m_currentIncomingClient = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[LLUDPSERVER]: Dropping incoming {0} packet for dead client {1}", packet.Type, udpClient.AgentID);
|
m_log.DebugFormat(
|
||||||
|
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
|
||||||
|
packet.Type, client.Name, m_scene.RegionInfo.RegionName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void LogoutHandler(IClientAPI client)
|
protected void LogoutHandler(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.SendLogoutPacket();
|
client.SendLogoutPacket();
|
||||||
if (client.IsActive)
|
|
||||||
RemoveClient(((LLClientView)client).UDPClient);
|
if (!client.IsLoggingOut)
|
||||||
|
{
|
||||||
|
client.IsLoggingOut = true;
|
||||||
|
client.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class BasicCircuitTests
|
public class BasicCircuitTests
|
||||||
{
|
{
|
||||||
|
private Scene m_scene;
|
||||||
|
private TestLLUDPServer m_udpServer;
|
||||||
|
|
||||||
[TestFixtureSetUp]
|
[TestFixtureSetUp]
|
||||||
public void FixtureInit()
|
public void FixtureInit()
|
||||||
{
|
{
|
||||||
|
@ -61,83 +64,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// <summary>
|
[SetUp]
|
||||||
// /// Add a client for testing
|
public void SetUp()
|
||||||
// /// </summary>
|
{
|
||||||
// /// <param name="scene"></param>
|
m_scene = new SceneHelpers().SetupScene();
|
||||||
// /// <param name="testLLUDPServer"></param>
|
}
|
||||||
// /// <param name="testPacketServer"></param>
|
|
||||||
// /// <param name="acm">Agent circuit manager used in setting up the stack</param>
|
|
||||||
// protected void SetupStack(
|
|
||||||
// IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer,
|
|
||||||
// out AgentCircuitManager acm)
|
|
||||||
// {
|
|
||||||
// IConfigSource configSource = new IniConfigSource();
|
|
||||||
// ClientStackUserSettings userSettings = new ClientStackUserSettings();
|
|
||||||
// testLLUDPServer = new TestLLUDPServer();
|
|
||||||
// acm = new AgentCircuitManager();
|
|
||||||
//
|
|
||||||
// uint port = 666;
|
|
||||||
// testLLUDPServer.Initialise(null, ref port, 0, false, configSource, acm);
|
|
||||||
// testPacketServer = new TestLLPacketServer(testLLUDPServer, userSettings);
|
|
||||||
// testLLUDPServer.LocalScene = scene;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// <summary>
|
|
||||||
// /// Set up a client for tests which aren't concerned with this process itself and where only one client is being
|
|
||||||
// /// tested
|
|
||||||
// /// </summary>
|
|
||||||
// /// <param name="circuitCode"></param>
|
|
||||||
// /// <param name="epSender"></param>
|
|
||||||
// /// <param name="testLLUDPServer"></param>
|
|
||||||
// /// <param name="acm"></param>
|
|
||||||
// protected void AddClient(
|
|
||||||
// uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
|
||||||
// {
|
|
||||||
// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
|
|
||||||
// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
|
|
||||||
//
|
|
||||||
// AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// <summary>
|
|
||||||
// /// Set up a client for tests which aren't concerned with this process itself
|
|
||||||
// /// </summary>
|
|
||||||
// /// <param name="circuitCode"></param>
|
|
||||||
// /// <param name="epSender"></param>
|
|
||||||
// /// <param name="agentId"></param>
|
|
||||||
// /// <param name="sessionId"></param>
|
|
||||||
// /// <param name="testLLUDPServer"></param>
|
|
||||||
// /// <param name="acm"></param>
|
|
||||||
// protected void AddClient(
|
|
||||||
// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
|
|
||||||
// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
|
||||||
// {
|
|
||||||
// AgentCircuitData acd = new AgentCircuitData();
|
|
||||||
// acd.AgentID = agentId;
|
|
||||||
// acd.SessionID = sessionId;
|
|
||||||
//
|
|
||||||
// UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
|
||||||
//
|
|
||||||
// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
|
||||||
// = new UseCircuitCodePacket.CircuitCodeBlock();
|
|
||||||
// uccpCcBlock.Code = circuitCode;
|
|
||||||
// uccpCcBlock.ID = agentId;
|
|
||||||
// uccpCcBlock.SessionID = sessionId;
|
|
||||||
// uccp.CircuitCode = uccpCcBlock;
|
|
||||||
//
|
|
||||||
// acm.AddNewCircuit(circuitCode, acd);
|
|
||||||
//
|
|
||||||
// testLLUDPServer.LoadReceive(uccp, epSender);
|
|
||||||
// testLLUDPServer.ReceiveData(null);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Build an object name packet for test purposes
|
/// Build an object name packet for test purposes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="objectLocalId"></param>
|
/// <param name="objectLocalId"></param>
|
||||||
/// <param name="objectName"></param>
|
/// <param name="objectName"></param>
|
||||||
protected ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
|
private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
|
||||||
{
|
{
|
||||||
ObjectNamePacket onp = new ObjectNamePacket();
|
ObjectNamePacket onp = new ObjectNamePacket();
|
||||||
ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
|
ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
|
||||||
|
@ -149,28 +87,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
return onp;
|
return onp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void AddUdpServer()
|
||||||
/// Test adding a client to the stack
|
|
||||||
/// </summary>
|
|
||||||
[Test]
|
|
||||||
public void TestAddClient()
|
|
||||||
{
|
{
|
||||||
TestHelpers.InMethod();
|
AddUdpServer(new IniConfigSource());
|
||||||
// XmlConfigurator.Configure();
|
}
|
||||||
|
|
||||||
TestScene scene = SceneHelpers.SetupScene();
|
private void AddUdpServer(IniConfigSource configSource)
|
||||||
uint myCircuitCode = 123456;
|
{
|
||||||
|
uint port = 0;
|
||||||
|
AgentCircuitManager acm = m_scene.AuthenticateHandler;
|
||||||
|
|
||||||
|
m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm);
|
||||||
|
m_udpServer.AddScene(m_scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used by tests that aren't testing this stage.
|
||||||
|
/// </summary>
|
||||||
|
private ScenePresence AddClient()
|
||||||
|
{
|
||||||
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||||
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||||
|
uint myCircuitCode = 123456;
|
||||||
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||||
|
|
||||||
uint port = 0;
|
|
||||||
AgentCircuitManager acm = scene.AuthenticateHandler;
|
|
||||||
|
|
||||||
TestLLUDPServer llUdpServer
|
|
||||||
= new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm);
|
|
||||||
llUdpServer.AddScene(scene);
|
|
||||||
|
|
||||||
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||||
|
|
||||||
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||||
|
@ -185,26 +125,67 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
||||||
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
||||||
|
|
||||||
llUdpServer.PacketReceived(upb);
|
AgentCircuitData acd = new AgentCircuitData();
|
||||||
|
acd.AgentID = myAgentUuid;
|
||||||
|
acd.SessionID = mySessionUuid;
|
||||||
|
|
||||||
|
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
|
||||||
|
|
||||||
|
m_udpServer.PacketReceived(upb);
|
||||||
|
|
||||||
|
return m_scene.GetScenePresence(myAgentUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test adding a client to the stack
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestAddClient()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
AddUdpServer();
|
||||||
|
|
||||||
|
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||||
|
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||||
|
uint myCircuitCode = 123456;
|
||||||
|
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||||
|
|
||||||
|
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||||
|
|
||||||
|
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||||
|
= new UseCircuitCodePacket.CircuitCodeBlock();
|
||||||
|
uccpCcBlock.Code = myCircuitCode;
|
||||||
|
uccpCcBlock.ID = myAgentUuid;
|
||||||
|
uccpCcBlock.SessionID = mySessionUuid;
|
||||||
|
uccp.CircuitCode = uccpCcBlock;
|
||||||
|
|
||||||
|
byte[] uccpBytes = uccp.ToBytes();
|
||||||
|
UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
|
||||||
|
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
||||||
|
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
||||||
|
|
||||||
|
m_udpServer.PacketReceived(upb);
|
||||||
|
|
||||||
// Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
|
// Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
|
||||||
Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null);
|
Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);
|
||||||
|
|
||||||
AgentCircuitData acd = new AgentCircuitData();
|
AgentCircuitData acd = new AgentCircuitData();
|
||||||
acd.AgentID = myAgentUuid;
|
acd.AgentID = myAgentUuid;
|
||||||
acd.SessionID = mySessionUuid;
|
acd.SessionID = mySessionUuid;
|
||||||
|
|
||||||
acm.AddNewCircuit(myCircuitCode, acd);
|
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
|
||||||
|
|
||||||
llUdpServer.PacketReceived(upb);
|
m_udpServer.PacketReceived(upb);
|
||||||
|
|
||||||
// Should succeed now
|
// Should succeed now
|
||||||
ScenePresence sp = scene.GetScenePresence(myAgentUuid);
|
ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);
|
||||||
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
|
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
|
||||||
|
|
||||||
Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1));
|
Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1));
|
||||||
|
|
||||||
Packet packet = llUdpServer.PacketsSent[0];
|
Packet packet = m_udpServer.PacketsSent[0];
|
||||||
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
|
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
|
||||||
|
|
||||||
PacketAckPacket ackPacket = packet as PacketAckPacket;
|
PacketAckPacket ackPacket = packet as PacketAckPacket;
|
||||||
|
@ -212,6 +193,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
|
Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLogoutClientDueToAck()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// TestHelpers.EnableLogging();
|
||||||
|
|
||||||
|
IniConfigSource ics = new IniConfigSource();
|
||||||
|
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
|
||||||
|
config.Set("AckTimeout", -1);
|
||||||
|
AddUdpServer(ics);
|
||||||
|
|
||||||
|
ScenePresence sp = AddClient();
|
||||||
|
m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
|
||||||
|
|
||||||
|
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
|
||||||
|
Assert.That(spAfterAckTimeout, Is.Null);
|
||||||
|
|
||||||
|
// TestHelpers.DisableLogging();
|
||||||
|
}
|
||||||
|
|
||||||
// /// <summary>
|
// /// <summary>
|
||||||
// /// Test removing a client from the stack
|
// /// Test removing a client from the stack
|
||||||
// /// </summary>
|
// /// </summary>
|
||||||
|
|
|
@ -79,7 +79,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
|
|
||||||
J2KDecoderModule j2kdm = new J2KDecoderModule();
|
J2KDecoderModule j2kdm = new J2KDecoderModule();
|
||||||
|
|
||||||
scene = SceneHelpers.SetupScene();
|
SceneHelpers sceneHelpers = new SceneHelpers();
|
||||||
|
scene = sceneHelpers.SetupScene();
|
||||||
SceneHelpers.SetupSceneModules(scene, j2kdm);
|
SceneHelpers.SetupSceneModules(scene, j2kdm);
|
||||||
|
|
||||||
tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
|
tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue