Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork

Conflicts:
	prebuild.xml
avinationmerge
UbitUmarov 2012-02-10 23:03:30 +00:00
commit e3f5fd81f1
17 changed files with 309 additions and 34 deletions

View File

@ -75,7 +75,7 @@ namespace OpenSim.Data.SQLite
cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue(":Friend", friend);
ExecuteNonQuery(cmd, cmd.Connection);
ExecuteNonQuery(cmd, m_Connection);
return true;
}

View File

@ -422,7 +422,7 @@ namespace OpenSim.Region.ClientStack.Linden
string assetType)
{
m_log.DebugFormat(
"Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
"[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
assetID, inventoryItem, inventoryType, assetType);
sbyte assType = 0;
@ -625,7 +625,12 @@ namespace OpenSim.Region.ClientStack.Linden
item.AssetType = assType;
item.InvType = inType;
item.Folder = parentFolder;
item.CurrentPermissions = (uint)PermissionMask.All;
// If we set PermissionMask.All then when we rez the item the next permissions will replace the current
// (owner) permissions. This becomes a problem if next permissions are changed.
item.CurrentPermissions
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
item.BasePermissions = (uint)PermissionMask.All;
item.EveryOnePermissions = 0;
item.NextPermissions = (uint)PermissionMask.All;

View File

@ -50,8 +50,7 @@ namespace OpenSim.Region.ClientStack.Linden
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
{
// private static readonly ILog m_log =
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
// private IAssetService m_assetService;
@ -210,6 +209,9 @@ namespace OpenSim.Region.ClientStack.Linden
UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
string assetType,UUID AgentID)
{
// m_log.DebugFormat(
// "[NEW FILE AGENT INVENTORY VARIABLE PRICE MODULE]: Upload complete for {0}", inventoryItem);
sbyte assType = 0;
sbyte inType = 0;
@ -259,13 +261,13 @@ namespace OpenSim.Region.ClientStack.Linden
item.AssetType = assType;
item.InvType = inType;
item.Folder = parentFolder;
item.CurrentPermissions = (uint)PermissionMask.All;
item.CurrentPermissions
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
item.BasePermissions = (uint)PermissionMask.All;
item.EveryOnePermissions = 0;
item.NextPermissions = (uint)PermissionMask.All;
item.CreationDate = Util.UnixTimeSinceEpoch();
m_scene.AddInventoryItem(item);
}
}
}

View File

@ -5168,7 +5168,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage, false);
AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship);
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFrendship);
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship);
AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
@ -5891,7 +5891,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true;
}
private bool HandlerTerminateFrendship(IClientAPI sender, Packet Pack)
private bool HandlerTerminateFriendship(IClientAPI sender, Packet Pack)
{
TerminateFriendshipPacket tfriendpack = (TerminateFriendshipPacket)Pack;
@ -5906,14 +5906,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
UUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
UUID exFriendID = tfriendpack.ExBlock.OtherID;
FriendshipTermination handlerTerminateFriendship = OnTerminateFriendship;
if (handlerTerminateFriendship != null)
FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
if (TerminateFriendshipHandler != null)
{
handlerTerminateFriendship(this, listOwnerAgentID, exFriendID);
}
TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID);
return true;
}
return false;
}
private bool HandleFindAgent(IClientAPI client, Packet Packet)
{

View File

@ -830,6 +830,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
group = objlist[i];
SceneObjectPart rootPart = group.RootPart;
// m_log.DebugFormat(
// "[InventoryAccessModule]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
// group.Name, group.LocalId, group.UUID,
// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
// remoteClient.Name);
// Vector3 storedPosition = group.AbsolutePosition;
if (group.UUID == UUID.Zero)
{
@ -892,6 +898,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
rootPart.ScheduleFullUpdate();
}
// m_log.DebugFormat(
// "[InventoryAccessModule]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
// group.Name, group.LocalId, group.UUID,
// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
// remoteClient.Name);
}
group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
@ -959,6 +971,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
rootPart.FromFolderID = item.Folder;
// Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
if ((rootPart.OwnerID != item.Owner) ||
(item.CurrentPermissions & 16) != 0 ||
(item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)

View File

@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// </param>
/// <param name="scene"></param>
/// <param name="appearance">The avatar appearance to use for the new NPC.</param>
/// <returns>The UUID of the ScenePresence created.</returns>
/// <returns>The UUID of the ScenePresence created. UUID.Zero if there was a failure.</returns>
UUID CreateNPC(
string firstname,
string lastname,

View File

@ -330,6 +330,12 @@ namespace OpenSim.Region.Framework.Scenes
item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
item.Name = itemUpd.Name;
item.Description = itemUpd.Description;
// m_log.DebugFormat(
// "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}",
// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions);
if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
@ -338,6 +344,9 @@ namespace OpenSim.Region.Framework.Scenes
item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions;
if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions))
item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
// m_log.DebugFormat("[USER INVENTORY]: item.Flags {0}", item.Flags);
item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions;
item.GroupID = itemUpd.GroupID;
item.GroupOwned = itemUpd.GroupOwned;
@ -2310,7 +2319,24 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.DelinkObjects(parts);
}
/// <summary>
/// Link the scene objects containing the indicated parts to a root object.
/// </summary>
/// <param name="client"></param>
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
public void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds)
{
LinkObjects(client.AgentId, parentPrimId, childPrimIds);
}
/// <summary>
/// Link the scene objects containing the indicated parts to a root object.
/// </summary>
/// <param name="agentId">The ID of the user linking.</param>
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
public void LinkObjects(UUID agentId, uint parentPrimId, List<uint> childPrimIds)
{
List<UUID> owners = new List<UUID>();
@ -2323,7 +2349,7 @@ namespace OpenSim.Region.Framework.Scenes
return;
}
if (!Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID))
if (!Permissions.CanLinkObject(agentId, root.ParentGroup.RootPart.UUID))
{
m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim");
return;
@ -2339,7 +2365,7 @@ namespace OpenSim.Region.Framework.Scenes
if (!owners.Contains(part.OwnerID))
owners.Add(part.OwnerID);
if (Permissions.CanLinkObject(client.AgentId, part.ParentGroup.RootPart.UUID))
if (Permissions.CanLinkObject(agentId, part.ParentGroup.RootPart.UUID))
children.Add(part);
}

View File

@ -1751,6 +1751,10 @@ namespace OpenSim.Region.Framework.Scenes
{
SceneObjectGroup child = children[i].ParentGroup;
// Don't try and add a group to itself - this will only cause severe problems later on.
if (child == parentGroup)
continue;
// Make sure no child prim is set for sale
// So that, on delink, no prims are unwittingly
// left for sale and sold off
@ -1777,8 +1781,13 @@ namespace OpenSim.Region.Framework.Scenes
// We need to explicitly resend the newly link prim's object properties since no other actions
// occur on link to invoke this elsewhere (such as object selection)
if (childGroups.Count > 0)
{
parentGroup.RootPart.CreateSelected = true;
parentGroup.TriggerScriptChangedEvent(Changed.LINK);
parentGroup.HasGroupChanged = true;
parentGroup.ScheduleGroupForFullUpdate();
}
}
finally
{

View File

@ -269,6 +269,8 @@ namespace OpenSim.Region.Framework.Scenes
public void ApplyNextOwnerPermissions()
{
// m_log.DebugFormat("[PRIM INVENTORY]: Applying next owner permissions to {0} {1}", Name, UUID);
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
parts[i].ApplyNextOwnerPermissions();

View File

@ -2377,6 +2377,10 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
// objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
// Linking to ourselves is not a valid operation.
if (objectGroup == this)
return;
SceneObjectPart linkPart = objectGroup.m_rootPart;
Vector3 oldGroupPosition = linkPart.GroupPosition;

View File

@ -39,14 +39,31 @@ using log4net;
namespace OpenSim.Region.Framework.Scenes.Tests
{
/// <summary>
/// Linking tests
/// </summary>
[TestFixture]
public class SceneObjectLinkingTests
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Links to self should be ignored.
/// </summary>
[Test]
public void TestLinkToSelf()
{
TestHelpers.InMethod();
UUID ownerId = TestHelpers.ParseTail(0x1);
int nParts = 3;
TestScene scene = SceneHelpers.SetupScene();
SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(nParts, ownerId, "TestLinkToSelf_", 0x10);
scene.AddSceneObject(sog1);
scene.LinkObjects(ownerId, sog1.LocalId, new List<uint>() { sog1.Parts[1].LocalId });
// sog1.LinkToGroup(sog1);
Assert.That(sog1.Parts.Length, Is.EqualTo(nParts));
}
[Test]
public void TestLinkDelink2SceneObjects()
{

View File

@ -44,7 +44,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
private readonly string m_firstname;
private readonly string m_lastname;
private readonly Vector3 m_startPos;
private readonly UUID m_uuid = UUID.Random();
private UUID m_uuid = UUID.Random();
private readonly Scene m_scene;
private readonly UUID m_ownerID;
@ -444,6 +444,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public virtual UUID AgentId
{
get { return m_uuid; }
set { m_uuid = value; }
}
public UUID SessionId

View File

@ -155,20 +155,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC
"[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID);
sp.CompleteMovement(npcAvatar, false);
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
}
else
{
m_log.WarnFormat("[NPC MODULE]: Could not find scene presence for NPC {0} {1}", sp.Name, sp.UUID);
npcAvatar.AgentId = UUID.Zero;
}
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
}
ev.Set();
});
ev.WaitOne();
m_log.DebugFormat("[NPC MODULE]: Created NPC with id {0}", npcAvatar.AgentId);
// m_log.DebugFormat("[NPC MODULE]: Created NPC with id {0}", npcAvatar.AgentId);
return npcAvatar.AgentId;
}
@ -299,13 +300,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC
NPCAvatar av;
if (m_avatars.TryGetValue(agentID, out av))
{
// m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove", agentID, av.Name);
scene.RemoveClient(agentID, false);
m_avatars.Remove(agentID);
// m_log.DebugFormat("[NPC MODULE]: Removed {0} {1}", agentID, av.Name);
return true;
}
}
// m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove", agentID);
return false;
}

View File

@ -538,6 +538,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public bool Stop(int timeout)
{
// m_log.DebugFormat(
// "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout);
IScriptWorkItem result;
lock (m_EventQueue)
@ -772,7 +775,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
}
catch (Exception e)
{
// m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message);
// m_log.DebugFormat(
// "[SCRIPT] Exception in script {0} {1}: {2}{3}",
// ScriptName, ItemID, e.Message, e.StackTrace);
m_InEvent = false;
m_CurrentEvent = String.Empty;

View File

@ -301,7 +301,7 @@ namespace OpenSim.Region.UserStatistics
public void OnRegisterCaps(UUID agentID, Caps caps)
{
m_log.DebugFormat("[VC]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
string capsPath = "/CAPS/VS/" + UUID.Random();
caps.RegisterHandler("ViewerStats",
new RestStreamHandler("POST", capsPath,
@ -462,7 +462,7 @@ namespace OpenSim.Region.UserStatistics
if (!m_sessions.ContainsKey(agentID))
{
m_log.Warn("[VS]: no session for stat disclosure");
m_log.Warn("[WEB STATS MODULE]: no session for stat disclosure");
return new UserSessionID();
}
uid = m_sessions[agentID];
@ -667,14 +667,13 @@ namespace OpenSim.Region.UserStatistics
{
updatecmd.ExecuteNonQuery();
}
catch
(SqliteExecutionException)
catch (SqliteExecutionException)
{
m_log.Warn("[WEBSTATS]: failed to write stats to storage Execution Exception");
m_log.Warn("[WEB STATS MODULE]: failed to write stats to storage Execution Exception");
}
catch (SqliteSyntaxException)
{
m_log.Warn("[WEBSTATS]: failed to write stats to storage SQL Syntax Exception");
m_log.Warn("[WEB STATS MODULE]: failed to write stats to storage SQL Syntax Exception");
}
}

View File

@ -0,0 +1,185 @@
/*
* 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.Diagnostics;
using System.Reflection;
using log4net;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Region.CoreModules.Avatar.Attachments;
using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
using OpenSim.Region.CoreModules.Framework.InventoryAccess;
using OpenSim.Region.CoreModules.Framework.UserManagement;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.OptionalModules.World.NPC;
using OpenSim.Services.AvatarService;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Tests.Torture
{
/// <summary>
/// NPC torture tests
/// </summary>
/// <remarks>
/// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached,
/// how much memory is free, etc. In some cases, later larger tests will apparently take less time than smaller
/// earlier tests.
/// </remarks>
[TestFixture]
public class NPCTortureTests
{
private TestScene scene;
private AvatarFactoryModule afm;
private UserManagementModule umm;
private AttachmentsModule am;
[TestFixtureSetUp]
public void FixtureInit()
{
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
Util.FireAndForgetMethod = FireAndForgetMethod.None;
}
[TestFixtureTearDown]
public void TearDown()
{
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
// threads. Possibly, later tests should be rewritten not to worry about such things.
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
}
[SetUp]
public void Init()
{
IConfigSource config = new IniConfigSource();
config.AddConfig("NPC");
config.Configs["NPC"].Set("Enabled", "true");
config.AddConfig("Modules");
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
afm = new AvatarFactoryModule();
umm = new UserManagementModule();
am = new AttachmentsModule();
scene = SceneHelpers.SetupScene();
SceneHelpers.SetupSceneModules(scene, config, afm, umm, am, new BasicInventoryAccessModule(), new NPCModule());
}
[Test]
public void TestAddRemove100NPCs()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
TestAddRemoveNPCs(100);
}
[Test]
public void TestAddRemove1000NPCs()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
TestAddRemoveNPCs(1000);
}
[Test]
public void TestAddRemove2000NPCs()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
TestAddRemoveNPCs(2000);
}
private void TestAddRemoveNPCs(int numberOfNpcs)
{
ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
// 8 is the index of the first baked texture in AvatarAppearance
UUID originalFace8TextureId = TestHelpers.ParseTail(0x10);
Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero);
Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8);
originalTef.TextureID = originalFace8TextureId;
// We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell
// ScenePresence.SendInitialData() to reset our entire appearance.
scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
afm.SetAppearance(sp, originalTe, null);
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
List<UUID> npcs = new List<UUID>();
long startGcMemory = GC.GetTotalMemory(true);
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < numberOfNpcs; i++)
{
npcs.Add(
npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance));
}
for (int i = 0; i < numberOfNpcs; i++)
{
Assert.That(npcs[i], Is.Not.Null);
ScenePresence npc = scene.GetScenePresence(npcs[i]);
Assert.That(npc, Is.Not.Null);
}
for (int i = 0; i < numberOfNpcs; i++)
{
Assert.That(npcModule.DeleteNPC(npcs[i], scene), Is.True);
ScenePresence npc = scene.GetScenePresence(npcs[i]);
Assert.That(npc, Is.Null);
}
sw.Stop();
long endGcMemory = GC.GetTotalMemory(true);
Console.WriteLine("Took {0} ms", sw.ElapsedMilliseconds);
Console.WriteLine(
"End {0} MB, Start {1} MB, Diff {2} MB",
endGcMemory / 1024 / 1024,
startGcMemory / 1024 / 1024,
(endGcMemory - startGcMemory) / 1024 / 1024);
}
}
}