aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs16
-rw-r--r--OpenSim/Data/PGSQL/PGSQLFSAssetData.cs316
-rw-r--r--OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations14
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs73
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs4
7 files changed, 383 insertions, 48 deletions
diff --git a/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs b/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs
index 5340bcd..d8164e7 100644
--- a/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs
+++ b/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs
@@ -114,7 +114,6 @@ namespace OpenSim.OfflineIM
114 scene.ForEachClient(delegate(IClientAPI client) 114 scene.ForEachClient(delegate(IClientAPI client)
115 { 115 {
116 client.OnRetrieveInstantMessages -= RetrieveInstantMessages; 116 client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
117 client.OnMuteListRequest -= OnMuteListRequest;
118 }); 117 });
119 } 118 }
120 119
@@ -162,7 +161,6 @@ namespace OpenSim.OfflineIM
162 private void OnNewClient(IClientAPI client) 161 private void OnNewClient(IClientAPI client)
163 { 162 {
164 client.OnRetrieveInstantMessages += RetrieveInstantMessages; 163 client.OnRetrieveInstantMessages += RetrieveInstantMessages;
165 client.OnMuteListRequest += OnMuteListRequest;
166 } 164 }
167 165
168 private void RetrieveInstantMessages(IClientAPI client) 166 private void RetrieveInstantMessages(IClientAPI client)
@@ -194,20 +192,6 @@ namespace OpenSim.OfflineIM
194 } 192 }
195 } 193 }
196 194
197 // Apparently this is needed in order for the viewer to request the IMs.
198 private void OnMuteListRequest(IClientAPI client, uint crc)
199 {
200 m_log.DebugFormat("[OfflineIM.V2] Got mute list request for crc {0}", crc);
201 string filename = "mutes" + client.AgentId.ToString();
202
203 IXfer xfer = client.Scene.RequestModuleInterface<IXfer>();
204 if (xfer != null)
205 {
206 xfer.AddNewFile(filename, new Byte[0]);
207 client.SendMuteListUpdate(filename);
208 }
209 }
210
211 private void UndeliveredMessage(GridInstantMessage im) 195 private void UndeliveredMessage(GridInstantMessage im)
212 { 196 {
213 if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && 197 if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
diff --git a/OpenSim/Data/PGSQL/PGSQLFSAssetData.cs b/OpenSim/Data/PGSQL/PGSQLFSAssetData.cs
new file mode 100644
index 0000000..59b857c
--- /dev/null
+++ b/OpenSim/Data/PGSQL/PGSQLFSAssetData.cs
@@ -0,0 +1,316 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections.Generic;
31using System.Data;
32using OpenSim.Framework;
33using OpenSim.Framework.Console;
34using log4net;
35using OpenMetaverse;
36using Npgsql;
37using NpgsqlTypes;
38
39namespace OpenSim.Data.PGSQL
40{
41 public class PGSQLFSAssetData : IFSAssetDataPlugin
42 {
43 private const string _migrationStore = "FSAssetStore";
44 private static string m_Table = "fsassets";
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 private long m_ticksToEpoch;
47
48 private PGSQLManager m_database;
49 private string m_connectionString;
50
51 public PGSQLFSAssetData()
52 {
53 }
54
55 public void Initialise(string connect, string realm, int UpdateAccessTime)
56 {
57 DaysBetweenAccessTimeUpdates = UpdateAccessTime;
58
59 m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks;
60
61 m_connectionString = connect;
62 m_database = new PGSQLManager(m_connectionString);
63
64 //New migration to check for DB changes
65 m_database.CheckMigration(_migrationStore);
66 }
67
68 public void Initialise()
69 {
70 throw new NotImplementedException();
71 }
72
73 /// <summary>
74 /// Number of days that must pass before we update the access time on an asset when it has been fetched
75 /// Config option to change this is "DaysBetweenAccessTimeUpdates"
76 /// </summary>
77 private int DaysBetweenAccessTimeUpdates = 0;
78
79 protected virtual Assembly Assembly
80 {
81 get { return GetType().Assembly; }
82 }
83
84 #region IPlugin Members
85
86 public string Version { get { return "1.0.0.0"; } }
87
88 public void Dispose() { }
89
90 public string Name
91 {
92 get { return "PGSQL FSAsset storage engine"; }
93 }
94
95 #endregion
96
97 #region IFSAssetDataPlugin Members
98
99 public AssetMetadata Get(string id, out string hash)
100 {
101 hash = String.Empty;
102 AssetMetadata meta = null;
103 UUID uuid = new UUID(id);
104
105 string query = String.Format("select \"id\", \"type\", \"hash\", \"create_time\", \"access_time\", \"asset_flags\" from {0} where \"id\" = :id", m_Table);
106 using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
107 using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
108 {
109 dbcon.Open();
110 cmd.Parameters.Add(m_database.CreateParameter("id", uuid));
111 using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
112 {
113 if (reader.Read())
114 {
115 meta = new AssetMetadata();
116 hash = reader["hash"].ToString();
117 meta.ID = id;
118 meta.FullID = uuid;
119 meta.Name = String.Empty;
120 meta.Description = String.Empty;
121 meta.Type = (sbyte)Convert.ToInt32(reader["type"]);
122 meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
123 meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
124 meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]);
125 int atime = Convert.ToInt32(reader["access_time"]);
126 UpdateAccessTime(atime, uuid);
127 }
128 }
129 }
130
131 return meta;
132 }
133
134 private void UpdateAccessTime(int AccessTime, UUID id)
135 {
136 // Reduce DB work by only updating access time if asset hasn't recently been accessed
137 // 0 By Default, Config option is "DaysBetweenAccessTimeUpdates"
138 if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
139 return;
140
141 string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table);
142 using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
143 using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
144 {
145 dbcon.Open();
146 int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
147 cmd.Parameters.Add(m_database.CreateParameter("id", id));
148 cmd.Parameters.Add(m_database.CreateParameter("access_time", now));
149 cmd.ExecuteNonQuery();
150 }
151 }
152
153 public bool Store(AssetMetadata meta, string hash)
154 {
155 try
156 {
157 bool found = false;
158 string oldhash;
159 AssetMetadata existingAsset = Get(meta.ID, out oldhash);
160
161 string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table);
162 if (existingAsset == null)
163 {
164 query = String.Format("insert into {0} (\"id\", \"type\", \"hash\", \"asset_flags\", \"create_time\", \"access_time\") values ( :id, :type, :hash, :asset_flags, :create_time, :access_time)", m_Table);
165 found = true;
166 }
167
168 using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
169 using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
170 {
171 dbcon.Open();
172 int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
173 cmd.Parameters.Add(m_database.CreateParameter("id", meta.FullID));
174 cmd.Parameters.Add(m_database.CreateParameter("type", meta.Type));
175 cmd.Parameters.Add(m_database.CreateParameter("hash", hash));
176 cmd.Parameters.Add(m_database.CreateParameter("asset_flags", Convert.ToInt32(meta.Flags)));
177 cmd.Parameters.Add(m_database.CreateParameter("create_time", now));
178 cmd.Parameters.Add(m_database.CreateParameter("access_time", now));
179 cmd.ExecuteNonQuery();
180 }
181 return found;
182 }
183 catch(Exception e)
184 {
185 m_log.Error("[PGSQL FSASSETS] Failed to store asset with ID " + meta.ID);
186 m_log.Error(e.ToString());
187 return false;
188 }
189 }
190
191 /// <summary>
192 /// Check if the assets exist in the database.
193 /// </summary>
194 /// <param name="uuids">The asset UUID's</param>
195 /// <returns>For each asset: true if it exists, false otherwise</returns>
196 public bool[] AssetsExist(UUID[] uuids)
197 {
198 if (uuids.Length == 0)
199 return new bool[0];
200
201 HashSet<UUID> exists = new HashSet<UUID>();
202
203 string ids = "'" + string.Join("','", uuids) + "'";
204 string query = string.Format("select \"id\" from {1} where id in ({0})", ids, m_Table);
205 using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
206 using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
207 {
208 dbcon.Open();
209 using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
210 {
211 while (reader.Read())
212 {
213 UUID id = DBGuid.FromDB(reader["id"]);;
214 exists.Add(id);
215 }
216 }
217 }
218
219 bool[] results = new bool[uuids.Length];
220 for (int i = 0; i < uuids.Length; i++)
221 results[i] = exists.Contains(uuids[i]);
222 return results;
223 }
224
225 public int Count()
226 {
227 int count = 0;
228 string query = String.Format("select count(*) as count from {0}", m_Table);
229 using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
230 using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
231 {
232 dbcon.Open();
233 IDataReader reader = cmd.ExecuteReader();
234 reader.Read();
235 count = Convert.ToInt32(reader["count"]);
236 reader.Close();
237 }
238
239 return count;
240 }
241
242 public bool Delete(string id)
243 {
244 string query = String.Format("delete from {0} where \"id\" = :id", m_Table);
245 using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
246 using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
247 {
248 dbcon.Open();
249 cmd.Parameters.Add(m_database.CreateParameter("id", new UUID(id)));
250 cmd.ExecuteNonQuery();
251 }
252
253 return true;
254 }
255
256 public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store)
257 {
258 int imported = 0;
259 string limit = String.Empty;
260 if(count != -1)
261 {
262 limit = String.Format(" limit {0} offset {1}", start, count);
263 }
264 string query = String.Format("select * from {0}{1}", table, limit);
265 try
266 {
267 using (NpgsqlConnection remote = new NpgsqlConnection(conn))
268 using (NpgsqlCommand cmd = new NpgsqlCommand(query, remote))
269 {
270 remote.Open();
271 MainConsole.Instance.Output("Querying database");
272 MainConsole.Instance.Output("Reading data");
273 using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
274 {
275 while (reader.Read())
276 {
277 if ((imported % 100) == 0)
278 {
279 MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported));
280 }
281
282 AssetBase asset = new AssetBase();
283 AssetMetadata meta = new AssetMetadata();
284
285 meta.ID = reader["id"].ToString();
286 meta.FullID = new UUID(meta.ID);
287
288 meta.Name = String.Empty;
289 meta.Description = String.Empty;
290 meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]);
291 meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
292 meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
293
294 asset.Metadata = meta;
295 asset.Data = (byte[])reader["data"];
296
297 store(asset, force);
298
299 imported++;
300 }
301 }
302 }
303 }
304 catch (Exception e)
305 {
306 m_log.ErrorFormat("[PGSQL FSASSETS]: Error importing assets: {0}",
307 e.Message.ToString());
308 return;
309 }
310
311 MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported));
312 }
313
314 #endregion
315 }
316}
diff --git a/OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations b/OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations
new file mode 100644
index 0000000..3a072e5
--- /dev/null
+++ b/OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations
@@ -0,0 +1,14 @@
1:VERSION 1
2
3BEGIN TRANSACTION;
4
5CREATE TABLE fsassets (
6 "id" uuid NOT NULL PRIMARY KEY,
7 "type" integer NOT NULL,
8 "hash" char(64) NOT NULL,
9 "create_time" integer NOT NULL DEFAULT '0',
10 "access_time" integer NOT NULL DEFAULT '0',
11 "asset_flags" integer NOT NULL DEFAULT '0'
12);
13
14COMMIT;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 057ca17..f29cdf4 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1209,10 +1209,10 @@ namespace OpenSim.Region.Framework.Scenes
1209 1209
1210 if (group.GetInventoryItem(localID, itemID) != null) 1210 if (group.GetInventoryItem(localID, itemID) != null)
1211 { 1211 {
1212 if (item.Type == 10) 1212 if (item.Type == (int)InventoryType.LSL)
1213 { 1213 {
1214 part.RemoveScriptEvents(itemID); 1214 part.RemoveScriptEvents(itemID);
1215 EventManager.TriggerRemoveScript(localID, itemID); 1215 part.ParentGroup.AddActiveScriptCount(-1);
1216 } 1216 }
1217 1217
1218 group.RemoveInventoryItem(localID, itemID); 1218 group.RemoveInventoryItem(localID, itemID);
@@ -1317,7 +1317,7 @@ namespace OpenSim.Region.Framework.Scenes
1317 if (taskItem.Type == (int)AssetType.LSLText) 1317 if (taskItem.Type == (int)AssetType.LSLText)
1318 { 1318 {
1319 part.RemoveScriptEvents(itemId); 1319 part.RemoveScriptEvents(itemId);
1320 EventManager.TriggerRemoveScript(part.LocalId, itemId); 1320 part.ParentGroup.AddActiveScriptCount(-1);
1321 } 1321 }
1322 1322
1323 part.Inventory.RemoveInventoryItem(itemId); 1323 part.Inventory.RemoveInventoryItem(itemId);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index f778367..bf217a5 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -358,7 +358,7 @@ namespace OpenSim.Region.Framework.Scenes
358 SceneObjectPart part = parts[i]; 358 SceneObjectPart part = parts[i];
359 359
360 if(m_DeepEffectivePermsInvalid) 360 if(m_DeepEffectivePermsInvalid)
361 part.AggregateInnerPerms(); 361 part.AggregatedInnerPermsForGroup();
362 362
363 owner &= part.AggregatedInnerOwnerPerms; 363 owner &= part.AggregatedInnerOwnerPerms;
364 group &= part.AggregatedInnerGroupPerms; 364 group &= part.AggregatedInnerGroupPerms;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 7bde7c0..532263a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2579,8 +2579,30 @@ namespace OpenSim.Region.Framework.Scenes
2579 AggregatedInnerOwnerPerms = owner & mask; 2579 AggregatedInnerOwnerPerms = owner & mask;
2580 AggregatedInnerGroupPerms = group & mask; 2580 AggregatedInnerGroupPerms = group & mask;
2581 AggregatedInnerEveryonePerms = everyone & mask; 2581 AggregatedInnerEveryonePerms = everyone & mask;
2582 if(ParentGroup != null) 2582 }
2583 ParentGroup.InvalidateEffectivePerms(); 2583 if(ParentGroup != null)
2584 ParentGroup.InvalidateEffectivePerms();
2585 }
2586
2587 // same as above but called during group Effective Permission validation
2588 public void AggregatedInnerPermsForGroup()
2589 {
2590 // assuming child prims permissions masks are irrelevant on a linkset
2591 // root part is handle at SOG since its masks are the sog masks
2592 const uint mask = (uint)PermissionMask.AllEffective;
2593
2594 uint owner = mask;
2595 uint group = mask;
2596 uint everyone = mask;
2597
2598 lock(InnerPermsLock) // do we really need this?
2599 {
2600 if(Inventory != null)
2601 Inventory.AggregateInnerPerms(ref owner, ref group, ref everyone);
2602
2603 AggregatedInnerOwnerPerms = owner & mask;
2604 AggregatedInnerGroupPerms = group & mask;
2605 AggregatedInnerEveryonePerms = everyone & mask;
2584 } 2606 }
2585 } 2607 }
2586 2608
@@ -3817,7 +3839,8 @@ namespace OpenSim.Region.Framework.Scenes
3817 Byte[] buf = Shape.Textures.GetBytes(); 3839 Byte[] buf = Shape.Textures.GetBytes();
3818 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); 3840 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
3819 Color4 texcolor; 3841 Color4 texcolor;
3820 if (face >= 0 && face < GetNumberOfSides()) 3842 int nsides = GetNumberOfSides();
3843 if (face >= 0 && face < nsides)
3821 { 3844 {
3822 texcolor = tex.CreateFace((uint)face).RGBA; 3845 texcolor = tex.CreateFace((uint)face).RGBA;
3823 texcolor.R = clippedColor.X; 3846 texcolor.R = clippedColor.X;
@@ -3833,7 +3856,7 @@ namespace OpenSim.Region.Framework.Scenes
3833 } 3856 }
3834 else if (face == ALL_SIDES) 3857 else if (face == ALL_SIDES)
3835 { 3858 {
3836 for (uint i = 0; i < GetNumberOfSides(); i++) 3859 for (uint i = 0; i < nsides; i++)
3837 { 3860 {
3838 if (tex.FaceTextures[i] != null) 3861 if (tex.FaceTextures[i] != null)
3839 { 3862 {
@@ -5138,20 +5161,20 @@ namespace OpenSim.Region.Framework.Scenes
5138 5161
5139 Changed changeFlags = 0; 5162 Changed changeFlags = 0;
5140 5163
5141 Primitive.TextureEntryFace fallbackNewFace = newTex.DefaultTexture; 5164 Primitive.TextureEntryFace defaultNewFace = newTex.DefaultTexture;
5142 Primitive.TextureEntryFace fallbackOldFace = oldTex.DefaultTexture; 5165 Primitive.TextureEntryFace defaultOldFace = oldTex.DefaultTexture;
5143 5166
5144 // On Incoming packets, sometimes newText.DefaultTexture is null. The assumption is that all 5167 // On Incoming packets, sometimes newText.DefaultTexture is null. The assumption is that all
5145 // other prim-sides are set, but apparently that's not always the case. Lets assume packet/data corruption at this point. 5168 // other prim-sides are set, but apparently that's not always the case. Lets assume packet/data corruption at this point.
5146 if (fallbackNewFace == null) 5169 if (defaultNewFace == null)
5147 { 5170 {
5148 fallbackNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); 5171 defaultNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
5149 newTex.DefaultTexture = fallbackNewFace; 5172 newTex.DefaultTexture = defaultNewFace;
5150 } 5173 }
5151 if (fallbackOldFace == null) 5174 if (defaultOldFace == null)
5152 { 5175 {
5153 fallbackOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); 5176 defaultOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
5154 oldTex.DefaultTexture = fallbackOldFace; 5177 oldTex.DefaultTexture = defaultOldFace;
5155 } 5178 }
5156 5179
5157 // Materials capable viewers can send a ObjectImage packet 5180 // Materials capable viewers can send a ObjectImage packet
@@ -5161,13 +5184,11 @@ namespace OpenSim.Region.Framework.Scenes
5161 // we should ignore any changes and not update Shape.TextureEntry 5184 // we should ignore any changes and not update Shape.TextureEntry
5162 5185
5163 bool otherFieldsChanged = false; 5186 bool otherFieldsChanged = false;
5164 5187 int nsides = GetNumberOfSides();
5165 for (int i = 0 ; i < GetNumberOfSides(); i++) 5188 for (int i = 0 ; i < nsides; i++)
5166 { 5189 {
5167 5190 Primitive.TextureEntryFace newFace = defaultNewFace;
5168 Primitive.TextureEntryFace newFace = newTex.DefaultTexture; 5191 Primitive.TextureEntryFace oldFace = defaultOldFace;
5169 Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture;
5170
5171 if (oldTex.FaceTextures[i] != null) 5192 if (oldTex.FaceTextures[i] != null)
5172 oldFace = oldTex.FaceTextures[i]; 5193 oldFace = oldTex.FaceTextures[i];
5173 if (newTex.FaceTextures[i] != null) 5194 if (newTex.FaceTextures[i] != null)
@@ -5202,17 +5223,17 @@ namespace OpenSim.Region.Framework.Scenes
5202 if (oldFace.Rotation != newFace.Rotation) otherFieldsChanged = true; 5223 if (oldFace.Rotation != newFace.Rotation) otherFieldsChanged = true;
5203 if (oldFace.Shiny != newFace.Shiny) otherFieldsChanged = true; 5224 if (oldFace.Shiny != newFace.Shiny) otherFieldsChanged = true;
5204 if (oldFace.TexMapType != newFace.TexMapType) otherFieldsChanged = true; 5225 if (oldFace.TexMapType != newFace.TexMapType) otherFieldsChanged = true;
5226 if(otherFieldsChanged)
5227 changeFlags |= Changed.TEXTURE;
5205 } 5228 }
5206 } 5229 }
5207 5230
5208 if (changeFlags != 0 || otherFieldsChanged) 5231 if (changeFlags == 0)
5209 { 5232 return;
5210 m_shape.TextureEntry = newTex.GetBytes(); 5233 m_shape.TextureEntry = newTex.GetBytes();
5211 if (changeFlags != 0) 5234 TriggerScriptChangedEvent(changeFlags);
5212 TriggerScriptChangedEvent(changeFlags); 5235 ParentGroup.HasGroupChanged = true;
5213 ParentGroup.HasGroupChanged = true; 5236 ScheduleFullUpdate();
5214 ScheduleFullUpdate();
5215 }
5216 } 5237 }
5217 5238
5218 internal void UpdatePhysicsSubscribedEvents() 5239 internal void UpdatePhysicsSubscribedEvents()
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index d8f2b80..b22bda0 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -1081,7 +1081,7 @@ namespace OpenSim.Region.Framework.Scenes
1081 { 1081 {
1082 int type = m_items[itemID].InvType; 1082 int type = m_items[itemID].InvType;
1083 m_items.LockItemsForRead(false); 1083 m_items.LockItemsForRead(false);
1084 if (type == 10) // Script 1084 if (type == (int)InventoryType.LSL) // Script
1085 { 1085 {
1086 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 1086 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
1087 } 1087 }
@@ -1101,7 +1101,7 @@ namespace OpenSim.Region.Framework.Scenes
1101 m_items.LockItemsForRead(true); 1101 m_items.LockItemsForRead(true);
1102 foreach (TaskInventoryItem item in m_items.Values) 1102 foreach (TaskInventoryItem item in m_items.Values)
1103 { 1103 {
1104 if (item.Type == 10) 1104 if (item.Type == (int)InventoryType.LSL)
1105 { 1105 {
1106 scriptcount++; 1106 scriptcount++;
1107 } 1107 }