aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2011-06-09 02:05:04 +0100
committerMelanie2011-06-09 02:05:04 +0100
commit326c46ba70cea70ddfe4aef9a6b73edff63e126a (patch)
tree5e76347b0d77f58717d8e5e4f3b8787ff01a18d7 /OpenSim/Region
parentMake the last otem in a list created with llCSV2List findable (diff)
parentConsistency fix on the last commit. (diff)
downloadopensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.zip
opensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.gz
opensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.bz2
opensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.xz
Merge branch 'master' into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/Application.cs4
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs45
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs355
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs628
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs350
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs82
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs244
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs15
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs173
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs35
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs57
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs34
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs84
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs112
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs25
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs23
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs41
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs83
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs3
-rw-r--r--OpenSim/Region/Framework/Interfaces/IFriendsModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserManagement.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs48
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs402
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs30
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs110
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs32
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs161
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs139
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs756
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs193
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs366
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs206
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs375
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs163
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs317
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs167
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs94
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs270
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs104
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/README52
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs216
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs92
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs3
53 files changed, 2708 insertions, 4095 deletions
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index 7e320e6..3b261e7 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -231,6 +231,8 @@ namespace OpenSim
231 configSource.Alias.AddAlias("Off", false); 231 configSource.Alias.AddAlias("Off", false);
232 configSource.Alias.AddAlias("True", true); 232 configSource.Alias.AddAlias("True", true);
233 configSource.Alias.AddAlias("False", false); 233 configSource.Alias.AddAlias("False", false);
234 configSource.Alias.AddAlias("Yes", true);
235 configSource.Alias.AddAlias("No", false);
234 236
235 configSource.AddSwitch("Startup", "background"); 237 configSource.AddSwitch("Startup", "background");
236 configSource.AddSwitch("Startup", "inifile"); 238 configSource.AddSwitch("Startup", "inifile");
@@ -239,6 +241,8 @@ namespace OpenSim
239 configSource.AddSwitch("Startup", "physics"); 241 configSource.AddSwitch("Startup", "physics");
240 configSource.AddSwitch("Startup", "gui"); 242 configSource.AddSwitch("Startup", "gui");
241 configSource.AddSwitch("Startup", "console"); 243 configSource.AddSwitch("Startup", "console");
244 configSource.AddSwitch("Startup", "save_crashes");
245 configSource.AddSwitch("Startup", "crash_dir");
242 246
243 configSource.AddConfig("StandAlone"); 247 configSource.AddConfig("StandAlone");
244 configSource.AddConfig("Network"); 248 configSource.AddConfig("Network");
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 503123e..04a68ae 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -918,7 +918,7 @@ namespace OpenSim
918 918
919 if (regInfo.EstateSettings.EstateID == 0) // No record at all 919 if (regInfo.EstateSettings.EstateID == 0) // No record at all
920 { 920 {
921 MainConsole.Instance.OutputFormat("Region {0} is not part of an estate.", regInfo.RegionName); 921 m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
922 922
923 List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll(); 923 List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
924 List<string> estateNames = new List<string>(); 924 List<string> estateNames = new List<string>();
@@ -929,7 +929,7 @@ namespace OpenSim
929 { 929 {
930 if (estates.Count == 0) 930 if (estates.Count == 0)
931 { 931 {
932 MainConsole.Instance.Output("No existing estates found. You must create a new one."); 932 m_log.Info("[ESTATE] No existing estates found. You must create a new one.");
933 933
934 if (CreateEstate(regInfo, estateNames)) 934 if (CreateEstate(regInfo, estateNames))
935 break; 935 break;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 05e6d27..eed8878 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -1476,6 +1476,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1476 money.MoneyData.TransactionSuccess = success; 1476 money.MoneyData.TransactionSuccess = success;
1477 money.MoneyData.Description = description; 1477 money.MoneyData.Description = description;
1478 money.MoneyData.MoneyBalance = balance; 1478 money.MoneyData.MoneyBalance = balance;
1479 money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE");
1479 OutPacket(money, ThrottleOutPacketType.Task); 1480 OutPacket(money, ThrottleOutPacketType.Task);
1480 } 1481 }
1481 1482
@@ -2231,7 +2232,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2231 OutPacket(loadURL, ThrottleOutPacketType.Task); 2232 OutPacket(loadURL, ThrottleOutPacketType.Task);
2232 } 2233 }
2233 2234
2234 public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) 2235 public void SendDialog(
2236 string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg,
2237 UUID textureID, int ch, string[] buttonlabels)
2235 { 2238 {
2236 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); 2239 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
2237 dialog.Data.ObjectID = objectID; 2240 dialog.Data.ObjectID = objectID;
@@ -2249,6 +2252,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2249 buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]); 2252 buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
2250 } 2253 }
2251 dialog.Buttons = buttons; 2254 dialog.Buttons = buttons;
2255
2256 dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
2257 dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
2258 dialog.OwnerData[0].OwnerID = ownerID;
2259
2252 OutPacket(dialog, ThrottleOutPacketType.Task); 2260 OutPacket(dialog, ThrottleOutPacketType.Task);
2253 } 2261 }
2254 2262
@@ -2320,8 +2328,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2320 OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff; 2328 OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff;
2321 } 2329 }
2322 2330
2323
2324
2325 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage); 2331 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
2326 viewertime.TimeInfo.SunDirection = Position; 2332 viewertime.TimeInfo.SunDirection = Position;
2327 viewertime.TimeInfo.SunAngVelocity = Velocity; 2333 viewertime.TimeInfo.SunAngVelocity = Velocity;
@@ -8358,16 +8364,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8358 AssetLandmark lm; 8364 AssetLandmark lm;
8359 if (lmid != UUID.Zero) 8365 if (lmid != UUID.Zero)
8360 { 8366 {
8367
8361 //AssetBase lma = m_assetCache.GetAsset(lmid, false); 8368 //AssetBase lma = m_assetCache.GetAsset(lmid, false);
8362 AssetBase lma = m_assetService.Get(lmid.ToString()); 8369 AssetBase lma = m_assetService.Get(lmid.ToString());
8363 8370
8364 if (lma == null) 8371 if (lma == null)
8365 { 8372 {
8366 // Failed to find landmark 8373 // Failed to find landmark
8367 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel); 8374
8368 tpCancel.Info.SessionID = tpReq.Info.SessionID; 8375 // Let's try to search in the user's home asset server
8369 tpCancel.Info.AgentID = tpReq.Info.AgentID; 8376 lma = FindAssetInUserAssetServer(lmid.ToString());
8370 OutPacket(tpCancel, ThrottleOutPacketType.Task); 8377
8378 if (lma == null)
8379 {
8380 // Really doesn't exist
8381 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
8382 tpCancel.Info.SessionID = tpReq.Info.SessionID;
8383 tpCancel.Info.AgentID = tpReq.Info.AgentID;
8384 OutPacket(tpCancel, ThrottleOutPacketType.Task);
8385 }
8371 } 8386 }
8372 8387
8373 try 8388 try
@@ -8398,13 +8413,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8398 TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; 8413 TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest;
8399 if (handlerTeleportLandmarkRequest != null) 8414 if (handlerTeleportLandmarkRequest != null)
8400 { 8415 {
8401 handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position); 8416 handlerTeleportLandmarkRequest(this, lm);
8402 } 8417 }
8403 else 8418 else
8404 { 8419 {
8405 //no event handler so cancel request 8420 //no event handler so cancel request
8406
8407
8408 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel); 8421 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
8409 tpCancel.Info.AgentID = tpReq.Info.AgentID; 8422 tpCancel.Info.AgentID = tpReq.Info.AgentID;
8410 tpCancel.Info.SessionID = tpReq.Info.SessionID; 8423 tpCancel.Info.SessionID = tpReq.Info.SessionID;
@@ -8414,6 +8427,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8414 return true; 8427 return true;
8415 } 8428 }
8416 8429
8430 private AssetBase FindAssetInUserAssetServer(string id)
8431 {
8432 AgentCircuitData aCircuit = ((Scene)Scene).AuthenticateHandler.GetAgentCircuitData(CircuitCode);
8433 if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
8434 {
8435 string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString();
8436 return ((Scene)Scene).AssetService.Get(assetServer + "/" + id);
8437 }
8438
8439 return null;
8440 }
8441
8417 private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack) 8442 private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack)
8418 { 8443 {
8419 TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack; 8444 TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index ded8743..8a16582 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -124,7 +124,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
124 124
125 ScenePresence sp = m_scene.GetScenePresence(avatarID); 125 ScenePresence sp = m_scene.GetScenePresence(avatarID);
126 if (sp != null) 126 if (sp != null)
127 sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); 127 sp.ControllingClient.SendDialog(
128 objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
128 } 129 }
129 130
130 public void SendUrlToUser( 131 public void SendUrlToUser(
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 0cd05e3..c8167c5 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
49{ 49{
50 public class FriendsModule : ISharedRegionModule, IFriendsModule 50 public class FriendsModule : ISharedRegionModule, IFriendsModule
51 { 51 {
52 protected bool m_Enabled = false;
53
52 protected class UserFriendData 54 protected class UserFriendData
53 { 55 {
54 public UUID PrincipalID; 56 public UUID PrincipalID;
@@ -67,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
67 } 69 }
68 } 70 }
69 71
70 private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; 72 protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
71 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 73 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
72 74
73 protected List<Scene> m_Scenes = new List<Scene>(); 75 protected List<Scene> m_Scenes = new List<Scene>();
@@ -130,8 +132,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
130 } 132 }
131 } 133 }
132 134
135 #region ISharedRegionModule
133 public void Initialise(IConfigSource config) 136 public void Initialise(IConfigSource config)
134 { 137 {
138 IConfig moduleConfig = config.Configs["Modules"];
139 if (moduleConfig != null)
140 {
141 string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
142 if (name == Name)
143 {
144 InitModule(config);
145
146 m_Enabled = true;
147 m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
148 }
149 }
150 }
151
152 protected void InitModule(IConfigSource config)
153 {
135 IConfig friendsConfig = config.Configs["Friends"]; 154 IConfig friendsConfig = config.Configs["Friends"];
136 if (friendsConfig != null) 155 if (friendsConfig != null)
137 { 156 {
@@ -153,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
153 m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue"); 172 m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
154 throw new Exception("Connector load error"); 173 throw new Exception("Connector load error");
155 } 174 }
156
157 } 175 }
158 176
159 public void PostInitialise() 177 public void PostInitialise()
@@ -164,8 +182,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
164 { 182 {
165 } 183 }
166 184
167 public void AddRegion(Scene scene) 185 public virtual void AddRegion(Scene scene)
168 { 186 {
187 if (!m_Enabled)
188 return;
189 m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
190
169 m_Scenes.Add(scene); 191 m_Scenes.Add(scene);
170 scene.RegisterModuleInterface<IFriendsModule>(this); 192 scene.RegisterModuleInterface<IFriendsModule>(this);
171 193
@@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
181 203
182 public void RemoveRegion(Scene scene) 204 public void RemoveRegion(Scene scene)
183 { 205 {
206 if (!m_Enabled)
207 return;
208
184 m_Scenes.Remove(scene); 209 m_Scenes.Remove(scene);
185 } 210 }
186 211
187 public string Name 212 public virtual string Name
188 { 213 {
189 get { return "FriendsModule"; } 214 get { return "FriendsModule"; }
190 } 215 }
@@ -194,13 +219,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
194 get { return null; } 219 get { return null; }
195 } 220 }
196 221
197 public uint GetFriendPerms(UUID principalID, UUID friendID) 222 #endregion
223
224 public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
198 { 225 {
199 FriendInfo[] friends = GetFriends(principalID); 226 FriendInfo[] friends = GetFriends(principalID);
200 foreach (FriendInfo fi in friends) 227 FriendInfo finfo = GetFriend(friends, friendID);
228 if (finfo != null)
201 { 229 {
202 if (fi.Friend == friendID.ToString()) 230 return (uint)finfo.TheirFlags;
203 return (uint)fi.TheirFlags;
204 } 231 }
205 232
206 return 0; 233 return 0;
@@ -214,30 +241,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
214 client.OnTerminateFriendship += OnTerminateFriendship; 241 client.OnTerminateFriendship += OnTerminateFriendship;
215 client.OnGrantUserRights += OnGrantUserRights; 242 client.OnGrantUserRights += OnGrantUserRights;
216 243
217 // Asynchronously fetch the friends list or increment the refcount for the existing 244 Util.FireAndForget(delegate { FetchFriendslist(client); });
218 // friends list 245 }
219 Util.FireAndForget( 246
220 delegate(object o) 247 /// Fetch the friends list or increment the refcount for the existing
248 /// friends list
249 /// Returns true if the list was fetched, false if it wasn't
250 protected virtual bool FetchFriendslist(IClientAPI client)
251 {
252 UUID agentID = client.AgentId;
253 lock (m_Friends)
254 {
255 UserFriendData friendsData;
256 if (m_Friends.TryGetValue(agentID, out friendsData))
221 { 257 {
222 lock (m_Friends) 258 friendsData.Refcount++;
223 { 259 return false;
224 UserFriendData friendsData; 260 }
225 if (m_Friends.TryGetValue(client.AgentId, out friendsData)) 261 else
226 { 262 {
227 friendsData.Refcount++; 263 friendsData = new UserFriendData();
228 } 264 friendsData.PrincipalID = agentID;
229 else 265 friendsData.Friends = GetFriendsFromService(client);
230 { 266 friendsData.Refcount = 1;
231 friendsData = new UserFriendData();
232 friendsData.PrincipalID = client.AgentId;
233 friendsData.Friends = FriendsService.GetFriends(client.AgentId);
234 friendsData.Refcount = 1;
235 267
236 m_Friends[client.AgentId] = friendsData; 268 m_Friends[agentID] = friendsData;
237 } 269 return true;
238 }
239 } 270 }
240 ); 271 }
241 } 272 }
242 273
243 private void OnClientClosed(UUID agentID, Scene scene) 274 private void OnClientClosed(UUID agentID, Scene scene)
@@ -263,14 +294,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
263 294
264 private void OnMakeRootAgent(ScenePresence sp) 295 private void OnMakeRootAgent(ScenePresence sp)
265 { 296 {
266 UUID agentID = sp.ControllingClient.AgentId; 297 RefetchFriends(sp.ControllingClient);
267 UpdateFriendsCache(agentID);
268 } 298 }
269 299
270 private void OnClientLogin(IClientAPI client) 300 private void OnClientLogin(IClientAPI client)
271 { 301 {
272 UUID agentID = client.AgentId; 302 UUID agentID = client.AgentId;
273 303
304 //m_log.DebugFormat("[XXX]: OnClientLogin!");
274 // Inform the friends that this user is online 305 // Inform the friends that this user is online
275 StatusChange(agentID, true); 306 StatusChange(agentID, true);
276 307
@@ -279,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
279 m_NeedsListOfFriends.Add(agentID); 310 m_NeedsListOfFriends.Add(agentID);
280 } 311 }
281 312
282 public void SendFriendsOnlineIfNeeded(IClientAPI client) 313 public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
283 { 314 {
284 UUID agentID = client.AgentId; 315 UUID agentID = client.AgentId;
285 316
@@ -287,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
287 lock (m_NeedsListOfFriends) 318 lock (m_NeedsListOfFriends)
288 { 319 {
289 if (!m_NeedsListOfFriends.Remove(agentID)) 320 if (!m_NeedsListOfFriends.Remove(agentID))
290 return; 321 return false;
291 } 322 }
292 323
293 // Send the friends online 324 // Send the friends online
@@ -313,10 +344,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
313 foreach (string fid in outstanding) 344 foreach (string fid in outstanding)
314 { 345 {
315 UUID fromAgentID; 346 UUID fromAgentID;
316 if (!UUID.TryParse(fid, out fromAgentID)) 347 string firstname = "Unknown", lastname = "User";
348 if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
349 {
350 m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
317 continue; 351 continue;
318 352 }
319 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
320 353
321 PresenceInfo presence = null; 354 PresenceInfo presence = null;
322 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); 355 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
@@ -326,13 +359,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
326 im.offline = 0; 359 im.offline = 0;
327 360
328 im.fromAgentID = fromAgentID.Guid; 361 im.fromAgentID = fromAgentID.Guid;
329 im.fromAgentName = account.FirstName + " " + account.LastName; 362 im.fromAgentName = firstname + " " + lastname;
330 im.offline = (byte)((presence == null) ? 1 : 0); 363 im.offline = (byte)((presence == null) ? 1 : 0);
331 im.imSessionID = im.fromAgentID; 364 im.imSessionID = im.fromAgentID;
365 im.message = FriendshipMessage(fid);
332 366
333 // Finally 367 // Finally
334 LocalFriendshipOffered(agentID, im); 368 LocalFriendshipOffered(agentID, im);
335 } 369 }
370
371 return true;
372 }
373
374 protected virtual string FriendshipMessage(string friendID)
375 {
376 return "Will you be my friend?";
377 }
378
379 protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
380 {
381 first = "Unknown"; last = "User";
382 if (!UUID.TryParse(fid, out agentID))
383 return false;
384
385 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID);
386 if (account != null)
387 {
388 first = account.FirstName;
389 last = account.LastName;
390 }
391
392 return true;
336 } 393 }
337 394
338 List<UUID> GetOnlineFriends(UUID userID) 395 List<UUID> GetOnlineFriends(UUID userID)
@@ -348,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
348 } 405 }
349 406
350 if (friendList.Count > 0) 407 if (friendList.Count > 0)
351 { 408 GetOnlineFriends(userID, friendList, online);
352 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
353 foreach (PresenceInfo pi in presence)
354 {
355 UUID presenceID;
356 if (UUID.TryParse(pi.UserID, out presenceID))
357 online.Add(presenceID);
358 }
359 }
360 409
361 return online; 410 return online;
362 } 411 }
363 412
413 protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
414 {
415 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
416 foreach (PresenceInfo pi in presence)
417 {
418 UUID presenceID;
419 if (UUID.TryParse(pi.UserID, out presenceID))
420 online.Add(presenceID);
421 }
422 }
423
364 /// <summary> 424 /// <summary>
365 /// Find the client for a ID 425 /// Find the client for a ID
366 /// </summary> 426 /// </summary>
@@ -415,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
415 Util.FireAndForget( 475 Util.FireAndForget(
416 delegate 476 delegate
417 { 477 {
418 foreach (FriendInfo fi in friendList) 478 m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
419 { 479 // Notify about this user status
420 //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID); 480 StatusNotify(friendList, agentID, online);
421 // Notify about this user status
422 StatusNotify(fi, agentID, online);
423 }
424 } 481 }
425 ); 482 );
426 } 483 }
427 } 484 }
428 485
429 private void StatusNotify(FriendInfo friend, UUID userID, bool online) 486 protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
430 { 487 {
431 UUID friendID; 488 foreach (FriendInfo friend in friendList)
432 if (UUID.TryParse(friend.Friend, out friendID))
433 { 489 {
434 // Try local 490 UUID friendID;
435 if (LocalStatusNotification(userID, friendID, online)) 491 if (UUID.TryParse(friend.Friend, out friendID))
436 return;
437
438 // The friend is not here [as root]. Let's forward.
439 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
440 if (friendSessions != null && friendSessions.Length > 0)
441 { 492 {
442 PresenceInfo friendSession = null; 493 // Try local
443 foreach (PresenceInfo pinfo in friendSessions) 494 if (LocalStatusNotification(userID, friendID, online))
444 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad 495 return;
445 {
446 friendSession = pinfo;
447 break;
448 }
449 496
450 if (friendSession != null) 497 // The friend is not here [as root]. Let's forward.
498 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
499 if (friendSessions != null && friendSessions.Length > 0)
451 { 500 {
452 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 501 PresenceInfo friendSession = null;
453 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); 502 foreach (PresenceInfo pinfo in friendSessions)
454 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); 503 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
504 {
505 friendSession = pinfo;
506 break;
507 }
508
509 if (friendSession != null)
510 {
511 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
512 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
513 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
514 }
455 } 515 }
456 }
457 516
458 // Friend is not online. Ignore. 517 // Friend is not online. Ignore.
459 } 518 }
460 else 519 else
461 { 520 {
462 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); 521 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
522 }
463 } 523 }
464 } 524 }
465 525
@@ -475,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
475 535
476 // This user wants to be friends with the other user. 536 // This user wants to be friends with the other user.
477 // Let's add the relation backwards, in case the other is not online 537 // Let's add the relation backwards, in case the other is not online
478 FriendsService.StoreFriend(friendID, principalID.ToString(), 0); 538 StoreBackwards(friendID, principalID);
479 539
480 // Now let's ask the other user to be friends with this user 540 // Now let's ask the other user to be friends with this user
481 ForwardFriendshipOffer(principalID, friendID, im); 541 ForwardFriendshipOffer(principalID, friendID, im);
@@ -487,11 +547,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
487 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) 547 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
488 // We stick this agent's ID as imSession, so that it's directly available on the receiving end 548 // We stick this agent's ID as imSession, so that it's directly available on the receiving end
489 im.imSessionID = im.fromAgentID; 549 im.imSessionID = im.fromAgentID;
550 im.fromAgentName = GetFriendshipRequesterName(agentID);
490 551
491 // Try the local sim 552 // Try the local sim
492 UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
493 im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
494
495 if (LocalFriendshipOffered(friendID, im)) 553 if (LocalFriendshipOffered(friendID, im))
496 return; 554 return;
497 555
@@ -509,12 +567,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
509 // If the prospective friend is not online, he'll get the message upon login. 567 // If the prospective friend is not online, he'll get the message upon login.
510 } 568 }
511 569
570 protected virtual string GetFriendshipRequesterName(UUID agentID)
571 {
572 UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
573 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
574 }
575
512 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) 576 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
513 { 577 {
514 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID); 578 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
515 579
516 FriendsService.StoreFriend(agentID, friendID.ToString(), 1); 580 StoreFriendships(agentID, friendID);
517 FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
518 581
519 ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>(); 582 ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
520 if (ccm != null) 583 if (ccm != null)
@@ -523,7 +586,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
523 } 586 }
524 587
525 // Update the local cache 588 // Update the local cache
526 UpdateFriendsCache(agentID); 589 RefetchFriends(client);
527 590
528 // 591 //
529 // Notify the friend 592 // Notify the friend
@@ -554,8 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
554 { 617 {
555 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); 618 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
556 619
557 FriendsService.Delete(agentID, friendID.ToString()); 620 DeleteFriendship(agentID, friendID);
558 FriendsService.Delete(friendID, agentID.ToString());
559 621
560 // 622 //
561 // Notify the friend 623 // Notify the friend
@@ -582,11 +644,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
582 644
583 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) 645 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
584 { 646 {
585 FriendsService.Delete(agentID, exfriendID.ToString()); 647 if (!DeleteFriendship(agentID, exfriendID))
586 FriendsService.Delete(exfriendID, agentID.ToString()); 648 client.SendAlertMessage("Unable to terminate friendship on this sim.");
587 649
588 // Update local cache 650 // Update local cache
589 UpdateFriendsCache(agentID); 651 RefetchFriends(client);
590 652
591 client.SendTerminateFriend(exfriendID); 653 client.SendTerminateFriend(exfriendID);
592 654
@@ -612,23 +674,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
612 674
613 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) 675 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
614 { 676 {
677 m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
678
615 FriendInfo[] friends = GetFriends(remoteClient.AgentId); 679 FriendInfo[] friends = GetFriends(remoteClient.AgentId);
616 if (friends.Length == 0) 680 if (friends.Length == 0)
681 {
617 return; 682 return;
683 }
618 684
619 m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
620 // Let's find the friend in this user's friend list 685 // Let's find the friend in this user's friend list
621 FriendInfo friend = null; 686 FriendInfo friend = GetFriend(friends, target);
622 foreach (FriendInfo fi in friends)
623 {
624 if (fi.Friend == target.ToString())
625 friend = fi;
626 }
627 687
628 if (friend != null) // Found it 688 if (friend != null) // Found it
629 { 689 {
630 // Store it on the DB 690 // Store it on the DB
631 FriendsService.StoreFriend(requester, target.ToString(), rights); 691 if (!StoreRights(requester, target, rights))
692 {
693 remoteClient.SendAlertMessage("Unable to grant rights.");
694 return;
695 }
632 696
633 // Store it in the local cache 697 // Store it in the local cache
634 int myFlags = friend.MyFlags; 698 int myFlags = friend.MyFlags;
@@ -658,6 +722,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
658 } 722 }
659 } 723 }
660 } 724 }
725 else
726 m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
727 }
728
729 protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
730 {
731 foreach (FriendInfo fi in friends)
732 {
733 if (fi.Friend == friendID.ToString())
734 return fi;
735 }
736 return null;
661 } 737 }
662 738
663 #region Local 739 #region Local
@@ -693,7 +769,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
693 769
694 770
695 // Update the local cache 771 // Update the local cache
696 UpdateFriendsCache(friendID); 772 RefetchFriends(friendClient);
697 773
698 // we're done 774 // we're done
699 return true; 775 return true;
@@ -726,7 +802,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
726 // the friend in this sim as root agent 802 // the friend in this sim as root agent
727 friendClient.SendTerminateFriend(exfriendID); 803 friendClient.SendTerminateFriend(exfriendID);
728 // update local cache 804 // update local cache
729 UpdateFriendsCache(exfriendID); 805 RefetchFriends(friendClient);
730 // we're done 806 // we're done
731 return true; 807 return true;
732 } 808 }
@@ -756,15 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
756 } 832 }
757 833
758 // Update local cache 834 // Update local cache
759 lock (m_Friends) 835 UpdateLocalCache(userID, friendID, rights);
760 {
761 FriendInfo[] friends = GetFriends(friendID);
762 foreach (FriendInfo finfo in friends)
763 {
764 if (finfo.Friend == userID.ToString())
765 finfo.TheirFlags = rights;
766 }
767 }
768 836
769 return true; 837 return true;
770 } 838 }
@@ -775,10 +843,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
775 843
776 public bool LocalStatusNotification(UUID userID, UUID friendID, bool online) 844 public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
777 { 845 {
846 m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
778 IClientAPI friendClient = LocateClientObject(friendID); 847 IClientAPI friendClient = LocateClientObject(friendID);
779 if (friendClient != null) 848 if (friendClient != null)
780 { 849 {
781 //m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
782 // the friend in this sim as root agent 850 // the friend in this sim as root agent
783 if (online) 851 if (online)
784 friendClient.SendAgentOnline(new UUID[] { userID }); 852 friendClient.SendAgentOnline(new UUID[] { userID });
@@ -793,7 +861,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
793 861
794 #endregion 862 #endregion
795 863
796 private FriendInfo[] GetFriends(UUID agentID) 864 #region Get / Set friends in several flavours
865 /// <summary>
866 /// Get friends from local cache only
867 /// </summary>
868 /// <param name="agentID"></param>
869 /// <returns></returns>
870 protected FriendInfo[] GetFriends(UUID agentID)
797 { 871 {
798 UserFriendData friendsData; 872 UserFriendData friendsData;
799 873
@@ -806,14 +880,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
806 return EMPTY_FRIENDS; 880 return EMPTY_FRIENDS;
807 } 881 }
808 882
809 private void UpdateFriendsCache(UUID agentID) 883 /// <summary>
884 /// Update loca cache only
885 /// </summary>
886 /// <param name="userID"></param>
887 /// <param name="friendID"></param>
888 /// <param name="rights"></param>
889 protected void UpdateLocalCache(UUID userID, UUID friendID, int rights)
890 {
891 // Update local cache
892 lock (m_Friends)
893 {
894 FriendInfo[] friends = GetFriends(friendID);
895 FriendInfo finfo = GetFriend(friends, userID);
896 finfo.TheirFlags = rights;
897 }
898 }
899
900 protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
901 {
902 return FriendsService.GetFriends(client.AgentId);
903 }
904
905 private void RefetchFriends(IClientAPI client)
810 { 906 {
907 UUID agentID = client.AgentId;
811 lock (m_Friends) 908 lock (m_Friends)
812 { 909 {
813 UserFriendData friendsData; 910 UserFriendData friendsData;
814 if (m_Friends.TryGetValue(agentID, out friendsData)) 911 if (m_Friends.TryGetValue(agentID, out friendsData))
815 friendsData.Friends = FriendsService.GetFriends(agentID); 912 friendsData.Friends = GetFriendsFromService(client);
816 } 913 }
817 } 914 }
915
916 protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
917 {
918 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
919 return true;
920 }
921
922 protected virtual void StoreBackwards(UUID friendID, UUID agentID)
923 {
924 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
925 }
926
927 protected virtual void StoreFriendships(UUID agentID, UUID friendID)
928 {
929 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
930 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
931 }
932
933 protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
934 {
935 FriendsService.Delete(agentID, exfriendID.ToString());
936 FriendsService.Delete(exfriendID, agentID.ToString());
937 return true;
938 }
939
940 #endregion
818 } 941 }
819} 942}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
new file mode 100644
index 0000000..b9d6719
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -0,0 +1,628 @@
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.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Nwc.XmlRpc;
35using Mono.Addins;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.Connectors.Hypergrid;
42using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
43using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
44using GridRegion = OpenSim.Services.Interfaces.GridRegion;
45
46namespace OpenSim.Region.CoreModules.Avatar.Friends
47{
48 public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 #region ISharedRegionModule
53 public override string Name
54 {
55 get { return "HGFriendsModule"; }
56 }
57
58 public override void AddRegion(Scene scene)
59 {
60 if (!m_Enabled)
61 return;
62
63 base.AddRegion(scene);
64 scene.RegisterModuleInterface<IFriendsSimConnector>(this);
65 }
66
67 #endregion
68
69 #region IFriendsSimConnector
70
71 /// <summary>
72 /// Notify the user that the friend's status changed
73 /// </summary>
74 /// <param name="userID">user to be notified</param>
75 /// <param name="friendID">friend whose status changed</param>
76 /// <param name="online">status</param>
77 /// <returns></returns>
78 public bool StatusNotify(UUID friendID, UUID userID, bool online)
79 {
80 return LocalStatusNotification(friendID, userID, online);
81 }
82
83 #endregion
84
85 protected override bool FetchFriendslist(IClientAPI client)
86 {
87 if (base.FetchFriendslist(client))
88 {
89 UUID agentID = client.AgentId;
90 // we do this only for the root agent
91 if (m_Friends[agentID].Refcount == 1)
92 {
93 // We need to preload the user management cache with the names
94 // of foreign friends, just like we do with SOPs' creators
95 foreach (FriendInfo finfo in m_Friends[agentID].Friends)
96 {
97 if (finfo.TheirFlags != -1)
98 {
99 UUID id;
100 if (!UUID.TryParse(finfo.Friend, out id))
101 {
102 string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
103 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
104 {
105 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
106 uMan.AddUser(id, url + ";" + first + " " + last);
107 }
108 }
109 }
110 }
111 return true;
112 }
113 }
114 return false;
115 }
116
117 public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
118 {
119 if (base.SendFriendsOnlineIfNeeded(client))
120 {
121 AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
122 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
123 {
124 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
125 if (account == null) // foreign
126 {
127 FriendInfo[] friends = GetFriends(client.AgentId);
128 foreach (FriendInfo f in friends)
129 {
130 client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
131 }
132 }
133 }
134 }
135 return false;
136 }
137
138 protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
139 {
140 List<string> fList = new List<string>();
141 foreach (string s in friendList)
142 fList.Add(s.Substring(0, 36));
143
144 PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
145 foreach (PresenceInfo pi in presence)
146 {
147 UUID presenceID;
148 if (UUID.TryParse(pi.UserID, out presenceID))
149 online.Add(presenceID);
150 }
151 }
152
153 //protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
154 //{
155 // // Let's single out the UUIs
156 // List<string> localFriends = new List<string>();
157 // List<string> foreignFriends = new List<string>();
158 // string tmp = string.Empty;
159
160 // foreach (string s in friendList)
161 // {
162 // UUID id;
163 // if (UUID.TryParse(s, out id))
164 // localFriends.Add(s);
165 // else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
166 // {
167 // foreignFriends.Add(s);
168 // // add it here too, who knows maybe the foreign friends happens to be on this grid
169 // localFriends.Add(id.ToString());
170 // }
171 // }
172
173 // // OK, see who's present on this grid
174 // List<string> toBeRemoved = new List<string>();
175 // PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
176 // foreach (PresenceInfo pi in presence)
177 // {
178 // UUID presenceID;
179 // if (UUID.TryParse(pi.UserID, out presenceID))
180 // {
181 // online.Add(presenceID);
182 // foreach (string s in foreignFriends)
183 // if (s.StartsWith(pi.UserID))
184 // toBeRemoved.Add(s);
185 // }
186 // }
187
188 // foreach (string s in toBeRemoved)
189 // foreignFriends.Remove(s);
190
191 // // OK, let's send this up the stack, and leave a closure here
192 // // collecting online friends in other grids
193 // Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
194
195 //}
196
197 private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
198 {
199 // let's divide the friends on a per-domain basis
200 Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
201 foreach (string friend in foreignFriends)
202 {
203 UUID friendID;
204 if (!UUID.TryParse(friend, out friendID))
205 {
206 // it's a foreign friend
207 string url = string.Empty, tmp = string.Empty;
208 if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
209 {
210 if (!friendsPerDomain.ContainsKey(url))
211 friendsPerDomain[url] = new List<string>();
212 friendsPerDomain[url].Add(friend);
213 }
214 }
215 }
216
217 // Now, call those worlds
218
219 foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
220 {
221 List<string> ids = new List<string>();
222 foreach (string f in kvp.Value)
223 ids.Add(f);
224 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
225 List<UUID> online = uConn.GetOnlineFriends(userID, ids);
226 // Finally send the notifications to the user
227 // this whole process may take a while, so let's check at every
228 // iteration that the user is still here
229 IClientAPI client = LocateClientObject(userID);
230 if (client != null)
231 client.SendAgentOnline(online.ToArray());
232 else
233 break;
234 }
235
236 }
237
238 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
239 {
240 // First, let's divide the friends on a per-domain basis
241 Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
242 foreach (FriendInfo friend in friendList)
243 {
244 UUID friendID;
245 if (UUID.TryParse(friend.Friend, out friendID))
246 {
247 if (!friendsPerDomain.ContainsKey("local"))
248 friendsPerDomain["local"] = new List<FriendInfo>();
249 friendsPerDomain["local"].Add(friend);
250 }
251 else
252 {
253 // it's a foreign friend
254 string url = string.Empty, tmp = string.Empty;
255 if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
256 {
257 // Let's try our luck in the local sim. Who knows, maybe it's here
258 if (LocalStatusNotification(userID, friendID, online))
259 continue;
260
261 if (!friendsPerDomain.ContainsKey(url))
262 friendsPerDomain[url] = new List<FriendInfo>();
263 friendsPerDomain[url].Add(friend);
264 }
265 }
266 }
267
268 // For the local friends, just call the base method
269 // Let's do this first of all
270 if (friendsPerDomain.ContainsKey("local"))
271 base.StatusNotify(friendsPerDomain["local"], userID, online);
272
273 foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
274 {
275 if (kvp.Key != "local")
276 {
277 // For the others, call the user agent service
278 List<string> ids = new List<string>();
279 foreach (FriendInfo f in kvp.Value)
280 ids.Add(f.Friend);
281 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
282 List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
283 // need to debug this here
284 if (online)
285 {
286 IClientAPI client = LocateClientObject(userID);
287 if (client != null)
288 client.SendAgentOnline(friendsOnline.ToArray());
289 }
290 }
291 }
292 }
293
294 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
295 {
296 first = "Unknown"; last = "User";
297 if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
298 return true;
299
300 // fid is not a UUID...
301 string url = string.Empty, tmp = string.Empty;
302 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
303 {
304 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
305 userMan.AddUser(agentID, url + ";" + first + " " + last);
306
307 try // our best
308 {
309 string[] parts = userMan.GetUserName(agentID).Split();
310 first = parts[0];
311 last = parts[1];
312 }
313 catch { }
314 return true;
315 }
316 return false;
317 }
318
319 protected override string GetFriendshipRequesterName(UUID agentID)
320 {
321 // For the time being we assume that HG friendship requests can only happen
322 // when avies are on the same region.
323 IClientAPI client = LocateClientObject(agentID);
324 if (client != null)
325 return client.FirstName + " " + client.LastName;
326 else
327 return base.GetFriendshipRequesterName(agentID);
328 }
329
330 protected override string FriendshipMessage(string friendID)
331 {
332 UUID id;
333 if (UUID.TryParse(friendID, out id))
334 return base.FriendshipMessage(friendID);
335
336 return "Please confirm this friendship you made while you were away.";
337 }
338
339 protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
340 {
341 foreach (FriendInfo fi in friends)
342 {
343 if (fi.Friend.StartsWith(friendID.ToString()))
344 return fi;
345 }
346 return null;
347 }
348
349
350 protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
351 {
352 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
353 if (account1 != null)
354 return base.GetFriendsFromService(client);
355
356 FriendInfo[] finfos = new FriendInfo[0];
357 // Foreigner
358 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
359 if (agentClientCircuit != null)
360 {
361 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
362
363 finfos = FriendsService.GetFriends(agentUUI);
364 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
365 }
366 return finfos;
367 }
368
369 protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
370 {
371 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
372 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
373 // Are they both local users?
374 if (account1 != null && account2 != null)
375 {
376 // local grid users
377 return base.StoreRights(agentID, friendID, rights);
378 }
379
380 if (account1 != null) // agent is local, friend is foreigner
381 {
382 FriendInfo[] finfos = GetFriends(agentID);
383 FriendInfo finfo = GetFriend(finfos, friendID);
384 if (finfo != null)
385 {
386 FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
387 return true;
388 }
389 }
390
391 if (account2 != null) // agent is foreigner, friend is local
392 {
393 string agentUUI = GetUUI(friendID, agentID);
394 if (agentUUI != string.Empty)
395 {
396 FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
397 return true;
398 }
399 }
400
401 return false;
402
403 }
404
405 protected override void StoreBackwards(UUID friendID, UUID agentID)
406 {
407 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
408 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
409 // Are they both local users?
410 if (account1 != null && account2 != null)
411 {
412 // local grid users
413 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
414 base.StoreBackwards(friendID, agentID);
415 return;
416 }
417
418 // no provision for this temporary friendship state
419 //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
420 }
421
422 protected override void StoreFriendships(UUID agentID, UUID friendID)
423 {
424 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
425 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
426 // Are they both local users?
427 if (agentAccount != null && friendAccount != null)
428 {
429 // local grid users
430 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
431 base.StoreFriendships(agentID, friendID);
432 return;
433 }
434
435 // ok, at least one of them is foreigner, let's get their data
436 IClientAPI agentClient = LocateClientObject(agentID);
437 IClientAPI friendClient = LocateClientObject(friendID);
438 AgentCircuitData agentClientCircuit = null;
439 AgentCircuitData friendClientCircuit = null;
440 string agentUUI = string.Empty;
441 string friendUUI = string.Empty;
442 string agentFriendService = string.Empty;
443 string friendFriendService = string.Empty;
444
445 if (agentClient != null)
446 {
447 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
448 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
449 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
450 }
451 if (friendClient != null)
452 {
453 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
454 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
455 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
456 }
457
458 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
459 agentUUI, friendUUI, agentFriendService, friendFriendService);
460
461 // Generate a random 8-character hex number that will sign this friendship
462 string secret = UUID.Random().ToString().Substring(0, 8);
463
464 if (agentAccount != null) // agent is local, 'friend' is foreigner
465 {
466 // This may happen when the agent returned home, in which case the friend is not there
467 // We need to look for its information in the friends list itself
468 bool confirming = false;
469 if (friendUUI == string.Empty)
470 {
471 FriendInfo[] finfos = GetFriends(agentID);
472 foreach (FriendInfo finfo in finfos)
473 {
474 if (finfo.TheirFlags == -1)
475 {
476 if (finfo.Friend.StartsWith(friendID.ToString()))
477 {
478 friendUUI = finfo.Friend;
479 confirming = true;
480 }
481 }
482 }
483 }
484
485 // If it's confirming the friendship, we already have the full friendUUI with the secret
486 string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
487
488 // store in the local friends service a reference to the foreign friend
489 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
490 // and also the converse
491 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
492
493 if (!confirming && friendClientCircuit != null)
494 {
495 // store in the foreign friends service a reference to the local agent
496 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
497 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
498 }
499 }
500 else if (friendAccount != null) // 'friend' is local, agent is foreigner
501 {
502 // store in the local friends service a reference to the foreign agent
503 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
504 // and also the converse
505 FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
506
507 if (agentClientCircuit != null)
508 {
509 // store in the foreign friends service a reference to the local agent
510 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
511 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
512 }
513 }
514 else // They're both foreigners!
515 {
516 HGFriendsServicesConnector friendsConn;
517 if (agentClientCircuit != null)
518 {
519 friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
520 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
521 }
522 if (friendClientCircuit != null)
523 {
524 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
525 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
526 }
527 }
528 // my brain hurts now
529 }
530
531 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
532 {
533 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
534 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
535 // Are they both local users?
536 if (agentAccount != null && friendAccount != null)
537 {
538 // local grid users
539 return base.DeleteFriendship(agentID, exfriendID);
540 }
541
542 // ok, at least one of them is foreigner, let's get their data
543 string agentUUI = string.Empty;
544 string friendUUI = string.Empty;
545
546 if (agentAccount != null) // agent is local, 'friend' is foreigner
547 {
548 // We need to look for its information in the friends list itself
549 FriendInfo[] finfos = GetFriends(agentID);
550 FriendInfo finfo = GetFriend(finfos, exfriendID);
551 if (finfo != null)
552 {
553 friendUUI = finfo.Friend;
554
555 // delete in the local friends service the reference to the foreign friend
556 FriendsService.Delete(agentID, friendUUI);
557 // and also the converse
558 FriendsService.Delete(friendUUI, agentID.ToString());
559
560 // notify the exfriend's service
561 Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
562
563 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
564 return true;
565 }
566 }
567 else if (friendAccount != null) // agent is foreigner, 'friend' is local
568 {
569 agentUUI = GetUUI(exfriendID, agentID);
570
571 if (agentUUI != string.Empty)
572 {
573 // delete in the local friends service the reference to the foreign agent
574 FriendsService.Delete(exfriendID, agentUUI);
575 // and also the converse
576 FriendsService.Delete(agentUUI, exfriendID.ToString());
577
578 // notify the agent's service?
579 Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
580
581 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
582 return true;
583 }
584 }
585 //else They're both foreigners! Can't handle this
586
587 return false;
588 }
589
590 private string GetUUI(UUID localUser, UUID foreignUser)
591 {
592 // Let's see if the user is here by any chance
593 FriendInfo[] finfos = GetFriends(localUser);
594 if (finfos != EMPTY_FRIENDS) // friend is here, cool
595 {
596 FriendInfo finfo = GetFriend(finfos, foreignUser);
597 if (finfo != null)
598 {
599 return finfo.Friend;
600 }
601 }
602 else // user is not currently on this sim, need to get from the service
603 {
604 finfos = FriendsService.GetFriends(localUser);
605 foreach (FriendInfo finfo in finfos)
606 {
607 if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
608 {
609 return finfo.Friend;
610 }
611 }
612 }
613 return string.Empty;
614 }
615
616 private void Delete(UUID foreignUser, UUID localUser, string uui)
617 {
618 UUID id;
619 string url = string.Empty, secret = string.Empty, tmp = string.Empty;
620 if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
621 {
622 m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
623 HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
624 friendConn.DeleteFriendship(foreignUser, localUser, secret);
625 }
626 }
627 }
628}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
new file mode 100644
index 0000000..7753c25
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
@@ -0,0 +1,350 @@
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 */
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Nwc.XmlRpc;
35using Mono.Addins;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
42using OpenSim.Services.Interfaces;
43using OpenSim.Services.Connectors.InstantMessage;
44using OpenSim.Services.Connectors.Hypergrid;
45using OpenSim.Server.Handlers.Hypergrid;
46
47namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
50 public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector
51 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 protected bool m_Enabled = false;
55 protected List<Scene> m_Scenes = new List<Scene>();
56
57 protected IInstantMessage m_IMService;
58 protected Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
59
60 public event UndeliveredMessage OnUndeliveredMessage;
61
62 IUserManagement m_uMan;
63 IUserManagement UserManagementModule
64 {
65 get
66 {
67 if (m_uMan == null)
68 m_uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
69 return m_uMan;
70 }
71 }
72
73 public virtual void Initialise(IConfigSource config)
74 {
75 IConfig cnf = config.Configs["Messaging"];
76 if (cnf != null && cnf.GetString(
77 "MessageTransferModule", "MessageTransferModule") != Name)
78 {
79 m_log.Debug("[HG MESSAGE TRANSFER]: Disabled by configuration");
80 return;
81 }
82
83 InstantMessageServerConnector imServer = new InstantMessageServerConnector(config, MainServer.Instance, this);
84 m_IMService = imServer.GetService();
85 m_Enabled = true;
86 }
87
88 public virtual void AddRegion(Scene scene)
89 {
90 if (!m_Enabled)
91 return;
92
93 lock (m_Scenes)
94 {
95 m_log.DebugFormat("[HG MESSAGE TRANSFER]: Message transfer module {0} active", Name);
96 scene.RegisterModuleInterface<IMessageTransferModule>(this);
97 m_Scenes.Add(scene);
98 }
99 }
100
101 public virtual void PostInitialise()
102 {
103 if (!m_Enabled)
104 return;
105
106 }
107
108 public virtual void RegionLoaded(Scene scene)
109 {
110 }
111
112 public virtual void RemoveRegion(Scene scene)
113 {
114 if (!m_Enabled)
115 return;
116
117 lock (m_Scenes)
118 {
119 m_Scenes.Remove(scene);
120 }
121 }
122
123 public virtual void Close()
124 {
125 }
126
127 public virtual string Name
128 {
129 get { return "HGMessageTransferModule"; }
130 }
131
132 public virtual Type ReplaceableInterface
133 {
134 get { return null; }
135 }
136
137 public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
138 {
139 UUID toAgentID = new UUID(im.toAgentID);
140
141 // Try root avatar only first
142 foreach (Scene scene in m_Scenes)
143 {
144 if (scene.Entities.ContainsKey(toAgentID) &&
145 scene.Entities[toAgentID] is ScenePresence)
146 {
147// m_log.DebugFormat(
148// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
149// toAgentID.ToString(), scene.RegionInfo.RegionName);
150
151 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
152 if (!user.IsChildAgent)
153 {
154 // Local message
155// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
156 user.ControllingClient.SendInstantMessage(im);
157
158 // Message sent
159 result(true);
160 return;
161 }
162 }
163 }
164
165 // try child avatar second
166 foreach (Scene scene in m_Scenes)
167 {
168// m_log.DebugFormat(
169// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
170
171 if (scene.Entities.ContainsKey(toAgentID) &&
172 scene.Entities[toAgentID] is ScenePresence)
173 {
174 // Local message
175 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
176
177// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
178 user.ControllingClient.SendInstantMessage(im);
179
180 // Message sent
181 result(true);
182 return;
183 }
184 }
185
186// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
187 // Is the user a local user?
188 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
189 string url = string.Empty;
190 bool foreigner = false;
191 if (account == null) // foreign user
192 {
193 url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI");
194 foreigner = true;
195 }
196
197 Util.FireAndForget(delegate
198 {
199 bool success = false;
200 if (foreigner && url == string.Empty) // we don't know about this user
201 {
202 string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID);
203 m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
204 if (recipientUUI != string.Empty)
205 {
206 UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty;
207 if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret))
208 {
209 success = m_IMService.OutgoingInstantMessage(im, u, true);
210 if (success)
211 UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last);
212 }
213 }
214 }
215 else
216 success = m_IMService.OutgoingInstantMessage(im, url, foreigner);
217
218 if (!success && !foreigner)
219 HandleUndeliveredMessage(im, result);
220 else
221 result(success);
222 });
223
224 return;
225 }
226
227 protected bool SendIMToScene(GridInstantMessage gim, UUID toAgentID)
228 {
229 bool successful = false;
230 foreach (Scene scene in m_Scenes)
231 {
232 if (scene.Entities.ContainsKey(toAgentID) &&
233 scene.Entities[toAgentID] is ScenePresence)
234 {
235 ScenePresence user =
236 (ScenePresence)scene.Entities[toAgentID];
237
238 if (!user.IsChildAgent)
239 {
240 scene.EventManager.TriggerIncomingInstantMessage(gim);
241 successful = true;
242 }
243 }
244 }
245 if (!successful)
246 {
247 // If the message can't be delivered to an agent, it
248 // is likely to be a group IM. On a group IM, the
249 // imSessionID = toAgentID = group id. Raise the
250 // unhandled IM event to give the groups module
251 // a chance to pick it up. We raise that in a random
252 // scene, since the groups module is shared.
253 //
254 m_Scenes[0].EventManager.TriggerUnhandledInstantMessage(gim);
255 }
256
257 return successful;
258 }
259
260 protected void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
261 {
262 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
263
264 // If this event has handlers, then an IM from an agent will be
265 // considered delivered. This will suppress the error message.
266 //
267 if (handlerUndeliveredMessage != null)
268 {
269 handlerUndeliveredMessage(im);
270 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
271 result(true);
272 else
273 result(false);
274 return;
275 }
276
277 //m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
278 result(false);
279 }
280
281 private string TryGetRecipientUUI(UUID fromAgent, UUID toAgent)
282 {
283 // Let's call back the fromAgent's user agent service
284 // Maybe that service knows about the toAgent
285 IClientAPI client = LocateClientObject(fromAgent);
286 if (client != null)
287 {
288 AgentCircuitData circuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.AgentId);
289 if (circuit != null)
290 {
291 if (circuit.ServiceURLs.ContainsKey("HomeURI"))
292 {
293 string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
294 m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
295 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
296 return uasConn.GetUUI(fromAgent, toAgent);
297 }
298 }
299 }
300
301 return string.Empty;
302 }
303
304
305 /// <summary>
306 /// Find the scene for an agent
307 /// </summary>
308 private Scene GetClientScene(UUID agentId)
309 {
310 lock (m_Scenes)
311 {
312 foreach (Scene scene in m_Scenes)
313 {
314 ScenePresence presence = scene.GetScenePresence(agentId);
315 if (presence != null && !presence.IsChildAgent)
316 return scene;
317 }
318 }
319
320 return null;
321 }
322
323 /// <summary>
324 /// Find the client for a ID
325 /// </summary>
326 public IClientAPI LocateClientObject(UUID agentID)
327 {
328 Scene scene = GetClientScene(agentID);
329 if (scene != null)
330 {
331 ScenePresence presence = scene.GetScenePresence(agentID);
332 if (presence != null)
333 return presence.ControllingClient;
334 }
335
336 return null;
337 }
338
339 #region IInstantMessageSimConnector
340 public bool SendInstantMessage(GridInstantMessage im)
341 {
342 //m_log.DebugFormat("[XXX] Hook SendInstantMessage {0}", im.message);
343 UUID agentID = new UUID(im.toAgentID);
344 return SendIMToScene(im, agentID);
345 }
346 #endregion
347
348
349 }
350}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index 47e34dc..0d90a15 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -149,14 +149,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
149 149
150 /// <summary> 150 /// <summary>
151 /// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder. 151 /// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder.
152 /// 152 /// </summary>
153 /// <remarks>
153 /// This method does not handle paths that contain multiple delimitors 154 /// This method does not handle paths that contain multiple delimitors
154 /// 155 ///
155 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some 156 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
156 /// XPath like expression 157 /// XPath like expression
157 /// 158 ///
158 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 159 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
159 /// </summary> 160 /// </remarks>
160 /// 161 ///
161 /// <param name="inventoryService"> 162 /// <param name="inventoryService">
162 /// Inventory service to query 163 /// Inventory service to query
@@ -178,32 +179,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
178 179
179 return FindItemByPath(inventoryService, rootFolder, path); 180 return FindItemByPath(inventoryService, rootFolder, path);
180 } 181 }
181 182
182 /// <summary> 183 /// <summary>
183 /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. 184 /// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
184 /// 185 /// </summary>
185 /// This method does not handle paths that contain multiple delimitors 186 /// <remarks>
187 /// This method does not handle paths that contain multiple delimiters
186 /// 188 ///
187 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some 189 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
188 /// XPath like expression 190 /// XPath like expression
189 /// 191 ///
190 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 192 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
191 /// </summary> 193 /// </remarks>
192 /// 194 ///
193 /// <param name="inventoryService"> 195 /// <param name="inventoryService">Inventory service to query</param>
194 /// Inventory service to query 196 /// <param name="startFolder">The folder from which the path starts</param>
195 /// </param> 197 /// <param name="path">The path to the required item.</param>
196 /// <param name="startFolder">
197 /// The folder from which the path starts
198 /// </param>
199 /// <param name="path">
200 /// <param name="path">
201 /// The path to the required item.
202 /// </param>
203 /// <returns>null if the item is not found</returns> 198 /// <returns>null if the item is not found</returns>
204 public static InventoryItemBase FindItemByPath( 199 public static InventoryItemBase FindItemByPath(
205 IInventoryService inventoryService, InventoryFolderBase startFolder, string path) 200 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
206 { 201 {
202 List<InventoryItemBase> foundItems = FindItemsByPath(inventoryService, startFolder, path);
203
204 if (foundItems.Count != 0)
205 return foundItems[0];
206 else
207 return null;
208 }
209
210 public static List<InventoryItemBase> FindItemsByPath(
211 IInventoryService inventoryService, UUID userId, string path)
212 {
213 InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
214
215 if (null == rootFolder)
216 return new List<InventoryItemBase>();
217
218 return FindItemsByPath(inventoryService, rootFolder, path);
219 }
220
221 /// <summary>
222 /// Find items that match a given PATH_DELIMITOR delimited path starting from this folder.
223 /// </summary>
224 /// <remarks>
225 /// This method does not handle paths that contain multiple delimiters
226 ///
227 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
228 /// XPath like expression
229 ///
230 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
231 /// </remarks>
232 ///
233 /// <param name="inventoryService">Inventory service to query</param>
234 /// <param name="startFolder">The folder from which the path starts</param>
235 /// <param name="path">The path to the required item.</param>
236 /// <returns>The items that were found with this path. An empty list if no items were found.</returns>
237 public static List<InventoryItemBase> FindItemsByPath(
238 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
239 {
240 List<InventoryItemBase> foundItems = new List<InventoryItemBase>();
241
207 // If the path isn't just / then trim any starting extraneous slashes 242 // If the path isn't just / then trim any starting extraneous slashes
208 path = path.TrimStart(new char[] { PATH_DELIMITER }); 243 path = path.TrimStart(new char[] { PATH_DELIMITER });
209 244
@@ -215,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
215 if (components.Length == 1) 250 if (components.Length == 1)
216 { 251 {
217// m_log.DebugFormat( 252// m_log.DebugFormat(
218// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}", 253// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
219// components[0], startFolder.Name, startFolder.ID); 254// components[0], startFolder.Name, startFolder.ID);
220 255
221 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); 256 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
222 257
223// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count); 258// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
224 259
225 foreach (InventoryItemBase item in items) 260 foreach (InventoryItemBase item in items)
@@ -227,24 +262,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
227// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID); 262// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
228 263
229 if (item.Name == components[0]) 264 if (item.Name == components[0])
230 return item; 265 foundItems.Add(item);
231 } 266 }
232 } 267 }
233 else 268 else
234 { 269 {
235// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]); 270// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
236 271
237 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 272 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
238 273
239 foreach (InventoryFolderBase folder in contents.Folders) 274 foreach (InventoryFolderBase folder in contents.Folders)
240 { 275 {
241 if (folder.Name == components[0]) 276 if (folder.Name == components[0])
242 return FindItemByPath(inventoryService, folder, components[1]); 277 foundItems.AddRange(FindItemsByPath(inventoryService, folder, components[1]));
243 } 278 }
244 } 279 }
245 280
246 // We didn't find an item or intermediate folder with the given name 281 return foundItems;
247 return null;
248 } 282 }
249 283
250 /// <summary> 284 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index e043caa..93657a8 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -154,7 +154,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
154 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); 154 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
155 m_archiveWriter.WriteFile(filename, serialization); 155 m_archiveWriter.WriteFile(filename, serialization);
156 156
157 if (SaveAssets) 157 AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
158
159 // Don't chase down link asset items as they actually point to their target item IDs rather than an asset
160 if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
158 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); 161 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
159 } 162 }
160 163
@@ -246,10 +249,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
246 249
247 // The path may point to an item instead 250 // The path may point to an item instead
248 if (inventoryFolder == null) 251 if (inventoryFolder == null)
249 {
250 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); 252 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
251 //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
252 }
253 253
254 if (null == inventoryFolder && null == inventoryItem) 254 if (null == inventoryFolder && null == inventoryItem)
255 { 255 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
new file mode 100644
index 0000000..c82cfd2
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -0,0 +1,244 @@
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.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using Mono.Addins;
35
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Connectors.Hypergrid;
40
41using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42
43namespace OpenSim.Region.CoreModules.Avatar.Lure
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
46 public class HGLureModule : ISharedRegionModule
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(
49 MethodBase.GetCurrentMethod().DeclaringType);
50
51 private readonly List<Scene> m_scenes = new List<Scene>();
52
53 private IMessageTransferModule m_TransferModule = null;
54 private bool m_Enabled = false;
55
56 private string m_ThisGridURL;
57
58 private ExpiringCache<UUID, GridInstantMessage> m_PendingLures = new ExpiringCache<UUID, GridInstantMessage>();
59
60 public void Initialise(IConfigSource config)
61 {
62 if (config.Configs["Messaging"] != null)
63 {
64 if (config.Configs["Messaging"].GetString("LureModule", string.Empty) == "HGLureModule")
65 {
66 m_Enabled = true;
67
68 m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty);
69 m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
70 }
71 }
72 }
73
74 public void AddRegion(Scene scene)
75 {
76 if (!m_Enabled)
77 return;
78
79 lock (m_scenes)
80 {
81 m_scenes.Add(scene);
82 scene.EventManager.OnIncomingInstantMessage += OnIncomingInstantMessage;
83 scene.EventManager.OnNewClient += OnNewClient;
84 }
85 }
86
87 public void RegionLoaded(Scene scene)
88 {
89 if (!m_Enabled)
90 return;
91
92 if (m_TransferModule == null)
93 {
94 m_TransferModule =
95 scene.RequestModuleInterface<IMessageTransferModule>();
96
97 if (m_TransferModule == null)
98 {
99 m_log.Error("[LURE MODULE]: No message transfer module, lures will not work!");
100
101 m_Enabled = false;
102 m_scenes.Clear();
103 scene.EventManager.OnNewClient -= OnNewClient;
104 scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
105 }
106 }
107
108 }
109
110 public void RemoveRegion(Scene scene)
111 {
112 if (!m_Enabled)
113 return;
114
115 lock (m_scenes)
116 {
117 m_scenes.Remove(scene);
118 scene.EventManager.OnNewClient -= OnNewClient;
119 scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
120 }
121 }
122
123 void OnNewClient(IClientAPI client)
124 {
125 client.OnInstantMessage += OnInstantMessage;
126 client.OnStartLure += OnStartLure;
127 client.OnTeleportLureRequest += OnTeleportLureRequest;
128 }
129
130 public void PostInitialise()
131 {
132 }
133
134 public void Close()
135 {
136 }
137
138 public string Name
139 {
140 get { return "HGLureModule"; }
141 }
142
143 public Type ReplaceableInterface
144 {
145 get { return null; }
146 }
147
148 void OnInstantMessage(IClientAPI client, GridInstantMessage im)
149 {
150 }
151
152 void OnIncomingInstantMessage(GridInstantMessage im)
153 {
154 if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
155 {
156 UUID sessionID = new UUID(im.imSessionID);
157 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
158 m_PendingLures.Add(sessionID, im, 7200); // 2 hours
159
160 // Forward. We do this, because the IM module explicitly rejects
161 // IMs of this type
162 if (m_TransferModule != null)
163 m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
164
165 }
166 }
167
168 public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client)
169 {
170 if (!(client.Scene is Scene))
171 return;
172
173 Scene scene = (Scene)(client.Scene);
174 ScenePresence presence = scene.GetScenePresence(client.AgentId);
175
176 message += "@" + m_ThisGridURL;
177
178 m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
179
180 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
181 client.FirstName+" "+client.LastName, targetid,
182 (byte)InstantMessageDialog.RequestTeleport, false,
183 message, UUID.Random(), false, presence.AbsolutePosition,
184 new Byte[0]);
185 m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
186
187 if (m_TransferModule != null)
188 {
189 m_TransferModule.SendInstantMessage(m,
190 delegate(bool success) { });
191 }
192 }
193
194 public void OnTeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client)
195 {
196 if (!(client.Scene is Scene))
197 return;
198
199 Scene scene = (Scene)(client.Scene);
200
201 GridInstantMessage im = null;
202 if (m_PendingLures.TryGetValue(lureID, out im))
203 {
204 m_PendingLures.Remove(lureID);
205 Lure(client, teleportFlags, im);
206 }
207 else
208 m_log.DebugFormat("[HG LURE MODULE]: pending lure {0} not found", lureID);
209
210 }
211
212 private void Lure(IClientAPI client, uint teleportflags, GridInstantMessage im)
213 {
214 Scene scene = (Scene)(client.Scene);
215 GridRegion region = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID, new UUID(im.RegionID));
216 if (region != null)
217 scene.RequestTeleportLocation(client, region.RegionHandle, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags);
218 else // we don't have that region here. Check if it's HG
219 {
220 string[] parts = im.message.Split(new char[] { '@' });
221 if (parts.Length > 1)
222 {
223 string url = parts[parts.Length - 1]; // the last part
224 if (url.Trim(new char[] {'/'}) != m_ThisGridURL.Trim(new char[] {'/'}))
225 {
226 m_log.DebugFormat("[HG LURE MODULE]: Luring agent to grid {0} region {1} position {2}", url, im.RegionID, im.Position);
227 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
228 GridRegion gatekeeper = new GridRegion();
229 gatekeeper.ServerURI = url;
230 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID));
231 if (finalDestination != null)
232 {
233 ScenePresence sp = scene.GetScenePresence(client.AgentId);
234 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
235 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
236 if (transferMod != null && sp != null && eq != null)
237 transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq);
238 }
239 }
240 }
241 }
242 }
243 }
244}
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index a12b57a..dcfdf8f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -45,16 +45,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
45 private readonly List<Scene> m_scenes = new List<Scene>(); 45 private readonly List<Scene> m_scenes = new List<Scene>();
46 46
47 private IMessageTransferModule m_TransferModule = null; 47 private IMessageTransferModule m_TransferModule = null;
48 private bool m_Enabled = true; 48 private bool m_Enabled = false;
49 49
50 public void Initialise(IConfigSource config) 50 public void Initialise(IConfigSource config)
51 { 51 {
52 if (config.Configs["Messaging"] != null) 52 if (config.Configs["Messaging"] != null)
53 { 53 {
54 if (config.Configs["Messaging"].GetString( 54 if (config.Configs["Messaging"].GetString(
55 "LureModule", "LureModule") != 55 "LureModule", "LureModule") ==
56 "LureModule") 56 "LureModule")
57 m_Enabled = false; 57 {
58 m_Enabled = true;
59 m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
60 }
58 } 61 }
59 } 62 }
60 63
@@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
74 77
75 public void RegionLoaded(Scene scene) 78 public void RegionLoaded(Scene scene)
76 { 79 {
80 if (!m_Enabled)
81 return;
82
77 if (m_TransferModule == null) 83 if (m_TransferModule == null)
78 { 84 {
79 m_TransferModule = 85 m_TransferModule =
@@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
96 102
97 public void RemoveRegion(Scene scene) 103 public void RemoveRegion(Scene scene)
98 { 104 {
105 if (!m_Enabled)
106 return;
107
99 lock (m_scenes) 108 lock (m_scenes)
100 { 109 {
101 m_scenes.Remove(scene); 110 m_scenes.Remove(scene);
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
new file mode 100644
index 0000000..079e1b6
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
@@ -0,0 +1,173 @@
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 */
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using System.Globalization;
31using System.Reflection;
32
33using OpenMetaverse;
34using log4net;
35using Nini.Config;
36using Mono.Addins;
37
38using OpenSim.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces;
42
43namespace OpenSim.Region.CoreModules.Avatar.Profile
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
46 public class BasicProfileModule : ISharedRegionModule
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 //
51 // Module vars
52 //
53 private List<Scene> m_Scenes = new List<Scene>();
54 private bool m_Enabled = false;
55
56 #region ISharedRegionModule
57
58 public void Initialise(IConfigSource config)
59 {
60 if (config.Configs["Profile"] != null)
61 {
62 if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule")
63 return;
64 }
65
66 m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled");
67 m_Enabled = true;
68
69 }
70
71 public void AddRegion(Scene scene)
72 {
73 if (!m_Enabled)
74 return;
75
76 lock (m_Scenes)
77 {
78 if (!m_Scenes.Contains(scene))
79 {
80 m_Scenes.Add(scene);
81 // Hook up events
82 scene.EventManager.OnNewClient += OnNewClient;
83 }
84 }
85 }
86
87 public void RegionLoaded(Scene scene)
88 {
89 if (!m_Enabled)
90 return;
91 }
92
93 public void RemoveRegion(Scene scene)
94 {
95 if (!m_Enabled)
96 return;
97
98 lock (m_Scenes)
99 {
100 m_Scenes.Remove(scene);
101 }
102 }
103
104 public void PostInitialise()
105 {
106 }
107
108 public void Close()
109 {
110 }
111
112 public string Name
113 {
114 get { return "BasicProfileModule"; }
115 }
116
117 public Type ReplaceableInterface
118 {
119 get { return null; }
120 }
121
122 #endregion
123
124 /// New Client Event Handler
125 private void OnNewClient(IClientAPI client)
126 {
127 //Profile
128 client.OnRequestAvatarProperties += RequestAvatarProperties;
129 }
130
131 public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
132 {
133 IScene s = remoteClient.Scene;
134 if (!(s is Scene))
135 return;
136
137 Scene scene = (Scene)s;
138
139 string profileUrl = String.Empty;
140 string aboutText = String.Empty;
141 string firstLifeAboutText = String.Empty;
142 UUID image = UUID.Zero;
143 UUID firstLifeImage = UUID.Zero;
144 UUID partner = UUID.Zero;
145 uint wantMask = 0;
146 string wantText = String.Empty;
147 uint skillsMask = 0;
148 string skillsText = String.Empty;
149 string languages = String.Empty;
150
151 Byte[] charterMember = Utils.StringToBytes("Avatar");
152
153 profileUrl = "No profile data";
154 aboutText = string.Empty;
155 firstLifeAboutText = string.Empty;
156 image = UUID.Zero;
157 firstLifeImage = UUID.Zero;
158 partner = UUID.Zero;
159
160 remoteClient.SendAvatarProperties(avatarID, aboutText,
161 Util.ToDateTime(0).ToString(
162 "M/d/yyyy", CultureInfo.InvariantCulture),
163 charterMember, firstLifeAboutText,
164 (uint)(0 & 0xff),
165 firstLifeImage, image, profileUrl, partner);
166
167 //Viewer expects interest data when it asks for properties.
168 remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
169 skillsMask, skillsText, languages);
170 }
171
172 }
173} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 1fb346e..02efcd8 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
52 52
53 protected bool m_Enabled = false; 53 protected bool m_Enabled = false;
54 protected Scene m_aScene; 54 protected Scene m_aScene;
55 protected List<Scene> m_Scenes = new List<Scene>();
55 protected List<UUID> m_agentsInTransit; 56 protected List<UUID> m_agentsInTransit;
56 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = 57 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
57 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); 58 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
@@ -96,13 +97,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
96 if (m_aScene == null) 97 if (m_aScene == null)
97 m_aScene = scene; 98 m_aScene = scene;
98 99
100 m_Scenes.Add(scene);
99 scene.RegisterModuleInterface<IEntityTransferModule>(this); 101 scene.RegisterModuleInterface<IEntityTransferModule>(this);
100 scene.EventManager.OnNewClient += OnNewClient; 102 scene.EventManager.OnNewClient += OnNewClient;
101 } 103 }
102 104
103 protected virtual void OnNewClient(IClientAPI client) 105 protected virtual void OnNewClient(IClientAPI client)
104 { 106 {
105 client.OnTeleportHomeRequest += TeleportHomeFired; 107 client.OnTeleportHomeRequest += TriggerTeleportHome;
108 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
106 } 109 }
107 110
108 public virtual void Close() 111 public virtual void Close()
@@ -118,6 +121,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
118 return; 121 return;
119 if (scene == m_aScene) 122 if (scene == m_aScene)
120 m_aScene = null; 123 m_aScene = null;
124
125 m_Scenes.Remove(scene);
121 } 126 }
122 127
123 public virtual void RegionLoaded(Scene scene) 128 public virtual void RegionLoaded(Scene scene)
@@ -127,7 +132,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
127 132
128 } 133 }
129 134
130
131 #endregion 135 #endregion
132 136
133 #region Agent Teleports 137 #region Agent Teleports
@@ -249,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
249 } 253 }
250 } 254 }
251 255
252 protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) 256 public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
253 { 257 {
254 if (reg == null || finalDestination == null) 258 if (reg == null || finalDestination == null)
255 { 259 {
@@ -557,9 +561,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
557 561
558 #endregion 562 #endregion
559 563
564 #region Landmark Teleport
565 /// <summary>
566 /// Tries to teleport agent to landmark.
567 /// </summary>
568 /// <param name="remoteClient"></param>
569 /// <param name="regionHandle"></param>
570 /// <param name="position"></param>
571 public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
572 {
573 GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
574
575 if (info == null)
576 {
577 // can't find the region: Tell viewer and abort
578 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
579 return;
580 }
581 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
582 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
583 }
584
585 #endregion
586
560 #region Teleport Home 587 #region Teleport Home
561 588
562 public void TeleportHomeFired(UUID id, IClientAPI client) 589 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
563 { 590 {
564 TeleportHome(id, client); 591 TeleportHome(id, client);
565 } 592 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 1ccbcfd..d6ef5df 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -86,7 +86,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
86 86
87 protected override void OnNewClient(IClientAPI client) 87 protected override void OnNewClient(IClientAPI client)
88 { 88 {
89 client.OnTeleportHomeRequest += TeleportHomeFired; 89 client.OnTeleportHomeRequest += TriggerTeleportHome;
90 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
90 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); 91 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
91 } 92 }
92 93
@@ -178,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
178 return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); 179 return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
179 } 180 }
180 181
181 public void TeleportHomeFired(UUID id, IClientAPI client) 182 public void TriggerTeleportHome(UUID id, IClientAPI client)
182 { 183 {
183 TeleportHome(id, client); 184 TeleportHome(id, client);
184 } 185 }
@@ -233,6 +234,58 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
233 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); 234 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
234 return true; 235 return true;
235 } 236 }
237
238 /// <summary>
239 /// Tries to teleport agent to landmark.
240 /// </summary>
241 /// <param name="remoteClient"></param>
242 /// <param name="regionHandle"></param>
243 /// <param name="position"></param>
244 public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
245 {
246 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
247 (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
248 if (lm.Gatekeeper == string.Empty)
249 {
250 base.RequestTeleportLandmark(remoteClient, lm);
251 return;
252 }
253
254 GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
255
256 // Local region?
257 if (info != null)
258 {
259 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
260 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
261 return;
262 }
263 else
264 {
265 // Foreign region
266 Scene scene = (Scene)(remoteClient.Scene);
267 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
268 GridRegion gatekeeper = new GridRegion();
269 gatekeeper.ServerURI = lm.Gatekeeper;
270 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID));
271 if (finalDestination != null)
272 {
273 ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
274 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
275 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
276 if (transferMod != null && sp != null && eq != null)
277 transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position,
278 Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq);
279 }
280
281 }
282
283 // can't find the region: Tell viewer and abort
284 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
285
286 }
287
288
236 #endregion 289 #endregion
237 290
238 #region IUserAgentVerificationModule 291 #region IUserAgentVerificationModule
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 52791cb..49d484b 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
56 56
57 private string m_ProfileServerURI; 57 private string m_ProfileServerURI;
58 private bool m_OutboundPermission; 58 private bool m_OutboundPermission;
59 private string m_ThisGatekeeper;
59 60
60// private bool m_Initialized = false; 61// private bool m_Initialized = false;
61 62
@@ -85,6 +86,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
85 { 86 {
86 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); 87 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
87 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); 88 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
89 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
88 } 90 }
89 else 91 else
90 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); 92 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
@@ -110,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
110 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) 112 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
111 { 113 {
112 string userAssetServer = string.Empty; 114 string userAssetServer = string.Empty;
113 if (IsForeignUser(avatarID, out userAssetServer) && m_OutboundPermission) 115 if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
114 { 116 {
115 Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); }); 117 Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
116 } 118 }
@@ -119,6 +121,24 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
119 #endregion 121 #endregion
120 122
121 #region Overrides of Basic Inventory Access methods 123 #region Overrides of Basic Inventory Access methods
124
125 protected override string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
126 {
127 UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, presence.UUID);
128 if (account == null)
129 prefix = "HG ";
130 else
131 prefix = string.Empty;
132 suffix = " @ " + m_ThisGatekeeper;
133 Vector3 pos = presence.AbsolutePosition;
134 return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}\n",
135 presence.Scene.RegionInfo.RegionID,
136 pos.X, pos.Y, pos.Z,
137 presence.RegionHandle,
138 m_ThisGatekeeper);
139 }
140
141
122 /// 142 ///
123 /// CapsUpdateInventoryItemAsset 143 /// CapsUpdateInventoryItemAsset
124 /// 144 ///
@@ -180,10 +200,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
180 public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) 200 public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
181 { 201 {
182 string userAssetServer = string.Empty; 202 string userAssetServer = string.Empty;
183 if (IsForeignUser(sender, out userAssetServer)) 203 if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty)
184 m_assMapper.Get(item.AssetID, sender, userAssetServer); 204 m_assMapper.Get(item.AssetID, sender, userAssetServer);
185 205
186 if (IsForeignUser(receiver, out userAssetServer) && m_OutboundPermission) 206 if (IsForeignUser(receiver, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
187 m_assMapper.Post(item.AssetID, receiver, userAssetServer); 207 m_assMapper.Post(item.AssetID, receiver, userAssetServer);
188 } 208 }
189 209
@@ -203,9 +223,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
203 if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) 223 if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
204 { 224 {
205 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 225 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
206 assetServerURL = assetServerURL.Trim(new char[] { '/' }); return true; 226 assetServerURL = assetServerURL.Trim(new char[] { '/' });
207 } 227 }
208 } 228 }
229 else
230 {
231 assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI");
232 assetServerURL = assetServerURL.Trim(new char[] { '/' });
233 }
234 return true;
209 } 235 }
210 236
211 return false; 237 return false;
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 184b223..7bad814 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using System.Xml; 31using System.Xml;
32using System.Reflection; 32using System.Reflection;
33using System.Text;
33using System.Threading; 34using System.Threading;
34 35
35using OpenSim.Framework; 36using OpenSim.Framework;
@@ -128,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
128 129
129 protected virtual void OnNewClient(IClientAPI client) 130 protected virtual void OnNewClient(IClientAPI client)
130 { 131 {
131 132 client.OnCreateNewInventoryItem += CreateNewInventoryItem;
132 } 133 }
133 134
134 public virtual void Close() 135 public virtual void Close()
@@ -157,6 +158,87 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
157 #region Inventory Access 158 #region Inventory Access
158 159
159 /// <summary> 160 /// <summary>
161 /// Create a new inventory item. Called when the client creates a new item directly within their
162 /// inventory (e.g. by selecting a context inventory menu option).
163 /// </summary>
164 /// <param name="remoteClient"></param>
165 /// <param name="transactionID"></param>
166 /// <param name="folderID"></param>
167 /// <param name="callbackID"></param>
168 /// <param name="description"></param>
169 /// <param name="name"></param>
170 /// <param name="invType"></param>
171 /// <param name="type"></param>
172 /// <param name="wearableType"></param>
173 /// <param name="nextOwnerMask"></param>
174 public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
175 uint callbackID, string description, string name, sbyte invType,
176 sbyte assetType,
177 byte wearableType, uint nextOwnerMask, int creationDate)
178 {
179 m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
180
181 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
182 return;
183
184 InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
185 InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f);
186
187 if (folder == null || folder.Owner != remoteClient.AgentId)
188 return;
189
190 if (transactionID == UUID.Zero)
191 {
192 ScenePresence presence;
193 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
194 {
195 byte[] data = null;
196
197 if (invType == (sbyte)InventoryType.Landmark && presence != null)
198 {
199 string suffix = string.Empty, prefix = string.Empty;
200 string strdata = GenerateLandmark(presence, out prefix, out suffix);
201 data = Encoding.ASCII.GetBytes(strdata);
202 name = prefix + name;
203 description += suffix;
204 }
205
206 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
207 m_Scene.AssetService.Store(asset);
208
209 m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
210 }
211 else
212 {
213 m_log.ErrorFormat(
214 "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
215 remoteClient.AgentId);
216 }
217 }
218 else
219 {
220 IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface<IAgentAssetTransactions>();
221 if (agentTransactions != null)
222 {
223 agentTransactions.HandleItemCreationFromTransaction(
224 remoteClient, transactionID, folderID, callbackID, description,
225 name, invType, assetType, wearableType, nextOwnerMask);
226 }
227 }
228 }
229
230 protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
231 {
232 prefix = string.Empty;
233 suffix = string.Empty;
234 Vector3 pos = presence.AbsolutePosition;
235 return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
236 presence.Scene.RegionInfo.RegionID,
237 pos.X, pos.Y, pos.Z,
238 presence.RegionHandle);
239 }
240
241 /// <summary>
160 /// Capability originating call to update the asset of an item in an agent's inventory 242 /// Capability originating call to update the asset of an item in an agent's inventory
161 /// </summary> 243 /// </summary>
162 /// <param name="remoteClient"></param> 244 /// <param name="remoteClient"></param>
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 4cc6905..ae4336c 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -30,11 +30,13 @@ using System.IO;
30using System.Reflection; 30using System.Reflection;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Console;
33 34
34using OpenSim.Region.Framework; 35using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
39using OpenSim.Services.Connectors.Hypergrid;
38 40
39using OpenMetaverse; 41using OpenMetaverse;
40using log4net; 42using log4net;
@@ -47,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
47 public UUID Id; 49 public UUID Id;
48 public string FirstName; 50 public string FirstName;
49 public string LastName; 51 public string LastName;
50 public string ProfileURL; 52 public string HomeURL;
53 public Dictionary<string, object> ServerURLs;
51 } 54 }
52 55
53 public class UserManagementModule : ISharedRegionModule, IUserManagement 56 public class UserManagementModule : ISharedRegionModule, IUserManagement
@@ -78,6 +81,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
78 // } 81 // }
79 // } 82 // }
80 //} 83 //}
84 MainConsole.Instance.Commands.AddCommand("grid", true,
85 "show user-names",
86 "show user-names",
87 "Show the bindings between user UUIDs and user names",
88 String.Empty,
89 HandleShowUsers);
90
91
81 } 92 }
82 93
83 public bool IsSharedModule 94 public bool IsSharedModule
@@ -101,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
101 112
102 scene.RegisterModuleInterface<IUserManagement>(this); 113 scene.RegisterModuleInterface<IUserManagement>(this);
103 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); 114 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
115 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
104 } 116 }
105 117
106 public void RemoveRegion(Scene scene) 118 public void RemoveRegion(Scene scene)
@@ -109,18 +121,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
109 m_Scenes.Remove(scene); 121 m_Scenes.Remove(scene);
110 } 122 }
111 123
112 public void RegionLoaded(Scene scene) 124 public void RegionLoaded(Scene s)
113 { 125 {
114 } 126 }
115 127
116 public void PostInitialise() 128 public void PostInitialise()
117 { 129 {
118 foreach (Scene s in m_Scenes)
119 {
120 // let's sniff all the user names referenced by objects in the scene
121 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
122 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
123 }
124 } 130 }
125 131
126 public void Close() 132 public void Close()
@@ -134,6 +140,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
134 140
135 #region Event Handlers 141 #region Event Handlers
136 142
143 void EventManager_OnPrimsLoaded(Scene s)
144 {
145 // let's sniff all the user names referenced by objects in the scene
146 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
147 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
148 }
149
150
137 void EventManager_OnNewClient(IClientAPI client) 151 void EventManager_OnNewClient(IClientAPI client)
138 { 152 {
139 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); 153 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
@@ -150,6 +164,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
150 string[] names = GetUserNames(uuid); 164 string[] names = GetUserNames(uuid);
151 if (names.Length == 2) 165 if (names.Length == 2)
152 { 166 {
167 //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]);
153 remote_client.SendNameReply(uuid, names[0], names[1]); 168 remote_client.SendNameReply(uuid, names[0], names[1]);
154 } 169 }
155 170
@@ -210,6 +225,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
210 225
211 public string GetUserName(UUID uuid) 226 public string GetUserName(UUID uuid)
212 { 227 {
228 //m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
213 string[] names = GetUserNames(uuid); 229 string[] names = GetUserNames(uuid);
214 if (names.Length == 2) 230 if (names.Length == 2)
215 { 231 {
@@ -222,6 +238,60 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
222 return "(hippos)"; 238 return "(hippos)";
223 } 239 }
224 240
241 public string GetUserHomeURL(UUID userID)
242 {
243 if (m_UserCache.ContainsKey(userID))
244 return m_UserCache[userID].HomeURL;
245
246 return string.Empty;
247 }
248
249 public string GetUserServerURL(UUID userID, string serverType)
250 {
251 if (m_UserCache.ContainsKey(userID))
252 {
253 UserData userdata = m_UserCache[userID];
254 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
255 return userdata.ServerURLs[serverType].ToString();
256
257 if (userdata.HomeURL != string.Empty)
258 {
259 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
260 userdata.ServerURLs = uConn.GetServerURLs(userID);
261 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
262 return userdata.ServerURLs[serverType].ToString();
263 }
264 }
265
266 return string.Empty;
267 }
268
269 public string GetUserUUI(UUID userID)
270 {
271 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
272 if (account != null)
273 return userID.ToString();
274
275 if (m_UserCache.ContainsKey(userID))
276 {
277 UserData ud = m_UserCache[userID];
278 string homeURL = ud.HomeURL;
279 string first = ud.FirstName, last = ud.LastName;
280 if (ud.LastName.StartsWith("@"))
281 {
282 string[] parts = ud.FirstName.Split('.');
283 if (parts.Length >= 2)
284 {
285 first = parts[0];
286 last = parts[1];
287 }
288 return userID + ";" + homeURL + ";" + first + " " + last;
289 }
290 }
291
292 return userID.ToString();
293 }
294
225 public void AddUser(UUID id, string creatorData) 295 public void AddUser(UUID id, string creatorData)
226 { 296 {
227 if (m_UserCache.ContainsKey(id)) 297 if (m_UserCache.ContainsKey(id))
@@ -247,13 +317,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
247 string[] parts = creatorData.Split(';'); 317 string[] parts = creatorData.Split(';');
248 if (parts.Length >= 1) 318 if (parts.Length >= 1)
249 { 319 {
250 user.ProfileURL = parts[0]; 320 user.HomeURL = parts[0];
251 try 321 try
252 { 322 {
253 Uri uri = new Uri(parts[0]); 323 Uri uri = new Uri(parts[0]);
254 user.LastName = "@" + uri.Authority; 324 user.LastName = "@" + uri.Authority;
255 } 325 }
256 catch 326 catch (UriFormatException)
257 { 327 {
258 m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]); 328 m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
259 user.LastName = "@unknown"; 329 user.LastName = "@unknown";
@@ -272,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
272 lock (m_UserCache) 342 lock (m_UserCache)
273 m_UserCache[id] = user; 343 m_UserCache[id] = user;
274 344
275 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL); 345 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL);
276 } 346 }
277 347
278 public void AddUser(UUID uuid, string first, string last, string profileURL) 348 public void AddUser(UUID uuid, string first, string last, string profileURL)
@@ -311,5 +381,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
311 //} 381 //}
312 382
313 #endregion IUserManagement 383 #endregion IUserManagement
384
385 private void HandleShowUsers(string module, string[] cmd)
386 {
387 if (m_UserCache.Count == 0)
388 {
389 MainConsole.Instance.Output("No users not found");
390 return;
391 }
392
393 MainConsole.Instance.Output("UUID User Name");
394 MainConsole.Instance.Output("-----------------------------------------------------------------------------");
395 foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
396 {
397 MainConsole.Instance.Output(String.Format("{0} {1} {2}",
398 kvp.Key, kvp.Value.FirstName, kvp.Value.LastName));
399 }
400 return;
401 }
402
403
314 } 404 }
315} 405}
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index 5ab334f..f066f83 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -25,6 +25,7 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
28using System.Collections.Generic; 29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using log4net; 31using log4net;
@@ -67,9 +68,26 @@ namespace OpenSim.Region.CoreModules.Hypergrid
67 68
68 foreach (GridRegion r in regions) 69 foreach (GridRegion r in regions)
69 { 70 {
70 MapBlockData block = new MapBlockData(); 71 uint x = 0, y = 0;
71 MapBlockFromGridRegion(block, r); 72 long handle = 0;
72 mapBlocks.Add(block); 73 if (r.RegionSecret != null && r.RegionSecret != string.Empty)
74 {
75 if (long.TryParse(r.RegionSecret, out handle))
76 {
77 Utils.LongToUInts((ulong)handle, out x, out y);
78 x = x / Constants.RegionSize;
79 y = y / Constants.RegionSize;
80 }
81 }
82
83 if (handle == 0 ||
84 // Check the distance from the current region
85 (handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096))
86 {
87 MapBlockData block = new MapBlockData();
88 MapBlockFromGridRegion(block, r);
89 mapBlocks.Add(block);
90 }
73 } 91 }
74 92
75 // Different from super 93 // Different from super
@@ -77,6 +95,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid
77 // 95 //
78 96
79 remoteClient.SendMapBlock(mapBlocks, 0); 97 remoteClient.SendMapBlock(mapBlocks, 0);
98
80 } 99 }
81 100
82 101
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index 8a6735f..e22fd38 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -24,6 +24,7 @@
24 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" /> 24 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
25 <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" /> 25 <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
26 <RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" /> 26 <RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" />
27 <RegionModule id="HGFriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.HGFriendsModule" />
27 <RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" /> 28 <RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" />
28 <RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" /> 29 <RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" />
29 <RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" /> 30 <RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" />
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
index d2343c9..a5b5637 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
@@ -113,8 +113,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
113 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); 113 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
114 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); 114 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
115 115
116 new UserAgentServerConnector(m_Config, MainServer.Instance); 116 IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
117 new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
117 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); 118 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
119 new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
118 } 120 }
119 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper); 121 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
120 } 122 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index 3f63db3..698fd56 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -58,6 +58,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
58 58
59 private List<Scene> m_Scenes = new List<Scene>(); 59 private List<Scene> m_Scenes = new List<Scene>();
60 60
61 protected IUserManagement m_UserManagement;
62 protected IUserManagement UserManagementModule
63 {
64 get
65 {
66 if (m_UserManagement == null)
67 m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>();
68 return m_UserManagement;
69 }
70 }
71
61 public Type ReplaceableInterface 72 public Type ReplaceableInterface
62 { 73 {
63 get { return null; } 74 get { return null; }
@@ -207,6 +218,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
207 } 218 }
208 } 219 }
209 } 220 }
221 if (sp == null)
222 {
223 inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI");
224 if (inventoryURL != null && inventoryURL != string.Empty)
225 {
226 inventoryURL = inventoryURL.Trim(new char[] { '/' });
227 m_InventoryURLs.Add(userID, inventoryURL);
228 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
229 }
230
231 }
232
210 } 233 }
211 } 234 }
212 235
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 5da1656..eb00de8 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -230,6 +230,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
230 /// <param name="asset"></param> 230 /// <param name="asset"></param>
231 public void AssetRequestCallback(string id, object sender, AssetBase asset) 231 public void AssetRequestCallback(string id, object sender, AssetBase asset)
232 { 232 {
233 Culture.SetCurrentCulture();
234
233 try 235 try
234 { 236 {
235 lock (this) 237 lock (this)
@@ -289,6 +291,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
289 /// </summary> 291 /// </summary>
290 protected void PerformAssetsRequestCallback(object o) 292 protected void PerformAssetsRequestCallback(object o)
291 { 293 {
294 Culture.SetCurrentCulture();
295
292 try 296 try
293 { 297 {
294 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids); 298 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index a098ff6..43b37c7 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -548,18 +548,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
548 548
549 // libomv will moan about PrimFlags.ObjectYouOfficer being 549 // libomv will moan about PrimFlags.ObjectYouOfficer being
550 // deprecated 550 // deprecated
551 #pragma warning disable 0612 551#pragma warning disable 0612
552 objflags &= (uint) 552 objflags &= (uint)
553 ~(PrimFlags.ObjectCopy | // Tells client you can copy the object 553 ~(PrimFlags.ObjectCopy | // Tells client you can copy the object
554 PrimFlags.ObjectModify | // tells client you can modify the object 554 PrimFlags.ObjectModify | // tells client you can modify the object
555 PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) 555 PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
556 PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it 556 PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
557 PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object 557 PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
558 PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object 558 PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
559 PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object 559 PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
560 PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set 560 PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
561 ); 561 );
562 #pragma warning restore 0612 562#pragma warning restore 0612
563 563
564 // Creating the three ObjectFlags options for this method to choose from. 564 // Creating the three ObjectFlags options for this method to choose from.
565 // Customize the OwnerMask 565 // Customize the OwnerMask
@@ -576,22 +576,27 @@ namespace OpenSim.Region.CoreModules.World.Permissions
576 576
577 if (m_bypassPermissions) 577 if (m_bypassPermissions)
578 return objectOwnerMask; 578 return objectOwnerMask;
579 579
580 // Object owners should be able to edit their own content 580 // Object owners should be able to edit their own content
581 if (user == objectOwner) 581 if (user == objectOwner)
582 return objectOwnerMask; 582 return objectOwnerMask;
583 583
584 if (IsFriendWithPerms(user, objectOwner)) 584 if (IsFriendWithPerms(user, objectOwner))
585 {
585 return objectOwnerMask; 586 return objectOwnerMask;
586 587 }
587 // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set 588 // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
588 if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) 589 if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
590 {
589 return objectOwnerMask; 591 return objectOwnerMask;
592 }
590 593
591 // Admin should be able to edit anything in the sim (including admin objects) 594 // Admin should be able to edit anything in the sim (including admin objects)
592 if (IsAdministrator(user)) 595 if (IsAdministrator(user))
596 {
593 return objectOwnerMask; 597 return objectOwnerMask;
594 598 }
599
595 // Users should be able to edit what is over their land. 600 // Users should be able to edit what is over their land.
596 Vector3 taskPos = task.AbsolutePosition; 601 Vector3 taskPos = task.AbsolutePosition;
597 ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); 602 ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
@@ -599,13 +604,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions
599 { 604 {
600 // Admin objects should not be editable by the above 605 // Admin objects should not be editable by the above
601 if (!IsAdministrator(objectOwner)) 606 if (!IsAdministrator(objectOwner))
607 {
602 return objectOwnerMask; 608 return objectOwnerMask;
609 }
603 } 610 }
604 611
605 // Group permissions 612 // Group permissions
606 if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) 613 if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
607 return objectGroupMask | objectEveryoneMask; 614 return objectGroupMask | objectEveryoneMask;
608 615
609 return objectEveryoneMask; 616 return objectEveryoneMask;
610 } 617 }
611 618
@@ -673,7 +680,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
673 // 680 //
674 // Nobody but the object owner can set permissions on an object 681 // Nobody but the object owner can set permissions on an object
675 // 682 //
676
677 if (locked && (!IsAdministrator(currentUser)) && denyOnLocked) 683 if (locked && (!IsAdministrator(currentUser)) && denyOnLocked)
678 { 684 {
679 return false; 685 return false;
@@ -704,6 +710,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
704 // Return immediately, so that the administrator can shares group objects 710 // Return immediately, so that the administrator can shares group objects
705 return true; 711 return true;
706 } 712 }
713
714 // Friends with benefits should be able to edit the objects too
715 if (IsFriendWithPerms(currentUser, objectOwner))
716 // Return immediately, so that the administrator can share objects with friends
717 return true;
707 718
708 // Users should be able to edit what is over their land. 719 // Users should be able to edit what is over their land.
709 ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y); 720 ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index cd40c5d..3f6f359 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -208,52 +208,65 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
208 //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", 208 //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}",
209 // path, param, agentID.ToString()); 209 // path, param, agentID.ToString());
210 210
211 // this is here because CAPS map requests work even beyond the 10,000 limit. 211 // There is a major hack going on in this method. The viewer doesn't request
212 ScenePresence avatarPresence = null; 212 // map blocks (RequestMapBlocks) above 4096. That means that if we don't hack,
213 213 // grids above that cell don't have a map at all. So, here's the hack: we wait
214 m_scene.TryGetScenePresence(agentID, out avatarPresence); 214 // for this CAP request to come, and we inject the map blocks at this point.
215 215 // In a normal scenario, this request simply sends back the MapLayer (the blue color).
216 if (avatarPresence != null) 216 // In the hacked scenario, it also sends the map blocks via UDP.
217 //
218 // 6/8/2011 -- I'm adding an explicit 4096 check, so that we never forget that there is
219 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
220
221 if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY >= 4096)
217 { 222 {
218 bool lookup = false; 223 ScenePresence avatarPresence = null;
219 224
220 lock (cachedMapBlocks) 225 m_scene.TryGetScenePresence(agentID, out avatarPresence);
221 {
222 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
223 {
224 List<MapBlockData> mapBlocks;
225 226
226 mapBlocks = cachedMapBlocks; 227 if (avatarPresence != null)
227 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
228 }
229 else
230 {
231 lookup = true;
232 }
233 }
234 if (lookup)
235 { 228 {
236 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 229 bool lookup = false;
237 230
238 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 231 lock (cachedMapBlocks)
239 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
240 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
241 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
242 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
243 foreach (GridRegion r in regions)
244 { 232 {
245 MapBlockData block = new MapBlockData(); 233 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
246 MapBlockFromGridRegion(block, r); 234 {
247 mapBlocks.Add(block); 235 List<MapBlockData> mapBlocks;
236
237 mapBlocks = cachedMapBlocks;
238 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
239 }
240 else
241 {
242 lookup = true;
243 }
248 } 244 }
249 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 245 if (lookup)
246 {
247 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
248
249 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
250 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
251 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
252 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
253 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
254 foreach (GridRegion r in regions)
255 {
256 MapBlockData block = new MapBlockData();
257 MapBlockFromGridRegion(block, r);
258 mapBlocks.Add(block);
259 }
260 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
250 261
251 lock (cachedMapBlocks) 262 lock (cachedMapBlocks)
252 cachedMapBlocks = mapBlocks; 263 cachedMapBlocks = mapBlocks;
253 264
254 cachedTime = Util.UnixTimeSinceEpoch(); 265 cachedTime = Util.UnixTimeSinceEpoch();
266 }
255 } 267 }
256 } 268 }
269
257 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 270 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
258 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 271 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
259 return mapResponse.ToString(); 272 return mapResponse.ToString();
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index b3bdff3..cdce36e 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -540,7 +540,7 @@ namespace OpenSim.Region.Examples.SimpleModule
540 { 540 {
541 } 541 }
542 542
543 public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) 543 public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
544 { 544 {
545 } 545 }
546 546
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 3eb38b8..c38ecd9 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -42,6 +42,9 @@ namespace OpenSim.Region.Framework.Interfaces
42 42
43 bool TeleportHome(UUID id, IClientAPI client); 43 bool TeleportHome(UUID id, IClientAPI client);
44 44
45 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
46 Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq);
47
45 bool Cross(ScenePresence agent, bool isFlying); 48 bool Cross(ScenePresence agent, bool isFlying);
46 49
47 void AgentArrivedAtDestination(UUID agent); 50 void AgentArrivedAtDestination(UUID agent);
diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
index 0ff7dee..d4a6857 100644
--- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
@@ -34,6 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces
34 public interface IFriendsModule 34 public interface IFriendsModule
35 { 35 {
36 uint GetFriendPerms(UUID PrincipalID, UUID FriendID); 36 uint GetFriendPerms(UUID PrincipalID, UUID FriendID);
37 void SendFriendsOnlineIfNeeded(IClientAPI client); 37 bool SendFriendsOnlineIfNeeded(IClientAPI client);
38 } 38 }
39} 39}
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index 2904ee8..5d30aa8 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -8,6 +8,9 @@ namespace OpenSim.Region.Framework.Interfaces
8 public interface IUserManagement 8 public interface IUserManagement
9 { 9 {
10 string GetUserName(UUID uuid); 10 string GetUserName(UUID uuid);
11 string GetUserHomeURL(UUID uuid);
12 string GetUserUUI(UUID uuid);
13 string GetUserServerURL(UUID uuid, string serverType);
11 void AddUser(UUID uuid, string userData); 14 void AddUser(UUID uuid, string userData);
12 void AddUser(UUID uuid, string firstName, string lastName, string profileURL); 15 void AddUser(UUID uuid, string firstName, string lastName, string profileURL);
13 } 16 }
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index d326141..3ec4e59 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -393,6 +393,12 @@ namespace OpenSim.Region.Framework.Scenes
393 public delegate void RegionUp(GridRegion region); 393 public delegate void RegionUp(GridRegion region);
394 public event RegionUp OnRegionUp; 394 public event RegionUp OnRegionUp;
395 395
396 public delegate void LoginsEnabled(string regionName);
397 public event LoginsEnabled OnLoginsEnabled;
398
399 public delegate void PrimsLoaded(Scene s);
400 public event PrimsLoaded OnPrimsLoaded;
401
396 public class MoneyTransferArgs : EventArgs 402 public class MoneyTransferArgs : EventArgs
397 { 403 {
398 public UUID sender; 404 public UUID sender;
@@ -2242,5 +2248,47 @@ namespace OpenSim.Region.Framework.Scenes
2242 } 2248 }
2243 } 2249 }
2244 } 2250 }
2251
2252 public void TriggerLoginsEnabled (string regionName)
2253 {
2254 LoginsEnabled handler = OnLoginsEnabled;
2255
2256 if ( handler != null)
2257 {
2258 foreach (LoginsEnabled d in handler.GetInvocationList())
2259 {
2260 try
2261 {
2262 d(regionName);
2263 }
2264 catch (Exception e)
2265 {
2266 m_log.ErrorFormat("[EVENT MANAGER]: Delegate for LoginsEnabled failed - continuing {0} - {1}",
2267 e.Message, e.StackTrace);
2268 }
2269 }
2270 }
2271 }
2272
2273 public void TriggerPrimsLoaded(Scene s)
2274 {
2275 PrimsLoaded handler = OnPrimsLoaded;
2276
2277 if (handler != null)
2278 {
2279 foreach (PrimsLoaded d in handler.GetInvocationList())
2280 {
2281 try
2282 {
2283 d(s);
2284 }
2285 catch (Exception e)
2286 {
2287 m_log.ErrorFormat("[EVENT MANAGER]: Delegate for PrimsLoaded failed - continuing {0} - {1}",
2288 e.Message, e.StackTrace);
2289 }
2290 }
2291 }
2292 }
2245 } 2293 }
2246} 2294}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 0b92818..c04bbb4 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -408,192 +408,198 @@ namespace OpenSim.Region.Framework.Scenes
408 InventoryItemBase item = new InventoryItemBase(itemId, senderId); 408 InventoryItemBase item = new InventoryItemBase(itemId, senderId);
409 item = InventoryService.GetItem(item); 409 item = InventoryService.GetItem(item);
410 410
411 if ((item != null) && (item.Owner == senderId)) 411 if (item == null)
412 { 412 {
413 IUserManagement uman = RequestModuleInterface<IUserManagement>(); 413 m_log.WarnFormat(
414 if (uman != null) 414 "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient);
415 uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); 415 return null;
416 }
416 417
417 if (!Permissions.BypassPermissions()) 418 if (item.Owner != senderId)
418 { 419 {
419 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) 420 m_log.WarnFormat(
420 return null; 421 "[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}",
421 } 422 item.Name, item.ID, recipient, senderId, item.Owner);
423 return null;
424 }
425
426 IUserManagement uman = RequestModuleInterface<IUserManagement>();
427 if (uman != null)
428 uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
429
430 if (!Permissions.BypassPermissions())
431 {
432 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
433 return null;
434 }
422 435
423 // Insert a copy of the item into the recipient 436 // Insert a copy of the item into the recipient
424 InventoryItemBase itemCopy = new InventoryItemBase(); 437 InventoryItemBase itemCopy = new InventoryItemBase();
425 itemCopy.Owner = recipient; 438 itemCopy.Owner = recipient;
426 itemCopy.CreatorId = item.CreatorId; 439 itemCopy.CreatorId = item.CreatorId;
427 itemCopy.CreatorData = item.CreatorData; 440 itemCopy.CreatorData = item.CreatorData;
428 itemCopy.ID = UUID.Random(); 441 itemCopy.ID = UUID.Random();
429 itemCopy.AssetID = item.AssetID; 442 itemCopy.AssetID = item.AssetID;
430 itemCopy.Description = item.Description; 443 itemCopy.Description = item.Description;
431 itemCopy.Name = item.Name; 444 itemCopy.Name = item.Name;
432 itemCopy.AssetType = item.AssetType; 445 itemCopy.AssetType = item.AssetType;
433 itemCopy.InvType = item.InvType; 446 itemCopy.InvType = item.InvType;
434 itemCopy.Folder = recipientFolderId; 447 itemCopy.Folder = recipientFolderId;
435 448
436 if (Permissions.PropagatePermissions() && recipient != senderId) 449 if (Permissions.PropagatePermissions() && recipient != senderId)
450 {
451 // Trying to do this right this time. This is evil. If
452 // you believe in Good, go elsewhere. Vampires and other
453 // evil creatores only beyond this point. You have been
454 // warned.
455
456 // We're going to mask a lot of things by the next perms
457 // Tweak the next perms to be nicer to our data
458 //
459 // In this mask, all the bits we do NOT want to mess
460 // with are set. These are:
461 //
462 // Transfer
463 // Copy
464 // Modufy
465 uint permsMask = ~ ((uint)PermissionMask.Copy |
466 (uint)PermissionMask.Transfer |
467 (uint)PermissionMask.Modify);
468
469 // Now, reduce the next perms to the mask bits
470 // relevant to the operation
471 uint nextPerms = permsMask | (item.NextPermissions &
472 ((uint)PermissionMask.Copy |
473 (uint)PermissionMask.Transfer |
474 (uint)PermissionMask.Modify));
475
476 // nextPerms now has all bits set, except for the actual
477 // next permission bits.
478
479 // This checks for no mod, no copy, no trans.
480 // This indicates an error or messed up item. Do it like
481 // SL and assume trans
482 if (nextPerms == permsMask)
483 nextPerms |= (uint)PermissionMask.Transfer;
484
485 // Inventory owner perms are the logical AND of the
486 // folded perms and the root prim perms, however, if
487 // the root prim is mod, the inventory perms will be
488 // mod. This happens on "take" and is of little concern
489 // here, save for preventing escalation
490
491 // This hack ensures that items previously permalocked
492 // get unlocked when they're passed or rezzed
493 uint basePerms = item.BasePermissions |
494 (uint)PermissionMask.Move;
495 uint ownerPerms = item.CurrentPermissions;
496
497 // If this is an object, root prim perms may be more
498 // permissive than folded perms. Use folded perms as
499 // a mask
500 if (item.InvType == (int)InventoryType.Object)
437 { 501 {
438 // Trying to do this right this time. This is evil. If 502 // Create a safe mask for the current perms
439 // you believe in Good, go elsewhere. Vampires and other 503 uint foldedPerms = (item.CurrentPermissions & 7) << 13;
440 // evil creatores only beyond this point. You have been 504 foldedPerms |= permsMask;
441 // warned. 505
442 506 bool isRootMod = (item.CurrentPermissions &
443 // We're going to mask a lot of things by the next perms 507 (uint)PermissionMask.Modify) != 0 ?
444 // Tweak the next perms to be nicer to our data 508 true : false;
445 // 509
446 // In this mask, all the bits we do NOT want to mess 510 // Mask the owner perms to the folded perms
447 // with are set. These are: 511 ownerPerms &= foldedPerms;
448 // 512 basePerms &= foldedPerms;
449 // Transfer 513
450 // Copy 514 // If the root was mod, let the mask reflect that
451 // Modufy 515 // We also need to adjust the base here, because
452 uint permsMask = ~ ((uint)PermissionMask.Copy | 516 // we should be able to edit in-inventory perms
453 (uint)PermissionMask.Transfer | 517 // for the root prim, if it's mod.
454 (uint)PermissionMask.Modify); 518 if (isRootMod)
455
456 // Now, reduce the next perms to the mask bits
457 // relevant to the operation
458 uint nextPerms = permsMask | (item.NextPermissions &
459 ((uint)PermissionMask.Copy |
460 (uint)PermissionMask.Transfer |
461 (uint)PermissionMask.Modify));
462
463 // nextPerms now has all bits set, except for the actual
464 // next permission bits.
465
466 // This checks for no mod, no copy, no trans.
467 // This indicates an error or messed up item. Do it like
468 // SL and assume trans
469 if (nextPerms == permsMask)
470 nextPerms |= (uint)PermissionMask.Transfer;
471
472 // Inventory owner perms are the logical AND of the
473 // folded perms and the root prim perms, however, if
474 // the root prim is mod, the inventory perms will be
475 // mod. This happens on "take" and is of little concern
476 // here, save for preventing escalation
477
478 // This hack ensures that items previously permalocked
479 // get unlocked when they're passed or rezzed
480 uint basePerms = item.BasePermissions |
481 (uint)PermissionMask.Move;
482 uint ownerPerms = item.CurrentPermissions;
483
484 // If this is an object, root prim perms may be more
485 // permissive than folded perms. Use folded perms as
486 // a mask
487 if (item.InvType == (int)InventoryType.Object)
488 { 519 {
489 // Create a safe mask for the current perms 520 ownerPerms |= (uint)PermissionMask.Modify;
490 uint foldedPerms = (item.CurrentPermissions & 7) << 13; 521 basePerms |= (uint)PermissionMask.Modify;
491 foldedPerms |= permsMask;
492
493 bool isRootMod = (item.CurrentPermissions &
494 (uint)PermissionMask.Modify) != 0 ?
495 true : false;
496
497 // Mask the owner perms to the folded perms
498 ownerPerms &= foldedPerms;
499 basePerms &= foldedPerms;
500
501 // If the root was mod, let the mask reflect that
502 // We also need to adjust the base here, because
503 // we should be able to edit in-inventory perms
504 // for the root prim, if it's mod.
505 if (isRootMod)
506 {
507 ownerPerms |= (uint)PermissionMask.Modify;
508 basePerms |= (uint)PermissionMask.Modify;
509 }
510 } 522 }
523 }
511 524
512 // These will be applied to the root prim at next rez. 525 // These will be applied to the root prim at next rez.
513 // The slam bit (bit 3) and folded permission (bits 0-2) 526 // The slam bit (bit 3) and folded permission (bits 0-2)
514 // are preserved due to the above mangling 527 // are preserved due to the above mangling
515 ownerPerms &= nextPerms; 528 ownerPerms &= nextPerms;
516 529
517 // Mask the base permissions. This is a conservative 530 // Mask the base permissions. This is a conservative
518 // approach altering only the three main perms 531 // approach altering only the three main perms
519 basePerms &= nextPerms; 532 basePerms &= nextPerms;
520 533
521 // Assign to the actual item. Make sure the slam bit is 534 // Assign to the actual item. Make sure the slam bit is
522 // set, if it wasn't set before. 535 // set, if it wasn't set before.
523 itemCopy.BasePermissions = basePerms; 536 itemCopy.BasePermissions = basePerms;
524 itemCopy.CurrentPermissions = ownerPerms; 537 itemCopy.CurrentPermissions = ownerPerms;
525 itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; 538 itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
526 539
527 itemCopy.NextPermissions = item.NextPermissions; 540 itemCopy.NextPermissions = item.NextPermissions;
528 541
529 // This preserves "everyone can move" 542 // This preserves "everyone can move"
530 itemCopy.EveryOnePermissions = item.EveryOnePermissions & 543 itemCopy.EveryOnePermissions = item.EveryOnePermissions &
531 nextPerms; 544 nextPerms;
532 545
533 // Intentionally killing "share with group" here, as 546 // Intentionally killing "share with group" here, as
534 // the recipient will not have the group this is 547 // the recipient will not have the group this is
535 // set to 548 // set to
536 itemCopy.GroupPermissions = 0; 549 itemCopy.GroupPermissions = 0;
537 } 550 }
538 else 551 else
552 {
553 itemCopy.CurrentPermissions = item.CurrentPermissions;
554 itemCopy.NextPermissions = item.NextPermissions;
555 itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
556 itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
557 itemCopy.BasePermissions = item.BasePermissions;
558 }
559
560 if (itemCopy.Folder == UUID.Zero)
561 {
562 InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
563
564 if (folder != null)
539 { 565 {
540 itemCopy.CurrentPermissions = item.CurrentPermissions; 566 itemCopy.Folder = folder.ID;
541 itemCopy.NextPermissions = item.NextPermissions;
542 itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
543 itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
544 itemCopy.BasePermissions = item.BasePermissions;
545 } 567 }
546 568 else
547 if (itemCopy.Folder == UUID.Zero)
548 { 569 {
549 InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); 570 InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
550 571
551 if (folder != null) 572 if (root != null)
552 { 573 itemCopy.Folder = root.ID;
553 itemCopy.Folder = folder.ID;
554 }
555 else 574 else
556 { 575 return null; // No destination
557 InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
558
559 if (root != null)
560 itemCopy.Folder = root.ID;
561 else
562 return null; // No destination
563 }
564 } 576 }
577 }
565 578
566 itemCopy.GroupID = UUID.Zero; 579 itemCopy.GroupID = UUID.Zero;
567 itemCopy.GroupOwned = false; 580 itemCopy.GroupOwned = false;
568 itemCopy.Flags = item.Flags; 581 itemCopy.Flags = item.Flags;
569 itemCopy.SalePrice = item.SalePrice; 582 itemCopy.SalePrice = item.SalePrice;
570 itemCopy.SaleType = item.SaleType; 583 itemCopy.SaleType = item.SaleType;
571 584
572 if (AddInventoryItem(itemCopy)) 585 if (AddInventoryItem(itemCopy))
573 { 586 {
574 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); 587 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
575 if (invAccess != null) 588 if (invAccess != null)
576 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); 589 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
577 } 590 }
578 591
579 if (!Permissions.BypassPermissions()) 592 if (!Permissions.BypassPermissions())
593 {
594 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
580 { 595 {
581 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 596 List<UUID> items = new List<UUID>();
582 { 597 items.Add(itemId);
583 List<UUID> items = new List<UUID>(); 598 InventoryService.DeleteItems(senderId, items);
584 items.Add(itemId);
585 InventoryService.DeleteItems(senderId, items);
586 }
587 } 599 }
588
589 return itemCopy;
590 }
591 else
592 {
593 m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId);
594 return null;
595 } 600 }
596 601
602 return itemCopy;
597 } 603 }
598 604
599 /// <summary> 605 /// <summary>
@@ -781,7 +787,7 @@ namespace OpenSim.Region.Framework.Scenes
781 /// <param name="asset"></param> 787 /// <param name="asset"></param>
782 /// <param name="invType"></param> 788 /// <param name="invType"></param>
783 /// <param name="nextOwnerMask"></param> 789 /// <param name="nextOwnerMask"></param>
784 private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, 790 public void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
785 AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate) 791 AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
786 { 792 {
787 CreateNewInventoryItem( 793 CreateNewInventoryItem(
@@ -836,78 +842,6 @@ namespace OpenSim.Region.Framework.Scenes
836 } 842 }
837 843
838 /// <summary> 844 /// <summary>
839 /// Create a new inventory item. Called when the client creates a new item directly within their
840 /// inventory (e.g. by selecting a context inventory menu option).
841 /// </summary>
842 /// <param name="remoteClient"></param>
843 /// <param name="transactionID"></param>
844 /// <param name="folderID"></param>
845 /// <param name="callbackID"></param>
846 /// <param name="description"></param>
847 /// <param name="name"></param>
848 /// <param name="invType"></param>
849 /// <param name="type"></param>
850 /// <param name="wearableType"></param>
851 /// <param name="nextOwnerMask"></param>
852 public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
853 uint callbackID, string description, string name, sbyte invType,
854 sbyte assetType,
855 byte wearableType, uint nextOwnerMask, int creationDate)
856 {
857 m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
858
859 if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
860 return;
861
862 InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
863 InventoryFolderBase folder = InventoryService.GetFolder(f);
864
865 if (folder == null || folder.Owner != remoteClient.AgentId)
866 return;
867
868 if (transactionID == UUID.Zero)
869 {
870 ScenePresence presence;
871 if (TryGetScenePresence(remoteClient.AgentId, out presence))
872 {
873 byte[] data = null;
874
875 if (invType == (sbyte)InventoryType.Landmark && presence != null)
876 {
877 Vector3 pos = presence.AbsolutePosition;
878 string strdata = String.Format(
879 "Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
880 presence.Scene.RegionInfo.RegionID,
881 pos.X, pos.Y, pos.Z,
882 presence.RegionHandle);
883 data = Encoding.ASCII.GetBytes(strdata);
884 }
885
886 AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId);
887 AssetService.Store(asset);
888
889 CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
890 }
891 else
892 {
893 m_log.ErrorFormat(
894 "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
895 remoteClient.AgentId);
896 }
897 }
898 else
899 {
900 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
901 if (agentTransactions != null)
902 {
903 agentTransactions.HandleItemCreationFromTransaction(
904 remoteClient, transactionID, folderID, callbackID, description,
905 name, invType, assetType, wearableType, nextOwnerMask);
906 }
907 }
908 }
909
910 /// <summary>
911 /// Link an inventory item to an existing item. 845 /// Link an inventory item to an existing item.
912 /// </summary> 846 /// </summary>
913 /// <remarks> 847 /// <remarks>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 254ad05..1575e50 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -95,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes
95 public bool m_strictAccessControl = true; 95 public bool m_strictAccessControl = true;
96 public bool m_seeIntoBannedRegion = false; 96 public bool m_seeIntoBannedRegion = false;
97 public int MaxUndoCount = 5; 97 public int MaxUndoCount = 5;
98 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
99 public bool LoginLock = false;
98 public bool LoginsDisabled = true; 100 public bool LoginsDisabled = true;
101 public bool StartDisabled = false;
99 public bool LoadingPrims; 102 public bool LoadingPrims;
100 public IXfer XferManager; 103 public IXfer XferManager;
101 104
@@ -1399,10 +1402,26 @@ namespace OpenSim.Region.Framework.Scenes
1399 IConfig startupConfig = m_config.Configs["Startup"]; 1402 IConfig startupConfig = m_config.Configs["Startup"];
1400 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) 1403 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1401 { 1404 {
1405 // This handles a case of a region having no scripts for the RegionReady module
1406 if (m_sceneGraph.GetActiveScriptsCount() == 0)
1407 {
1408 // need to be able to tell these have changed in RegionReady
1409 LoginLock = false;
1410 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
1411 }
1402 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); 1412 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1403 LoginsDisabled = false; 1413 // For RegionReady lockouts
1414 if( LoginLock == false)
1415 {
1416 LoginsDisabled = false;
1417 }
1404 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo); 1418 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1405 } 1419 }
1420 else
1421 {
1422 StartDisabled = true;
1423 LoginsDisabled = true;
1424 }
1406 } 1425 }
1407 } 1426 }
1408 catch (NotImplementedException) 1427 catch (NotImplementedException)
@@ -1765,6 +1784,7 @@ namespace OpenSim.Region.Framework.Scenes
1765 1784
1766 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); 1785 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
1767 LoadingPrims = false; 1786 LoadingPrims = false;
1787 EventManager.TriggerPrimsLoaded(this);
1768 } 1788 }
1769 1789
1770 1790
@@ -1930,6 +1950,10 @@ namespace OpenSim.Region.Framework.Scenes
1930 sceneObject.SetGroup(groupID, null); 1950 sceneObject.SetGroup(groupID, null);
1931 } 1951 }
1932 1952
1953 IUserManagement uman = RequestModuleInterface<IUserManagement>();
1954 if (uman != null)
1955 sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
1956
1933 sceneObject.ScheduleGroupForFullUpdate(); 1957 sceneObject.ScheduleGroupForFullUpdate();
1934 1958
1935 return sceneObject; 1959 return sceneObject;
@@ -2658,6 +2682,10 @@ namespace OpenSim.Region.Framework.Scenes
2658 if (TryGetScenePresence(client.AgentId, out presence)) 2682 if (TryGetScenePresence(client.AgentId, out presence))
2659 { 2683 {
2660 m_LastLogin = Util.EnvironmentTickCount(); 2684 m_LastLogin = Util.EnvironmentTickCount();
2685
2686 // Cache the user's name
2687 CacheUserName(aCircuit);
2688
2661 EventManager.TriggerOnNewClient(client); 2689 EventManager.TriggerOnNewClient(client);
2662 if (vialogin) 2690 if (vialogin)
2663 { 2691 {
@@ -2671,6 +2699,28 @@ namespace OpenSim.Region.Framework.Scenes
2671 } 2699 }
2672 } 2700 }
2673 2701
2702 private void CacheUserName(AgentCircuitData aCircuit)
2703 {
2704 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
2705 if (uMan != null)
2706 {
2707 string homeURL = string.Empty;
2708 string first = aCircuit.firstname, last = aCircuit.lastname;
2709 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
2710 homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
2711 if (aCircuit.lastname.StartsWith("@"))
2712 {
2713 string[] parts = aCircuit.firstname.Split('.');
2714 if (parts.Length >= 2)
2715 {
2716 first = parts[0];
2717 last = parts[1];
2718 }
2719 }
2720 uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
2721 }
2722 }
2723
2674 private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin) 2724 private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
2675 { 2725 {
2676 vialogin = false; 2726 vialogin = false;
@@ -2813,7 +2863,7 @@ namespace OpenSim.Region.Framework.Scenes
2813 2863
2814 public virtual void SubscribeToClientInventoryEvents(IClientAPI client) 2864 public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
2815 { 2865 {
2816 client.OnCreateNewInventoryItem += CreateNewInventoryItem; 2866
2817 client.OnLinkInventoryItem += HandleLinkInventoryItem; 2867 client.OnLinkInventoryItem += HandleLinkInventoryItem;
2818 client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder; 2868 client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
2819 client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder; 2869 client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
@@ -2837,7 +2887,6 @@ namespace OpenSim.Region.Framework.Scenes
2837 public virtual void SubscribeToClientTeleportEvents(IClientAPI client) 2887 public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
2838 { 2888 {
2839 client.OnTeleportLocationRequest += RequestTeleportLocation; 2889 client.OnTeleportLocationRequest += RequestTeleportLocation;
2840 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
2841 } 2890 }
2842 2891
2843 public virtual void SubscribeToClientScriptEvents(IClientAPI client) 2892 public virtual void SubscribeToClientScriptEvents(IClientAPI client)
@@ -2941,7 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
2941 2990
2942 public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client) 2991 public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
2943 { 2992 {
2944 client.OnCreateNewInventoryItem -= CreateNewInventoryItem; 2993
2945 client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder; 2994 client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
2946 client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder; 2995 client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
2947 client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!! 2996 client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
@@ -2963,7 +3012,7 @@ namespace OpenSim.Region.Framework.Scenes
2963 public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client) 3012 public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
2964 { 3013 {
2965 client.OnTeleportLocationRequest -= RequestTeleportLocation; 3014 client.OnTeleportLocationRequest -= RequestTeleportLocation;
2966 client.OnTeleportLandmarkRequest -= RequestTeleportLandmark; 3015 //client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
2967 //client.OnTeleportHomeRequest -= TeleportClientHome; 3016 //client.OnTeleportHomeRequest -= TeleportClientHome;
2968 } 3017 }
2969 3018
@@ -4064,26 +4113,6 @@ namespace OpenSim.Region.Framework.Scenes
4064 } 4113 }
4065 } 4114 }
4066 4115
4067 /// <summary>
4068 /// Tries to teleport agent to landmark.
4069 /// </summary>
4070 /// <param name="remoteClient"></param>
4071 /// <param name="regionHandle"></param>
4072 /// <param name="position"></param>
4073 public void RequestTeleportLandmark(IClientAPI remoteClient, UUID regionID, Vector3 position)
4074 {
4075 GridRegion info = GridService.GetRegionByUUID(UUID.Zero, regionID);
4076
4077 if (info == null)
4078 {
4079 // can't find the region: Tell viewer and abort
4080 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
4081 return;
4082 }
4083
4084 RequestTeleportLocation(remoteClient, info.RegionHandle, position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark));
4085 }
4086
4087 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) 4116 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
4088 { 4117 {
4089 if (m_teleportModule != null) 4118 if (m_teleportModule != null)
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 95ded7f..5c284b9 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -121,7 +121,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
121 } 121 }
122 } 122 }
123 123
124
125 /// <summary> 124 /// <summary>
126 /// Serialize a scene object to the original xml format 125 /// Serialize a scene object to the original xml format
127 /// </summary> 126 /// </summary>
@@ -572,7 +571,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
572 571
573 private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) 572 private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
574 { 573 {
575 obj.Shape = ReadShape(reader, "Shape"); 574 bool errors = false;
575 obj.Shape = ReadShape(reader, "Shape", out errors);
576
577 if (errors)
578 m_log.DebugFormat(
579 "[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors. Please see earlier log entries.",
580 obj.Name, obj.UUID);
576 } 581 }
577 582
578 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) 583 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
@@ -1479,7 +1484,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1479 } 1484 }
1480 catch (Exception e) 1485 catch (Exception e)
1481 { 1486 {
1482 m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing {0}: {1}", nodeName, e); 1487 m_log.DebugFormat(
1488 "[SceneObjectSerializer]: exception while parsing {0} in object {1} {2}: {3}{4}",
1489 obj.Name, obj.UUID, nodeName, e.Message, e.StackTrace);
1483 if (reader.NodeType == XmlNodeType.EndElement) 1490 if (reader.NodeType == XmlNodeType.EndElement)
1484 reader.Read(); 1491 reader.Read();
1485 } 1492 }
@@ -1531,8 +1538,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1531 return tinv; 1538 return tinv;
1532 } 1539 }
1533 1540
1534 static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name) 1541 /// <summary>
1542 /// Read a shape from xml input
1543 /// </summary>
1544 /// <param name="reader"></param>
1545 /// <param name="name">The name of the xml element containing the shape</param>
1546 /// <param name="errors">true if any errors were encountered during parsing, false otherwise</param>
1547 /// <returns>The shape parsed</returns>
1548 static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
1535 { 1549 {
1550 errors = false;
1551
1536 PrimitiveBaseShape shape = new PrimitiveBaseShape(); 1552 PrimitiveBaseShape shape = new PrimitiveBaseShape();
1537 1553
1538 reader.ReadStartElement(name, String.Empty); // Shape 1554 reader.ReadStartElement(name, String.Empty); // Shape
@@ -1551,7 +1567,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1551 } 1567 }
1552 catch (Exception e) 1568 catch (Exception e)
1553 { 1569 {
1554 m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing Shape {0}: {1}", nodeName, e); 1570 errors = true;
1571 m_log.DebugFormat(
1572 "[SceneObjectSerializer]: exception while parsing Shape property {0}: {1}{2}",
1573 nodeName, e.Message, e.StackTrace);
1574
1555 if (reader.NodeType == XmlNodeType.EndElement) 1575 if (reader.NodeType == XmlNodeType.EndElement)
1556 reader.Read(); 1576 reader.Read();
1557 } 1577 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
new file mode 100644
index 0000000..abca792
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -0,0 +1,110 @@
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.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using System.Threading;
33using System.Timers;
34using Timer=System.Timers.Timer;
35using Nini.Config;
36using NUnit.Framework;
37using OpenMetaverse;
38using OpenMetaverse.Assets;
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
44using OpenSim.Region.CoreModules.World.Serialiser;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49
50namespace OpenSim.Region.Framework.Tests
51{
52 [TestFixture]
53 public class UserInventoryTests
54 {
55 [Test]
56 public void TestGiveInventoryItem()
57 {
58 TestHelper.InMethod();
59// log4net.Config.XmlConfigurator.Configure();
60
61 Scene scene = SceneSetupHelpers.SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001);
63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002);
64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID);
65
66 scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID);
67
68 InventoryItemBase retrievedItem1
69 = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Notecards/item1");
70
71 Assert.That(retrievedItem1, Is.Not.Null);
72
73 // Try giving back the freshly received item
74 scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID);
75
76 List<InventoryItemBase> reretrievedItems
77 = UserInventoryHelpers.GetInventoryItems(scene.InventoryService, user1.PrincipalID, "Notecards/item1");
78
79 Assert.That(reretrievedItems.Count, Is.EqualTo(2));
80 }
81
82 [Test]
83 public void TestGiveInventoryFolder()
84 {
85 TestHelper.InMethod();
86// log4net.Config.XmlConfigurator.Configure();
87
88 Scene scene = SceneSetupHelpers.SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001);
90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002);
91 InventoryFolderBase folder1
92 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1");
93
94 scene.GiveInventoryFolder(user2.PrincipalID, user1.PrincipalID, folder1.ID, UUID.Zero);
95
96 InventoryFolderBase retrievedFolder1
97 = UserInventoryHelpers.GetInventoryFolder(scene.InventoryService, user2.PrincipalID, "folder1");
98
99 Assert.That(retrievedFolder1, Is.Not.Null);
100
101 // Try giving back the freshly received folder
102 scene.GiveInventoryFolder(user1.PrincipalID, user2.PrincipalID, retrievedFolder1.ID, UUID.Zero);
103
104 List<InventoryFolderBase> reretrievedFolders
105 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, "folder1");
106
107 Assert.That(reretrievedFolders.Count, Is.EqualTo(2));
108 }
109 }
110} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 07af201..4045507 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -1183,7 +1183,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1183 IRC_SendChannelPrivmsg(objectname,url); 1183 IRC_SendChannelPrivmsg(objectname,url);
1184 } 1184 }
1185 1185
1186 public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) 1186 public void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
1187 { 1187 {
1188 1188
1189 } 1189 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 1c791b9..630fcab 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -1223,6 +1223,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1223 1223
1224 /// <summary> 1224 /// <summary>
1225 /// Get a list of groups memberships for the agent that are marked "ListInProfile" 1225 /// Get a list of groups memberships for the agent that are marked "ListInProfile"
1226 /// (unless that agent has a godLike aspect, in which case get all groups)
1226 /// </summary> 1227 /// </summary>
1227 /// <param name="dataForAgentID"></param> 1228 /// <param name="dataForAgentID"></param>
1228 /// <returns></returns> 1229 /// <returns></returns>
@@ -1231,20 +1232,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1231 List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); 1232 List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID);
1232 GroupMembershipData[] membershipArray; 1233 GroupMembershipData[] membershipArray;
1233 1234
1234 if (requestingClient.AgentId != dataForAgentID) 1235 // cScene and property accessor 'isGod' are in support of the opertions to bypass 'hidden' group attributes for
1235 { 1236 // those with a GodLike aspect.
1236 Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership) 1237 Scene cScene = (Scene)requestingClient.Scene;
1237 { 1238 bool isGod = cScene.Permissions.IsGod(requestingClient.AgentId);
1238 return membership.ListInProfile;
1239 };
1240 1239
1241 membershipArray = membershipData.FindAll(showInProfile).ToArray(); 1240 if (isGod)
1242 }
1243 else
1244 { 1241 {
1245 membershipArray = membershipData.ToArray(); 1242 membershipArray = membershipData.ToArray();
1246 } 1243 }
1244 else
1245 {
1246 if (requestingClient.AgentId != dataForAgentID)
1247 {
1248 Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership)
1249 {
1250 return membership.ListInProfile;
1251 };
1247 1252
1253 membershipArray = membershipData.FindAll(showInProfile).ToArray();
1254 }
1255 else
1256 {
1257 membershipArray = membershipData.ToArray();
1258 }
1259 }
1260
1248 if (m_debugEnabled) 1261 if (m_debugEnabled)
1249 { 1262 {
1250 m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); 1263 m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId);
@@ -1257,6 +1270,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1257 return membershipArray; 1270 return membershipArray;
1258 } 1271 }
1259 1272
1273
1260 private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) 1274 private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle)
1261 { 1275 {
1262 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1276 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs
deleted file mode 100644
index 4a402bf..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs
+++ /dev/null
@@ -1,161 +0,0 @@
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
28#region Header
29
30// AuraMetaEntity.cs created with MonoDevelop
31// User: bongiojp at 3:03 PM 8/6/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections.Generic;
40using System.Drawing;
41
42using OpenMetaverse;
43
44using Nini.Config;
45
46using OpenSim.Framework;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Physics.Manager;
50
51using log4net;
52
53namespace OpenSim.Region.OptionalModules.ContentManagement
54{
55 public class AuraMetaEntity : PointMetaEntity
56 {
57 #region Constructors
58
59 //transparency of root part, NOT particle system. Should probably add support for changing particle system transparency.
60 public AuraMetaEntity(Scene scene, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
61 : base(scene, groupPos, transparency)
62 {
63 SetAura(color, scale);
64 }
65
66 public AuraMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
67 : base(scene, uuid, groupPos, transparency)
68 {
69 SetAura(color, scale);
70 }
71
72 #endregion Constructors
73
74 #region Private Methods
75
76 private float Average(Vector3 values)
77 {
78 return (values.X + values.Y + values.Z)/3f;
79 }
80
81 #endregion Private Methods
82
83 #region Public Methods
84
85 public void SetAura(Vector3 color, Vector3 scale)
86 {
87 SetAura(color, Average(scale) * 2.0f);
88 }
89
90 public void SetAura(Vector3 color, float radius)
91 {
92 SceneObjectPart From = m_Entity.RootPart;
93
94 //m_log.Debug("[META ENTITY] BEFORE: radius = " + radius);
95 float burstRadius = 0.1f;
96 Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None;
97 float age = 1.5f;
98 float burstRate = 0.4f;
99 if (radius >= 8.0f)
100 {
101 //float sizeOfObject = radius / 2.0f;
102 burstRadius = (radius - 8.0f)/3f;
103 burstRate = 1.5f;
104 radius = 7.99f;
105 patternFlags = Primitive.ParticleSystem.SourcePattern.Explode;
106 age = 4.0f;
107 }
108 SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags);
109 }
110
111 public void SetAura(SceneObjectPart From, Vector3 color, float radius, float burstRadius, float age, float burstRate, Primitive.ParticleSystem.SourcePattern patternFlags)
112 {
113 Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
114 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
115 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
116 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
117 // Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
118 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
119 prules.PartStartColor.G = color.Y;
120 prules.PartStartColor.B = color.Z;
121 prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency
122 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
123 prules.PartEndColor.G = color.Y;
124 prules.PartEndColor.B = color.Z;
125 prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency
126 /*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE
127 prules.PartStartScaleY = 0.5f;
128 prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE
129 prules.PartEndScaleY = 0.5f;
130 */
131 prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE
132 prules.PartStartScaleY = radius;
133 prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE
134 prules.PartEndScaleY = radius;
135 prules.PartMaxAge = age; //PSYS_PART_MAX_AGE
136 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
137 prules.PartAcceleration.Y = 0.0f;
138 prules.PartAcceleration.Z = 0.0f;
139 prules.Pattern = patternFlags; //PSYS_SRC_PATTERN
140 //prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
141 prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE
142 prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT
143 //prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS
144 prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS
145 prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN
146 prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX
147 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
148 //prules.Target = To; //PSYS_SRC_TARGET_KEY
149 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
150 prules.AngularVelocity.Y = 0.0f;
151 prules.AngularVelocity.Z = 0.0f;
152 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
153 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
154
155 prules.CRC = 1; //activates the particle system??
156 From.AddNewParticleSystem(prules);
157 }
158
159 #endregion Public Methods
160 }
161}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs
deleted file mode 100644
index 6966de0..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs
+++ /dev/null
@@ -1,139 +0,0 @@
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
28#region Header
29
30// BeamMetaEntity.cs created with MonoDevelop
31// User: bongiojp at 3:03 PM 8/6/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections.Generic;
40using System.Drawing;
41
42using OpenMetaverse;
43
44using Nini.Config;
45
46using OpenSim.Framework;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Physics.Manager;
50
51using log4net;
52
53namespace OpenSim.Region.OptionalModules.ContentManagement
54{
55 public class BeamMetaEntity : PointMetaEntity
56 {
57 #region Constructors
58
59 public BeamMetaEntity(Scene scene, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
60 : base(scene, groupPos, transparency)
61 {
62 SetBeamToUUID(To, color);
63 }
64
65 public BeamMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
66 : base(scene, uuid, groupPos, transparency)
67 {
68 SetBeamToUUID(To, color);
69 }
70
71 #endregion Constructors
72
73 #region Public Methods
74
75 public void SetBeamToUUID(SceneObjectPart To, Vector3 color)
76 {
77 SceneObjectPart From = m_Entity.RootPart;
78 //Scale size of particles to distance objects are apart (for better visibility)
79 Vector3 FromPos = From.GetWorldPosition();
80 Vector3 ToPos = From.GetWorldPosition();
81 // UUID toUUID = To.UUID;
82 float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) +
83 Math.Pow(FromPos.X-ToPos.Y, 2) +
84 Math.Pow(FromPos.X-ToPos.Z, 2)
85 )
86 );
87 //float rate = (float) (distance/4f);
88 float rate = 0.5f;
89 float scale = (float) (distance/128f);
90 float speed = (float) (2.0f - distance/128f);
91
92 SetBeamToUUID(From, To, color, rate, scale, speed);
93 }
94
95 public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, Vector3 color, float rate, float scale, float speed)
96 {
97 Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
98 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
99 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
100 prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
101 Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
102 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
103 prules.PartStartColor.G = color.Y;
104 prules.PartStartColor.B = color.Z;
105 prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency
106 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
107 prules.PartEndColor.G = color.Y;
108 prules.PartEndColor.B = color.Z;
109 prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency
110 prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE
111 prules.PartStartScaleY = scale;
112 prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE
113 prules.PartEndScaleY = scale;
114 prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE
115 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
116 prules.PartAcceleration.Y = 0.0f;
117 prules.PartAcceleration.Z = 0.0f;
118 //prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN
119 //prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
120 prules.BurstRate = rate; //PSYS_SRC_BURST_RATE
121 prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT
122 prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS
123 prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN
124 prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX
125 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
126 prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY
127 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
128 prules.AngularVelocity.Y = 0.0f;
129 prules.AngularVelocity.Z = 0.0f;
130 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
131 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
132
133 prules.CRC = 1; //activates the particle system??
134 From.AddNewParticleSystem(prules);
135 }
136
137 #endregion Public Methods
138 }
139}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs
deleted file mode 100644
index 8d6c41d..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs
+++ /dev/null
@@ -1,756 +0,0 @@
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
28#region Header
29
30// CMController.cs
31// User: bongiojp
32//
33
34#endregion Header
35
36using System;
37using System.Collections;
38using System.Collections.Generic;
39using System.Diagnostics;
40using System.Threading;
41
42using OpenMetaverse;
43
44using OpenSim;
45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49
50using log4net;
51
52namespace OpenSim.Region.OptionalModules.ContentManagement
53{
54 /// <summary>
55 /// The controller in a Model-View-Controller framework. This controller catches actions by the avatars, creates work packets, loops through these work packets in a separate thread,
56 /// then dictates to the model how the data should change and dictates to the view which data should be displayed. The main mechanism for interaction is through the simchat system.
57 /// </summary>
58 public class CMController
59 {
60 #region Static Fields
61
62 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
63
64 /// <value>
65 /// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue.
66 /// </value>
67 private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>();
68
69 #endregion Static Fields
70
71 #region Fields
72
73 //bool init = false;
74 int m_channel = -1;
75
76 /// <value>
77 /// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers.
78 /// </value>
79 IEstateModule m_estateModule = null;
80
81 //These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop)
82 CMModel m_model = null;
83
84 /// <value>
85 /// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region.
86 /// </value>
87 Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable());
88 State m_state = State.NONE;
89 CMView m_view = null;
90
91 #endregion Fields
92
93 #region Constructors
94
95 /// <summary>
96 /// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method.
97 /// </summary>
98 /// <param name="model">
99 /// <see cref="CMModel"/>
100 /// </param>
101 /// <param name="view">
102 /// <see cref="CMView"/>
103 /// </param>
104 /// <param name="scene">
105 /// The first scene to keep track of. <see cref="Scene"/>
106 /// </param>
107 /// <param name="channel">
108 /// The simchat channel number to listen to for instructions <see cref="System.Int32"/>
109 /// </param>
110 public CMController(CMModel model, CMView view, Scene scene, int channel)
111 {
112 m_model = model; m_view = view; m_channel = channel;
113 RegisterNewRegion(scene);
114 Initialize(model, view, scene, channel);
115 }
116
117 #endregion Constructors
118
119 #region Private Methods
120
121 //------------------------------------------------ EVENTS ----------------------------------------------------//
122// private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
123// {
124// }
125
126 /// <summary>
127 /// Searches in all scenes for a SceneObjectGroup that contains a part with a specific localID. If found, the object is returned. Else null is returned.
128 /// </summary>
129 private SceneObjectGroup GetGroupByPrim(uint localID)
130 {
131 foreach (Object currScene in m_sceneList.Values)
132 {
133 foreach (EntityBase ent in ((Scene)currScene).GetEntities())
134 {
135 if (ent is SceneObjectGroup)
136 {
137 if (((SceneObjectGroup)ent).HasChildPrim(localID))
138 return (SceneObjectGroup)ent;
139 }
140 }
141 }
142 return null;
143 }
144
145 private void Initialize(CMModel model, CMView view, Scene scene, int channel)
146 {
147 lock (this)
148 {
149 m_estateModule = scene.RequestModuleInterface<IEstateModule>();
150 Watchdog.StartThread(MainLoop, "Content Management", ThreadPriority.Normal, true);
151 m_state = State.NONE;
152 }
153 }
154
155 /// <summary>
156 /// Run in a thread of its own. A endless loop that consumes (or blocks on) and work queue. Thw work queue is filled through client actions.
157 /// </summary>
158 private void MainLoop()
159 {
160 try
161 {
162 CMModel model = m_model; CMView view = m_view; int channel = m_channel;
163 Work currentJob = new Work();
164 while (true)
165 {
166 currentJob = m_WorkQueue.Dequeue();
167 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request");
168 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type);
169 switch (currentJob.Type)
170 {
171 case WorkType.NONE:
172 break;
173 case WorkType.OBJECTATTRIBUTECHANGE:
174 ObjectAttributeChanged(model, view, currentJob.LocalId);
175 break;
176 case WorkType.PRIMITIVEADDED:
177 PrimitiveAdded(model, view, currentJob);
178 break;
179 case WorkType.OBJECTDUPLICATED:
180 ObjectDuplicated(model, view, currentJob.LocalId);
181 break;
182 case WorkType.OBJECTKILLED:
183 ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1);
184 break;
185 case WorkType.UNDODID:
186 UndoDid(model, view, currentJob.UUID);
187 break;
188 case WorkType.NEWCLIENT:
189 NewClient(view, (IClientAPI) currentJob.Data1);
190 break;
191 case WorkType.SIMCHAT:
192 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message);
193 SimChat(model, view, (OSChatMessage) currentJob.Data1, channel);
194 break;
195 default:
196 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?");
197 break;
198 }
199
200 Watchdog.UpdateThread();
201 }
202 }
203 catch (Exception e)
204 {
205 // TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened
206 m_log.ErrorFormat(
207 "[CONTENT MANAGEMENT]: Content management thread terminating with exception. PLEASE REBOOT YOUR SIM - CONTENT MANAGEMENT WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}",
208 e);
209 }
210
211 Watchdog.RemoveThread();
212 }
213
214 /// <summary>
215 /// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled.
216 /// </summary>
217 private void NewClient(CMView view, IClientAPI client)
218 {
219 if ((m_state & State.SHOWING_CHANGES) > 0)
220 view.SendMetaEntitiesToNewClient(client);
221 }
222
223 /// <summary>
224 /// Only called by the MainLoop.
225 /// </summary>
226 private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId)
227 {
228 SceneObjectGroup group = null;
229 if ((m_state & State.SHOWING_CHANGES) > 0)
230 {
231 group = GetGroupByPrim(LocalId);
232 if (group != null)
233 {
234 view.DisplayAuras(model.UpdateNormalEntityEffects(group)); //Might be a normal entity (green aura)
235 m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura)
236 }
237 }
238 }
239
240 /// <summary>
241 /// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied.
242 /// </summary>
243 private void ObjectDuplicated(CMModel model, CMView view, uint localId)
244 {
245 if ((m_state & State.SHOWING_CHANGES) > 0)
246 view.DisplayAuras(model.CheckForNewEntitiesMissingAuras(GetGroupByPrim(localId).Scene));
247 }
248
249 /// <summary>
250 /// Only called by the MainLoop.
251 /// </summary>
252 private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group)
253 {
254 if ((m_state & State.SHOWING_CHANGES) > 0)
255 {
256 view.RemoveOrUpdateDeletedEntity(group);
257 model.RemoveOrUpdateDeletedEntity(group);
258 }
259 }
260
261 /// <summary>
262 /// Only called by the MainLoop.
263 /// </summary>
264 private void PrimitiveAdded(CMModel model, CMView view, Work currentJob)
265 {
266 if ((m_state & State.SHOWING_CHANGES) > 0)
267 {
268 foreach (Object scene in m_sceneList.Values)
269 m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene));
270 }
271 }
272
273 /// <summary>
274 /// Only called by the MainLoop.
275 /// </summary>
276 private void UndoDid(CMModel model, CMView view, UUID uuid)
277 {
278 if ((m_state & State.SHOWING_CHANGES) > 0)
279 {
280 ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid);
281 if (ent != null)
282 view.DisplayEntity(ent);
283 }
284 }
285
286 #endregion Private Methods
287
288 #region Protected Methods
289
290 protected void GroupBeingDeleted(SceneObjectGroup group)
291 {
292 m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!");
293 Work moreWork = new Work();
294 moreWork.Type = WorkType.OBJECTKILLED;
295 moreWork.Data1 = group.Copy();
296 m_WorkQueue.Enqueue(moreWork);
297 }
298
299 protected void ObjectDuplicated(uint localID, Vector3 offset, uint dupeFlags, UUID AgentID, UUID GroupID)
300 {
301 Work moreWork = new Work();
302 moreWork.Type = WorkType.OBJECTDUPLICATED;
303 moreWork.LocalId = localID;
304 m_WorkQueue.Enqueue(moreWork);
305 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
306 }
307
308 protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
309 UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
310 bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
311 {
312 Work moreWork = new Work();
313 moreWork.Type = WorkType.OBJECTDUPLICATED;
314 moreWork.LocalId = localID;
315 m_WorkQueue.Enqueue(moreWork);
316 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
317 }
318
319 protected void OnNewClient(IClientAPI client)
320 {
321 Work moreWork = new Work();
322 moreWork.Type = WorkType.NEWCLIENT;
323 moreWork.Data1 = client;
324 m_WorkQueue.Enqueue(moreWork);
325 m_log.Debug("[CONTENT MANAGEMENT] new client");
326 }
327
328 protected void OnUnDid(IClientAPI remoteClient, UUID primId)
329 {
330 Work moreWork = new Work();
331 moreWork.Type = WorkType.UNDODID;
332 moreWork.UUID = primId;
333 m_WorkQueue.Enqueue(moreWork);
334 m_log.Debug("[CONTENT MANAGEMENT] undid");
335 }
336
337 /// <summary>
338 /// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument.
339 /// </summary>
340 protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity(Hashtable sceneList, Scene scene)
341 {
342 int somethingAddedToList = 1;
343 System.Collections.Generic.List<Scene> newList = new List<Scene>();
344 newList.Add(scene);
345
346 if (!sceneList.ContainsValue(scene))
347 {
348 foreach (Object sceneObj in sceneList)
349 newList.Add((Scene) sceneObj);
350 return newList;
351 }
352
353 while (somethingAddedToList > 0)
354 {
355 somethingAddedToList = 0;
356 for (int i = 0; i < newList.Count; i++)
357 {
358 foreach (Object sceneObj in sceneList.Values)
359 {
360 if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (!newList.Contains((Scene)sceneObj)))
361 {
362 newList.Add((Scene)sceneObj);
363 somethingAddedToList++;
364 }
365 }
366 }
367 }
368
369 foreach (Object sceneObj in sceneList.Values)
370 if (!newList.Contains((Scene)sceneObj))
371 newList.Add((Scene)sceneObj);
372
373 return newList;
374 }
375
376 //This is stupid, the same information is contained in the first and second argument
377 protected void SimChatSent(Object x, OSChatMessage e)
378 {
379 m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!");
380 m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message);
381 Work moreWork = new Work();
382 moreWork.Type = WorkType.SIMCHAT;
383 moreWork.Data1 = e;
384 m_WorkQueue.Enqueue(moreWork);
385 }
386
387 /// <summary>
388 /// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions.
389 /// </summary>
390 protected void StartManaging(IClientAPI client)
391 {
392 m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services.");
393 // client.OnChatFromClient += SimChatSent;
394 //init = true;
395
396 OnNewClient(client);
397
398 m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client.");
399 client.OnUpdatePrimScale += UpdateSingleScale;
400 client.OnUpdatePrimGroupScale += UpdateMultipleScale;
401 client.OnUpdatePrimGroupPosition += UpdateMultiplePosition;
402 client.OnUpdatePrimSinglePosition += UpdateSinglePosition;
403 client.OnUpdatePrimGroupRotation += UpdateMultipleRotation;
404 client.OnUpdatePrimSingleRotation += UpdateSingleRotation;
405 client.OnAddPrim += UpdateNewParts;
406 client.OnObjectDuplicate += ObjectDuplicated;
407 client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay;
408 client.OnUndo += OnUnDid;
409 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
410 }
411
412 /// <summary>
413 ///
414 /// </summary>
415 protected void StopManaging(UUID clientUUID)
416 {
417 foreach (Object sceneobj in m_sceneList.Values)
418 {
419 ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID);
420 if (presence != null)
421 {
422 IClientAPI client = presence.ControllingClient;
423 m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services.");
424 // client.OnChatFromViewer -= SimChatSent;
425
426 m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client");
427 client.OnUpdatePrimScale -= UpdateSingleScale;
428 client.OnUpdatePrimGroupScale -= UpdateMultipleScale;
429 client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition;
430 client.OnUpdatePrimSinglePosition -= UpdateSinglePosition;
431 client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation;
432 client.OnUpdatePrimSingleRotation -= UpdateSingleRotation;
433 client.OnAddPrim -= UpdateNewParts;
434 client.OnObjectDuplicate -= ObjectDuplicated;
435 client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay;
436 client.OnUndo -= OnUnDid;
437 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
438 return;
439 }
440 }
441 }
442
443 protected void UpdateMultiplePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
444 {
445 Work moreWork = new Work();
446 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
447 moreWork.LocalId = localID;
448 m_WorkQueue.Enqueue(moreWork);
449 m_log.Debug("[CONTENT MANAGEMENT] pos");
450 }
451
452 protected void UpdateMultipleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
453 {
454 Work moreWork = new Work();
455 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
456 moreWork.LocalId = localID;
457 m_WorkQueue.Enqueue(moreWork);
458 m_log.Debug("[CONTENT MANAGEMENT] rot");
459 }
460
461 protected void UpdateMultipleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
462 {
463 Work moreWork = new Work();
464 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
465 moreWork.LocalId = localID;
466 m_WorkQueue.Enqueue(moreWork);
467 m_log.Debug("[CONTENT MANAGEMENT]scale");
468 }
469
470 protected void UpdateNewParts(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
471 byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
472 byte RayEndIsIntersection)
473 {
474 Work moreWork = new Work();
475 moreWork.Type = WorkType.PRIMITIVEADDED;
476 moreWork.UUID = ownerID;
477 m_WorkQueue.Enqueue(moreWork);
478 m_log.Debug("[CONTENT MANAGEMENT] new parts");
479 }
480
481 protected void UpdateSinglePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
482 {
483 Work moreWork = new Work();
484 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
485 moreWork.LocalId = localID;
486 m_WorkQueue.Enqueue(moreWork);
487 m_log.Debug("[CONTENT MANAGEMENT] move");
488 }
489
490 /// <summary>
491 ///
492 /// </summary>
493 protected void UpdateSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
494 {
495 Work moreWork = new Work();
496 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
497 moreWork.LocalId = localID;
498 m_WorkQueue.Enqueue(moreWork);
499 m_log.Debug("[CONTENT MANAGEMENT] rot");
500 }
501
502 protected void UpdateSingleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
503 {
504 Work moreWork = new Work();
505 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
506 moreWork.LocalId = localID;
507 m_WorkQueue.Enqueue(moreWork);
508 m_log.Debug("[CONTENT MANAGEMENT] scale");
509 }
510
511 /// <summary>
512 /// Only called from within the SimChat method.
513 /// </summary>
514 protected void commit(string message, Scene scene, CMModel model, CMView view)
515 {
516 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
517
518 string[] args = message.Split(new char[] {' '});
519
520 char[] logMessage = {' '};
521 if (args.Length > 1)
522 {
523 logMessage = new char[message.Length - (args[0].Length)];
524 message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length));
525 }
526
527 m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region.");
528 foreach (Scene currScene in proximitySceneList)
529 {
530 model.CommitRegion(currScene, new String(logMessage));
531 view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName);
532 }
533
534 view.SendSimChatMessage(scene, "Successfully saved all regions.");
535 m_state |= State.DIRTY;
536
537 if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES
538 {
539 view.SendSimChatMessage(scene, "Updating differences between new revision and current environment.");
540 //Hide objects from users and Forget about them
541 view.HideAllMetaEntities();
542 view.HideAllAuras();
543 model.DeleteAllMetaObjects();
544
545 //Recreate them from backend files
546 foreach (Scene currScene in proximitySceneList)
547 {
548 model.UpdateCMEntities(currScene);
549 view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName);
550 }
551
552 //Display new objects to users1
553 view.DisplayRecentChanges();
554 view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE.");
555 m_state &= ~(State.DIRTY);
556 m_state |= State.SHOWING_CHANGES;
557 }
558 }
559
560 /// <summary>
561 /// Only called from within the SimChat method.
562 /// </summary>
563 protected void diffmode(Scene scene, CMModel model, CMView view)
564 {
565 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
566
567 if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF
568 {
569 view.SendSimChatMessage(scene, "Hiding all meta objects.");
570 view.HideAllMetaEntities();
571 view.HideAllAuras();
572 view.SendSimChatMessage(scene, "Diff-mode = OFF");
573
574 m_state &= ~State.SHOWING_CHANGES;
575 return;
576 }
577 else // TURN ON
578 {
579 if ((m_state & State.DIRTY) != 0 || m_state == State.NONE)
580 {
581 view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision");
582 //Hide objects from users and Forget about them
583 view.HideAllMetaEntities();
584 view.HideAllAuras();
585 model.DeleteAllMetaObjects();
586 //Recreate them from backend files
587 foreach (Object currScene in m_sceneList.Values)
588 model.UpdateCMEntities((Scene) currScene);
589 }
590 else if ((m_state & State.DIRTY) != 0) {
591 view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision");
592 foreach (Scene currScene in proximitySceneList)
593 model.UpdateCMEntities(currScene);
594 }
595
596 view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment");
597 foreach (Scene currScene in proximitySceneList)
598 model.CheckForNewEntitiesMissingAuras(currScene);
599 view.DisplayRecentChanges();
600
601 view.SendSimChatMessage(scene, "Diff-mode = ON");
602 m_state |= State.SHOWING_CHANGES;
603 m_state &= ~State.DIRTY;
604 }
605 }
606
607 /// <summary>
608 /// Only called from within the SimChat method. Hides all auras and meta entities,
609 /// retrieves the current scene object list with the most recent revision retrieved from the model for each scene,
610 /// then lets the view update the clients of the new objects.
611 /// </summary>
612 protected void rollback(Scene scene, CMModel model, CMView view)
613 {
614 if ((m_state & State.SHOWING_CHANGES) > 0)
615 {
616 view.HideAllAuras();
617 view.HideAllMetaEntities();
618 }
619
620 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
621 foreach (Scene currScene in proximitySceneList)
622 model.RollbackRegion(currScene);
623
624 if ((m_state & State.DIRTY) != 0)
625 {
626 model.DeleteAllMetaObjects();
627 foreach (Scene currScene in proximitySceneList)
628 model.UpdateCMEntities(currScene);
629 }
630
631 if ((m_state & State.SHOWING_CHANGES) > 0)
632 view.DisplayRecentChanges();
633 }
634
635 #endregion Protected Methods
636
637 #region Public Methods
638
639 /// <summary>
640 /// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene.
641 /// </summary>
642 /// <param name="scene">
643 /// A <see cref="Scene"/>
644 /// </param>
645 public void RegisterNewRegion(Scene scene)
646 {
647 m_sceneList.Add(scene.RegionInfo.RegionID, scene);
648
649 m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID);
650 m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System.");
651
652 scene.EventManager.OnNewClient += StartManaging;
653 scene.EventManager.OnChatFromClient += SimChatSent;
654 scene.EventManager.OnRemovePresence += StopManaging;
655 // scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
656 scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted;
657 }
658
659 /// <summary>
660 /// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command.
661 /// </summary>
662 public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel)
663 {
664 if (e.Channel != channel)
665 return;
666 if (e.Sender == null)
667 return;
668
669 m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message);
670
671 IClientAPI client = e.Sender;
672 Scene scene = (Scene) e.Scene;
673 string message = e.Message;
674 string[] args = e.Message.Split(new char[] {' '});
675
676 ScenePresence avatar = scene.GetScenePresence(client.AgentId);
677
678 if (!(m_estateModule.IsManager(avatar.UUID)))
679 {
680 m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring.");
681 view.SendSimChatMessage(scene, "You must be an estate manager to perform that action.");
682 return;
683 }
684
685 switch (args[0])
686 {
687 case "ci":
688 case "commit":
689 commit(message, scene, model, view);
690 break;
691 case "dm":
692 case "diff-mode":
693 diffmode(scene, model, view);
694 break;
695 case "rb":
696 case "rollback":
697 rollback(scene, model, view);
698 break;
699 case "help":
700 m_view.DisplayHelpMenu(scene);
701 break;
702 default:
703 view.SendSimChatMessage(scene, "Command not found: " + args[0]);
704 break;
705 }
706 }
707
708 #endregion Public Methods
709
710 #region Other
711
712 /// <value>
713 /// Used to keep track of whether a list has been produced yet and whether that list is up-to-date compard to latest revision on disk.
714 /// </value>
715 [Flags]
716 private enum State
717 {
718 NONE = 0,
719 DIRTY = 1, // The meta entities may not correctly represent the last revision.
720 SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user.
721 }
722
723 /// <value>
724 /// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem.
725 /// </value>
726 private struct Work
727 {
728 #region Fields
729
730 public Object Data1; //Just space for holding data.
731 public Object Data2; //Just more space for holding data.
732 public uint LocalId; //Convenient
733 public WorkType Type;
734 public UUID UUID; //Convenient
735
736 #endregion Fields
737 }
738
739 /// <value>
740 /// Identifies what the data in struct Work should be used for.
741 /// </value>
742 private enum WorkType
743 {
744 NONE,
745 OBJECTATTRIBUTECHANGE,
746 PRIMITIVEADDED,
747 OBJECTDUPLICATED,
748 OBJECTKILLED,
749 UNDODID,
750 NEWCLIENT,
751 SIMCHAT
752 }
753
754 #endregion Other
755 }
756}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
deleted file mode 100644
index 7f64ebd..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
+++ /dev/null
@@ -1,193 +0,0 @@
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
28#region Header
29
30// CMEntityCollection.cs created with MonoDevelop
31// User: bongiojp at 10:09 AM 7/7/2008
32//
33// Creates, Deletes, Stores ContentManagementEntities
34//
35
36#endregion Header
37
38using System;
39using System.Collections;
40using System.Collections.Generic;
41using System.Threading;
42
43using OpenMetaverse;
44
45using Nini.Config;
46
47using OpenSim;
48using OpenSim.Framework;
49using OpenSim.Region.Framework.Interfaces;
50using OpenSim.Region.Framework.Scenes;
51using OpenSim.Region.Physics.Manager;
52
53using log4net;
54
55namespace OpenSim.Region.OptionalModules.ContentManagement
56{
57 public class CMEntityCollection
58 {
59 #region Fields
60
61 // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
62 // Any ContentManagementEntities that represent old versions of current SceneObjectGroups or
63 // old versions of deleted SceneObjectGroups will be stored in this hash table.
64 // The UUID keys are from the SceneObjectGroup RootPart UUIDs
65 protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //UUID to ContentManagementEntity
66
67 // SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable
68 // The UUID keys are from the SceneObjectPart that they are supposed to be on.
69 protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //UUID to AuraMetaEntity
70
71 #endregion Fields
72
73 #region Constructors
74
75 public CMEntityCollection()
76 {
77 }
78
79 #endregion Constructors
80
81 #region Public Properties
82
83 public Hashtable Auras
84 {
85 get {return m_NewlyCreatedEntityAura; }
86 }
87
88 public Hashtable Entities
89 {
90 get { return m_CMEntityHash; }
91 }
92
93 #endregion Public Properties
94
95 #region Public Methods
96
97 public bool AddAura(ContentManagementEntity aura)
98 {
99 if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID))
100 return false;
101 m_NewlyCreatedEntityAura.Add(aura.UUID, aura);
102 return true;
103 }
104
105 public bool AddEntity(ContentManagementEntity ent)
106 {
107 if (m_CMEntityHash.ContainsKey(ent.UUID))
108 return false;
109 m_CMEntityHash.Add(ent.UUID, ent);
110 return true;
111 }
112
113 // Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash
114 public System.Collections.ArrayList CheckForMissingEntities(EntityBase[] currList)
115 {
116 System.Collections.ArrayList missingList = new System.Collections.ArrayList();
117 SceneObjectGroup temp = null;
118 foreach (EntityBase currObj in currList)
119 {
120 if (!(currObj is SceneObjectGroup))
121 continue;
122 temp = (SceneObjectGroup) currObj;
123
124 if (m_CMEntityHash.ContainsKey(temp.UUID))
125 {
126 foreach (SceneObjectPart part in temp.Parts)
127 if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
128 missingList.Add(part);
129 }
130 else //Entire group is missing from revision. (and is a new part in region)
131 {
132 foreach (SceneObjectPart part in temp.Parts)
133 missingList.Add(part);
134 }
135 }
136 return missingList;
137 }
138
139 public void ClearAll()
140 {
141 m_CMEntityHash.Clear();
142 m_NewlyCreatedEntityAura.Clear();
143 }
144
145 // Old uuid and new sceneobjectgroup
146 public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part)
147 {
148 AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene,
149 part.GetWorldPosition(),
150 MetaEntity.TRANSLUCENT,
151 new Vector3(0,254,0),
152 part.Scale
153 );
154 m_NewlyCreatedEntityAura.Add(part.UUID, ent);
155 return ent;
156 }
157
158 // Old uuid and new sceneobjectgroup
159 public ContentManagementEntity CreateNewEntity(SceneObjectGroup group)
160 {
161 ContentManagementEntity ent = new ContentManagementEntity(group, false);
162 m_CMEntityHash.Add(group.UUID, ent);
163 return ent;
164 }
165
166 public ContentManagementEntity CreateNewEntity(String xml, Scene scene)
167 {
168 ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false);
169 if (ent == null)
170 return null;
171 m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent);
172 return ent;
173 }
174
175 public bool RemoveEntity(UUID uuid)
176 {
177 if (!m_CMEntityHash.ContainsKey(uuid))
178 return false;
179 m_CMEntityHash.Remove(uuid);
180 return true;
181 }
182
183 public bool RemoveNewlyCreatedEntityAura(UUID uuid)
184 {
185 if (!m_NewlyCreatedEntityAura.ContainsKey(uuid))
186 return false;
187 m_NewlyCreatedEntityAura.Remove(uuid);
188 return true;
189 }
190
191 #endregion Public Methods
192 }
193}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
deleted file mode 100644
index 84c7f29..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
+++ /dev/null
@@ -1,366 +0,0 @@
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.Collections;
30using System.Collections.Generic;
31using System.Diagnostics;
32
33using OpenMetaverse;
34
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Framework.Scenes.Serialization;
40using OpenSim.Region.Physics.Manager;
41
42using log4net;
43
44namespace OpenSim.Region.OptionalModules.ContentManagement
45{
46 public class CMModel
47 {
48 #region Static Fields
49
50 static float TimeToUpdate = 0;
51 static float TimeToConvertXml = 0;
52 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
53
54 #endregion Static Fields
55
56 #region Fields
57
58 /// <value>
59 /// The class that contains all auras and metaentities used in the CMS.
60 /// </value>
61 CMEntityCollection m_MetaEntityCollection = new CMEntityCollection();
62 IContentDatabase m_database = null;
63
64 #endregion Fields
65
66 #region Constructors
67
68 public CMModel()
69 {
70 }
71
72 #endregion Constructors
73
74 #region Public Properties
75
76 public CMEntityCollection MetaEntityCollection
77 {
78 get { return m_MetaEntityCollection; }
79 }
80
81 #endregion Public Properties
82
83 #region Public Methods
84
85 /// <summary>
86 /// Compares the scene's object group list to the list of meta entities. If there is an object group that does not have a corresponding meta entity
87 /// it is a new part that must have a green aura (for diff mode).
88 /// Returns list of ContentManagementEntities
89 /// </summary>
90 public ArrayList CheckForNewEntitiesMissingAuras(Scene scene)
91 {
92 ArrayList missingList = null;
93 ArrayList newList = new ArrayList();
94
95 m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName);
96
97 //Check if the current scene has groups not included in the current list of MetaEntities
98 //If so, then the current scene's parts that are new should be marked green.
99 missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities());
100
101 foreach (Object missingPart in missingList)
102 {
103 if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID))
104 continue;
105 newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart));
106 }
107 m_log.Info("Number of missing objects found: " + newList.Count);
108 return newList;
109 }
110
111 /// <summary>
112 /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message.
113 /// </summary>
114 public void CommitRegion(Scene scene, String logMessage)
115 {
116 m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length);
117 m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage);
118 m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName);
119 }
120
121 public void DeleteAllMetaObjects()
122 {
123 m_MetaEntityCollection.ClearAll();
124 }
125
126 public ContentManagementEntity FindMetaEntityAffectedByUndo(UUID uuid)
127 {
128 ContentManagementEntity ent = GetMetaGroupByPrim(uuid);
129 return ent;
130 }
131
132 //-------------------------------- HELPERS --------------------------------------------------------------------//
133 public ContentManagementEntity GetMetaGroupByPrim(UUID uuid)
134 {
135 foreach (Object ent in m_MetaEntityCollection.Entities.Values)
136 {
137 if (((ContentManagementEntity)ent).HasChildPrim(uuid))
138 return (ContentManagementEntity)ent;
139 }
140 return null;
141 }
142
143 public void Initialise(string database)
144 {
145 if (database == "FileSystemDatabase")
146 m_database = new FileSystemDatabase();
147 else if (database == "GitDatabase")
148 m_database = new GitDatabase();
149 }
150
151 public void InitialiseDatabase(Scene scene, string dir)
152 {
153 m_database.Initialise(scene, dir);
154 }
155
156 /// <summary>
157 /// Should be called just once to finish initializing the database.
158 /// </summary>
159 public void PostInitialise()
160 {
161 m_database.PostInitialise();
162 }
163
164 /// <summary>
165 /// Removes the green aura when an a new scene object group is deleted.
166 /// </summary>
167 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
168 {
169 // Deal with new parts not revisioned that have been deleted.
170 SceneObjectPart[] parts = group.Parts;
171 for (int i = 0; i < parts.Length; i++)
172 {
173 if (m_MetaEntityCollection.Auras.ContainsKey(parts[i].UUID))
174 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(parts[i].UUID);
175 }
176 }
177
178 /// <summary>
179 /// Retrieves the latest revision of a region in xml form,
180 /// converts it to scene object groups and scene presences,
181 /// swaps the current scene's entity list with the revision's list.
182 /// Note: Since deleted objects while
183 /// </summary>
184 public void RollbackRegion(Scene scene)
185 {
186 System.Collections.ArrayList xmllist = null;
187 SceneObjectGroup temp = null;
188 System.Collections.Hashtable deleteListUUIDs = new Hashtable();
189// Dictionary<LLUUID, EntityBase> SearchList = new Dictionary<LLUUID,EntityBase>();
190 Dictionary<UUID, EntityBase> ReplacementList = new Dictionary<UUID,EntityBase>();
191 int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID);
192// EntityBase[] searchArray;
193
194 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision);
195 if (xmllist == null)
196 {
197 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ").");
198 return;
199 }
200
201 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ").");
202 m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count);
203 m_log.Info("[CMMODEL]: Converting scene entities list to specified revision.");
204
205 m_log.ErrorFormat("[CMMODEL]: 1");
206
207 foreach (string xml in xmllist)
208 {
209 try
210 {
211 temp = SceneObjectSerializer.FromXml2Format(xml);
212 temp.SetScene(scene);
213
214 SceneObjectPart[] parts = temp.Parts;
215 for (int i = 0; i < parts.Length; i++)
216 parts[i].RegionHandle = scene.RegionInfo.RegionHandle;
217
218 ReplacementList.Add(temp.UUID, (EntityBase)temp);
219 }
220 catch (Exception e)
221 {
222 m_log.Info("[CMMODEL]: Error while creating replacement list for rollback: " + e);
223 }
224 }
225
226 //If in scene but not in revision and not a client, remove them
227 while (true)
228 {
229 try
230 {
231 foreach (EntityBase entity in scene.GetEntities())
232 {
233 if (entity == null)
234 continue;
235
236 if (entity is ScenePresence)
237 {
238 ReplacementList.Add(entity.UUID, entity);
239 continue;
240 }
241 else //if (!ReplacementList.ContainsKey(entity.UUID))
242 deleteListUUIDs.Add(entity.UUID, 0);
243 }
244 }
245 catch(Exception e)
246 {
247 m_log.ErrorFormat("[CMMODEL]: " + e);
248 deleteListUUIDs.Clear();
249 ReplacementList.Clear();
250 continue;
251 }
252 break;
253 }
254
255 foreach (UUID uuid in deleteListUUIDs.Keys)
256 {
257 try
258 {
259 // I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles.
260 ((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup();
261 scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor);
262 scene.SendKillObject(new List<uint>() { scene.Entities[uuid].LocalId });
263 scene.SceneGraph.DeleteSceneObject(uuid, false);
264 ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroupFromScene(false);
265 scene.SendKillObject(new List<uint>() { ((SceneObjectGroup)scene.Entities[uuid]).LocalId });
266 }
267 catch(Exception e)
268 {
269 m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e);
270 }
271 }
272
273 lock (scene)
274 {
275 scene.Entities.Clear();
276
277 foreach (KeyValuePair<UUID,EntityBase> kvp in ReplacementList)
278 {
279 scene.Entities.Add(kvp.Value);
280 }
281 }
282
283 foreach (EntityBase ent in ReplacementList.Values)
284 {
285 try
286 {
287 if (!(ent is SceneObjectGroup))
288 continue;
289
290 if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) PrimFlags.Phantom) == 0)
291 ((SceneObjectGroup)ent).ApplyPhysics(true);
292 ((SceneObjectGroup)ent).AttachToBackup();
293 ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected.
294 ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
295 }
296 catch(Exception e)
297 {
298 m_log.ErrorFormat("[CMMODEL]: Error while attaching new scene entities to backup and scheduling for a full update: " + e);
299 }
300 }
301 m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup.");
302 scene.Backup(true);
303 }
304
305 /// <summary>
306 /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences
307 /// and display the differences to clients.
308 /// </summary>
309 public void UpdateCMEntities(Scene scene)
310 {
311 Stopwatch x = new Stopwatch();
312 x.Start();
313
314 System.Collections.ArrayList xmllist = null;
315 m_log.Debug("[CONTENT MANAGEMENT] Retrieving object xml files for region: " + scene.RegionInfo.RegionID);
316 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID);
317 m_log.Info("[FSDB]: got list");
318 if (xmllist == null)
319 return;
320
321 Stopwatch y = new Stopwatch();
322 y.Start();
323 foreach (string xml in xmllist)
324 m_MetaEntityCollection.CreateNewEntity(xml, scene);
325 y.Stop();
326 TimeToConvertXml += y.ElapsedMilliseconds;
327 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds);
328 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml);
329
330 m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras");
331 CheckForNewEntitiesMissingAuras(scene);
332
333 x.Stop();
334 TimeToUpdate += x.ElapsedMilliseconds;
335 m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds);
336 m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate);
337 }
338
339 /// <summary>
340 /// Detects if a scene object group from the scene list has moved or changed scale. The green aura
341 /// that surrounds the object is then moved or scaled with the group.
342 /// </summary>
343 public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group)
344 {
345 System.Collections.ArrayList auraList = new System.Collections.ArrayList();
346 if (group == null)
347 return null;
348
349 SceneObjectPart[] parts = group.Parts;
350 for (int i = 0; i < parts.Length; i++)
351 {
352 SceneObjectPart part = parts[i];
353 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
354 {
355 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0, 254, 0), part.Scale);
356 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
357 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
358 }
359 }
360
361 return auraList;
362 }
363
364 #endregion Public Methods
365 }
366}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
deleted file mode 100644
index 3807ccd..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
+++ /dev/null
@@ -1,206 +0,0 @@
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
28#region Header
29
30// CMView.cs created with MonoDevelop
31// User: bongiojp at 11:57 AM 7/3/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections;
40using System.Collections.Generic;
41
42using OpenMetaverse;
43
44using OpenSim;
45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49
50using log4net;
51
52namespace OpenSim.Region.OptionalModules.ContentManagement
53{
54 public class CMView
55 {
56 #region Static Fields
57
58 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
59
60 #endregion Static Fields
61
62 #region Fields
63
64 CMModel m_model = null;
65
66 #endregion Fields
67
68 #region Constructors
69
70 public CMView()
71 {
72 }
73
74 #endregion Constructors
75
76 #region Public Methods
77
78 // Auras To
79 public void DisplayAuras(CMEntityCollection auraCollection)
80 {
81 foreach (Object ent in auraCollection.Auras.Values)
82 ((AuraMetaEntity)ent).SendFullUpdateToAll();
83 }
84
85 // Auras To Client
86 public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client)
87 {
88 foreach (Object ent in auraCollection.Auras.Values)
89 ((AuraMetaEntity)ent).SendFullUpdate(client);
90 }
91
92 // Auras from List To ALL
93 public void DisplayAuras(ArrayList list)
94 {
95 foreach (Object ent in list)
96 {
97 m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW");
98 ((AuraMetaEntity)ent).SendFullUpdateToAll();
99 }
100 }
101
102 // Entities to ALL
103 public void DisplayEntities(CMEntityCollection entityCollection)
104 {
105 foreach (Object ent in entityCollection.Entities.Values)
106 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
107 }
108
109 // Entities to Client
110 public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client)
111 {
112 foreach (Object ent in entityCollection.Entities.Values)
113 ((ContentManagementEntity)ent).SendFullDiffUpdate(client);
114 }
115
116 // Entities from List to ALL
117 public void DisplayEntities(ArrayList list)
118 {
119 foreach (Object ent in list)
120 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
121 }
122
123 // Entity to ALL
124 public void DisplayEntity(ContentManagementEntity ent)
125 {
126 ent.SendFullDiffUpdateToAll();
127 }
128
129 public void DisplayHelpMenu(Scene scene)
130 {
131 string menu = "Menu:\n";
132 menu += "commit (ci) - saves current state of the region to a database on the server\n";
133 menu += "diff-mode (dm) - displays those aspects of region that have not been saved but changed since the very last revision. Will dynamically update as you change environment.\n";
134 SendSimChatMessage(scene, menu);
135 }
136
137 public void DisplayMetaEntity(UUID uuid)
138 {
139 ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid);
140 if (group != null)
141 group.SendFullDiffUpdateToAll();
142 }
143
144 /// <summary>
145 /// update all clients of red/green/blue auras and meta entities that the model knows about.
146 /// </summary>
147 public void DisplayRecentChanges()
148 {
149 m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects.");
150 DisplayEntities(m_model.MetaEntityCollection);
151 DisplayAuras(m_model.MetaEntityCollection);
152 }
153
154 public void Hide(ContentManagementEntity ent)
155 {
156 ent.HideFromAll();
157 }
158
159 public void HideAllAuras()
160 {
161 foreach (Object obj in m_model.MetaEntityCollection.Auras.Values)
162 ((MetaEntity)obj).HideFromAll();
163 }
164
165 public void HideAllMetaEntities()
166 {
167 foreach (Object obj in m_model.MetaEntityCollection.Entities.Values)
168 ((ContentManagementEntity)obj).HideFromAll();
169 }
170
171 public void Initialise(CMModel model)
172 {
173 m_model = model;
174 }
175
176 /// <summary>
177 /// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted.
178 /// If it's a new scene object, any green aura attached to it is deleted.
179 /// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will
180 /// figure out that there should be a red aura and not a blue aura/beam.
181 /// </summary>
182 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
183 {
184 // Deal with revisioned parts that have been deleted.
185 if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID))
186 ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
187
188 // Deal with new parts not revisioned that have been deleted.
189 foreach (SceneObjectPart part in group.Parts)
190 if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
191 ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
192 }
193
194 public void SendMetaEntitiesToNewClient(IClientAPI client)
195 {
196 }
197
198 public void SendSimChatMessage(Scene scene, string message)
199 {
200 scene.SimChat(Utils.StringToBytes(message),
201 ChatTypeEnum.Broadcast, 0, new Vector3(0,0,0), "Content Manager", UUID.Zero, false);
202 }
203
204 #endregion Public Methods
205 }
206}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
deleted file mode 100644
index 0248f36..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
+++ /dev/null
@@ -1,375 +0,0 @@
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.Collections.Generic;
30using System.Drawing;
31
32using OpenMetaverse;
33
34using Nini.Config;
35
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Framework.Scenes.Serialization;
40using OpenSim.Region.Physics.Manager;
41
42using log4net;
43
44namespace OpenSim.Region.OptionalModules.ContentManagement
45{
46 public class ContentManagementEntity : MetaEntity
47 {
48 #region Static Fields
49
50// static float TimeToDiff = 0;
51// static float TimeToCreateEntities = 0;
52
53 #endregion Static Fields
54
55 #region Fields
56
57 protected Dictionary<UUID, AuraMetaEntity> m_AuraEntities = new Dictionary<UUID, AuraMetaEntity>();
58 protected Dictionary<UUID, BeamMetaEntity> m_BeamEntities = new Dictionary<UUID, BeamMetaEntity>();
59
60 // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different.
61 // This can come in handy.
62 protected SceneObjectGroup m_UnchangedEntity = null;
63
64 /// <value>
65 /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list.
66 /// </value>
67 bool DiffersFromSceneGroup = false;
68
69 #endregion Fields
70
71 #region Constructors
72
73 public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics)
74 : base(Unchanged, false)
75 {
76 m_UnchangedEntity = Unchanged.Copy(false);
77 }
78
79 public ContentManagementEntity(string objectXML, Scene scene, bool physics)
80 : base(objectXML, scene, false)
81 {
82 m_UnchangedEntity = SceneObjectSerializer.FromXml2Format(objectXML);
83 }
84
85 #endregion Constructors
86
87 #region Public Properties
88
89 public SceneObjectGroup UnchangedEntity
90 {
91 get { return m_UnchangedEntity; }
92 }
93
94 #endregion Public Properties
95
96 #region Private Methods
97
98 /// <summary>
99 /// Check if an entitybase list (like that returned by scene.GetEntities()) contains a group with the rootpart uuid that matches the current uuid.
100 /// </summary>
101 private bool ContainsKey(List<EntityBase> list, UUID uuid)
102 {
103 foreach (EntityBase part in list)
104 if (part.UUID == uuid)
105 return true;
106 return false;
107 }
108
109 private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, UUID uuid)
110 {
111 foreach (EntityBase ent in list)
112 {
113 if (ent is SceneObjectGroup)
114 if (ent.UUID == uuid)
115 return (SceneObjectGroup)ent;
116 }
117 return null;
118 }
119
120 #endregion Private Methods
121
122 #region Public Methods
123
124 /// <summary>
125 /// Search for a corresponding group UUID in the scene. If not found, then the revisioned group this CMEntity represents has been deleted. Mark the metaentity appropriately.
126 /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately.
127 /// </summary>
128 public void FindDifferences()
129 {
130 List<EntityBase> sceneEntityList = new List<EntityBase>(m_Entity.Scene.GetEntities());
131 DiffersFromSceneGroup = false;
132 // if group is not contained in scene's list
133 if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
134 {
135 foreach (SceneObjectPart part in m_UnchangedEntity.Parts)
136 {
137 // if scene list no longer contains this part, display translucent part and mark with red aura
138 if (!ContainsKey(sceneEntityList, part.UUID))
139 {
140 // if already displaying a red aura over part, make sure its red
141 if (m_AuraEntities.ContainsKey(part.UUID))
142 {
143 m_AuraEntities[part.UUID].SetAura(new Vector3(254, 0, 0), part.Scale);
144 }
145 else
146 {
147 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
148 part.GetWorldPosition(),
149 MetaEntity.TRANSLUCENT,
150 new Vector3(254, 0, 0),
151 part.Scale
152 );
153 m_AuraEntities.Add(part.UUID, auraGroup);
154 }
155 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
156 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
157 }
158 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
159 }
160
161 // a deleted part has no where to point a beam particle system,
162 // if a metapart had a particle system (maybe it represented a moved part) remove it
163 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
164 {
165 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
166 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
167 }
168
169 DiffersFromSceneGroup = true;
170 }
171 // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately
172 else
173 {
174 MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID));
175 }
176 }
177
178 /// <summary>
179 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID.
180 /// </summary>
181 public bool HasChildPrim(UUID uuid)
182 {
183 return m_UnchangedEntity.ContainsPart(uuid);
184 }
185
186 /// <summary>
187 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId.
188 /// </summary>
189 public bool HasChildPrim(uint localID)
190 {
191 foreach (SceneObjectPart part in m_UnchangedEntity.Parts)
192 if (part.LocalId == localID)
193 return true;
194
195 return false;
196 }
197
198 public override void Hide(IClientAPI client)
199 {
200 base.Hide(client);
201 foreach (MetaEntity group in m_AuraEntities.Values)
202 group.Hide(client);
203 foreach (MetaEntity group in m_BeamEntities.Values)
204 group.Hide(client);
205 }
206
207 public override void HideFromAll()
208 {
209 base.HideFromAll();
210 foreach (MetaEntity group in m_AuraEntities.Values)
211 group.HideFromAll();
212 foreach (MetaEntity group in m_BeamEntities.Values)
213 group.HideFromAll();
214 }
215
216 /// <summary>
217 /// Returns true if there was a change between meta entity and the entity group, false otherwise.
218 /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated).
219 /// </summary>
220 public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup)
221 {
222 SceneObjectPart sceneEntityPart;
223 SceneObjectPart metaEntityPart;
224 Diff differences;
225 bool changed = false;
226
227 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
228 // had originally saved.
229 // m_Entity will NOT necessarily be the same entity as the user had saved.
230 foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Parts)
231 {
232 //This is the part that we use to show changes.
233 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
234 if (sceneEntityGroup.ContainsPart(UnchangedPart.UUID))
235 {
236 sceneEntityPart = sceneEntityGroup.GetChildPart(UnchangedPart.UUID);
237 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
238 if (differences != Diff.NONE)
239 metaEntityPart.Text = "CHANGE: " + differences.ToString();
240 if (differences != 0)
241 {
242 // Root Part that has been modified
243 if ((differences & Diff.POSITION) > 0)
244 {
245 // If the position of any part has changed, make sure the RootPart of the
246 // meta entity is pointing with a beam particle system
247 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
248 {
249 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
250 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
251 }
252 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
253 m_UnchangedEntity.RootPart.GetWorldPosition(),
254 MetaEntity.TRANSLUCENT,
255 sceneEntityPart,
256 new Vector3(0, 0, 254)
257 );
258 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
259 }
260
261 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
262 {
263 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
264 m_AuraEntities.Remove(UnchangedPart.UUID);
265 }
266 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
267 UnchangedPart.GetWorldPosition(),
268 MetaEntity.TRANSLUCENT,
269 new Vector3(0, 0, 254),
270 UnchangedPart.Scale
271 );
272 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
273 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
274
275 DiffersFromSceneGroup = true;
276 }
277 else // no differences between scene part and meta part
278 {
279 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
280 {
281 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
282 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
283 }
284 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
285 {
286 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
287 m_AuraEntities.Remove(UnchangedPart.UUID);
288 }
289 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
290 }
291 }
292 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
293 {
294 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
295 {
296 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
297 m_AuraEntities.Remove(UnchangedPart.UUID);
298 }
299 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
300 UnchangedPart.GetWorldPosition(),
301 MetaEntity.TRANSLUCENT,
302 new Vector3(254, 0, 0),
303 UnchangedPart.Scale
304 );
305 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
306 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
307
308 DiffersFromSceneGroup = true;
309 }
310 }
311
312 return changed;
313 }
314
315 public void SendFullAuraUpdate(IClientAPI client)
316 {
317 if (DiffersFromSceneGroup)
318 {
319 foreach (AuraMetaEntity group in m_AuraEntities.Values)
320 group.SendFullUpdate(client);
321 }
322 }
323
324 public void SendFullAuraUpdateToAll()
325 {
326 if (DiffersFromSceneGroup)
327 {
328 foreach (AuraMetaEntity group in m_AuraEntities.Values)
329 group.SendFullUpdateToAll();
330 }
331 }
332
333 public void SendFullBeamUpdate(IClientAPI client)
334 {
335 if (DiffersFromSceneGroup)
336 {
337 foreach (BeamMetaEntity group in m_BeamEntities.Values)
338 group.SendFullUpdate(client);
339 }
340 }
341
342 public void SendFullBeamUpdateToAll()
343 {
344 if (DiffersFromSceneGroup)
345 {
346 foreach (BeamMetaEntity group in m_BeamEntities.Values)
347 group.SendFullUpdateToAll();
348 }
349 }
350
351 public void SendFullDiffUpdate(IClientAPI client)
352 {
353 FindDifferences();
354 if (DiffersFromSceneGroup)
355 {
356 SendFullUpdate(client);
357 SendFullAuraUpdate(client);
358 SendFullBeamUpdate(client);
359 }
360 }
361
362 public void SendFullDiffUpdateToAll()
363 {
364 FindDifferences();
365 if (DiffersFromSceneGroup)
366 {
367 SendFullUpdateToAll();
368 SendFullAuraUpdateToAll();
369 SendFullBeamUpdateToAll();
370 }
371 }
372
373 #endregion Public Methods
374 }
375}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs
deleted file mode 100644
index 3d1c346..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs
+++ /dev/null
@@ -1,163 +0,0 @@
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
28#region Header
29
30// ContentManagementModule.cs
31// User: bongiojp
32
33#endregion Header
34
35using System;
36using System.Collections.Generic;
37using System.Threading;
38
39using OpenMetaverse;
40
41using Nini.Config;
42
43using OpenSim;
44using OpenSim.Framework;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.Physics.Manager;
48
49using log4net;
50
51namespace OpenSim.Region.OptionalModules.ContentManagement
52{
53 public class ContentManagementModule : IRegionModule
54 {
55 #region Static Fields
56
57 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
58
59 #endregion Static Fields
60
61 #region Fields
62
63 bool initialised = false;
64 CMController m_control = null;
65 bool m_enabled = false;
66 CMModel m_model = null;
67 bool m_posted = false;
68 CMView m_view = null;
69
70 #endregion Fields
71
72 #region Public Properties
73
74 public bool IsSharedModule
75 {
76 get { return true; }
77 }
78
79 public string Name
80 {
81 get { return "ContentManagementModule"; }
82 }
83
84 #endregion Public Properties
85
86 #region Public Methods
87
88 public void Close()
89 {
90 }
91
92 public void Initialise(Scene scene, IConfigSource source)
93 {
94 string databaseDir = "./";
95 string database = "FileSystemDatabase";
96 int channel = 345;
97 try
98 {
99 if (source.Configs["CMS"] == null)
100 return;
101
102 m_enabled = source.Configs["CMS"].GetBoolean("enabled", false);
103 databaseDir = source.Configs["CMS"].GetString("directory", databaseDir);
104 database = source.Configs["CMS"].GetString("database", database);
105 channel = source.Configs["CMS"].GetInt("channel", channel);
106
107 if (database != "FileSystemDatabase" && database != "GitDatabase")
108 {
109 m_log.ErrorFormat("[Content Management]: The Database attribute must be defined as either FileSystemDatabase or GitDatabase");
110 m_enabled = false;
111 }
112 }
113 catch (Exception e)
114 {
115 m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e);
116 m_enabled = false;
117 }
118
119 if (!m_enabled)
120 {
121 m_log.Info("[Content Management]: Content Management System is not Enabled.");
122 return;
123 }
124
125 lock (this)
126 {
127 if (!initialised) //only init once
128 {
129 m_view = new CMView();
130 m_model = new CMModel();
131 m_control = new CMController(m_model, m_view, scene, channel);
132 m_model.Initialise(database);
133 m_view.Initialise(m_model);
134
135 initialised = true;
136 m_model.InitialiseDatabase(scene, databaseDir);
137 }
138 else
139 {
140 m_model.InitialiseDatabase(scene, databaseDir);
141 m_control.RegisterNewRegion(scene);
142 }
143 }
144 }
145
146 public void PostInitialise()
147 {
148 if (! m_enabled)
149 return;
150
151 lock (this)
152 {
153 if (!m_posted) //only post once
154 {
155 m_model.PostInitialise();
156 m_posted = true;
157 }
158 }
159 }
160
161 #endregion Public Methods
162 }
163}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs
deleted file mode 100644
index a3d7977..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs
+++ /dev/null
@@ -1,317 +0,0 @@
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
28#region Header
29
30// FileSystemDatabase.cs
31// User: bongiojp
32
33#endregion Header
34
35using System;
36using System.Collections.Generic;
37using System.Diagnostics;
38using System.IO;
39using Slash = System.IO.Path;
40using System.Reflection;
41using System.Xml;
42
43using OpenMetaverse;
44
45using Nini.Config;
46
47using OpenSim.Framework;
48using OpenSim.Region.Framework.Interfaces;
49using OpenSim.Region.Framework.Scenes;
50using OpenSim.Region.CoreModules.World.Serialiser;
51using OpenSim.Region.CoreModules.World.Terrain;
52using OpenSim.Region.Physics.Manager;
53
54using log4net;
55
56namespace OpenSim.Region.OptionalModules.ContentManagement
57{
58 public class FileSystemDatabase : IContentDatabase
59 {
60 #region Static Fields
61
62 public static float TimeToDownload = 0;
63 public static float TimeToSave = 0;
64 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
65
66 #endregion Static Fields
67
68 #region Fields
69
70 private string m_repodir = null;
71 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
72 private Dictionary<UUID, IRegionSerialiserModule> m_serialiser = new Dictionary<UUID, IRegionSerialiserModule>();
73
74 #endregion Fields
75
76 #region Constructors
77
78 public FileSystemDatabase()
79 {
80 }
81
82 #endregion Constructors
83
84 #region Private Methods
85
86 // called by postinitialise
87 private void CreateDirectory()
88 {
89 string scenedir;
90 if (!Directory.Exists(m_repodir))
91 Directory.CreateDirectory(m_repodir);
92
93 foreach (UUID region in m_scenes.Keys)
94 {
95 scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar;
96 if (!Directory.Exists(scenedir))
97 Directory.CreateDirectory(scenedir);
98 }
99 }
100
101 // called by postinitialise
102 private void SetupSerialiser()
103 {
104 if (m_serialiser.Count == 0)
105 {
106 foreach (UUID region in m_scenes.Keys)
107 {
108 m_serialiser.Add(region, m_scenes[region].RequestModuleInterface<IRegionSerialiserModule>());
109 }
110 }
111 }
112
113 #endregion Private Methods
114
115 #region Public Methods
116
117 public int GetMostRecentRevision(UUID regionid)
118 {
119 return NumOfRegionRev(regionid);
120 }
121
122 public string GetRegionObjectHeightMap(UUID regionid)
123 {
124 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
125 Slash.DirectorySeparatorChar + "heightmap.r32";
126 FileStream fs = new FileStream(filename, FileMode.Open);
127 StreamReader sr = new StreamReader(fs);
128 String result = sr.ReadToEnd();
129 sr.Close();
130 fs.Close();
131 return result;
132 }
133
134 public string GetRegionObjectHeightMap(UUID regionid, int revision)
135 {
136 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
137 Slash.DirectorySeparatorChar + "heightmap.r32";
138 FileStream fs = new FileStream(filename, FileMode.Open);
139 StreamReader sr = new StreamReader(fs);
140 String result = sr.ReadToEnd();
141 sr.Close();
142 fs.Close();
143 return result;
144 }
145
146 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
147 {
148 System.Collections.ArrayList objectList = new System.Collections.ArrayList();
149 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
150 + revision + Slash.DirectorySeparatorChar + "objects.xml";
151 XmlDocument doc = new XmlDocument();
152 XmlNode rootNode;
153 //int primCount = 0;
154 //SceneObjectGroup obj = null;
155
156 if (File.Exists(filename))
157 {
158 XmlTextReader reader = new XmlTextReader(filename);
159 reader.WhitespaceHandling = WhitespaceHandling.None;
160 doc.Load(reader);
161 reader.Close();
162 rootNode = doc.FirstChild;
163 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
164 {
165 objectList.Add(aPrimNode.OuterXml);
166 }
167 return objectList;
168 }
169 return null;
170 }
171
172 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
173 {
174 int revision = NumOfRegionRev(regionid);
175 m_log.Info("[FSDB]: found revisions:" + revision);
176 System.Collections.ArrayList xmlList = new System.Collections.ArrayList();
177 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
178 + revision + Slash.DirectorySeparatorChar + "objects.xml";
179 XmlDocument doc = new XmlDocument();
180 XmlNode rootNode;
181
182 m_log.Info("[FSDB]: Checking if " + filename + " exists.");
183 if (File.Exists(filename))
184 {
185 Stopwatch x = new Stopwatch();
186 x.Start();
187
188 XmlTextReader reader = new XmlTextReader(filename);
189 reader.WhitespaceHandling = WhitespaceHandling.None;
190 doc.Load(reader);
191 reader.Close();
192 rootNode = doc.FirstChild;
193
194 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
195 {
196 xmlList.Add(aPrimNode.OuterXml);
197 }
198
199 x.Stop();
200 TimeToDownload += x.ElapsedMilliseconds;
201 m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload);
202
203 return xmlList;
204 }
205 return null;
206 }
207
208 public void Initialise(Scene scene, string dir)
209 {
210 lock (this)
211 {
212 if (m_repodir == null)
213 m_repodir = dir;
214 }
215 lock (m_scenes)
216 m_scenes.Add(scene.RegionInfo.RegionID, scene);
217 }
218
219 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID regionid)
220 {
221 SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>();
222
223 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
224 string[] directories = Directory.GetDirectories(scenedir);
225
226 FileStream fs = null;
227 StreamReader sr = null;
228 String logMessage = "";
229 String logLocation = "";
230 foreach (string revisionDir in directories)
231 {
232 try
233 {
234 logLocation = revisionDir + Slash.DirectorySeparatorChar + "log";
235 fs = new FileStream(logLocation, FileMode.Open);
236 sr = new StreamReader(fs);
237 logMessage = sr.ReadToEnd();
238 sr.Close();
239 fs.Close();
240 revisionDict.Add(revisionDir, logMessage);
241 }
242 catch (Exception)
243 {
244 }
245 }
246
247 return revisionDict;
248 }
249
250 public int NumOfRegionRev(UUID regionid)
251 {
252 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
253 m_log.Info("[FSDB]: Reading scene dir: " + scenedir);
254 string[] directories = Directory.GetDirectories(scenedir);
255 return directories.Length;
256 }
257
258 // Run once and only once.
259 public void PostInitialise()
260 {
261 SetupSerialiser();
262
263 m_log.Info("[FSDB]: Creating repository in " + m_repodir + ".");
264 CreateDirectory();
265 }
266
267 public void SaveRegion(UUID regionid, string regionName, string logMessage)
268 {
269 m_log.Info("[FSDB]: ...............................");
270 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
271
272 m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir);
273 if (!Directory.Exists(scenedir))
274 Directory.CreateDirectory(scenedir);
275
276 int newRevisionNum = GetMostRecentRevision(regionid)+1;
277 string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar;
278
279 m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir);
280 if (!Directory.Exists(revisiondir))
281 Directory.CreateDirectory(revisiondir);
282
283 try {
284 Stopwatch x = new Stopwatch();
285 x.Start();
286 if (m_scenes.ContainsKey(regionid))
287 {
288 m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir);
289 }
290 x.Stop();
291 TimeToSave += x.ElapsedMilliseconds;
292 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds);
293 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave);
294 }
295 catch (Exception e)
296 {
297 m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e);
298 return;
299 }
300
301 try {
302 // Finish by writing log message.
303 FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite);
304 StreamWriter sw = new StreamWriter(file);
305 sw.Write(logMessage);
306 sw.Close();
307 }
308 catch (Exception e)
309 {
310 m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e);
311 return;
312 }
313 }
314
315 #endregion Public Methods
316 }
317}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs
deleted file mode 100644
index 80a0a93..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs
+++ /dev/null
@@ -1,167 +0,0 @@
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
28#region Header
29
30// GitDatabase.cs
31//
32//
33//
34
35#endregion Header
36
37using System;
38using System.Collections.Generic;
39using System.IO;
40using Slash = System.IO.Path;
41using System.Reflection;
42using System.Xml;
43
44using OpenMetaverse;
45
46using Nini.Config;
47
48using OpenSim.Framework;
49using OpenSim.Region.Framework.Interfaces;
50using OpenSim.Region.Framework.Scenes;
51using OpenSim.Region.CoreModules.World.Serialiser;
52using OpenSim.Region.CoreModules.World.Terrain;
53using OpenSim.Region.Physics.Manager;
54
55using log4net;
56
57namespace OpenSim.Region.OptionalModules.ContentManagement
58{
59 /// <summary>
60 /// Just a stub :-(
61 /// </summary>
62 public class GitDatabase : IContentDatabase
63 {
64 #region Constructors
65
66 public GitDatabase()
67 {
68 }
69
70 #endregion Constructors
71
72 #region Public Methods
73
74 public SceneObjectGroup GetMostRecentObjectRevision(UUID id)
75 {
76 return null;
77 }
78
79 public int GetMostRecentRevision(UUID regionid)
80 {
81 return 0;
82 }
83
84 public SceneObjectGroup GetObjectRevision(UUID id, int revision)
85 {
86 return null;
87 }
88
89 public System.Collections.ArrayList GetObjectsFromRegion(UUID regionid, int revision)
90 {
91 return null;
92 }
93
94 public string GetRegionObjectHeightMap(UUID regionid)
95 {
96 return null;
97 }
98
99 public string GetRegionObjectHeightMap(UUID regionid, int revision)
100 {
101 return null;
102 }
103
104 public string GetRegionObjectXML(UUID regionid)
105 {
106 return null;
107 }
108
109 public string GetRegionObjectXML(UUID regionid, int revision)
110 {
111 return null;
112 }
113
114 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
115 {
116 return null;
117 }
118
119 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
120 {
121 return null;
122 }
123
124 public bool InRepository(UUID id)
125 {
126 return false;
127 }
128
129 public void Initialise(Scene scene, String dir)
130 {
131 }
132
133 public System.Collections.Generic.SortedDictionary<string, string> ListOfObjectRevisions(UUID id)
134 {
135 return null;
136 }
137
138 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id)
139 {
140 return null;
141 }
142
143 public int NumOfObjectRev(UUID id)
144 {
145 return 0;
146 }
147
148 public int NumOfRegionRev(UUID regionid)
149 {
150 return 0;
151 }
152
153 public void PostInitialise()
154 {
155 }
156
157 public void SaveObject(SceneObjectGroup entity)
158 {
159 }
160
161 public void SaveRegion(UUID regionid, string regionName, string logMessage)
162 {
163 }
164
165 #endregion Public Methods
166 }
167}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs
deleted file mode 100644
index fc1f115..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs
+++ /dev/null
@@ -1,94 +0,0 @@
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
28#region Header
29
30// IContentDatabase.cs
31// User: bongiojp
32//
33//
34//
35
36#endregion Header
37
38using System;
39using OpenMetaverse;
40using OpenSim.Region.Framework.Scenes;
41using Nini.Config;
42
43namespace OpenSim.Region.OptionalModules.ContentManagement
44{
45 public interface IContentDatabase
46 {
47 #region Methods
48
49 /// <summary>
50 /// Returns the most recent revision number of a region.
51 /// </summary>
52 int GetMostRecentRevision(UUID regionid);
53
54 string GetRegionObjectHeightMap(UUID regionid);
55
56 string GetRegionObjectHeightMap(UUID regionid, int revision);
57
58 /// <summary>
59 /// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region.
60 /// </summary>
61 System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid);
62
63 System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision);
64
65 /// <summary>
66 /// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database.
67 /// Initialise should be called one for each region to be contained in the database. The directory should be the full path
68 /// to the repository and will only be defined once, regardless of how many times the method is called.
69 /// </summary>
70 void Initialise(Scene scene, String dir);
71
72 /// <summary>
73 /// Returns a list of the revision numbers and corresponding log messages for a given region.
74 /// </summary>
75 System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id);
76
77 /// <summary>
78 /// Returns the total number of revisions saved for a specific region.
79 /// </summary>
80 int NumOfRegionRev(UUID regionid);
81
82 /// <summary>
83 /// Should be called once after Initialise has been called.
84 /// </summary>
85 void PostInitialise();
86
87 /// <summary>
88 /// Saves the Region terrain map and objects within the region as xml to the database.
89 /// </summary>
90 void SaveRegion(UUID regionid, string regionName, string logMessage);
91
92 #endregion Methods
93 }
94}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
deleted file mode 100644
index cd60f4b..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
+++ /dev/null
@@ -1,270 +0,0 @@
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.Collections.Generic;
30using System.Drawing;
31
32using OpenMetaverse;
33
34using Nini.Config;
35
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Framework.Scenes.Serialization;
40using OpenSim.Region.Physics.Manager;
41
42using log4net;
43
44namespace OpenSim.Region.OptionalModules.ContentManagement
45{
46 public class MetaEntity
47 {
48 #region Constants
49
50 public const float INVISIBLE = .95f;
51
52 // Settings for transparency of metaentity
53 public const float NONE = 0f;
54 public const float TRANSLUCENT = .5f;
55
56 #endregion Constants
57
58 #region Static Fields
59
60 //private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
61
62 #endregion Static Fields
63
64 #region Fields
65
66 protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity.
67 protected uint m_metaLocalid;
68
69 #endregion Fields
70
71 #region Constructors
72
73 public MetaEntity()
74 {
75 }
76
77 /// <summary>
78 /// Makes a new meta entity by copying the given scene object group.
79 /// The physics boolean is just a stub right now.
80 /// </summary>
81 public MetaEntity(SceneObjectGroup orig, bool physics)
82 {
83 m_Entity = orig.Copy(false);
84 Initialize(physics);
85 }
86
87 /// <summary>
88 /// Takes an XML description of a scene object group and converts it to a meta entity.
89 /// </summary>
90 public MetaEntity(string objectXML, Scene scene, bool physics)
91 {
92 m_Entity = SceneObjectSerializer.FromXml2Format(objectXML);
93 m_Entity.SetScene(scene);
94 Initialize(physics);
95 }
96
97 #endregion Constructors
98
99 #region Public Properties
100
101 public SceneObjectPart[] Parts
102 {
103 get { return m_Entity.Parts; }
104 }
105
106 public uint LocalId
107 {
108 get { return m_Entity.LocalId; }
109 set { m_Entity.LocalId = value; }
110 }
111
112 public SceneObjectGroup ObjectGroup
113 {
114 get { return m_Entity; }
115 }
116
117 public int PrimCount
118 {
119 get { return m_Entity.PrimCount; }
120 }
121
122 public SceneObjectPart RootPart
123 {
124 get { return m_Entity.RootPart; }
125 }
126
127 public Scene Scene
128 {
129 get { return m_Entity.Scene; }
130 }
131
132 public UUID UUID
133 {
134 get { return m_Entity.UUID; }
135 set { m_Entity.UUID = value; }
136 }
137
138 #endregion Public Properties
139
140 #region Protected Methods
141
142 // The metaentity objectgroup must have unique localids as well as unique uuids.
143 // localids are used by the client to refer to parts.
144 // uuids are sent to the client and back to the server to identify parts on the server side.
145 /// <summary>
146 /// Changes localids and uuids of m_Entity.
147 /// </summary>
148 protected void Initialize(bool physics)
149 {
150 //make new uuids
151 Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
152
153 foreach (SceneObjectPart part in m_Entity.Parts)
154 {
155 part.ResetIDs(part.LinkNum);
156 parts.Add(part.UUID, part);
157 }
158
159 //finalize
160 m_Entity.RootPart.PhysActor = null;
161 foreach (SceneObjectPart part in parts.Values)
162 m_Entity.AddPart(part);
163 }
164
165 #endregion Protected Methods
166
167 #region Public Methods
168
169 /// <summary>
170 /// Hides the metaentity from a single client.
171 /// </summary>
172 public virtual void Hide(IClientAPI client)
173 {
174 //This deletes the group without removing from any databases.
175 //This is important because we are not IN any database.
176 //m_Entity.FakeDeleteGroup();
177 foreach (SceneObjectPart part in m_Entity.Parts)
178 client.SendKillObject(m_Entity.RegionHandle, new List<uint>() { part.LocalId });
179 }
180
181 /// <summary>
182 /// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server.
183 /// </summary>
184 public virtual void HideFromAll()
185 {
186 foreach (SceneObjectPart part in m_Entity.Parts)
187 {
188 m_Entity.Scene.ForEachClient(
189 delegate(IClientAPI controller)
190 { controller.SendKillObject(m_Entity.RegionHandle, new List<uint>() { part.LocalId }); }
191 );
192 }
193 }
194
195 public void SendFullUpdate(IClientAPI client)
196 {
197 // Not sure what clientFlags should be but 0 seems to work
198 SendFullUpdate(client, 0);
199 }
200
201 public void SendFullUpdate(IClientAPI client, uint clientFlags)
202 {
203 m_Entity.SendFullUpdateToClient(client);
204 }
205
206 public void SendFullUpdateToAll()
207 {
208 m_Entity.Scene.ForEachClient(
209 delegate(IClientAPI controller)
210 { m_Entity.SendFullUpdateToClient(controller); }
211 );
212 }
213
214 /// <summary>
215 /// Makes a single SceneObjectPart see through.
216 /// </summary>
217 /// <param name="part">
218 /// A <see cref="SceneObjectPart"/>
219 /// The part to make see through
220 /// </param>
221 /// <param name="transparencyAmount">
222 /// A <see cref="System.Single"/>
223 /// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible.
224 /// </param>
225 public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount)
226 {
227 Primitive.TextureEntry tex = null;
228 Color4 texcolor;
229 try
230 {
231 tex = part.Shape.Textures;
232 texcolor = new Color4();
233 }
234 catch(Exception)
235 {
236 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e);
237 return;
238 }
239
240 for (uint i = 0; i < tex.FaceTextures.Length; i++)
241 {
242 try {
243 if (tex.FaceTextures[i] != null)
244 {
245 texcolor = tex.FaceTextures[i].RGBA;
246 texcolor.A = transparencyAmount;
247 tex.FaceTextures[i].RGBA = texcolor;
248 }
249 }
250 catch (Exception)
251 {
252 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e);
253 continue;
254 }
255 }
256 try {
257 texcolor = tex.DefaultTexture.RGBA;
258 texcolor.A = transparencyAmount;
259 tex.DefaultTexture.RGBA = texcolor;
260 part.Shape.TextureEntry = tex.GetBytes();
261 }
262 catch (Exception)
263 {
264 //m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e);
265 }
266 }
267
268 #endregion Public Methods
269 }
270}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
deleted file mode 100644
index 2c5093f..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
+++ /dev/null
@@ -1,104 +0,0 @@
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.Collections.Generic;
30using System.Drawing;
31
32using OpenMetaverse;
33
34using Nini.Config;
35
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Physics.Manager;
40
41using log4net;
42
43namespace OpenSim.Region.OptionalModules.ContentManagement
44{
45 public class PointMetaEntity : MetaEntity
46 {
47 #region Constructors
48
49 public PointMetaEntity(Scene scene, Vector3 groupPos, float transparency)
50 : base()
51 {
52 CreatePointEntity(scene, UUID.Random(), groupPos);
53 SetPartTransparency(m_Entity.RootPart, transparency);
54 }
55
56 public PointMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency)
57 : base()
58 {
59 CreatePointEntity(scene, uuid, groupPos);
60 SetPartTransparency(m_Entity.RootPart, transparency);
61 }
62
63 #endregion Constructors
64
65 #region Private Methods
66
67 private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos)
68 {
69 SceneObjectPart y = new SceneObjectPart();
70
71 //Initialize part
72 y.Name = "Very Small Point";
73 y.RegionHandle = scene.RegionInfo.RegionHandle;
74 y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
75 y.OwnerID = UUID.Zero;
76 y.CreatorID = UUID.Zero;
77 y.LastOwnerID = UUID.Zero;
78 y.UUID = uuid;
79
80 y.Shape = PrimitiveBaseShape.CreateBox();
81 y.Scale = new Vector3(0.01f,0.01f,0.01f);
82 y.LastOwnerID = UUID.Zero;
83 y.GroupPosition = groupPos;
84 y.OffsetPosition = Vector3.Zero;
85 y.RotationOffset = Quaternion.Identity;
86 y.Velocity = Vector3.Zero;
87 y.AngularVelocity = Vector3.Zero;
88 y.Acceleration = Vector3.Zero;
89
90 y.Flags = 0;
91 y.TrimPermissions();
92
93 //Initialize group and add part as root part
94 SceneObjectGroup x = new SceneObjectGroup(y);
95 x.SetScene(scene);
96 x.RegionHandle = scene.RegionInfo.RegionHandle;
97 x.SetScene(scene);
98
99 m_Entity = x;
100 }
101
102 #endregion Private Methods
103 }
104}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/README b/OpenSim/Region/OptionalModules/ContentManagementSystem/README
deleted file mode 100644
index 1a69fef..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/README
+++ /dev/null
@@ -1,52 +0,0 @@
1This module is meant to be built alone and not added to the Opensim code base. References are made to required dlls through a
2reference file, ContentManagement.mdp. Originally, for development, this project was contained in the Opensim/Region/Modules/
3directory.
4
5To compile: nant
6To use: Copy ContentManagement.dll into the bin directory of your Opensim build. You should find many other dlls in the same directory.
7
8
9--------------------------------------------------------------------------------------------------------------------
10To build the libgit.so file:
11
12#Download GIT git repository
13$ git clone git://git2.kernel.org/pub/OpenSim/Region/Environment/Modules/ContentManagementSystem/scm/git/git.git
14$ cd git
15
16#Compile GIT
17#Note that we are adding two extra flags to pass to gcc while compiling (-c and -fPIC)
18$ autoconf
19$ ./configure
20$ CFLAGS="-g -O2 -Wall -c -fPIC" make
21
22#Copy necessary object files (and some not so necessary) to their own directory for shared object file creation
23$ mkdir ../libgit-objects
24$ cp builtin*.o ../libgit-objects
25$ cp xdiff/*.o ../libgit-objects
26$ cp libgit.a ../libgit-objects
27
28#Remove the main symbol from any object files (like git.o)
29$ cd ../libgit-objects
30$ strip -N main *.o
31
32#Uncompress the plumbing objects from archive created by git
33$ ar x libgit.a
34
35#Create shared object file from all objects (including the zlib library)
36$ ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o
37
38
39#You can also just copy the following commands into a file and run as a script inside the git directory
40
41make clean
42autoconf
43./configure
44CFLAGS="-g -O2 -Wall -c -fPIC" make
45mkdir libgit-objects
46cp builtin*.o libgit-objects
47cp xdiff/*.o libgit-objects
48cp libgit.a libgit-objects
49cd libgit-objects
50strip -N main *.o
51ar x libgit.a
52ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
deleted file mode 100644
index a6afa5a..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
+++ /dev/null
@@ -1,216 +0,0 @@
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
28#region Header
29
30// SceneObjectGroupDiff.cs
31// User: bongiojp
32
33#endregion Header
34
35using System;
36using System.Collections.Generic;
37using System.Diagnostics;
38using System.Drawing;
39
40using OpenMetaverse;
41
42using Nini.Config;
43
44using OpenSim.Framework;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.Physics.Manager;
48
49using log4net;
50
51namespace OpenSim.Region.OptionalModules.ContentManagement
52{
53 #region Enumerations
54
55 [Flags]
56 public enum Diff
57 {
58 NONE = 0,
59 FACECOLOR = 1,
60 SHAPE = 1<<1,
61 MATERIAL = 1<<2,
62 TEXTURE = 1<<3,
63 SCALE = 1<<4,
64 POSITION = 1<<5,
65 OFFSETPOSITION = 1<<6,
66 ROTATIONOFFSET = 1<<7,
67 ROTATIONALVELOCITY = 1<<8,
68 ACCELERATION = 1<<9,
69 ANGULARVELOCITY = 1<<10,
70 VELOCITY = 1<<11,
71 OBJECTOWNER = 1<<12,
72 PERMISSIONS = 1<<13,
73 DESCRIPTION = 1<<14,
74 NAME = 1<<15,
75 SCRIPT = 1<<16,
76 CLICKACTION = 1<<17,
77 PARTICLESYSTEM = 1<<18,
78 GLOW = 1<<19,
79 SALEPRICE = 1<<20,
80 SITNAME = 1<<21,
81 SITTARGETORIENTATION = 1<<22,
82 SITTARGETPOSITION = 1<<23,
83 TEXT = 1<<24,
84 TOUCHNAME = 1<<25
85 }
86
87 #endregion Enumerations
88
89 public static class Difference
90 {
91 #region Static Fields
92
93 static float TimeToDiff = 0;
94// private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
95
96 #endregion Static Fields
97
98 #region Private Methods
99
100 private static bool AreQuaternionsEquivalent(Quaternion first, Quaternion second)
101 {
102 Vector3 firstVector = llRot2Euler(first);
103 Vector3 secondVector = llRot2Euler(second);
104 return AreVectorsEquivalent(firstVector, secondVector);
105 }
106
107 private static bool AreVectorsEquivalent(Vector3 first, Vector3 second)
108 {
109 if (TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2)
110 && TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2)
111 && TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2)
112 )
113 return true;
114 else
115 return false;
116 }
117
118 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
119 private static double NormalizeAngle(double angle)
120 {
121 angle = angle % (Math.PI * 2);
122 if (angle < 0) angle = angle + Math.PI * 2;
123 return angle;
124 }
125
126 private static int TruncateSignificant(float num, int digits)
127 {
128 return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits));
129 // return (int) ((num * (10*digits))/10*digits);
130 }
131
132 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
133 // Also changed the original function from LSL_Types to LL types
134 private static Vector3 llRot2Euler(Quaternion r)
135 {
136 Quaternion t = new Quaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W);
137 double m = (t.X + t.Y + t.Z + t.W);
138 if (m == 0) return new Vector3();
139 double n = 2 * (r.Y * r.W + r.X * r.Z);
140 double p = m * m - n * n;
141 if (p > 0)
142 return new Vector3((float)NormalizeAngle(Math.Atan2(2.0 * (r.X * r.W - r.Y * r.Z), (-t.X - t.Y + t.Z + t.W))),
143 (float)NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))),
144 (float)NormalizeAngle(Math.Atan2(2.0 * (r.Z * r.W - r.X * r.Y), (t.X - t.Y - t.Z + t.W))));
145 else if (n > 0)
146 return new Vector3(0.0f, (float)(Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z)));
147 else
148 return new Vector3(0.0f, (float)(-Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z)));
149 }
150
151 #endregion Private Methods
152
153 #region Public Methods
154
155 /// <summary>
156 /// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts
157 /// and returns a Diff bitmask which details what the differences are.
158 /// </summary>
159 public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second)
160 {
161 Stopwatch x = new Stopwatch();
162 x.Start();
163
164 Diff result = 0;
165
166 // VECTOR COMPARISONS
167 if (!AreVectorsEquivalent(first.Acceleration, second.Acceleration))
168 result |= Diff.ACCELERATION;
169 if (!AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition))
170 result |= Diff.POSITION;
171 if (!AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity))
172 result |= Diff.ANGULARVELOCITY;
173 if (!AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition))
174 result |= Diff.OFFSETPOSITION;
175 if (!AreVectorsEquivalent(first.Scale, second.Scale))
176 result |= Diff.SCALE;
177 if (!AreVectorsEquivalent(first.Velocity, second.Velocity))
178 result |= Diff.VELOCITY;
179
180
181 // QUATERNION COMPARISONS
182 if (!AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset))
183 result |= Diff.ROTATIONOFFSET;
184
185
186 // MISC COMPARISONS (UUID, Byte)
187 if (first.ClickAction != second.ClickAction)
188 result |= Diff.CLICKACTION;
189 if (first.OwnerID != second.OwnerID)
190 result |= Diff.OBJECTOWNER;
191
192
193 // STRING COMPARISONS
194 if (first.Description != second.Description)
195 result |= Diff.DESCRIPTION;
196 if (first.Material != second.Material)
197 result |= Diff.MATERIAL;
198 if (first.Name != second.Name)
199 result |= Diff.NAME;
200 if (first.SitName != second.SitName)
201 result |= Diff.SITNAME;
202 if (first.Text != second.Text)
203 result |= Diff.TEXT;
204 if (first.TouchName != second.TouchName)
205 result |= Diff.TOUCHNAME;
206
207 x.Stop();
208 TimeToDiff += x.ElapsedMilliseconds;
209 //m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff);
210
211 return result;
212 }
213
214 #endregion Public Methods
215 }
216}
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index 122ad40..eed6450 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -28,10 +28,14 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Net;
32using System.IO;
33using System.Text;
31 34
32using log4net; 35using log4net;
33using Nini.Config; 36using Nini.Config;
34using OpenMetaverse; 37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
35 39
36using OpenSim.Framework; 40using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces; 41using OpenSim.Region.Framework.Interfaces;
@@ -50,6 +54,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
50 private bool m_lastOarLoadedOk; 54 private bool m_lastOarLoadedOk;
51 private int m_channelNotify = -1000; 55 private int m_channelNotify = -1000;
52 private bool m_enabled = false; 56 private bool m_enabled = false;
57 private bool m_disable_logins = false;
58 private string m_uri = string.Empty;
53 59
54 Scene m_scene = null; 60 Scene m_scene = null;
55 61
@@ -68,10 +74,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
68 if (m_config != null) 74 if (m_config != null)
69 { 75 {
70 m_enabled = m_config.GetBoolean("enabled", false); 76 m_enabled = m_config.GetBoolean("enabled", false);
77
71 if (m_enabled) 78 if (m_enabled)
72 { 79 {
73 m_channelNotify = m_config.GetInt("channel_notify", m_channelNotify); 80 m_channelNotify = m_config.GetInt("channel_notify", m_channelNotify);
74 } 81 m_disable_logins = m_config.GetBoolean("login_disable", false);
82 m_uri = m_config.GetString("alert_uri",string.Empty);
83 }
75 } 84 }
76 85
77// if (!m_enabled) 86// if (!m_enabled)
@@ -91,8 +100,21 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
91 100
92 m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue; 101 m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
93 m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded; 102 m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded;
103 m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
94 104
95 m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName); 105 m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName);
106
107 if(m_disable_logins == true)
108 {
109 scene.LoginLock = true;
110 scene.LoginsDisabled = true;
111 m_log.InfoFormat("[RegionReady]: Logins disabled for {0}",m_scene.RegionInfo.RegionName);
112
113 if(m_uri != string.Empty)
114 {
115 RRAlert("disabled");
116 }
117 }
96 } 118 }
97 119
98 public void RemoveRegion(Scene scene) 120 public void RemoveRegion(Scene scene)
@@ -150,7 +172,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
150 172
151 m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", 173 m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}",
152 m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); 174 m_scene.RegionInfo.RegionName, c.Message, m_channelNotify);
153 m_scene.EventManager.TriggerOnChatBroadcast(this, c); 175
176 m_scene.EventManager.TriggerOnChatBroadcast(this, c);
177 m_scene.EventManager.TriggerLoginsEnabled(m_scene.RegionInfo.RegionName);
154 } 178 }
155 } 179 }
156 180
@@ -165,5 +189,69 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
165 m_lastOarLoadedOk = false; 189 m_lastOarLoadedOk = false;
166 } 190 }
167 } 191 }
192
193 void OnLoginsEnabled(string regionName)
194 {
195 if (m_disable_logins == true)
196 {
197 if (m_scene.StartDisabled == false)
198 {
199 m_scene.LoginsDisabled = false;
200 m_scene.LoginLock = false;
201 m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName);
202 if ( m_uri != string.Empty )
203 {
204 RRAlert("enabled");
205 }
206 }
207 }
208 }
209
210 public void RRAlert(string status)
211 {
212 string request_method = "POST";
213 string content_type = "application/json";
214 OSDMap RRAlert = new OSDMap();
215
216 RRAlert["alert"] = "region_ready";
217 RRAlert["login"] = status;
218 RRAlert["region_name"] = m_scene.RegionInfo.RegionName;
219 RRAlert["region_id"] = m_scene.RegionInfo.RegionID;
220
221 string strBuffer = "";
222 byte[] buffer = new byte[1];
223 try
224 {
225 strBuffer = OSDParser.SerializeJsonString(RRAlert);
226 Encoding str = Util.UTF8;
227 buffer = str.GetBytes(strBuffer);
228
229 }
230 catch (Exception e)
231 {
232 m_log.WarnFormat("[RegionReady]: Exception thrown on alert: {0}", e.Message);
233 }
234
235 WebRequest request = WebRequest.Create(m_uri);
236 request.Method = request_method;
237 request.ContentType = content_type;
238
239 Stream os = null;
240 try
241 {
242 request.ContentLength = buffer.Length;
243 os = request.GetRequestStream();
244 os.Write(buffer, 0, strBuffer.Length);
245 }
246 catch(Exception e)
247 {
248 m_log.WarnFormat("[RegionReady]: Exception thrown sending alert: {0}", e.Message);
249 }
250 finally
251 {
252 if (os != null)
253 os.Close();
254 }
255 }
168 } 256 }
169} 257}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index d895438..f07ad67 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -631,7 +631,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
631 { 631 {
632 } 632 }
633 633
634 public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) 634 public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
635 { 635 {
636 } 636 }
637 637
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3afedc7..d695a0c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -309,7 +309,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
309 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
310 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
311 // in mouselook. 311 // in mouselook.
312
313 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
314 fromRegionPos = avatar.AbsolutePosition; 313 fromRegionPos = avatar.AbsolutePosition;
315 q = avatar.Rotation; 314 q = avatar.Rotation;
@@ -424,6 +423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
424 423
425 SceneObjectPart SensePoint = ts.host; 424 SceneObjectPart SensePoint = ts.host;
426 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 425 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
426
427 Quaternion q = SensePoint.RotationOffset; 427 Quaternion q = SensePoint.RotationOffset;
428 if (SensePoint.ParentGroup.RootPart.IsAttachment) 428 if (SensePoint.ParentGroup.RootPart.IsAttachment)
429 { 429 {
@@ -435,6 +435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
435 fromRegionPos = avatar.AbsolutePosition; 435 fromRegionPos = avatar.AbsolutePosition;
436 q = avatar.Rotation; 436 q = avatar.Rotation;
437 } 437 }
438
438 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 439 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
439 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 440 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
440 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 441 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);