From 7fa3335fd53f863b20190025c3cfc8e8e36f96ed Mon Sep 17 00:00:00 2001 From: dahlia Date: Mon, 18 Oct 2010 04:17:36 -0700 Subject: [PATCH 01/11] initial support for meshies physics. Must set ini option UseMeshiesPhysicsMesh = true to enable. See file OpenSimDefaults.ini for example. --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 129 ++++++++++++------ bin/OpenSimDefaults.ini | 6 + bin/zlib.net.dll | Bin 0 -> 65536 bytes prebuild.xml | 2 +- 4 files changed, 97 insertions(+), 40 deletions(-) create mode 100644 bin/zlib.net.dll diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 3e3a0f0589..89ee5afb47 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -40,6 +40,7 @@ using log4net; using Nini.Config; using System.Reflection; using System.IO; +using ComponentAce.Compression.Libs.zlib; namespace OpenSim.Region.Physics.Meshing { @@ -74,6 +75,7 @@ namespace OpenSim.Region.Physics.Meshing private bool cacheSculptMaps = true; private string decodedSculptMapPath = null; + private bool useMeshiesPhysicsMesh = false; private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh @@ -85,6 +87,7 @@ namespace OpenSim.Region.Physics.Meshing decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); + useMeshiesPhysicsMesh = start_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); try { @@ -268,73 +271,121 @@ namespace OpenSim.Region.Physics.Meshing { if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh) { - // add code for mesh physics proxy generation here - m_log.Debug("[MESH]: mesh proxy generation not implemented yet "); + if (!useMeshiesPhysicsMesh) + return null; + + m_log.Debug("[MESH]: experimental mesh proxy generation"); OSD meshOsd; - if (primShape.SculptData.Length > 0) - { - - - m_log.Debug("[MESH]: asset data length: " + primShape.SculptData.Length.ToString()); - byte[] header = Util.StringToBytes256(""); - - ////dump to debugging file - //string filename = System.IO.Path.Combine(decodedSculptMapPath, "mesh_" + primShape.SculptTexture.ToString()); - //BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create)); - //writer.Write(primShape.SculptData); - //writer.Close(); - - } - else + if (primShape.SculptData.Length <= 0) { m_log.Error("[MESH]: asset data is zero length"); return null; } - try + long start = 0; + using (MemoryStream data = new MemoryStream(primShape.SculptData)) { - meshOsd = OSDParser.DeserializeLLSDBinary(primShape.SculptData, true); - } - catch (Exception e) - { - m_log.Error("[MESH]: exception decoding mesh asset: " + e.ToString()); - return null; + meshOsd = (OSDMap)OSDParser.DeserializeLLSDBinary(data, true); + start = data.Position; } if (meshOsd is OSDMap) { OSDMap map = (OSDMap)meshOsd; - //foreach (string name in map.Keys) - // m_log.Debug("[MESH]: key:" + name + " value:" + map[name].AsString()); OSDMap physicsParms = (OSDMap)map["physics_shape"]; - int physOffset = physicsParms["offset"].AsInteger(); + int physOffset = physicsParms["offset"].AsInteger() + (int)start; int physSize = physicsParms["size"].AsInteger(); if (physOffset < 0 || physSize == 0) return null; // no mesh data in asset - m_log.Debug("[MESH]: physOffset:" + physOffset.ToString() + " physSize:" + physSize.ToString()); - //MemoryStream ms = new MemoryStream(primShape.SculptData, physOffset, physSize); - //GZipStream gzStream = new GZipStream(ms, CompressionMode.Decompress); - - //int maxSize = physSize * 5; // arbitrary guess - //byte[] readBuffer = new byte[maxSize]; + OSD decodedMeshOsd = new OSD(); + byte[] meshBytes = new byte[physSize]; + System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); + byte[] decompressed = new byte[physSize * 5]; + try + { + { + string filename = System.IO.Path.Combine(decodedSculptMapPath, "meshInput_" + primShape.SculptTexture.ToString()); + using (FileStream fs = new FileStream(filename, FileMode.Create)) + { + fs.Write(meshBytes, 0, meshBytes.Length); + } + } - //int bytesRead = gzStream.Read(readBuffer, 0, maxSize); + using (MemoryStream inMs = new MemoryStream(meshBytes)) + { + using (MemoryStream outMs = new MemoryStream()) + { + using (ZOutputStream zOut = new ZOutputStream(outMs)) + { + byte[] readBuffer = new byte[2048]; + int readLen = 0; + while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) + { + zOut.Write(readBuffer, 0, readLen); + } + zOut.Flush(); + outMs.Seek(0, SeekOrigin.Begin); - //OSD physMeshOsd = OSDParser.DeserializeLLSDBinary(readBuffer); + byte[] decompressedBuf = outMs.GetBuffer(); + decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf, true); + } + } + } + } + catch (Exception e) + { + m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); + return null; + } + OSDArray decodedMeshOsdArray = null; + // physics_shape is an array of OSDMaps, one for each submesh + if (decodedMeshOsd is OSDArray) + { + decodedMeshOsdArray = (OSDArray)decodedMeshOsd; + foreach (OSD subMeshOsd in decodedMeshOsdArray) + { + if (subMeshOsd is OSDMap) + { + OSDMap subMeshMap = (OSDMap)subMeshOsd; + OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3(); + OpenMetaverse.Vector3 posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"].AsVector3(); + byte[] posBytes = subMeshMap["Position"].AsBinary(); + for (int i = 0; i < posBytes.Length; i += 6) + { + ushort uX = Utils.BytesToUInt16(posBytes, i); + ushort uY = Utils.BytesToUInt16(posBytes, i + 2); + ushort uZ = Utils.BytesToUInt16(posBytes, i + 4); + + Coord c = new Coord( + Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X, + Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y, + Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z); + + coords.Add(c); + } + + byte[] triangleBytes = subMeshMap["TriangleList"].AsBinary(); + for (int i = 0; i < triangleBytes.Length; i += 6) + { + ushort v1 = Utils.BytesToUInt16(triangleBytes, i); + ushort v2 = Utils.BytesToUInt16(triangleBytes, i + 2); + ushort v3 = Utils.BytesToUInt16(triangleBytes, i + 4); + Face f = new Face(v1, v2, v3); + faces.Add(f); + } + } + } + } } - - //just bail out for now until mesh code is finished - return null; - } else { diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 05358c4373..82267edcc9 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -147,6 +147,12 @@ ; to false if you have compatibility problems. ;CacheSculptMaps = 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. This is currently experimental code and enabling + ; it may cause unexpected physics problems. + ;UseMeshiesPhysicsMesh = false + ; Choose one of the physics engines below ; OpenDynamicsEngine is by some distance the most developed physics engine ; basicphysics effectively does not model physics at all, making all objects phantom diff --git a/bin/zlib.net.dll b/bin/zlib.net.dll new file mode 100644 index 0000000000000000000000000000000000000000..9d156547f336ff1e7b51e28a2369a344fec2831c GIT binary patch literal 65536 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../../../../bin/ - @@ -597,6 +596,7 @@ + From e3bd10829f7e13d8ed97c7b5c3fa566edd082b5d Mon Sep 17 00:00:00 2001 From: dahlia Date: Mon, 18 Oct 2010 04:26:23 -0700 Subject: [PATCH 02/11] remove some cruft from last commit --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 89ee5afb47..72dce6ddcb 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -307,14 +307,6 @@ namespace OpenSim.Region.Physics.Meshing byte[] decompressed = new byte[physSize * 5]; try { - { - string filename = System.IO.Path.Combine(decodedSculptMapPath, "meshInput_" + primShape.SculptTexture.ToString()); - using (FileStream fs = new FileStream(filename, FileMode.Create)) - { - fs.Write(meshBytes, 0, meshBytes.Length); - } - } - using (MemoryStream inMs = new MemoryStream(meshBytes)) { using (MemoryStream outMs = new MemoryStream()) From 2be93066da042c21d396bb62b58d4d04fa63cbe0 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Oct 2010 19:08:26 +0100 Subject: [PATCH 03/11] Bump migration version on LastSeen field so it is actually run --- OpenSim/Data/MySQL/Resources/Presence.migrations | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/Resources/Presence.migrations b/OpenSim/Data/MySQL/Resources/Presence.migrations index 1075a15721..be4030efb0 100644 --- a/OpenSim/Data/MySQL/Resources/Presence.migrations +++ b/OpenSim/Data/MySQL/Resources/Presence.migrations @@ -14,7 +14,7 @@ CREATE INDEX UserID ON Presence(UserID); COMMIT; -:VERSION 1 # -------------------------- +:VERSION 2 # -------------------------- BEGIN; From 551015db6382b01d32100e91b569a5717121ccbe Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Oct 2010 20:29:00 +0100 Subject: [PATCH 04/11] Alphabetize results on region search by prefix matching --- OpenSim/Data/MySQL/MySQLRegionData.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index baa948e680..efefad9704 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -62,6 +62,8 @@ namespace OpenSim.Data.MySQL if (scopeID != UUID.Zero) command += " and ScopeID = ?scopeID"; + command += " order by regionName"; + using (MySqlCommand cmd = new MySqlCommand(command)) { cmd.Parameters.AddWithValue("?regionName", regionName); From 7de30cc57b5f9ad895e865736550c8d7a433ce55 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Oct 2010 22:58:04 +0100 Subject: [PATCH 05/11] Change substring matching to prefix matching in region search. This affects both map and login, as they use the same method. --- OpenSim/Services/GridService/GridService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index ce6f64b422..e7988d6e93 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -323,7 +323,7 @@ namespace OpenSim.Services.GridService { m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); - List rdatas = m_Database.Get("%" + name + "%", scopeID); + List rdatas = m_Database.Get(name + "%", scopeID); int count = 0; List rinfos = new List(); From 5b29b975ee6ae01e9cd9ba2f821122d0ea519da0 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 19 Oct 2010 00:51:04 +0100 Subject: [PATCH 06/11] Comment a spammy debug message in the serializer --- .../Framework/Scenes/Serialization/SceneObjectSerializer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 252304b876..ef012d53eb 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -1438,7 +1438,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization p(item, reader); else { - m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element in TaskInventory {0}, {1}", reader.Name, reader.Value); +// m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element in TaskInventory {0}, {1}", reader.Name, reader.Value); reader.ReadOuterXml(); } } From 43a4b7b735f1663fbbb0b74addf82e576b9e5042 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 19 Oct 2010 01:22:31 +0100 Subject: [PATCH 07/11] COmmented the wrong line instead, now I commented them all to be on the safe side --- .../Framework/Scenes/Serialization/SceneObjectSerializer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index ef012d53eb..7b94a8131a 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -1363,7 +1363,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } else { - m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element {0}", nodeName); +// m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element {0}", nodeName); reader.ReadOuterXml(); // ignore } @@ -1467,7 +1467,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization p(shape, reader); else { - m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element in Shape {0}", reader.Name); +// m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element in Shape {0}", reader.Name); reader.ReadOuterXml(); } } From b9bef50852cecab6e6fba75d44d4ee2306072299 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 18 Oct 2010 23:21:34 +0100 Subject: [PATCH 08/11] Display more information when xmlrpcgroupsserver comms fails Improve debugging messages --- .../XmlRpcGroups/GroupsMessagingModule.cs | 17 +++++++++-------- .../XmlRpcGroupsServicesConnectorModule.cs | 10 +++++----- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 185d44de80..d178e183c4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -212,12 +212,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { + List groupMembers = m_groupData.GetGroupMembers(UUID.Zero, groupID); + if (m_debugEnabled) - m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - - foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) - { + m_log.DebugFormat( + "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} members", + groupID, groupMembers.Count); + + foreach (GroupMembersData member in groupMembers) + { if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) { // Don't deliver messages to people who have dropped this session @@ -263,9 +266,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void OnClientLogin(IClientAPI client) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); - - + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); } private void OnNewClient(IClientAPI client) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 5fabbb03dd..2631ac10d3 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -641,11 +641,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; - } - - public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); @@ -988,8 +985,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } catch (Exception e) { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", e.ToString()); + m_log.ErrorFormat( + "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}", + function, m_groupsServerURI); + + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}{1}", e.Message, e.StackTrace); foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) { From 478b44f231841aafb2ea19d2b21d0d3826456ad7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 19 Oct 2010 01:54:51 +0100 Subject: [PATCH 09/11] Pass in requesting agent ID when GetGroupMembers is called in the XMLRPC groups module This allows the groups xmlrpc server to act appropriately if the requesting agent has permission to see all group members Not sure why this wasn't being done before... --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 4 ++-- .../OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index d178e183c4..25dba7f45e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -212,11 +212,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { - List groupMembers = m_groupData.GetGroupMembers(UUID.Zero, groupID); + List groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); if (m_debugEnabled) m_log.DebugFormat( - "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} members", + "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", groupID, groupMembers.Count); foreach (GroupMembersData member in groupMembers) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 6f044e0086..0c8113e604 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -599,7 +599,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: GroupMembersRequest called for {0} from client {1}", groupID, remoteClient.Name); + List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); if (m_debugEnabled) From 37a6be7ca9938ae4d3828f277b78f623fa84c9e1 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 19 Oct 2010 02:20:47 +0100 Subject: [PATCH 10/11] Stop the InventoryTransferModule logging every IM notification it receives, even if they are nothing to do with it. --- .../Avatar/Inventory/Transfer/InventoryTransferModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index d1274e9cf1..e3d49692f3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -159,9 +159,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { - m_log.DebugFormat( - "[INVENTORY TRANSFER]: {0} IM type received from {1}", - (InstantMessageDialog)im.dialog, client.Name); +// m_log.DebugFormat( +// "[INVENTORY TRANSFER]: {0} IM type received from {1}", +// (InstantMessageDialog)im.dialog, client.Name); Scene scene = FindClientScene(client.AgentId); From e561070d3f273048fc52ea1961a38d3f5d6803e2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 19 Oct 2010 02:28:10 +0100 Subject: [PATCH 11/11] Add 'contributors' notice for zlib.net.dll to keep track of its origin and version. Dahlia, please correct the details if they're wrong. --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 24432446c8..38343a4bbc 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -167,6 +167,7 @@ This software uses components from the following developers: * GlynnTucker.Cache (http://gtcache.sourceforge.net/) * NDesk.Options 0.2.1 (http://www.ndesk.org/Options) * Json.NET 3.5 Release 6. The binary used is actually Newtonsoft.Json.Net20.dll for Mono 2.4 compatability (http://james.newtonking.com/projects/json-net.aspx) +* zlib.net for C# 1.0.4 (http://www.componentace.com/zlib_.NET.htm) Some plugins are based on Cable Beach Cable Beach is Copyright (c) 2008 Intel Corporation