aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorUbitUmarov2016-12-25 05:51:08 +0000
committerUbitUmarov2016-12-25 05:51:08 +0000
commit1b95ada105f3a9a78b493412deb204a2a1d10745 (patch)
tree1882b1d1c637d4fd63f33e409c634cf0315ffcc2 /OpenSim/Region
parentMerge branch 'master' into httptests (diff)
parentFloatSamCache: dont use slideexpire on current libovm expirecache. Change exa... (diff)
downloadopensim-SC-1b95ada105f3a9a78b493412deb204a2a1d10745.zip
opensim-SC-1b95ada105f3a9a78b493412deb204a2a1d10745.tar.gz
opensim-SC-1b95ada105f3a9a78b493412deb204a2a1d10745.tar.bz2
opensim-SC-1b95ada105f3a9a78b493412deb204a2a1d10745.tar.xz
Merge branch 'master' into httptests
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs75
-rw-r--r--OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs96
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs13
4 files changed, 139 insertions, 50 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 9413598..b6dd565 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -62,7 +62,8 @@ namespace OpenSim.Region.CoreModules.Asset
62 MethodBase.GetCurrentMethod().DeclaringType); 62 MethodBase.GetCurrentMethod().DeclaringType);
63 63
64 private bool m_Enabled; 64 private bool m_Enabled;
65 private bool m_Running; 65 private bool m_timerRunning;
66 private bool m_cleanupRunning;
66 67
67 private const string m_ModuleName = "FlotsamAssetCache"; 68 private const string m_ModuleName = "FlotsamAssetCache";
68 private const string m_DefaultCacheDirectory = "./assetcache"; 69 private const string m_DefaultCacheDirectory = "./assetcache";
@@ -91,9 +92,8 @@ namespace OpenSim.Region.CoreModules.Asset
91 private bool m_MemoryCacheEnabled = false; 92 private bool m_MemoryCacheEnabled = false;
92 93
93 // Expiration is expressed in hours. 94 // Expiration is expressed in hours.
94 private const double m_DefaultMemoryExpiration = 2; 95 private double m_MemoryExpiration = 0.001;
95 private const double m_DefaultFileExpiration = 48; 96 private const double m_DefaultFileExpiration = 48;
96 private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration);
97 private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); 97 private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
98 private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0); 98 private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0);
99 99
@@ -150,7 +150,8 @@ namespace OpenSim.Region.CoreModules.Asset
150 m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); 150 m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
151 151
152 m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled); 152 m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled);
153 m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration)); 153 m_MemoryExpiration = assetConfig.GetDouble("MemoryCacheTimeout", m_MemoryExpiration);
154 m_MemoryExpiration *= 3600.0; // config in hours to seconds
154 155
155 #if WAIT_ON_INPROGRESS_REQUESTS 156 #if WAIT_ON_INPROGRESS_REQUESTS
156 m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000); 157 m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
@@ -224,9 +225,9 @@ namespace OpenSim.Region.CoreModules.Asset
224 m_Scenes.Remove(scene); 225 m_Scenes.Remove(scene);
225 lock(timerLock) 226 lock(timerLock)
226 { 227 {
227 if(m_Running && m_Scenes.Count <= 0) 228 if(m_timerRunning && m_Scenes.Count <= 0)
228 { 229 {
229 m_Running = false; 230 m_timerRunning = false;
230 m_CacheCleanTimer.Stop(); 231 m_CacheCleanTimer.Stop();
231 m_CacheCleanTimer.Close(); 232 m_CacheCleanTimer.Close();
232 } 233 }
@@ -242,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Asset
242 m_AssetService = scene.RequestModuleInterface<IAssetService>(); 243 m_AssetService = scene.RequestModuleInterface<IAssetService>();
243 lock(timerLock) 244 lock(timerLock)
244 { 245 {
245 if(!m_Running) 246 if(!m_timerRunning)
246 { 247 {
247 if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero)) 248 if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
248 { 249 {
@@ -250,7 +251,7 @@ namespace OpenSim.Region.CoreModules.Asset
250 m_CacheCleanTimer.AutoReset = false; 251 m_CacheCleanTimer.AutoReset = false;
251 m_CacheCleanTimer.Elapsed += CleanupExpiredFiles; 252 m_CacheCleanTimer.Elapsed += CleanupExpiredFiles;
252 m_CacheCleanTimer.Start(); 253 m_CacheCleanTimer.Start();
253 m_Running = true; 254 m_timerRunning = true;
254 } 255 }
255 } 256 }
256 } 257 }
@@ -263,6 +264,7 @@ namespace OpenSim.Region.CoreModules.Asset
263 264
264 private void UpdateMemoryCache(string key, AssetBase asset) 265 private void UpdateMemoryCache(string key, AssetBase asset)
265 { 266 {
267 // NOTE DO NOT USE SLIDEEXPIRE option on current libomv
266 m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration); 268 m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
267 } 269 }
268 270
@@ -480,12 +482,10 @@ namespace OpenSim.Region.CoreModules.Asset
480 asset = GetFromMemoryCache(id); 482 asset = GetFromMemoryCache(id);
481 483
482 if (asset == null && m_FileCacheEnabled) 484 if (asset == null && m_FileCacheEnabled)
483 {
484 asset = GetFromFileCache(id); 485 asset = GetFromFileCache(id);
485 486
486 if (m_MemoryCacheEnabled && asset != null) 487 if (m_MemoryCacheEnabled && asset != null)
487 UpdateMemoryCache(id, asset); 488 UpdateMemoryCache(id, asset);
488 }
489 489
490 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) 490 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
491 { 491 {
@@ -561,8 +561,12 @@ namespace OpenSim.Region.CoreModules.Asset
561 if (m_LogLevel >= 2) 561 if (m_LogLevel >= 2)
562 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration); 562 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration);
563 563
564 if(!m_Running) 564 lock(timerLock)
565 return; 565 {
566 if(!m_timerRunning || m_cleanupRunning)
567 return;
568 m_cleanupRunning = true;
569 }
566 // Purge all files last accessed prior to this point 570 // Purge all files last accessed prior to this point
567 DateTime purgeLine = DateTime.Now - m_FileExpiration; 571 DateTime purgeLine = DateTime.Now - m_FileExpiration;
568 572
@@ -578,8 +582,9 @@ namespace OpenSim.Region.CoreModules.Asset
578 582
579 lock(timerLock) 583 lock(timerLock)
580 { 584 {
581 if(m_Running) 585 if(m_timerRunning)
582 m_CacheCleanTimer.Start(); 586 m_CacheCleanTimer.Start();
587 m_cleanupRunning = false;
583 } 588 }
584 } 589 }
585 590
@@ -816,13 +821,13 @@ namespace OpenSim.Region.CoreModules.Asset
816 821
817 s.ForEachSOG(delegate(SceneObjectGroup e) 822 s.ForEachSOG(delegate(SceneObjectGroup e)
818 { 823 {
819 if(!m_Running && !storeUncached) 824 if(!m_timerRunning && !storeUncached)
820 return; 825 return;
821 826
822 gatherer.AddForInspection(e); 827 gatherer.AddForInspection(e);
823 gatherer.GatherAll(); 828 gatherer.GatherAll();
824 829
825 if(!m_Running && !storeUncached) 830 if(!m_timerRunning && !storeUncached)
826 return; 831 return;
827 832
828 foreach (UUID assetID in gatherer.GatheredUuids.Keys) 833 foreach (UUID assetID in gatherer.GatheredUuids.Keys)
@@ -854,13 +859,13 @@ namespace OpenSim.Region.CoreModules.Asset
854 } 859 }
855 860
856 gatherer.GatheredUuids.Clear(); 861 gatherer.GatheredUuids.Clear();
857 if(!m_Running && !storeUncached) 862 if(!m_timerRunning && !storeUncached)
858 return; 863 return;
859 864
860 if(!storeUncached) 865 if(!storeUncached)
861 Thread.Sleep(50); 866 Thread.Sleep(50);
862 }); 867 });
863 if(!m_Running && !storeUncached) 868 if(!m_timerRunning && !storeUncached)
864 break; 869 break;
865 } 870 }
866 871
@@ -905,16 +910,23 @@ namespace OpenSim.Region.CoreModules.Asset
905 { 910 {
906 List<string> outputLines = new List<string>(); 911 List<string> outputLines = new List<string>();
907 912
908 double fileHitRate = (double)m_DiskHits / m_Requests * 100.0; 913 double invReq = 100.0 / m_Requests;
914
915 double fileHitRate = m_DiskHits * invReq;
909 outputLines.Add( 916 outputLines.Add(
910 string.Format("File Hit Rate: {0}% for {1} requests", fileHitRate.ToString("0.00"), m_Requests)); 917 string.Format("File Hit Rate: {0}% for {1} requests", fileHitRate.ToString("0.00"), m_Requests));
911 918
912 if (m_MemoryCacheEnabled) 919 if (m_MemoryCacheEnabled)
913 { 920 {
914 double memHitRate = (double)m_MemoryHits / m_Requests * 100.0; 921 double HitRate = m_MemoryHits * invReq;
922
923 outputLines.Add(
924 string.Format("Memory Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests));
925
926 HitRate += fileHitRate;
915 927
916 outputLines.Add( 928 outputLines.Add(
917 string.Format("Memory Hit Rate: {0}% for {1} requests", memHitRate.ToString("0.00"), m_Requests)); 929 string.Format("Total Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests));
918 } 930 }
919 931
920 outputLines.Add( 932 outputLines.Add(
@@ -1019,17 +1031,27 @@ namespace OpenSim.Region.CoreModules.Asset
1019 break; 1031 break;
1020 1032
1021 case "assets": 1033 case "assets":
1022 con.Output("Ensuring assets are cached for all scenes."); 1034 lock(timerLock)
1035 {
1036 if(m_cleanupRunning)
1037 {
1038 con.OutputFormat("FloatSam assets check already running");
1039 return;
1040 }
1041 m_cleanupRunning = true;
1042 }
1043
1044 con.Output("FloatSam Ensuring assets are cached for all scenes.");
1023 1045
1024 WorkManager.RunInThread(delegate 1046 WorkManager.RunInThread(delegate
1025 { 1047 {
1026 bool wasRunning= false; 1048 bool wasRunning= false;
1027 lock(timerLock) 1049 lock(timerLock)
1028 { 1050 {
1029 if(m_Running) 1051 if(m_timerRunning)
1030 { 1052 {
1031 m_CacheCleanTimer.Stop(); 1053 m_CacheCleanTimer.Stop();
1032 m_Running = false; 1054 m_timerRunning = false;
1033 wasRunning = true; 1055 wasRunning = true;
1034 Thread.Sleep(100); 1056 Thread.Sleep(100);
1035 } 1057 }
@@ -1041,8 +1063,9 @@ namespace OpenSim.Region.CoreModules.Asset
1041 if(wasRunning) 1063 if(wasRunning)
1042 { 1064 {
1043 m_CacheCleanTimer.Start(); 1065 m_CacheCleanTimer.Start();
1044 m_Running = true; 1066 m_timerRunning = true;
1045 } 1067 }
1068 m_cleanupRunning = false;
1046 } 1069 }
1047 con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); 1070 con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal);
1048 }, null, "TouchAllSceneAssets"); 1071 }, null, "TouchAllSceneAssets");
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
index d232d82..3f7a8ee 100644
--- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
@@ -897,20 +897,36 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
897 else 897 else
898 { 898 {
899 // we have a proxy on map 899 // we have a proxy on map
900 // this is a fail on large regions 900 ulong oriHandle;
901 uint gtmp = (uint)globalPos.X >> 8; 901 uint oriX;
902 globalPos.X -= (gtmp << 8); 902 uint oriY;
903 globalPos.X += target.RegionLocX; 903 if(Util.ParseFakeParcelID(pick.ParcelId, out oriHandle, out oriX, out oriY))
904 904 {
905 gtmp = (uint)globalPos.Y >> 8; 905 pick.ParcelId = Util.BuildFakeParcelID(target.RegionHandle, oriX, oriY);
906 globalPos.Y -= (gtmp << 8); 906 globalPos.X = target.RegionLocX + oriX;
907 globalPos.Y += target.RegionLocY; 907 globalPos.Y = target.RegionLocY + oriY;
908 pick.GlobalPos = globalPos.ToString();
909 }
910 else
911 {
912 // this is a fail on large regions
913 uint gtmp = (uint)globalPos.X >> 8;
914 globalPos.X -= (gtmp << 8);
915
916 gtmp = (uint)globalPos.Y >> 8;
917 globalPos.Y -= (gtmp << 8);
918
919 pick.ParcelId = Util.BuildFakeParcelID(target.RegionHandle, (uint)globalPos.X, (uint)globalPos.Y);
920
921 globalPos.X += target.RegionLocX;
922 globalPos.Y += target.RegionLocY;
923 pick.GlobalPos = globalPos.ToString();
924 }
908 } 925 }
909 } 926 }
910 927
911 m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString()); 928 m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString());
912 929
913 pick.GlobalPos = globalPos.ToString();
914 lock(m_profilesCache) 930 lock(m_profilesCache)
915 { 931 {
916 if(!m_profilesCache.TryGetValue(targetID, out uce) || uce == null) 932 if(!m_profilesCache.TryGetValue(targetID, out uce) || uce == null)
@@ -1331,17 +1347,36 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1331 if(uce.props != null) 1347 if(uce.props != null)
1332 { 1348 {
1333 props = uce.props; 1349 props = uce.props;
1350 uint cflags = uce.flags;
1351 // if on same region force online
1352 if(p != null && !p.IsDeleted)
1353 cflags |= 0x10;
1354
1334 remoteClient.SendAvatarProperties(props.UserId, props.AboutText, 1355 remoteClient.SendAvatarProperties(props.UserId, props.AboutText,
1335 uce.born, uce.membershipType , props.FirstLifeText, uce.flags, 1356 uce.born, uce.membershipType , props.FirstLifeText, cflags,
1336 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); 1357 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId);
1337 1358
1338
1339 remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, 1359 remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask,
1340 props.WantToText, (uint)props.SkillsMask, 1360 props.WantToText, (uint)props.SkillsMask,
1341 props.SkillsText, props.Language); 1361 props.SkillsText, props.Language);
1342 return; 1362 return;
1363 }
1364 else
1365 {
1366 if(uce.ClientsWaitingProps == null)
1367 uce.ClientsWaitingProps = new HashSet<IClientAPI>();
1368 else if(uce.ClientsWaitingProps.Contains(remoteClient))
1369 return;
1370 uce.ClientsWaitingProps.Add(remoteClient);
1343 } 1371 }
1344 } 1372 }
1373 else
1374 {
1375 uce = new UserProfileCacheEntry();
1376 uce.ClientsWaitingProps = new HashSet<IClientAPI>();
1377 uce.ClientsWaitingProps.Add(remoteClient);
1378 m_profilesCache.AddOrUpdate(avatarID, uce, PROFILECACHEEXPIRE);
1379 }
1345 } 1380 }
1346 1381
1347 string serverURI = string.Empty; 1382 string serverURI = string.Empty;
@@ -1402,14 +1437,11 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1402 { 1437 {
1403 props.AboutText ="Profile not available at this time. User may still be unknown to this grid"; 1438 props.AboutText ="Profile not available at this time. User may still be unknown to this grid";
1404 } 1439 }
1405
1406 // if on same region force online
1407 if(p != null && !p.IsDeleted)
1408 flags |= 0x10;
1409 1440
1410 if(!m_allowUserProfileWebURLs) 1441 if(!m_allowUserProfileWebURLs)
1411 props.WebUrl =""; 1442 props.WebUrl ="";
1412 1443
1444 HashSet<IClientAPI> clients;
1413 lock(m_profilesCache) 1445 lock(m_profilesCache)
1414 { 1446 {
1415 if(!m_profilesCache.TryGetValue(props.UserId, out uce) || uce == null) 1447 if(!m_profilesCache.TryGetValue(props.UserId, out uce) || uce == null)
@@ -1418,15 +1450,39 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
1418 uce.born = born; 1450 uce.born = born;
1419 uce.membershipType = membershipType; 1451 uce.membershipType = membershipType;
1420 uce.flags = flags; 1452 uce.flags = flags;
1421 1453 clients = uce.ClientsWaitingProps;
1454 uce.ClientsWaitingProps = null;
1422 m_profilesCache.AddOrUpdate(props.UserId, uce, PROFILECACHEEXPIRE); 1455 m_profilesCache.AddOrUpdate(props.UserId, uce, PROFILECACHEEXPIRE);
1423 } 1456 }
1424 1457
1425 remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, membershipType , props.FirstLifeText, flags, 1458 // if on same region force online
1459 if(p != null && !p.IsDeleted)
1460 flags |= 0x10;
1461
1462 if(clients == null)
1463 {
1464 remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, membershipType , props.FirstLifeText, flags,
1426 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); 1465 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId);
1427 1466
1428 remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask, 1467 remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText,
1429 props.SkillsText, props.Language); 1468 (uint)props.SkillsMask, props.SkillsText, props.Language);
1469 }
1470 else
1471 {
1472 if(!clients.Contains(remoteClient))
1473 clients.Add(remoteClient);
1474 foreach(IClientAPI cli in clients)
1475 {
1476 if(!cli.IsActive)
1477 continue;
1478 cli.SendAvatarProperties(props.UserId, props.AboutText, born, membershipType , props.FirstLifeText, flags,
1479 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId);
1480
1481 cli.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText,
1482 (uint)props.SkillsMask, props.SkillsText, props.Language);
1483
1484 }
1485 }
1430 } 1486 }
1431 1487
1432 /// <summary> 1488 /// <summary>
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index bec5322..22bc49e 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -1880,8 +1880,9 @@ namespace OpenSim.Region.CoreModules.World.Land
1880 UUID.TryParse(id, out parcel); 1880 UUID.TryParse(id, out parcel);
1881 // assume we've got the parcelID we just computed in RemoteParcelRequest 1881 // assume we've got the parcelID we just computed in RemoteParcelRequest
1882 ExtendedLandData extLandData = new ExtendedLandData(); 1882 ExtendedLandData extLandData = new ExtendedLandData();
1883 Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle, 1883 if(!Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle,
1884 out extLandData.X, out extLandData.Y); 1884 out extLandData.X, out extLandData.Y))
1885 return null;
1885 m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelinfo request for regionHandle {0}, x/y {1}/{2}", 1886 m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelinfo request for regionHandle {0}, x/y {1}/{2}",
1886 extLandData.RegionHandle, extLandData.X, extLandData.Y); 1887 extLandData.RegionHandle, extLandData.X, extLandData.Y);
1887 1888
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 5638f01..ba5a46d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -310,7 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
310 foreach (string id in ids) 310 foreach (string id in ids)
311 { 311 {
312 string current = id.Trim(); 312 string current = id.Trim();
313 if (current.ToUpper() == "PARCEL_GROUP_MEMBER" || current.ToUpper() == "PARCEL_OWNER" || current.ToUpper() == "ESTATE_MANAGER" || current.ToUpper() == "ESTATE_OWNER" || current.ToUpper() == "GRID_GOD") 313 if (current.ToUpper() == "PARCEL_GROUP_MEMBER" || current.ToUpper() == "PARCEL_OWNER" || current.ToUpper() == "ESTATE_MANAGER" || current.ToUpper() == "ESTATE_OWNER" || current.ToUpper() == "GOD" || current.ToUpper() == "GRID_GOD")
314 { 314 {
315 if (!perms.AllowedOwnerClasses.Contains(current)) 315 if (!perms.AllowedOwnerClasses.Contains(current))
316 perms.AllowedOwnerClasses.Add(current.ToUpper()); 316 perms.AllowedOwnerClasses.Add(current.ToUpper());
@@ -416,9 +416,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
416 } 416 }
417 417
418 //Only gods may use the function 418 //Only gods may use the function
419 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("GOD"))
420 {
421 if (World.Permissions.IsGod(ownerID))
422 {
423 return String.Empty;
424 }
425 }
426
427 //Only grid gods may use the function
419 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("GRID_GOD")) 428 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("GRID_GOD"))
420 { 429 {
421 if (World.Permissions.IsGridGod(ownerID)) 430 if (World.Permissions.IsGridGod(ownerID))
422 { 431 {
423 return String.Empty; 432 return String.Empty;
424 } 433 }