Merge branch 'master' into httptests

httptests
UbitUmarov 2017-08-16 05:05:57 +01:00
commit 6d4b0a8ce3
36 changed files with 786 additions and 508 deletions

View File

@ -145,7 +145,12 @@
</exec> </exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
<delete dir="%temp%"/> <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.permissions">
<arg value="./bin/OpenSim.Tests.Permissions.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
<delete dir="%temp%"/>
</target> </target>
<target name="test-stress" depends="build, find-nunit"> <target name="test-stress" depends="build, find-nunit">
@ -260,6 +265,11 @@
<arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" /> <arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" />
</exec> </exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.tests.permissions">
<arg value="./bin/OpenSim.Tests.Permissions.dll" />
<arg value="-xml=test-results/OpenSim.Tests.Permissions.dll-Results.xml" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
@ -271,6 +281,7 @@
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" /> <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
</target> </target>
<target name="doxygen"> <target name="doxygen">

View File

@ -305,18 +305,12 @@ namespace OpenSim.Data.SQLite
using (SqliteCommand cmd = new SqliteCommand()) using (SqliteCommand cmd = new SqliteCommand())
{ {
cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = ?folderID"; cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = :folderID";
cmd.Parameters.Add(new SqliteParameter(":folderID", folderID)); cmd.Parameters.Add(new SqliteParameter(":folderID", folderID));
try if(ExecuteNonQuery(cmd, m_Connection) == 0)
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
return false; return false;
} }
}
return true; return true;
} }

View File

@ -31,7 +31,8 @@ using OpenMetaverse;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
public delegate bool AnimationSetValidator(UUID animID); // public delegate bool AnimationSetValidator(UUID animID);
public delegate uint AnimationSetValidator(UUID animID);
public class AnimationSet public class AnimationSet
{ {
@ -141,7 +142,7 @@ namespace OpenSim.Framework
assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key); assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key);
return System.Text.Encoding.ASCII.GetBytes(assetData); return System.Text.Encoding.ASCII.GetBytes(assetData);
} }
/*
public bool Validate(AnimationSetValidator val) public bool Validate(AnimationSetValidator val)
{ {
if (m_parseError) if (m_parseError)
@ -164,5 +165,22 @@ namespace OpenSim.Framework
return allOk; return allOk;
} }
*/
public uint Validate(AnimationSetValidator val)
{
if (m_parseError)
return 0;
uint ret = 0x7fffffff;
uint t;
foreach (KeyValuePair<string, KeyValuePair<string, UUID>> kvp in m_animations)
{
t = val(kvp.Value.Value);
if (t == 0)
return 0;
ret &= t;
}
return ret;
}
} }
} }

View File

@ -41,6 +41,7 @@ namespace OpenSim.Framework
void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData = ""); void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData = "");
void ApplyUploadCharge(UUID agentID, int amount, string text); void ApplyUploadCharge(UUID agentID, int amount, string text);
void MoveMoney(UUID fromUser, UUID toUser, int amount, string text); void MoveMoney(UUID fromUser, UUID toUser, int amount, string text);
bool MoveMoney(UUID fromUser, UUID toUser, int amount, MoneyTransactionType type, string text);
int UploadCharge { get; } int UploadCharge { get; }
int GroupCreationCharge { get; } int GroupCreationCharge { get; }

View File

@ -1970,7 +1970,7 @@ namespace OpenSim.Framework.Servers.HttpServer
Hashtable headerdata = (Hashtable)responsedata["headers"]; Hashtable headerdata = (Hashtable)responsedata["headers"];
foreach (string header in headerdata.Keys) foreach (string header in headerdata.Keys)
response.AddHeader(header, (string)headerdata[header]); response.AddHeader(header, headerdata[header].ToString());
} }
byte[] buffer; byte[] buffer;

View File

@ -491,7 +491,7 @@ namespace OpenSim.Region.ClientStack.Linden
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {3}", "[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {2}",
poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e); poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e);
} }
} }

View File

@ -6399,6 +6399,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ParcelGodMarkAsContentPacket ParcelGodMarkAsContent = ParcelGodMarkAsContentPacket ParcelGodMarkAsContent =
(ParcelGodMarkAsContentPacket)Packet; (ParcelGodMarkAsContentPacket)Packet;
if(SessionId != ParcelGodMarkAsContent.AgentData.SessionID || AgentId != ParcelGodMarkAsContent.AgentData.AgentID)
return false;
ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark; ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark;
if (ParcelGodMarkAsContentHandler != null) if (ParcelGodMarkAsContentHandler != null)
{ {
@ -6414,6 +6417,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet; FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet;
if(SessionId != FreezeUser.AgentData.SessionID || AgentId != FreezeUser.AgentData.AgentID)
return false;
FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser; FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser;
if (FreezeUserHandler != null) if (FreezeUserHandler != null)
{ {
@ -6431,6 +6437,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
EjectUserPacket EjectUser = EjectUserPacket EjectUser =
(EjectUserPacket)Packet; (EjectUserPacket)Packet;
if(SessionId != EjectUser.AgentData.SessionID || AgentId != EjectUser.AgentData.AgentID)
return false;
EjectUserUpdate EjectUserHandler = OnParcelEjectUser; EjectUserUpdate EjectUserHandler = OnParcelEjectUser;
if (EjectUserHandler != null) if (EjectUserHandler != null)
{ {
@ -6448,6 +6457,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ParcelBuyPassPacket ParcelBuyPass = ParcelBuyPassPacket ParcelBuyPass =
(ParcelBuyPassPacket)Packet; (ParcelBuyPassPacket)Packet;
if(SessionId != ParcelBuyPass.AgentData.SessionID || AgentId != ParcelBuyPass.AgentData.AgentID)
return false;
ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass; ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass;
if (ParcelBuyPassHandler != null) if (ParcelBuyPassHandler != null)
{ {

View File

@ -258,24 +258,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
{ {
m_uploadState = UploadState.Complete; m_uploadState = UploadState.Complete;
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); bool sucess = true;
if (m_createItem) if (m_createItem)
{ {
CompleteCreateItem(m_createItemCallback); sucess = CompleteCreateItem(m_createItemCallback);
} }
else if (m_updateItem) else if (m_updateItem)
{ {
CompleteItemUpdate(m_updateItemData); sucess = CompleteItemUpdate(m_updateItemData);
} }
else if (m_updateTaskItem) else if (m_updateTaskItem)
{ {
CompleteTaskItemUpdate(m_updateTaskItemData); sucess = CompleteTaskItemUpdate(m_updateTaskItemData);
} }
else if (m_asset.Local) else if (m_asset.Local)
{ {
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
} }
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, sucess, m_asset.FullID);
} }
m_log.DebugFormat( m_log.DebugFormat(
@ -411,46 +411,70 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
/// Store the asset for the given item when it has been uploaded. /// Store the asset for the given item when it has been uploaded.
/// </summary> /// </summary>
/// <param name="item"></param> /// <param name="item"></param>
private void CompleteItemUpdate(InventoryItemBase item) private bool CompleteItemUpdate(InventoryItemBase item)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
// m_asset.FullID, item.Name, ourClient.Name); // m_asset.FullID, item.Name, ourClient.Name);
ValidateAssets(); uint perms = ValidateAssets();
if(perms == 0)
{
string error = string.Format("Not enough permissions on asset(s) referenced by item '{0}', update failed", item.Name);
ourClient.SendAlertMessage(error);
m_transactions.RemoveXferUploader(m_transactionID);
ourClient.SendBulkUpdateInventory(item); // invalid the change item on viewer cache
}
else
{
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
if (m_asset.FullID != UUID.Zero) if (m_asset.FullID != UUID.Zero)
{ {
item.AssetID = m_asset.FullID; item.AssetID = m_asset.FullID;
m_Scene.InventoryService.UpdateItem(item); m_Scene.InventoryService.UpdateItem(item);
} }
ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0); ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0);
m_transactions.RemoveXferUploader(m_transactionID); m_transactions.RemoveXferUploader(m_transactionID);
m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0); m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0);
} }
return perms != 0;
}
/// <summary> /// <summary>
/// Store the asset for the given task item when it has been uploaded. /// Store the asset for the given task item when it has been uploaded.
/// </summary> /// </summary>
/// <param name="taskItem"></param> /// <param name="taskItem"></param>
private void CompleteTaskItemUpdate(TaskInventoryItem taskItem) private bool CompleteTaskItemUpdate(TaskInventoryItem taskItem)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}", // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
// m_asset.FullID, taskItem.Name, ourClient.Name); // m_asset.FullID, taskItem.Name, ourClient.Name);
ValidateAssets(); if(ValidateAssets() == 0)
m_Scene.AssetService.Store(m_asset); {
m_transactions.RemoveXferUploader(m_transactionID); m_transactions.RemoveXferUploader(m_transactionID);
string error = string.Format("Not enough permissions on asset(s) referenced by task item '{0}', update failed", taskItem.Name);
ourClient.SendAlertMessage(error);
// force old asset to viewers ??
return false;
} }
private void CompleteCreateItem(uint callbackID) m_Scene.AssetService.Store(m_asset);
m_transactions.RemoveXferUploader(m_transactionID);
return true;
}
private bool CompleteCreateItem(uint callbackID)
{ {
ValidateAssets(); if(ValidateAssets() == 0)
{
m_transactions.RemoveXferUploader(m_transactionID);
string error = string.Format("Not enough permissions on asset(s) referenced by item '{0}', creation failed", m_name);
ourClient.SendAlertMessage(error);
return false;
}
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
InventoryItemBase item = new InventoryItemBase(); InventoryItemBase item = new InventoryItemBase();
@ -480,35 +504,40 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
ourClient.SendAlertMessage("Unable to create inventory item"); ourClient.SendAlertMessage("Unable to create inventory item");
m_transactions.RemoveXferUploader(m_transactionID); m_transactions.RemoveXferUploader(m_transactionID);
return true;
} }
private uint ValidateAssets()
private void ValidateAssets()
{ {
uint retPerms = 0x7fffffff;
// if(m_Scene.Permissions.BypassPermissions())
// return retPerms;
if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet) if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet)
{ {
AnimationSet animSet = new AnimationSet(m_asset.Data); AnimationSet animSet = new AnimationSet(m_asset.Data);
bool allOk = animSet.Validate(x => { retPerms &= animSet.Validate(x => {
int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x); const uint required = (uint)(PermissionMask.Transfer | PermissionMask.Copy);
int required = (int)(PermissionMask.Transfer | PermissionMask.Copy); uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x);
// currrent yes/no rule
if ((perms & required) != required) if ((perms & required) != required)
return false; return 0;
return true; return perms;
}); });
if (!allOk) return retPerms;
m_asset.Data = animSet.ToBytes();
} }
if (m_asset.Type == (sbyte)AssetType.Clothing || if (m_asset.Type == (sbyte)AssetType.Clothing ||
m_asset.Type == (sbyte)AssetType.Bodypart) m_asset.Type == (sbyte)AssetType.Bodypart)
{ {
const uint texturesfullPermMask = (uint)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
string content = System.Text.Encoding.ASCII.GetString(m_asset.Data); string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
string[] lines = content.Split(new char[] {'\n'}); string[] lines = content.Split(new char[] {'\n'});
List<string> validated = new List<string>(); // on current requiriment of full rigths assume old assets where accepted
Dictionary<int, UUID> allowed = ExtractTexturesFromOldData(); Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
int textures = 0; int textures = 0;
@ -518,10 +547,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
try try
{ {
if (line.StartsWith("textures ")) if (line.StartsWith("textures "))
{
textures = Convert.ToInt32(line.Substring(9)); textures = Convert.ToInt32(line.Substring(9));
validated.Add(line);
}
else if (textures > 0) else if (textures > 0)
{ {
string[] parts = line.Split(new char[] {' '}); string[] parts = line.Split(new char[] {' '});
@ -532,42 +559,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
if (defaultIDs.Contains(tx) || tx == UUID.Zero || if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
(allowed.ContainsKey(id) && allowed[id] == tx)) (allowed.ContainsKey(id) && allowed[id] == tx))
{ {
validated.Add(parts[0] + " " + tx.ToString()); continue;
} }
else else
{ {
int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx); uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
if ((perms & full) != full) if ((perms & texturesfullPermMask) != texturesfullPermMask)
{ {
m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId); m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
validated.Add(parts[0] + " " + UUID.Zero.ToString()); return 0;
} }
else else
{ {
validated.Add(line); retPerms &= perms;
} }
} }
textures--; textures--;
} }
else
{
validated.Add(line);
}
} }
catch catch
{ {
// If it's malformed, skip it // If it's malformed, skip it
} }
} }
string final = String.Join("\n", validated.ToArray());
m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
} }
return retPerms;
} }
/* not in use
/// <summary> /// <summary>
/// Get the asset data uploaded in this transfer. /// Get the asset data uploaded in this transfer.
/// </summary> /// </summary>
@ -582,7 +602,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
return null; return null;
} }
*/
public void SetOldData(byte[] d) public void SetOldData(byte[] d)
{ {
m_oldData = d; m_oldData = d;

View File

@ -299,15 +299,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet) else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet)
{ {
AnimationSet animSet = new AnimationSet(data); AnimationSet animSet = new AnimationSet(data);
if (!animSet.Validate(x => { uint res = animSet.Validate(x => {
const int required = (int)(PermissionMask.Transfer | PermissionMask.Copy);
int perms = m_Scene.InventoryService.GetAssetPermissions(remoteClient.AgentId, x); int perms = m_Scene.InventoryService.GetAssetPermissions(remoteClient.AgentId, x);
int required = (int)(PermissionMask.Transfer | PermissionMask.Copy); // enforce previus perm rule
if ((perms & required) != required) if ((perms & required) != required)
return false; return 0;
return true; return (uint) perms;
})) });
if(res == 0)
{ {
data = animSet.ToBytes(); remoteClient.SendAgentAlertMessage("Not enought permissions on asset(s) referenced by animation set '{0}', update failed", false);
return UUID.Zero;
} }
} }

View File

@ -250,6 +250,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
if (inventoryURL != null && inventoryURL != string.Empty) if (inventoryURL != null && inventoryURL != string.Empty)
{ {
inventoryURL = inventoryURL.Trim(new char[] { '/' }); inventoryURL = inventoryURL.Trim(new char[] { '/' });
lock (m_InventoryURLs)
m_InventoryURLs[userID] = inventoryURL; m_InventoryURLs[userID] = inventoryURL;
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL); m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
return; return;
@ -268,18 +269,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
if (!string.IsNullOrEmpty(inventoryURL)) if (!string.IsNullOrEmpty(inventoryURL))
{ {
inventoryURL = inventoryURL.Trim(new char[] { '/' }); inventoryURL = inventoryURL.Trim(new char[] { '/' });
m_InventoryURLs.Add(userID, inventoryURL); lock (m_InventoryURLs)
m_InventoryURLs[userID] = inventoryURL;
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL); m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
} }
} }
} }
} }
private void DropInventoryServiceURL(UUID userID) private void DropInventoryServiceURL(UUID userID)
{ {
lock (m_InventoryURLs) lock (m_InventoryURLs)
{
if (m_InventoryURLs.ContainsKey(userID)) if (m_InventoryURLs.ContainsKey(userID))
{ {
string url = m_InventoryURLs[userID]; string url = m_InventoryURLs[userID];
@ -287,16 +288,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Removed {0} from the cache of inventory URLs", url); m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Removed {0} from the cache of inventory URLs", url);
} }
} }
}
public string GetInventoryServiceURL(UUID userID) public string GetInventoryServiceURL(UUID userID)
{
lock (m_InventoryURLs)
{ {
if (m_InventoryURLs.ContainsKey(userID)) if (m_InventoryURLs.ContainsKey(userID))
return m_InventoryURLs[userID]; return m_InventoryURLs[userID];
}
CacheInventoryServiceURL(userID); CacheInventoryServiceURL(userID);
lock (m_InventoryURLs)
{
if (m_InventoryURLs.ContainsKey(userID)) if (m_InventoryURLs.ContainsKey(userID))
return m_InventoryURLs[userID]; return m_InventoryURLs[userID];
}
return null; //it means that the methods should forward to local grid's inventory return null; //it means that the methods should forward to local grid's inventory

View File

@ -285,6 +285,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// Dearchive the region embodied in this request. /// Dearchive the region embodied in this request.
/// </summary> /// </summary>
public void DearchiveRegion() public void DearchiveRegion()
{
DearchiveRegion(true);
}
public void DearchiveRegion(bool shouldStartScripts)
{ {
int successfulAssetRestores = 0; int successfulAssetRestores = 0;
int failedAssetRestores = 0; int failedAssetRestores = 0;
@ -425,6 +430,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so
// that users can enter the scene. If we allow the scripts to start in the loop above // that users can enter the scene. If we allow the scripts to start in the loop above
// then they significantly increase the time until the OAR finishes loading. // then they significantly increase the time until the OAR finishes loading.
if (shouldStartScripts)
{
WorkManager.RunInThread(o => WorkManager.RunInThread(o =>
{ {
Thread.Sleep(15000); Thread.Sleep(15000);
@ -441,6 +448,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
sceneContext.SceneObjects.Clear(); sceneContext.SceneObjects.Clear();
} }
}, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId)); }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId));
}
m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive");

View File

@ -41,6 +41,7 @@ using OpenSim.Framework;
using OpenSim.Framework.Capabilities; using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
@ -216,6 +217,7 @@ namespace OpenSim.Region.CoreModules.World.Land
client.OnParcelEjectUser += ClientOnParcelEjectUser; client.OnParcelEjectUser += ClientOnParcelEjectUser;
client.OnParcelFreezeUser += ClientOnParcelFreezeUser; client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
client.OnSetStartLocationRequest += ClientOnSetHome; client.OnSetStartLocationRequest += ClientOnSetHome;
client.OnParcelBuyPass += ClientParcelBuyPass;
} }
public void EventMakeChildAgent(ScenePresence avatar) public void EventMakeChildAgent(ScenePresence avatar)
@ -537,6 +539,118 @@ namespace OpenSim.Region.CoreModules.World.Land
} }
} }
public void ClientParcelBuyPass(IClientAPI remote_client, UUID targetID, int landLocalID)
{
ILandObject land;
lock (m_landList)
{
m_landList.TryGetValue(landLocalID, out land);
}
// trivial checks
if(land == null)
return;
LandData ldata = land.LandData;
if(ldata == null)
return;
if(ldata.OwnerID == targetID)
return;
if(ldata.PassHours == 0)
return;
// don't allow passes on group owned until we can give money to groups
if(ldata.IsGroupOwned)
{
remote_client.SendAgentAlertMessage("pass to group owned parcel not suported", false);
return;
}
if((ldata.Flags & (uint)ParcelFlags.UsePassList) == 0)
return;
int cost = ldata.PassPrice;
int idx = land.LandData.ParcelAccessList.FindIndex(
delegate(LandAccessEntry e)
{
if (e.AgentID == targetID && e.Flags == AccessList.Access)
return true;
return false;
});
int now = Util.UnixTimeSinceEpoch();
int expires = (int)(3600.0 * ldata.PassHours + 0.5f);
int currenttime = -1;
if (idx != -1)
{
if(ldata.ParcelAccessList[idx].Expires == 0)
{
remote_client.SendAgentAlertMessage("You already have access to parcel", false);
return;
}
currenttime = ldata.ParcelAccessList[idx].Expires - now;
if(currenttime > (int)(0.25f * expires + 0.5f))
{
if(currenttime > 3600)
remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.###} hours",
currenttime/3600f), false);
else if(currenttime > 60)
remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.##} minutes",
currenttime/60f), false);
else
remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.#} seconds",
currenttime), false);
return;
}
}
LandAccessEntry entry = new LandAccessEntry();
entry.AgentID = targetID;
entry.Flags = AccessList.Access;
entry.Expires = now + expires;
if(currenttime > 0)
entry.Expires += currenttime;
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
if(cost != 0 && mm != null)
{
WorkManager.RunInThreadPool(
delegate
{
string regionName = m_scene.RegionInfo.RegionName;
if (!mm.AmountCovered(remote_client.AgentId, cost))
{
remote_client.SendAgentAlertMessage(String.Format("Insufficient funds in region '{0}' money system", regionName), true);
return;
}
string payDescription = String.Format("Parcel '{0}' at region '{1} {2:0.###} hours access pass", ldata.Name, regionName, ldata.PassHours);
if(!mm.MoveMoney(remote_client.AgentId, ldata.OwnerID, cost,MoneyTransactionType.LandPassSale, payDescription))
{
remote_client.SendAgentAlertMessage("Sorry pass payment processing failed, please try again later", true);
return;
}
if (idx != -1)
ldata.ParcelAccessList.RemoveAt(idx);
ldata.ParcelAccessList.Add(entry);
m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
return;
}, null, "ParcelBuyPass");
}
else
{
if (idx != -1)
ldata.ParcelAccessList.RemoveAt(idx);
ldata.ParcelAccessList.Add(entry);
m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
}
}
public void ClientOnParcelAccessListRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID, public void ClientOnParcelAccessListRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID,
int landLocalID, IClientAPI remote_client) int landLocalID, IClientAPI remote_client)
{ {
@ -1292,7 +1406,7 @@ namespace OpenSim.Region.CoreModules.World.Land
{ {
if (!temp.Contains(currentParcel)) if (!temp.Contains(currentParcel))
{ {
if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId)) if (!currentParcel.IsBannedFromLand(remote_client.AgentId))
{ {
currentParcel.ForceUpdateLandInfo(); currentParcel.ForceUpdateLandInfo();
temp.Add(currentParcel); temp.Add(currentParcel);
@ -1766,7 +1880,7 @@ namespace OpenSim.Region.CoreModules.World.Land
land_update.MusicURL = properties.MusicURL; land_update.MusicURL = properties.MusicURL;
land_update.Name = properties.Name; land_update.Name = properties.Name;
land_update.ParcelFlags = (uint) properties.ParcelFlags; land_update.ParcelFlags = (uint) properties.ParcelFlags;
land_update.PassHours = (int) properties.PassHours; land_update.PassHours = properties.PassHours;
land_update.PassPrice = (int) properties.PassPrice; land_update.PassPrice = (int) properties.PassPrice;
land_update.SalePrice = (int) properties.SalePrice; land_update.SalePrice = (int) properties.SalePrice;
land_update.SnapshotID = properties.SnapshotID; land_update.SnapshotID = properties.SnapshotID;

View File

@ -540,7 +540,8 @@ namespace OpenSim.Region.CoreModules.World.Land
ParcelFlags.UseEstateVoiceChan); ParcelFlags.UseEstateVoiceChan);
} }
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false)) // don't allow passes on group owned until we can give money to groups
if (!newData.IsGroupOwned && m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false))
{ {
newData.PassHours = args.PassHours; newData.PassHours = args.PassHours;
newData.PassPrice = args.PassPrice; newData.PassPrice = args.PassPrice;

View File

@ -657,6 +657,9 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
// if(!m_scene.IsRunning)
// return sog;
if (root.KeyframeMotion != null) if (root.KeyframeMotion != null)
root.KeyframeMotion.StartCrossingCheck(); root.KeyframeMotion.StartCrossingCheck();
@ -3018,12 +3021,13 @@ namespace OpenSim.Region.Framework.Scenes
// If we somehow got here to updating the SOG and its root part is not scheduled for update, // If we somehow got here to updating the SOG and its root part is not scheduled for update,
// check to see if the physical position or rotation warrant an update. // check to see if the physical position or rotation warrant an update.
/*
if (m_rootPart.UpdateFlag == UpdateRequired.NONE) if (m_rootPart.UpdateFlag == UpdateRequired.NONE)
{ {
// rootpart SendScheduledUpdates will check if a update is needed // rootpart SendScheduledUpdates will check if a update is needed
m_rootPart.UpdateFlag = UpdateRequired.TERSE; m_rootPart.UpdateFlag = UpdateRequired.TERSE;
} }
*/
if (IsAttachment) if (IsAttachment)
{ {
ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar); ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar);

View File

@ -238,12 +238,6 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks> /// </remarks>
public bool SoundQueueing { get; set; } public bool SoundQueueing { get; set; }
public uint TimeStampFull;
public uint TimeStampLastActivity; // Will be used for AutoReturn
public uint TimeStampTerse;
[XmlIgnore] [XmlIgnore]
public Quaternion AttachRotation = Quaternion.Identity; public Quaternion AttachRotation = Quaternion.Identity;
@ -1219,6 +1213,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
public UpdateRequired UpdateFlag { get; set; } public UpdateRequired UpdateFlag { get; set; }
private object UpdateFlagLock = new object();
/// <summary> /// <summary>
/// Used for media on a prim. /// Used for media on a prim.
@ -1641,8 +1636,10 @@ namespace OpenSim.Region.Framework.Scenes
PhysActor.SetMaterial((int)value); PhysActor.SetMaterial((int)value);
} }
if(ParentGroup != null) if(ParentGroup != null)
{
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleFullUpdateIfNone(); ScheduleFullUpdate();
}
} }
} }
} }
@ -1675,7 +1672,7 @@ namespace OpenSim.Region.Framework.Scenes
get get
{ {
byte pst = PhysicsShapeType; byte pst = PhysicsShapeType;
if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh()) if(pst == (byte) PhysShapeType.none || HasMesh())
return true; return true;
return false; return false;
} }
@ -1730,7 +1727,12 @@ namespace OpenSim.Region.Framework.Scenes
public byte PhysicsShapeType public byte PhysicsShapeType
{ {
get { return m_physicsShapeType; } get
{
// if (PhysActor != null)
// m_physicsShapeType = PhysActor.PhysicsShapeType;
return m_physicsShapeType;
}
set set
{ {
byte oldv = m_physicsShapeType; byte oldv = m_physicsShapeType;
@ -1781,10 +1783,12 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_density = value; m_density = value;
ScheduleFullUpdateIfNone();
if (ParentGroup != null) if (ParentGroup != null)
{
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate();
}
PhysicsActor pa = PhysActor; PhysicsActor pa = PhysActor;
if (pa != null) if (pa != null)
@ -1802,10 +1806,11 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_gravitymod = value; m_gravitymod = value;
ScheduleFullUpdateIfNone();
if (ParentGroup != null) if (ParentGroup != null)
{
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate();
}
PhysicsActor pa = PhysActor; PhysicsActor pa = PhysActor;
if (pa != null) if (pa != null)
@ -1823,10 +1828,11 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_friction = value; m_friction = value;
ScheduleFullUpdateIfNone();
if (ParentGroup != null) if (ParentGroup != null)
{
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate();
}
PhysicsActor pa = PhysActor; PhysicsActor pa = PhysActor;
if (pa != null) if (pa != null)
@ -1844,10 +1850,11 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_bounce = value; m_bounce = value;
ScheduleFullUpdateIfNone();
if (ParentGroup != null) if (ParentGroup != null)
{
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate();
}
PhysicsActor pa = PhysActor; PhysicsActor pa = PhysActor;
if (pa != null) if (pa != null)
@ -1876,6 +1883,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public void ClearUpdateSchedule() public void ClearUpdateSchedule()
{ {
lock(UpdateFlagLock)
UpdateFlag = UpdateRequired.NONE; UpdateFlag = UpdateRequired.NONE;
} }
@ -3239,17 +3247,6 @@ namespace OpenSim.Region.Framework.Scenes
APIDActive = false; APIDActive = false;
} }
public void ScheduleFullUpdateIfNone()
{
if (ParentGroup == null)
return;
// ??? ParentGroup.HasGroupChanged = true;
if (UpdateFlag != UpdateRequired.FULL)
ScheduleFullUpdate();
}
/// <summary> /// <summary>
/// Schedules this prim for a full update /// Schedules this prim for a full update
/// </summary> /// </summary>
@ -3260,22 +3257,11 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup == null) if (ParentGroup == null)
return; return;
ParentGroup.QueueForUpdateCheck(); lock(UpdateFlagLock)
int timeNow = Util.UnixTimeSinceEpoch();
// If multiple updates are scheduled on the same second, we still need to perform all of them
// So we'll force the issue by bumping up the timestamp so that later processing sees these need
// to be performed.
if (timeNow <= TimeStampFull)
{ {
TimeStampFull += 1; ParentGroup.QueueForUpdateCheck(); // just in case
} if(UpdateFlag != UpdateRequired.FULL)
else
{ {
TimeStampFull = (uint)timeNow;
}
UpdateFlag = UpdateRequired.FULL; UpdateFlag = UpdateRequired.FULL;
// m_log.DebugFormat( // m_log.DebugFormat(
@ -3285,6 +3271,8 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup.Scene != null) if (ParentGroup.Scene != null)
ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true); ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true);
} }
}
}
/// <summary> /// <summary>
/// Schedule a terse update for this prim. Terse updates only send position, /// Schedule a terse update for this prim. Terse updates only send position,
@ -3304,12 +3292,13 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
} }
lock(UpdateFlagLock)
{
if (UpdateFlag == UpdateRequired.NONE) if (UpdateFlag == UpdateRequired.NONE)
{ {
ParentGroup.HasGroupChanged = true; ParentGroup.HasGroupChanged = true;
ParentGroup.QueueForUpdateCheck(); ParentGroup.QueueForUpdateCheck();
TimeStampTerse = (uint) Util.UnixTimeSinceEpoch();
UpdateFlag = UpdateRequired.TERSE; UpdateFlag = UpdateRequired.TERSE;
// m_log.DebugFormat( // m_log.DebugFormat(
@ -3320,6 +3309,7 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup.Scene != null) if (ParentGroup.Scene != null)
ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false); ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false);
} }
}
public void ScriptSetPhysicsStatus(bool UsePhysics) public void ScriptSetPhysicsStatus(bool UsePhysics)
{ {
@ -3362,12 +3352,15 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
// Update the "last" values // Update the "last" values
lock(UpdateFlagLock)
{
m_lastPosition = AbsolutePosition; m_lastPosition = AbsolutePosition;
m_lastRotation = RotationOffset; m_lastRotation = RotationOffset;
m_lastVelocity = Velocity; m_lastVelocity = Velocity;
m_lastAcceleration = Acceleration; m_lastAcceleration = Acceleration;
m_lastAngularVelocity = AngularVelocity; m_lastAngularVelocity = AngularVelocity;
m_lastUpdateSentTime = Util.GetTimeStampMS(); m_lastUpdateSentTime = Util.GetTimeStampMS();
}
ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{ {
@ -3381,12 +3374,15 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
// Update the "last" values // Update the "last" values
lock(UpdateFlagLock)
{
m_lastPosition = AbsolutePosition; m_lastPosition = AbsolutePosition;
m_lastRotation = RotationOffset; m_lastRotation = RotationOffset;
m_lastVelocity = Velocity; m_lastVelocity = Velocity;
m_lastAcceleration = Acceleration; m_lastAcceleration = Acceleration;
m_lastAngularVelocity = AngularVelocity; m_lastAngularVelocity = AngularVelocity;
m_lastUpdateSentTime = Util.GetTimeStampMS(); m_lastUpdateSentTime = Util.GetTimeStampMS();
}
if (ParentGroup.IsAttachment) if (ParentGroup.IsAttachment)
{ {
@ -3443,16 +3439,22 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public void SendScheduledUpdates() public void SendScheduledUpdates()
{ {
switch (UpdateFlag) UpdateRequired currentUpdate;
lock(UpdateFlagLock)
{
currentUpdate = UpdateFlag;
ClearUpdateSchedule();
}
switch (currentUpdate)
{ {
case UpdateRequired.NONE: case UpdateRequired.NONE:
ClearUpdateSchedule();
break; break;
case UpdateRequired.TERSE: case UpdateRequired.TERSE:
ClearUpdateSchedule();
bool needupdate = true; bool needupdate = true;
lock(UpdateFlagLock)
{
double now = Util.GetTimeStampMS(); double now = Util.GetTimeStampMS();
Vector3 curvel = Velocity; Vector3 curvel = Velocity;
Vector3 curacc = Acceleration; Vector3 curacc = Acceleration;
@ -3543,7 +3545,11 @@ namespace OpenSim.Region.Framework.Scenes
m_lastAcceleration = curacc; m_lastAcceleration = curacc;
m_lastAngularVelocity = angvel; m_lastAngularVelocity = angvel;
m_lastUpdateSentTime = now; m_lastUpdateSentTime = now;
}
}
if(needupdate)
{
ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
{ {
SendTerseUpdateToClient(client); SendTerseUpdateToClient(client);
@ -3552,7 +3558,6 @@ namespace OpenSim.Region.Framework.Scenes
break; break;
case UpdateRequired.FULL: case UpdateRequired.FULL:
ClearUpdateSchedule();
SendFullUpdateToAllClientsInternal(); SendFullUpdateToAllClientsInternal();
break; break;
} }
@ -3567,7 +3572,10 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup == null || ParentGroup.Scene == null) if (ParentGroup == null || ParentGroup.Scene == null)
return; return;
ClearUpdateSchedule(); lock(UpdateFlagLock)
{
if(UpdateFlag != UpdateRequired.NONE)
return;
// Update the "last" values // Update the "last" values
m_lastPosition = AbsolutePosition; m_lastPosition = AbsolutePosition;
@ -3576,6 +3584,7 @@ namespace OpenSim.Region.Framework.Scenes
m_lastAcceleration = Acceleration; m_lastAcceleration = Acceleration;
m_lastAngularVelocity = AngularVelocity; m_lastAngularVelocity = AngularVelocity;
m_lastUpdateSentTime = Util.GetTimeStampMS(); m_lastUpdateSentTime = Util.GetTimeStampMS();
}
ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
{ {
@ -3588,7 +3597,10 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup == null || ParentGroup.Scene == null) if (ParentGroup == null || ParentGroup.Scene == null)
return; return;
ClearUpdateSchedule(); lock(UpdateFlagLock)
{
if(UpdateFlag != UpdateRequired.NONE)
return;
// Update the "last" values // Update the "last" values
m_lastPosition = AbsolutePosition; m_lastPosition = AbsolutePosition;
@ -3597,6 +3609,7 @@ namespace OpenSim.Region.Framework.Scenes
m_lastAcceleration = Acceleration; m_lastAcceleration = Acceleration;
m_lastAngularVelocity = AngularVelocity; m_lastAngularVelocity = AngularVelocity;
m_lastUpdateSentTime = Util.GetTimeStampMS(); m_lastUpdateSentTime = Util.GetTimeStampMS();
}
if (ParentGroup.IsAttachment) if (ParentGroup.IsAttachment)
{ {

View File

@ -844,9 +844,14 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
module.BuyObject(remoteClient, categoryID, localID, saleType, salePrice); module.BuyObject(remoteClient, categoryID, localID, saleType, salePrice);
} }
public void MoveMoney(UUID fromAgentID, UUID toAgentID, int amount, string text) public void MoveMoney(UUID fromUser, UUID toUser, int amount, string text)
{ {
} }
public bool MoveMoney(UUID fromUser, UUID toUser, int amount, MoneyTransactionType type, string text)
{
return true;
}
} }
public enum TransactionType : int public enum TransactionType : int

View File

@ -141,14 +141,30 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
} }
// The passed position is relative to the base of the region. // The passed position is relative to the base of the region.
// There are many assumptions herein that the heightmap increment is 1.
public override float GetTerrainHeightAtXYZ(Vector3 pos) public override float GetTerrainHeightAtXYZ(Vector3 pos)
{ {
float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; try {
try int baseX = (int)pos.X;
{ int baseY = (int)pos.Y;
ret = m_mapInfo.heightMap[mapIndex]; int maxX = (int)m_mapInfo.sizeX;
int maxY = (int)m_mapInfo.sizeY;
float diffX = pos.X - (float)baseX;
float diffY = pos.Y - (float)baseY;
float mapHeight1 = m_mapInfo.heightMap[baseY * maxY + baseX];
float mapHeight2 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + baseX];
float mapHeight3 = m_mapInfo.heightMap[baseY * maxY + Math.Min(baseX + 1, maxX - 1)];
float mapHeight4 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + Math.Min(baseX + 1, maxX - 1)];
float Xrise = (mapHeight4 - mapHeight3) * diffX;
float Yrise = (mapHeight2 - mapHeight1) * diffY;
ret = mapHeight1 + ((Xrise + Yrise) / 2f);
// m_physicsScene.DetailLog("{0},BSTerrainHeightMap,GetTerrainHeightAtXYZ,pos={1},{2}/{3}/{4}/{5},ret={6}",
// BSScene.DetailLogZero, pos, mapHeight1, mapHeight2, mapHeight3, mapHeight4, ret);
} }
catch catch
{ {

View File

@ -66,7 +66,7 @@ namespace OpenSim.Region.PhysicsModule.Meshing
private bool cacheSculptMaps = true; private bool cacheSculptMaps = true;
private string decodedSculptMapPath = null; private string decodedSculptMapPath = null;
private bool useMeshiesPhysicsMesh = false; private bool useMeshiesPhysicsMesh = true;
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh

View File

@ -62,6 +62,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
public byte shapetype; public byte shapetype;
public bool hasOBB; public bool hasOBB;
public bool hasMeshVolume; public bool hasMeshVolume;
public bool isTooSmall;
public MeshState meshState; public MeshState meshState;
public UUID? assetID; public UUID? assetID;
public meshWorkerCmnds comand; public meshWorkerCmnds comand;
@ -69,16 +70,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde
public class ODEMeshWorker public class ODEMeshWorker
{ {
private ILog m_log; private ILog m_log;
private ODEScene m_scene; private ODEScene m_scene;
private IMesher m_mesher; private IMesher m_mesher;
public bool meshSculptedPrim = true; public bool meshSculptedPrim = true;
public bool forceSimplePrimMeshing = false;
public float meshSculptLOD = 32; public float meshSculptLOD = 32;
public float MeshSculptphysicalLOD = 32; public float MeshSculptphysicalLOD = 32;
public float MinSizeToMeshmerize = 0.1f;
private OpenSim.Framework.BlockingQueue<ODEPhysRepData> workQueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>(); private OpenSim.Framework.BlockingQueue<ODEPhysRepData> workQueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>();
private bool m_running; private bool m_running;
@ -93,9 +92,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
if (pConfig != null) if (pConfig != null)
{ {
forceSimplePrimMeshing = pConfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim); meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD); meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
MinSizeToMeshmerize = pConfig.GetFloat("mesh_min_size", MinSizeToMeshmerize);
MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD); MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
} }
m_running = true; m_running = true;
@ -288,6 +287,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde
{ {
PrimitiveBaseShape pbs = repData.pbs; PrimitiveBaseShape pbs = repData.pbs;
// check sculpts or meshs // check sculpts or meshs
Vector3 scale = pbs.Scale;
if(scale.X <= MinSizeToMeshmerize &&
scale.Y <= MinSizeToMeshmerize &&
scale.Z <= MinSizeToMeshmerize)
{
repData.isTooSmall = true;
return false;
}
if (pbs.SculptEntry) if (pbs.SculptEntry)
{ {
if (meshSculptedPrim) if (meshSculptedPrim)
@ -299,9 +308,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
return false; return false;
} }
if (forceSimplePrimMeshing)
return true;
// convex shapes have no holes // convex shapes have no holes
ushort profilehollow = pbs.ProfileHollow; ushort profilehollow = pbs.ProfileHollow;
if(repData.shapetype == 2) if(repData.shapetype == 2)
@ -425,17 +431,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
Vector3 size = repData.size; Vector3 size = repData.size;
int clod = (int)LevelOfDetail.High; int clod = (int)LevelOfDetail.High;
bool convex;
byte shapetype = repData.shapetype; byte shapetype = repData.shapetype;
if (shapetype == 0) bool convex = shapetype == 2;
convex = false;
else
{
convex = true;
// sculpts pseudo convex
if (pbs.SculptEntry && pbs.SculptType != (byte)SculptType.Mesh)
clod = (int)LevelOfDetail.Low;
}
mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
@ -563,10 +560,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde
private void CalculateBasicPrimVolume(ODEPhysRepData repData) private void CalculateBasicPrimVolume(ODEPhysRepData repData)
{ {
PrimitiveBaseShape _pbs = repData.pbs;
Vector3 _size = repData.size; Vector3 _size = repData.size;
float volume = _size.X * _size.Y * _size.Z; // default float volume = _size.X * _size.Y * _size.Z; // default
if(repData.isTooSmall)
{
repData.volume = volume;
return;
}
PrimitiveBaseShape _pbs = repData.pbs;
float tmp; float tmp;
float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;

View File

@ -1733,7 +1733,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
return true; return true;
} }
private void CreateGeom() private void CreateGeom(bool OverrideToBox)
{ {
bool hasMesh = false; bool hasMesh = false;
@ -1742,7 +1742,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
if ((m_meshState & MeshState.MeshNoColide) != 0) if ((m_meshState & MeshState.MeshNoColide) != 0)
m_NoColide = true; m_NoColide = true;
else if(m_mesh != null) else if(!OverrideToBox && m_mesh != null)
{ {
if (GetMeshGeom()) if (GetMeshGeom())
hasMesh = true; hasMesh = true;
@ -3180,7 +3180,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
primVolume = repData.volume; primVolume = repData.volume;
CreateGeom(); CreateGeom(repData.isTooSmall);
if (prim_geom != IntPtr.Zero) if (prim_geom != IntPtr.Zero)
{ {
@ -3256,7 +3256,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
primVolume = repData.volume; primVolume = repData.volume;
CreateGeom(); CreateGeom(repData.isTooSmall);
if (prim_geom != IntPtr.Zero) if (prim_geom != IntPtr.Zero)
{ {

View File

@ -36,15 +36,13 @@ using OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Threading;
using System.IO.Compression; using System.IO.Compression;
using PrimMesher; using PrimMesher;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using System.Reflection; using System.Reflection;
using System.IO; using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Mono.Addins; using Mono.Addins;
@ -58,22 +56,22 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
// Setting baseDir to a path will enable the dumping of raw files // Setting baseDir to a path will enable the dumping of raw files
// raw files can be imported by blender so a visual inspection of the results can be done // raw files can be imported by blender so a visual inspection of the results can be done
private static string cacheControlFilename = "cntr";
private bool m_Enabled = false; private bool m_Enabled = false;
public static object diskLock = new object(); public static object diskLock = new object();
public bool doMeshFileCache = true; public bool doMeshFileCache = true;
public bool doCacheExpire = true;
public string cachePath = "MeshCache"; public string cachePath = "MeshCache";
public TimeSpan CacheExpire; public TimeSpan CacheExpire;
public bool doCacheExpire = true;
// const string baseDir = "rawFiles"; // const string baseDir = "rawFiles";
private const string baseDir = null; //"rawFiles"; private const string baseDir = null; //"rawFiles";
private bool useMeshiesPhysicsMesh = false; private bool useMeshiesPhysicsMesh = true;
private bool doConvexPrims = true;
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh private bool doConvexSculpts = true;
private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>(); private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>();
private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>(); private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>();
@ -103,40 +101,31 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
if (mesh_config != null) if (mesh_config != null)
{ {
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
if (useMeshiesPhysicsMesh) doConvexPrims = mesh_config.GetBoolean("ConvexPrims",doConvexPrims);
{ doConvexSculpts = mesh_config.GetBoolean("ConvexSculpts",doConvexPrims);
doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache); doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache);
cachePath = mesh_config.GetString("MeshFileCachePath", cachePath); cachePath = mesh_config.GetString("MeshFileCachePath", cachePath);
fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache); fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache);
doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire); doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire);
}
else
{
doMeshFileCache = false;
doCacheExpire = false;
}
m_Enabled = true; m_Enabled = true;
} }
CacheExpire = TimeSpan.FromHours(fcache); CacheExpire = TimeSpan.FromHours(fcache);
lock (diskLock) if(String.IsNullOrEmpty(cachePath))
doMeshFileCache = false;
if(doMeshFileCache)
{ {
if(doMeshFileCache && cachePath != "") if(!checkCache())
{
try
{
if (!Directory.Exists(cachePath))
Directory.CreateDirectory(cachePath);
}
catch
{ {
doMeshFileCache = false; doMeshFileCache = false;
doCacheExpire = false; doCacheExpire = false;
} }
} }
} else
doCacheExpire = false;
} }
} }
@ -168,87 +157,6 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
#endregion #endregion
/// <summary>
/// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may
/// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail
/// for some reason
/// </summary>
/// <param name="minX"></param>
/// <param name="maxX"></param>
/// <param name="minY"></param>
/// <param name="maxY"></param>
/// <param name="minZ"></param>
/// <param name="maxZ"></param>
/// <returns></returns>
private static Mesh CreateSimpleBoxMesh(float minX, float maxX, float minY, float maxY, float minZ, float maxZ)
{
Mesh box = new Mesh(true);
List<Vertex> vertices = new List<Vertex>();
// bottom
vertices.Add(new Vertex(minX, maxY, minZ));
vertices.Add(new Vertex(maxX, maxY, minZ));
vertices.Add(new Vertex(maxX, minY, minZ));
vertices.Add(new Vertex(minX, minY, minZ));
box.Add(new Triangle(vertices[0], vertices[1], vertices[2]));
box.Add(new Triangle(vertices[0], vertices[2], vertices[3]));
// top
vertices.Add(new Vertex(maxX, maxY, maxZ));
vertices.Add(new Vertex(minX, maxY, maxZ));
vertices.Add(new Vertex(minX, minY, maxZ));
vertices.Add(new Vertex(maxX, minY, maxZ));
box.Add(new Triangle(vertices[4], vertices[5], vertices[6]));
box.Add(new Triangle(vertices[4], vertices[6], vertices[7]));
// sides
box.Add(new Triangle(vertices[5], vertices[0], vertices[3]));
box.Add(new Triangle(vertices[5], vertices[3], vertices[6]));
box.Add(new Triangle(vertices[1], vertices[0], vertices[5]));
box.Add(new Triangle(vertices[1], vertices[5], vertices[4]));
box.Add(new Triangle(vertices[7], vertices[1], vertices[4]));
box.Add(new Triangle(vertices[7], vertices[2], vertices[1]));
box.Add(new Triangle(vertices[3], vertices[2], vertices[7]));
box.Add(new Triangle(vertices[3], vertices[7], vertices[6]));
return box;
}
/// <summary>
/// Creates a simple bounding box mesh for a complex input mesh
/// </summary>
/// <param name="meshIn"></param>
/// <returns></returns>
private static Mesh CreateBoundingBoxMesh(Mesh meshIn)
{
float minX = float.MaxValue;
float maxX = float.MinValue;
float minY = float.MaxValue;
float maxY = float.MinValue;
float minZ = float.MaxValue;
float maxZ = float.MinValue;
foreach (Vector3 v in meshIn.getVertexList())
{
if (v.X < minX) minX = v.X;
if (v.Y < minY) minY = v.Y;
if (v.Z < minZ) minZ = v.Z;
if (v.X > maxX) maxX = v.X;
if (v.Y > maxY) maxY = v.Y;
if (v.Z > maxZ) maxZ = v.Z;
}
return CreateSimpleBoxMesh(minX, maxX, minY, maxY, minZ, maxZ);
}
private void ReportPrimError(string message, string primName, PrimMesh primMesh) private void ReportPrimError(string message, string primName, PrimMesh primMesh)
{ {
m_log.Error(message); m_log.Error(message);
@ -330,6 +238,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
List<Coord> coords; List<Coord> coords;
List<Face> faces; List<Face> faces;
bool needsConvexProcessing = convex;
if (primShape.SculptEntry) if (primShape.SculptEntry)
{ {
@ -340,23 +249,49 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex)) if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex))
return null; return null;
needsConvexProcessing = false;
} }
else else
{ {
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces)) if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces))
return null; return null;
needsConvexProcessing &= doConvexSculpts;
} }
} }
else else
{ {
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, convex, out coords, out faces)) if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, convex, out coords, out faces))
return null; return null;
needsConvexProcessing &= doConvexPrims;
} }
int numCoords = coords.Count; int numCoords = coords.Count;
int numFaces = faces.Count; int numFaces = faces.Count;
if(numCoords < 3 || (!needsConvexProcessing && numFaces < 1))
{
m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName);
return null;
}
if(needsConvexProcessing)
{
List<Coord> convexcoords;
List<Face> convexfaces;
if(CreateBoundingHull(coords, out convexcoords, out convexfaces) && convexcoords != null && convexfaces != null)
{
coords.Clear();
coords = convexcoords;
numCoords = coords.Count;
faces.Clear();
faces = convexfaces;
numFaces = faces.Count;
}
else
m_log.ErrorFormat("[ubMESH]: failed to create convex for {0} using normal mesh", primName);
}
Mesh mesh = new Mesh(true); Mesh mesh = new Mesh(true);
// Add the corresponding triangles to the mesh // Add the corresponding triangles to the mesh
for (int i = 0; i < numFaces; i++) for (int i = 0; i < numFaces; i++)
@ -372,7 +307,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
if(mesh.numberVertices() < 3 || mesh.numberTriangles() < 1) if(mesh.numberVertices() < 3 || mesh.numberTriangles() < 1)
{ {
m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim " + primName + " ignored"); m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName);
return null; return null;
} }
@ -625,45 +560,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
vs.Clear(); vs.Clear();
continue; continue;
} }
/*
if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
{
vs.Clear();
continue;
}
nverts = hullr.Vertices.Count;
nindexs = hullr.Indices.Count;
if (nindexs % 3 != 0)
{
vs.Clear();
continue;
}
for (i = 0; i < nverts; i++)
{
c.X = hullr.Vertices[i].x;
c.Y = hullr.Vertices[i].y;
c.Z = hullr.Vertices[i].z;
coords.Add(c);
}
for (i = 0; i < nindexs; i += 3)
{
t1 = hullr.Indices[i];
if (t1 > nverts)
break;
t2 = hullr.Indices[i + 1];
if (t2 > nverts)
break;
t3 = hullr.Indices[i + 2];
if (t3 > nverts)
break;
f = new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3);
faces.Add(f);
}
*/
List<int> indices; List<int> indices;
if (!HullUtils.ComputeHull(vs, out indices)) if (!HullUtils.ComputeHull(vs, out indices))
{ {
@ -769,38 +666,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
vs.Clear(); vs.Clear();
return true; return true;
} }
/*
if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
return false;
nverts = hullr.Vertices.Count;
nindexs = hullr.Indices.Count;
if (nindexs % 3 != 0)
return false;
for (i = 0; i < nverts; i++)
{
c.X = hullr.Vertices[i].x;
c.Y = hullr.Vertices[i].y;
c.Z = hullr.Vertices[i].z;
coords.Add(c);
}
for (i = 0; i < nindexs; i += 3)
{
t1 = hullr.Indices[i];
if (t1 > nverts)
break;
t2 = hullr.Indices[i + 1];
if (t2 > nverts)
break;
t3 = hullr.Indices[i + 2];
if (t3 > nverts)
break;
f = new Face(t1, t2, t3);
faces.Add(f);
}
*/
List<int> indices; List<int> indices;
if (!HullUtils.ComputeHull(vs, out indices)) if (!HullUtils.ComputeHull(vs, out indices))
return false; return false;
@ -1413,7 +1279,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
} }
} }
public void FileNames(AMeshKey key, out string dir,out string fullFileName) public void FileNames(AMeshKey key, out string dir, out string fullFileName)
{ {
string id = key.ToString(); string id = key.ToString();
string init = id.Substring(0, 1); string init = id.Substring(0, 1);
@ -1530,7 +1396,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
if (!doCacheExpire) if (!doCacheExpire)
return; return;
string controlfile = System.IO.Path.Combine(cachePath, "cntr"); string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename);
lock (diskLock) lock (diskLock)
{ {
@ -1583,5 +1449,153 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
catch { } catch { }
} }
} }
public bool checkCache()
{
string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename);
lock (diskLock)
{
try
{
if (!Directory.Exists(cachePath))
{
Directory.CreateDirectory(cachePath);
Thread.Sleep(100);
FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough);
fs.Close();
return true;
}
}
catch
{
doMeshFileCache = false;
doCacheExpire = false;
return false;
}
finally {}
if (File.Exists(controlfile))
return true;
try
{
Directory.Delete(cachePath, true);
while(Directory.Exists(cachePath))
Thread.Sleep(100);
}
catch(Exception e)
{
m_log.Error("[MESH CACHE]: failed to delete old version of the cache: " + e.Message);
doMeshFileCache = false;
doCacheExpire = false;
return false;
}
finally {}
try
{
Directory.CreateDirectory(cachePath);
while(!Directory.Exists(cachePath))
Thread.Sleep(100);
}
catch(Exception e)
{
m_log.Error("[MESH CACHE]: failed to create new cache folder: " + e.Message);
doMeshFileCache = false;
doCacheExpire = false;
return false;
}
finally {}
try
{
FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough);
fs.Close();
}
catch(Exception e)
{
m_log.Error("[MESH CACHE]: failed to create new control file: " + e.Message);
doMeshFileCache = false;
doCacheExpire = false;
return false;
}
finally {}
return true;
}
}
public bool CreateBoundingHull(List<Coord> inputVertices, out List<Coord> convexcoords, out List<Face> newfaces)
{
convexcoords = null;
newfaces = null;
HullDesc desc = new HullDesc();
HullResult result = new HullResult();
int nInputVerts = inputVertices.Count;
int i;
List<float3> vs = new List<float3>(nInputVerts);
float3 f3;
//useless copy
for(i = 0 ; i < nInputVerts; i++)
{
f3 = new float3(inputVertices[i].X, inputVertices[i].Y, inputVertices[i].Z);
vs.Add(f3);
}
desc.Vertices = vs;
desc.Flags = HullFlag.QF_TRIANGLES;
desc.MaxVertices = 256;
try
{
HullError ret = HullUtils.CreateConvexHull(desc, ref result);
if (ret != HullError.QE_OK)
return false;
int nverts = result.OutputVertices.Count;
int nindx = result.Indices.Count;
if(nverts < 3 || nindx< 3)
return false;
if(nindx % 3 != 0)
return false;
convexcoords = new List<Coord>(nverts);
Coord c;
vs = result.OutputVertices;
for(i = 0 ; i < nverts; i++)
{
c = new Coord(vs[i].x, vs[i].y, vs[i].z);
convexcoords.Add(c);
}
newfaces = new List<Face>(nindx / 3);
List<int> indxs = result.Indices;
int k, l, m;
Face f;
for(i = 0 ; i < nindx;)
{
k = indxs[i++];
l = indxs[i++];
m = indxs[i++];
if(k > nInputVerts)
continue;
if(l > nInputVerts)
continue;
if(m > nInputVerts)
continue;
f = new Face(k,l,m);
newfaces.Add(f);
}
return true;
}
catch
{
return false;
}
return false;
}
} }
} }

View File

@ -7851,7 +7851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
UUID key; UUID key;
ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false)) if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false))
{ {
int expires = 0; int expires = 0;
if (hours != 0) if (hours != 0)
@ -13073,7 +13073,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
UUID key; UUID key;
ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed, false)) if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false))
{ {
if (UUID.TryParse(avatar, out key)) if (UUID.TryParse(avatar, out key))
{ {

View File

@ -525,7 +525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
} }
[Serializable] [Serializable]
public class list: MarshalByRefObject public class list
{ {
private object[] m_data; private object[] m_data;

View File

@ -395,6 +395,7 @@ namespace OpenSim.Services.HypergridService
{ {
if(SendAgentGodKillToRegion(UUID.Zero, agentID, guinfo)) if(SendAgentGodKillToRegion(UUID.Zero, agentID, guinfo))
{ {
if(account != null)
m_log.InfoFormat( m_log.InfoFormat(
"[GATEKEEPER SERVICE]: Login failed for {0} {1}, reason: already logged in", "[GATEKEEPER SERVICE]: Login failed for {0} {1}, reason: already logged in",
account.FirstName, account.LastName); account.FirstName, account.LastName);

View File

@ -44,6 +44,13 @@ namespace OpenSim.Tests.Permissions
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
// In case we're dealing with some older version of nunit
if (Common.TheInstance == null)
{
Common.TheInstance = new Common();
Common.TheInstance.SetUp();
}
Common.TheInstance.DeleteObjectsFolders(); Common.TheInstance.DeleteObjectsFolders();
} }

View File

@ -46,6 +46,12 @@ namespace OpenSim.Tests.Permissions
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
// In case we're dealing with some older version of nunit
if (Common.TheInstance == null)
{
Common.TheInstance = new Common();
Common.TheInstance.SetUp();
}
Common.TheInstance.DeleteObjectsFolders(); Common.TheInstance.DeleteObjectsFolders();
} }
@ -74,6 +80,7 @@ namespace OpenSim.Tests.Permissions
// Try A2 takes copies of objects that cannot be copied. // Try A2 takes copies of objects that cannot be copied.
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]); TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]);
// Ad-hoc. Enough time to let the take work.
Thread.Sleep(5000); Thread.Sleep(5000);
List<InventoryItemBase> items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID); List<InventoryItemBase> items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID);
@ -86,6 +93,7 @@ namespace OpenSim.Tests.Permissions
// Try A2 takes copies of objects that can be copied. // Try A2 takes copies of objects that can be copied.
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]); TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]);
// Ad-hoc. Enough time to let the take work.
Thread.Sleep(5000); Thread.Sleep(5000);
items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID); items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID);
@ -101,6 +109,7 @@ namespace OpenSim.Tests.Permissions
private void TakeOneBox(List<SceneObjectGroup> objs, string name, PermissionMask mask) private void TakeOneBox(List<SceneObjectGroup> objs, string name, PermissionMask mask)
{ {
// Find the object inworld
SceneObjectGroup box = objs.Find(sog => sog.Name == name && sog.OwnerID == Common.TheAvatars[0].UUID); SceneObjectGroup box = objs.Find(sog => sog.Name == name && sog.OwnerID == Common.TheAvatars[0].UUID);
Assert.That(box, Is.Not.Null, name); Assert.That(box, Is.Not.Null, name);

View File

@ -949,18 +949,35 @@
[Mesh] [Mesh]
; enable / disable Collada mesh support ; enable / disable mesh asset uploads
; mesh asset must conform to standard mesh format, with OpenSim extensions
; default is true ; default is true
AllowMeshUpload = true AllowMeshUpload = true
; if you use Meshmerizer and want collisions for meshies, setting this to true
; will cause OpenSim to attempt to decode meshies assets, extract the physics
; mesh, and use it for collisions.
UseMeshiesPhysicsMesh = true
; Minimum user level required to upload meshes ; Minimum user level required to upload meshes
;LevelUpload = 0 ;LevelUpload = 0
; support meshes on physics
;UseMeshiesPhysicsMesh = true
;support convex shape type on normal prims
; (ubOde only)
;ConvexPrims = true
;support convex shape type on sculpts
; (ubOde only)
;ConvexSculpts = true
; mesh cache settings:
; (ubOde only)
; do cache (keep true)
;MeshFileCache = true
; cache folder name relative to bin/ or absolute path
;MeshFileCachePath = MeshCache
;MeshFileCacheDoExpire = true;
;MeshFileCacheExpireHours = 48
[Textures] [Textures]
; If true, textures generated dynamically (i.e. through osSetDynamicTextureData() and similar OSSL functions) are reused where possible ; If true, textures generated dynamically (i.e. through osSetDynamicTextureData() and similar OSSL functions) are reused where possible
@ -982,7 +999,7 @@
[ODEPhysicsSettings] [ODEPhysicsSettings]
; ## ; ##
; ## Physics stats settings ; ## Physics stats settings ( most ignored by ubOde )
; ;
; If collect_stats is enabled, then extra stat information is collected which is accessible via the MonitorModule ; If collect_stats is enabled, then extra stat information is collected which is accessible via the MonitorModule
@ -1155,12 +1172,14 @@
; ## additional meshing options ; ## additional meshing options
; ## ; ##
; Physical collision mesh proxies are normally created for complex prim shapes, ; Physics needs to create internal meshs (or convert the object meshs or scultps)
; and collisions for simple boxes and spheres are computed algorithmically. ; for all prims except simple boxes and spheres.
; If you would rather have mesh proxies for simple prims, you can set this to
; true. Note that this will increase memory usage and region startup time. ; collisions of small objects againts larger ones can have a increased CPU load cost
; Default is false. ; so this are represented by a simple BOX
;force_simple_prim_meshing = false ; if all their scale dimensions are lower or equal to this option. Default is 0.1m
; (ubOde only)
; MinSizeToMeshmerize = 0.1
[BulletSim] [BulletSim]
@ -1469,7 +1488,7 @@
; active_trees allows module to change its trees in time. ; active_trees allows module to change its trees in time.
; some will be deleted, others created and rest may grow ; some will be deleted, others created and rest may grow
; default is false. You can change it with console comand tree active true | false later ; default is false. You can change it with console command tree active true | false later
active_trees = false active_trees = false
; the trees change execution time rate (in ms) ; the trees change execution time rate (in ms)
update_rate = 1000 update_rate = 1000
@ -2061,7 +2080,7 @@
;XmlRpcServiceWriteKey = 1234 ;XmlRpcServiceWriteKey = 1234
; Disables HTTP Keep-Alive for XmlRpcGroupsServicesConnector HTTP Requests, ; Disables HTTP Keep-Alive for XmlRpcGroupsServicesConnector HTTP Requests,
; only set to false it if you absolute sure regions and groups server suport it. ; only set to false it if you absolute sure regions and groups server support it.
; XmlRpcDisableKeepAlive = true ; XmlRpcDisableKeepAlive = true
; Minimum user level required to create groups ; Minimum user level required to create groups

View File

@ -36,9 +36,6 @@
SimulationServiceInConnector = true SimulationServiceInConnector = true
LibraryModule = true LibraryModule = true
[Profile]
Module = "BasicProfileModule"
[SimulationDataStore] [SimulationDataStore]
LocalServiceModule = "OpenSim.Services.SimulationService.dll:SimulationDataService" LocalServiceModule = "OpenSim.Services.SimulationService.dll:SimulationDataService"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.