From d21e9c755f004d8fe03b11bc57b810dbd401435a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 19 May 2011 16:54:46 -0700 Subject: HG Friends working to some extent: friendships offered and accepted correctly handled. Friends list showing correct foreign names. TODO: GrantRights. --- OpenSim/Data/IFriendsData.cs | 2 +- .../Data/MySQL/Resources/FriendsStore.migrations | 6 + OpenSim/Data/Null/NullFriendsData.cs | 4 +- OpenSim/Framework/AgentCircuitData.cs | 1 + OpenSim/Framework/AssetBase.cs | 6 + OpenSim/Framework/Util.cs | 61 +++ .../CoreModules/Avatar/Friends/FriendsModule.cs | 151 +++++-- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 438 +++++++++++++++++++++ .../UserManagement/UserManagementModule.cs | 2 + .../Hypergrid/HypergridServiceInConnectorModule.cs | 1 + .../Handlers/Friends/FriendServerConnector.cs | 6 +- .../Handlers/Friends/FriendsServerPostHandler.cs | 2 +- .../Handlers/Hypergrid/HGFriendServerConnector.cs | 71 ++++ .../Hypergrid/HGFriendsServerPostHandler.cs | 242 ++++++++++++ .../Connectors/Friends/FriendsServiceConnector.cs | 13 +- .../Hypergrid/HGFriendsServiceConnector.cs | 175 ++++++++ .../SimianGrid/SimianFriendsServiceConnector.cs | 2 +- OpenSim/Services/Friends/FriendsService.cs | 9 +- .../Services/HypergridService/HGFriendsService.cs | 95 +++++ OpenSim/Services/Interfaces/IFriendsService.cs | 2 +- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 14 +- bin/config-include/StandaloneHypergrid.ini | 5 + prebuild.xml | 1 + 23 files changed, 1252 insertions(+), 57 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs create mode 100644 OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs create mode 100644 OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs create mode 100644 OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs create mode 100644 OpenSim/Services/HypergridService/HGFriendsService.cs diff --git a/OpenSim/Data/IFriendsData.cs b/OpenSim/Data/IFriendsData.cs index 1f1a031..4da567e 100644 --- a/OpenSim/Data/IFriendsData.cs +++ b/OpenSim/Data/IFriendsData.cs @@ -34,7 +34,7 @@ namespace OpenSim.Data { public class FriendsData { - public UUID PrincipalID; + public string PrincipalID; public string Friend; public Dictionary Data; } diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations index ce713bd..35e5e93 100644 --- a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations +++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations @@ -21,5 +21,11 @@ INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userf COMMIT; +:VERSION 3 # ------------------------- +BEGIN; + +ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; + +COMMIT; diff --git a/OpenSim/Data/Null/NullFriendsData.cs b/OpenSim/Data/Null/NullFriendsData.cs index e7f7fd3..0c69bb1 100644 --- a/OpenSim/Data/Null/NullFriendsData.cs +++ b/OpenSim/Data/Null/NullFriendsData.cs @@ -53,7 +53,7 @@ namespace OpenSim.Data.Null { List lst = m_Data.FindAll(delegate (FriendsData fdata) { - return fdata.PrincipalID == userID; + return fdata.PrincipalID == userID.ToString(); }); if (lst != null) @@ -74,7 +74,7 @@ namespace OpenSim.Data.Null public bool Delete(UUID userID, string friendID) { - List lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID; }); + List lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); }); if (lst != null) { FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; }); diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index dbd47d3..125910e 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -345,6 +345,7 @@ namespace OpenSim.Framework } } } + } diff --git a/OpenSim/Framework/AssetBase.cs b/OpenSim/Framework/AssetBase.cs index 53d28be..5f68cda 100644 --- a/OpenSim/Framework/AssetBase.cs +++ b/OpenSim/Framework/AssetBase.cs @@ -215,6 +215,12 @@ namespace OpenSim.Framework set { m_metadata.Temporary = value; } } + public string CreatorID + { + get { return m_metadata.CreatorID; } + set { m_metadata.CreatorID = value; } + } + public AssetFlags Flags { get { return m_metadata.Flags; } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index aaa2724..af21cb5 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1694,5 +1694,66 @@ namespace OpenSim.Framework return (T)Enum.Parse(typeof(T), value); ; } #endregion + + #region Universal User Identifiers + /// + /// + /// uuid[;endpoint[;name]] + /// + /// + /// + /// + public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname) + { + uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; + + string[] parts = value.Split(';'); + if (parts.Length >= 1) + if (!UUID.TryParse(parts[0], out uuid)) + return false; + + if (parts.Length >= 2) + url = parts[1]; + + if (parts.Length >= 3) + { + string[] name = parts[2].Split(); + if (name.Length == 2) + { + firstname = name[0]; + lastname = name[1]; + } + } + + return true; + } + + /// + /// + /// + /// + /// uuid[;endpoint[;name]] + public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit) + { + if (acircuit.ServiceURLs.ContainsKey("HomeURI")) + { + string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString(); + if (!agentsURI.EndsWith("/")) + agentsURI += "/"; + + // This is ugly, but there's no other way, given that the name is changed + // in the agent circuit data for foreigners + if (acircuit.lastname.Contains("@")) + { + string[] parts = acircuit.firstname.Split(new char[] { '.' }); + if (parts.Length == 2) + return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1]; + } + return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname; + } + else + return acircuit.AgentID.ToString(); + } + #endregion } } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 5baf078..21cd924 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 { public class FriendsModule : ISharedRegionModule, IFriendsModule { + protected bool m_Enabled = false; + protected class UserFriendData { public UUID PrincipalID; @@ -130,8 +132,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } + #region ISharedRegionModule public void Initialise(IConfigSource config) { + IConfig moduleConfig = config.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("FriendsModule", "FriendsModule"); + m_log.DebugFormat("[XXX] {0} compared to {1}", name, Name); + if (name == Name) + { + InitModule(config); + + m_Enabled = true; + m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name); + } + } + } + + protected void InitModule(IConfigSource config) + { IConfig friendsConfig = config.Configs["Friends"]; if (friendsConfig != null) { @@ -153,7 +173,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue"); throw new Exception("Connector load error"); } - } public void PostInitialise() @@ -166,6 +185,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends public void AddRegion(Scene scene) { + if (!m_Enabled) + return; + m_Scenes.Add(scene); scene.RegisterModuleInterface(this); @@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends public void RemoveRegion(Scene scene) { + if (!m_Enabled) + return; + m_Scenes.Remove(scene); } - public string Name + public virtual string Name { get { return "FriendsModule"; } } @@ -194,6 +219,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends get { return null; } } + #endregion + public uint GetFriendPerms(UUID principalID, UUID friendID) { FriendInfo[] friends = GetFriends(principalID); @@ -214,30 +241,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends client.OnTerminateFriendship += OnTerminateFriendship; client.OnGrantUserRights += OnGrantUserRights; - // Asynchronously fetch the friends list or increment the refcount for the existing - // friends list - Util.FireAndForget( - delegate(object o) + Util.FireAndForget(delegate { FetchFriendslist(client.AgentId); }); + } + + /// Fetch the friends list or increment the refcount for the existing + /// friends list + /// Returns true if the list was fetched, false if it wasn't + protected virtual bool FetchFriendslist(UUID agentID) + { + lock (m_Friends) + { + UserFriendData friendsData; + if (m_Friends.TryGetValue(agentID, out friendsData)) { - lock (m_Friends) - { - UserFriendData friendsData; - if (m_Friends.TryGetValue(client.AgentId, out friendsData)) - { - friendsData.Refcount++; - } - else - { - friendsData = new UserFriendData(); - friendsData.PrincipalID = client.AgentId; - friendsData.Friends = FriendsService.GetFriends(client.AgentId); - friendsData.Refcount = 1; + friendsData.Refcount++; + return false; + } + else + { + friendsData = new UserFriendData(); + friendsData.PrincipalID = agentID; + friendsData.Friends = FriendsService.GetFriends(agentID); + friendsData.Refcount = 1; - m_Friends[client.AgentId] = friendsData; - } - } + m_Friends[agentID] = friendsData; + return true; } - ); + } } private void OnClientClosed(UUID agentID, Scene scene) @@ -313,10 +343,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends foreach (string fid in outstanding) { UUID fromAgentID; - if (!UUID.TryParse(fid, out fromAgentID)) + string firstname = "Unknown", lastname = "User"; + if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname)) + { + m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid); continue; - - UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID); + } PresenceInfo presence = null; PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); @@ -326,15 +358,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends im.offline = 0; im.fromAgentID = fromAgentID.Guid; - im.fromAgentName = account.FirstName + " " + account.LastName; + im.fromAgentName = firstname + " " + lastname; im.offline = (byte)((presence == null) ? 1 : 0); im.imSessionID = im.fromAgentID; + im.message = FriendshipMessage(fid); // Finally LocalFriendshipOffered(agentID, im); } } + protected virtual string FriendshipMessage(string friendID) + { + return "Will you be my friend?"; + } + + protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) + { + first = "Unknown"; last = "User"; + if (!UUID.TryParse(fid, out agentID)) + return false; + + UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID); + if (account != null) + { + first = account.FirstName; + last = account.LastName; + } + + return true; + } + List GetOnlineFriends(UUID userID) { List friendList = new List(); @@ -475,23 +529,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // This user wants to be friends with the other user. // Let's add the relation backwards, in case the other is not online - FriendsService.StoreFriend(friendID, principalID.ToString(), 0); + StoreBackwards(friendID, principalID); // Now let's ask the other user to be friends with this user ForwardFriendshipOffer(principalID, friendID, im); } } + protected virtual void StoreBackwards(UUID friendID, UUID agentID) + { + FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0); + } + private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) { // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) // We stick this agent's ID as imSession, so that it's directly available on the receiving end im.imSessionID = im.fromAgentID; + im.fromAgentName = GetFriendshipRequesterName(agentID); - // Try the local sim - UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID); - im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; - + // Try the local sim if (LocalFriendshipOffered(friendID, im)) return; @@ -509,12 +566,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // If the prospective friend is not online, he'll get the message upon login. } + protected virtual string GetFriendshipRequesterName(UUID agentID) + { + UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID); + return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; + } + private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List callingCardFolders) { m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID); - - FriendsService.StoreFriend(agentID, friendID.ToString(), 1); - FriendsService.StoreFriend(friendID, agentID.ToString(), 1); + + StoreFriendships(agentID, friendID); // Update the local cache UpdateFriendsCache(agentID); @@ -544,6 +606,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } + protected virtual void StoreFriendships(UUID agentID, UUID friendID) + { + FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1); + FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1); + } + private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List callingCardFolders) { m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); @@ -576,8 +644,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) { - FriendsService.Delete(agentID, exfriendID.ToString()); - FriendsService.Delete(exfriendID, agentID.ToString()); + DeleteFriendship(agentID, exfriendID); // Update local cache UpdateFriendsCache(agentID); @@ -604,6 +671,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } + protected virtual void DeleteFriendship(UUID agentID, UUID exfriendID) + { + FriendsService.Delete(agentID, exfriendID.ToString()); + FriendsService.Delete(exfriendID, agentID.ToString()); + } + private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) { FriendInfo[] friends = GetFriends(remoteClient.AgentId); @@ -622,7 +695,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (friend != null) // Found it { // Store it on the DB - FriendsService.StoreFriend(requester, target.ToString(), rights); + FriendsService.StoreFriend(requester.ToString(), target.ToString(), rights); // Store it in the local cache int myFlags = friend.MyFlags; @@ -780,7 +853,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends #endregion - private FriendInfo[] GetFriends(UUID agentID) + protected FriendInfo[] GetFriends(UUID agentID) { UserFriendData friendsData; diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs new file mode 100644 index 0000000..645ecdc --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -0,0 +1,438 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using Nwc.XmlRpc; +using Mono.Addins; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.Hypergrid; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; +using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.CoreModules.Avatar.Friends +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + #region ISharedRegionModule + public override string Name + { + get { return "HGFriendsModule"; } + } + + #endregion + + //public void SendFriendsOnlineIfNeeded(IClientAPI client) + //{ + // UUID agentID = client.AgentId; + + // // Check if the online friends list is needed + // lock (m_NeedsListOfFriends) + // { + // if (!m_NeedsListOfFriends.Remove(agentID)) + // return; + // } + + // // Send the friends online + // List online = GetOnlineFriends(agentID); + // if (online.Count > 0) + // { + // m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count); + // client.SendAgentOnline(online.ToArray()); + // } + + // // Send outstanding friendship offers + // List outstanding = new List(); + // FriendInfo[] friends = GetFriends(agentID); + // foreach (FriendInfo fi in friends) + // { + // if (fi.TheirFlags == -1) + // outstanding.Add(fi.Friend); + // } + + // GridInstantMessage im = new GridInstantMessage(client.Scene, UUID.Zero, String.Empty, agentID, (byte)InstantMessageDialog.FriendshipOffered, + // "Will you be my friend?", true, Vector3.Zero); + + // foreach (string fid in outstanding) + // { + // UUID fromAgentID; + // if (!UUID.TryParse(fid, out fromAgentID)) + // continue; + + // UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID); + + // PresenceInfo presence = null; + // PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); + // if (presences != null && presences.Length > 0) + // presence = presences[0]; + // if (presence != null) + // im.offline = 0; + + // im.fromAgentID = fromAgentID.Guid; + // im.fromAgentName = account.FirstName + " " + account.LastName; + // im.offline = (byte)((presence == null) ? 1 : 0); + // im.imSessionID = im.fromAgentID; + + // // Finally + // LocalFriendshipOffered(agentID, im); + // } + //} + + //List GetOnlineFriends(UUID userID) + //{ + // List friendList = new List(); + // List online = new List(); + + // FriendInfo[] friends = GetFriends(userID); + // foreach (FriendInfo fi in friends) + // { + // if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1)) + // friendList.Add(fi.Friend); + // } + + // if (friendList.Count > 0) + // { + // PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); + // foreach (PresenceInfo pi in presence) + // { + // UUID presenceID; + // if (UUID.TryParse(pi.UserID, out presenceID)) + // online.Add(presenceID); + // } + // } + + // return online; + //} + + //private void StatusNotify(FriendInfo friend, UUID userID, bool online) + //{ + // UUID friendID; + // if (UUID.TryParse(friend.Friend, out friendID)) + // { + // // Try local + // if (LocalStatusNotification(userID, friendID, online)) + // return; + + // // The friend is not here [as root]. Let's forward. + // PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); + // if (friendSessions != null && friendSessions.Length > 0) + // { + // PresenceInfo friendSession = null; + // foreach (PresenceInfo pinfo in friendSessions) + // if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad + // { + // friendSession = pinfo; + // break; + // } + + // if (friendSession != null) + // { + // GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + // //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); + // m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); + // } + // } + + // // Friend is not online. Ignore. + // } + // else + // { + // m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); + // } + //} + + protected override bool FetchFriendslist(UUID agentID) + { + if (base.FetchFriendslist(agentID)) + { + // We need to preload the user management cache with the names + // of foreign friends, just like we do with SOPs' creators + foreach (FriendInfo finfo in m_Friends[agentID].Friends) + { + if (finfo.TheirFlags != -1) + { + UUID id; + if (!UUID.TryParse(finfo.Friend, out id)) + { + string url = string.Empty, first = string.Empty, last = string.Empty; + if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last)) + { + IUserManagement uMan = m_Scenes[0].RequestModuleInterface(); + uMan.AddUser(id, url + ";" + first + " " + last); + } + } + } + } + return true; + } + return false; + } + + protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) + { + first = "Unknown"; last = "User"; + if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last)) + return true; + + // fid is not a UUID... + string url = string.Empty; + if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last)) + { + IUserManagement userMan = m_Scenes[0].RequestModuleInterface(); + userMan.AddUser(agentID, url + ";" + first + " " + last); + + try // our best + { + string[] parts = userMan.GetUserName(agentID).Split(); + first = parts[0]; + last = parts[1]; + } + catch { } + return true; + } + return false; + } + + protected override string GetFriendshipRequesterName(UUID agentID) + { + // For the time being we assume that HG friendship requests can only happen + // when avies are on the same region. + IClientAPI client = LocateClientObject(agentID); + if (client != null) + return client.FirstName + " " + client.LastName; + else + return base.GetFriendshipRequesterName(agentID); + } + + protected override string FriendshipMessage(string friendID) + { + UUID id; + if (UUID.TryParse(friendID, out id)) + return base.FriendshipMessage(friendID); + + return "Please confirm this friendship you made while you were away."; + } + + protected override void StoreBackwards(UUID friendID, UUID agentID) + { + UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); + UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); + // Are they both local users? + if (account1 != null && account2 != null) + { + // local grid users + m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local"); + base.StoreBackwards(friendID, agentID); + return; + } + + // no provision for this temporary friendship state + //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0); + } + + protected override void StoreFriendships(UUID agentID, UUID friendID) + { + UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); + UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); + // Are they both local users? + if (agentAccount != null && friendAccount != null) + { + // local grid users + m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local"); + base.StoreFriendships(agentID, friendID); + return; + } + + + // ok, at least one of them is foreigner, let's get their data + IClientAPI agentClient = LocateClientObject(agentID); + IClientAPI friendClient = LocateClientObject(friendID); + AgentCircuitData agentClientCircuit = null; + AgentCircuitData friendClientCircuit = null; + string agentUUI = string.Empty; + string friendUUI = string.Empty; + string agentFriendService = string.Empty; + string friendFriendService = string.Empty; + + if (agentClient != null) + { + agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); + agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); + agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); + } + if (friendClient != null) + { + friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); + friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); + friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); + } + + m_log.DebugFormat("[XXX] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", + agentUUI, friendUUI, agentFriendService, friendFriendService); + + if (agentAccount != null) // agent is local, 'friend' is foreigner + { + // This may happen when the agent returned home, in which case the friend is not there + // We need to llok for its information in the friends list itself + if (friendUUI == string.Empty) + { + FriendInfo[] finfos = GetFriends(agentID); + foreach (FriendInfo finfo in finfos) + { + if (finfo.TheirFlags == -1) + { + if (finfo.Friend.StartsWith(friendID.ToString())) + friendUUI = finfo.Friend; + } + } + } + + // store in the local friends service a reference to the foreign friend + FriendsService.StoreFriend(agentID.ToString(), friendUUI, 1); + // and also the converse + FriendsService.StoreFriend(friendUUI, agentID.ToString(), 1); + + if (friendClientCircuit != null) + { + // store in the foreign friends service a reference to the local agent + HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); + friendsConn.NewFriendship(friendID, agentUUI); + } + } + else if (friendAccount != null) // 'friend' is local, agent is foreigner + { + // store in the local friends service a reference to the foreign agent + FriendsService.StoreFriend(friendID.ToString(), agentUUI, 1); + // and also the converse + FriendsService.StoreFriend(agentUUI, friendID.ToString(), 1); + + if (agentClientCircuit != null) + { + // store in the foreign friends service a reference to the local agent + HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); + friendsConn.NewFriendship(agentID, friendUUI); + } + } + else // They're both foreigners! + { + HGFriendsServicesConnector friendsConn; + if (agentClientCircuit != null) + { + friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); + friendsConn.NewFriendship(agentID, friendUUI); + } + if (friendClientCircuit != null) + { + friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); + friendsConn.NewFriendship(friendID, agentUUI); + } + } + // my brain hurts now + } + + protected override void DeleteFriendship(UUID agentID, UUID exfriendID) + { + base.DeleteFriendship(agentID, exfriendID); + // Maybe some of the base deletes will fail. + // Let's delete the local friendship with foreign friend + FriendInfo[] friends = GetFriends(agentID); + foreach (FriendInfo finfo in friends) + { + if (finfo.Friend != exfriendID.ToString() && finfo.Friend.EndsWith(exfriendID.ToString())) + { + FriendsService.Delete(agentID, exfriendID.ToString()); + // TODO: delete the friendship on the other side + // Should use the homeurl given in finfo.Friend + } + } + } + + //private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) + //{ + // FriendInfo[] friends = GetFriends(remoteClient.AgentId); + // if (friends.Length == 0) + // return; + + // m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); + // // Let's find the friend in this user's friend list + // FriendInfo friend = null; + // foreach (FriendInfo fi in friends) + // { + // if (fi.Friend == target.ToString()) + // friend = fi; + // } + + // if (friend != null) // Found it + // { + // // Store it on the DB + // FriendsService.StoreFriend(requester, target.ToString(), rights); + + // // Store it in the local cache + // int myFlags = friend.MyFlags; + // friend.MyFlags = rights; + + // // Always send this back to the original client + // remoteClient.SendChangeUserRights(requester, target, rights); + + // // + // // Notify the friend + // // + + // // Try local + // if (LocalGrantRights(requester, target, myFlags, rights)) + // return; + + // PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() }); + // if (friendSessions != null && friendSessions.Length > 0) + // { + // PresenceInfo friendSession = friendSessions[0]; + // if (friendSession != null) + // { + // GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + // // TODO: You might want to send the delta to save the lookup + // // on the other end!! + // m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights); + // } + // } + // } + //} + + + } +} diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 4cc6905..795de09 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -141,6 +141,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) { + m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0}", uuid); if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) { remote_client.SendNameReply(uuid, "Mr", "OpenSim"); @@ -210,6 +211,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public string GetUserName(UUID uuid) { + m_log.DebugFormat("[XXX] GetUserName {0}", uuid); string[] names = GetUserNames(uuid); if (names.Length == 2) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs index d2343c9..f5b6817 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs @@ -115,6 +115,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid new UserAgentServerConnector(m_Config, MainServer.Instance); new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); + new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService"); } scene.RegisterModuleInterface(m_HypergridHandler.GateKeeper); } diff --git a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs index 074f869..5784bdf 100644 --- a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs +++ b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs @@ -46,14 +46,14 @@ namespace OpenSim.Server.Handlers.Friends if (serverConfig == null) throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); - string gridService = serverConfig.GetString("LocalServiceModule", + string theService = serverConfig.GetString("LocalServiceModule", String.Empty); - if (gridService == String.Empty) + if (theService == String.Empty) throw new Exception("No LocalServiceModule in config file"); Object[] args = new Object[] { config }; - m_FriendsService = ServerUtils.LoadPlugin(gridService, args); + m_FriendsService = ServerUtils.LoadPlugin(theService, args); server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService)); } diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs index b168bb3..64002e1 100644 --- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs @@ -138,7 +138,7 @@ namespace OpenSim.Server.Handlers.Friends { FriendInfo friend = new FriendInfo(request); - bool success = m_FriendsService.StoreFriend(friend.PrincipalID, friend.Friend, friend.MyFlags); + bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, friend.MyFlags); if (success) return SuccessResult(); diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs new file mode 100644 index 0000000..82a7220 --- /dev/null +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs @@ -0,0 +1,71 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; + +namespace OpenSim.Server.Handlers.Hypergrid +{ + public class HGFriendsServerConnector : ServiceConnector + { + private IFriendsService m_FriendsService; + private IUserAgentService m_UserAgentService; + private string m_ConfigName = "HGFriendsService"; + + public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + if (configName != string.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); + + string theService = serverConfig.GetString("LocalServiceModule", + String.Empty); + + if (theService == String.Empty) + throw new Exception("No LocalServiceModule in config file"); + + Object[] args = new Object[] { config }; + m_FriendsService = ServerUtils.LoadPlugin(theService, args); + + theService = serverConfig.GetString("UserAgentService", string.Empty); + if (theService == String.Empty) + throw new Exception("No UserAgentService in " + m_ConfigName); + + m_UserAgentService = ServerUtils.LoadPlugin(theService, args); + + server.AddStreamHandler(new HGFriendsServerPostHandler(m_FriendsService, m_UserAgentService)); + } + } +} diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs new file mode 100644 index 0000000..13d1502 --- /dev/null +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs @@ -0,0 +1,242 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using Nini.Config; +using log4net; +using System; +using System.Reflection; +using System.IO; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Xml; +using System.Xml.Serialization; +using System.Collections.Generic; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenMetaverse; + +namespace OpenSim.Server.Handlers.Hypergrid +{ + public class HGFriendsServerPostHandler : BaseStreamHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IFriendsService m_FriendsService; + private IUserAgentService m_UserAgentService; + + public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) : + base("POST", "/hgfriends") + { + m_FriendsService = service; + m_UserAgentService = uservice; + m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On"); + } + + public override byte[] Handle(string path, Stream requestData, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + StreamReader sr = new StreamReader(requestData); + string body = sr.ReadToEnd(); + sr.Close(); + body = body.Trim(); + + //m_log.DebugFormat("[XXX]: query String: {0}", body); + + try + { + Dictionary request = + ServerUtils.ParseQueryString(body); + + if (!request.ContainsKey("METHOD")) + return FailureResult(); + + string method = request["METHOD"].ToString(); + + switch (method) + { + case "getfriends": + return GetFriends(request); + + case "newfriendship": + return NewFriendship(request); + + } + m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); + } + catch (Exception e) + { + m_log.DebugFormat("[HGFRIENDS HANDLER]: Exception {0}", e); + } + + return FailureResult(); + + } + + #region Method-specific handlers + + byte[] GetFriends(Dictionary request) + { + UUID principalID = UUID.Zero; + if (request.ContainsKey("PRINCIPALID")) + UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID); + else + m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friends"); + + FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); + //m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count); + + Dictionary result = new Dictionary(); + if ((finfos == null) || ((finfos != null) && (finfos.Length == 0))) + result["result"] = "null"; + else + { + int i = 0; + foreach (FriendInfo finfo in finfos) + { + Dictionary rinfoDict = finfo.ToKeyValuePairs(); + result["friend" + i] = rinfoDict; + i++; + } + } + + string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[FRIENDS HANDLER]: resp string: {0}", xmlString); + UTF8Encoding encoding = new UTF8Encoding(); + return encoding.GetBytes(xmlString); + + } + + byte[] NewFriendship(Dictionary request) + { + if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID")) + { + m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID"); + return FailureResult(); + } + + string serviceKey = request["KEY"].ToString(); + string sessionStr = request["SESSIONID"].ToString(); + UUID sessionID; + UUID.TryParse(sessionStr, out sessionID); + + if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey)) + { + m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID); + return FailureResult(); + } + + m_log.DebugFormat("[XXX] Verification ok"); + // OK, can proceed + FriendInfo friend = new FriendInfo(request); + + // the user needs to confirm when he gets home + bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0); + //if (success) + // m_FriendsService.StoreFriend(friend.Friend, friend.PrincipalID.ToString(), 1); + + if (success) + return SuccessResult(); + else + return FailureResult(); + } + + #endregion + + #region Misc + + private byte[] SuccessResult() + { + XmlDocument doc = new XmlDocument(); + + XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, + "", ""); + + doc.AppendChild(xmlnode); + + XmlElement rootElement = doc.CreateElement("", "ServerResponse", + ""); + + doc.AppendChild(rootElement); + + XmlElement result = doc.CreateElement("", "Result", ""); + result.AppendChild(doc.CreateTextNode("Success")); + + rootElement.AppendChild(result); + + return DocToBytes(doc); + } + + private byte[] FailureResult() + { + return FailureResult(String.Empty); + } + + private byte[] FailureResult(string msg) + { + XmlDocument doc = new XmlDocument(); + + XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, + "", ""); + + doc.AppendChild(xmlnode); + + XmlElement rootElement = doc.CreateElement("", "ServerResponse", + ""); + + doc.AppendChild(rootElement); + + XmlElement result = doc.CreateElement("", "Result", ""); + result.AppendChild(doc.CreateTextNode("Failure")); + + rootElement.AppendChild(result); + + XmlElement message = doc.CreateElement("", "Message", ""); + message.AppendChild(doc.CreateTextNode(msg)); + + rootElement.AppendChild(message); + + return DocToBytes(doc); + } + + private byte[] DocToBytes(XmlDocument doc) + { + MemoryStream ms = new MemoryStream(); + XmlTextWriter xw = new XmlTextWriter(ms, null); + xw.Formatting = Formatting.Indented; + doc.WriteTo(xw); + xw.Flush(); + + return ms.ToArray(); + } + + #endregion + } +} diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs index 861c475..52b80e1 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs @@ -38,7 +38,7 @@ using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; using OpenSim.Server.Base; using OpenMetaverse; -namespace OpenSim.Services.Connectors +namespace OpenSim.Services.Connectors.Friends { public class FriendsServicesConnector : IFriendsService { @@ -144,10 +144,17 @@ namespace OpenSim.Services.Connectors } - public bool StoreFriend(UUID PrincipalID, string Friend, int flags) + public bool StoreFriend(string PrincipalID, string Friend, int flags) { FriendInfo finfo = new FriendInfo(); - finfo.PrincipalID = PrincipalID; + try + { + finfo.PrincipalID = new UUID(PrincipalID); + } + catch + { + return false; + } finfo.Friend = Friend; finfo.MyFlags = flags; diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs new file mode 100644 index 0000000..76f5f19 --- /dev/null +++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs @@ -0,0 +1,175 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.Friends; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors.Hypergrid +{ + public class HGFriendsServicesConnector + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + private string m_ServiceKey = String.Empty; + private UUID m_SessionID; + + public HGFriendsServicesConnector() + { + } + + public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey) + { + m_ServerURI = serverURI.TrimEnd('/'); + m_ServiceKey = serviceKey; + m_SessionID = sessionID; + } + + #region IFriendsService + + public FriendInfo[] GetFriends(UUID PrincipalID) + { + Dictionary sendData = new Dictionary(); + + sendData["PRINCIPALID"] = PrincipalID.ToString(); + sendData["METHOD"] = "getfriends"; + sendData["KEY"] = m_ServiceKey; + sendData["SESSIONID"] = m_SessionID.ToString(); + + string reqString = ServerUtils.BuildQueryString(sendData); + + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/hgfriends", + reqString); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + if (replyData.ContainsKey("result") && (replyData["result"].ToString().ToLower() == "null")) + { + return new FriendInfo[0]; + } + + List finfos = new List(); + Dictionary.ValueCollection finfosList = replyData.Values; + //m_log.DebugFormat("[FRIENDS CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count); + foreach (object f in finfosList) + { + if (f is Dictionary) + { + FriendInfo finfo = new FriendInfo((Dictionary)f); + finfos.Add(finfo); + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received invalid response type {1}", + PrincipalID, f.GetType()); + } + + // Success + return finfos.ToArray(); + } + + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received null response", + PrincipalID); + + } + } + catch (Exception e) + { + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message); + } + + return new FriendInfo[0]; + + } + + public bool NewFriendship(UUID PrincipalID, string Friend) + { + FriendInfo finfo = new FriendInfo(); + finfo.PrincipalID = PrincipalID; + finfo.Friend = Friend; + + Dictionary sendData = finfo.ToKeyValuePairs(); + + sendData["METHOD"] = "newfriendship"; + sendData["KEY"] = m_ServiceKey; + sendData["SESSIONID"] = m_SessionID.ToString(); + + string reply = string.Empty; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/hgfriends", + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message); + return false; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null)) + { + bool success = false; + Boolean.TryParse(replyData["Result"].ToString(), out success); + return success; + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend {0} {1} received null response", + PrincipalID, Friend); + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend received null reply"); + + return false; + + } + + #endregion + } +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs index 6f2d735..f61ab29 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs @@ -127,7 +127,7 @@ namespace OpenSim.Services.Connectors.SimianGrid return array; } - public bool StoreFriend(UUID principalID, string friend, int flags) + public bool StoreFriend(string principalID, string friend, int flags) { if (String.IsNullOrEmpty(m_serverUrl)) return true; diff --git a/OpenSim/Services/Friends/FriendsService.cs b/OpenSim/Services/Friends/FriendsService.cs index 3c64ecc..039dc0b 100644 --- a/OpenSim/Services/Friends/FriendsService.cs +++ b/OpenSim/Services/Friends/FriendsService.cs @@ -43,17 +43,16 @@ namespace OpenSim.Services.Friends { } - public FriendInfo[] GetFriends(UUID PrincipalID) + public virtual FriendInfo[] GetFriends(UUID PrincipalID) { FriendsData[] data = m_Database.GetFriends(PrincipalID); - List info = new List(); foreach (FriendsData d in data) { FriendInfo i = new FriendInfo(); - i.PrincipalID = d.PrincipalID; + i.PrincipalID = new UUID(d.PrincipalID); i.Friend = d.Friend; i.MyFlags = Convert.ToInt32(d.Data["Flags"]); i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]); @@ -64,7 +63,7 @@ namespace OpenSim.Services.Friends return info.ToArray(); } - public bool StoreFriend(UUID PrincipalID, string Friend, int flags) + public virtual bool StoreFriend(string PrincipalID, string Friend, int flags) { FriendsData d = new FriendsData(); @@ -76,7 +75,7 @@ namespace OpenSim.Services.Friends return m_Database.Store(d); } - public bool Delete(UUID PrincipalID, string Friend) + public virtual bool Delete(UUID PrincipalID, string Friend) { return m_Database.Delete(PrincipalID, Friend); } diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs new file mode 100644 index 0000000..fa4ec5d --- /dev/null +++ b/OpenSim/Services/HypergridService/HGFriendsService.cs @@ -0,0 +1,95 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenMetaverse; +using OpenSim.Framework; +using System; +using System.Collections.Generic; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Friends; +using OpenSim.Data; +using Nini.Config; +using log4net; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; + +namespace OpenSim.Services.HypergridService +{ + public class HGFriendsService : FriendsService, IFriendsService + { + public HGFriendsService(IConfigSource config) : base(config) + { + } + + /// + /// Overrides base. + /// Storing new friendships from the outside is a tricky, sensitive operation, and it + /// needs to be done under certain restrictions. + /// First of all, if the friendship already exists, this is a no-op. In other words, + /// we cannot change just the flags, it needs to be a new friendship. + /// Second, we store it as flags=0 always, independent of what the caller sends. The + /// owner of the friendship needs to confirm when it gets back home. + /// + /// + /// + /// + /// + public override bool StoreFriend(string PrincipalID, string Friend, int flags) + { + UUID userID; + if (UUID.TryParse(PrincipalID, out userID)) + { + FriendsData[] friendsData = m_Database.GetFriends(userID); + List fList = new List(friendsData); + if (fList.Find(delegate(FriendsData fdata) + { + return fdata.Friend == Friend; + }) != null) + return false; + } + + FriendsData d = new FriendsData(); + d.PrincipalID = PrincipalID; + d.Friend = Friend; + d.Data = new Dictionary(); + d.Data["Flags"] = "0"; + + return m_Database.Store(d); + } + + /// + /// Overrides base. Cannot delete friendships while away from home. + /// + /// + /// + /// + public override bool Delete(UUID PrincipalID, string Friend) + { + return false; + } + + } +} diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs index 0ddd5e5..05e85f2 100644 --- a/OpenSim/Services/Interfaces/IFriendsService.cs +++ b/OpenSim/Services/Interfaces/IFriendsService.cs @@ -74,7 +74,7 @@ namespace OpenSim.Services.Interfaces public interface IFriendsService { FriendInfo[] GetFriends(UUID PrincipalID); - bool StoreFriend(UUID PrincipalID, string Friend, int flags); + bool StoreFriend(string PrincipalID, string Friend, int flags); bool Delete(UUID PrincipalID, string Friend); } } diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index ddc8855..4fac951 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -621,7 +621,19 @@ namespace OpenSim.Services.LLLoginService if (finfo.TheirFlags == -1) continue; LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend); - buddyitem.BuddyID = finfo.Friend; + // finfo.Friend may not be a simple uuid + UUID friendID = UUID.Zero; + if (UUID.TryParse(finfo.Friend, out friendID)) + buddyitem.BuddyID = finfo.Friend; + else + { + string tmp; + if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp)) + buddyitem.BuddyID = friendID.ToString(); + else + // junk entry + continue; + } buddyitem.BuddyRightsHave = (int)finfo.TheirFlags; buddyitem.BuddyRightsGiven = (int)finfo.MyFlags; buddylistreturn.AddNewBuddy(buddyitem); diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 486f22e..324c258 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -20,6 +20,7 @@ AvatarServices = "LocalAvatarServicesConnector" EntityTransferModule = "HGEntityTransferModule" InventoryAccessModule = "HGInventoryAccessModule" + FriendsModule = "HGFriendsModule" InventoryServiceInConnector = true AssetServiceInConnector = true @@ -140,6 +141,10 @@ LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGAssetService" UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" +[HGFriendsService] + LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGFriendsService" + UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" + ;; This should always be the very last thing on this file [Includes] Include-Common = "config-include/StandaloneCommon.ini" diff --git a/prebuild.xml b/prebuild.xml index a07ad14..1f620dc 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1256,6 +1256,7 @@ + -- cgit v1.1 From 58c53c41de2cae0bb041a2e8121792e136d1edb2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 21 May 2011 16:48:00 -0700 Subject: Fixed permissions bug related to friends in PermissionsModule. Added FriendsData[] GetFriends(string principalID) to IFriendsData and FriendInfo[] GetFriends(string PrincipalID) to IFriendsService. Refactored some more in the FriendsModule. Made client get notification of local friends permissions upon HGLogin. HG Friends object permissions work. --- OpenSim/Data/IFriendsData.cs | 1 + OpenSim/Data/MSSQL/MSSQLFriendsData.cs | 6 + OpenSim/Data/MySQL/MySQLFriendsData.cs | 5 + OpenSim/Data/Null/NullFriendsData.cs | 7 +- OpenSim/Data/SQLite/SQLiteFriendsData.cs | 7 +- .../CoreModules/Avatar/Friends/FriendsModule.cs | 103 +++++--- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 259 +++++++-------------- .../World/Permissions/PermissionsModule.cs | 41 ++-- .../Region/Framework/Interfaces/IFriendsModule.cs | 2 +- .../Handlers/Friends/FriendsServerPostHandler.cs | 23 +- .../Hypergrid/HGFriendsServerPostHandler.cs | 112 ++++++--- .../Connectors/Friends/FriendsServiceConnector.cs | 17 +- .../Hypergrid/HGFriendsServiceConnector.cs | 37 +-- .../SimianGrid/SimianFriendsServiceConnector.cs | 18 +- OpenSim/Services/Friends/FriendsService.cs | 26 +++ .../Services/HypergridService/HGFriendsService.cs | 4 +- OpenSim/Services/Interfaces/IFriendsService.cs | 1 + 17 files changed, 372 insertions(+), 297 deletions(-) diff --git a/OpenSim/Data/IFriendsData.cs b/OpenSim/Data/IFriendsData.cs index 4da567e..52e7f14 100644 --- a/OpenSim/Data/IFriendsData.cs +++ b/OpenSim/Data/IFriendsData.cs @@ -47,5 +47,6 @@ namespace OpenSim.Data bool Store(FriendsData data); bool Delete(UUID ownerID, string friend); FriendsData[] GetFriends(UUID principalID); + FriendsData[] GetFriends(string principalID); } } diff --git a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs index af4fd9b..ba1b085 100644 --- a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs +++ b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs @@ -68,6 +68,11 @@ namespace OpenSim.Data.MSSQL public FriendsData[] GetFriends(UUID principalID) { + return GetFriends(principalID.ToString()); + } + + public FriendsData[] GetFriends(string principalID) + { using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand()) { @@ -79,5 +84,6 @@ namespace OpenSim.Data.MSSQL return DoQuery(cmd); } } + } } diff --git a/OpenSim/Data/MySQL/MySQLFriendsData.cs b/OpenSim/Data/MySQL/MySQLFriendsData.cs index 663fad6..69fac9d 100644 --- a/OpenSim/Data/MySQL/MySQLFriendsData.cs +++ b/OpenSim/Data/MySQL/MySQLFriendsData.cs @@ -57,6 +57,11 @@ namespace OpenSim.Data.MySQL public FriendsData[] GetFriends(UUID principalID) { + return GetFriends(principalID.ToString()); + } + + public FriendsData[] GetFriends(string principalID) + { MySqlCommand cmd = new MySqlCommand(); cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm); diff --git a/OpenSim/Data/Null/NullFriendsData.cs b/OpenSim/Data/Null/NullFriendsData.cs index 0c69bb1..2bfdc7a 100644 --- a/OpenSim/Data/Null/NullFriendsData.cs +++ b/OpenSim/Data/Null/NullFriendsData.cs @@ -42,6 +42,11 @@ namespace OpenSim.Data.Null { } + public FriendsData[] GetFriends(UUID principalID) + { + return GetFriends(principalID.ToString()); + } + /// /// Tries to implement the Get [] semantics, but it cuts corners. /// Specifically, it gets all friendships even if they weren't accepted yet. @@ -49,7 +54,7 @@ namespace OpenSim.Data.Null /// /// /// - public FriendsData[] GetFriends(UUID userID) + public FriendsData[] GetFriends(string userID) { List lst = m_Data.FindAll(delegate (FriendsData fdata) { diff --git a/OpenSim/Data/SQLite/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs index 4bfd228..d925412 100644 --- a/OpenSim/Data/SQLite/SQLiteFriendsData.cs +++ b/OpenSim/Data/SQLite/SQLiteFriendsData.cs @@ -46,7 +46,12 @@ namespace OpenSim.Data.SQLite { } - public FriendsData[] GetFriends(UUID userID) + public FriendsData[] GetFriends(UUID principalID) + { + return GetFriends(principalID.ToString()); + } + + public FriendsData[] GetFriends(string userID) { SqliteCommand cmd = new SqliteCommand(); diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 21cd924..4879d20 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; + protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected List m_Scenes = new List(); @@ -187,6 +187,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { if (!m_Enabled) return; + m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); m_Scenes.Add(scene); scene.RegisterModuleInterface(this); @@ -221,13 +222,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends #endregion - public uint GetFriendPerms(UUID principalID, UUID friendID) + public virtual uint GetFriendPerms(UUID principalID, UUID friendID) { FriendInfo[] friends = GetFriends(principalID); - foreach (FriendInfo fi in friends) + FriendInfo finfo = GetFriend(friends, friendID); + if (finfo != null) { - if (fi.Friend == friendID.ToString()) - return (uint)fi.TheirFlags; + return (uint)finfo.TheirFlags; } return 0; @@ -241,14 +242,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends client.OnTerminateFriendship += OnTerminateFriendship; client.OnGrantUserRights += OnGrantUserRights; - Util.FireAndForget(delegate { FetchFriendslist(client.AgentId); }); + Util.FireAndForget(delegate { FetchFriendslist(client); }); } /// Fetch the friends list or increment the refcount for the existing /// friends list /// Returns true if the list was fetched, false if it wasn't - protected virtual bool FetchFriendslist(UUID agentID) + protected virtual bool FetchFriendslist(IClientAPI client) { + UUID agentID = client.AgentId; lock (m_Friends) { UserFriendData friendsData; @@ -261,7 +263,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { friendsData = new UserFriendData(); friendsData.PrincipalID = agentID; - friendsData.Friends = FriendsService.GetFriends(agentID); + friendsData.Friends = GetFriendsFromService(client); friendsData.Refcount = 1; m_Friends[agentID] = friendsData; @@ -270,6 +272,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } + protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client) + { + return FriendsService.GetFriends(client.AgentId); + } + private void OnClientClosed(UUID agentID, Scene scene) { ScenePresence sp = scene.GetScenePresence(agentID); @@ -293,8 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private void OnMakeRootAgent(ScenePresence sp) { - UUID agentID = sp.ControllingClient.AgentId; - UpdateFriendsCache(agentID); + UpdateFriendsCache(sp.ControllingClient); } private void OnClientLogin(IClientAPI client) @@ -309,7 +315,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends m_NeedsListOfFriends.Add(agentID); } - public void SendFriendsOnlineIfNeeded(IClientAPI client) + public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client) { UUID agentID = client.AgentId; @@ -317,7 +323,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends lock (m_NeedsListOfFriends) { if (!m_NeedsListOfFriends.Remove(agentID)) - return; + return false; } // Send the friends online @@ -366,6 +372,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // Finally LocalFriendshipOffered(agentID, im); } + + return true; } protected virtual string FriendshipMessage(string friendID) @@ -579,7 +587,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends StoreFriendships(agentID, friendID); // Update the local cache - UpdateFriendsCache(agentID); + UpdateFriendsCache(client); // // Notify the friend @@ -647,7 +655,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends DeleteFriendship(agentID, exfriendID); // Update local cache - UpdateFriendsCache(agentID); + UpdateFriendsCache(client); client.SendTerminateFriend(exfriendID); @@ -679,23 +687,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) { + m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); + FriendInfo[] friends = GetFriends(remoteClient.AgentId); if (friends.Length == 0) + { + m_log.DebugFormat("[XXX]: agent {0} has no friends", requester); return; + } - m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); // Let's find the friend in this user's friend list - FriendInfo friend = null; - foreach (FriendInfo fi in friends) - { - if (fi.Friend == target.ToString()) - friend = fi; - } + FriendInfo friend = GetFriend(friends, target); if (friend != null) // Found it { // Store it on the DB - FriendsService.StoreFriend(requester.ToString(), target.ToString(), rights); + if (!SimpleStore(requester, target, rights)) + { + remoteClient.SendAlertMessage("Unable to grant rights."); + return; + } // Store it in the local cache int myFlags = friend.MyFlags; @@ -725,6 +736,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } } + else + m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester); + } + + protected virtual bool SimpleStore(UUID agentID, UUID friendID, int rights) + { + FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights); + return true; + } + + protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) + { + foreach (FriendInfo fi in friends) + { + if (fi.Friend == friendID.ToString()) + return fi; + } + return null; } #region Local @@ -753,7 +782,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends friendClient.SendInstantMessage(im); // Update the local cache - UpdateFriendsCache(friendID); + UpdateFriendsCache(friendClient); // we're done return true; @@ -786,7 +815,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // the friend in this sim as root agent friendClient.SendTerminateFriend(exfriendID); // update local cache - UpdateFriendsCache(exfriendID); + UpdateFriendsCache(friendClient); // we're done return true; } @@ -816,15 +845,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } // Update local cache - lock (m_Friends) - { - FriendInfo[] friends = GetFriends(friendID); - foreach (FriendInfo finfo in friends) - { - if (finfo.Friend == userID.ToString()) - finfo.TheirFlags = rights; - } - } + UpdateLocalCache(userID, friendID, rights); return true; } @@ -866,13 +887,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return EMPTY_FRIENDS; } - private void UpdateFriendsCache(UUID agentID) + private void UpdateFriendsCache(IClientAPI client) { + UUID agentID = client.AgentId; lock (m_Friends) { UserFriendData friendsData; if (m_Friends.TryGetValue(agentID, out friendsData)) - friendsData.Friends = FriendsService.GetFriends(agentID); + friendsData.Friends = GetFriendsFromService(client); + } + } + + protected void UpdateLocalCache(UUID userID, UUID friendID, int rights) + { + // Update local cache + lock (m_Friends) + { + FriendInfo[] friends = GetFriends(friendID); + FriendInfo finfo = GetFriend(friends, userID); + finfo.TheirFlags = rights; } } } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 645ecdc..abffb94 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -58,129 +58,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends #endregion - //public void SendFriendsOnlineIfNeeded(IClientAPI client) - //{ - // UUID agentID = client.AgentId; - - // // Check if the online friends list is needed - // lock (m_NeedsListOfFriends) - // { - // if (!m_NeedsListOfFriends.Remove(agentID)) - // return; - // } - - // // Send the friends online - // List online = GetOnlineFriends(agentID); - // if (online.Count > 0) - // { - // m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count); - // client.SendAgentOnline(online.ToArray()); - // } - - // // Send outstanding friendship offers - // List outstanding = new List(); - // FriendInfo[] friends = GetFriends(agentID); - // foreach (FriendInfo fi in friends) - // { - // if (fi.TheirFlags == -1) - // outstanding.Add(fi.Friend); - // } - - // GridInstantMessage im = new GridInstantMessage(client.Scene, UUID.Zero, String.Empty, agentID, (byte)InstantMessageDialog.FriendshipOffered, - // "Will you be my friend?", true, Vector3.Zero); - - // foreach (string fid in outstanding) - // { - // UUID fromAgentID; - // if (!UUID.TryParse(fid, out fromAgentID)) - // continue; - - // UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID); - - // PresenceInfo presence = null; - // PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); - // if (presences != null && presences.Length > 0) - // presence = presences[0]; - // if (presence != null) - // im.offline = 0; - - // im.fromAgentID = fromAgentID.Guid; - // im.fromAgentName = account.FirstName + " " + account.LastName; - // im.offline = (byte)((presence == null) ? 1 : 0); - // im.imSessionID = im.fromAgentID; - - // // Finally - // LocalFriendshipOffered(agentID, im); - // } - //} - - //List GetOnlineFriends(UUID userID) - //{ - // List friendList = new List(); - // List online = new List(); - - // FriendInfo[] friends = GetFriends(userID); - // foreach (FriendInfo fi in friends) - // { - // if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1)) - // friendList.Add(fi.Friend); - // } - - // if (friendList.Count > 0) - // { - // PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); - // foreach (PresenceInfo pi in presence) - // { - // UUID presenceID; - // if (UUID.TryParse(pi.UserID, out presenceID)) - // online.Add(presenceID); - // } - // } - - // return online; - //} - - //private void StatusNotify(FriendInfo friend, UUID userID, bool online) - //{ - // UUID friendID; - // if (UUID.TryParse(friend.Friend, out friendID)) - // { - // // Try local - // if (LocalStatusNotification(userID, friendID, online)) - // return; - - // // The friend is not here [as root]. Let's forward. - // PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); - // if (friendSessions != null && friendSessions.Length > 0) - // { - // PresenceInfo friendSession = null; - // foreach (PresenceInfo pinfo in friendSessions) - // if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad - // { - // friendSession = pinfo; - // break; - // } - - // if (friendSession != null) - // { - // GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - // //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); - // m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); - // } - // } - - // // Friend is not online. Ignore. - // } - // else - // { - // m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); - // } - //} - - protected override bool FetchFriendslist(UUID agentID) + protected override bool FetchFriendslist(IClientAPI client) { - if (base.FetchFriendslist(agentID)) + if (base.FetchFriendslist(client)) { + UUID agentID = client.AgentId; // We need to preload the user management cache with the names // of foreign friends, just like we do with SOPs' creators foreach (FriendInfo finfo in m_Friends[agentID].Friends) @@ -204,6 +86,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return false; } + public override bool SendFriendsOnlineIfNeeded(IClientAPI client) + { + if (base.SendFriendsOnlineIfNeeded(client)) + { + UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId); + if (account == null) // foreign + { + FriendInfo[] friends = GetFriends(client.AgentId); + foreach (FriendInfo f in friends) + { + client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags); + } + } + } + return false; + } + + protected override FriendInfo[] GetFriendsFromService(IClientAPI client) + { + UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId); + if (account1 != null) + return base.GetFriendsFromService(client); + + // Foreigner + AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); + string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); + + FriendInfo[] finfos = FriendsService.GetFriends(agentUUI); + m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); + return finfos; + } + + protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) { first = "Unknown"; last = "User"; @@ -249,6 +164,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return "Please confirm this friendship you made while you were away."; } + protected override bool SimpleStore(UUID agentID, UUID friendID, int rights) + { + UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); + UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); + // Are they both local users? + if (account1 != null && account2 != null) + { + // local grid users + return base.SimpleStore(agentID, friendID, rights); + } + + if (account1 != null) + { + FriendInfo[] finfos = GetFriends(agentID); + if (finfos.Length > 0) + { + FriendInfo finfo = GetFriend(finfos, friendID); + FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights); + return true; + } + } + if (account2 != null) + { + IClientAPI client = LocateClientObject(agentID); + if (client != null) + { + AgentCircuitData acircuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); + if (acircuit != null) + { + FriendsService.StoreFriend(Util.ProduceUserUniversalIdentifier(acircuit), friendID.ToString(), rights); + return true; + } + } + } + + return false; + + } + protected override void StoreBackwards(UUID friendID, UUID agentID) { UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); @@ -366,6 +320,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // my brain hurts now } + protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) + { + foreach (FriendInfo fi in friends) + { + if (fi.Friend.StartsWith(friendID.ToString())) + return fi; + } + return null; + } + protected override void DeleteFriendship(UUID agentID, UUID exfriendID) { base.DeleteFriendship(agentID, exfriendID); @@ -374,7 +338,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends FriendInfo[] friends = GetFriends(agentID); foreach (FriendInfo finfo in friends) { - if (finfo.Friend != exfriendID.ToString() && finfo.Friend.EndsWith(exfriendID.ToString())) + if (finfo.Friend != exfriendID.ToString() && finfo.Friend.StartsWith(exfriendID.ToString())) { FriendsService.Delete(agentID, exfriendID.ToString()); // TODO: delete the friendship on the other side @@ -383,56 +347,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - //private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) - //{ - // FriendInfo[] friends = GetFriends(remoteClient.AgentId); - // if (friends.Length == 0) - // return; - - // m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); - // // Let's find the friend in this user's friend list - // FriendInfo friend = null; - // foreach (FriendInfo fi in friends) - // { - // if (fi.Friend == target.ToString()) - // friend = fi; - // } - - // if (friend != null) // Found it - // { - // // Store it on the DB - // FriendsService.StoreFriend(requester, target.ToString(), rights); - - // // Store it in the local cache - // int myFlags = friend.MyFlags; - // friend.MyFlags = rights; - - // // Always send this back to the original client - // remoteClient.SendChangeUserRights(requester, target, rights); - - // // - // // Notify the friend - // // - - // // Try local - // if (LocalGrantRights(requester, target, myFlags, rights)) - // return; - - // PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() }); - // if (friendSessions != null && friendSessions.Length > 0) - // { - // PresenceInfo friendSession = friendSessions[0]; - // if (friendSession != null) - // { - // GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - // // TODO: You might want to send the delta to save the lookup - // // on the other end!! - // m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights); - // } - // } - // } - //} - - } } diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 170c35f..d7324c6 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 // libomv will moan about PrimFlags.ObjectYouOfficer being // deprecated - #pragma warning disable 0612 +#pragma warning disable 0612 objflags &= (uint) ~(PrimFlags.ObjectCopy | // Tells client you can copy the object - PrimFlags.ObjectModify | // tells client you can modify the object - PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) - PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it - PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object - PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object - PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object - PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set + PrimFlags.ObjectModify | // tells client you can modify the object + PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) + PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it + PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object + PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object + PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object + PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set ); - #pragma warning restore 0612 +#pragma warning restore 0612 // Creating the three ObjectFlags options for this method to choose from. // Customize the OwnerMask @@ -576,22 +576,27 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (m_bypassPermissions) return objectOwnerMask; - + // Object owners should be able to edit their own content if (user == objectOwner) return objectOwnerMask; - + if (IsFriendWithPerms(user, objectOwner)) + { return objectOwnerMask; - + } // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) + { return objectOwnerMask; + } // Admin should be able to edit anything in the sim (including admin objects) if (IsAdministrator(user)) + { return objectOwnerMask; - + } + // Users should be able to edit what is over their land. Vector3 taskPos = task.AbsolutePosition; ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); @@ -599,13 +604,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions { // Admin objects should not be editable by the above if (!IsAdministrator(objectOwner)) + { return objectOwnerMask; + } } // Group permissions if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) return objectGroupMask | objectEveryoneMask; - + return objectEveryoneMask; } @@ -673,7 +680,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions // // Nobody but the object owner can set permissions on an object // - if (locked && (!IsAdministrator(currentUser)) && denyOnLocked) { return false; @@ -704,6 +710,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions // Return immediately, so that the administrator can shares group objects return true; } + + // Friends with benefits should be able to edit the objects too + if (IsFriendWithPerms(currentUser, objectOwner)) + // Return immediately, so that the administrator can share objects with friends + return true; // Users should be able to edit what is over their land. ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y); 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 public interface IFriendsModule { uint GetFriendPerms(UUID PrincipalID, UUID FriendID); - void SendFriendsOnlineIfNeeded(IClientAPI client); + bool SendFriendsOnlineIfNeeded(IClientAPI client); } } diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs index 64002e1..71c3c73 100644 --- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs @@ -82,6 +82,9 @@ namespace OpenSim.Server.Handlers.Friends case "getfriends": return GetFriends(request); + case "getfriends_string": + return GetFriendsString(request); + case "storefriend": return StoreFriend(request); @@ -111,7 +114,25 @@ namespace OpenSim.Server.Handlers.Friends m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends"); FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); - //m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count); + + return PackageFriends(finfos); + } + + byte[] GetFriendsString(Dictionary request) + { + string principalID = string.Empty; + if (request.ContainsKey("PRINCIPALID")) + principalID = request["PRINCIPALID"].ToString(); + else + m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends"); + + FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); + + return PackageFriends(finfos); + } + + private byte[] PackageFriends(FriendInfo[] finfos) + { Dictionary result = new Dictionary(); if ((finfos == null) || ((finfos != null) && (finfos.Length == 0))) diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs index 13d1502..dde7875 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs @@ -82,8 +82,8 @@ namespace OpenSim.Server.Handlers.Hypergrid switch (method) { - case "getfriends": - return GetFriends(request); + case "getfriendperms": + return GetFriendPerms(request); case "newfriendship": return NewFriendship(request); @@ -102,58 +102,45 @@ namespace OpenSim.Server.Handlers.Hypergrid #region Method-specific handlers - byte[] GetFriends(Dictionary request) + byte[] GetFriendPerms(Dictionary request) { + if (!VerifyServiceKey(request)) + return FailureResult(); + UUID principalID = UUID.Zero; if (request.ContainsKey("PRINCIPALID")) UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID); else - m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friends"); - - FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); - //m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count); + { + m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friend perms"); + return FailureResult(); + } - Dictionary result = new Dictionary(); - if ((finfos == null) || ((finfos != null) && (finfos.Length == 0))) - result["result"] = "null"; + UUID friendID = UUID.Zero; + if (request.ContainsKey("FRIENDID")) + UUID.TryParse(request["FRIENDID"].ToString(), out friendID); else { - int i = 0; - foreach (FriendInfo finfo in finfos) - { - Dictionary rinfoDict = finfo.ToKeyValuePairs(); - result["friend" + i] = rinfoDict; - i++; - } + m_log.WarnFormat("[HGFRIENDS HANDLER]: no friendID in request to get friend perms"); + return FailureResult(); } - string xmlString = ServerUtils.BuildXmlResponse(result); - //m_log.DebugFormat("[FRIENDS HANDLER]: resp string: {0}", xmlString); - UTF8Encoding encoding = new UTF8Encoding(); - return encoding.GetBytes(xmlString); + string perms = "0"; + FriendInfo[] friendsInfo = m_FriendsService.GetFriends(principalID); + foreach (FriendInfo finfo in friendsInfo) + { + if (finfo.Friend.StartsWith(friendID.ToString())) + return SuccessResult(finfo.TheirFlags.ToString()); + } + return FailureResult("Friend not found"); } byte[] NewFriendship(Dictionary request) { - if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID")) - { - m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID"); - return FailureResult(); - } - - string serviceKey = request["KEY"].ToString(); - string sessionStr = request["SESSIONID"].ToString(); - UUID sessionID; - UUID.TryParse(sessionStr, out sessionID); - - if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey)) - { - m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID); + if (!VerifyServiceKey(request)) return FailureResult(); - } - m_log.DebugFormat("[XXX] Verification ok"); // OK, can proceed FriendInfo friend = new FriendInfo(request); @@ -172,6 +159,29 @@ namespace OpenSim.Server.Handlers.Hypergrid #region Misc + private bool VerifyServiceKey(Dictionary request) + { + if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID")) + { + m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID"); + return false; + } + + string serviceKey = request["KEY"].ToString(); + string sessionStr = request["SESSIONID"].ToString(); + UUID sessionID; + UUID.TryParse(sessionStr, out sessionID); + + if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey)) + { + m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID); + return false; + } + + m_log.DebugFormat("[XXX] Verification ok"); + return true; + } + private byte[] SuccessResult() { XmlDocument doc = new XmlDocument(); @@ -194,6 +204,34 @@ namespace OpenSim.Server.Handlers.Hypergrid return DocToBytes(doc); } + private byte[] SuccessResult(string value) + { + XmlDocument doc = new XmlDocument(); + + XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, + "", ""); + + doc.AppendChild(xmlnode); + + XmlElement rootElement = doc.CreateElement("", "ServerResponse", + ""); + + doc.AppendChild(rootElement); + + XmlElement result = doc.CreateElement("", "Result", ""); + result.AppendChild(doc.CreateTextNode("Success")); + + rootElement.AppendChild(result); + + XmlElement message = doc.CreateElement("", "Value", ""); + message.AppendChild(doc.CreateTextNode(value)); + + rootElement.AppendChild(message); + + return DocToBytes(doc); + } + + private byte[] FailureResult() { return FailureResult(String.Empty); diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs index 52b80e1..d1afea2 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs @@ -84,7 +84,7 @@ namespace OpenSim.Services.Connectors.Friends #region IFriendsService - + public FriendInfo[] GetFriends(UUID PrincipalID) { Dictionary sendData = new Dictionary(); @@ -92,6 +92,21 @@ namespace OpenSim.Services.Connectors.Friends sendData["PRINCIPALID"] = PrincipalID.ToString(); sendData["METHOD"] = "getfriends"; + return GetFriends(sendData, PrincipalID.ToString()); + } + + public FriendInfo[] GetFriends(string PrincipalID) + { + Dictionary sendData = new Dictionary(); + + sendData["PRINCIPALID"] = PrincipalID; + sendData["METHOD"] = "getfriends_string"; + + return GetFriends(sendData, PrincipalID); + } + + protected FriendInfo[] GetFriends(Dictionary sendData, string PrincipalID) + { string reqString = ServerUtils.BuildQueryString(sendData); try diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs index 76f5f19..f823889 100644 --- a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs @@ -63,12 +63,13 @@ namespace OpenSim.Services.Connectors.Hypergrid #region IFriendsService - public FriendInfo[] GetFriends(UUID PrincipalID) + public uint GetFriendPerms(UUID PrincipalID, UUID friendID) { Dictionary sendData = new Dictionary(); sendData["PRINCIPALID"] = PrincipalID.ToString(); - sendData["METHOD"] = "getfriends"; + sendData["FRIENDID"] = friendID.ToString(); + sendData["METHOD"] = "getfriendperms"; sendData["KEY"] = m_ServiceKey; sendData["SESSIONID"] = m_SessionID.ToString(); @@ -83,34 +84,14 @@ namespace OpenSim.Services.Connectors.Hypergrid { Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - if (replyData != null) + if ((replyData != null) && replyData.ContainsKey("Value") && (replyData["Value"] != null)) { - if (replyData.ContainsKey("result") && (replyData["result"].ToString().ToLower() == "null")) - { - return new FriendInfo[0]; - } - - List finfos = new List(); - Dictionary.ValueCollection finfosList = replyData.Values; - //m_log.DebugFormat("[FRIENDS CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count); - foreach (object f in finfosList) - { - if (f is Dictionary) - { - FriendInfo finfo = new FriendInfo((Dictionary)f); - finfos.Add(finfo); - } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received invalid response type {1}", - PrincipalID, f.GetType()); - } - - // Success - return finfos.ToArray(); + uint perms = 0; + uint.TryParse(replyData["Value"].ToString(), out perms); + return perms; } - else - m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received null response", + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriendPerms {0} received null response", PrincipalID); } @@ -120,7 +101,7 @@ namespace OpenSim.Services.Connectors.Hypergrid m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message); } - return new FriendInfo[0]; + return 0; } diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs index f61ab29..b1c34dd 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs @@ -78,6 +78,11 @@ namespace OpenSim.Services.Connectors.SimianGrid public FriendInfo[] GetFriends(UUID principalID) { + return GetFriends(principalID.ToString()); + } + + public FriendInfo[] GetFriends(string principalID) + { if (String.IsNullOrEmpty(m_serverUrl)) return new FriendInfo[0]; @@ -95,7 +100,14 @@ namespace OpenSim.Services.Connectors.SimianGrid UUID friendID = friendEntry["Key"].AsUUID(); FriendInfo friend = new FriendInfo(); - friend.PrincipalID = principalID; + if (!UUID.TryParse(principalID, out friend.PrincipalID)) + { + string tmp = string.Empty; + if (!Util.ParseUniversalUserIdentifier(principalID, out friend.PrincipalID, out tmp, out tmp, out tmp)) + // bad record. ignore this entry + continue; + } + friend.Friend = friendID.ToString(); friend.MyFlags = friendEntry["Value"].AsInteger(); friend.TheirFlags = -1; @@ -174,7 +186,7 @@ namespace OpenSim.Services.Connectors.SimianGrid #endregion IFriendsService - private OSDArray GetFriended(UUID ownerID) + private OSDArray GetFriended(string ownerID) { NameValueCollection requestArgs = new NameValueCollection { @@ -195,7 +207,7 @@ namespace OpenSim.Services.Connectors.SimianGrid } } - private OSDArray GetFriendedBy(UUID ownerID) + private OSDArray GetFriendedBy(string ownerID) { NameValueCollection requestArgs = new NameValueCollection { diff --git a/OpenSim/Services/Friends/FriendsService.cs b/OpenSim/Services/Friends/FriendsService.cs index 039dc0b..4664cb3 100644 --- a/OpenSim/Services/Friends/FriendsService.cs +++ b/OpenSim/Services/Friends/FriendsService.cs @@ -63,6 +63,32 @@ namespace OpenSim.Services.Friends return info.ToArray(); } + public virtual FriendInfo[] GetFriends(string PrincipalID) + { + FriendsData[] data = m_Database.GetFriends(PrincipalID); + List info = new List(); + + foreach (FriendsData d in data) + { + FriendInfo i = new FriendInfo(); + + if (!UUID.TryParse(d.PrincipalID, out i.PrincipalID)) + { + string tmp = string.Empty; + if (!Util.ParseUniversalUserIdentifier(d.PrincipalID, out i.PrincipalID, out tmp, out tmp, out tmp)) + // bad record. ignore this entry + continue; + } + i.Friend = d.Friend; + i.MyFlags = Convert.ToInt32(d.Data["Flags"]); + i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]); + + info.Add(i); + } + + return info.ToArray(); + } + public virtual bool StoreFriend(string PrincipalID, string Friend, int flags) { FriendsData d = new FriendsData(); diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs index fa4ec5d..3ffe889 100644 --- a/OpenSim/Services/HypergridService/HGFriendsService.cs +++ b/OpenSim/Services/HypergridService/HGFriendsService.cs @@ -62,7 +62,7 @@ namespace OpenSim.Services.HypergridService UUID userID; if (UUID.TryParse(PrincipalID, out userID)) { - FriendsData[] friendsData = m_Database.GetFriends(userID); + FriendsData[] friendsData = m_Database.GetFriends(userID.ToString()); List fList = new List(friendsData); if (fList.Find(delegate(FriendsData fdata) { @@ -70,6 +70,8 @@ namespace OpenSim.Services.HypergridService }) != null) return false; } + else + return false; FriendsData d = new FriendsData(); d.PrincipalID = PrincipalID; diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs index 05e85f2..0a8efad 100644 --- a/OpenSim/Services/Interfaces/IFriendsService.cs +++ b/OpenSim/Services/Interfaces/IFriendsService.cs @@ -74,6 +74,7 @@ namespace OpenSim.Services.Interfaces public interface IFriendsService { FriendInfo[] GetFriends(UUID PrincipalID); + FriendInfo[] GetFriends(string PrincipalID); bool StoreFriend(string PrincipalID, string Friend, int flags); bool Delete(UUID PrincipalID, string Friend); } -- cgit v1.1 From fed3cc630efd223866ab03b904dc1053c2d28fe2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 22 May 2011 15:35:40 -0700 Subject: File to be removed --- OpenSim/Services/HypergridService/HGFriendsService.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs index 3ffe889..1829ae3 100644 --- a/OpenSim/Services/HypergridService/HGFriendsService.cs +++ b/OpenSim/Services/HypergridService/HGFriendsService.cs @@ -82,16 +82,5 @@ namespace OpenSim.Services.HypergridService return m_Database.Store(d); } - /// - /// Overrides base. Cannot delete friendships while away from home. - /// - /// - /// - /// - public override bool Delete(UUID PrincipalID, string Friend) - { - return false; - } - } } -- cgit v1.1 From 336665e03532cf9d7a1ad65d5071e7050bf6ecd0 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 22 May 2011 16:51:03 -0700 Subject: More on HG Friends. Added Delete(string, string) across the board. Added security to friendship identifiers so that they can safely be deleted across worlds. Had to change Get(string) to use LIKE because the secret in the identifier is not always known -- affects only HG visitors. BOTTOM LINE SO FAR: HG friendships established and deleted safely across grids, local rights working but not (yet?) being transmitted back. --- OpenSim/Data/IFriendsData.cs | 1 + OpenSim/Data/MSSQL/MSSQLFriendsData.cs | 5 + OpenSim/Data/MySQL/MySQLFriendsData.cs | 17 +- OpenSim/Data/Null/NullFriendsData.cs | 7 +- OpenSim/Data/SQLite/SQLiteFriendsData.cs | 5 + OpenSim/Framework/Util.cs | 6 +- .../CoreModules/Avatar/Friends/FriendsModule.cs | 107 ++++++----- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 212 +++++++++++++++------ .../Handlers/Friends/FriendsServerPostHandler.cs | 23 ++- .../Hypergrid/HGFriendsServerPostHandler.cs | 43 ++++- .../Connectors/Friends/FriendsServiceConnector.cs | 15 ++ .../Hypergrid/HGFriendsServiceConnector.cs | 50 +++++ .../SimianGrid/SimianFriendsServiceConnector.cs | 7 +- OpenSim/Services/Friends/FriendsService.cs | 7 +- .../Services/HypergridService/HGFriendsService.cs | 86 --------- OpenSim/Services/Interfaces/IFriendsService.cs | 1 + OpenSim/Services/LLLoginService/LLLoginResponse.cs | 2 +- bin/config-include/StandaloneHypergrid.ini | 2 +- 18 files changed, 389 insertions(+), 207 deletions(-) delete mode 100644 OpenSim/Services/HypergridService/HGFriendsService.cs diff --git a/OpenSim/Data/IFriendsData.cs b/OpenSim/Data/IFriendsData.cs index 52e7f14..3fdf87b 100644 --- a/OpenSim/Data/IFriendsData.cs +++ b/OpenSim/Data/IFriendsData.cs @@ -46,6 +46,7 @@ namespace OpenSim.Data { bool Store(FriendsData data); bool Delete(UUID ownerID, string friend); + bool Delete(string ownerID, string friend); FriendsData[] GetFriends(UUID principalID); FriendsData[] GetFriends(string principalID); } diff --git a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs index ba1b085..0b178f1 100644 --- a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs +++ b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs @@ -52,6 +52,11 @@ namespace OpenSim.Data.MSSQL public bool Delete(UUID principalID, string friend) { + return Delete(principalID.ToString(), friend); + } + + public bool Delete(string principalID, string friend) + { using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand()) { diff --git a/OpenSim/Data/MySQL/MySQLFriendsData.cs b/OpenSim/Data/MySQL/MySQLFriendsData.cs index 69fac9d..130ba5e 100644 --- a/OpenSim/Data/MySQL/MySQLFriendsData.cs +++ b/OpenSim/Data/MySQL/MySQLFriendsData.cs @@ -44,6 +44,11 @@ namespace OpenSim.Data.MySQL public bool Delete(UUID principalID, string friend) { + return Delete(principalID.ToString(), friend); + } + + public bool Delete(string principalID, string friend) + { MySqlCommand cmd = new MySqlCommand(); cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm); @@ -57,16 +62,20 @@ namespace OpenSim.Data.MySQL public FriendsData[] GetFriends(UUID principalID) { - return GetFriends(principalID.ToString()); + MySqlCommand cmd = new MySqlCommand(); + + cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm); + cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); + + return DoQuery(cmd); } public FriendsData[] GetFriends(string principalID) { MySqlCommand cmd = new MySqlCommand(); - cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm); - cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); - + cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm); + cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%'); return DoQuery(cmd); } } diff --git a/OpenSim/Data/Null/NullFriendsData.cs b/OpenSim/Data/Null/NullFriendsData.cs index 2bfdc7a..d90788a 100644 --- a/OpenSim/Data/Null/NullFriendsData.cs +++ b/OpenSim/Data/Null/NullFriendsData.cs @@ -77,7 +77,12 @@ namespace OpenSim.Data.Null return true; } - public bool Delete(UUID userID, string friendID) + public bool Delete(UUID principalID, string friend) + { + return Delete(principalID.ToString(), friend); + } + + public bool Delete(string userID, string friendID) { List lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); }); if (lst != null) diff --git a/OpenSim/Data/SQLite/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs index d925412..b14c348 100644 --- a/OpenSim/Data/SQLite/SQLiteFriendsData.cs +++ b/OpenSim/Data/SQLite/SQLiteFriendsData.cs @@ -64,6 +64,11 @@ namespace OpenSim.Data.SQLite public bool Delete(UUID principalID, string friend) { + return Delete(principalID.ToString(), friend); + } + + public bool Delete(string principalID, string friend) + { SqliteCommand cmd = new SqliteCommand(); cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm); diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index af21cb5..e5ff27a 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1703,9 +1703,9 @@ namespace OpenSim.Framework /// /// /// - public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname) + public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) { - uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; + uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; string[] parts = value.Split(';'); if (parts.Length >= 1) @@ -1724,6 +1724,8 @@ namespace OpenSim.Framework lastname = name[1]; } } + if (parts.Length >= 4) + secret = parts[3]; return true; } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 4879d20..7d94813 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -272,11 +272,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client) - { - return FriendsService.GetFriends(client.AgentId); - } - private void OnClientClosed(UUID agentID, Scene scene) { ScenePresence sp = scene.GetScenePresence(agentID); @@ -300,7 +295,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private void OnMakeRootAgent(ScenePresence sp) { - UpdateFriendsCache(sp.ControllingClient); + RefetchFriends(sp.ControllingClient); } private void OnClientLogin(IClientAPI client) @@ -544,11 +539,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - protected virtual void StoreBackwards(UUID friendID, UUID agentID) - { - FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0); - } - private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) { // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) @@ -587,7 +577,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends StoreFriendships(agentID, friendID); // Update the local cache - UpdateFriendsCache(client); + RefetchFriends(client); // // Notify the friend @@ -614,18 +604,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - protected virtual void StoreFriendships(UUID agentID, UUID friendID) - { - FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1); - FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1); - } - private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List callingCardFolders) { m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); - FriendsService.Delete(agentID, friendID.ToString()); - FriendsService.Delete(friendID, agentID.ToString()); + DeleteFriendship(agentID, friendID); // // Notify the friend @@ -652,10 +635,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) { - DeleteFriendship(agentID, exfriendID); + if (!DeleteFriendship(agentID, exfriendID)) + client.SendAlertMessage("Unable to terminate friendship on this sim."); // Update local cache - UpdateFriendsCache(client); + RefetchFriends(client); client.SendTerminateFriend(exfriendID); @@ -679,12 +663,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - protected virtual void DeleteFriendship(UUID agentID, UUID exfriendID) - { - FriendsService.Delete(agentID, exfriendID.ToString()); - FriendsService.Delete(exfriendID, agentID.ToString()); - } - private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) { m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); @@ -702,7 +680,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (friend != null) // Found it { // Store it on the DB - if (!SimpleStore(requester, target, rights)) + if (!StoreRights(requester, target, rights)) { remoteClient.SendAlertMessage("Unable to grant rights."); return; @@ -740,12 +718,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester); } - protected virtual bool SimpleStore(UUID agentID, UUID friendID, int rights) - { - FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights); - return true; - } - protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) { foreach (FriendInfo fi in friends) @@ -782,7 +754,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends friendClient.SendInstantMessage(im); // Update the local cache - UpdateFriendsCache(friendClient); + RefetchFriends(friendClient); // we're done return true; @@ -815,7 +787,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // the friend in this sim as root agent friendClient.SendTerminateFriend(exfriendID); // update local cache - UpdateFriendsCache(friendClient); + RefetchFriends(friendClient); // we're done return true; } @@ -874,6 +846,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends #endregion + #region Get / Set friends in several flavours + /// + /// Get friends from local cache only + /// + /// + /// protected FriendInfo[] GetFriends(UUID agentID) { UserFriendData friendsData; @@ -887,7 +865,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return EMPTY_FRIENDS; } - private void UpdateFriendsCache(IClientAPI client) + /// + /// Update loca cache only + /// + /// + /// + /// + protected void UpdateLocalCache(UUID userID, UUID friendID, int rights) + { + // Update local cache + lock (m_Friends) + { + FriendInfo[] friends = GetFriends(friendID); + FriendInfo finfo = GetFriend(friends, userID); + finfo.TheirFlags = rights; + } + } + + protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client) + { + return FriendsService.GetFriends(client.AgentId); + } + + private void RefetchFriends(IClientAPI client) { UUID agentID = client.AgentId; lock (m_Friends) @@ -898,15 +898,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - protected void UpdateLocalCache(UUID userID, UUID friendID, int rights) + protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights) { - // Update local cache - lock (m_Friends) - { - FriendInfo[] friends = GetFriends(friendID); - FriendInfo finfo = GetFriend(friends, userID); - finfo.TheirFlags = rights; - } + FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights); + return true; } + + protected virtual void StoreBackwards(UUID friendID, UUID agentID) + { + FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0); + } + + protected virtual void StoreFriendships(UUID agentID, UUID friendID) + { + FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1); + FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1); + } + + protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID) + { + FriendsService.Delete(agentID, exfriendID.ToString()); + FriendsService.Delete(exfriendID, agentID.ToString()); + return true; + } + + #endregion } } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index abffb94..c55839f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -72,8 +72,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends UUID id; if (!UUID.TryParse(finfo.Friend, out id)) { - string url = string.Empty, first = string.Empty, last = string.Empty; - if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last)) + string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty; + if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp)) { IUserManagement uMan = m_Scenes[0].RequestModuleInterface(); uMan.AddUser(id, url + ";" + first + " " + last); @@ -103,22 +103,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return false; } - protected override FriendInfo[] GetFriendsFromService(IClientAPI client) - { - UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId); - if (account1 != null) - return base.GetFriendsFromService(client); - - // Foreigner - AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); - string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); - - FriendInfo[] finfos = FriendsService.GetFriends(agentUUI); - m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); - return finfos; - } - - protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) { first = "Unknown"; last = "User"; @@ -126,8 +110,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return true; // fid is not a UUID... - string url = string.Empty; - if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last)) + string url = string.Empty, tmp = string.Empty; + if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp)) { IUserManagement userMan = m_Scenes[0].RequestModuleInterface(); userMan.AddUser(agentID, url + ";" + first + " " + last); @@ -164,7 +148,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return "Please confirm this friendship you made while you were away."; } - protected override bool SimpleStore(UUID agentID, UUID friendID, int rights) + protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) + { + foreach (FriendInfo fi in friends) + { + if (fi.Friend.StartsWith(friendID.ToString())) + return fi; + } + return null; + } + + + protected override FriendInfo[] GetFriendsFromService(IClientAPI client) + { + UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId); + if (account1 != null) + return base.GetFriendsFromService(client); + + FriendInfo[] finfos = new FriendInfo[0]; + // Foreigner + AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); + if (agentClientCircuit != null) + { + string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); + + m_log.DebugFormat("[XXX] GetFriendsFromService to {0}", agentUUI); + finfos = FriendsService.GetFriends(agentUUI); + m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); + } + return finfos; + } + + protected override bool StoreRights(UUID agentID, UUID friendID, int rights) { UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); @@ -172,30 +187,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (account1 != null && account2 != null) { // local grid users - return base.SimpleStore(agentID, friendID, rights); + return base.StoreRights(agentID, friendID, rights); } - if (account1 != null) + if (account1 != null) // agent is local, friend is foreigner { FriendInfo[] finfos = GetFriends(agentID); - if (finfos.Length > 0) + FriendInfo finfo = GetFriend(finfos, friendID); + if (finfo != null) { - FriendInfo finfo = GetFriend(finfos, friendID); FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights); return true; } } - if (account2 != null) + + if (account2 != null) // agent is foreigner, friend is local { - IClientAPI client = LocateClientObject(agentID); - if (client != null) + string agentUUI = GetUUI(friendID, agentID); + if (agentUUI != string.Empty) { - AgentCircuitData acircuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); - if (acircuit != null) - { - FriendsService.StoreFriend(Util.ProduceUserUniversalIdentifier(acircuit), friendID.ToString(), rights); - return true; - } + FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights); + return true; } } @@ -233,7 +245,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return; } - // ok, at least one of them is foreigner, let's get their data IClientAPI agentClient = LocateClientObject(agentID); IClientAPI friendClient = LocateClientObject(friendID); @@ -257,13 +268,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); } - m_log.DebugFormat("[XXX] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", + m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", agentUUI, friendUUI, agentFriendService, friendFriendService); + // Generate a random 8-character hex number that will sign this friendship + string secret = UUID.Random().ToString().Substring(0, 8); + if (agentAccount != null) // agent is local, 'friend' is foreigner { // This may happen when the agent returned home, in which case the friend is not there - // We need to llok for its information in the friends list itself + // We need to look for its information in the friends list itself + bool confirming = false; if (friendUUI == string.Empty) { FriendInfo[] finfos = GetFriends(agentID); @@ -272,35 +287,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (finfo.TheirFlags == -1) { if (finfo.Friend.StartsWith(friendID.ToString())) + { friendUUI = finfo.Friend; + confirming = true; + } } } } + // If it's confirming the friendship, we already have the full friendUUI with the secret + string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret; + // store in the local friends service a reference to the foreign friend - FriendsService.StoreFriend(agentID.ToString(), friendUUI, 1); + FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1); // and also the converse - FriendsService.StoreFriend(friendUUI, agentID.ToString(), 1); + FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1); - if (friendClientCircuit != null) + if (!confirming && friendClientCircuit != null) { // store in the foreign friends service a reference to the local agent HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); - friendsConn.NewFriendship(friendID, agentUUI); + friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); } } else if (friendAccount != null) // 'friend' is local, agent is foreigner { // store in the local friends service a reference to the foreign agent - FriendsService.StoreFriend(friendID.ToString(), agentUUI, 1); + FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1); // and also the converse - FriendsService.StoreFriend(agentUUI, friendID.ToString(), 1); + FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1); if (agentClientCircuit != null) { // store in the foreign friends service a reference to the local agent HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); - friendsConn.NewFriendship(agentID, friendUUI); + friendsConn.NewFriendship(agentID, friendUUI + ";" + secret); } } else // They're both foreigners! @@ -309,43 +330,112 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (agentClientCircuit != null) { friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); - friendsConn.NewFriendship(agentID, friendUUI); + friendsConn.NewFriendship(agentID, friendUUI + ";" + secret); } if (friendClientCircuit != null) { friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); - friendsConn.NewFriendship(friendID, agentUUI); + friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); } } // my brain hurts now } - protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) + protected override bool DeleteFriendship(UUID agentID, UUID exfriendID) { - foreach (FriendInfo fi in friends) + UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); + UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID); + // Are they both local users? + if (agentAccount != null && friendAccount != null) { - if (fi.Friend.StartsWith(friendID.ToString())) - return fi; + // local grid users + return base.DeleteFriendship(agentID, exfriendID); } - return null; + + // ok, at least one of them is foreigner, let's get their data + string agentUUI = string.Empty; + string friendUUI = string.Empty; + + if (agentAccount != null) // agent is local, 'friend' is foreigner + { + // We need to look for its information in the friends list itself + FriendInfo[] finfos = GetFriends(agentID); + FriendInfo finfo = GetFriend(finfos, exfriendID); + if (finfo != null) + { + friendUUI = finfo.Friend; + + // delete in the local friends service the reference to the foreign friend + FriendsService.Delete(agentID, friendUUI); + // and also the converse + FriendsService.Delete(friendUUI, agentID.ToString()); + + // notify the exfriend's service + Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); }); + + m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI); + return true; + } + } + else if (friendAccount != null) // agent is foreigner, 'friend' is local + { + agentUUI = GetUUI(exfriendID, agentID); + + if (agentUUI != string.Empty) + { + // delete in the local friends service the reference to the foreign agent + FriendsService.Delete(exfriendID, agentUUI); + // and also the converse + FriendsService.Delete(agentUUI, exfriendID.ToString()); + + // notify the agent's service? + Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); }); + + m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID); + return true; + } + } + //else They're both foreigners! Can't handle this + + return false; } - protected override void DeleteFriendship(UUID agentID, UUID exfriendID) + private string GetUUI(UUID localUser, UUID foreignUser) { - base.DeleteFriendship(agentID, exfriendID); - // Maybe some of the base deletes will fail. - // Let's delete the local friendship with foreign friend - FriendInfo[] friends = GetFriends(agentID); - foreach (FriendInfo finfo in friends) + // Let's see if the user is here by any chance + FriendInfo[] finfos = GetFriends(localUser); + if (finfos != EMPTY_FRIENDS) // friend is here, cool { - if (finfo.Friend != exfriendID.ToString() && finfo.Friend.StartsWith(exfriendID.ToString())) + FriendInfo finfo = GetFriend(finfos, foreignUser); + if (finfo != null) { - FriendsService.Delete(agentID, exfriendID.ToString()); - // TODO: delete the friendship on the other side - // Should use the homeurl given in finfo.Friend + return finfo.Friend; } } + else // user is not currently on this sim, need to get from the service + { + finfos = FriendsService.GetFriends(localUser); + foreach (FriendInfo finfo in finfos) + { + if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it! + { + return finfo.Friend; + } + } + } + return string.Empty; } + private void Delete(UUID foreignUser, UUID localUser, string uui) + { + UUID id; + string url = string.Empty, secret = string.Empty, tmp = string.Empty; + if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret)) + { + m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url); + HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url); + friendConn.DeleteFriendship(foreignUser, localUser, secret); + } + } } } diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs index 71c3c73..9969086 100644 --- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs @@ -91,6 +91,9 @@ namespace OpenSim.Server.Handlers.Friends case "deletefriend": return DeleteFriend(request); + case "deletefriend_string": + return DeleteFriendString(request); + } m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); } @@ -184,7 +187,25 @@ namespace OpenSim.Server.Handlers.Friends else return FailureResult(); } - + + byte[] DeleteFriendString(Dictionary request) + { + string principalID = string.Empty; + if (request.ContainsKey("PRINCIPALID")) + principalID = request["PRINCIPALID"].ToString(); + else + m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to delete friend"); + string friend = string.Empty; + if (request.ContainsKey("FRIEND")) + friend = request["FRIEND"].ToString(); + + bool success = m_FriendsService.Delete(principalID, friend); + if (success) + return SuccessResult(); + else + return FailureResult(); + } + #endregion #region Misc diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs index dde7875..a83d0e8 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs @@ -88,6 +88,8 @@ namespace OpenSim.Server.Handlers.Hypergrid case "newfriendship": return NewFriendship(request); + case "deletefriendship": + return DeleteFriendship(request); } m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); } @@ -143,11 +145,21 @@ namespace OpenSim.Server.Handlers.Hypergrid // OK, can proceed FriendInfo friend = new FriendInfo(request); + UUID friendID; + string tmp = string.Empty; + if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp)) + return FailureResult(); + + m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend); + + // If the friendship already exists, return fail + FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID); + foreach (FriendInfo finfo in finfos) + if (finfo.Friend.StartsWith(friendID.ToString())) + return FailureResult(); // the user needs to confirm when he gets home bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0); - //if (success) - // m_FriendsService.StoreFriend(friend.Friend, friend.PrincipalID.ToString(), 1); if (success) return SuccessResult(); @@ -155,6 +167,33 @@ namespace OpenSim.Server.Handlers.Hypergrid return FailureResult(); } + byte[] DeleteFriendship(Dictionary request) + { + FriendInfo friend = new FriendInfo(request); + string secret = string.Empty; + if (request.ContainsKey("SECRET")) + secret = request["SECRET"].ToString(); + + if (secret == string.Empty) + return FailureResult(); + + FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID); + foreach (FriendInfo finfo in finfos) + { + // We check the secret here + if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret)) + { + m_log.DebugFormat("[HGFRIENDS HANDLER]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend); + m_FriendsService.Delete(friend.PrincipalID, finfo.Friend); + m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString()); + + return SuccessResult(); + } + } + + return FailureResult(); + } + #endregion #region Misc diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs index d1afea2..08f1dc3 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs @@ -211,6 +211,16 @@ namespace OpenSim.Services.Connectors.Friends } + public bool Delete(string PrincipalID, string Friend) + { + Dictionary sendData = new Dictionary(); + sendData["PRINCIPALID"] = PrincipalID.ToString(); + sendData["FRIEND"] = Friend; + sendData["METHOD"] = "deletefriend_string"; + + return Delete(sendData, PrincipalID, Friend); + } + public bool Delete(UUID PrincipalID, string Friend) { Dictionary sendData = new Dictionary(); @@ -218,6 +228,11 @@ namespace OpenSim.Services.Connectors.Friends sendData["FRIEND"] = Friend; sendData["METHOD"] = "deletefriend"; + return Delete(sendData, PrincipalID.ToString(), Friend); + } + + public bool Delete(Dictionary sendData, string PrincipalID, string Friend) + { string reply = string.Empty; try { diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs index f823889..d699f59 100644 --- a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs @@ -54,6 +54,11 @@ namespace OpenSim.Services.Connectors.Hypergrid { } + public HGFriendsServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey) { m_ServerURI = serverURI.TrimEnd('/'); @@ -151,6 +156,51 @@ namespace OpenSim.Services.Connectors.Hypergrid } + public bool DeleteFriendship(UUID PrincipalID, UUID Friend, string secret) + { + FriendInfo finfo = new FriendInfo(); + finfo.PrincipalID = PrincipalID; + finfo.Friend = Friend.ToString(); + + Dictionary sendData = finfo.ToKeyValuePairs(); + + sendData["METHOD"] = "deletefriendship"; + sendData["SECRET"] = secret; + + string reply = string.Empty; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/hgfriends", + ServerUtils.BuildQueryString(sendData)); + } + catch (Exception e) + { + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message); + return false; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null)) + { + bool success = false; + Boolean.TryParse(replyData["Result"].ToString(), out success); + return success; + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Delete {0} {1} received null response", + PrincipalID, Friend); + } + else + m_log.DebugFormat("[HGFRIENDS CONNECTOR]: DeleteFriend received null reply"); + + return false; + + } + #endregion } } \ No newline at end of file diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs index b1c34dd..7422d94 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs @@ -103,7 +103,7 @@ namespace OpenSim.Services.Connectors.SimianGrid if (!UUID.TryParse(principalID, out friend.PrincipalID)) { string tmp = string.Empty; - if (!Util.ParseUniversalUserIdentifier(principalID, out friend.PrincipalID, out tmp, out tmp, out tmp)) + if (!Util.ParseUniversalUserIdentifier(principalID, out friend.PrincipalID, out tmp, out tmp, out tmp, out tmp)) // bad record. ignore this entry continue; } @@ -164,6 +164,11 @@ namespace OpenSim.Services.Connectors.SimianGrid public bool Delete(UUID principalID, string friend) { + return Delete(principalID.ToString(), friend); + } + + public bool Delete(string principalID, string friend) + { if (String.IsNullOrEmpty(m_serverUrl)) return true; diff --git a/OpenSim/Services/Friends/FriendsService.cs b/OpenSim/Services/Friends/FriendsService.cs index 4664cb3..e2033ac 100644 --- a/OpenSim/Services/Friends/FriendsService.cs +++ b/OpenSim/Services/Friends/FriendsService.cs @@ -75,7 +75,7 @@ namespace OpenSim.Services.Friends if (!UUID.TryParse(d.PrincipalID, out i.PrincipalID)) { string tmp = string.Empty; - if (!Util.ParseUniversalUserIdentifier(d.PrincipalID, out i.PrincipalID, out tmp, out tmp, out tmp)) + if (!Util.ParseUniversalUserIdentifier(d.PrincipalID, out i.PrincipalID, out tmp, out tmp, out tmp, out tmp)) // bad record. ignore this entry continue; } @@ -101,6 +101,11 @@ namespace OpenSim.Services.Friends return m_Database.Store(d); } + public bool Delete(string principalID, string friend) + { + return m_Database.Delete(principalID, friend); + } + public virtual bool Delete(UUID PrincipalID, string Friend) { return m_Database.Delete(PrincipalID, Friend); diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs deleted file mode 100644 index 1829ae3..0000000 --- a/OpenSim/Services/HypergridService/HGFriendsService.cs +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using OpenMetaverse; -using OpenSim.Framework; -using System; -using System.Collections.Generic; -using OpenSim.Services.Interfaces; -using OpenSim.Services.Friends; -using OpenSim.Data; -using Nini.Config; -using log4net; -using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; - -namespace OpenSim.Services.HypergridService -{ - public class HGFriendsService : FriendsService, IFriendsService - { - public HGFriendsService(IConfigSource config) : base(config) - { - } - - /// - /// Overrides base. - /// Storing new friendships from the outside is a tricky, sensitive operation, and it - /// needs to be done under certain restrictions. - /// First of all, if the friendship already exists, this is a no-op. In other words, - /// we cannot change just the flags, it needs to be a new friendship. - /// Second, we store it as flags=0 always, independent of what the caller sends. The - /// owner of the friendship needs to confirm when it gets back home. - /// - /// - /// - /// - /// - public override bool StoreFriend(string PrincipalID, string Friend, int flags) - { - UUID userID; - if (UUID.TryParse(PrincipalID, out userID)) - { - FriendsData[] friendsData = m_Database.GetFriends(userID.ToString()); - List fList = new List(friendsData); - if (fList.Find(delegate(FriendsData fdata) - { - return fdata.Friend == Friend; - }) != null) - return false; - } - else - return false; - - FriendsData d = new FriendsData(); - d.PrincipalID = PrincipalID; - d.Friend = Friend; - d.Data = new Dictionary(); - d.Data["Flags"] = "0"; - - return m_Database.Store(d); - } - - } -} diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs index 0a8efad..1664f3b 100644 --- a/OpenSim/Services/Interfaces/IFriendsService.cs +++ b/OpenSim/Services/Interfaces/IFriendsService.cs @@ -77,5 +77,6 @@ namespace OpenSim.Services.Interfaces FriendInfo[] GetFriends(string PrincipalID); bool StoreFriend(string PrincipalID, string Friend, int flags); bool Delete(UUID PrincipalID, string Friend); + bool Delete(string PrincipalID, string Friend); } } diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 4fac951..f68c078 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -628,7 +628,7 @@ namespace OpenSim.Services.LLLoginService else { string tmp; - if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp)) + if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp, out tmp)) buddyitem.BuddyID = friendID.ToString(); else // junk entry diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 324c258..f8e8ae2 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -142,7 +142,7 @@ UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" [HGFriendsService] - LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGFriendsService" + LocalServiceModule = "OpenSim.Services.FriendsService.dll:FriendsService" UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" ;; This should always be the very last thing on this file -- cgit v1.1 From 24f28d353427d1905ae1a46408841265379e29c3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 23 May 2011 19:45:39 -0700 Subject: HG friends: Status notifications working. Also initial logins get the online friends in other grids. --- .../CoreModules/Avatar/Friends/FriendsModule.cs | 92 +++++------ .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 162 ++++++++++++++++++- .../Hypergrid/HypergridServiceInConnectorModule.cs | 3 +- .../Hypergrid/HGFriendsServerPostHandler.cs | 4 + .../Handlers/Hypergrid/UserAgentServerConnector.cs | 84 +++++++++- .../Hypergrid/UserAgentServiceConnector.cs | 91 +++++++++++ .../Services/HypergridService/UserAgentService.cs | 172 ++++++++++++++++++++- OpenSim/Services/Interfaces/IGatekeeperService.cs | 3 + .../Services/Interfaces/ISimulatorSocialService.cs | 40 +++++ bin/config-include/StandaloneHypergrid.ini | 3 + 10 files changed, 602 insertions(+), 52 deletions(-) create mode 100644 OpenSim/Services/Interfaces/ISimulatorSocialService.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 7d94813..f82716d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -139,7 +139,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (moduleConfig != null) { string name = moduleConfig.GetString("FriendsModule", "FriendsModule"); - m_log.DebugFormat("[XXX] {0} compared to {1}", name, Name); if (name == Name) { InitModule(config); @@ -183,7 +182,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { } - public void AddRegion(Scene scene) + public virtual void AddRegion(Scene scene) { if (!m_Enabled) return; @@ -302,6 +301,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { UUID agentID = client.AgentId; + //m_log.DebugFormat("[XXX]: OnClientLogin!"); // Inform the friends that this user is online StatusChange(agentID, true); @@ -405,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } if (friendList.Count > 0) - { - PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); - foreach (PresenceInfo pi in presence) - { - UUID presenceID; - if (UUID.TryParse(pi.UserID, out presenceID)) - online.Add(presenceID); - } - } + GetOnlineFriends(userID, friendList, online); return online; } + protected virtual void GetOnlineFriends(UUID userID, List friendList, /*collector*/ List online) + { + PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); + foreach (PresenceInfo pi in presence) + { + UUID presenceID; + if (UUID.TryParse(pi.UserID, out presenceID)) + online.Add(presenceID); + } + } + /// /// Find the client for a ID /// @@ -472,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends Util.FireAndForget( delegate { - foreach (FriendInfo fi in friendList) - { - //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID); - // Notify about this user status - StatusNotify(fi, agentID, online); - } + m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count); + // Notify about this user status + StatusNotify(friendList, agentID, online); } ); } } - private void StatusNotify(FriendInfo friend, UUID userID, bool online) + protected virtual void StatusNotify(List friendList, UUID userID, bool online) { - UUID friendID; - if (UUID.TryParse(friend.Friend, out friendID)) + foreach (FriendInfo friend in friendList) { - // Try local - if (LocalStatusNotification(userID, friendID, online)) - return; - - // The friend is not here [as root]. Let's forward. - PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); - if (friendSessions != null && friendSessions.Length > 0) + UUID friendID; + if (UUID.TryParse(friend.Friend, out friendID)) { - PresenceInfo friendSession = null; - foreach (PresenceInfo pinfo in friendSessions) - if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad - { - friendSession = pinfo; - break; - } + // Try local + if (LocalStatusNotification(userID, friendID, online)) + return; - if (friendSession != null) + // The friend is not here [as root]. Let's forward. + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); + if (friendSessions != null && friendSessions.Length > 0) { - GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); - m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); + PresenceInfo friendSession = null; + foreach (PresenceInfo pinfo in friendSessions) + if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad + { + friendSession = pinfo; + break; + } + + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); + m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); + } } - } - // Friend is not online. Ignore. - } - else - { - m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); + // Friend is not online. Ignore. + } + else + { + m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); + } } } @@ -670,7 +673,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends FriendInfo[] friends = GetFriends(remoteClient.AgentId); if (friends.Length == 0) { - m_log.DebugFormat("[XXX]: agent {0} has no friends", requester); return; } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index c55839f..b0a7567 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -46,7 +46,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.Avatar.Friends { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule + public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -56,6 +56,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends get { return "HGFriendsModule"; } } + public override void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + base.AddRegion(scene); + scene.RegisterModuleInterface(this); + } + + #endregion + + #region IFriendsSimConnector + + /// + /// Notify the user that the friend's status changed + /// + /// user to be notified + /// friend whose status changed + /// status + /// + public bool StatusNotify(UUID userID, UUID friendID, bool online) + { + return LocalStatusNotification(friendID, userID, online); + } + #endregion protected override bool FetchFriendslist(IClientAPI client) @@ -103,6 +128,140 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return false; } + protected override void GetOnlineFriends(UUID userID, List friendList, /*collector*/ List online) + { + // Let's single out the UUIs + List localFriends = new List(); + List foreignFriends = new List(); + string tmp = string.Empty; + + foreach (string s in friendList) + { + UUID id; + if (UUID.TryParse(s, out id)) + localFriends.Add(s); + else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp)) + { + foreignFriends.Add(s); + // add it here too, who knows maybe the foreign friends happens to be on this grid + localFriends.Add(id.ToString()); + } + } + + // OK, see who's present on this grid + List toBeRemoved = new List(); + PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray()); + foreach (PresenceInfo pi in presence) + { + UUID presenceID; + if (UUID.TryParse(pi.UserID, out presenceID)) + { + online.Add(presenceID); + foreach (string s in foreignFriends) + if (s.StartsWith(pi.UserID)) + toBeRemoved.Add(s); + } + } + + foreach (string s in toBeRemoved) + foreignFriends.Remove(s); + + // OK, let's send this up the stack, and leave a closure here + // collecting online friends in other grids + Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); }); + + } + + private void CollectOnlineFriendsElsewhere(UUID userID, List foreignFriends) + { + // let's divide the friends on a per-domain basis + Dictionary> friendsPerDomain = new Dictionary>(); + foreach (string friend in foreignFriends) + { + UUID friendID; + if (!UUID.TryParse(friend, out friendID)) + { + // it's a foreign friend + string url = string.Empty, tmp = string.Empty; + if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp)) + { + if (!friendsPerDomain.ContainsKey(url)) + friendsPerDomain[url] = new List(); + friendsPerDomain[url].Add(friend); + } + } + } + + // Now, call those worlds + + foreach (KeyValuePair> kvp in friendsPerDomain) + { + List ids = new List(); + foreach (string f in kvp.Value) + ids.Add(f); + UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); + List online = uConn.GetOnlineFriends(userID, ids); + // Finally send the notifications to the user + // this whole process may take a while, so let's check at every + // iteration that the user is still here + IClientAPI client = LocateClientObject(userID); + if (client != null) + client.SendAgentOnline(online.ToArray()); + else + break; + } + + } + + protected override void StatusNotify(List friendList, UUID userID, bool online) + { + // First, let's divide the friends on a per-domain basis + Dictionary> friendsPerDomain = new Dictionary>(); + foreach (FriendInfo friend in friendList) + { + UUID friendID; + if (UUID.TryParse(friend.Friend, out friendID)) + { + if (!friendsPerDomain.ContainsKey("local")) + friendsPerDomain["local"] = new List(); + friendsPerDomain["local"].Add(friend); + } + else + { + // it's a foreign friend + string url = string.Empty, tmp = string.Empty; + if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp)) + { + // Let's try our luck in the local sim. Who knows, maybe it's here + if (LocalStatusNotification(userID, friendID, online)) + continue; + + if (!friendsPerDomain.ContainsKey(url)) + friendsPerDomain[url] = new List(); + friendsPerDomain[url].Add(friend); + } + } + } + + // For the local friends, just call the base method + // Let's do this first of all + if (friendsPerDomain.ContainsKey("local")) + base.StatusNotify(friendsPerDomain["local"], userID, online); + + foreach (KeyValuePair> kvp in friendsPerDomain) + { + if (kvp.Key != "local") + { + // For the others, call the user agent service + List ids = new List(); + foreach (FriendInfo f in kvp.Value) + ids.Add(f.Friend); + UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); + uConn.StatusNotification(ids, userID, online); + } + } + } + protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) { first = "Unknown"; last = "User"; @@ -172,7 +331,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); - m_log.DebugFormat("[XXX] GetFriendsFromService to {0}", agentUUI); finfos = FriendsService.GetFriends(agentUUI); m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs index f5b6817..a5b5637 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs @@ -113,7 +113,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid ISimulationService simService = scene.RequestModuleInterface(); m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); - new UserAgentServerConnector(m_Config, MainServer.Instance); + IFriendsSimConnector friendsConn = scene.RequestModuleInterface(); + new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn); new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService"); } diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs index a83d0e8..841811e 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs @@ -140,16 +140,20 @@ namespace OpenSim.Server.Handlers.Hypergrid byte[] NewFriendship(Dictionary request) { + m_log.DebugFormat("[XXX] 1"); if (!VerifyServiceKey(request)) return FailureResult(); + m_log.DebugFormat("[XXX] 2"); // OK, can proceed FriendInfo friend = new FriendInfo(request); UUID friendID; string tmp = string.Empty; + m_log.DebugFormat("[XXX] 3"); if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp)) return FailureResult(); + m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend); // If the friendship already exists, return fail diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index 0e8ce80..7a9fb4b 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -54,13 +54,19 @@ namespace OpenSim.Server.Handlers.Hypergrid private IUserAgentService m_HomeUsersService; public UserAgentServerConnector(IConfigSource config, IHttpServer server) : + this(config, server, null) + { + } + + public UserAgentServerConnector(IConfigSource config, IHttpServer server, IFriendsSimConnector friendsConnector) : base(config, server, String.Empty) { IConfig gridConfig = config.Configs["UserAgentService"]; if (gridConfig != null) { string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty); - Object[] args = new Object[] { config }; + + Object[] args = new Object[] { config, friendsConnector }; m_HomeUsersService = ServerUtils.LoadPlugin(serviceDll, args); } if (m_HomeUsersService == null) @@ -75,6 +81,9 @@ namespace OpenSim.Server.Handlers.Hypergrid server.AddXmlRPCHandler("verify_client", VerifyClient, false); server.AddXmlRPCHandler("logout_agent", LogoutAgent, false); + server.AddXmlRPCHandler("status_notification", StatusNotification, false); + server.AddXmlRPCHandler("get_online_friends", GetOnlineFriends, false); + server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); } @@ -194,5 +203,78 @@ namespace OpenSim.Server.Handlers.Hypergrid } + public XmlRpcResponse StatusNotification(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable hash = new Hashtable(); + hash["result"] = "false"; + + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + if (requestData.ContainsKey("userID") && requestData.ContainsKey("online")) + { + string userID_str = (string)requestData["userID"]; + UUID userID = UUID.Zero; + UUID.TryParse(userID_str, out userID); + List ids = new List(); + foreach (object key in requestData.Keys) + { + if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null) + ids.Add(requestData[key].ToString()); + } + bool online = false; + bool.TryParse(requestData["online"].ToString(), out online); + + hash["result"] = "true"; + + // let's spawn a thread for this, because it may take a long time... + Util.FireAndForget(delegate { m_HomeUsersService.StatusNotification(ids, userID, online); }); + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } + + public XmlRpcResponse GetOnlineFriends(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable hash = new Hashtable(); + + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + if (requestData.ContainsKey("userID")) + { + string userID_str = (string)requestData["userID"]; + UUID userID = UUID.Zero; + UUID.TryParse(userID_str, out userID); + List ids = new List(); + foreach (object key in requestData.Keys) + { + if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null) + ids.Add(requestData[key].ToString()); + } + + // let's spawn a thread for this, because it may take a long time... + List online = m_HomeUsersService.GetOnlineFriends(userID, ids); + if (online.Count > 0) + { + int i = 0; + foreach (UUID id in online) + { + hash["friend_" + i.ToString()] = id.ToString(); + i++; + } + + } + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } + } } diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index c40a347..46d30df 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -404,6 +404,97 @@ namespace OpenSim.Services.Connectors.Hypergrid GetBoolResponse(request, out reason); } + public void StatusNotification(List friends, UUID userID, bool online) + { + Hashtable hash = new Hashtable(); + hash["userID"] = userID.ToString(); + hash["online"] = online.ToString(); + int i = 0; + foreach (string s in friends) + { + hash["friend_" + i.ToString()] = s; + i++; + } + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("status_notification", paramList); + string reason = string.Empty; + GetBoolResponse(request, out reason); + + } + + public List GetOnlineFriends(UUID userID, List friends) + { + Hashtable hash = new Hashtable(); + hash["userID"] = userID.ToString(); + int i = 0; + foreach (string s in friends) + { + hash["friend_" + i.ToString()] = s; + i++; + } + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("get_online_friends", paramList); + string reason = string.Empty; + + // Send and get reply + List online = new List(); + XmlRpcResponse response = null; + try + { + response = request.Send(m_ServerURL, 10000); + } + catch (Exception e) + { + m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); + reason = "Exception: " + e.Message; + return online; + } + + if (response.IsFault) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); + reason = "XMLRPC Fault"; + return online; + } + + hash = (Hashtable)response.Value; + //foreach (Object o in hash) + // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); + try + { + if (hash == null) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got null response from {0}! THIS IS BAAAAD", m_ServerURL); + reason = "Internal error 1"; + return online; + } + + // Here is the actual response + foreach (object key in hash.Keys) + { + if (key is string && ((string)key).StartsWith("friend_") && hash[key] != null) + { + UUID uuid; + if (UUID.TryParse(hash[key].ToString(), out uuid)) + online.Add(uuid); + } + } + + } + catch (Exception e) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response."); + reason = "Exception: " + e.Message; + } + + return online; + } private bool GetBoolResponse(XmlRpcRequest request, out string reason) { diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 445d45e..0181533 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -31,10 +31,12 @@ using System.Net; using System.Reflection; using OpenSim.Framework; +using OpenSim.Services.Connectors.Friends; using OpenSim.Services.Connectors.Hypergrid; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; using OpenSim.Server.Base; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; using OpenMetaverse; using log4net; @@ -63,19 +65,34 @@ namespace OpenSim.Services.HypergridService protected static IGridService m_GridService; protected static GatekeeperServiceConnector m_GatekeeperConnector; protected static IGatekeeperService m_GatekeeperService; + protected static IFriendsService m_FriendsService; + protected static IPresenceService m_PresenceService; + protected static IFriendsSimConnector m_FriendsLocalSimConnector; // standalone, points to HGFriendsModule + protected static FriendsSimConnector m_FriendsSimConnector; // grid protected static string m_GridName; protected static bool m_BypassClientVerification; - public UserAgentService(IConfigSource config) + public UserAgentService(IConfigSource config) : this(config, null) { + } + + public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector) + { + // Let's set this always, because we don't know the sequence + // of instantiations + if (friendsConnector != null) + m_FriendsLocalSimConnector = friendsConnector; + if (!m_Initialized) { m_Initialized = true; m_log.DebugFormat("[HOME USERS SECURITY]: Starting..."); - + + m_FriendsSimConnector = new FriendsSimConnector(); + IConfig serverConfig = config.Configs["UserAgentService"]; if (serverConfig == null) throw new Exception(String.Format("No section UserAgentService in config file")); @@ -83,6 +100,8 @@ namespace OpenSim.Services.HypergridService string gridService = serverConfig.GetString("GridService", String.Empty); string gridUserService = serverConfig.GetString("GridUserService", String.Empty); string gatekeeperService = serverConfig.GetString("GatekeeperService", String.Empty); + string friendsService = serverConfig.GetString("FriendsService", String.Empty); + string presenceService = serverConfig.GetString("PresenceService", String.Empty); m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false); @@ -94,6 +113,8 @@ namespace OpenSim.Services.HypergridService m_GridUserService = ServerUtils.LoadPlugin(gridUserService, args); m_GatekeeperConnector = new GatekeeperServiceConnector(); m_GatekeeperService = ServerUtils.LoadPlugin(gatekeeperService, args); + m_FriendsService = ServerUtils.LoadPlugin(friendsService, args); + m_PresenceService = ServerUtils.LoadPlugin(presenceService, args); m_GridName = serverConfig.GetString("ExternalName", string.Empty); if (m_GridName == string.Empty) @@ -156,11 +177,16 @@ namespace OpenSim.Services.HypergridService string gridName = gatekeeper.ServerURI; m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}", m_GridName, gridName); - + if (m_GridName == gridName) success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); else + { success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason); + if (success) + // Report them as nowhere + m_PresenceService.ReportAgent(agentCircuit.SessionID, UUID.Zero); + } if (!success) { @@ -179,6 +205,7 @@ namespace OpenSim.Services.HypergridService if (clientIP != null) m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString(); m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP; + return true; } @@ -291,6 +318,145 @@ namespace OpenSim.Services.HypergridService return false; } + public void StatusNotification(List friends, UUID foreignUserID, bool online) + { + if (m_FriendsService == null || m_PresenceService == null) + { + m_log.WarnFormat("[USER AGENT SERVICE]: Unable to perform status notifications because friends or presence services are missing"); + return; + } + + m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: foreign user {0} wants to notify {1} local friends", foreignUserID, friends.Count); + + // First, let's double check that the reported friends are, indeed, friends of that user + // And let's check that the secret matches + List usersToBeNotified = new List(); + foreach (string uui in friends) + { + UUID localUserID; + string secret = string.Empty, tmp = string.Empty; + if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret)) + { + FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID); + foreach (FriendInfo finfo in friendInfos) + { + if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret)) + { + // great! + usersToBeNotified.Add(localUserID.ToString()); + } + } + } + } + + // Now, let's send the notifications + m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: user has {0} local friends", usersToBeNotified.Count); + + // First, let's send notifications to local users who are online in the home grid + PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray()); + if (friendSessions != null && friendSessions.Length > 0) + { + PresenceInfo friendSession = null; + foreach (PresenceInfo pinfo in friendSessions) + if (pinfo.RegionID != UUID.Zero) // let's guard against traveling agents + { + friendSession = pinfo; + break; + } + + if (friendSession != null) + { + ForwardStatusNotificationToSim(friendSession.RegionID, friendSession.UserID, foreignUserID, online); + usersToBeNotified.Remove(friendSession.UserID.ToString()); + } + } + + // Lastly, let's notify the rest who may be online somewhere else + foreach (string user in usersToBeNotified) + { + UUID id = new UUID(user); + if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName) + { + string url = m_TravelingAgents[id].GridExternalName; + // forward + m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url); + } + } + } + + protected void ForwardStatusNotificationToSim(UUID regionID, string user, UUID foreignUserID, bool online) + { + UUID userID; + if (UUID.TryParse(user, out userID)) + { + if (m_FriendsLocalSimConnector != null) + { + m_log.DebugFormat("[USER AGENT SERVICE]: Local Notify, user {0} is {1}", foreignUserID, (online ? "online" : "offline")); + m_FriendsLocalSimConnector.StatusNotify(userID, foreignUserID, online); + } + else + { + GridRegion region = m_GridService.GetRegionByUUID(UUID.Zero /* !!! */, regionID); + if (region != null) + { + m_log.DebugFormat("[USER AGENT SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, user, foreignUserID, (online ? "online" : "offline")); + m_FriendsSimConnector.StatusNotify(region, userID, foreignUserID, online); + } + } + } + } + + public List GetOnlineFriends(UUID foreignUserID, List friends) + { + List online = new List(); + + if (m_FriendsService == null || m_PresenceService == null) + { + m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get online friends because friends or presence services are missing"); + return online; + } + + m_log.DebugFormat("[USER AGENT SERVICE]: Foreign user {0} wants to know status of {1} local friends", foreignUserID, friends.Count); + + // First, let's double check that the reported friends are, indeed, friends of that user + // And let's check that the secret matches and the rights + List usersToBeNotified = new List(); + foreach (string uui in friends) + { + UUID localUserID; + string secret = string.Empty, tmp = string.Empty; + if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret)) + { + FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID); + foreach (FriendInfo finfo in friendInfos) + { + if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret) && + (finfo.TheirFlags & (int)FriendRights.CanSeeOnline) != 0 && (finfo.TheirFlags != -1)) + { + // great! + usersToBeNotified.Add(localUserID.ToString()); + } + } + } + } + + // Now, let's find out their status + m_log.DebugFormat("[USER AGENT SERVICE]: GetOnlineFriends: user has {0} local friends with status rights", usersToBeNotified.Count); + + // First, let's send notifications to local users who are online in the home grid + PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray()); + if (friendSessions != null && friendSessions.Length > 0) + { + foreach (PresenceInfo pi in friendSessions) + { + UUID presenceID; + if (UUID.TryParse(pi.UserID, out presenceID)) + online.Add(presenceID); + } + } + + return online; + } } class TravelingAgentInfo diff --git a/OpenSim/Services/Interfaces/IGatekeeperService.cs b/OpenSim/Services/Interfaces/IGatekeeperService.cs index aac8293..fa1ab1c 100644 --- a/OpenSim/Services/Interfaces/IGatekeeperService.cs +++ b/OpenSim/Services/Interfaces/IGatekeeperService.cs @@ -55,6 +55,9 @@ namespace OpenSim.Services.Interfaces void LogoutAgent(UUID userID, UUID sessionID); GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); + void StatusNotification(List friends, UUID userID, bool online); + List GetOnlineFriends(UUID userID, List friends); + bool AgentIsComingHome(UUID sessionID, string thisGridExternalName); bool VerifyAgent(UUID sessionID, string token); bool VerifyClient(UUID sessionID, string reportedIP); diff --git a/OpenSim/Services/Interfaces/ISimulatorSocialService.cs b/OpenSim/Services/Interfaces/ISimulatorSocialService.cs new file mode 100644 index 0000000..0b7aefc --- /dev/null +++ b/OpenSim/Services/Interfaces/ISimulatorSocialService.cs @@ -0,0 +1,40 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using OpenSim.Framework; +using OpenMetaverse; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Services.Interfaces +{ + public interface IFriendsSimConnector + { + bool StatusNotify(UUID userID, UUID friendID, bool online); + } +} diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index f8e8ae2..f56bccd 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -126,6 +126,9 @@ GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService" GridService = "OpenSim.Services.GridService.dll:GridService" GatekeeperService = "OpenSim.Services.HypergridService.dll:GatekeeperService" + PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" + FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" + ;; The interface that local users get when they are in other grids -- cgit v1.1 From e19031849ec2957f7312d7e2417bd8c8da0efc53 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 24 May 2011 09:38:03 -0700 Subject: Added necessary code to drop inventory on hg friends using the profile window, but can't test because this mechanism doesn't seem to work without a profile service. --- .../InventoryAccess/HGInventoryAccessModule.cs | 14 +++-- .../UserManagement/UserManagementModule.cs | 36 +++++++++++- .../Inventory/HGInventoryBroker.cs | 16 ++++++ .../Region/Framework/Interfaces/IUserManagement.cs | 2 + .../Handlers/Hypergrid/UserAgentServerConnector.cs | 32 ++++++++++- .../Hypergrid/UserAgentServiceConnector.cs | 66 +++++++++++++++++++++- .../Services/HypergridService/UserAgentService.cs | 17 ++++++ OpenSim/Services/Interfaces/IGatekeeperService.cs | 1 + OpenSim/Services/LLLoginService/LLLoginService.cs | 30 ++++++---- bin/config-include/StandaloneHypergrid.ini | 2 +- 10 files changed, 196 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 52791cb..429dda7 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -110,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) { string userAssetServer = string.Empty; - if (IsForeignUser(avatarID, out userAssetServer) && m_OutboundPermission) + if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission) { Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); }); } @@ -180,10 +180,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) { string userAssetServer = string.Empty; - if (IsForeignUser(sender, out userAssetServer)) + if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty) m_assMapper.Get(item.AssetID, sender, userAssetServer); - if (IsForeignUser(receiver, out userAssetServer) && m_OutboundPermission) + if (IsForeignUser(receiver, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission) m_assMapper.Post(item.AssetID, receiver, userAssetServer); } @@ -203,9 +203,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) { assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); - assetServerURL = assetServerURL.Trim(new char[] { '/' }); return true; + assetServerURL = assetServerURL.Trim(new char[] { '/' }); } } + else + { + assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI"); + assetServerURL = assetServerURL.Trim(new char[] { '/' }); + } + return true; } return false; diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 795de09..4d073b2 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -35,6 +35,7 @@ using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.Hypergrid; using OpenMetaverse; using log4net; @@ -47,7 +48,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public UUID Id; public string FirstName; public string LastName; - public string ProfileURL; + public string HomeURL; + public Dictionary ServerURLs; } public class UserManagementModule : ISharedRegionModule, IUserManagement @@ -224,6 +226,34 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement return "(hippos)"; } + public string GetUserHomeURL(UUID userID) + { + if (m_UserCache.ContainsKey(userID)) + return m_UserCache[userID].HomeURL; + + return string.Empty; + } + + public string GetUserServerURL(UUID userID, string serverType) + { + if (m_UserCache.ContainsKey(userID)) + { + UserData userdata = m_UserCache[userID]; + if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) + return userdata.ServerURLs[serverType].ToString(); + + if (userdata.HomeURL != string.Empty) + { + UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); + userdata.ServerURLs = uConn.GetServerURLs(userID); + if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) + return userdata.ServerURLs[serverType].ToString(); + } + } + + return string.Empty; + } + public void AddUser(UUID id, string creatorData) { if (m_UserCache.ContainsKey(id)) @@ -249,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement string[] parts = creatorData.Split(';'); if (parts.Length >= 1) { - user.ProfileURL = parts[0]; + user.HomeURL = parts[0]; try { Uri uri = new Uri(parts[0]); @@ -274,7 +304,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement lock (m_UserCache) m_UserCache[id] = user; - m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL); + m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL); } public void AddUser(UUID uuid, string first, string last, string profileURL) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs index 3f63db3..eef60a1 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 private List m_Scenes = new List(); + protected IUserManagement m_UserManagement; + protected IUserManagement UserManagementModule + { + get + { + if (m_UserManagement == null) + m_UserManagement = m_Scenes[0].RequestModuleInterface(); + return m_UserManagement; + } + } + public Type ReplaceableInterface { get { return null; } @@ -206,6 +217,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return; } } + else + { + inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI"); + inventoryURL = inventoryURL.Trim(new char[] { '/' }); + } } } } diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs index 2904ee8..9cac3b0 100644 --- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs +++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs @@ -8,6 +8,8 @@ namespace OpenSim.Region.Framework.Interfaces public interface IUserManagement { string GetUserName(UUID uuid); + string GetUserHomeURL(UUID uuid); + string GetUserServerURL(UUID uuid, string serverType); void AddUser(UUID uuid, string userData); void AddUser(UUID uuid, string firstName, string lastName, string profileURL); } diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index 7a9fb4b..e51fe0b 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -83,6 +83,7 @@ namespace OpenSim.Server.Handlers.Hypergrid server.AddXmlRPCHandler("status_notification", StatusNotification, false); server.AddXmlRPCHandler("get_online_friends", GetOnlineFriends, false); + server.AddXmlRPCHandler("get_server_urls", GetServerURLs, false); server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); } @@ -256,7 +257,6 @@ namespace OpenSim.Server.Handlers.Hypergrid ids.Add(requestData[key].ToString()); } - // let's spawn a thread for this, because it may take a long time... List online = m_HomeUsersService.GetOnlineFriends(userID, ids); if (online.Count > 0) { @@ -266,8 +266,38 @@ namespace OpenSim.Server.Handlers.Hypergrid hash["friend_" + i.ToString()] = id.ToString(); i++; } + } + else + hash["result"] = "No Friends Online"; + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } + + public XmlRpcResponse GetServerURLs(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable hash = new Hashtable(); + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + if (requestData.ContainsKey("userID")) + { + string userID_str = (string)requestData["userID"]; + UUID userID = UUID.Zero; + UUID.TryParse(userID_str, out userID); + + Dictionary serverURLs = m_HomeUsersService.GetServerURLs(userID); + if (serverURLs.Count > 0) + { + foreach (KeyValuePair kvp in serverURLs) + hash["SRV_" + kvp.Key] = kvp.Value.ToString(); } + else + hash["result"] = "No Service URLs"; } XmlRpcResponse response = new XmlRpcResponse(); diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 46d30df..265bacf 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -470,7 +470,7 @@ namespace OpenSim.Services.Connectors.Hypergrid { if (hash == null) { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got null response from {0}! THIS IS BAAAAD", m_ServerURL); + m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL); reason = "Internal error 1"; return online; } @@ -496,6 +496,70 @@ namespace OpenSim.Services.Connectors.Hypergrid return online; } + public Dictionary GetServerURLs(UUID userID) + { + Hashtable hash = new Hashtable(); + hash["userID"] = userID.ToString(); + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("get_server_urls", paramList); + string reason = string.Empty; + + // Send and get reply + Dictionary serverURLs = new Dictionary(); + XmlRpcResponse response = null; + try + { + response = request.Send(m_ServerURL, 10000); + } + catch (Exception e) + { + m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); + reason = "Exception: " + e.Message; + return serverURLs; + } + + if (response.IsFault) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); + reason = "XMLRPC Fault"; + return serverURLs; + } + + hash = (Hashtable)response.Value; + //foreach (Object o in hash) + // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); + try + { + if (hash == null) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetServerURLs Got null response from {0}! THIS IS BAAAAD", m_ServerURL); + reason = "Internal error 1"; + return serverURLs; + } + + // Here is the actual response + foreach (object key in hash.Keys) + { + if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null) + { + string serverType = key.ToString().Substring(4); // remove "SRV_" + serverURLs.Add(serverType, hash[key].ToString()); + } + } + + } + catch (Exception e) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response."); + reason = "Exception: " + e.Message; + } + + return serverURLs; + } + private bool GetBoolResponse(XmlRpcRequest request, out string reason) { //m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURL); diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 0181533..e63f941 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -67,6 +67,7 @@ namespace OpenSim.Services.HypergridService protected static IGatekeeperService m_GatekeeperService; protected static IFriendsService m_FriendsService; protected static IPresenceService m_PresenceService; + protected static IUserAccountService m_UserAccountService; protected static IFriendsSimConnector m_FriendsLocalSimConnector; // standalone, points to HGFriendsModule protected static FriendsSimConnector m_FriendsSimConnector; // grid @@ -102,6 +103,7 @@ namespace OpenSim.Services.HypergridService string gatekeeperService = serverConfig.GetString("GatekeeperService", String.Empty); string friendsService = serverConfig.GetString("FriendsService", String.Empty); string presenceService = serverConfig.GetString("PresenceService", String.Empty); + string userAccountService = serverConfig.GetString("UserAccountService", String.Empty); m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false); @@ -115,6 +117,7 @@ namespace OpenSim.Services.HypergridService m_GatekeeperService = ServerUtils.LoadPlugin(gatekeeperService, args); m_FriendsService = ServerUtils.LoadPlugin(friendsService, args); m_PresenceService = ServerUtils.LoadPlugin(presenceService, args); + m_UserAccountService = ServerUtils.LoadPlugin(userAccountService, args); m_GridName = serverConfig.GetString("ExternalName", string.Empty); if (m_GridName == string.Empty) @@ -457,6 +460,20 @@ namespace OpenSim.Services.HypergridService return online; } + + public Dictionary GetServerURLs(UUID userID) + { + if (m_UserAccountService == null) + { + m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get server URLs because user account service is missing"); + return new Dictionary(); + } + UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero /*!!!*/, userID); + if (account != null) + return account.ServiceURLs; + + return new Dictionary(); + } } class TravelingAgentInfo diff --git a/OpenSim/Services/Interfaces/IGatekeeperService.cs b/OpenSim/Services/Interfaces/IGatekeeperService.cs index fa1ab1c..f1860cc 100644 --- a/OpenSim/Services/Interfaces/IGatekeeperService.cs +++ b/OpenSim/Services/Interfaces/IGatekeeperService.cs @@ -54,6 +54,7 @@ namespace OpenSim.Services.Interfaces bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason); void LogoutAgent(UUID userID, UUID sessionID); GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); + Dictionary GetServerURLs(UUID userID); void StatusNotification(List friends, UUID userID, bool online); List GetOnlineFriends(UUID userID, List friends); diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 2ca2d15..a5a728b 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -804,16 +804,13 @@ namespace OpenSim.Services.LLLoginService // Old style: get the service keys from the DB foreach (KeyValuePair kvp in account.ServiceURLs) { - if (kvp.Value == null || (kvp.Value != null && kvp.Value.ToString() == string.Empty)) - { - aCircuit.ServiceURLs[kvp.Key] = m_LoginServerConfig.GetString(kvp.Key, string.Empty); - } - else + if (kvp.Value != null) { aCircuit.ServiceURLs[kvp.Key] = kvp.Value; + + if (!aCircuit.ServiceURLs[kvp.Key].ToString().EndsWith("/")) + aCircuit.ServiceURLs[kvp.Key] = aCircuit.ServiceURLs[kvp.Key] + "/"; } - if (!aCircuit.ServiceURLs[kvp.Key].ToString().EndsWith("/")) - aCircuit.ServiceURLs[kvp.Key] = aCircuit.ServiceURLs[kvp.Key] + "/"; } // New style: service keys start with SRV_; override the previous @@ -821,16 +818,29 @@ namespace OpenSim.Services.LLLoginService if (keys.Length > 0) { + bool newUrls = false; IEnumerable serviceKeys = keys.Where(value => value.StartsWith("SRV_")); foreach (string serviceKey in serviceKeys) { string keyName = serviceKey.Replace("SRV_", ""); - aCircuit.ServiceURLs[keyName] = m_LoginServerConfig.GetString(serviceKey, string.Empty); - if (!aCircuit.ServiceURLs[keyName].ToString().EndsWith("/")) - aCircuit.ServiceURLs[keyName] = aCircuit.ServiceURLs[keyName] + "/"; + string keyValue = m_LoginServerConfig.GetString(serviceKey, string.Empty); + if (!keyValue.EndsWith("/")) + keyValue = keyValue + "/"; + + if (!account.ServiceURLs.ContainsKey(keyName) || (account.ServiceURLs.ContainsKey(keyName) && account.ServiceURLs[keyName] != keyValue)) + { + account.ServiceURLs[keyName] = keyValue; + newUrls = true; + } + aCircuit.ServiceURLs[keyName] = keyValue; m_log.DebugFormat("[LLLOGIN SERVICE]: found new key {0} {1}", keyName, aCircuit.ServiceURLs[keyName]); } + + // The grid operator decided to override the defaults in the + // [LoginService] configuration. Let's store the correct ones. + if (newUrls) + m_UserAccountService.StoreUserAccount(account); } } diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index f56bccd..6cd24b0 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -128,7 +128,7 @@ GatekeeperService = "OpenSim.Services.HypergridService.dll:GatekeeperService" PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" - + UserAccountService = "OpenSim.Services.UserAccountService.dll:UserAccountService" ;; The interface that local users get when they are in other grids -- cgit v1.1 From 5c2168cae758ae19367f4c2f5a02713e74fc0912 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 25 May 2011 12:32:21 -0700 Subject: HG: Instant Message working. Tested on HG standalones only. Needs a lot more testing. --- .../InstantMessage/HGMessageTransferModule.cs | 268 ++++++++++++++++++ .../Hypergrid/InstantMessageServerConnector.cs | 280 +++++++++++++++++++ .../Handlers/Hypergrid/UserAgentServerConnector.cs | 48 ++++ .../Hypergrid/UserAgentServiceConnector.cs | 58 ++++ .../InstantMessageServiceConnector.cs | 129 +++++++++ .../HypergridService/HGInstantMessageService.cs | 311 +++++++++++++++++++++ .../Services/HypergridService/UserAgentService.cs | 11 + OpenSim/Services/Interfaces/IGatekeeperService.cs | 8 + .../Services/Interfaces/ISimulatorSocialService.cs | 5 + bin/config-include/StandaloneHypergrid.ini | 10 + 10 files changed, 1128 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs create mode 100644 OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs create mode 100644 OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs create mode 100644 OpenSim/Services/HypergridService/HGInstantMessageService.cs diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs new file mode 100644 index 0000000..9ba4e49 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -0,0 +1,268 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using log4net; +using Nini.Config; +using Nwc.XmlRpc; +using Mono.Addins; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.InstantMessage; +using OpenSim.Services.Connectors.Hypergrid; +using OpenSim.Server.Handlers.Hypergrid; + +namespace OpenSim.Region.CoreModules.Avatar.InstantMessage +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected bool m_Enabled = false; + protected List m_Scenes = new List(); + + protected IInstantMessage m_IMService; + protected Dictionary m_UserLocationMap = new Dictionary(); + + public event UndeliveredMessage OnUndeliveredMessage; + + IUserManagement m_uMan; + IUserManagement UserManagementModule + { + get + { + if (m_uMan == null) + m_uMan = m_Scenes[0].RequestModuleInterface(); + return m_uMan; + } + } + + public virtual void Initialise(IConfigSource config) + { + IConfig cnf = config.Configs["Messaging"]; + if (cnf != null && cnf.GetString( + "MessageTransferModule", "MessageTransferModule") != Name) + { + m_log.Debug("[HG MESSAGE TRANSFER]: Disabled by configuration"); + return; + } + + InstantMessageServerConnector imServer = new InstantMessageServerConnector(config, MainServer.Instance, this); + m_IMService = imServer.GetService(); + m_Enabled = true; + } + + public virtual void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock (m_Scenes) + { + m_log.DebugFormat("[HG MESSAGE TRANSFER]: Message transfer module {0} active", Name); + scene.RegisterModuleInterface(this); + m_Scenes.Add(scene); + } + } + + public virtual void PostInitialise() + { + if (!m_Enabled) + return; + + } + + public virtual void RegionLoaded(Scene scene) + { + } + + public virtual void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock (m_Scenes) + { + m_Scenes.Remove(scene); + } + } + + public virtual void Close() + { + } + + public virtual string Name + { + get { return "HGMessageTransferModule"; } + } + + public virtual Type ReplaceableInterface + { + get { return null; } + } + + public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result) + { + UUID toAgentID = new UUID(im.toAgentID); + + // Try root avatar only first + foreach (Scene scene in m_Scenes) + { + if (scene.Entities.ContainsKey(toAgentID) && + scene.Entities[toAgentID] is ScenePresence) + { +// m_log.DebugFormat( +// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}", +// toAgentID.ToString(), scene.RegionInfo.RegionName); + + ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; + if (!user.IsChildAgent) + { + // Local message +// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID); + user.ControllingClient.SendInstantMessage(im); + + // Message sent + result(true); + return; + } + } + } + + // try child avatar second + foreach (Scene scene in m_Scenes) + { +// m_log.DebugFormat( +// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); + + if (scene.Entities.ContainsKey(toAgentID) && + scene.Entities[toAgentID] is ScenePresence) + { + // Local message + ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; + +// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID); + user.ControllingClient.SendInstantMessage(im); + + // Message sent + result(true); + return; + } + } + +// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); + // Is the user a local user? + UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID); + string url = string.Empty; + PresenceInfo upd; + if (account == null) // foreign user + url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI"); + + Util.FireAndForget(delegate + { + bool success = m_IMService.OutgoingInstantMessage(im, url); + result(success); + }); + + return; + } + + protected bool SendIMToScene(GridInstantMessage gim, UUID toAgentID) + { + bool successful = false; + foreach (Scene scene in m_Scenes) + { + if (scene.Entities.ContainsKey(toAgentID) && + scene.Entities[toAgentID] is ScenePresence) + { + ScenePresence user = + (ScenePresence)scene.Entities[toAgentID]; + + if (!user.IsChildAgent) + { + scene.EventManager.TriggerIncomingInstantMessage(gim); + successful = true; + } + } + } + if (!successful) + { + // If the message can't be delivered to an agent, it + // is likely to be a group IM. On a group IM, the + // imSessionID = toAgentID = group id. Raise the + // unhandled IM event to give the groups module + // a chance to pick it up. We raise that in a random + // scene, since the groups module is shared. + // + m_Scenes[0].EventManager.TriggerUnhandledInstantMessage(gim); + } + + return successful; + } + + protected void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result) + { + UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage; + + // If this event has handlers, then an IM from an agent will be + // considered delivered. This will suppress the error message. + // + if (handlerUndeliveredMessage != null) + { + handlerUndeliveredMessage(im); + if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) + result(true); + else + result(false); + return; + } + + //m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable"); + result(false); + } + + #region IInstantMessageSimConnector + public bool SendInstantMessage(GridInstantMessage im) + { + //m_log.DebugFormat("[XXX] Hook SendInstantMessage {0}", im.message); + UUID agentID = new UUID(im.toAgentID); + return SendIMToScene(im, agentID); + } + #endregion + + + } +} diff --git a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs new file mode 100644 index 0000000..138313a --- /dev/null +++ b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs @@ -0,0 +1,280 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net; +using System.Reflection; + +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using log4net; +using Nwc.XmlRpc; +using OpenMetaverse; + +namespace OpenSim.Server.Handlers.Hypergrid +{ + public class InstantMessageServerConnector : ServiceConnector + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private IInstantMessage m_IMService; + + public InstantMessageServerConnector(IConfigSource config, IHttpServer server) : + this(config, server, null) + { + } + + public InstantMessageServerConnector(IConfigSource config, IHttpServer server, IInstantMessageSimConnector simConnector) : + base(config, server, String.Empty) + { + IConfig gridConfig = config.Configs["HGInstantMessageService"]; + if (gridConfig != null) + { + string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty); + + Object[] args = new Object[] { config, simConnector }; + m_IMService = ServerUtils.LoadPlugin(serviceDll, args); + } + if (m_IMService == null) + throw new Exception("InstantMessage server connector cannot proceed because of missing service"); + + MainServer.Instance.AddXmlRPCHandler("grid_instant_message", ProcessInstantMessage, false); + + } + + public IInstantMessage GetService() + { + return m_IMService; + } + + protected virtual XmlRpcResponse ProcessInstantMessage(XmlRpcRequest request, IPEndPoint remoteClient) + { + bool successful = false; + + try + { + // various rational defaults + UUID fromAgentID = UUID.Zero; + UUID toAgentID = UUID.Zero; + UUID imSessionID = UUID.Zero; + uint timestamp = 0; + string fromAgentName = ""; + string message = ""; + byte dialog = (byte)0; + bool fromGroup = false; + byte offline = (byte)0; + uint ParentEstateID = 0; + Vector3 Position = Vector3.Zero; + UUID RegionID = UUID.Zero; + byte[] binaryBucket = new byte[0]; + + float pos_x = 0; + float pos_y = 0; + float pos_z = 0; + //m_log.Info("Processing IM"); + + + Hashtable requestData = (Hashtable)request.Params[0]; + // Check if it's got all the data + if (requestData.ContainsKey("from_agent_id") + && requestData.ContainsKey("to_agent_id") && requestData.ContainsKey("im_session_id") + && requestData.ContainsKey("timestamp") && requestData.ContainsKey("from_agent_name") + && requestData.ContainsKey("message") && requestData.ContainsKey("dialog") + && requestData.ContainsKey("from_group") + && requestData.ContainsKey("offline") && requestData.ContainsKey("parent_estate_id") + && requestData.ContainsKey("position_x") && requestData.ContainsKey("position_y") + && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id") + && requestData.ContainsKey("binary_bucket")) + { + // Do the easy way of validating the UUIDs + UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID); + UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); + UUID.TryParse((string)requestData["im_session_id"], out imSessionID); + UUID.TryParse((string)requestData["region_id"], out RegionID); + + try + { + timestamp = (uint)Convert.ToInt32((string)requestData["timestamp"]); + } + catch (ArgumentException) + { + } + catch (FormatException) + { + } + catch (OverflowException) + { + } + + fromAgentName = (string)requestData["from_agent_name"]; + message = (string)requestData["message"]; + if (message == null) + message = string.Empty; + + // Bytes don't transfer well over XMLRPC, so, we Base64 Encode them. + string requestData1 = (string)requestData["dialog"]; + if (string.IsNullOrEmpty(requestData1)) + { + dialog = 0; + } + else + { + byte[] dialogdata = Convert.FromBase64String(requestData1); + dialog = dialogdata[0]; + } + + if ((string)requestData["from_group"] == "TRUE") + fromGroup = true; + + string requestData2 = (string)requestData["offline"]; + if (String.IsNullOrEmpty(requestData2)) + { + offline = 0; + } + else + { + byte[] offlinedata = Convert.FromBase64String(requestData2); + offline = offlinedata[0]; + } + + try + { + ParentEstateID = (uint)Convert.ToInt32((string)requestData["parent_estate_id"]); + } + catch (ArgumentException) + { + } + catch (FormatException) + { + } + catch (OverflowException) + { + } + + try + { + pos_x = (uint)Convert.ToInt32((string)requestData["position_x"]); + } + catch (ArgumentException) + { + } + catch (FormatException) + { + } + catch (OverflowException) + { + } + try + { + pos_y = (uint)Convert.ToInt32((string)requestData["position_y"]); + } + catch (ArgumentException) + { + } + catch (FormatException) + { + } + catch (OverflowException) + { + } + try + { + pos_z = (uint)Convert.ToInt32((string)requestData["position_z"]); + } + catch (ArgumentException) + { + } + catch (FormatException) + { + } + catch (OverflowException) + { + } + + Position = new Vector3(pos_x, pos_y, pos_z); + + string requestData3 = (string)requestData["binary_bucket"]; + if (string.IsNullOrEmpty(requestData3)) + { + binaryBucket = new byte[0]; + } + else + { + binaryBucket = Convert.FromBase64String(requestData3); + } + + // Create a New GridInstantMessageObject the the data + GridInstantMessage gim = new GridInstantMessage(); + gim.fromAgentID = fromAgentID.Guid; + gim.fromAgentName = fromAgentName; + gim.fromGroup = fromGroup; + gim.imSessionID = imSessionID.Guid; + gim.RegionID = UUID.Zero.Guid; // RegionID.Guid; + gim.timestamp = timestamp; + gim.toAgentID = toAgentID.Guid; + gim.message = message; + gim.dialog = dialog; + gim.offline = offline; + gim.ParentEstateID = ParentEstateID; + gim.Position = Position; + gim.binaryBucket = binaryBucket; + + successful = m_IMService.IncomingInstantMessage(gim); + + } + } + catch (Exception e) + { + m_log.Error("[INSTANT MESSAGE]: Caught unexpected exception:", e); + successful = false; + } + + //Send response back to region calling if it was successful + // calling region uses this to know when to look up a user's location again. + XmlRpcResponse resp = new XmlRpcResponse(); + Hashtable respdata = new Hashtable(); + if (successful) + respdata["success"] = "TRUE"; + else + respdata["success"] = "FALSE"; + resp.Value = respdata; + + return resp; + } + + } +} diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index e51fe0b..942d960 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -52,6 +52,7 @@ namespace OpenSim.Server.Handlers.Hypergrid // MethodBase.GetCurrentMethod().DeclaringType); private IUserAgentService m_HomeUsersService; + private string[] m_AuthorizedCallers; public UserAgentServerConnector(IConfigSource config, IHttpServer server) : this(config, server, null) @@ -75,6 +76,10 @@ namespace OpenSim.Server.Handlers.Hypergrid string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1"); bool proxy = gridConfig.GetBoolean("HasProxy", false); + string csv = gridConfig.GetString("AuthorizedCallers", "127.0.0.1"); + csv = csv.Replace(" ", ""); + m_AuthorizedCallers = csv.Split(','); + server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false); server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false); server.AddXmlRPCHandler("verify_agent", VerifyAgent, false); @@ -85,6 +90,8 @@ namespace OpenSim.Server.Handlers.Hypergrid server.AddXmlRPCHandler("get_online_friends", GetOnlineFriends, false); server.AddXmlRPCHandler("get_server_urls", GetServerURLs, false); + server.AddXmlRPCHandler("locate_user", LocateUser, false); + server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); } @@ -306,5 +313,46 @@ namespace OpenSim.Server.Handlers.Hypergrid } + /// + /// Locates the user. + /// This is a sensitive operation, only authorized IP addresses can perform it. + /// + /// + /// + /// + public XmlRpcResponse LocateUser(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable hash = new Hashtable(); + + bool authorized = false; + foreach (string s in m_AuthorizedCallers) + if (s == remoteClient.Address.ToString()) + { + authorized = true; + break; + } + + if (authorized) + { + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + if (requestData.ContainsKey("userID")) + { + string userID_str = (string)requestData["userID"]; + UUID userID = UUID.Zero; + UUID.TryParse(userID_str, out userID); + + string url = m_HomeUsersService.LocateUser(userID); + if (url != string.Empty) + hash["URL"] = url; + } + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } } } diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 265bacf..50036b3 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -560,6 +560,64 @@ namespace OpenSim.Services.Connectors.Hypergrid return serverURLs; } + public string LocateUser(UUID userID) + { + Hashtable hash = new Hashtable(); + hash["userID"] = userID.ToString(); + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("locate_user", paramList); + string reason = string.Empty; + + // Send and get reply + string url = string.Empty; + XmlRpcResponse response = null; + try + { + response = request.Send(m_ServerURL, 10000); + } + catch (Exception e) + { + m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); + reason = "Exception: " + e.Message; + return url; + } + + if (response.IsFault) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); + reason = "XMLRPC Fault"; + return url; + } + + hash = (Hashtable)response.Value; + //foreach (Object o in hash) + // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); + try + { + if (hash == null) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: LocateUser Got null response from {0}! THIS IS BAAAAD", m_ServerURL); + reason = "Internal error 1"; + return url; + } + + // Here's the actual response + if (hash.ContainsKey("URL")) + url = hash["URL"].ToString(); + + } + catch (Exception e) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response."); + reason = "Exception: " + e.Message; + } + + return url; + } + private bool GetBoolResponse(XmlRpcRequest request, out string reason) { //m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURL); diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs new file mode 100644 index 0000000..65ee7c7 --- /dev/null +++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs @@ -0,0 +1,129 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net; +using System.Reflection; + +using OpenMetaverse; +using Nwc.XmlRpc; +using log4net; + +using OpenSim.Framework; + +namespace OpenSim.Services.Connectors.InstantMessage +{ + public class InstantMessageServiceConnector + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// This actually does the XMLRPC Request + /// + /// URL we pull the data out of to send the request to + /// The Instant Message + /// Bool if the message was successfully delivered at the other side. + public static bool SendInstantMessage(string url, GridInstantMessage im) + { + Hashtable xmlrpcdata = ConvertGridInstantMessageToXMLRPC(im); + xmlrpcdata["region_handle"] = 0; + + ArrayList SendParams = new ArrayList(); + SendParams.Add(xmlrpcdata); + XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams); + try + { + + XmlRpcResponse GridResp = GridReq.Send(url, 3000); + + Hashtable responseData = (Hashtable)GridResp.Value; + + if (responseData.ContainsKey("success")) + { + if ((string)responseData["success"] == "TRUE") + { + m_log.DebugFormat("[XXX] Success"); + return true; + } + else + { + m_log.DebugFormat("[XXX] Fail"); + return false; + } + } + else + { + return false; + } + } + catch (WebException e) + { + m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0} the host didn't respond " + e.ToString(), url); + } + + return false; + } + + /// + /// Takes a GridInstantMessage and converts it into a Hashtable for XMLRPC + /// + /// The GridInstantMessage object + /// Hashtable containing the XMLRPC request + protected static Hashtable ConvertGridInstantMessageToXMLRPC(GridInstantMessage msg) + { + Hashtable gim = new Hashtable(); + gim["from_agent_id"] = msg.fromAgentID.ToString(); + // Kept for compatibility + gim["from_agent_session"] = UUID.Zero.ToString(); + gim["to_agent_id"] = msg.toAgentID.ToString(); + gim["im_session_id"] = msg.imSessionID.ToString(); + gim["timestamp"] = msg.timestamp.ToString(); + gim["from_agent_name"] = msg.fromAgentName; + gim["message"] = msg.message; + byte[] dialogdata = new byte[1]; dialogdata[0] = msg.dialog; + gim["dialog"] = Convert.ToBase64String(dialogdata, Base64FormattingOptions.None); + + if (msg.fromGroup) + gim["from_group"] = "TRUE"; + else + gim["from_group"] = "FALSE"; + byte[] offlinedata = new byte[1]; offlinedata[0] = msg.offline; + gim["offline"] = Convert.ToBase64String(offlinedata, Base64FormattingOptions.None); + gim["parent_estate_id"] = msg.ParentEstateID.ToString(); + gim["position_x"] = msg.Position.X.ToString(); + gim["position_y"] = msg.Position.Y.ToString(); + gim["position_z"] = msg.Position.Z.ToString(); + gim["region_id"] = msg.RegionID.ToString(); + gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None); + return gim; + } + + } +} diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs new file mode 100644 index 0000000..6178ca1 --- /dev/null +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -0,0 +1,311 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; + +using OpenSim.Framework; +using OpenSim.Services.Connectors.Friends; +using OpenSim.Services.Connectors.Hypergrid; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.InstantMessage; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Server.Base; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; + +using OpenMetaverse; +using log4net; +using Nini.Config; + +namespace OpenSim.Services.HypergridService +{ + /// + /// Inter-grid IM + /// + public class HGInstantMessageService : IInstantMessage + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours + + static bool m_Initialized = false; + + protected static IGridService m_GridService; + protected static IPresenceService m_PresenceService; + protected static IUserAgentService m_UserAgentService; + + protected static IInstantMessageSimConnector m_IMSimConnector; + + protected Dictionary m_UserLocationMap = new Dictionary(); + private ExpiringCache m_RegionCache; + + public HGInstantMessageService(IConfigSource config) + : this(config, null) + { + } + + public HGInstantMessageService(IConfigSource config, IInstantMessageSimConnector imConnector) + { + if (imConnector != null) + m_IMSimConnector = imConnector; + + if (!m_Initialized) + { + m_Initialized = true; + + m_log.DebugFormat("[HG IM SERVICE]: Starting..."); + + IConfig serverConfig = config.Configs["HGInstantMessageService"]; + if (serverConfig == null) + throw new Exception(String.Format("No section HGInstantMessageService in config file")); + + string gridService = serverConfig.GetString("GridService", String.Empty); + string presenceService = serverConfig.GetString("PresenceService", String.Empty); + string userAgentService = serverConfig.GetString("UserAgentService", String.Empty); + + if (gridService == string.Empty || presenceService == string.Empty) + throw new Exception(String.Format("Incomplete specifications, InstantMessage Service cannot function.")); + + Object[] args = new Object[] { config }; + m_GridService = ServerUtils.LoadPlugin(gridService, args); + m_PresenceService = ServerUtils.LoadPlugin(presenceService, args); + m_UserAgentService = ServerUtils.LoadPlugin(userAgentService, args); + + m_RegionCache = new ExpiringCache(); + + } + } + + public bool IncomingInstantMessage(GridInstantMessage im) + { + m_log.DebugFormat("[HG IM SERVICE]: Received message {0} from {1} to {2}", im.message, im.fromAgentID, im.toAgentID); + UUID toAgentID = new UUID(im.toAgentID); + + if (m_IMSimConnector != null) + { + m_log.DebugFormat("[XXX] SendIMToRegion local im connector"); + return m_IMSimConnector.SendInstantMessage(im); + } + else + return TrySendInstantMessage(im, "", true); + } + + public bool OutgoingInstantMessage(GridInstantMessage im, string url) + { + m_log.DebugFormat("[HG IM SERVICE]: Sending message {0} from {1} to {2}@{3}", im.message, im.fromAgentID, im.toAgentID, url); + if (url != string.Empty) + return TrySendInstantMessage(im, url, true); + else + { + PresenceInfo upd = new PresenceInfo(); + upd.RegionID = UUID.Zero; + return TrySendInstantMessage(im, upd, true); + } + } + + protected bool TrySendInstantMessage(GridInstantMessage im, object previousLocation, bool firstTime) + { + UUID toAgentID = new UUID(im.toAgentID); + + PresenceInfo upd = null; + string url = string.Empty; + + bool lookupAgent = false; + + lock (m_UserLocationMap) + { + if (m_UserLocationMap.ContainsKey(toAgentID)) + { + object o = m_UserLocationMap[toAgentID]; + if (o is PresenceInfo) + upd = (PresenceInfo)o; + else if (o is string) + url = (string)o; + + // We need to compare the current location with the previous + // or the recursive loop will never end because it will never try to lookup the agent again + if (!firstTime) + { + lookupAgent = true; + } + } + else + { + lookupAgent = true; + } + } + + m_log.DebugFormat("[XXX] Neeed lookup ? {0}", (lookupAgent ? "yes" : "no")); + + // Are we needing to look-up an agent? + if (lookupAgent) + { + bool isPresent = false; + // Non-cached user agent lookup. + PresenceInfo[] presences = m_PresenceService.GetAgents(new string[] { toAgentID.ToString() }); + if (presences != null && presences.Length > 0) + { + foreach (PresenceInfo p in presences) + { + if (p.RegionID != UUID.Zero) + { + upd = p; + break; + } + else + isPresent = true; + } + } + + if (upd == null && isPresent) + { + // Let's check with the UAS if the user is elsewhere + url = m_UserAgentService.LocateUser(toAgentID); + } + + if (upd != null || url != string.Empty) + { + // check if we've tried this before.. + // This is one way to end the recursive loop + // + if (!firstTime && ((previousLocation is PresenceInfo && upd != null && upd.RegionID == ((PresenceInfo)previousLocation).RegionID) || + (previousLocation is string && previousLocation.Equals(url)))) + { + // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); + m_log.DebugFormat("[XXX] Fail 1 {0} {1}", previousLocation, url); + + return false; + } + } + } + + if (upd != null) + { + // ok, the user is around somewhere. Let's send back the reply with "success" + // even though the IM may still fail. Just don't keep the caller waiting for + // the entire time we're trying to deliver the IM + return SendIMToRegion(upd, im, toAgentID); + } + else if (url != string.Empty) + { + // ok, the user is around somewhere. Let's send back the reply with "success" + // even though the IM may still fail. Just don't keep the caller waiting for + // the entire time we're trying to deliver the IM + return ForwardIMToGrid(url, im, toAgentID); + } + else if (firstTime && previousLocation is string && (string)previousLocation != string.Empty) + { + return ForwardIMToGrid((string)previousLocation, im, toAgentID); + } + else + m_log.DebugFormat("[HG IM SERVICE]: Unable to locate user {0}", toAgentID); + return false; + } + + bool SendIMToRegion(PresenceInfo upd, GridInstantMessage im, UUID toAgentID) + { + bool imresult = false; + GridRegion reginfo = null; + if (!m_RegionCache.TryGetValue(upd.RegionID, out reginfo)) + { + reginfo = m_GridService.GetRegionByUUID(UUID.Zero /*!!!*/, upd.RegionID); + if (reginfo != null) + m_RegionCache.AddOrUpdate(upd.RegionID, reginfo, CACHE_EXPIRATION_SECONDS); + } + + if (reginfo != null) + imresult = InstantMessageServiceConnector.SendInstantMessage(reginfo.ServerURI, im); + else + return false; + + if (imresult) + { + // IM delivery successful, so store the Agent's location in our local cache. + lock (m_UserLocationMap) + { + if (m_UserLocationMap.ContainsKey(toAgentID)) + { + m_UserLocationMap[toAgentID] = upd; + } + else + { + m_UserLocationMap.Add(toAgentID, upd); + } + } + return true; + } + else + { + // try again, but lookup user this time. + // Warning, this must call the Async version + // of this method or we'll be making thousands of threads + // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync + // The version that spawns the thread is SendGridInstantMessageViaXMLRPC + + // This is recursive!!!!! + return TrySendInstantMessage(im, upd, false); + } + } + + bool ForwardIMToGrid(string url, GridInstantMessage im, UUID toAgentID) + { + if (InstantMessageServiceConnector.SendInstantMessage(url, im)) + { + // IM delivery successful, so store the Agent's location in our local cache. + lock (m_UserLocationMap) + { + if (m_UserLocationMap.ContainsKey(toAgentID)) + { + m_UserLocationMap[toAgentID] = url; + } + else + { + m_UserLocationMap.Add(toAgentID, url); + } + } + + return true; + } + else + { + // try again, but lookup user this time. + // Warning, this must call the Async version + // of this method or we'll be making thousands of threads + // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync + // The version that spawns the thread is SendGridInstantMessageViaXMLRPC + + // This is recursive!!!!! + return TrySendInstantMessage(im, url, false); + } + + } + } +} diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index e63f941..59ad043 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -474,6 +474,17 @@ namespace OpenSim.Services.HypergridService return new Dictionary(); } + + public string LocateUser(UUID userID) + { + foreach (TravelingAgentInfo t in m_TravelingAgents.Values) + { + if (t.UserID == userID) + return t.GridExternalName; + } + + return string.Empty; + } } class TravelingAgentInfo diff --git a/OpenSim/Services/Interfaces/IGatekeeperService.cs b/OpenSim/Services/Interfaces/IGatekeeperService.cs index f1860cc..ffab9ea 100644 --- a/OpenSim/Services/Interfaces/IGatekeeperService.cs +++ b/OpenSim/Services/Interfaces/IGatekeeperService.cs @@ -56,6 +56,8 @@ namespace OpenSim.Services.Interfaces GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); Dictionary GetServerURLs(UUID userID); + string LocateUser(UUID userID); + void StatusNotification(List friends, UUID userID, bool online); List GetOnlineFriends(UUID userID, List friends); @@ -63,4 +65,10 @@ namespace OpenSim.Services.Interfaces bool VerifyAgent(UUID sessionID, string token); bool VerifyClient(UUID sessionID, string reportedIP); } + + public interface IInstantMessage + { + bool IncomingInstantMessage(GridInstantMessage im); + bool OutgoingInstantMessage(GridInstantMessage im, string url); + } } diff --git a/OpenSim/Services/Interfaces/ISimulatorSocialService.cs b/OpenSim/Services/Interfaces/ISimulatorSocialService.cs index 0b7aefc..df9e7e7 100644 --- a/OpenSim/Services/Interfaces/ISimulatorSocialService.cs +++ b/OpenSim/Services/Interfaces/ISimulatorSocialService.cs @@ -37,4 +37,9 @@ namespace OpenSim.Services.Interfaces { bool StatusNotify(UUID userID, UUID friendID, bool online); } + + public interface IInstantMessageSimConnector + { + bool SendInstantMessage(GridInstantMessage im); + } } diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 6cd24b0..cd2d7a7 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -32,6 +32,9 @@ AuthenticationServiceInConnector = true SimulationServiceInConnector = true +[Messaging] + MessageTransferModule = HGMessageTransferModule + [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService" @@ -148,6 +151,13 @@ LocalServiceModule = "OpenSim.Services.FriendsService.dll:FriendsService" UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" +[HGInstantMessageService] + LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService" + GridService = "OpenSim.Services.GridService.dll:GridService" + PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" + UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" + + ;; This should always be the very last thing on this file [Includes] Include-Common = "config-include/StandaloneCommon.ini" -- cgit v1.1 From 587b17e23b3919377f4f1af08e2a59e8eec69ef6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 25 May 2011 12:37:37 -0700 Subject: HG: Renamed, shuffled some interfaces around. Move them all to IHypergridServices. --- OpenSim/Services/Interfaces/IGatekeeperService.cs | 74 ------------------- OpenSim/Services/Interfaces/IHypergridServices.cs | 83 ++++++++++++++++++++++ .../Services/Interfaces/ISimulatorSocialService.cs | 45 ------------ 3 files changed, 83 insertions(+), 119 deletions(-) delete mode 100644 OpenSim/Services/Interfaces/IGatekeeperService.cs create mode 100644 OpenSim/Services/Interfaces/IHypergridServices.cs delete mode 100644 OpenSim/Services/Interfaces/ISimulatorSocialService.cs diff --git a/OpenSim/Services/Interfaces/IGatekeeperService.cs b/OpenSim/Services/Interfaces/IGatekeeperService.cs deleted file mode 100644 index ffab9ea..0000000 --- a/OpenSim/Services/Interfaces/IGatekeeperService.cs +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Net; -using System.Collections.Generic; - -using OpenSim.Framework; -using OpenMetaverse; - -namespace OpenSim.Services.Interfaces -{ - public interface IGatekeeperService - { - bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason); - GridRegion GetHyperlinkRegion(UUID regionID); - - bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason); - - } - - /// - /// HG1.5 only - /// - public interface IUserAgentService - { - // called by login service only - bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason); - // called by simulators - bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason); - void LogoutAgent(UUID userID, UUID sessionID); - GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); - Dictionary GetServerURLs(UUID userID); - - string LocateUser(UUID userID); - - void StatusNotification(List friends, UUID userID, bool online); - List GetOnlineFriends(UUID userID, List friends); - - bool AgentIsComingHome(UUID sessionID, string thisGridExternalName); - bool VerifyAgent(UUID sessionID, string token); - bool VerifyClient(UUID sessionID, string reportedIP); - } - - public interface IInstantMessage - { - bool IncomingInstantMessage(GridInstantMessage im); - bool OutgoingInstantMessage(GridInstantMessage im, string url); - } -} diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs new file mode 100644 index 0000000..3ab6d4f --- /dev/null +++ b/OpenSim/Services/Interfaces/IHypergridServices.cs @@ -0,0 +1,83 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Net; +using System.Collections.Generic; + +using OpenSim.Framework; +using OpenMetaverse; + +namespace OpenSim.Services.Interfaces +{ + public interface IGatekeeperService + { + bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason); + GridRegion GetHyperlinkRegion(UUID regionID); + + bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason); + + } + + /// + /// HG1.5 only + /// + public interface IUserAgentService + { + // called by login service only + bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason); + // called by simulators + bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason); + void LogoutAgent(UUID userID, UUID sessionID); + GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); + Dictionary GetServerURLs(UUID userID); + + string LocateUser(UUID userID); + + void StatusNotification(List friends, UUID userID, bool online); + List GetOnlineFriends(UUID userID, List friends); + + bool AgentIsComingHome(UUID sessionID, string thisGridExternalName); + bool VerifyAgent(UUID sessionID, string token); + bool VerifyClient(UUID sessionID, string reportedIP); + } + + public interface IInstantMessage + { + bool IncomingInstantMessage(GridInstantMessage im); + bool OutgoingInstantMessage(GridInstantMessage im, string url); + } + public interface IFriendsSimConnector + { + bool StatusNotify(UUID userID, UUID friendID, bool online); + } + + public interface IInstantMessageSimConnector + { + bool SendInstantMessage(GridInstantMessage im); + } +} diff --git a/OpenSim/Services/Interfaces/ISimulatorSocialService.cs b/OpenSim/Services/Interfaces/ISimulatorSocialService.cs deleted file mode 100644 index df9e7e7..0000000 --- a/OpenSim/Services/Interfaces/ISimulatorSocialService.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using OpenSim.Framework; -using OpenMetaverse; - -using GridRegion = OpenSim.Services.Interfaces.GridRegion; - -namespace OpenSim.Services.Interfaces -{ - public interface IFriendsSimConnector - { - bool StatusNotify(UUID userID, UUID friendID, bool online); - } - - public interface IInstantMessageSimConnector - { - bool SendInstantMessage(GridInstantMessage im); - } -} -- cgit v1.1 From 0c58a9e68074f3593920dc9f2356bbed96416497 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 26 May 2011 10:04:48 -0700 Subject: HG IM in grid mode working fairly well. Unknown target user references looked back in source user's User Agent service. --- .../InstantMessage/HGMessageTransferModule.cs | 74 ++++++++++++++++++++++ OpenSim/Server/Base/ServerUtils.cs | 4 ++ .../Handlers/Hypergrid/UserAgentServerConnector.cs | 57 +++++++++++++++-- .../Hypergrid/UserAgentServiceConnector.cs | 61 ++++++++++++++++++ .../InstantMessageServiceConnector.cs | 1 + .../HypergridService/HGInstantMessageService.cs | 22 ++++--- .../Services/HypergridService/UserAgentService.cs | 24 +++++++ OpenSim/Services/Interfaces/IHypergridServices.cs | 3 + bin/Robust.HG.ini.example | 18 +++++- bin/config-include/GridCommon.ini.example | 6 ++ bin/config-include/GridHypergrid.ini | 11 ++++ 11 files changed, 264 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index 9ba4e49..ed02119 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -194,6 +194,22 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage Util.FireAndForget(delegate { bool success = m_IMService.OutgoingInstantMessage(im, url); + if (!success && account == null) + { + // One last chance + string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID); + m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI); + if (recipientUUI != string.Empty) + { + UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty; + if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret)) + { + success = m_IMService.OutgoingInstantMessage(im, u); + if (success) + UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last); + } + } + } result(success); }); @@ -254,6 +270,64 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage result(false); } + private string TryGetRecipientUUI(UUID fromAgent, UUID toAgent) + { + // Let's call back the fromAgent's user agent service + // Maybe that service knows about the toAgent + IClientAPI client = LocateClientObject(fromAgent); + if (client != null) + { + AgentCircuitData circuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.AgentId); + if (circuit != null) + { + if (circuit.ServiceURLs.ContainsKey("HomeURI")) + { + string uasURL = circuit.ServiceURLs["HomeURI"].ToString(); + m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL); + UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL); + return uasConn.GetUUI(fromAgent, toAgent); + } + } + } + + return string.Empty; + } + + + /// + /// Find the scene for an agent + /// + private Scene GetClientScene(UUID agentId) + { + lock (m_Scenes) + { + foreach (Scene scene in m_Scenes) + { + ScenePresence presence = scene.GetScenePresence(agentId); + if (presence != null && !presence.IsChildAgent) + return scene; + } + } + + return null; + } + + /// + /// Find the client for a ID + /// + public IClientAPI LocateClientObject(UUID agentID) + { + Scene scene = GetClientScene(agentID); + if (scene != null) + { + ScenePresence presence = scene.GetScenePresence(agentID); + if (presence != null) + return presence.ControllingClient; + } + + return null; + } + #region IInstantMessageSimConnector public bool SendInstantMessage(GridInstantMessage im) { diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index f4472c7..6743a2e 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -65,6 +65,10 @@ namespace OpenSim.Server.Base /// public static T LoadPlugin(string dllName, Object[] args) where T:class { + // This is good to debug configuration problems + //if (dllName == string.Empty) + // Util.PrintCallStack(); + string[] parts = dllName.Split(new char[] {':'}); dllName = parts[0]; diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index 942d960..eb184a5 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -54,6 +54,8 @@ namespace OpenSim.Server.Handlers.Hypergrid private IUserAgentService m_HomeUsersService; private string[] m_AuthorizedCallers; + private bool m_VerifyCallers = false; + public UserAgentServerConnector(IConfigSource config, IHttpServer server) : this(config, server, null) { @@ -76,6 +78,7 @@ namespace OpenSim.Server.Handlers.Hypergrid string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1"); bool proxy = gridConfig.GetBoolean("HasProxy", false); + m_VerifyCallers = gridConfig.GetBoolean("VerifyCallers", false); string csv = gridConfig.GetString("AuthorizedCallers", "127.0.0.1"); csv = csv.Replace(" ", ""); m_AuthorizedCallers = csv.Split(','); @@ -91,6 +94,7 @@ namespace OpenSim.Server.Handlers.Hypergrid server.AddXmlRPCHandler("get_server_urls", GetServerURLs, false); server.AddXmlRPCHandler("locate_user", LocateUser, false); + server.AddXmlRPCHandler("get_uui", GetUUI, false); server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); } @@ -324,13 +328,17 @@ namespace OpenSim.Server.Handlers.Hypergrid { Hashtable hash = new Hashtable(); - bool authorized = false; - foreach (string s in m_AuthorizedCallers) - if (s == remoteClient.Address.ToString()) - { - authorized = true; - break; - } + bool authorized = true; + if (m_VerifyCallers) + { + authorized = false; + foreach (string s in m_AuthorizedCallers) + if (s == remoteClient.Address.ToString()) + { + authorized = true; + break; + } + } if (authorized) { @@ -354,5 +362,40 @@ namespace OpenSim.Server.Handlers.Hypergrid return response; } + + /// + /// Locates the user. + /// This is a sensitive operation, only authorized IP addresses can perform it. + /// + /// + /// + /// + public XmlRpcResponse GetUUI(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable hash = new Hashtable(); + + Hashtable requestData = (Hashtable)request.Params[0]; + //string host = (string)requestData["host"]; + //string portstr = (string)requestData["port"]; + if (requestData.ContainsKey("userID") && requestData.ContainsKey("targetUserID")) + { + string userID_str = (string)requestData["userID"]; + UUID userID = UUID.Zero; + UUID.TryParse(userID_str, out userID); + + string tuserID_str = (string)requestData["targetUserID"]; + UUID targetUserID = UUID.Zero; + UUID.TryParse(tuserID_str, out targetUserID); + string uui = m_HomeUsersService.GetUUI(userID, targetUserID); + if (uui != string.Empty) + hash["UUI"] = uui; + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + + } + } } diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 50036b3..1c01563 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -576,6 +576,7 @@ namespace OpenSim.Services.Connectors.Hypergrid XmlRpcResponse response = null; try { + m_log.DebugFormat("[XXX]: Calling locate_user on {0}", m_ServerURL); response = request.Send(m_ServerURL, 10000); } catch (Exception e) @@ -618,6 +619,66 @@ namespace OpenSim.Services.Connectors.Hypergrid return url; } + public string GetUUI(UUID userID, UUID targetUserID) + { + Hashtable hash = new Hashtable(); + hash["userID"] = userID.ToString(); + hash["targetUserID"] = targetUserID.ToString(); + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("get_uui", paramList); + string reason = string.Empty; + + // Send and get reply + string uui = string.Empty; + XmlRpcResponse response = null; + try + { + m_log.DebugFormat("[XXX]: Calling get_uuid on {0}", m_ServerURL); + response = request.Send(m_ServerURL, 10000); + } + catch (Exception e) + { + m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); + reason = "Exception: " + e.Message; + return uui; + } + + if (response.IsFault) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); + reason = "XMLRPC Fault"; + return uui; + } + + hash = (Hashtable)response.Value; + //foreach (Object o in hash) + // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); + try + { + if (hash == null) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUI Got null response from {0}! THIS IS BAAAAD", m_ServerURL); + reason = "Internal error 1"; + return uui; + } + + // Here's the actual response + if (hash.ContainsKey("UUI")) + uui = hash["UUI"].ToString(); + + } + catch (Exception e) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response."); + reason = "Exception: " + e.Message; + } + + return uui; + } + private bool GetBoolResponse(XmlRpcRequest request, out string reason) { //m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURL); diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs index 65ee7c7..2a922de 100644 --- a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs +++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs @@ -80,6 +80,7 @@ namespace OpenSim.Services.Connectors.InstantMessage } else { + m_log.DebugFormat("[GRID INSTANT MESSAGE]: No response from {0}", url); return false; } } diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index 6178ca1..ca0fd7f 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -64,8 +64,8 @@ namespace OpenSim.Services.HypergridService protected static IInstantMessageSimConnector m_IMSimConnector; - protected Dictionary m_UserLocationMap = new Dictionary(); - private ExpiringCache m_RegionCache; + protected static Dictionary m_UserLocationMap = new Dictionary(); + private static ExpiringCache m_RegionCache; public HGInstantMessageService(IConfigSource config) : this(config, null) @@ -155,6 +155,8 @@ namespace OpenSim.Services.HypergridService if (!firstTime) { lookupAgent = true; + upd = null; + url = string.Empty; } } else @@ -168,7 +170,6 @@ namespace OpenSim.Services.HypergridService // Are we needing to look-up an agent? if (lookupAgent) { - bool isPresent = false; // Non-cached user agent lookup. PresenceInfo[] presences = m_PresenceService.GetAgents(new string[] { toAgentID.ToString() }); if (presences != null && presences.Length > 0) @@ -177,17 +178,17 @@ namespace OpenSim.Services.HypergridService { if (p.RegionID != UUID.Zero) { + m_log.DebugFormat("[XXX]: Found presence in {0}", p.RegionID); upd = p; break; } - else - isPresent = true; } } - if (upd == null && isPresent) + if (upd == null) { // Let's check with the UAS if the user is elsewhere + m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service"); url = m_UserAgentService.LocateUser(toAgentID); } @@ -197,10 +198,10 @@ namespace OpenSim.Services.HypergridService // This is one way to end the recursive loop // if (!firstTime && ((previousLocation is PresenceInfo && upd != null && upd.RegionID == ((PresenceInfo)previousLocation).RegionID) || - (previousLocation is string && previousLocation.Equals(url)))) + (previousLocation is string && upd == null && previousLocation.Equals(url)))) { // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); - m_log.DebugFormat("[XXX] Fail 1 {0} {1}", previousLocation, url); + m_log.DebugFormat("[HG IM SERVICE]: Fail 2 {0} {1}", previousLocation, url); return false; } @@ -242,9 +243,14 @@ namespace OpenSim.Services.HypergridService } if (reginfo != null) + { imresult = InstantMessageServiceConnector.SendInstantMessage(reginfo.ServerURI, im); + } else + { + m_log.DebugFormat("[HG IM SERVICE]: Failed to deliver message to {0}", reginfo.ServerURI); return false; + } if (imresult) { diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 59ad043..387547e 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -485,6 +485,30 @@ namespace OpenSim.Services.HypergridService return string.Empty; } + + public string GetUUI(UUID userID, UUID targetUserID) + { + // Let's see if it's a local user + UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, targetUserID); + if (account != null) + return targetUserID.ToString() + ";" + m_GridName + ";" + account.FirstName + " " + account.LastName ; + + // Let's try the list of friends + FriendInfo[] friends = m_FriendsService.GetFriends(userID); + if (friends != null && friends.Length > 0) + { + foreach (FriendInfo f in friends) + if (f.Friend.StartsWith(targetUserID.ToString())) + { + // Let's remove the secret + UUID id; string tmp = string.Empty, secret = string.Empty; + if (Util.ParseUniversalUserIdentifier(f.Friend, out id, out tmp, out tmp, out tmp, out secret)) + return f.Friend.Replace(secret, "0"); + } + } + + return string.Empty; + } } class TravelingAgentInfo diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs index 3ab6d4f..753c205 100644 --- a/OpenSim/Services/Interfaces/IHypergridServices.cs +++ b/OpenSim/Services/Interfaces/IHypergridServices.cs @@ -57,6 +57,9 @@ namespace OpenSim.Services.Interfaces Dictionary GetServerURLs(UUID userID); string LocateUser(UUID userID); + // Tries to get the universal user identifier for the targetUserId + // on behalf of the userID + string GetUUI(UUID userID, UUID targetUserID); void StatusNotification(List friends, UUID userID, bool online); List GetOnlineFriends(UUID userID, List friends); diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 0d79e77..bfefe32 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -21,7 +21,7 @@ ; * [[@]/][:] ; * [Startup] -ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector" +ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector,8002/OpenSim.Server.Handlers.dll:HGFriendsServerConnector,8002/OpenSim.Server.Handlers.dll:InstantMessageServerConnector" ; * This is common for all services, it's the network setup for the entire ; * server instance, if none is specified above @@ -316,7 +316,10 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService" GridService = "OpenSim.Services.GridService.dll:GridService" GatekeeperService = "OpenSim.Services.HypergridService.dll:GatekeeperService" - + PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" + FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" + UserAccountService = "OpenSim.Services.UserAccountService.dll:UserAccountService" + ; If you run this user agent server behind a proxy, set this to true ; HasProxy = false @@ -344,3 +347,14 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGAssetService" UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" ProfileServerURI = "http://127.0.0.1:8002/user" + +[HGFriendsService] + LocalServiceModule = "OpenSim.Services.FriendsService.dll:FriendsService" + UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" + +[HGInstantMessageService] + LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService" + GridService = "OpenSim.Services.GridService.dll:GridService" + PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" + UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" + diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index bc8bc0f..b2ecc79 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -93,6 +93,12 @@ ;; uncomment the next line. You may want to do this on sims that have licensed content. ; OutboundPermission = False +[UserAgentService] + ; + ; === HG ONLY === + ; Change this to your user agent server + ; + UserAgentServerURI = "http://mygridserver.com:8002" [Modules] ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index 5142d90..d2cf898 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -24,12 +24,14 @@ EntityTransferModule = "HGEntityTransferModule" InventoryAccessModule = "HGInventoryAccessModule" LandServices = "RemoteLandServicesConnector" + FriendsModule = "HGFriendsModule" LandServiceInConnector = true NeighbourServiceInConnector = true SimulationServiceInConnector = true LibraryModule = true + [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService" @@ -63,3 +65,12 @@ [Friends] Connector = "OpenSim.Services.Connectors.dll:FriendsServicesConnector" + +[Messaging] + MessageTransferModule = HGMessageTransferModule + +[HGInstantMessageService] + LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService" + GridService = "OpenSim.Services.Connectors.dll:GridServicesConnector" + PresenceService = "OpenSim.Services.Connectors.dll:PresenceServicesConnector" + UserAgentService = "OpenSim.Services.Connectors.dll:UserAgentServiceConnector" \ No newline at end of file -- cgit v1.1 From 0d29f7391629defa0ec1463fb24486ee76cca527 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 26 May 2011 19:13:03 -0700 Subject: Commented a few extra debug messages. --- .../Framework/UserManagement/UserManagementModule.cs | 4 ++-- .../Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs | 5 +---- .../Services/Connectors/Hypergrid/UserAgentServiceConnector.cs | 2 -- .../InstantMessage/InstantMessageServiceConnector.cs | 4 ++-- OpenSim/Services/HypergridService/HGInstantMessageService.cs | 10 +++++----- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 4d073b2..f721195 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -143,7 +143,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) { - m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0}", uuid); + //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0}", uuid); if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) { remote_client.SendNameReply(uuid, "Mr", "OpenSim"); @@ -213,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public string GetUserName(UUID uuid) { - m_log.DebugFormat("[XXX] GetUserName {0}", uuid); + //m_log.DebugFormat("[XXX] GetUserName {0}", uuid); string[] names = GetUserNames(uuid); if (names.Length == 2) { diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs index 841811e..5c89d0f 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs @@ -140,16 +140,13 @@ namespace OpenSim.Server.Handlers.Hypergrid byte[] NewFriendship(Dictionary request) { - m_log.DebugFormat("[XXX] 1"); if (!VerifyServiceKey(request)) return FailureResult(); - m_log.DebugFormat("[XXX] 2"); // OK, can proceed FriendInfo friend = new FriendInfo(request); UUID friendID; string tmp = string.Empty; - m_log.DebugFormat("[XXX] 3"); if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp)) return FailureResult(); @@ -221,7 +218,7 @@ namespace OpenSim.Server.Handlers.Hypergrid return false; } - m_log.DebugFormat("[XXX] Verification ok"); + m_log.DebugFormat("[HGFRIENDS HANDLER]: Verification ok"); return true; } diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 1c01563..046f755 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -576,7 +576,6 @@ namespace OpenSim.Services.Connectors.Hypergrid XmlRpcResponse response = null; try { - m_log.DebugFormat("[XXX]: Calling locate_user on {0}", m_ServerURL); response = request.Send(m_ServerURL, 10000); } catch (Exception e) @@ -636,7 +635,6 @@ namespace OpenSim.Services.Connectors.Hypergrid XmlRpcResponse response = null; try { - m_log.DebugFormat("[XXX]: Calling get_uuid on {0}", m_ServerURL); response = request.Send(m_ServerURL, 10000); } catch (Exception e) diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs index 2a922de..e94e335 100644 --- a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs +++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs @@ -69,12 +69,12 @@ namespace OpenSim.Services.Connectors.InstantMessage { if ((string)responseData["success"] == "TRUE") { - m_log.DebugFormat("[XXX] Success"); + //m_log.DebugFormat("[XXX] Success"); return true; } else { - m_log.DebugFormat("[XXX] Fail"); + //m_log.DebugFormat("[XXX] Fail"); return false; } } diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index ca0fd7f..dd5fd71 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -106,12 +106,12 @@ namespace OpenSim.Services.HypergridService public bool IncomingInstantMessage(GridInstantMessage im) { - m_log.DebugFormat("[HG IM SERVICE]: Received message {0} from {1} to {2}", im.message, im.fromAgentID, im.toAgentID); + m_log.DebugFormat("[HG IM SERVICE]: Received message from {0} to {1}", im.fromAgentID, im.toAgentID); UUID toAgentID = new UUID(im.toAgentID); if (m_IMSimConnector != null) { - m_log.DebugFormat("[XXX] SendIMToRegion local im connector"); + //m_log.DebugFormat("[XXX] SendIMToRegion local im connector"); return m_IMSimConnector.SendInstantMessage(im); } else @@ -120,7 +120,7 @@ namespace OpenSim.Services.HypergridService public bool OutgoingInstantMessage(GridInstantMessage im, string url) { - m_log.DebugFormat("[HG IM SERVICE]: Sending message {0} from {1} to {2}@{3}", im.message, im.fromAgentID, im.toAgentID, url); + m_log.DebugFormat("[HG IM SERVICE]: Sending message from {0} to {1}@{2}", im.fromAgentID, im.toAgentID, url); if (url != string.Empty) return TrySendInstantMessage(im, url, true); else @@ -165,7 +165,7 @@ namespace OpenSim.Services.HypergridService } } - m_log.DebugFormat("[XXX] Neeed lookup ? {0}", (lookupAgent ? "yes" : "no")); + //m_log.DebugFormat("[XXX] Neeed lookup ? {0}", (lookupAgent ? "yes" : "no")); // Are we needing to look-up an agent? if (lookupAgent) @@ -178,7 +178,7 @@ namespace OpenSim.Services.HypergridService { if (p.RegionID != UUID.Zero) { - m_log.DebugFormat("[XXX]: Found presence in {0}", p.RegionID); + //m_log.DebugFormat("[XXX]: Found presence in {0}", p.RegionID); upd = p; break; } -- cgit v1.1 From 07acb4d321d1388aeae7e789b59280dee8de63da Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 26 May 2011 19:15:39 -0700 Subject: Last commit before pushing. WARNING: (a) DB migration on the friends table; and (b) several config additions related to HG. See Robust.HG.ini.example, GridCommon.ini.example and/or StandaloneCommon.ini.example. --- bin/config-include/GridCommon.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index b2ecc79..486ba76 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -96,7 +96,7 @@ [UserAgentService] ; ; === HG ONLY === - ; Change this to your user agent server + ; Change this to your user agent server (HG robust) ; UserAgentServerURI = "http://mygridserver.com:8002" -- cgit v1.1 From abae859e7a7c21e855fdfe7ae454f35ead7a4480 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 26 May 2011 19:20:29 -0700 Subject: Added missing configuration variables to Robust.HG.ini.example --- bin/Robust.HG.ini.example | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index bfefe32..54f4650 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -216,6 +216,8 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 SRV_InventoryServerURI = "http://127.0.0.1:8002" SRV_AssetServerURI = "http://127.0.0.1:8002" SRV_ProfileServerURI = "http://127.0.0.1:8002/user" + SRV_FriendsServerURI = "http://127.0.0.1:8002/user" + SRV_IMServerURI = "http://127.0.0.1:8002/user" ;; Regular expressions for controlling which client versions are accepted/denied. ;; An empty string means nothing is checked. -- cgit v1.1 From 31d07859f9b073a8db080228192ce5303af54cd9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 26 May 2011 19:43:24 -0700 Subject: Added missing config vars to StandaloneCommon.ini.example and fixed the ones in Robust.HG.ini.example --- bin/Robust.HG.ini.example | 4 ++-- bin/config-include/StandaloneCommon.ini.example | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 54f4650..0dd93f8 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -216,8 +216,8 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 SRV_InventoryServerURI = "http://127.0.0.1:8002" SRV_AssetServerURI = "http://127.0.0.1:8002" SRV_ProfileServerURI = "http://127.0.0.1:8002/user" - SRV_FriendsServerURI = "http://127.0.0.1:8002/user" - SRV_IMServerURI = "http://127.0.0.1:8002/user" + SRV_FriendsServerURI = "http://127.0.0.1:8002" + SRV_IMServerURI = "http://127.0.0.1:8002" ;; Regular expressions for controlling which client versions are accepted/denied. ;; An empty string means nothing is checked. diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 67efa11..df93cee 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -82,6 +82,8 @@ SRV_InventoryServerURI = "http://127.0.0.1:9000" SRV_AssetServerURI = "http://127.0.0.1:9000" SRV_ProfileServerURI = "http://127.0.0.1:9000" + SRV_FriendsServerURI = "http://127.0.0.1:9000" + SRV_IMServerURI = "http://127.0.0.1:9000" ;; Regular expressions for controlling which client versions are accepted/denied. ;; An empty string means nothing is checked. -- cgit v1.1 From 36f9d55c363f0b6877a4eeb4a9d37ba989257393 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 May 2011 07:00:36 -0700 Subject: Added a BasicProfilemodule so that the profile-based actions (like give inventory, etc) work. This is just a mock profile, the same for all users, and with no DB backend behind it -- meaning that nothing will be saved. For serious profiles, use 3rd party implementations. --- .../Avatar/Profile/BasicProfileModule.cs | 173 +++++++++++++++++++++ bin/config-include/Grid.ini | 3 + bin/config-include/GridHypergrid.ini | 2 + bin/config-include/Standalone.ini | 3 + bin/config-include/StandaloneHypergrid.ini | 3 + 5 files changed, 184 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs new file mode 100644 index 0000000..e04fff6 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs @@ -0,0 +1,173 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; + +using OpenMetaverse; +using log4net; +using Nini.Config; +using Mono.Addins; + +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Region.CoreModules.Avatar.Profile +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class BasicProfileModule : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + // + // Module vars + // + private List m_Scenes = new List(); + private bool m_Enabled = false; + + #region ISharedRegionModule + + public void Initialise(IConfigSource config) + { + if (config.Configs["Profiles"] != null) + { + if (config.Configs["Profiles"].GetString("Module", string.Empty) != "BasicProfileModule") + return; + } + + m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); + m_Enabled = true; + + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock (m_Scenes) + { + if (!m_Scenes.Contains(scene)) + { + m_Scenes.Add(scene); + // Hook up events + scene.EventManager.OnNewClient += OnNewClient; + } + } + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock (m_Scenes) + { + m_Scenes.Remove(scene); + } + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public string Name + { + get { return "BasicProfileModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + #endregion + + /// New Client Event Handler + private void OnNewClient(IClientAPI client) + { + //Profile + client.OnRequestAvatarProperties += RequestAvatarProperties; + } + + public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) + { + IScene s = remoteClient.Scene; + if (!(s is Scene)) + return; + + Scene scene = (Scene)s; + + string profileUrl = String.Empty; + string aboutText = String.Empty; + string firstLifeAboutText = String.Empty; + UUID image = UUID.Zero; + UUID firstLifeImage = UUID.Zero; + UUID partner = UUID.Zero; + uint wantMask = 0; + string wantText = String.Empty; + uint skillsMask = 0; + string skillsText = String.Empty; + string languages = String.Empty; + + Byte[] charterMember = Utils.StringToBytes("Avatar"); + + profileUrl = "No profile data"; + aboutText = string.Empty; + firstLifeAboutText = string.Empty; + image = UUID.Zero; + firstLifeImage = UUID.Zero; + partner = UUID.Zero; + + remoteClient.SendAvatarProperties(avatarID, aboutText, + Util.ToDateTime(0).ToString( + "M/d/yyyy", CultureInfo.InvariantCulture), + charterMember, firstLifeAboutText, + (uint)(0 & 0xff), + firstLifeImage, image, profileUrl, partner); + + //Viewer expects interest data when it asks for properties. + remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText, + skillsMask, skillsText, languages); + } + + } +} \ No newline at end of file diff --git a/bin/config-include/Grid.ini b/bin/config-include/Grid.ini index ce5588e..baadbb8 100644 --- a/bin/config-include/Grid.ini +++ b/bin/config-include/Grid.ini @@ -27,6 +27,9 @@ SimulationServiceInConnector = true LibraryModule = true +[Profiles] + Module = "BasicProfileModule" + [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService" diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index d2cf898..72b7412 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -31,6 +31,8 @@ SimulationServiceInConnector = true LibraryModule = true +[Profiles] + Module = "BasicProfileModule" [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService" diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index 6355d09..cfcf5ed 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -22,6 +22,9 @@ LLLoginServiceInConnector = true GridInfoServiceInConnector = true +[Profiles] + Module = "BasicProfileModule" + [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService" diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index cd2d7a7..7d1ff60 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -32,6 +32,9 @@ AuthenticationServiceInConnector = true SimulationServiceInConnector = true +[Profiles] + Module = "BasicProfileModule" + [Messaging] MessageTransferModule = HGMessageTransferModule -- cgit v1.1 From d60f525baa8697f896b9f756175118828db9ac78 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 May 2011 08:19:40 -0700 Subject: HG inventory transfers over the profile working. --- .../ServiceConnectorsOut/Inventory/HGInventoryBroker.cs | 11 +++++++++-- OpenSim/Services/HypergridService/HGInventoryService.cs | 2 ++ OpenSim/Services/InventoryService/XInventoryService.cs | 10 +++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs index eef60a1..698fd56 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs @@ -217,12 +217,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return; } } - else + } + if (sp == null) + { + inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI"); + if (inventoryURL != null && inventoryURL != string.Empty) { - inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI"); inventoryURL = inventoryURL.Trim(new char[] { '/' }); + m_InventoryURLs.Add(userID, inventoryURL); + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL); } + } + } } diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs index 9ee1ae4..4eb61ba 100644 --- a/OpenSim/Services/HypergridService/HGInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGInventoryService.cs @@ -134,6 +134,7 @@ namespace OpenSim.Services.HypergridService public override InventoryFolderBase GetRootFolder(UUID principalID) { + //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetRootFolder for {0}", principalID); // Warp! Root folder for travelers XInventoryFolder[] folders = m_Database.GetFolders( new string[] { "agentID", "folderName"}, @@ -171,6 +172,7 @@ namespace OpenSim.Services.HypergridService public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) { + //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type); return GetRootFolder(principalID); } diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 58c59eb..eeab67a 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -40,9 +40,9 @@ namespace OpenSim.Services.InventoryService { public class XInventoryService : ServiceBase, IInventoryService { -// private static readonly ILog m_log = -// LogManager.GetLogger( -// MethodBase.GetCurrentMethod().DeclaringType); + //private static readonly ILog m_log = + // LogManager.GetLogger( + // MethodBase.GetCurrentMethod().DeclaringType); protected IXInventoryData m_Database; protected bool m_AllowDelete = true; @@ -385,8 +385,8 @@ namespace OpenSim.Services.InventoryService public virtual bool AddItem(InventoryItemBase item) { -// m_log.DebugFormat( -// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner); + //m_log.DebugFormat( + // "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner); return m_Database.StoreItem(ConvertFromOpenSim(item)); } -- cgit v1.1 From 4087a453dc90356d8e62d371165b427096f5c26e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 May 2011 08:53:26 -0700 Subject: Avoid a scary warning message about null replies from the user agent service. --- OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index eb184a5..9961164 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -354,6 +354,8 @@ namespace OpenSim.Server.Handlers.Hypergrid string url = m_HomeUsersService.LocateUser(userID); if (url != string.Empty) hash["URL"] = url; + else + hash["result"] = "Unable to locate user"; } } @@ -389,6 +391,8 @@ namespace OpenSim.Server.Handlers.Hypergrid string uui = m_HomeUsersService.GetUUI(userID, targetUserID); if (uui != string.Empty) hash["UUI"] = uui; + else + hash["result"] = "User unknown"; } XmlRpcResponse response = new XmlRpcResponse(); -- cgit v1.1 From 0af5bb239f757eabfc4c59a18b88edfbf7afa6e6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 May 2011 19:39:03 +0100 Subject: When saving an iar, don't chase down link asset IDs (since these points to other items rather than real assets) This bug had no practical effect other than to make "save iar" misreport the number of missing assets --- .../Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index b5272ad..c34a0ec 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -157,7 +157,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); m_archiveWriter.WriteFile(filename, serialization); - if (SaveAssets) + AssetType itemAssetType = (AssetType)inventoryItem.AssetType; + + // Don't chase down link asset items as they actually point to their target item IDs rather than an asset + if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder) m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); } -- cgit v1.1 From 4e4db749eb74bf02ae956c4a9461499988f0f0ec Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 May 2011 20:59:35 +0100 Subject: If parsing fails in the primitive base shape (which prints out a debug log message), also print out the name and uuid of the part containing this shape. This is to help in diagnosing parsing failures. --- .../Scenes/Serialization/SceneObjectSerializer.cs | 29 +++++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 872816c..47af0dd 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -570,7 +570,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) { - obj.Shape = ReadShape(reader, "Shape"); + bool errors = false; + obj.Shape = ReadShape(reader, "Shape", out errors); + + if (errors) + m_log.DebugFormat( + "[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors. Please see earlier log entries.", + obj.Name, obj.UUID); } private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) @@ -1470,7 +1476,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } catch (Exception e) { - m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing {0}: {1}", nodeName, e); + m_log.DebugFormat( + "[SceneObjectSerializer]: exception while parsing {0} in object {1} {2}: {3}{4}", + obj.Name, obj.UUID, nodeName, e.Message, e.StackTrace); if (reader.NodeType == XmlNodeType.EndElement) reader.Read(); } @@ -1528,8 +1536,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization return tinv; } - static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name) + /// + /// Read a shape from xml input + /// + /// + /// The name of the xml element containing the shape + /// true if any errors were encountered during parsing, false otherwise + /// The shape parsed + static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors) { + errors = false; + PrimitiveBaseShape shape = new PrimitiveBaseShape(); if (reader.IsEmptyElement) @@ -1554,7 +1571,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } catch (Exception e) { - m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing Shape {0}: {1}", nodeName, e); + errors = true; + m_log.DebugFormat( + "[SceneObjectSerializer]: exception while parsing Shape property {0}: {1}{2}", + nodeName, e.Message, e.StackTrace); + if (reader.NodeType == XmlNodeType.EndElement) reader.Read(); } -- cgit v1.1 From 76525be7b2cb1a72c45a72801dac871c4a338bcb Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 May 2011 13:07:18 -0700 Subject: HG lures working! Friends can offer friends HG teleports via the profile. WARNING: additional configuration for HG inis -- see *Common.ini.example --- .../InstantMessage/HGMessageTransferModule.cs | 1 - .../Region/CoreModules/Avatar/Lure/HGLureModule.cs | 244 +++++++++++++++++++++ .../Region/CoreModules/Avatar/Lure/LureModule.cs | 15 +- .../EntityTransfer/EntityTransferModule.cs | 2 +- .../Framework/Interfaces/IEntityTransferModule.cs | 3 + .../Hypergrid/InstantMessageServerConnector.cs | 45 +--- .../InstantMessageServiceConnector.cs | 1 + bin/config-include/GridCommon.ini.example | 6 + bin/config-include/GridHypergrid.ini | 3 +- bin/config-include/StandaloneCommon.ini.example | 5 + bin/config-include/StandaloneHypergrid.ini | 3 +- 11 files changed, 280 insertions(+), 48 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index ed02119..e0c404b 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -187,7 +187,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // Is the user a local user? UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID); string url = string.Empty; - PresenceInfo upd; if (account == null) // foreign user url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI"); 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 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; +using Mono.Addins; + +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Connectors.Hypergrid; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.CoreModules.Avatar.Lure +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class HGLureModule : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private readonly List m_scenes = new List(); + + private IMessageTransferModule m_TransferModule = null; + private bool m_Enabled = false; + + private string m_ThisGridURL; + + private ExpiringCache m_PendingLures = new ExpiringCache(); + + public void Initialise(IConfigSource config) + { + if (config.Configs["Messaging"] != null) + { + if (config.Configs["Messaging"].GetString("LureModule", string.Empty) == "HGLureModule") + { + m_Enabled = true; + + m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty); + m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); + } + } + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock (m_scenes) + { + m_scenes.Add(scene); + scene.EventManager.OnIncomingInstantMessage += OnIncomingInstantMessage; + scene.EventManager.OnNewClient += OnNewClient; + } + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + if (m_TransferModule == null) + { + m_TransferModule = + scene.RequestModuleInterface(); + + if (m_TransferModule == null) + { + m_log.Error("[LURE MODULE]: No message transfer module, lures will not work!"); + + m_Enabled = false; + m_scenes.Clear(); + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage; + } + } + + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock (m_scenes) + { + m_scenes.Remove(scene); + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage; + } + } + + void OnNewClient(IClientAPI client) + { + client.OnInstantMessage += OnInstantMessage; + client.OnStartLure += OnStartLure; + client.OnTeleportLureRequest += OnTeleportLureRequest; + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public string Name + { + get { return "HGLureModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + void OnInstantMessage(IClientAPI client, GridInstantMessage im) + { + } + + void OnIncomingInstantMessage(GridInstantMessage im) + { + if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) + { + UUID sessionID = new UUID(im.imSessionID); + m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message); + m_PendingLures.Add(sessionID, im, 7200); // 2 hours + + // Forward. We do this, because the IM module explicitly rejects + // IMs of this type + if (m_TransferModule != null) + m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); + + } + } + + public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client) + { + if (!(client.Scene is Scene)) + return; + + Scene scene = (Scene)(client.Scene); + ScenePresence presence = scene.GetScenePresence(client.AgentId); + + message += "@" + m_ThisGridURL; + + m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message); + + GridInstantMessage m = new GridInstantMessage(scene, client.AgentId, + client.FirstName+" "+client.LastName, targetid, + (byte)InstantMessageDialog.RequestTeleport, false, + message, UUID.Random(), false, presence.AbsolutePosition, + new Byte[0]); + m.RegionID = client.Scene.RegionInfo.RegionID.Guid; + + if (m_TransferModule != null) + { + m_TransferModule.SendInstantMessage(m, + delegate(bool success) { }); + } + } + + public void OnTeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client) + { + if (!(client.Scene is Scene)) + return; + + Scene scene = (Scene)(client.Scene); + + GridInstantMessage im = null; + if (m_PendingLures.TryGetValue(lureID, out im)) + { + m_PendingLures.Remove(lureID); + Lure(client, teleportFlags, im); + } + else + m_log.DebugFormat("[HG LURE MODULE]: pending lure {0} not found", lureID); + + } + + private void Lure(IClientAPI client, uint teleportflags, GridInstantMessage im) + { + Scene scene = (Scene)(client.Scene); + GridRegion region = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID, new UUID(im.RegionID)); + if (region != null) + scene.RequestTeleportLocation(client, region.RegionHandle, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags); + else // we don't have that region here. Check if it's HG + { + string[] parts = im.message.Split(new char[] { '@' }); + if (parts.Length > 1) + { + string url = parts[parts.Length - 1]; // the last part + if (url.Trim(new char[] {'/'}) != m_ThisGridURL.Trim(new char[] {'/'})) + { + m_log.DebugFormat("[HG LURE MODULE]: Luring agent to grid {0} region {1} position {2}", url, im.RegionID, im.Position); + GatekeeperServiceConnector gConn = new GatekeeperServiceConnector(); + GridRegion gatekeeper = new GridRegion(); + gatekeeper.ServerURI = url; + GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID)); + if (finalDestination != null) + { + ScenePresence sp = scene.GetScenePresence(client.AgentId); + IEntityTransferModule transferMod = scene.RequestModuleInterface(); + IEventQueue eq = sp.Scene.RequestModuleInterface(); + if (transferMod != null && sp != null && eq != null) + transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq); + } + } + } + } + } + } +} diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index d1d7df2..d295384 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 private readonly List m_scenes = new List(); private IMessageTransferModule m_TransferModule = null; - private bool m_Enabled = true; + private bool m_Enabled = false; public void Initialise(IConfigSource config) { if (config.Configs["Messaging"] != null) { if (config.Configs["Messaging"].GetString( - "LureModule", "LureModule") != + "LureModule", "LureModule") == "LureModule") - m_Enabled = false; + { + m_Enabled = true; + m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); + } } } @@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure public void RegionLoaded(Scene scene) { + if (!m_Enabled) + return; + if (m_TransferModule == null) { m_TransferModule = @@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure public void RemoveRegion(Scene scene) { + if (!m_Enabled) + return; + lock (m_scenes) { m_scenes.Remove(scene); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 6e4ec81..ec084fb 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -248,7 +248,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } - protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) + public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) { if (reg == null || finalDestination == null) { diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 8b96de4..07e97d5 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -40,6 +40,9 @@ namespace OpenSim.Region.Framework.Interfaces void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags); + void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, + Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq); + void TeleportHome(UUID id, IClientAPI client); bool Cross(ScenePresence agent, bool isFlying); diff --git a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs index 138313a..74b7422 100644 --- a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs @@ -125,7 +125,6 @@ namespace OpenSim.Server.Handlers.Hypergrid UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); UUID.TryParse((string)requestData["im_session_id"], out imSessionID); UUID.TryParse((string)requestData["region_id"], out RegionID); - try { timestamp = (uint)Convert.ToInt32((string)requestData["timestamp"]); @@ -185,45 +184,9 @@ namespace OpenSim.Server.Handlers.Hypergrid { } - try - { - pos_x = (uint)Convert.ToInt32((string)requestData["position_x"]); - } - catch (ArgumentException) - { - } - catch (FormatException) - { - } - catch (OverflowException) - { - } - try - { - pos_y = (uint)Convert.ToInt32((string)requestData["position_y"]); - } - catch (ArgumentException) - { - } - catch (FormatException) - { - } - catch (OverflowException) - { - } - try - { - pos_z = (uint)Convert.ToInt32((string)requestData["position_z"]); - } - catch (ArgumentException) - { - } - catch (FormatException) - { - } - catch (OverflowException) - { - } + float.TryParse((string)requestData["position_x"], out pos_x); + float.TryParse((string)requestData["position_y"], out pos_y); + float.TryParse((string)requestData["position_z"], out pos_z); Position = new Vector3(pos_x, pos_y, pos_z); @@ -243,7 +206,7 @@ namespace OpenSim.Server.Handlers.Hypergrid gim.fromAgentName = fromAgentName; gim.fromGroup = fromGroup; gim.imSessionID = imSessionID.Guid; - gim.RegionID = UUID.Zero.Guid; // RegionID.Guid; + gim.RegionID = RegionID.Guid; gim.timestamp = timestamp; gim.toAgentID = toAgentID.Guid; gim.message = message; diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs index e94e335..161be02 100644 --- a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs +++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs @@ -123,6 +123,7 @@ namespace OpenSim.Services.Connectors.InstantMessage gim["position_z"] = msg.Position.Z.ToString(); gim["region_id"] = msg.RegionID.ToString(); gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None); + return gim; } diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index 486ba76..29f0de3 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -46,6 +46,12 @@ ;; Robust server in port 8002, but not always) Gatekeeper="http://mygridserver.com:8002" +[Messaging] + ;; change this to the address of your Gatekeeper service + ;; (usually bundled with the rest of the services in one + ;; Robust server in port 8002, but not always) + Gatekeeper = "http://mygridserver.com:8002" + [AvatarService] ; ; change this to your grid-wide grid server diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index 72b7412..510a315 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -69,7 +69,8 @@ Connector = "OpenSim.Services.Connectors.dll:FriendsServicesConnector" [Messaging] - MessageTransferModule = HGMessageTransferModule + MessageTransferModule = HGMessageTransferModule + LureModule = HGLureModule [HGInstantMessageService] LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index df93cee..931a77b 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -70,6 +70,11 @@ ;; change this to the address of your simulator Gatekeeper="http://127.0.0.1:9000" +[Messaging] + ; === HG ONLY === + ;; change this to the address of your simulator + Gatekeeper = "http://127.0.0.1:9000" + [LibraryModule] ; Set this if you want to change the name of the OpenSim Library ;LibraryName = "My World's Library" diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 7d1ff60..44ca3ac 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -36,7 +36,8 @@ Module = "BasicProfileModule" [Messaging] - MessageTransferModule = HGMessageTransferModule + MessageTransferModule = HGMessageTransferModule + LureModule = HGLureModule [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService" -- cgit v1.1 From e9988a3728706e346dfb869de554a24e6a3b0a79 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 May 2011 21:19:20 +0100 Subject: Make sure culture is en-US when saving archive related xml. This might resolve http://opensimulator.org/mantis/view.php?id=5475 --- OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs | 4 ++++ .../Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index b888698..3078ab3 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 /// public void AssetRequestCallback(string id, object sender, AssetBase asset) { + Culture.SetCurrentCulture(); + try { lock (this) @@ -293,6 +295,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// protected void PerformAssetsRequestCallback(object o) { + Culture.SetCurrentCulture(); + try { m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 47af0dd..6ae4f38 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 } } - /// /// Serialize a scene object to the original xml format /// -- cgit v1.1 From 44d5821c4ebac350a1db72abe7fa6c6527892f57 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 May 2011 13:35:22 -0700 Subject: Fixed one comment in a config file. --- bin/config-include/GridCommon.ini.example | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index 29f0de3..e022f1f 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -47,6 +47,7 @@ Gatekeeper="http://mygridserver.com:8002" [Messaging] + ; === HG ONLY === ;; change this to the address of your Gatekeeper service ;; (usually bundled with the rest of the services in one ;; Robust server in port 8002, but not always) -- cgit v1.1 From 28cd03cda5c4beae2befeaef116b54dbd344c636 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 May 2011 22:54:03 +0100 Subject: fix bug where generic sqlite table delete wasn't working. this would have caused dupe links bugs when using the sqlite adaptor --- OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs index 3fb2d3f..0d7ae1f 100644 --- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs @@ -280,7 +280,7 @@ namespace OpenSim.Data.SQLite string where = String.Join(" and ", terms.ToArray()); - string query = String.Format("delete * from {0} where {1}", m_Realm, where); + string query = String.Format("delete from {0} where {1}", m_Realm, where); cmd.CommandText = query; -- cgit v1.1 From 6f4a2685cff4fd70658dda0a6c81c9b050541027 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 May 2011 23:43:31 +0100 Subject: minor: remove mono compiler warning --- OpenSim/Services/FreeswitchService/FreeswitchService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Services/FreeswitchService/FreeswitchService.cs b/OpenSim/Services/FreeswitchService/FreeswitchService.cs index c3f1056..201e72f 100644 --- a/OpenSim/Services/FreeswitchService/FreeswitchService.cs +++ b/OpenSim/Services/FreeswitchService/FreeswitchService.cs @@ -54,10 +54,10 @@ namespace OpenSim.Services.FreeswitchService Hashtable response = new Hashtable(); - foreach (DictionaryEntry item in request) - { -// m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value); - } +// foreach (DictionaryEntry item in request) +// { +//// m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value); +// } string requestcontext = (string) request["Hunt-Context"]; response["content_type"] = "text/xml"; -- cgit v1.1 From 99f42c0a6ec064d7b625c9b33e185a5e153d6be8 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 27 May 2011 19:05:16 -0400 Subject: Add option to disable logins This just covers script loading for now. More to come. --- OpenSim/Region/Framework/Scenes/Scene.cs | 18 +++++++++++++++- .../RegionReadyModule/RegionReadyModule.cs | 25 +++++++++++++++++++++- bin/OpenSimDefaults.ini | 1 + 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4aae13c..e9f5f9e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -94,7 +94,10 @@ namespace OpenSim.Region.Framework.Scenes // root agents when ACL denies access to root agent public bool m_strictAccessControl = true; public int MaxUndoCount = 5; + // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; + public bool LoginLock = false; public bool LoginsDisabled = true; + public bool StartDisabled = false; public bool LoadingPrims; public IXfer XferManager; @@ -1373,10 +1376,23 @@ namespace OpenSim.Region.Framework.Scenes IConfig startupConfig = m_config.Configs["Startup"]; if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) { + if (m_sceneGraph.GetActiveScriptsCount() == 0) + { + LoginLock = false; + } m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); - LoginsDisabled = false; + // For RegionReady lockouts + if( LoginLock == false) + { + LoginsDisabled = false; + } m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface(), RegionInfo); } + else + { + StartDisabled = true; + LoginsDisabled = true; + } } } catch (NotImplementedException) diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index 122ad40..c59c88c 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -28,10 +28,13 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Net; +using System.IO; using log4net; using Nini.Config; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -50,6 +53,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady private bool m_lastOarLoadedOk; private int m_channelNotify = -1000; private bool m_enabled = false; + private bool m_disable_logins = false; Scene m_scene = null; @@ -68,10 +72,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady if (m_config != null) { m_enabled = m_config.GetBoolean("enabled", false); + if (m_enabled) { m_channelNotify = m_config.GetInt("channel_notify", m_channelNotify); - } + m_disable_logins = m_config.GetBoolean("login_disable", false); + } } // if (!m_enabled) @@ -93,6 +99,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded; m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName); + + if(m_disable_logins == true) + { + scene.LoginLock = true; + scene.LoginsDisabled = true; + m_log.InfoFormat("[RegionReady]: Logins disabled for {0}",m_scene.RegionInfo.RegionName); + } } public void RemoveRegion(Scene scene) @@ -148,6 +161,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady c.SenderUUID = UUID.Zero; c.Scene = m_scene; + if(m_disable_logins == true) + { + if(m_scene.StartDisabled == false) + { + m_scene.LoginsDisabled = false; + m_scene.LoginLock = false; + m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName); + } + } + m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); m_scene.EventManager.TriggerOnChatBroadcast(this, c); diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index b32d198..1d24201 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1174,6 +1174,7 @@ ; - the third field is a number indicating how many scripts failed to compile ; - "oar error" if supplied, provides the error message from the OAR load channel_notify = -800 + login_disable = false [MRM] -- cgit v1.1 From c7e18f9017302991f7a4411293ef2fbb20cc9b5a Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sat, 28 May 2011 11:11:01 -0400 Subject: Adding an event to signal that logins are enabled Added an event to signal the eabling of logins and added an alert to send to a configured service. --- OpenSim/Region/Framework/Scenes/EventManager.cs | 24 ++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 3 + .../RegionReadyModule/RegionReadyModule.cs | 87 +++++++++++++++++++--- bin/OpenSimDefaults.ini | 3 + 4 files changed, 106 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index e04317b..b43d5f0 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -389,6 +389,9 @@ namespace OpenSim.Region.Framework.Scenes public delegate void RegionUp(GridRegion region); public event RegionUp OnRegionUp; + public delegate void LoginsEnabled(string regionName); + public event LoginsEnabled OnLoginsEnabled; + public class MoneyTransferArgs : EventArgs { public UUID sender; @@ -2218,5 +2221,26 @@ namespace OpenSim.Region.Framework.Scenes } } } + + public void TriggerLoginsEnabled (string regionName) + { + LoginsEnabled handler = OnLoginsEnabled; + + if ( handler != null) + { + foreach (LoginsEnabled d in handler.GetInvocationList()) + { + try + { + d(regionName); + } + catch (Exception e) + { + m_log.ErrorFormat("[EVENT MANAGER]: Delegate for LoginsEnabled failed - continuing {0} - {1}", + e.Message, e.StackTrace); + } + } + } + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e9f5f9e..1d562fd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1376,9 +1376,12 @@ namespace OpenSim.Region.Framework.Scenes IConfig startupConfig = m_config.Configs["Startup"]; if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) { + // This handles a case of a region having no scripts for the RegionReady module if (m_sceneGraph.GetActiveScriptsCount() == 0) { + // need to be able to tell these have changed in RegionReady LoginLock = false; + EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); } m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); // For RegionReady lockouts diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index c59c88c..eed6450 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Reflection; using System.Net; using System.IO; +using System.Text; using log4net; using Nini.Config; @@ -54,6 +55,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady private int m_channelNotify = -1000; private bool m_enabled = false; private bool m_disable_logins = false; + private string m_uri = string.Empty; Scene m_scene = null; @@ -77,6 +79,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady { m_channelNotify = m_config.GetInt("channel_notify", m_channelNotify); m_disable_logins = m_config.GetBoolean("login_disable", false); + m_uri = m_config.GetString("alert_uri",string.Empty); } } @@ -97,6 +100,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue; m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded; + m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled; m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName); @@ -105,6 +109,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady scene.LoginLock = true; scene.LoginsDisabled = true; m_log.InfoFormat("[RegionReady]: Logins disabled for {0}",m_scene.RegionInfo.RegionName); + + if(m_uri != string.Empty) + { + RRAlert("disabled"); + } } } @@ -161,19 +170,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady c.SenderUUID = UUID.Zero; c.Scene = m_scene; - if(m_disable_logins == true) - { - if(m_scene.StartDisabled == false) - { - m_scene.LoginsDisabled = false; - m_scene.LoginLock = false; - m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName); - } - } - m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); - m_scene.EventManager.TriggerOnChatBroadcast(this, c); + + m_scene.EventManager.TriggerOnChatBroadcast(this, c); + m_scene.EventManager.TriggerLoginsEnabled(m_scene.RegionInfo.RegionName); } } @@ -188,5 +189,69 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady m_lastOarLoadedOk = false; } } + + void OnLoginsEnabled(string regionName) + { + if (m_disable_logins == true) + { + if (m_scene.StartDisabled == false) + { + m_scene.LoginsDisabled = false; + m_scene.LoginLock = false; + m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName); + if ( m_uri != string.Empty ) + { + RRAlert("enabled"); + } + } + } + } + + public void RRAlert(string status) + { + string request_method = "POST"; + string content_type = "application/json"; + OSDMap RRAlert = new OSDMap(); + + RRAlert["alert"] = "region_ready"; + RRAlert["login"] = status; + RRAlert["region_name"] = m_scene.RegionInfo.RegionName; + RRAlert["region_id"] = m_scene.RegionInfo.RegionID; + + string strBuffer = ""; + byte[] buffer = new byte[1]; + try + { + strBuffer = OSDParser.SerializeJsonString(RRAlert); + Encoding str = Util.UTF8; + buffer = str.GetBytes(strBuffer); + + } + catch (Exception e) + { + m_log.WarnFormat("[RegionReady]: Exception thrown on alert: {0}", e.Message); + } + + WebRequest request = WebRequest.Create(m_uri); + request.Method = request_method; + request.ContentType = content_type; + + Stream os = null; + try + { + request.ContentLength = buffer.Length; + os = request.GetRequestStream(); + os.Write(buffer, 0, strBuffer.Length); + } + catch(Exception e) + { + m_log.WarnFormat("[RegionReady]: Exception thrown sending alert: {0}", e.Message); + } + finally + { + if (os != null) + os.Close(); + } + } } } diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 1d24201..8613d4e 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1174,7 +1174,10 @@ ; - the third field is a number indicating how many scripts failed to compile ; - "oar error" if supplied, provides the error message from the OAR load channel_notify = -800 + ; - disallow logins while scripts are loading login_disable = false + ; - send an alert as json to a service + alert_uri = "http://myappserver.net/my_handler/" [MRM] -- cgit v1.1 From 16fae059bbe09f26d9ef29156bddfcccf767269d Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sat, 28 May 2011 16:40:05 -0400 Subject: Comment the alert_uri so it remains disabled until set --- bin/OpenSimDefaults.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 8613d4e..fa5392d 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1177,7 +1177,7 @@ ; - disallow logins while scripts are loading login_disable = false ; - send an alert as json to a service - alert_uri = "http://myappserver.net/my_handler/" + ; alert_uri = "http://myappserver.net/my_handler/" [MRM] -- cgit v1.1 From d5326197ac530c955a585b2fac429a927b5baa42 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 28 May 2011 13:52:06 -0700 Subject: Fixed an issue with the response of CreateAgent over the SimulationConnector. --- .../Simulation/SimulationServiceConnector.cs | 27 +++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index f380873..7cbd361 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -103,16 +103,31 @@ namespace OpenSim.Services.Connectors.Simulation args["teleport_flags"] = OSD.FromString(flags.ToString()); OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000); - if (result["Success"].AsBoolean()) - return true; - + bool success = result["success"].AsBoolean(); + if (success && result.ContainsKey("_Result")) + { + OSDMap data = (OSDMap)result["_Result"]; + + reason = data["reason"].AsString(); + success = data["success"].AsBoolean(); + return success; + } + + // Try the old version, uncompressed result = WebUtil.PostToService(uri, args, 30000); if (result["Success"].AsBoolean()) { - m_log.WarnFormat( - "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName); - return true; + if (result.ContainsKey("_Result")) + { + OSDMap data = (OSDMap)result["_Result"]; + + reason = data["reason"].AsString(); + success = data["success"].AsBoolean(); + m_log.WarnFormat( + "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName); + return success; + } } m_log.WarnFormat( -- cgit v1.1 From d671dbb7c743b2821cc36d845fc6ca94903625d9 Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Sat, 28 May 2011 11:10:07 +0900 Subject: Removing mssql_connection.ini.example - mssql_connection.ini is no longer used --- bin/mssql_connection.ini.example | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 bin/mssql_connection.ini.example diff --git a/bin/mssql_connection.ini.example b/bin/mssql_connection.ini.example deleted file mode 100644 index e0ae7ba..0000000 --- a/bin/mssql_connection.ini.example +++ /dev/null @@ -1,18 +0,0 @@ -; The IniConfig.cs that parses this file by just finding the first key={value} in the whole text so comments aren't really honoured. -; Also, this algorithm can probably lead to 'amusing' results in unfortunate cases. - -[mssqlconnection] -data_source=\SQLEXPRESS -initial_catalog=database -persist_security_info=True -user_id=username -password=password - -; These entries are only for if you, for some reason, wish to customize your user server table names. -; Do note that if you change the table names, you might have to change the sql resources too manually -; If ommitted, default values will be used. - -userstablename=users -userfriendstablename=userfriends -agentstablename=agents -regionstablename=regions -- cgit v1.1 From 7ea6dfecd9ede7f5f8ad169d9e6777404d97b164 Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Sat, 28 May 2011 12:07:23 +0900 Subject: Adding MSSQL connectionString example --- bin/config-include/GridCommon.ini.example | 8 ++++++++ bin/config-include/StandaloneCommon.ini.example | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index e022f1f..c5c26ec 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -14,6 +14,14 @@ ; Uncomment this line if you are using MySQL and want to use a different database for estates ;EstateConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;" + ; MSSQL + ; Uncomment these lines if you want to use MSSQL storage + ; Change the connection string to your db details + ; The value for server property is shown in your SQL Server Management Studio login dialog. + ; (This sample is the default of express edition) + ;StorageProvider = "OpenSim.Data.MSSQL.dll" + ;ConnectionString = "Server=localhost\SQLEXPRESS;Database=opensim;User Id=opensim; password=***;" + [AssetService] DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 931a77b..57380ee 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -16,6 +16,14 @@ ; Uncomment this line if you are using MySQL and want to use a different database for estates ;EstateConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;" + ; MSSQL + ; Uncomment these lines if you want to use MSSQL storage + ; Change the connection string to your db details + ; The value for server property is shown in your SQL Server Management Studio login dialog. + ; (This sample is the default of express edition) + ;StorageProvider = "OpenSim.Data.MSSQL.dll" + ;ConnectionString = "Server=localhost\SQLEXPRESS;Database=opensim;User Id=opensim; password=***;" + [AssetService] DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "assets/AssetSets.xml" -- cgit v1.1 From d473d9975e70366d0fd16276c9bafd5ec269dcd9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 30 May 2011 17:15:55 -0700 Subject: Improved reuse on the WorldMap/WorldMapModule.cs --- .../CoreModules/World/WorldMap/WorldMapModule.cs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 0cacf2d..10e1631 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -233,20 +233,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } if (lookup) { - List mapBlocks = new List(); ; - - List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, - (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, - (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, - (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); - foreach (GridRegion r in regions) - { - MapBlockData block = new MapBlockData(); - MapBlockFromGridRegion(block, r); - mapBlocks.Add(block); - } - avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); + List mapBlocks = GetAndSendBlocks(avatarPresence.ControllingClient, (int)(m_scene.RegionInfo.RegionLocX) - 4, (int)(m_scene.RegionInfo.RegionLocY) - 4, + (int)(m_scene.RegionInfo.RegionLocX) + 4, (int)(m_scene.RegionInfo.RegionLocY) + 4, 0); lock (cachedMapBlocks) cachedMapBlocks = mapBlocks; @@ -832,7 +820,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } } - protected virtual void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + protected virtual List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, @@ -847,6 +835,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap mapBlocks.Add(block); } remoteClient.SendMapBlock(mapBlocks, 0); + + return mapBlocks; } protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r) -- cgit v1.1 From e14b7ec9e115dd1705d6952f5ecbb19806709944 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 30 May 2011 17:19:46 -0700 Subject: HGWorldMap: don't send map blocks of hyperlinks that are farther than 4096 cells from the current region. --- .../CoreModules/Hypergrid/HGWorldMapModule.cs | 28 ++++++++++++++++++---- OpenSim/Services/GridService/HypergridLinker.cs | 5 +++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index 5ab334f..0781de0 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections.Generic; using System.Reflection; using log4net; @@ -58,7 +59,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid #endregion - protected override void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + protected override List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, @@ -67,9 +68,26 @@ namespace OpenSim.Region.CoreModules.Hypergrid foreach (GridRegion r in regions) { - MapBlockData block = new MapBlockData(); - MapBlockFromGridRegion(block, r); - mapBlocks.Add(block); + uint x = 0, y = 0; + long handle = 0; + if (r.RegionSecret != null && r.RegionSecret != string.Empty) + { + if (long.TryParse(r.RegionSecret, out handle)) + { + Utils.LongToUInts((ulong)handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + } + } + + if (handle == 0 || + // Check the distance from the current region + (handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096)) + { + MapBlockData block = new MapBlockData(); + MapBlockFromGridRegion(block, r); + mapBlocks.Add(block); + } } // Different from super @@ -77,6 +95,8 @@ namespace OpenSim.Region.CoreModules.Hypergrid // remoteClient.SendMapBlock(mapBlocks, 0); + + return mapBlocks; } diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index c539047..b7c0e91 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -363,11 +363,14 @@ namespace OpenSim.Services.GridService else regInfo.RegionName = externalName; - m_log.Debug("[HYPERGRID LINKER]: naming linked region " + regInfo.RegionName); + m_log.DebugFormat("[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString()); // Get the map image regInfo.TerrainImage = m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory); + // Store the origin's coordinates somewhere + regInfo.RegionSecret = handle.ToString(); + AddHyperlinkRegion(regInfo, handle); m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} with image {1}", regInfo.RegionName, regInfo.TerrainImage); return true; -- cgit v1.1 From b81a304baaeeee4e0dabb42c8e217c3c30be9863 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 30 May 2011 20:12:05 -0700 Subject: Made the GatekeeperConnector a public property. --- OpenSim/Services/GridService/HypergridLinker.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index b7c0e91..64935af 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -61,6 +61,10 @@ namespace OpenSim.Services.GridService protected GridService m_GridService; protected IAssetService m_AssetService; protected GatekeeperServiceConnector m_GatekeeperConnector; + public GatekeeperServiceConnector GatekeeperConnector + { + get { return m_GatekeeperConnector; } + } protected UUID m_ScopeID = UUID.Zero; protected bool m_Check4096 = true; -- cgit v1.1 From 44371118a2ac50b21e31995d3bcc309a5e1dc56c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 30 May 2011 20:23:45 -0700 Subject: Made GetMapImage public in the Hyperlinker --- OpenSim/Services/GridService/HypergridLinker.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index 64935af..5262598 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -61,10 +61,6 @@ namespace OpenSim.Services.GridService protected GridService m_GridService; protected IAssetService m_AssetService; protected GatekeeperServiceConnector m_GatekeeperConnector; - public GatekeeperServiceConnector GatekeeperConnector - { - get { return m_GatekeeperConnector; } - } protected UUID m_ScopeID = UUID.Zero; protected bool m_Check4096 = true; @@ -370,7 +366,7 @@ namespace OpenSim.Services.GridService m_log.DebugFormat("[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString()); // Get the map image - regInfo.TerrainImage = m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory); + regInfo.TerrainImage = GetMapImage(regionID, imageURL); // Store the origin's coordinates somewhere regInfo.RegionSecret = handle.ToString(); @@ -470,6 +466,10 @@ namespace OpenSim.Services.GridService m_Database.Delete(regionID); } + public UUID GetMapImage(UUID regionID, string imageURL) + { + return m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory); + } #endregion -- cgit v1.1 From c4b265aeae712432bebaca1aa3c97bbafe14e3e2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 31 May 2011 18:47:13 +0100 Subject: update libomv libraries to 0.9.0 this is a prerequisite to fixing llDialog issues for the latest Linden viewers, since they are now making use of a new OwnerData field in the ScriptDialog message --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 +++++++++++++++++---- bin/OpenMetaverse.Rendering.Meshmerizer.dll | Bin 20480 -> 20480 bytes bin/OpenMetaverse.StructuredData.dll | Bin 102400 -> 102400 bytes bin/OpenMetaverse.dll | Bin 1716224 -> 1736704 bytes bin/OpenMetaverseTypes.dll | Bin 114688 -> 114688 bytes 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 1c791b9..05223e0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1231,20 +1231,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - if (requestingClient.AgentId != dataForAgentID) - { + // c_scene and property accessor 'is_god' are in support of the opertions to bypass 'hidden' group attributes for + // those with a GodLike aspect. + Scene c_scene = (Scene) requestingClient.Scene; + bool is_god = c_scene.Permissions.IsGod(requestingClient.AgentId); + + if(is_god) { Predicate showInProfile = delegate(GroupMembershipData membership) { return membership.ListInProfile; }; - membershipArray = membershipData.FindAll(showInProfile).ToArray(); + membershipArray = membershipData.ToArray(); } else { - membershipArray = membershipData.ToArray(); - } + if (requestingClient.AgentId != dataForAgentID) + { + Predicate showInProfile = delegate(GroupMembershipData membership) + { + return membership.ListInProfile; + }; + + membershipArray = membershipData.FindAll(showInProfile).ToArray(); + } + else + { + membershipArray = membershipData.ToArray(); + } + } if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1257,6 +1273,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } + private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); diff --git a/bin/OpenMetaverse.Rendering.Meshmerizer.dll b/bin/OpenMetaverse.Rendering.Meshmerizer.dll index 6139a9d..a6dec04 100755 Binary files a/bin/OpenMetaverse.Rendering.Meshmerizer.dll and b/bin/OpenMetaverse.Rendering.Meshmerizer.dll differ diff --git a/bin/OpenMetaverse.StructuredData.dll b/bin/OpenMetaverse.StructuredData.dll index e3b729c..ed0a2d6 100755 Binary files a/bin/OpenMetaverse.StructuredData.dll and b/bin/OpenMetaverse.StructuredData.dll differ diff --git a/bin/OpenMetaverse.dll b/bin/OpenMetaverse.dll index 69c4e9b..37ec47a 100755 Binary files a/bin/OpenMetaverse.dll and b/bin/OpenMetaverse.dll differ diff --git a/bin/OpenMetaverseTypes.dll b/bin/OpenMetaverseTypes.dll index cab014d..6f7fbac 100755 Binary files a/bin/OpenMetaverseTypes.dll and b/bin/OpenMetaverseTypes.dll differ -- cgit v1.1 From 392d270264610e7c20cb4becedc652843715ef30 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 31 May 2011 18:49:38 +0100 Subject: revert the patch that accidentally got added in the last commit --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 ++++------------------ 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 05223e0..1c791b9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1231,36 +1231,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - // c_scene and property accessor 'is_god' are in support of the opertions to bypass 'hidden' group attributes for - // those with a GodLike aspect. - Scene c_scene = (Scene) requestingClient.Scene; - bool is_god = c_scene.Permissions.IsGod(requestingClient.AgentId); - - if(is_god) { + if (requestingClient.AgentId != dataForAgentID) + { Predicate showInProfile = delegate(GroupMembershipData membership) { return membership.ListInProfile; }; - membershipArray = membershipData.ToArray(); + membershipArray = membershipData.FindAll(showInProfile).ToArray(); } else { - - if (requestingClient.AgentId != dataForAgentID) - { - Predicate showInProfile = delegate(GroupMembershipData membership) - { - return membership.ListInProfile; - }; - - membershipArray = membershipData.FindAll(showInProfile).ToArray(); - } - else - { - membershipArray = membershipData.ToArray(); - } + membershipArray = membershipData.ToArray(); } + if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1273,7 +1257,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } - private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From 8129e64e2acea6509d5c3a80425f6aa68baa037c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 31 May 2011 19:25:01 +0100 Subject: Fill in the new OwnerData field in the LLUDP ScriptDialog message. If we don't do this then viewer 2.8 crashes. Resolves http://opensimulator.org/mantis/view.php?id=5510 --- OpenSim/Framework/IClientAPI.cs | 14 ++++++++++- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 11 ++++++--- .../CoreModules/Avatar/Dialog/DialogModule.cs | 3 ++- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 2 +- .../Server/IRCClientView.cs | 2 +- .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 ++++++++++++++++++---- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 +- OpenSim/Tests/Common/Mock/TestClient.cs | 2 +- 8 files changed, 49 insertions(+), 14 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index f3ac2df..137f432 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1159,7 +1159,19 @@ namespace OpenSim.Framework void SendAgentAlertMessage(string message, bool modal); void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url); - void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, + /// + /// Open a dialog box on the client. + /// + /// + /// + /// /param> + /// + /// + /// + /// + /// + /// + void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels); bool AddMoney(int debit); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 5a2c45c..821a370 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -2213,7 +2213,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(loadURL, ThrottleOutPacketType.Task); } - public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) + public void SendDialog( + string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, + UUID textureID, int ch, string[] buttonlabels) { ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); dialog.Data.ObjectID = objectID; @@ -2231,6 +2233,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]); } dialog.Buttons = buttons; + + dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1]; + dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock(); + dialog.OwnerData[0].OwnerID = ownerID; + OutPacket(dialog, ThrottleOutPacketType.Task); } @@ -2293,8 +2300,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff; } - - SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage); viewertime.TimeInfo.SunDirection = Position; viewertime.TimeInfo.SunAngVelocity = Velocity; diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index 8a977c9..0db31eb 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 ScenePresence sp = m_scene.GetScenePresence(avatarID); if (sp != null) - sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); + sp.ControllingClient.SendDialog( + objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); } public void SendUrlToUser( diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 89e9e20..56b46d7 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -540,7 +540,7 @@ namespace OpenSim.Region.Examples.SimpleModule { } - public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) + public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) { } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 4b6e52e..88db20e 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1177,7 +1177,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server IRC_SendChannelPrivmsg(objectname,url); } - public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) + public void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) { } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 1c791b9..05223e0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1231,20 +1231,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - if (requestingClient.AgentId != dataForAgentID) - { + // c_scene and property accessor 'is_god' are in support of the opertions to bypass 'hidden' group attributes for + // those with a GodLike aspect. + Scene c_scene = (Scene) requestingClient.Scene; + bool is_god = c_scene.Permissions.IsGod(requestingClient.AgentId); + + if(is_god) { Predicate showInProfile = delegate(GroupMembershipData membership) { return membership.ListInProfile; }; - membershipArray = membershipData.FindAll(showInProfile).ToArray(); + membershipArray = membershipData.ToArray(); } else { - membershipArray = membershipData.ToArray(); - } + if (requestingClient.AgentId != dataForAgentID) + { + Predicate showInProfile = delegate(GroupMembershipData membership) + { + return membership.ListInProfile; + }; + + membershipArray = membershipData.FindAll(showInProfile).ToArray(); + } + else + { + membershipArray = membershipData.ToArray(); + } + } if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1257,6 +1273,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } + private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 2504e30..15bc1b7 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 { } - public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) + public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index dca5626..bf91ab5 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -637,7 +637,7 @@ namespace OpenSim.Tests.Common.Mock { } - public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) + public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) { } -- cgit v1.1 From c67fa72d5628725581b61b7a16c37955e154006d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 31 May 2011 19:57:08 +0100 Subject: When sending an LLUDP MoneyBalanceReply message, fill out the transaction item description even though there is none. This is to deal with a problem in libomv where calling ToBytes() without this crashes because of an ItemDescription.Lnegth dereference. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 821a370..d8fcb62 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1469,6 +1469,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP money.MoneyData.TransactionSuccess = success; money.MoneyData.Description = description; money.MoneyData.MoneyBalance = balance; + money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE"); OutPacket(money, ThrottleOutPacketType.Task); } -- cgit v1.1 From 5711ada5c98bb6769eb5454380945791c14227e0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 31 May 2011 22:42:18 +0100 Subject: Fix dumb sql mistake in MSSQLGenericTableHandler.Delete() --- OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs index 317afac..ab9df4c 100644 --- a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs +++ b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs @@ -358,7 +358,7 @@ namespace OpenSim.Data.MSSQL string where = String.Join(" AND ", terms.ToArray()); - string query = String.Format("DELETE * FROM {0} WHERE {1}", m_Realm, where); + string query = String.Format("DELETE FROM {0} WHERE {1}", m_Realm, where); cmd.Connection = conn; cmd.CommandText = query; -- cgit v1.1 From aed6e74080a23bab148c085140e412aa0ba0aef2 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Wed, 1 Jun 2011 13:44:20 -0400 Subject: Add alternate region handling for url based logins as found in login to "home" or "last" --- OpenSim/Services/LLLoginService/LLLoginService.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index a5a728b..5d1779a 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -516,6 +516,7 @@ namespace OpenSim.Services.LLLoginService // free uri form // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34 where = "url"; + GridRegion region = null; Regex reURI = new Regex(@"^uri:(?[^&]+)&(?\d+)&(?\d+)&(?\d+)$"); Match uriMatch = reURI.Match(startLocation); if (uriMatch == null) @@ -546,8 +547,18 @@ namespace OpenSim.Services.LLLoginService } else { - m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions.", startLocation); - return null; + m_log.Info("[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region"); + region = FindAlternativeRegion(scopeID); + if (region != null) + { + where = "safe"; + return region; + } + else + { + m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions and no alternative found.", startLocation); + return null; + } } } return regions[0]; @@ -575,7 +586,8 @@ namespace OpenSim.Services.LLLoginService if (parts.Length > 1) UInt32.TryParse(parts[1], out port); - GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper); +// GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper); + region = FindForeignRegion(domainName, port, regionName, out gatekeeper); return region; } } -- cgit v1.1 From 8bacf56e46413edaf2d6afc227ff6bb5f2ac4d4d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 1 Jun 2011 20:51:38 +0100 Subject: revert the prematurely included groups patch, yet again --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 ++++------------------ 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 05223e0..1c791b9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1231,36 +1231,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - // c_scene and property accessor 'is_god' are in support of the opertions to bypass 'hidden' group attributes for - // those with a GodLike aspect. - Scene c_scene = (Scene) requestingClient.Scene; - bool is_god = c_scene.Permissions.IsGod(requestingClient.AgentId); - - if(is_god) { + if (requestingClient.AgentId != dataForAgentID) + { Predicate showInProfile = delegate(GroupMembershipData membership) { return membership.ListInProfile; }; - membershipArray = membershipData.ToArray(); + membershipArray = membershipData.FindAll(showInProfile).ToArray(); } else { - - if (requestingClient.AgentId != dataForAgentID) - { - Predicate showInProfile = delegate(GroupMembershipData membership) - { - return membership.ListInProfile; - }; - - membershipArray = membershipData.FindAll(showInProfile).ToArray(); - } - else - { - membershipArray = membershipData.ToArray(); - } + membershipArray = membershipData.ToArray(); } + if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1273,7 +1257,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } - private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From c43ad8a0e7728c41ed2a4aed6a8b76678aaa7071 Mon Sep 17 00:00:00 2001 From: James Stallings aka Hiro Protagonist Date: Tue, 31 May 2011 19:33:40 -0500 Subject: A final couple of tweaks to GroupsModule.cs. Remove unneeded delegate, and prettify codeing style/formatting --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 31 +++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 1c791b9..61c5503 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 /// /// Get a list of groups memberships for the agent that are marked "ListInProfile" + /// (unless that agent has a godLike aspect, in which case get all groups) /// /// /// @@ -1231,20 +1232,31 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - if (requestingClient.AgentId != dataForAgentID) - { - Predicate showInProfile = delegate(GroupMembershipData membership) - { - return membership.ListInProfile; - }; + // cScene and property accessor 'isGod' are in support of the opertions to bypass 'hidden' group attributes for + // those with a GodLike aspect. + Scene cScene = (Scene) requestingClient.Scene; + bool isGod = cScene.Permissions.IsGod(requestingClient.AgentId); - membershipArray = membershipData.FindAll(showInProfile).ToArray(); + if (isGod) { + membershipArray = membershipData.ToArray(); } else { - membershipArray = membershipData.ToArray(); - } + if (requestingClient.AgentId != dataForAgentID) + { + Predicate showInProfile = delegate(GroupMembershipData membership) + { + return membership.ListInProfile; + }; + + membershipArray = membershipData.FindAll(showInProfile).ToArray(); + } + else + { + membershipArray = membershipData.ToArray(); + } + } if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1257,6 +1269,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } + private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From a3e0895f12fa81074138a356c01fbcbc40d6aba2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 1 Jun 2011 20:55:03 +0100 Subject: a few minor formatting tweaks --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 61c5503..630fcab 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1234,15 +1234,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // cScene and property accessor 'isGod' are in support of the opertions to bypass 'hidden' group attributes for // those with a GodLike aspect. - Scene cScene = (Scene) requestingClient.Scene; + Scene cScene = (Scene)requestingClient.Scene; bool isGod = cScene.Permissions.IsGod(requestingClient.AgentId); - if (isGod) { + if (isGod) + { membershipArray = membershipData.ToArray(); } else { - if (requestingClient.AgentId != dataForAgentID) { Predicate showInProfile = delegate(GroupMembershipData membership) @@ -1257,6 +1257,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups membershipArray = membershipData.ToArray(); } } + if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); -- cgit v1.1 From 5fb0455e929d96efb41d23f67653b329792ab834 Mon Sep 17 00:00:00 2001 From: Chris Hart Date: Wed, 1 Jun 2011 04:01:18 +0100 Subject: Updates to MSSQL to most recent compatibility, also included Windlight support. Needs plenty of testing but clean install and migration from 0.6.9 have been tested and work, a few indexes still need to be added for performance. --- OpenSim/Data/MSSQL/MSSQLEstateData.cs | 203 +++++++- OpenSim/Data/MSSQL/MSSQLFriendsData.cs | 1 - OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs | 22 +- OpenSim/Data/MSSQL/MSSQLMigration.cs | 32 +- OpenSim/Data/MSSQL/MSSQLRegionData.cs | 1 + OpenSim/Data/MSSQL/MSSQLSimulationData.cs | 513 ++++++++++++++++++++- OpenSim/Data/MSSQL/MSSQLXInventoryData.cs | 32 +- OpenSim/Data/MSSQL/Resources/Avatar.migrations | 24 + .../Data/MSSQL/Resources/GridUserStore.migrations | 46 ++ .../Data/MSSQL/Resources/RegionStore.migrations | 2 +- 10 files changed, 828 insertions(+), 48 deletions(-) diff --git a/OpenSim/Data/MSSQL/MSSQLEstateData.cs b/OpenSim/Data/MSSQL/MSSQLEstateData.cs index d10ebe4..9c54e77 100644 --- a/OpenSim/Data/MSSQL/MSSQLEstateData.cs +++ b/OpenSim/Data/MSSQL/MSSQLEstateData.cs @@ -41,7 +41,7 @@ namespace OpenSim.Data.MSSQL { private const string _migrationStore = "EstateStore"; - private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private MSSQLManager _Database; private string m_connectionString; @@ -72,7 +72,12 @@ namespace OpenSim.Data.MSSQL } //Migration settings - _Database.CheckMigration(_migrationStore); + using (SqlConnection conn = new SqlConnection(m_connectionString)) + { + conn.Open(); + Migration m = new Migration(conn, GetType().Assembly, "EstateStore"); + m.Update(); + } //Interesting way to get parameters! Maybe implement that also with other types Type t = typeof(EstateSettings); @@ -112,19 +117,19 @@ namespace OpenSim.Data.MSSQL { FieldInfo f = _FieldMap[name]; object v = reader[name]; - if (f.FieldType == typeof(bool) ) + if (f.FieldType == typeof(bool)) { f.SetValue(es, Convert.ToInt32(v) != 0); } - else if (f.FieldType == typeof(UUID) ) + else if (f.FieldType == typeof(UUID)) { f.SetValue(es, new UUID((Guid)v)); // uuid); } - else if (f.FieldType == typeof(string)) + else if (f.FieldType == typeof(string)) { f.SetValue(es, v.ToString()); } - else if (f.FieldType == typeof(UInt32)) + else if (f.FieldType == typeof(UInt32)) { f.SetValue(es, Convert.ToUInt32(v)); } @@ -186,7 +191,7 @@ namespace OpenSim.Data.MSSQL } catch (Exception e) { - _Log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e); + m_log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e); } } @@ -310,12 +315,12 @@ namespace OpenSim.Data.MSSQL conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { - cmd.CommandText = "delete from estateban where EstateID = @EstateID"; + cmd.CommandText = "delete from estateban where EstateID = @EstateID"; cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID); cmd.ExecuteNonQuery(); //Insert after - cmd.CommandText = "insert into estateban (EstateID, bannedUUID) values ( @EstateID, @bannedUUID )"; + cmd.CommandText = "insert into estateban (EstateID, bannedUUID,bannedIp, bannedIpHostMask, bannedNameMask) values ( @EstateID, @bannedUUID, '','','' )"; cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty); foreach (EstateBan b in es.EstateBans) { @@ -350,43 +355,195 @@ namespace OpenSim.Data.MSSQL public EstateSettings LoadEstateSettings(int estateID) { - // TODO: Implementation! - return new EstateSettings(); + EstateSettings es = new EstateSettings(); + string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = @EstateID"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + { + conn.Open(); + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.AddWithValue("@EstateID", (int)estateID); + using (SqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) + { + foreach (string name in FieldList) + { + FieldInfo f = _FieldMap[name]; + object v = reader[name]; + if (f.FieldType == typeof(bool)) + { + f.SetValue(es, Convert.ToInt32(v) != 0); + } + else if (f.FieldType == typeof(UUID)) + { + f.SetValue(es, new UUID((Guid)v)); // uuid); + } + else if (f.FieldType == typeof(string)) + { + f.SetValue(es, v.ToString()); + } + else if (f.FieldType == typeof(UInt32)) + { + f.SetValue(es, Convert.ToUInt32(v)); + } + else if (f.FieldType == typeof(Single)) + { + f.SetValue(es, Convert.ToSingle(v)); + } + else + f.SetValue(es, v); + } + } + + } + } + } + LoadBanList(es); + + es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); + es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); + es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); + + //Set event + es.OnSave += StoreEstateSettings; + return es; + } - + public List LoadEstateSettingsAll() { - // TODO: Implementation! - return new List(); + List allEstateSettings = new List(); + + List allEstateIds = GetEstatesAll(); + + foreach (int estateId in allEstateIds) + allEstateSettings.Add(LoadEstateSettings(estateId)); + + return allEstateSettings; } public List GetEstates(string search) { - // TODO: Implementation! - return new List(); + List result = new List(); + string sql = "select estateID from estate_settings where EstateName = @EstateName"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + { + conn.Open(); + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.AddWithValue("@EstateName", search); + + using (IDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + result.Add(Convert.ToInt32(reader["EstateID"])); + } + reader.Close(); + } + } + } + + return result; } - + public List GetEstatesAll() { - // TODO: Implementation! - return new List(); + List result = new List(); + string sql = "select estateID from estate_settings"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + { + conn.Open(); + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + using (IDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + result.Add(Convert.ToInt32(reader["EstateID"])); + } + reader.Close(); + } + } + } + + return result; } public List GetEstatesByOwner(UUID ownerID) { - return new List(); + List result = new List(); + string sql = "select estateID from estate_settings where EstateOwner = @EstateOwner"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + { + conn.Open(); + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.AddWithValue("@EstateOwner", ownerID); + + using (IDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + result.Add(Convert.ToInt32(reader["EstateID"])); + } + reader.Close(); + } + } + } + + return result; } public bool LinkRegion(UUID regionID, int estateID) { - // TODO: Implementation! + string sql = "insert into estate_map values (@RegionID, @EstateID)"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + { + conn.Open(); + try + { + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.AddWithValue("@RegionID", regionID); + cmd.Parameters.AddWithValue("@EstateID", estateID); + + int ret = cmd.ExecuteNonQuery(); + return (ret != 0); + } + } + catch (Exception ex) + { + m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message); + } + } return false; } public List GetRegions(int estateID) { - // TODO: Implementation! - return new List(); + List result = new List(); + string sql = "select RegionID from estate_map where EstateID = @EstateID"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + { + conn.Open(); + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.AddWithValue("@EstateID", estateID); + + using (IDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + result.Add(DBGuid.FromDB(reader["RegionID"])); + } + reader.Close(); + } + } + } + + return result; } public bool DeleteEstate(int estateID) diff --git a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs index 0b178f1..09dde5e 100644 --- a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs +++ b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs @@ -89,6 +89,5 @@ namespace OpenSim.Data.MSSQL return DoQuery(cmd); } } - } } diff --git a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs index ab9df4c..4145d95 100644 --- a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs +++ b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs @@ -168,14 +168,13 @@ namespace OpenSim.Data.MSSQL protected T[] DoQuery(SqlCommand cmd) { + List result = new List(); using (SqlDataReader reader = cmd.ExecuteReader()) { if (reader == null) return new T[0]; - CheckColumnNames(reader); - - List result = new List(); + CheckColumnNames(reader); while (reader.Read()) { @@ -262,6 +261,15 @@ namespace OpenSim.Data.MSSQL { names.Add(fi.Name); values.Add("@" + fi.Name); + // Temporarily return more information about what field is unexpectedly null for + // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the + // InventoryTransferModule or we may be required to substitute a DBNull here. + if (fi.GetValue(row) == null) + throw new NullReferenceException( + string.Format( + "[MSSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null", + fi.Name, row)); + if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name)) { constraints.Add(new KeyValuePair(fi.Name, fi.GetValue(row).ToString())); @@ -363,7 +371,13 @@ namespace OpenSim.Data.MSSQL cmd.Connection = conn; cmd.CommandText = query; conn.Open(); - return cmd.ExecuteNonQuery() > 0; + + if (cmd.ExecuteNonQuery() > 0) + { + //m_log.Warn("[MSSQLGenericTable]: " + deleteCommand); + return true; + } + return false; } } } diff --git a/OpenSim/Data/MSSQL/MSSQLMigration.cs b/OpenSim/Data/MSSQL/MSSQLMigration.cs index cd395b8..1aa96c7 100644 --- a/OpenSim/Data/MSSQL/MSSQLMigration.cs +++ b/OpenSim/Data/MSSQL/MSSQLMigration.cs @@ -29,16 +29,19 @@ using System; using System.Data; using System.Data.Common; using System.Reflection; +using System.Data.SqlClient; namespace OpenSim.Data.MSSQL { public class MSSQLMigration : Migration { - public MSSQLMigration(DbConnection conn, Assembly assem, string type) : base(conn, assem, type) + public MSSQLMigration(DbConnection conn, Assembly assem, string type) + : base(conn, assem, type) { } - public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type) : base(conn, assem, subtype, type) + public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type) + : base(conn, assem, subtype, type) { } @@ -67,5 +70,30 @@ namespace OpenSim.Data.MSSQL } return version; } + + protected override void ExecuteScript(DbConnection conn, string[] script) + { + if (!(conn is SqlConnection)) + { + base.ExecuteScript(conn, script); + return; + } + + foreach (string sql in script) + { + try + { + using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)conn)) + { + cmd.ExecuteNonQuery(); + } + } + catch (Exception ex) + { + throw new Exception(sql); + + } + } + } } } diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index cdf8ec0..3ae87c3 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs @@ -70,6 +70,7 @@ namespace OpenSim.Data.MSSQL string sql = "select * from ["+m_Realm+"] where regionName like @regionName"; if (scopeID != UUID.Zero) sql += " and ScopeID = @scopeID"; + sql += " order by regionName"; using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) { diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs index 5155e56..78f80e1 100644 --- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs +++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs @@ -55,6 +55,10 @@ namespace OpenSim.Data.MSSQL /// private MSSQLManager _Database; private string m_connectionString; + protected virtual Assembly Assembly + { + get { return GetType().Assembly; } + } public MSSQLSimulationData() { @@ -74,9 +78,28 @@ namespace OpenSim.Data.MSSQL m_connectionString = connectionString; _Database = new MSSQLManager(connectionString); + using (SqlConnection conn = new SqlConnection(connectionString)) + { + conn.Open(); + //New Migration settings + Migration m = new Migration(conn, Assembly, "RegionStore"); + m.Update(); - //Migration settings - _Database.CheckMigration(_migrationStore); + // Clean dropped attachments + // + try + { + using (SqlCommand cmd = conn.CreateCommand()) + { + cmd.CommandText = "delete from prims where prims.UUID in (select UUID from primshapes where PCode = 9 and State <> 0); delete from primshapes where PCode = 9 and State <> 0"; + cmd.ExecuteNonQuery(); + } + } + catch (Exception ex) + { + _Log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message); + } + } } /// @@ -214,7 +237,7 @@ namespace OpenSim.Data.MSSQL { command.Parameters.Clear(); command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID)); - + List inventory = new List(); using (SqlDataReader reader = command.ExecuteReader()) @@ -241,6 +264,14 @@ namespace OpenSim.Data.MSSQL /// public void StoreObject(SceneObjectGroup obj, UUID regionUUID) { + uint flags = obj.RootPart.GetEffectiveObjectFlags(); + // Eligibility check + // + if ((flags & (uint)PrimFlags.Temporary) != 0) + return; + if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) + return; + _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Parts.Length); using (SqlConnection conn = new SqlConnection(m_connectionString)) @@ -700,16 +731,470 @@ VALUES } public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) { - //This connector doesn't support the windlight module yet - //Return default LL windlight settings - return new RegionLightShareData(); + RegionLightShareData nWP = new RegionLightShareData(); + nWP.OnSave += StoreRegionWindlightSettings; + string sql = "select * from [regionwindlight] where region_id = @regionID"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("@regionID", regionUUID)); + conn.Open(); + using (SqlDataReader result = cmd.ExecuteReader()) + { + if (!result.Read()) + { + //No result, so store our default windlight profile and return it + nWP.regionID = regionUUID; + StoreRegionWindlightSettings(nWP); + return nWP; + } + else + { + nWP.regionID = DBGuid.FromDB(result["region_id"]); + nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); + nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); + nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); + nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); + nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); + nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); + nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); + nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); + nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); + nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); + nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); + nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); + nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); + nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); + nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); + nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); + nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); + UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); + nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); + nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); + nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); + nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); + nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); + nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); + nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); + nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); + nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); + nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); + nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); + nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); + nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); + nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); + nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); + nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); + nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); + nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); + nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); + nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); + nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); + nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); + nWP.eastAngle = Convert.ToSingle(result["east_angle"]); + nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); + nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); + nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); + nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); + nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); + nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); + nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); + nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); + nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); + nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); + nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); + nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); + nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); + nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); + nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); + nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); + nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); + nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); + nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); + nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); + nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); + nWP.valid = true; + } + } + } + return nWP; } + public void RemoveRegionWindlightSettings(UUID regionID) { + string sql = "delete from [regionwindlight] where region_id = @region_id"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + conn.Open(); + cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionID)); + cmd.ExecuteNonQuery(); + } } + public void StoreRegionWindlightSettings(RegionLightShareData wl) { - //This connector doesn't support the windlight module yet + string sql = "select count (region_id) from regionwindlight where region_id = @region_id"; + bool exists = false; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + { + conn.Open(); + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("@region_id", wl.regionID)); + exists = (int)cmd.ExecuteScalar() > 0; + } + } + if (exists) + { + RemoveRegionWindlightSettings(wl.regionID); + } + + // sql insert + sql = @"INSERT INTO [regionwindlight] + ([region_id] + ,[water_color_r] + ,[water_color_g] + ,[water_color_b] + ,[water_fog_density_exponent] + ,[underwater_fog_modifier] + ,[reflection_wavelet_scale_1] + ,[reflection_wavelet_scale_2] + ,[reflection_wavelet_scale_3] + ,[fresnel_scale] + ,[fresnel_offset] + ,[refract_scale_above] + ,[refract_scale_below] + ,[blur_multiplier] + ,[big_wave_direction_x] + ,[big_wave_direction_y] + ,[little_wave_direction_x] + ,[little_wave_direction_y] + ,[normal_map_texture] + ,[horizon_r] + ,[horizon_g] + ,[horizon_b] + ,[horizon_i] + ,[haze_horizon] + ,[blue_density_r] + ,[blue_density_g] + ,[blue_density_b] + ,[blue_density_i] + ,[haze_density] + ,[density_multiplier] + ,[distance_multiplier] + ,[max_altitude] + ,[sun_moon_color_r] + ,[sun_moon_color_g] + ,[sun_moon_color_b] + ,[sun_moon_color_i] + ,[sun_moon_position] + ,[ambient_r] + ,[ambient_g] + ,[ambient_b] + ,[ambient_i] + ,[east_angle] + ,[sun_glow_focus] + ,[sun_glow_size] + ,[scene_gamma] + ,[star_brightness] + ,[cloud_color_r] + ,[cloud_color_g] + ,[cloud_color_b] + ,[cloud_color_i] + ,[cloud_x] + ,[cloud_y] + ,[cloud_density] + ,[cloud_coverage] + ,[cloud_scale] + ,[cloud_detail_x] + ,[cloud_detail_y] + ,[cloud_detail_density] + ,[cloud_scroll_x] + ,[cloud_scroll_x_lock] + ,[cloud_scroll_y] + ,[cloud_scroll_y_lock] + ,[draw_classic_clouds]) + VALUES + (@region_id + ,@water_color_r + ,@water_color_g + ,@water_color_b + ,@water_fog_density_exponent + ,@underwater_fog_modifier + ,@reflection_wavelet_scale_1 + ,@reflection_wavelet_scale_2 + ,@reflection_wavelet_scale_3 + ,@fresnel_scale + ,@fresnel_offset + ,@refract_scale_above + ,@refract_scale_below + ,@blur_multiplier + ,@big_wave_direction_x + ,@big_wave_direction_y + ,@little_wave_direction_x + ,@little_wave_direction_y + ,@normal_map_texture + ,@horizon_r + ,@horizon_g + ,@horizon_b + ,@horizon_i + ,@haze_horizon + ,@blue_density_r + ,@blue_density_g + ,@blue_density_b + ,@blue_density_i + ,@haze_density + ,@density_multiplier + ,@distance_multiplier + ,@max_altitude + ,@sun_moon_color_r + ,@sun_moon_color_g + ,@sun_moon_color_b + ,@sun_moon_color_i + ,@sun_moon_position + ,@ambient_r + ,@ambient_g + ,@ambient_b + ,@ambient_i + ,@east_angle + ,@sun_glow_focus + ,@sun_glow_size + ,@scene_gamma + ,@star_brightness + ,@cloud_color_r + ,@cloud_color_g + ,@cloud_color_b + ,@cloud_color_i + ,@cloud_x + ,@cloud_y + ,@cloud_density + ,@cloud_coverage + ,@cloud_scale + ,@cloud_detail_x + ,@cloud_detail_y + ,@cloud_detail_density + ,@cloud_scroll_x + ,@cloud_scroll_x_lock + ,@cloud_scroll_y + ,@cloud_scroll_y_lock + ,@draw_classic_clouds)"; + using (SqlConnection conn = new SqlConnection(m_connectionString)) + { + conn.Open(); + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + cmd.Parameters.Add(_Database.CreateParameter("region_id", wl.regionID)); + cmd.Parameters.Add(_Database.CreateParameter("water_color_r", wl.waterColor.X)); + cmd.Parameters.Add(_Database.CreateParameter("water_color_g", wl.waterColor.Y)); + cmd.Parameters.Add(_Database.CreateParameter("water_color_b", wl.waterColor.Z)); + cmd.Parameters.Add(_Database.CreateParameter("water_fog_density_exponent", wl.waterFogDensityExponent)); + cmd.Parameters.Add(_Database.CreateParameter("underwater_fog_modifier", wl.underwaterFogModifier)); + cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X)); + cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y)); + cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z)); + cmd.Parameters.Add(_Database.CreateParameter("fresnel_scale", wl.fresnelScale)); + cmd.Parameters.Add(_Database.CreateParameter("fresnel_offset", wl.fresnelOffset)); + cmd.Parameters.Add(_Database.CreateParameter("refract_scale_above", wl.refractScaleAbove)); + cmd.Parameters.Add(_Database.CreateParameter("refract_scale_below", wl.refractScaleBelow)); + cmd.Parameters.Add(_Database.CreateParameter("blur_multiplier", wl.blurMultiplier)); + cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_x", wl.bigWaveDirection.X)); + cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_y", wl.bigWaveDirection.Y)); + cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_x", wl.littleWaveDirection.X)); + cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_y", wl.littleWaveDirection.Y)); + cmd.Parameters.Add(_Database.CreateParameter("normal_map_texture", wl.normalMapTexture)); + cmd.Parameters.Add(_Database.CreateParameter("horizon_r", wl.horizon.X)); + cmd.Parameters.Add(_Database.CreateParameter("horizon_g", wl.horizon.Y)); + cmd.Parameters.Add(_Database.CreateParameter("horizon_b", wl.horizon.Z)); + cmd.Parameters.Add(_Database.CreateParameter("horizon_i", wl.horizon.W)); + cmd.Parameters.Add(_Database.CreateParameter("haze_horizon", wl.hazeHorizon)); + cmd.Parameters.Add(_Database.CreateParameter("blue_density_r", wl.blueDensity.X)); + cmd.Parameters.Add(_Database.CreateParameter("blue_density_g", wl.blueDensity.Y)); + cmd.Parameters.Add(_Database.CreateParameter("blue_density_b", wl.blueDensity.Z)); + cmd.Parameters.Add(_Database.CreateParameter("blue_density_i", wl.blueDensity.W)); + cmd.Parameters.Add(_Database.CreateParameter("haze_density", wl.hazeDensity)); + cmd.Parameters.Add(_Database.CreateParameter("density_multiplier", wl.densityMultiplier)); + cmd.Parameters.Add(_Database.CreateParameter("distance_multiplier", wl.distanceMultiplier)); + cmd.Parameters.Add(_Database.CreateParameter("max_altitude", wl.maxAltitude)); + cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_r", wl.sunMoonColor.X)); + cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_g", wl.sunMoonColor.Y)); + cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_b", wl.sunMoonColor.Z)); + cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_i", wl.sunMoonColor.W)); + cmd.Parameters.Add(_Database.CreateParameter("sun_moon_position", wl.sunMoonPosition)); + cmd.Parameters.Add(_Database.CreateParameter("ambient_r", wl.ambient.X)); + cmd.Parameters.Add(_Database.CreateParameter("ambient_g", wl.ambient.Y)); + cmd.Parameters.Add(_Database.CreateParameter("ambient_b", wl.ambient.Z)); + cmd.Parameters.Add(_Database.CreateParameter("ambient_i", wl.ambient.W)); + cmd.Parameters.Add(_Database.CreateParameter("east_angle", wl.eastAngle)); + cmd.Parameters.Add(_Database.CreateParameter("sun_glow_focus", wl.sunGlowFocus)); + cmd.Parameters.Add(_Database.CreateParameter("sun_glow_size", wl.sunGlowSize)); + cmd.Parameters.Add(_Database.CreateParameter("scene_gamma", wl.sceneGamma)); + cmd.Parameters.Add(_Database.CreateParameter("star_brightness", wl.starBrightness)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_color_r", wl.cloudColor.X)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_color_g", wl.cloudColor.Y)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_color_b", wl.cloudColor.Z)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_color_i", wl.cloudColor.W)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_x", wl.cloudXYDensity.X)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_y", wl.cloudXYDensity.Y)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_density", wl.cloudXYDensity.Z)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_coverage", wl.cloudCoverage)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_scale", wl.cloudScale)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_x", wl.cloudDetailXYDensity.X)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_y", wl.cloudDetailXYDensity.Y)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_density", wl.cloudDetailXYDensity.Z)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x", wl.cloudScrollX)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x_lock", wl.cloudScrollXLock)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y", wl.cloudScrollY)); + cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y_lock", wl.cloudScrollYLock)); + cmd.Parameters.Add(_Database.CreateParameter("draw_classic_clouds", wl.drawClassicClouds)); + + cmd.ExecuteNonQuery(); + } + } + #region update + // } + // else + // { + // // sql update + // sql = @"UPDATE [OpenSim].[dbo].[regionwindlight] + // SET [region_id] = @region_id + // ,[water_color_r] = @water_color_r + // ,[water_color_g] = @water_color_g + // ,[water_color_b] = @water_color_b + // ,[water_fog_density_exponent] = @water_fog_density_exponent + // ,[underwater_fog_modifier] = @underwater_fog_modifier + // ,[reflection_wavelet_scale_1] = @reflection_wavelet_scale_1 + // ,[reflection_wavelet_scale_2] = @reflection_wavelet_scale_2 + // ,[reflection_wavelet_scale_3] = @reflection_wavelet_scale_3 + // ,[fresnel_scale] = @fresnel_scale + // ,[fresnel_offset] = @fresnel_offset + // ,[refract_scale_above] = @refract_scale_above + // ,[refract_scale_below] = @refract_scale_below + // ,[blur_multiplier] = @blur_multiplier + // ,[big_wave_direction_x] = @big_wave_direction_x + // ,[big_wave_direction_y] = @big_wave_direction_y + // ,[little_wave_direction_x] = @little_wave_direction_x + // ,[little_wave_direction_y] = @little_wave_direction_y + // ,[normal_map_texture] = @normal_map_texture + // ,[horizon_r] = @horizon_r + // ,[horizon_g] = @horizon_g + // ,[horizon_b] = @horizon_b + // ,[horizon_i] = @horizon_i + // ,[haze_horizon] = @haze_horizon + // ,[blue_density_r] = @blue_density_r + // ,[blue_density_g] = @blue_density_g + // ,[blue_density_b] = @blue_density_b + // ,[blue_density_i] = @blue_density_i + // ,[haze_density] = @haze_density + // ,[density_multiplier] = @density_multiplier + // ,[distance_multiplier] = @distance_multiplier + // ,[max_altitude] = @max_altitude + // ,[sun_moon_color_r] = @sun_moon_color_r + // ,[sun_moon_color_g] = @sun_moon_color_g + // ,[sun_moon_color_b] = @sun_moon_color_b + // ,[sun_moon_color_i] = @sun_moon_color_i + // ,[sun_moon_position] = @sun_moon_position + // ,[ambient_r] = @ambient_r + // ,[ambient_g] = @ambient_g + // ,[ambient_b] = @ambient_b + // ,[ambient_i] = @ambient_i + // ,[east_angle] = @east_angle + // ,[sun_glow_focus] = @sun_glow_focus + // ,[sun_glow_size] = @sun_glow_size + // ,[scene_gamma] = @scene_gamma + // ,[star_brightness] = @star_brightness + // ,[cloud_color_r] = @cloud_color_r + // ,[cloud_color_g] = @cloud_color_g + // ,[cloud_color_b] = @cloud_color_b + // ,[cloud_color_i] = @cloud_color_i + // ,[cloud_x] = @cloud_x + // ,[cloud_y] = @cloud_y + // ,[cloud_density] = @cloud_density + // ,[cloud_coverage] = @cloud_coverage + // ,[cloud_scale] = @cloud_scale + // ,[cloud_detail_x] = @cloud_detail_x + // ,[cloud_detail_y] = @cloud_detail_y + // ,[cloud_detail_density] = @cloud_detail_density + // ,[cloud_scroll_x] = @cloud_scroll_x + // ,[cloud_scroll_x_lock] = @cloud_scroll_x_lock + // ,[cloud_scroll_y] = @cloud_scroll_y + // ,[cloud_scroll_y_lock] = @cloud_scroll_y_lock + // ,[draw_classic_clouds] = @draw_classic_clouds + // WHERE region_id = @region_id"; + // using (SqlConnection conn = new SqlConnection(m_connectionString)) + // { + // conn.Open(); + // using (SqlCommand cmd = new SqlCommand(sql, conn)) + // { + // cmd.Parameters.AddWithValue("region_id", wl.regionID); + // cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); + // cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); + // cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); + // cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); + // cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); + // cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); + // cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); + // cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); + // cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); + // cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); + // cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); + // cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); + // cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); + // cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); + // cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); + // cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); + // cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); + // cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); + // cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); + // cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); + // cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); + // cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); + // cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); + // cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); + // cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); + // cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); + // cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); + // cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); + // cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); + // cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); + // cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); + // cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); + // cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); + // cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); + // cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); + // cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); + // cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); + // cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); + // cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); + // cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); + // cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); + // cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); + // cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); + // cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); + // cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); + // cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); + // cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); + // cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); + // cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); + // cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); + // cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); + // cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); + // cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); + // cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); + // cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); + // cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); + // cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); + // cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); + // cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); + // cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); + // cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); + // cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); + + // cmd.ExecuteNonQuery(); + // } + // } + // } + #endregion } /// /// Loads the settings of a region. @@ -1136,7 +1621,7 @@ VALUES if (Convert.ToInt16(primRow["PassTouches"]) != 0) prim.PassTouches = true; prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); - + if (!(primRow["MediaURL"] is System.DBNull)) prim.MediaUrl = (string)primRow["MediaURL"]; @@ -1192,11 +1677,11 @@ VALUES { } - if (!(shapeRow["Media"] is System.DBNull) ) + if (!(shapeRow["Media"] is System.DBNull)) { baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]); } - + return baseShape; } @@ -1576,15 +2061,15 @@ VALUES parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); parameters.Add(_Database.CreateParameter("State", s.State)); - if(null == s.Media ) + if (null == s.Media) { - parameters.Add(_Database.CreateParameter("Media", DBNull.Value)); + parameters.Add(_Database.CreateParameter("Media", DBNull.Value)); } else { - parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml())); + parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml())); } - + return parameters.ToArray(); } diff --git a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs index 01689a4..10b0f29 100644 --- a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs +++ b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs @@ -66,11 +66,18 @@ namespace OpenSim.Data.MSSQL public bool StoreFolder(XInventoryFolder folder) { + if (folder.folderName.Length > 64) + folder.folderName = folder.folderName.Substring(0, 64); return m_Folders.Store(folder); } public bool StoreItem(XInventoryItem item) { + if (item.inventoryName.Length > 64) + item.inventoryName = item.inventoryName.Substring(0, 64); + if (item.inventoryDescription.Length > 128) + item.inventoryDescription = item.inventoryDescription.Substring(0, 128); + return m_Items.Store(item); } @@ -78,7 +85,6 @@ namespace OpenSim.Data.MSSQL { return m_Folders.Delete(field, val); } - public bool DeleteFolders(string[] fields, string[] vals) { return m_Folders.Delete(fields, vals); @@ -88,12 +94,10 @@ namespace OpenSim.Data.MSSQL { return m_Items.Delete(field, val); } - public bool DeleteItems(string[] fields, string[] vals) { return m_Items.Delete(fields, vals); } - public bool MoveItem(string id, string newParent) { return m_Items.MoveItem(id, newParent); @@ -172,5 +176,27 @@ namespace OpenSim.Data.MSSQL } } + public override bool Store(XInventoryItem item) + { + if (!base.Store(item)) + return false; + string sql = "update inventoryfolders set version=version+1 where folderID = @folderID"; + using (SqlConnection conn = new SqlConnection(m_ConnectionString)) + using (SqlCommand cmd = new SqlCommand(sql, conn)) + { + conn.Open(); + + cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString()); + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception e) + { + return false; + } + } + return true; + } } } diff --git a/OpenSim/Data/MSSQL/Resources/Avatar.migrations b/OpenSim/Data/MSSQL/Resources/Avatar.migrations index 5364153..61f7b56 100644 --- a/OpenSim/Data/MSSQL/Resources/Avatar.migrations +++ b/OpenSim/Data/MSSQL/Resources/Avatar.migrations @@ -37,4 +37,28 @@ EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT' COMMIT +:VERSION 3 + +BEGIN TRANSACTION + +CREATE TABLE dbo.Tmp_Avatars + ( + PrincipalID uniqueidentifier NOT NULL, + [Name] varchar(32) NOT NULL, + Value text NOT NULL DEFAULT '', + PRIMARY KEY CLUSTERED +( + [PrincipalID] ASC, [Name] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] + TEXTIMAGE_ON [PRIMARY] + +IF EXISTS(SELECT * FROM dbo.Avatars) + EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value) + SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)') + +DROP TABLE dbo.Avatars + +EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT' +COMMIT diff --git a/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations b/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations index 7a7cecd..ecd3f4d 100644 --- a/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations +++ b/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations @@ -17,3 +17,49 @@ CREATE TABLE "GridUser" ( ) COMMIT + +:VERSION 2 # -------------------------- + +BEGIN TRANSACTION + +CREATE TABLE [GridUser_tmp] ( + [UserID] VARCHAR(255) NOT NULL, + [HomeRegionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + [HomePosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>', + [HomeLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>', + [LastRegionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + [LastPosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>', + [LastLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>', + [Online] CHAR(5) NOT NULL DEFAULT 'false', + [Login] CHAR(16) NOT NULL DEFAULT '0', + [Logout] CHAR(16) NOT NULL DEFAULT '0', + + PRIMARY KEY CLUSTERED + ( + [UserID] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY] + +COMMIT + +IF EXISTS(SELECT * FROM dbo.GridUser) + EXEC('INSERT INTO dbo.GridUser_tmp ([UserID] + ,[HomeRegionID] + ,[HomePosition] + ,[HomeLookAt] + ,[LastRegionID] + ,[LastPosition] + ,[LastLookAt] + ,[Online] + ,[Login] + ,[Logout]) + SELECT CONVERT(varchar(36), [HomeRegionID]), [HomePosition] ,[HomeLookAt] , CONVERT(varchar(36),[LastRegionID]) + ,[LastPosition] + ,[LastLookAt] + ,[Online] + ,[Login] + ,[Logout] FROM dbo.GridUser WITH (HOLDLOCK TABLOCKX)') + +DROP TABLE dbo.GridUser + +EXECUTE sp_rename N'dbo.GridUser_tmp', N'GridUser', 'OBJECT' \ No newline at end of file diff --git a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations index 340b63d..3995e6c 100644 --- a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations @@ -1003,7 +1003,7 @@ CREATE TABLE "regionwindlight" ( PRIMARY KEY ("region_id") ) -COMMIT TRANSACTION +COMMIT :VERSION 26 -- cgit v1.1 From 54096db30b1b0a93de6bd3913e7000b55039b71a Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Tue, 31 May 2011 22:24:51 +0900 Subject: Fix: The command line switches 'save_crashes' and 'crash_dir' haven't actually worked --- OpenSim/Region/Application/Application.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 7e320e6..63c535d 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -239,6 +239,8 @@ namespace OpenSim configSource.AddSwitch("Startup", "physics"); configSource.AddSwitch("Startup", "gui"); configSource.AddSwitch("Startup", "console"); + configSource.AddSwitch("Startup", "save_crashes"); + configSource.AddSwitch("Startup", "crash_dir"); configSource.AddConfig("StandAlone"); configSource.AddConfig("Network"); -- cgit v1.1 From b0ed0e63dcc2c364b623ec2bf887c0a2fec8f80b Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Tue, 31 May 2011 21:38:32 +0900 Subject: Adding boolean alias for commandline switches like -save_crashes=yes --- OpenSim/Region/Application/Application.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 63c535d..3b261e7 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -231,6 +231,8 @@ namespace OpenSim configSource.Alias.AddAlias("Off", false); configSource.Alias.AddAlias("True", true); configSource.Alias.AddAlias("False", false); + configSource.Alias.AddAlias("Yes", true); + configSource.Alias.AddAlias("No", false); configSource.AddSwitch("Startup", "background"); configSource.AddSwitch("Startup", "inifile"); -- cgit v1.1 From 4b9e446c6267a1161263d885699e72c97e8a94eb Mon Sep 17 00:00:00 2001 From: BlueWall Date: Wed, 1 Jun 2011 16:57:01 -0400 Subject: Use current TravelingAgent if the login failure reason is "Logins Disabled" to fix NullReferenceException, allowing agent to login to fallback region when logins are disabled by "StartDisabled = true" or when logins are disabled by RegionReady --- OpenSim/Services/HypergridService/UserAgentService.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 387547e..2f2ebfb 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -197,8 +197,11 @@ namespace OpenSim.Services.HypergridService agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); // restore the old travel info - lock (m_TravelingAgents) - m_TravelingAgents[agentCircuit.SessionID] = old; + if(reason != "Logins Disabled") + { + lock (m_TravelingAgents) + m_TravelingAgents[agentCircuit.SessionID] = old; + } return false; } -- cgit v1.1 From 0a430bbffb561a5172220e7617257798c11a66f5 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Wed, 1 Jun 2011 18:10:56 -0400 Subject: Revert "Use current TravelingAgent if the login failure reason is "Logins Disabled" to fix NullReferenceException, allowing agent to login to fallback region when logins are disabled by "StartDisabled = true" or when logins are disabled by RegionReady" This reverts commit 4b9e446c6267a1161263d885699e72c97e8a94eb. --- OpenSim/Services/HypergridService/UserAgentService.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 2f2ebfb..387547e 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -197,11 +197,8 @@ namespace OpenSim.Services.HypergridService agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); // restore the old travel info - if(reason != "Logins Disabled") - { - lock (m_TravelingAgents) - m_TravelingAgents[agentCircuit.SessionID] = old; - } + lock (m_TravelingAgents) + m_TravelingAgents[agentCircuit.SessionID] = old; return false; } -- cgit v1.1 From 777f57d9469d4df11ea2bf2bd0704f89cae34b0a Mon Sep 17 00:00:00 2001 From: BlueWall Date: Wed, 1 Jun 2011 18:47:06 -0400 Subject: Re-Apply Use current TravelingAgent if the the login failure reason is "Logins Disabled" to fix NullReferenceException, allowing agent to login to fallback region when logins are disabled by "StartDisabled = true" or when logins are disabled by RegionReady"" This reverts commit 0a430bbffb561a5172220e7617257798c11a66f5. --- OpenSim/Services/HypergridService/UserAgentService.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 387547e..2f2ebfb 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -197,8 +197,11 @@ namespace OpenSim.Services.HypergridService agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); // restore the old travel info - lock (m_TravelingAgents) - m_TravelingAgents[agentCircuit.SessionID] = old; + if(reason != "Logins Disabled") + { + lock (m_TravelingAgents) + m_TravelingAgents[agentCircuit.SessionID] = old; + } return false; } -- cgit v1.1 From 46cdd442a8daebe5b1573f09cd5cef51c0b17874 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 1 Jun 2011 18:18:31 -0700 Subject: [Profiles] --> [Profile] --- OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs | 4 ++-- bin/config-include/Grid.ini | 2 +- bin/config-include/GridHypergrid.ini | 2 +- bin/config-include/Standalone.ini | 2 +- bin/config-include/StandaloneHypergrid.ini | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs index e04fff6..079e1b6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs @@ -57,9 +57,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile public void Initialise(IConfigSource config) { - if (config.Configs["Profiles"] != null) + if (config.Configs["Profile"] != null) { - if (config.Configs["Profiles"].GetString("Module", string.Empty) != "BasicProfileModule") + if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule") return; } diff --git a/bin/config-include/Grid.ini b/bin/config-include/Grid.ini index baadbb8..5220573 100644 --- a/bin/config-include/Grid.ini +++ b/bin/config-include/Grid.ini @@ -27,7 +27,7 @@ SimulationServiceInConnector = true LibraryModule = true -[Profiles] +[Profile] Module = "BasicProfileModule" [SimulationDataStore] diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index 510a315..b8e66c2 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -31,7 +31,7 @@ SimulationServiceInConnector = true LibraryModule = true -[Profiles] +[Profile] Module = "BasicProfileModule" [SimulationDataStore] diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index cfcf5ed..4ff1a26 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -22,7 +22,7 @@ LLLoginServiceInConnector = true GridInfoServiceInConnector = true -[Profiles] +[Profile] Module = "BasicProfileModule" [SimulationDataStore] diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 44ca3ac..574375e 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -32,7 +32,7 @@ AuthenticationServiceInConnector = true SimulationServiceInConnector = true -[Profiles] +[Profile] Module = "BasicProfileModule" [Messaging] -- cgit v1.1 From 3fa54a156a83e498a7d5d0949a5f848fe82fe86f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 1 Jun 2011 20:02:26 -0700 Subject: Changed Friends table to have 165-sized varchars on PrincipalID and FriendID. The reason for this number is the following: there is a combined key of these 2 fields; apparently MySql can't handle keys larger than 1000 bytes; when the table is created with utf8 encoding, this combined key is bigger than 1000 bytes, and the migration fails. WARNING: this is not a new migration! People who have gone through this migration and failed should update the sizes of these fields manually. --- OpenSim/Data/MySQL/Resources/FriendsStore.migrations | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations index 35e5e93..5abacf5 100644 --- a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations +++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations @@ -25,7 +25,8 @@ COMMIT; BEGIN; -ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; +ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(165) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; +ALTER TABLE `Friends` MODIFY COLUMN Friend varchar(165) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; COMMIT; -- cgit v1.1 From 43ecc46a224d07661af42379f12f394e1bd873fd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 1 Jun 2011 20:09:59 -0700 Subject: It looks like there's a better solution for that problem. Revert "Changed Friends table to have 165-sized varchars on PrincipalID and FriendID. The reason for this number is the following: there is a combined key of these 2 fields; apparently MySql can't handle keys larger than 1000 bytes; when the table is created with utf8 encoding, this combined key is bigger than 1000 bytes, and the migration fails. WARNING: this is not a new migration! People who have gone through this migration and failed should update the sizes of these fields manually." This reverts commit 3fa54a156a83e498a7d5d0949a5f848fe82fe86f. --- OpenSim/Data/MySQL/Resources/FriendsStore.migrations | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations index 5abacf5..35e5e93 100644 --- a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations +++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations @@ -25,8 +25,7 @@ COMMIT; BEGIN; -ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(165) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; -ALTER TABLE `Friends` MODIFY COLUMN Friend varchar(165) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; +ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; COMMIT; -- cgit v1.1 From c13acdf5a1a94df9b0ef50b7b2739a9256656582 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 1 Jun 2011 20:19:22 -0700 Subject: This is the better solution: make the combined key be only on the first 36 characters of each field -- that's the UUIDs. Thanks coyled. WARNING: Again, people who have gone through this migration and failed need to run it manually. --- OpenSim/Data/MySQL/Resources/FriendsStore.migrations | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations index 35e5e93..7848e49 100644 --- a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations +++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations @@ -25,7 +25,8 @@ COMMIT; BEGIN; +ALTER TABLE `Friends` DROP PRIMARY KEY; +ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36)); ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; COMMIT; - -- cgit v1.1 From f2f30a78908c93e1397be52e476da9fb5c44282d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 2 Jun 2011 07:26:40 -0700 Subject: HG Friends bug fix: connector was shrinking principalID to UUID. --- .../Handlers/Friends/FriendsServerPostHandler.cs | 19 ++++++++++++++--- .../Connectors/Friends/FriendsServiceConnector.cs | 24 +++++++++++----------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs index 9969086..fc97d8c 100644 --- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs @@ -160,9 +160,9 @@ namespace OpenSim.Server.Handlers.Friends byte[] StoreFriend(Dictionary request) { - FriendInfo friend = new FriendInfo(request); - - bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, friend.MyFlags); + string principalID = string.Empty, friend = string.Empty; int flags = 0; + FromKeyValuePairs(request, out principalID, out friend, out flags); + bool success = m_FriendsService.StoreFriend(principalID, friend, flags); if (success) return SuccessResult(); @@ -275,6 +275,19 @@ namespace OpenSim.Server.Handlers.Friends return ms.ToArray(); } + void FromKeyValuePairs(Dictionary kvp, out string principalID, out string friend, out int flags) + { + principalID = string.Empty; + if (kvp.ContainsKey("PrincipalID") && kvp["PrincipalID"] != null) + principalID = kvp["PrincipalID"].ToString(); + friend = string.Empty; + if (kvp.ContainsKey("Friend") && kvp["Friend"] != null) + friend = kvp["Friend"].ToString(); + flags = 0; + if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null) + Int32.TryParse(kvp["MyFlags"].ToString(), out flags); + } + #endregion } } diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs index 08f1dc3..c5ae0c0 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs @@ -161,19 +161,8 @@ namespace OpenSim.Services.Connectors.Friends public bool StoreFriend(string PrincipalID, string Friend, int flags) { - FriendInfo finfo = new FriendInfo(); - try - { - finfo.PrincipalID = new UUID(PrincipalID); - } - catch - { - return false; - } - finfo.Friend = Friend; - finfo.MyFlags = flags; - Dictionary sendData = finfo.ToKeyValuePairs(); + Dictionary sendData = ToKeyValuePairs(PrincipalID, Friend, flags); sendData["METHOD"] = "storefriend"; @@ -267,5 +256,16 @@ namespace OpenSim.Services.Connectors.Friends } #endregion + + public Dictionary ToKeyValuePairs(string principalID, string friend, int flags) + { + Dictionary result = new Dictionary(); + result["PrincipalID"] = principalID; + result["Friend"] = friend; + result["MyFlags"] = flags; + + return result; + } + } } \ No newline at end of file -- cgit v1.1 From 4696a9c95eaf87e5cb43cdba008d3f41a949d629 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 2 Jun 2011 08:13:54 -0700 Subject: Bug fix on HG IM. --- .../InstantMessage/HGMessageTransferModule.cs | 8 +++++-- .../HypergridService/HGInstantMessageService.cs | 26 +++++++++++----------- OpenSim/Services/Interfaces/IHypergridServices.cs | 2 +- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index e0c404b..4de197e 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -187,12 +187,16 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // Is the user a local user? UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID); string url = string.Empty; + bool foreigner = false; if (account == null) // foreign user + { url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI"); + foreigner = true; + } Util.FireAndForget(delegate { - bool success = m_IMService.OutgoingInstantMessage(im, url); + bool success = m_IMService.OutgoingInstantMessage(im, url, foreigner); if (!success && account == null) { // One last chance @@ -203,7 +207,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty; if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret)) { - success = m_IMService.OutgoingInstantMessage(im, u); + success = m_IMService.OutgoingInstantMessage(im, u, true); if (success) UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last); } diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index dd5fd71..4f68e55 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -115,23 +115,23 @@ namespace OpenSim.Services.HypergridService return m_IMSimConnector.SendInstantMessage(im); } else - return TrySendInstantMessage(im, "", true); + return TrySendInstantMessage(im, "", true, false); } - public bool OutgoingInstantMessage(GridInstantMessage im, string url) + public bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner) { m_log.DebugFormat("[HG IM SERVICE]: Sending message from {0} to {1}@{2}", im.fromAgentID, im.toAgentID, url); if (url != string.Empty) - return TrySendInstantMessage(im, url, true); + return TrySendInstantMessage(im, url, true, foreigner); else { PresenceInfo upd = new PresenceInfo(); upd.RegionID = UUID.Zero; - return TrySendInstantMessage(im, upd, true); + return TrySendInstantMessage(im, upd, true, foreigner); } } - protected bool TrySendInstantMessage(GridInstantMessage im, object previousLocation, bool firstTime) + protected bool TrySendInstantMessage(GridInstantMessage im, object previousLocation, bool firstTime, bool foreigner) { UUID toAgentID = new UUID(im.toAgentID); @@ -185,7 +185,7 @@ namespace OpenSim.Services.HypergridService } } - if (upd == null) + if (upd == null && !foreigner) { // Let's check with the UAS if the user is elsewhere m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service"); @@ -213,25 +213,25 @@ namespace OpenSim.Services.HypergridService // ok, the user is around somewhere. Let's send back the reply with "success" // even though the IM may still fail. Just don't keep the caller waiting for // the entire time we're trying to deliver the IM - return SendIMToRegion(upd, im, toAgentID); + return SendIMToRegion(upd, im, toAgentID, foreigner); } else if (url != string.Empty) { // ok, the user is around somewhere. Let's send back the reply with "success" // even though the IM may still fail. Just don't keep the caller waiting for // the entire time we're trying to deliver the IM - return ForwardIMToGrid(url, im, toAgentID); + return ForwardIMToGrid(url, im, toAgentID, foreigner); } else if (firstTime && previousLocation is string && (string)previousLocation != string.Empty) { - return ForwardIMToGrid((string)previousLocation, im, toAgentID); + return ForwardIMToGrid((string)previousLocation, im, toAgentID, foreigner); } else m_log.DebugFormat("[HG IM SERVICE]: Unable to locate user {0}", toAgentID); return false; } - bool SendIMToRegion(PresenceInfo upd, GridInstantMessage im, UUID toAgentID) + bool SendIMToRegion(PresenceInfo upd, GridInstantMessage im, UUID toAgentID, bool foreigner) { bool imresult = false; GridRegion reginfo = null; @@ -277,11 +277,11 @@ namespace OpenSim.Services.HypergridService // The version that spawns the thread is SendGridInstantMessageViaXMLRPC // This is recursive!!!!! - return TrySendInstantMessage(im, upd, false); + return TrySendInstantMessage(im, upd, false, foreigner); } } - bool ForwardIMToGrid(string url, GridInstantMessage im, UUID toAgentID) + bool ForwardIMToGrid(string url, GridInstantMessage im, UUID toAgentID, bool foreigner) { if (InstantMessageServiceConnector.SendInstantMessage(url, im)) { @@ -309,7 +309,7 @@ namespace OpenSim.Services.HypergridService // The version that spawns the thread is SendGridInstantMessageViaXMLRPC // This is recursive!!!!! - return TrySendInstantMessage(im, url, false); + return TrySendInstantMessage(im, url, false, foreigner); } } diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs index 753c205..82ec8ce 100644 --- a/OpenSim/Services/Interfaces/IHypergridServices.cs +++ b/OpenSim/Services/Interfaces/IHypergridServices.cs @@ -72,7 +72,7 @@ namespace OpenSim.Services.Interfaces public interface IInstantMessage { bool IncomingInstantMessage(GridInstantMessage im); - bool OutgoingInstantMessage(GridInstantMessage im, string url); + bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner); } public interface IFriendsSimConnector { -- cgit v1.1 From 3c15c0b2640b08f3786857837770dcdb53859fd4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 2 Jun 2011 09:39:09 -0700 Subject: Added test IM client. --- OpenSim/Tests/Clients/InstantMessage/IMClient.cs | 75 ++++++++++++++++++++++++ prebuild.xml | 26 ++++++++ 2 files changed, 101 insertions(+) create mode 100644 OpenSim/Tests/Clients/InstantMessage/IMClient.cs diff --git a/OpenSim/Tests/Clients/InstantMessage/IMClient.cs b/OpenSim/Tests/Clients/InstantMessage/IMClient.cs new file mode 100644 index 0000000..506d176 --- /dev/null +++ b/OpenSim/Tests/Clients/InstantMessage/IMClient.cs @@ -0,0 +1,75 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; + +using OpenMetaverse; +using log4net; +using log4net.Appender; +using log4net.Layout; + +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.InstantMessage; + +namespace OpenSim.Tests.Clients.InstantMessage +{ + public class IMClient + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + public static void Main(string[] args) + { + ConsoleAppender consoleAppender = new ConsoleAppender(); + consoleAppender.Layout = + new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"); + log4net.Config.BasicConfigurator.Configure(consoleAppender); + + string serverURI = "http://grid.nebadon2025.homeftp.net:8002/"; + GridInstantMessage im = new GridInstantMessage(); + im.fromAgentID = new Guid(); + im.toAgentID = new Guid(); + im.message = "Hello"; + im.imSessionID = new Guid(); + + bool success = InstantMessageServiceConnector.SendInstantMessage(serverURI, im); + + if (success) + m_log.InfoFormat("[IM CLIENT]: Successfully IMed {0}", serverURI); + else + m_log.InfoFormat("[IM CLIENT]: failed to IM {0}", serverURI); + + System.Console.WriteLine("\n"); + } + + } +} diff --git a/prebuild.xml b/prebuild.xml index 1f620dc..0bdd14d 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2645,6 +2645,32 @@ + + + + ../../../../bin/ + + + + + ../../../../bin/ + + + + ../../../../bin/ + + + + + + + + + + + + + -- cgit v1.1 From 65c71050cceb1a823fad682b906e0f8250f244c2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 2 Jun 2011 09:39:29 -0700 Subject: Extra debug message --- OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs index 74b7422..514793d 100644 --- a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs @@ -72,6 +72,7 @@ namespace OpenSim.Server.Handlers.Hypergrid if (m_IMService == null) throw new Exception("InstantMessage server connector cannot proceed because of missing service"); + m_log.DebugFormat("[XXX] IM Server Connector is ON"); MainServer.Instance.AddXmlRPCHandler("grid_instant_message", ProcessInstantMessage, false); } -- cgit v1.1 From 6312eea459e6c64b6b5fafe06c9b8e6617bb03c3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 2 Jun 2011 10:14:26 -0700 Subject: HG IM bug fix: grid_instant_message was being placed in the default port instead of the specified one. --- OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs | 3 +-- OpenSim/Tests/Clients/InstantMessage/IMClient.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs index 514793d..80eb5d2 100644 --- a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs @@ -72,8 +72,7 @@ namespace OpenSim.Server.Handlers.Hypergrid if (m_IMService == null) throw new Exception("InstantMessage server connector cannot proceed because of missing service"); - m_log.DebugFormat("[XXX] IM Server Connector is ON"); - MainServer.Instance.AddXmlRPCHandler("grid_instant_message", ProcessInstantMessage, false); + server.AddXmlRPCHandler("grid_instant_message", ProcessInstantMessage, false); } diff --git a/OpenSim/Tests/Clients/InstantMessage/IMClient.cs b/OpenSim/Tests/Clients/InstantMessage/IMClient.cs index 506d176..e7304a2 100644 --- a/OpenSim/Tests/Clients/InstantMessage/IMClient.cs +++ b/OpenSim/Tests/Clients/InstantMessage/IMClient.cs @@ -54,7 +54,7 @@ namespace OpenSim.Tests.Clients.InstantMessage new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"); log4net.Config.BasicConfigurator.Configure(consoleAppender); - string serverURI = "http://grid.nebadon2025.homeftp.net:8002/"; + string serverURI = "http://127.0.0.1:8002"; GridInstantMessage im = new GridInstantMessage(); im.fromAgentID = new Guid(); im.toAgentID = new Guid(); -- cgit v1.1 From 2a12d143c2a3fa996674ee77a34a82100da17230 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 2 Jun 2011 10:44:10 -0700 Subject: HG IM: increase the timeout value --- .../Connectors/InstantMessage/InstantMessageServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs index 161be02..dbce9f6 100644 --- a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs +++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs @@ -61,7 +61,7 @@ namespace OpenSim.Services.Connectors.InstantMessage try { - XmlRpcResponse GridResp = GridReq.Send(url, 3000); + XmlRpcResponse GridResp = GridReq.Send(url, 10000); Hashtable responseData = (Hashtable)GridResp.Value; -- cgit v1.1 From b000d4f67fd31251dfdcabbada371a5f57a80b0a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 2 Jun 2011 21:37:17 +0100 Subject: minor: add ini.example doc to hint that the server address in [FreeswitchService] must be reachable by viewers --- bin/OpenSim.ini.example | 1 + bin/Robust.HG.ini.example | 1 + bin/Robust.ini.example | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index c5df0db..55cf89a 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -649,6 +649,7 @@ ;; !!!!!!!!!!!!!!!!!!!!!!!!!!! ;; The IP address of your FreeSWITCH server. The common case is for this to be the same as the server running the OpenSim standalone ;; This has to be set for the FreeSWITCH service to work + ;; This address must be reachable by viewers. ;ServerAddress = 127.0.0.1 ;; The following configuration parameters are optional diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 0dd93f8..7b2f8ac 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -107,6 +107,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService" ;; The IP address of your FreeSWITCH server. + ;; This address must be reachable by viewers. ; ServerAddress = 127.0.0.1 ;; The following configuration parameters are optional diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index cc018f8..5d0ec09 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -21,7 +21,6 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 [Network] port = 8003 - ; HTTPS for "Out of band" management applications such as the remote admin ; module. May specify https_main = True to make the main http server ; use https or "False" to make the main server HTTP @@ -92,6 +91,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService" ;; The IP address of your FreeSWITCH server. + ;; This address must be reachable by viewers. ; ServerAddress = 127.0.0.1 ;; The following configuration parameters are optional -- cgit v1.1 From dfa4442319397abd91e1ffbf61b02fb63b8f46d2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 2 Jun 2011 22:43:44 +0100 Subject: Move the "!!!Standalone Only!!!" [FreeswitchService] section from OpenSim.ini.example to config/StandaloneCommon.ini.example where it belongs. --- bin/OpenSim.ini.example | 40 +------------------------ bin/config-include/StandaloneCommon.ini.example | 36 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 55cf89a..813c5b8 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -635,51 +635,13 @@ ;; You need to load a local service for a standalone, and a remote service ;; for a grid region. Use one of the lines below, as appropriate - ;; If you're using Freeswitch on a standalone then you will also need to configure the [FreeswitchService] section + ;; If you're using Freeswitch on a standalone then you will also need to configure the [FreeswitchService] section in config-include/StandaloneCommon.ini ; LocalServiceModule = OpenSim.Services.FreeswitchService.dll:FreeswitchService ; LocalServiceModule = OpenSim.Services.Connectors.dll:RemoteFreeswitchConnector ;; If using a remote connector, specify the server URL ; FreeswitchServiceURL = http://my.grid.server:8004/fsapi - -[FreeswitchService] - ;; !!!!!!!!!!!!!!!!!!!!!!!!!!! - ;; !!!!!!STANDALONE ONLY!!!!!! - ;; !!!!!!!!!!!!!!!!!!!!!!!!!!! - ;; The IP address of your FreeSWITCH server. The common case is for this to be the same as the server running the OpenSim standalone - ;; This has to be set for the FreeSWITCH service to work - ;; This address must be reachable by viewers. - ;ServerAddress = 127.0.0.1 - - ;; The following configuration parameters are optional - - ;; By default, this is the same as the ServerAddress - ; Realm = 127.0.0.1 - - ;; By default, this is the same as the ServerAddress on port 5060 - ; SIPProxy = 127.0.0.1:5060 - - ;; Default is 5000ms - ; DefaultTimeout = 5000 - - ;; The dial plan context. Default is "default" - ; Context = default - - ;; Currently unused - ; UserName = freeswitch - - ;; Currently unused - ; Password = password - - ;; The following parameters are for STUN = Simple Traversal of UDP through NATs - ;; See http://wiki.freeswitch.org/wiki/NAT_Traversal - ;; stun.freeswitch.org is not guaranteed to be running so use it in - ;; production at your own risk - ; EchoServer = 127.0.0.1 - ; EchoPort = 50505 - ; AttemptSTUN = false - [Groups] ;# {Enabled} {} {Enable groups?} {true false} false ;; Enables the groups module diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 57380ee..aeebcd0 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -139,6 +139,42 @@ ;AllowedClients = "" ;DeniedClients = "" +[FreeswitchService] + ;; If FreeSWITCH is not being used then you don't need to set any of these parameters + ;; + ;; The IP address of your FreeSWITCH server. The common case is for this to be the same as the server running the OpenSim standalone + ;; This has to be set for the FreeSWITCH service to work + ;; This address must be reachable by viewers. + ;ServerAddress = 127.0.0.1 + + ;; The following configuration parameters are optional + + ;; By default, this is the same as the ServerAddress + ; Realm = 127.0.0.1 + + ;; By default, this is the same as the ServerAddress on port 5060 + ; SIPProxy = 127.0.0.1:5060 + + ;; Default is 5000ms + ; DefaultTimeout = 5000 + + ;; The dial plan context. Default is "default" + ; Context = default + + ;; Currently unused + ; UserName = freeswitch + + ;; Currently unused + ; Password = password + + ;; The following parameters are for STUN = Simple Traversal of UDP through NATs + ;; See http://wiki.freeswitch.org/wiki/NAT_Traversal + ;; stun.freeswitch.org is not guaranteed to be running so use it in + ;; production at your own risk + ; EchoServer = 127.0.0.1 + ; EchoPort = 50505 + ; AttemptSTUN = false + [GridInfoService] ; These settings are used to return information on a get_grid_info call. ; Client launcher scripts and third-party clients make use of this to -- cgit v1.1 From 76c60f1f99ca8aa7c1a336918aa0ef5f83b1ae04 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 3 Jun 2011 08:27:01 -0700 Subject: Moved CreateNewInventoryItem to the InventoryAccessModule in preparation for supporting HG landmarks. --- .../InventoryAccess/InventoryAccessModule.cs | 79 +++++++++++++++++++++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 74 +------------------- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- 3 files changed, 81 insertions(+), 76 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 1370b1f..641a042 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; using System.Net; using System.Xml; using System.Reflection; +using System.Text; using System.Threading; using OpenSim.Framework; @@ -128,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess protected virtual void OnNewClient(IClientAPI client) { - + client.OnCreateNewInventoryItem += CreateNewInventoryItem; } public virtual void Close() @@ -157,6 +158,82 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess #region Inventory Access /// + /// Create a new inventory item. Called when the client creates a new item directly within their + /// inventory (e.g. by selecting a context inventory menu option). + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, + uint callbackID, string description, string name, sbyte invType, + sbyte assetType, + byte wearableType, uint nextOwnerMask, int creationDate) + { + m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID); + + if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) + return; + + InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId); + InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f); + + if (folder == null || folder.Owner != remoteClient.AgentId) + return; + + if (transactionID == UUID.Zero) + { + ScenePresence presence; + if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) + { + byte[] data = null; + + if (invType == (sbyte)InventoryType.Landmark && presence != null) + { + string strdata = GenerateLandmark(presence); + data = Encoding.ASCII.GetBytes(strdata); + } + + AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); + m_Scene.AssetService.Store(asset); + + m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate); + } + else + { + m_log.ErrorFormat( + "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", + remoteClient.AgentId); + } + } + else + { + IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface(); + if (agentTransactions != null) + { + agentTransactions.HandleItemCreationFromTransaction( + remoteClient, transactionID, folderID, callbackID, description, + name, invType, assetType, wearableType, nextOwnerMask); + } + } + } + + protected virtual string GenerateLandmark(ScenePresence presence) + { + Vector3 pos = presence.AbsolutePosition; + return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n", + presence.Scene.RegionInfo.RegionID, + pos.X, pos.Y, pos.Z, + presence.RegionHandle); + } + + /// /// Capability originating call to update the asset of an item in an agent's inventory /// /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 3c47873..b70e1c3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -778,7 +778,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, + public void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate) { CreateNewInventoryItem( @@ -833,78 +833,6 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Create a new inventory item. Called when the client creates a new item directly within their - /// inventory (e.g. by selecting a context inventory menu option). - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, - uint callbackID, string description, string name, sbyte invType, - sbyte assetType, - byte wearableType, uint nextOwnerMask, int creationDate) - { - m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID); - - if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) - return; - - InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId); - InventoryFolderBase folder = InventoryService.GetFolder(f); - - if (folder == null || folder.Owner != remoteClient.AgentId) - return; - - if (transactionID == UUID.Zero) - { - ScenePresence presence; - if (TryGetScenePresence(remoteClient.AgentId, out presence)) - { - byte[] data = null; - - if (invType == (sbyte)InventoryType.Landmark && presence != null) - { - Vector3 pos = presence.AbsolutePosition; - string strdata = String.Format( - "Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n", - presence.Scene.RegionInfo.RegionID, - pos.X, pos.Y, pos.Z, - presence.RegionHandle); - data = Encoding.ASCII.GetBytes(strdata); - } - - AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId); - AssetService.Store(asset); - - CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate); - } - else - { - m_log.ErrorFormat( - "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", - remoteClient.AgentId); - } - } - else - { - IAgentAssetTransactions agentTransactions = this.RequestModuleInterface(); - if (agentTransactions != null) - { - agentTransactions.HandleItemCreationFromTransaction( - remoteClient, transactionID, folderID, callbackID, description, - name, invType, assetType, wearableType, nextOwnerMask); - } - } - } - - /// /// Link an inventory item to an existing item. /// /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1d562fd..b179683 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2726,7 +2726,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void SubscribeToClientInventoryEvents(IClientAPI client) { - client.OnCreateNewInventoryItem += CreateNewInventoryItem; + client.OnLinkInventoryItem += HandleLinkInventoryItem; client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder; client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder; @@ -2853,7 +2853,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client) { - client.OnCreateNewInventoryItem -= CreateNewInventoryItem; + client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder; client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder; client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!! -- cgit v1.1 From 995b893e4c7c89db8fc044e3f8524229490fb220 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 3 Jun 2011 09:04:34 -0700 Subject: HG Landmarks being created. WARNING: new config var under [HGInventoryAccessModule], Gatekeeper. --- .../Framework/InventoryAccess/HGInventoryAccessModule.cs | 15 +++++++++++++++ .../Framework/InventoryAccess/InventoryAccessModule.cs | 7 +++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 429dda7..844054c 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 private string m_ProfileServerURI; private bool m_OutboundPermission; + private string m_ThisGatekeeper; // private bool m_Initialized = false; @@ -85,6 +86,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); + m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty); } else m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); @@ -119,6 +121,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess #endregion #region Overrides of Basic Inventory Access methods + + protected override string GenerateLandmark(ScenePresence presence, out string suffix) + { + suffix = " @ " + m_ThisGatekeeper; + Vector3 pos = presence.AbsolutePosition; + return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}", + presence.Scene.RegionInfo.RegionID, + pos.X, pos.Y, pos.Z, + presence.RegionHandle, + m_ThisGatekeeper); + } + + /// /// CapsUpdateInventoryItemAsset /// diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 641a042..d441aa4 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -196,8 +196,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (invType == (sbyte)InventoryType.Landmark && presence != null) { - string strdata = GenerateLandmark(presence); + string suffix = string.Empty; + string strdata = GenerateLandmark(presence, out suffix); data = Encoding.ASCII.GetBytes(strdata); + description += suffix; } AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); @@ -224,8 +226,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } - protected virtual string GenerateLandmark(ScenePresence presence) + protected virtual string GenerateLandmark(ScenePresence presence, out string suffix) { + suffix = string.Empty; Vector3 pos = presence.AbsolutePosition; return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n", presence.Scene.RegionInfo.RegionID, -- cgit v1.1 From e33cedfd427779a3df844150869eb07b664849df Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 3 Jun 2011 10:26:58 -0700 Subject: HG Landmarks now working. --- OpenSim/Framework/AssetLandmark.cs | 3 ++ OpenSim/Framework/IClientAPI.cs | 2 +- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 5 +- .../EntityTransfer/EntityTransferModule.cs | 29 +++++++++++- .../EntityTransfer/HGEntityTransferModule.cs | 53 ++++++++++++++++++++++ .../InventoryAccess/HGInventoryAccessModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 23 +--------- 7 files changed, 89 insertions(+), 28 deletions(-) diff --git a/OpenSim/Framework/AssetLandmark.cs b/OpenSim/Framework/AssetLandmark.cs index f433235..103f756 100644 --- a/OpenSim/Framework/AssetLandmark.cs +++ b/OpenSim/Framework/AssetLandmark.cs @@ -35,6 +35,7 @@ namespace OpenSim.Framework public Vector3 Position; public ulong RegionHandle; public UUID RegionID; + public string Gatekeeper = string.Empty; public int Version; public AssetLandmark(AssetBase a) @@ -51,6 +52,8 @@ namespace OpenSim.Framework string[] parts = temp.Split('\n'); int.TryParse(parts[0].Substring(17, 1), out Version); UUID.TryParse(parts[1].Substring(10, 36), out RegionID); + if (parts.Length >= 5) + Gatekeeper = parts[4].Replace("gatekeeper ", ""); // The position is a vector with spaces as separators ("10.3 32.5 43"). // Parse each scalar separately to take into account the system's culture setting. string[] scalars = parts[2].Substring(10, parts[2].Length - 10).Split(' '); diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 137f432..659d42f 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -83,7 +83,7 @@ namespace OpenSim.Framework IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags); public delegate void TeleportLandmarkRequest( - IClientAPI remoteClient, UUID regionID, Vector3 position); + IClientAPI remoteClient, AssetLandmark lm); public delegate void DisconnectUser(); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index d8fcb62..3a9e4b7 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -8301,6 +8301,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AssetLandmark lm; if (lmid != UUID.Zero) { + //AssetBase lma = m_assetCache.GetAsset(lmid, false); AssetBase lma = m_assetService.Get(lmid.ToString()); @@ -8341,13 +8342,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; if (handlerTeleportLandmarkRequest != null) { - handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position); + handlerTeleportLandmarkRequest(this, lm); } else { //no event handler so cancel request - - TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel); tpCancel.Info.AgentID = tpReq.Info.AgentID; tpCancel.Info.SessionID = tpReq.Info.SessionID; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ec084fb..1341533 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 protected bool m_Enabled = false; protected Scene m_aScene; + protected List m_Scenes = new List(); protected List m_agentsInTransit; private ExpiringCache> m_bannedRegions = new ExpiringCache>(); @@ -96,6 +97,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_aScene == null) m_aScene = scene; + m_Scenes.Add(scene); scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += OnNewClient; } @@ -103,6 +105,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void OnNewClient(IClientAPI client) { client.OnTeleportHomeRequest += TeleportHome; + client.OnTeleportLandmarkRequest += RequestTeleportLandmark; } public virtual void Close() @@ -118,6 +121,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; if (scene == m_aScene) m_aScene = null; + + m_Scenes.Remove(scene); } public virtual void RegionLoaded(Scene scene) @@ -127,7 +132,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } - #endregion #region Agent Teleports @@ -556,6 +560,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion + #region Landmark Teleport + /// + /// Tries to teleport agent to landmark. + /// + /// + /// + /// + public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) + { + GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + + if (info == null) + { + // can't find the region: Tell viewer and abort + remoteClient.SendTeleportFailed("The teleport destination could not be found."); + return; + } + ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, + Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + } + + #endregion + #region Teleport Home public virtual void TeleportHome(UUID id, IClientAPI client) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 5c53f78..f6ec481 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -87,6 +87,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override void OnNewClient(IClientAPI client) { client.OnTeleportHomeRequest += TeleportHome; + client.OnTeleportLandmarkRequest += RequestTeleportLandmark; client.OnConnectionClosed += new Action(OnConnectionClosed); } @@ -228,6 +229,58 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); } + + /// + /// Tries to teleport agent to landmark. + /// + /// + /// + /// + public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) + { + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", + (lm.Gatekeeper == string.Empty ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); + if (lm.Gatekeeper == string.Empty) + { + base.RequestTeleportLandmark(remoteClient, lm); + return; + } + + GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + + // Local region? + if (info != null) + { + ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, + Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + return; + } + else + { + // Foreign region + Scene scene = (Scene)(remoteClient.Scene); + GatekeeperServiceConnector gConn = new GatekeeperServiceConnector(); + GridRegion gatekeeper = new GridRegion(); + gatekeeper.ServerURI = lm.Gatekeeper; + GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID)); + if (finalDestination != null) + { + ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); + IEntityTransferModule transferMod = scene.RequestModuleInterface(); + IEventQueue eq = sp.Scene.RequestModuleInterface(); + if (transferMod != null && sp != null && eq != null) + transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position, + Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq); + } + + } + + // can't find the region: Tell viewer and abort + remoteClient.SendTeleportFailed("The teleport destination could not be found."); + + } + + #endregion #region IUserAgentVerificationModule diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 844054c..7964b4f 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -126,7 +126,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { suffix = " @ " + m_ThisGatekeeper; Vector3 pos = presence.AbsolutePosition; - return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}", + return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}\n", presence.Scene.RegionInfo.RegionID, pos.X, pos.Y, pos.Z, presence.RegionHandle, diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b179683..77301d8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2749,7 +2749,6 @@ namespace OpenSim.Region.Framework.Scenes public virtual void SubscribeToClientTeleportEvents(IClientAPI client) { client.OnTeleportLocationRequest += RequestTeleportLocation; - client.OnTeleportLandmarkRequest += RequestTeleportLandmark; } public virtual void SubscribeToClientScriptEvents(IClientAPI client) @@ -2875,7 +2874,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client) { client.OnTeleportLocationRequest -= RequestTeleportLocation; - client.OnTeleportLandmarkRequest -= RequestTeleportLandmark; + //client.OnTeleportLandmarkRequest -= RequestTeleportLandmark; //client.OnTeleportHomeRequest -= TeleportClientHome; } @@ -3925,26 +3924,6 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Tries to teleport agent to landmark. - /// - /// - /// - /// - public void RequestTeleportLandmark(IClientAPI remoteClient, UUID regionID, Vector3 position) - { - GridRegion info = GridService.GetRegionByUUID(UUID.Zero, regionID); - - if (info == null) - { - // can't find the region: Tell viewer and abort - remoteClient.SendTeleportFailed("The teleport destination could not be found."); - return; - } - - RequestTeleportLocation(remoteClient, info.RegionHandle, position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark)); - } - public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) { if (m_teleportModule != null) -- cgit v1.1 From 7772640ae8041555c1f1098ed036c1c42944a108 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 3 Jun 2011 10:29:59 -0700 Subject: .ini.example's updated for HG Landmarks --- bin/config-include/GridCommon.ini.example | 3 ++- bin/config-include/StandaloneCommon.ini.example | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index c5c26ec..e2e6459 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -100,10 +100,11 @@ [HGInventoryAccessModule] ; ; === HG ONLY === - ; Change this to your profile server + ; Change this to your server ; accessible from other grids ; ProfileServerURI = "http://mygridserver.com:8002/user" + Gatekeeper = "http://mygridserver.com:8002" ;; If you want to protect your assets from being copied by foreign visitors ;; uncomment the next line. You may want to do this on sims that have licensed content. ; OutboundPermission = False diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 57380ee..cda3ff8 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -36,6 +36,7 @@ [HGInventoryAccessModule] ProfileServerURI = "http://127.0.0.1:9000/profiles" + Gatekeeper = "http://127.0.0.1:9000" ;; If you want to protect your assets from being copied by foreign visitors ;; uncomment the next line. You may want to do this on sims that have licensed content. -- cgit v1.1 From fde3e704d3c6833da0a1ab80cc50549ad9581cd0 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 3 Jun 2011 10:50:55 -0700 Subject: oops --- .../CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index f6ec481..37d81a3 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -239,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", - (lm.Gatekeeper == string.Empty ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); + (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); if (lm.Gatekeeper == string.Empty) { base.RequestTeleportLandmark(remoteClient, lm); -- cgit v1.1 From 623706d988d47c3c0f3d46b68e77f9c54038d3f5 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 3 Jun 2011 11:33:44 -0700 Subject: HG Landmarks bug fix: pull landmark asset data from user's asset server when user is traveling. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 3a9e4b7..cefceb0 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -8308,10 +8308,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (lma == null) { // Failed to find landmark - TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel); - tpCancel.Info.SessionID = tpReq.Info.SessionID; - tpCancel.Info.AgentID = tpReq.Info.AgentID; - OutPacket(tpCancel, ThrottleOutPacketType.Task); + + // Let's try to search in the user's home asset server + lma = FindAssetInUserAssetServer(lmid.ToString()); + + if (lma == null) + { + // Really doesn't exist + TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel); + tpCancel.Info.SessionID = tpReq.Info.SessionID; + tpCancel.Info.AgentID = tpReq.Info.AgentID; + OutPacket(tpCancel, ThrottleOutPacketType.Task); + } } try @@ -8356,6 +8364,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; } + private AssetBase FindAssetInUserAssetServer(string id) + { + AgentCircuitData aCircuit = ((Scene)Scene).AuthenticateHandler.GetAgentCircuitData(CircuitCode); + if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) + { + string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString(); + return ((Scene)Scene).AssetService.Get(assetServer + "/" + id); + } + + return null; + } + private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack) { TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack; -- cgit v1.1 From cf86ba5559c7158af5c84415f78d5524b4191292 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 3 Jun 2011 11:48:24 -0700 Subject: Added prefix HG to the name of the landmark item in inventory, as a soft reminder that the landmark belongs to a place in another grid. People can change the name, but that's their decision. --- .../Framework/InventoryAccess/HGInventoryAccessModule.cs | 7 ++++++- .../Framework/InventoryAccess/InventoryAccessModule.cs | 8 +++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 7964b4f..49d484b 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -122,8 +122,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess #region Overrides of Basic Inventory Access methods - protected override string GenerateLandmark(ScenePresence presence, out string suffix) + protected override string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix) { + UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, presence.UUID); + if (account == null) + prefix = "HG "; + else + prefix = string.Empty; suffix = " @ " + m_ThisGatekeeper; Vector3 pos = presence.AbsolutePosition; return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}\n", diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index d441aa4..2930303 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -196,9 +196,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (invType == (sbyte)InventoryType.Landmark && presence != null) { - string suffix = string.Empty; - string strdata = GenerateLandmark(presence, out suffix); + string suffix = string.Empty, prefix = string.Empty; + string strdata = GenerateLandmark(presence, out prefix, out suffix); data = Encoding.ASCII.GetBytes(strdata); + name = prefix + name; description += suffix; } @@ -226,8 +227,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } - protected virtual string GenerateLandmark(ScenePresence presence, out string suffix) + protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix) { + prefix = string.Empty; suffix = string.Empty; Vector3 pos = presence.AbsolutePosition; return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n", -- cgit v1.1 From 527e10a04e9108bebe5de76541d47409dd6ce4f4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 3 Jun 2011 23:13:05 +0100 Subject: add stub UserInventoryTests.GiveInventoryFolder(). Not yet complete --- .../Framework/Scenes/Tests/UserInventoryTests.cs | 70 ++++++++++++++++++++++ .../Tests/Common/Helpers/UserInventoryHelpers.cs | 11 +++- 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs new file mode 100644 index 0000000..b82ddb4 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -0,0 +1,70 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Timers; +using Timer=System.Timers.Timer; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenMetaverse.Assets; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; +using OpenSim.Region.CoreModules.World.Serialiser; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.Framework.Tests +{ + [TestFixture] + public class UserInventoryTests + { + [Test] + public void TestGiveInventoryFolder() + { + Scene scene = SceneSetupHelpers.SetupScene(); + UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); + UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene); + InventoryFolderBase folder1 + = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1"); + + scene.GiveInventoryFolder(user2.PrincipalID, user1.PrincipalID, folder1.ID, UUID.Zero); + +// InventoryFolderBase receivedFolder1Template = new InventoryFolderBase( +// InventoryFolderBase receivedFolder1 = scene.InventoryService.GetFolder + } + } +} \ No newline at end of file diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs index 0419134..e33145f 100644 --- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs @@ -40,8 +40,15 @@ namespace OpenSim.Tests.Common { public static readonly string PATH_DELIMITER = "/"; - public static InventoryItemBase CreateInventoryItem( - Scene scene, string itemName, UUID itemId, string folderPath, UUID userId) + /// + /// Creates a notecard in the objects folder. + /// + /// + /// + /// + /// + /// + public static InventoryItemBase CreateInventoryItem(Scene scene, string itemName, UUID itemId, UUID userId) { InventoryItemBase item = new InventoryItemBase(); item.Name = itemName; -- cgit v1.1 From d09210da869ad2a91c9578225a1ca4843d565e05 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 3 Jun 2011 23:15:31 +0100 Subject: minor: add in method print out to new test --- OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index b82ddb4..651df3e 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -55,6 +55,9 @@ namespace OpenSim.Region.Framework.Tests [Test] public void TestGiveInventoryFolder() { + TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + Scene scene = SceneSetupHelpers.SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene); -- cgit v1.1 From 66004a9375bdb736b4e2569f2791ac14ed4925e4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 3 Jun 2011 23:43:09 +0100 Subject: If an llSensor() is in an attachment, make the detection cone face in the direction of the avatar, not the relative rotation of the attachment towards the avatar. This is effectively a copy/paste from 459323a, which should be refactored sometime. This seems the obvious problem from field reports but I have not tested the fix myself. Feedback welcome. --- .../Shared/Api/Implementation/Plugins/SensorRepeat.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 47c7915..e53a61a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -308,7 +308,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // In attachments, the sensor cone always orients with the // avatar rotation. This may include a nonzero elevation if // in mouselook. - ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); q = avatar.Rotation; } @@ -422,7 +421,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins SceneObjectPart SensePoint = ts.host; Vector3 fromRegionPos = SensePoint.AbsolutePosition; + Quaternion q = SensePoint.RotationOffset; + if (SensePoint.ParentGroup.RootPart.IsAttachment) + { + // In attachments, the sensor cone always orients with the + // avatar rotation. This may include a nonzero elevation if + // in mouselook. + ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); + q = avatar.Rotation; + } + LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); -- cgit v1.1 From 1543fd7fff3b3f3a7ce07caa3ed19846b6587df7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 4 Jun 2011 00:20:54 +0100 Subject: extend TestGiveInventoryFolder() to check for the receipt by user 2 --- .../Framework/Scenes/Tests/UserInventoryTests.cs | 6 ++++-- .../Tests/Common/Helpers/UserInventoryHelpers.cs | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 651df3e..c6bd296 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -66,8 +66,10 @@ namespace OpenSim.Region.Framework.Tests scene.GiveInventoryFolder(user2.PrincipalID, user1.PrincipalID, folder1.ID, UUID.Zero); -// InventoryFolderBase receivedFolder1Template = new InventoryFolderBase( -// InventoryFolderBase receivedFolder1 = scene.InventoryService.GetFolder + InventoryFolderBase retrievedFolder1 + = UserInventoryHelpers.GetInventoryFolder(scene.InventoryService, user2.PrincipalID, "folder1"); + + Assert.That(retrievedFolder1, Is.Not.Null); } } } \ No newline at end of file diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs index e33145f..03215f2 100644 --- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs @@ -26,8 +26,10 @@ */ using System; +using System.Collections.Generic; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; @@ -118,5 +120,24 @@ namespace OpenSim.Tests.Common else return newFolder; } + + /// + /// Get the inventory folder that matches the path name. If there are multiple folders then only the first + /// is returned. + /// + /// + /// + /// + /// null if no folder matching the path was found + public static InventoryFolderBase GetInventoryFolder(IInventoryService inventoryService, UUID userId, string path) + { + List folders + = InventoryArchiveUtils.FindFolderByPath(inventoryService, userId, path); + + if (folders.Count != 0) + return folders[0]; + else + return null; + } } } \ No newline at end of file -- cgit v1.1 From 896f039513398a46458b18ef49f52a9a3ac43659 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 4 Jun 2011 00:51:49 +0100 Subject: create TestGetInventoryItem() --- .../Inventory/Archiver/InventoryArchiveUtils.cs | 20 ++++++---------- .../Framework/Scenes/Tests/UserInventoryTests.cs | 19 +++++++++++++++ .../Tests/Common/Helpers/UserInventoryHelpers.cs | 28 +++++++++++++++++++++- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs index 47e34dc..dc665c1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs @@ -181,25 +181,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. - /// - /// This method does not handle paths that contain multiple delimitors + /// + /// + /// This method does not handle paths that contain multiple delimiters /// /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some /// XPath like expression /// /// FIXME: Delimitors which occur in names themselves are not currently escapable. - /// + /// /// - /// - /// Inventory service to query - /// - /// - /// The folder from which the path starts - /// - /// - /// - /// The path to the required item. - /// + /// Inventory service to query + /// The folder from which the path starts + /// The path to the required item. /// null if the item is not found public static InventoryItemBase FindItemByPath( IInventoryService inventoryService, InventoryFolderBase startFolder, string path) diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index c6bd296..bacf7c1 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -53,6 +53,25 @@ namespace OpenSim.Region.Framework.Tests public class UserInventoryTests { [Test] + public void TestGiveInventoryItem() + { + TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + Scene scene = SceneSetupHelpers.SetupScene(); + UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); + UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene); + InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); + + scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID); + + InventoryItemBase retrievedItem1 + = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Objects/item1"); + + Assert.That(retrievedItem1, Is.Not.Null); + } + + [Test] public void TestGiveInventoryFolder() { TestHelper.InMethod(); diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs index 03215f2..93b655a 100644 --- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs @@ -43,7 +43,20 @@ namespace OpenSim.Tests.Common public static readonly string PATH_DELIMITER = "/"; /// - /// Creates a notecard in the objects folder. + /// Creates a notecard in the objects folder and specify an item id. + /// + /// + /// + /// + /// + /// + public static InventoryItemBase CreateInventoryItem(Scene scene, string itemName, UUID userId) + { + return CreateInventoryItem(scene, itemName, UUID.Random(), userId); + } + + /// + /// Creates a notecard in the objects folder and specify an item id. /// /// /// @@ -139,5 +152,18 @@ namespace OpenSim.Tests.Common else return null; } + + /// + /// Get the inventory item that matches the path name. If there are multiple items then only the first + /// is returned. + /// + /// + /// + /// + /// null if no item matching the path was found + public static InventoryItemBase GetInventoryItem(IInventoryService inventoryService, UUID userId, string path) + { + return InventoryArchiveUtils.FindItemByPath(inventoryService, userId, path); + } } } \ No newline at end of file -- cgit v1.1 From fe890554fbf47cafda2a41e04b400d971f1242ad Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 4 Jun 2011 01:37:01 +0100 Subject: insert an InventoryArchiveUtils.FindItemsByPath() to return multiple items rather than just the first one --- .../Inventory/Archiver/InventoryArchiveUtils.cs | 45 ++++++++++++++++++---- .../Archiver/InventoryArchiveWriteRequest.cs | 3 -- .../Framework/Scenes/Tests/UserInventoryTests.cs | 3 ++ 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs index dc665c1..e7fb43a 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 /// /// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder. - /// + /// + /// /// This method does not handle paths that contain multiple delimitors /// /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some /// XPath like expression /// /// FIXME: Delimitors which occur in names themselves are not currently escapable. - /// + /// /// /// /// Inventory service to query @@ -178,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return FindItemByPath(inventoryService, rootFolder, path); } - + /// /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. /// @@ -190,7 +191,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// /// FIXME: Delimitors which occur in names themselves are not currently escapable. /// - /// + /// /// Inventory service to query /// The folder from which the path starts /// The path to the required item. @@ -198,6 +199,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver public static InventoryItemBase FindItemByPath( IInventoryService inventoryService, InventoryFolderBase startFolder, string path) { + List foundItems = FindItemsByPath(inventoryService, startFolder, path); + + if (foundItems.Count != 0) + return foundItems[0]; + else + return null; + } + + /// + /// Find items that match a given PATH_DELIMITOR delimited path starting from this folder. + /// + /// + /// This method does not handle paths that contain multiple delimiters + /// + /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some + /// XPath like expression + /// + /// FIXME: Delimitors which occur in names themselves are not currently escapable. + /// + /// + /// Inventory service to query + /// The folder from which the path starts + /// The path to the required item. + /// The items that were found with this path. An empty list if no items were found. + public static List FindItemsByPath( + IInventoryService inventoryService, InventoryFolderBase startFolder, string path) + { + List foundItems = new List(); + // If the path isn't just / then trim any starting extraneous slashes path = path.TrimStart(new char[] { PATH_DELIMITER }); @@ -221,7 +251,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID); if (item.Name == components[0]) - return item; + foundItems.Add(item); } } else @@ -233,12 +263,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver foreach (InventoryFolderBase folder in contents.Folders) { if (folder.Name == components[0]) - return FindItemByPath(inventoryService, folder, components[1]); + foundItems.AddRange(FindItemsByPath(inventoryService, folder, components[1])); } } - // We didn't find an item or intermediate folder with the given name - return null; + return foundItems; } /// diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index c34a0ec..c2ad079 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -255,10 +255,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // The path may point to an item instead if (inventoryFolder == null) - { inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); - //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath); - } if (null == inventoryFolder && null == inventoryItem) { diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index bacf7c1..83f0686 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -69,6 +69,9 @@ namespace OpenSim.Region.Framework.Tests = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Objects/item1"); Assert.That(retrievedItem1, Is.Not.Null); + + // Try giving back the freshly received item + //scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID); } [Test] -- cgit v1.1 From 12b1cbf8bfc559e4da40abf518e8e99fac793870 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 4 Jun 2011 02:39:26 +0100 Subject: Fix give inventory tests to use different users rather than (accidentally) the same user. Extend TestGiveInventoryItem() to test giving back the same item. --- .../Inventory/Archiver/InventoryArchiveUtils.cs | 19 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 328 +++++++++++---------- .../Framework/Scenes/Tests/UserInventoryTests.cs | 17 +- .../Services/InventoryService/InventoryService.cs | 8 +- OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs | 11 +- .../Tests/Common/Helpers/UserInventoryHelpers.cs | 25 +- 6 files changed, 226 insertions(+), 182 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs index e7fb43a..0d90a15 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs @@ -206,7 +206,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else return null; } - + + public static List FindItemsByPath( + IInventoryService inventoryService, UUID userId, string path) + { + InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId); + + if (null == rootFolder) + return new List(); + + return FindItemsByPath(inventoryService, rootFolder, path); + } + /// /// Find items that match a given PATH_DELIMITOR delimited path starting from this folder. /// @@ -239,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (components.Length == 1) { // m_log.DebugFormat( -// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}", +// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}", // components[0], startFolder.Name, startFolder.ID); List items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); - + // m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count); foreach (InventoryItemBase item in items) @@ -257,7 +268,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else { // m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]); - + InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); foreach (InventoryFolderBase folder in contents.Folders) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index b70e1c3..f37f94a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -425,192 +425,198 @@ namespace OpenSim.Region.Framework.Scenes InventoryItemBase item = new InventoryItemBase(itemId, senderId); item = InventoryService.GetItem(item); - if ((item != null) && (item.Owner == senderId)) + if (item == null) { - IUserManagement uman = RequestModuleInterface(); - if (uman != null) - uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); + m_log.WarnFormat( + "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient); + return null; + } - if (!Permissions.BypassPermissions()) - { - if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) - return null; - } + if (item.Owner != senderId) + { + m_log.WarnFormat( + "[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}", + item.Name, item.ID, recipient, senderId, item.Owner); + return null; + } + + IUserManagement uman = RequestModuleInterface(); + if (uman != null) + uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); + + if (!Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) + return null; + } - // Insert a copy of the item into the recipient - InventoryItemBase itemCopy = new InventoryItemBase(); - itemCopy.Owner = recipient; - itemCopy.CreatorId = item.CreatorId; - itemCopy.CreatorData = item.CreatorData; - itemCopy.ID = UUID.Random(); - itemCopy.AssetID = item.AssetID; - itemCopy.Description = item.Description; - itemCopy.Name = item.Name; - itemCopy.AssetType = item.AssetType; - itemCopy.InvType = item.InvType; - itemCopy.Folder = recipientFolderId; - - if (Permissions.PropagatePermissions() && recipient != senderId) + // Insert a copy of the item into the recipient + InventoryItemBase itemCopy = new InventoryItemBase(); + itemCopy.Owner = recipient; + itemCopy.CreatorId = item.CreatorId; + itemCopy.CreatorData = item.CreatorData; + itemCopy.ID = UUID.Random(); + itemCopy.AssetID = item.AssetID; + itemCopy.Description = item.Description; + itemCopy.Name = item.Name; + itemCopy.AssetType = item.AssetType; + itemCopy.InvType = item.InvType; + itemCopy.Folder = recipientFolderId; + + if (Permissions.PropagatePermissions() && recipient != senderId) + { + // Trying to do this right this time. This is evil. If + // you believe in Good, go elsewhere. Vampires and other + // evil creatores only beyond this point. You have been + // warned. + + // We're going to mask a lot of things by the next perms + // Tweak the next perms to be nicer to our data + // + // In this mask, all the bits we do NOT want to mess + // with are set. These are: + // + // Transfer + // Copy + // Modufy + uint permsMask = ~ ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify); + + // Now, reduce the next perms to the mask bits + // relevant to the operation + uint nextPerms = permsMask | (item.NextPermissions & + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify)); + + // nextPerms now has all bits set, except for the actual + // next permission bits. + + // This checks for no mod, no copy, no trans. + // This indicates an error or messed up item. Do it like + // SL and assume trans + if (nextPerms == permsMask) + nextPerms |= (uint)PermissionMask.Transfer; + + // Inventory owner perms are the logical AND of the + // folded perms and the root prim perms, however, if + // the root prim is mod, the inventory perms will be + // mod. This happens on "take" and is of little concern + // here, save for preventing escalation + + // This hack ensures that items previously permalocked + // get unlocked when they're passed or rezzed + uint basePerms = item.BasePermissions | + (uint)PermissionMask.Move; + uint ownerPerms = item.CurrentPermissions; + + // If this is an object, root prim perms may be more + // permissive than folded perms. Use folded perms as + // a mask + if (item.InvType == (int)InventoryType.Object) { - // Trying to do this right this time. This is evil. If - // you believe in Good, go elsewhere. Vampires and other - // evil creatores only beyond this point. You have been - // warned. - - // We're going to mask a lot of things by the next perms - // Tweak the next perms to be nicer to our data - // - // In this mask, all the bits we do NOT want to mess - // with are set. These are: - // - // Transfer - // Copy - // Modufy - uint permsMask = ~ ((uint)PermissionMask.Copy | - (uint)PermissionMask.Transfer | - (uint)PermissionMask.Modify); - - // Now, reduce the next perms to the mask bits - // relevant to the operation - uint nextPerms = permsMask | (item.NextPermissions & - ((uint)PermissionMask.Copy | - (uint)PermissionMask.Transfer | - (uint)PermissionMask.Modify)); - - // nextPerms now has all bits set, except for the actual - // next permission bits. - - // This checks for no mod, no copy, no trans. - // This indicates an error or messed up item. Do it like - // SL and assume trans - if (nextPerms == permsMask) - nextPerms |= (uint)PermissionMask.Transfer; - - // Inventory owner perms are the logical AND of the - // folded perms and the root prim perms, however, if - // the root prim is mod, the inventory perms will be - // mod. This happens on "take" and is of little concern - // here, save for preventing escalation - - // This hack ensures that items previously permalocked - // get unlocked when they're passed or rezzed - uint basePerms = item.BasePermissions | - (uint)PermissionMask.Move; - uint ownerPerms = item.CurrentPermissions; - - // If this is an object, root prim perms may be more - // permissive than folded perms. Use folded perms as - // a mask - if (item.InvType == (int)InventoryType.Object) + // Create a safe mask for the current perms + uint foldedPerms = (item.CurrentPermissions & 7) << 13; + foldedPerms |= permsMask; + + bool isRootMod = (item.CurrentPermissions & + (uint)PermissionMask.Modify) != 0 ? + true : false; + + // Mask the owner perms to the folded perms + ownerPerms &= foldedPerms; + basePerms &= foldedPerms; + + // If the root was mod, let the mask reflect that + // We also need to adjust the base here, because + // we should be able to edit in-inventory perms + // for the root prim, if it's mod. + if (isRootMod) { - // Create a safe mask for the current perms - uint foldedPerms = (item.CurrentPermissions & 7) << 13; - foldedPerms |= permsMask; - - bool isRootMod = (item.CurrentPermissions & - (uint)PermissionMask.Modify) != 0 ? - true : false; - - // Mask the owner perms to the folded perms - ownerPerms &= foldedPerms; - basePerms &= foldedPerms; - - // If the root was mod, let the mask reflect that - // We also need to adjust the base here, because - // we should be able to edit in-inventory perms - // for the root prim, if it's mod. - if (isRootMod) - { - ownerPerms |= (uint)PermissionMask.Modify; - basePerms |= (uint)PermissionMask.Modify; - } + ownerPerms |= (uint)PermissionMask.Modify; + basePerms |= (uint)PermissionMask.Modify; } + } - // These will be applied to the root prim at next rez. - // The slam bit (bit 3) and folded permission (bits 0-2) - // are preserved due to the above mangling - ownerPerms &= nextPerms; + // These will be applied to the root prim at next rez. + // The slam bit (bit 3) and folded permission (bits 0-2) + // are preserved due to the above mangling + ownerPerms &= nextPerms; - // Mask the base permissions. This is a conservative - // approach altering only the three main perms - basePerms &= nextPerms; + // Mask the base permissions. This is a conservative + // approach altering only the three main perms + basePerms &= nextPerms; - // Assign to the actual item. Make sure the slam bit is - // set, if it wasn't set before. - itemCopy.BasePermissions = basePerms; - itemCopy.CurrentPermissions = ownerPerms; - itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; + // Assign to the actual item. Make sure the slam bit is + // set, if it wasn't set before. + itemCopy.BasePermissions = basePerms; + itemCopy.CurrentPermissions = ownerPerms; + itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; - itemCopy.NextPermissions = item.NextPermissions; + itemCopy.NextPermissions = item.NextPermissions; - // This preserves "everyone can move" - itemCopy.EveryOnePermissions = item.EveryOnePermissions & - nextPerms; + // This preserves "everyone can move" + itemCopy.EveryOnePermissions = item.EveryOnePermissions & + nextPerms; - // Intentionally killing "share with group" here, as - // the recipient will not have the group this is - // set to - itemCopy.GroupPermissions = 0; - } - else + // Intentionally killing "share with group" here, as + // the recipient will not have the group this is + // set to + itemCopy.GroupPermissions = 0; + } + else + { + itemCopy.CurrentPermissions = item.CurrentPermissions; + itemCopy.NextPermissions = item.NextPermissions; + itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; + itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; + itemCopy.BasePermissions = item.BasePermissions; + } + + if (itemCopy.Folder == UUID.Zero) + { + InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); + + if (folder != null) { - itemCopy.CurrentPermissions = item.CurrentPermissions; - itemCopy.NextPermissions = item.NextPermissions; - itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; - itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; - itemCopy.BasePermissions = item.BasePermissions; + itemCopy.Folder = folder.ID; } - - if (itemCopy.Folder == UUID.Zero) + else { - InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); + InventoryFolderBase root = InventoryService.GetRootFolder(recipient); - if (folder != null) - { - itemCopy.Folder = folder.ID; - } + if (root != null) + itemCopy.Folder = root.ID; else - { - InventoryFolderBase root = InventoryService.GetRootFolder(recipient); - - if (root != null) - itemCopy.Folder = root.ID; - else - return null; // No destination - } + return null; // No destination } + } - itemCopy.GroupID = UUID.Zero; - itemCopy.GroupOwned = false; - itemCopy.Flags = item.Flags; - itemCopy.SalePrice = item.SalePrice; - itemCopy.SaleType = item.SaleType; + itemCopy.GroupID = UUID.Zero; + itemCopy.GroupOwned = false; + itemCopy.Flags = item.Flags; + itemCopy.SalePrice = item.SalePrice; + itemCopy.SaleType = item.SaleType; - if (AddInventoryItem(itemCopy)) - { - IInventoryAccessModule invAccess = RequestModuleInterface(); - if (invAccess != null) - invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); - } + if (AddInventoryItem(itemCopy)) + { + IInventoryAccessModule invAccess = RequestModuleInterface(); + if (invAccess != null) + invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); + } - if (!Permissions.BypassPermissions()) + if (!Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) - { - List items = new List(); - items.Add(itemId); - InventoryService.DeleteItems(senderId, items); - } + List items = new List(); + items.Add(itemId); + InventoryService.DeleteItems(senderId, items); } - - return itemCopy; - } - else - { - m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId); - return null; } + return itemCopy; } /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 83f0686..10c275e 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -59,19 +59,24 @@ namespace OpenSim.Region.Framework.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneSetupHelpers.SetupScene(); - UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); - UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene); + UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); + UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID); InventoryItemBase retrievedItem1 - = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Objects/item1"); + = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Notecards/item1"); Assert.That(retrievedItem1, Is.Not.Null); // Try giving back the freshly received item - //scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID); + scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID); + + List reretrievedItems + = UserInventoryHelpers.GetInventoryItems(scene.InventoryService, user1.PrincipalID, "Notecards/item1"); + + Assert.That(reretrievedItems.Count, Is.EqualTo(2)); } [Test] @@ -81,8 +86,8 @@ namespace OpenSim.Region.Framework.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneSetupHelpers.SetupScene(); - UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); - UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene); + UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); + UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); InventoryFolderBase folder1 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1"); diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs index e543337..73dd06a 100644 --- a/OpenSim/Services/InventoryService/InventoryService.cs +++ b/OpenSim/Services/InventoryService/InventoryService.cs @@ -340,6 +340,9 @@ namespace OpenSim.Services.InventoryService List itemsList = new List(); itemsList.AddRange(m_Database.getInventoryInFolder(folderID)); + +// m_log.DebugFormat( +// "[INVENTORY SERVICE]: Found {0} items in folder {1} for {2}", itemsList.Count, folderID, userID); return itemsList; } @@ -385,8 +388,9 @@ namespace OpenSim.Services.InventoryService // See IInventoryServices public virtual bool AddItem(InventoryItemBase item) { - m_log.DebugFormat( - "[INVENTORY SERVICE]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder); +// m_log.DebugFormat( +// "[INVENTORY SERVICE]: Adding item {0} {1} to folder {2} for {3}", +// item.Name, item.ID, item.Folder, item.Owner); m_Database.addInventoryItem(item); diff --git a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs index 8cfad79..d924ecd 100644 --- a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs @@ -118,16 +118,19 @@ namespace OpenSim.Tests.Common public static UserAccount CreateUserWithInventory(Scene scene) { + return CreateUserWithInventory(scene, 99); + } + + public static UserAccount CreateUserWithInventory(Scene scene, int uuidTail) + { return CreateUserWithInventory( - scene, "Bill", "Bailey", UUID.Parse("00000000-0000-0000-0000-000000000099"), "troll"); + scene, "Bill", "Bailey", new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail)), "troll"); } public static UserAccount CreateUserWithInventory( Scene scene, string firstName, string lastName, UUID userId, string pw) { - UserAccount ua - = new UserAccount(userId) - { FirstName = firstName, LastName = lastName }; + UserAccount ua = new UserAccount(userId) { FirstName = firstName, LastName = lastName }; CreateUserWithInventory(scene, ua, pw); return ua; } diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs index 93b655a..875bf4a 100644 --- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs @@ -65,15 +65,18 @@ namespace OpenSim.Tests.Common /// public static InventoryItemBase CreateInventoryItem(Scene scene, string itemName, UUID itemId, UUID userId) { + AssetBase asset = AssetHelpers.CreateAsset(scene, userId); InventoryItemBase item = new InventoryItemBase(); item.Name = itemName; - item.AssetID = AssetHelpers.CreateAsset(scene, userId).FullID; + item.AssetID = asset.FullID; item.ID = itemId; + item.Owner = userId; + item.AssetType = asset.Type; + item.InvType = (int)InventoryType.Notecard; + + InventoryFolderBase folder = scene.InventoryService.GetFolderForType(userId, AssetType.Notecard); - // Really quite bad since the objs folder could be moved in the future and confuse the tests - InventoryFolderBase objsFolder = scene.InventoryService.GetFolderForType(userId, AssetType.Object); - - item.Folder = objsFolder.ID; + item.Folder = folder.ID; scene.AddInventoryItem(item); return item; @@ -165,5 +168,17 @@ namespace OpenSim.Tests.Common { return InventoryArchiveUtils.FindItemByPath(inventoryService, userId, path); } + + /// + /// Get the inventory items that match the path name. + /// + /// + /// + /// + /// An empty list if no matching items were found. + public static List GetInventoryItems(IInventoryService inventoryService, UUID userId, string path) + { + return InventoryArchiveUtils.FindItemsByPath(inventoryService, userId, path); + } } } \ No newline at end of file -- cgit v1.1 From fe471b64245f99a895d661a8952fc3c226ba6bfe Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 4 Jun 2011 02:44:53 +0100 Subject: Extend TestGiveInventoryFolder() to test giving back the freshly received folder --- .../Region/Framework/Scenes/Tests/UserInventoryTests.cs | 8 ++++++++ OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 10c275e..abca792 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -97,6 +97,14 @@ namespace OpenSim.Region.Framework.Tests = UserInventoryHelpers.GetInventoryFolder(scene.InventoryService, user2.PrincipalID, "folder1"); Assert.That(retrievedFolder1, Is.Not.Null); + + // Try giving back the freshly received folder + scene.GiveInventoryFolder(user1.PrincipalID, user2.PrincipalID, retrievedFolder1.ID, UUID.Zero); + + List reretrievedFolders + = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, "folder1"); + + Assert.That(reretrievedFolders.Count, Is.EqualTo(2)); } } } \ No newline at end of file diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs index 875bf4a..1703597 100644 --- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs @@ -147,8 +147,7 @@ namespace OpenSim.Tests.Common /// null if no folder matching the path was found public static InventoryFolderBase GetInventoryFolder(IInventoryService inventoryService, UUID userId, string path) { - List folders - = InventoryArchiveUtils.FindFolderByPath(inventoryService, userId, path); + List folders = GetInventoryFolders(inventoryService, userId, path); if (folders.Count != 0) return folders[0]; @@ -157,6 +156,18 @@ namespace OpenSim.Tests.Common } /// + /// Get the inventory folders that match the path name. + /// + /// + /// + /// + /// An empty list if no matching folders were found + public static List GetInventoryFolders(IInventoryService inventoryService, UUID userId, string path) + { + return InventoryArchiveUtils.FindFolderByPath(inventoryService, userId, path); + } + + /// /// Get the inventory item that matches the path name. If there are multiple items then only the first /// is returned. /// -- cgit v1.1 From 205b2f7ea4aacb66304d3e9a5c70c5001fdeda4d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 4 Jun 2011 03:01:52 +0100 Subject: Remove the unmaintained 'CMS' framework, which was really a 'source-control' experiment from 2008. This hasn't been touched for about 2 years and I haven't being using it. If this is wrong then please let me know. --- .../ContentManagementSystem/AuraMetaEntity.cs | 161 ----- .../ContentManagementSystem/BeamMetaEntity.cs | 139 ---- .../ContentManagementSystem/CMController.cs | 756 --------------------- .../ContentManagementSystem/CMEntityCollection.cs | 193 ------ .../ContentManagementSystem/CMModel.cs | 365 ---------- .../ContentManagementSystem/CMView.cs | 206 ------ .../ContentManagementEntity.cs | 375 ---------- .../ContentManagementModule.cs | 163 ----- .../ContentManagementSystem/FileSystemDatabase.cs | 317 --------- .../ContentManagementSystem/GitDatabase.cs | 167 ----- .../ContentManagementSystem/IContentDatabase.cs | 94 --- .../ContentManagementSystem/MetaEntity.cs | 270 -------- .../ContentManagementSystem/PointMetaEntity.cs | 104 --- .../OptionalModules/ContentManagementSystem/README | 52 -- .../SceneObjectGroupDiff.cs | 216 ------ 15 files changed, 3578 deletions(-) delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/README delete mode 100644 OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// AuraMetaEntity.cs created with MonoDevelop -// User: bongiojp at 3:03 PM 8/6/2008 -// -// To change standard headers go to Edit->Preferences->Coding->Standard Headers -// - -#endregion Header - -using System; -using System.Collections.Generic; -using System.Drawing; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class AuraMetaEntity : PointMetaEntity - { - #region Constructors - - //transparency of root part, NOT particle system. Should probably add support for changing particle system transparency. - public AuraMetaEntity(Scene scene, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale) - : base(scene, groupPos, transparency) - { - SetAura(color, scale); - } - - public AuraMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale) - : base(scene, uuid, groupPos, transparency) - { - SetAura(color, scale); - } - - #endregion Constructors - - #region Private Methods - - private float Average(Vector3 values) - { - return (values.X + values.Y + values.Z)/3f; - } - - #endregion Private Methods - - #region Public Methods - - public void SetAura(Vector3 color, Vector3 scale) - { - SetAura(color, Average(scale) * 2.0f); - } - - public void SetAura(Vector3 color, float radius) - { - SceneObjectPart From = m_Entity.RootPart; - - //m_log.Debug("[META ENTITY] BEFORE: radius = " + radius); - float burstRadius = 0.1f; - Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None; - float age = 1.5f; - float burstRate = 0.4f; - if (radius >= 8.0f) - { - //float sizeOfObject = radius / 2.0f; - burstRadius = (radius - 8.0f)/3f; - burstRate = 1.5f; - radius = 7.99f; - patternFlags = Primitive.ParticleSystem.SourcePattern.Explode; - age = 4.0f; - } - SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags); - } - - public void SetAura(SceneObjectPart From, Vector3 color, float radius, float burstRadius, float age, float burstRate, Primitive.ParticleSystem.SourcePattern patternFlags) - { - Primitive.ParticleSystem prules = new Primitive.ParticleSystem(); - //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive | - // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS - //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam | - // Primitive.ParticleSystem.ParticleDataFlags.TargetPos; - prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR - prules.PartStartColor.G = color.Y; - prules.PartStartColor.B = color.Z; - prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency - prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR - prules.PartEndColor.G = color.Y; - prules.PartEndColor.B = color.Z; - prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency - /*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE - prules.PartStartScaleY = 0.5f; - prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE - prules.PartEndScaleY = 0.5f; - */ - prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE - prules.PartStartScaleY = radius; - prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE - prules.PartEndScaleY = radius; - prules.PartMaxAge = age; //PSYS_PART_MAX_AGE - prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL - prules.PartAcceleration.Y = 0.0f; - prules.PartAcceleration.Z = 0.0f; - prules.Pattern = patternFlags; //PSYS_SRC_PATTERN - //prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank - prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE - prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT - //prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS - prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS - prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN - prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX - prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE - //prules.Target = To; //PSYS_SRC_TARGET_KEY - prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA - prules.AngularVelocity.Y = 0.0f; - prules.AngularVelocity.Z = 0.0f; - prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN - prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END - - prules.CRC = 1; //activates the particle system?? - From.AddNewParticleSystem(prules); - } - - #endregion Public Methods - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// BeamMetaEntity.cs created with MonoDevelop -// User: bongiojp at 3:03 PM 8/6/2008 -// -// To change standard headers go to Edit->Preferences->Coding->Standard Headers -// - -#endregion Header - -using System; -using System.Collections.Generic; -using System.Drawing; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class BeamMetaEntity : PointMetaEntity - { - #region Constructors - - public BeamMetaEntity(Scene scene, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color) - : base(scene, groupPos, transparency) - { - SetBeamToUUID(To, color); - } - - public BeamMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color) - : base(scene, uuid, groupPos, transparency) - { - SetBeamToUUID(To, color); - } - - #endregion Constructors - - #region Public Methods - - public void SetBeamToUUID(SceneObjectPart To, Vector3 color) - { - SceneObjectPart From = m_Entity.RootPart; - //Scale size of particles to distance objects are apart (for better visibility) - Vector3 FromPos = From.GetWorldPosition(); - Vector3 ToPos = From.GetWorldPosition(); - // UUID toUUID = To.UUID; - float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) + - Math.Pow(FromPos.X-ToPos.Y, 2) + - Math.Pow(FromPos.X-ToPos.Z, 2) - ) - ); - //float rate = (float) (distance/4f); - float rate = 0.5f; - float scale = (float) (distance/128f); - float speed = (float) (2.0f - distance/128f); - - SetBeamToUUID(From, To, color, rate, scale, speed); - } - - public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, Vector3 color, float rate, float scale, float speed) - { - Primitive.ParticleSystem prules = new Primitive.ParticleSystem(); - //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive | - // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS - prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam | - Primitive.ParticleSystem.ParticleDataFlags.TargetPos; - prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR - prules.PartStartColor.G = color.Y; - prules.PartStartColor.B = color.Z; - prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency - prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR - prules.PartEndColor.G = color.Y; - prules.PartEndColor.B = color.Z; - prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency - prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE - prules.PartStartScaleY = scale; - prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE - prules.PartEndScaleY = scale; - prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE - prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL - prules.PartAcceleration.Y = 0.0f; - prules.PartAcceleration.Z = 0.0f; - //prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN - //prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank - prules.BurstRate = rate; //PSYS_SRC_BURST_RATE - prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT - prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS - prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN - prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX - prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE - prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY - prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA - prules.AngularVelocity.Y = 0.0f; - prules.AngularVelocity.Z = 0.0f; - prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN - prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END - - prules.CRC = 1; //activates the particle system?? - From.AddNewParticleSystem(prules); - } - - #endregion Public Methods - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// CMController.cs -// User: bongiojp -// - -#endregion Header - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; - -using OpenMetaverse; - -using OpenSim; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - /// - /// 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, - /// 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. - /// - public class CMController - { - #region Static Fields - - private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue. - /// - private static OpenSim.Framework.BlockingQueue m_WorkQueue = new OpenSim.Framework.BlockingQueue(); - - #endregion Static Fields - - #region Fields - - //bool init = false; - int m_channel = -1; - - /// - /// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers. - /// - IEstateModule m_estateModule = null; - - //These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop) - CMModel m_model = null; - - /// - /// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region. - /// - Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable()); - State m_state = State.NONE; - CMView m_view = null; - - #endregion Fields - - #region Constructors - - /// - /// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method. - /// - /// - /// - /// - /// - /// - /// - /// - /// The first scene to keep track of. - /// - /// - /// The simchat channel number to listen to for instructions - /// - public CMController(CMModel model, CMView view, Scene scene, int channel) - { - m_model = model; m_view = view; m_channel = channel; - RegisterNewRegion(scene); - Initialize(model, view, scene, channel); - } - - #endregion Constructors - - #region Private Methods - - //------------------------------------------------ EVENTS ----------------------------------------------------// -// private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) -// { -// } - - /// - /// 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. - /// - private SceneObjectGroup GetGroupByPrim(uint localID) - { - foreach (Object currScene in m_sceneList.Values) - { - foreach (EntityBase ent in ((Scene)currScene).GetEntities()) - { - if (ent is SceneObjectGroup) - { - if (((SceneObjectGroup)ent).HasChildPrim(localID)) - return (SceneObjectGroup)ent; - } - } - } - return null; - } - - private void Initialize(CMModel model, CMView view, Scene scene, int channel) - { - lock (this) - { - m_estateModule = scene.RequestModuleInterface(); - Watchdog.StartThread(MainLoop, "Content Management", ThreadPriority.Normal, true); - m_state = State.NONE; - } - } - - /// - /// 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. - /// - private void MainLoop() - { - try - { - CMModel model = m_model; CMView view = m_view; int channel = m_channel; - Work currentJob = new Work(); - while (true) - { - currentJob = m_WorkQueue.Dequeue(); - m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request"); - m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type); - switch (currentJob.Type) - { - case WorkType.NONE: - break; - case WorkType.OBJECTATTRIBUTECHANGE: - ObjectAttributeChanged(model, view, currentJob.LocalId); - break; - case WorkType.PRIMITIVEADDED: - PrimitiveAdded(model, view, currentJob); - break; - case WorkType.OBJECTDUPLICATED: - ObjectDuplicated(model, view, currentJob.LocalId); - break; - case WorkType.OBJECTKILLED: - ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1); - break; - case WorkType.UNDODID: - UndoDid(model, view, currentJob.UUID); - break; - case WorkType.NEWCLIENT: - NewClient(view, (IClientAPI) currentJob.Data1); - break; - case WorkType.SIMCHAT: - m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message); - SimChat(model, view, (OSChatMessage) currentJob.Data1, channel); - break; - default: - m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?"); - break; - } - - Watchdog.UpdateThread(); - } - } - catch (Exception e) - { - // TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened - m_log.ErrorFormat( - "[CONTENT MANAGEMENT]: Content management thread terminating with exception. PLEASE REBOOT YOUR SIM - CONTENT MANAGEMENT WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}", - e); - } - - Watchdog.RemoveThread(); - } - - /// - /// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled. - /// - private void NewClient(CMView view, IClientAPI client) - { - if ((m_state & State.SHOWING_CHANGES) > 0) - view.SendMetaEntitiesToNewClient(client); - } - - /// - /// Only called by the MainLoop. - /// - private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId) - { - SceneObjectGroup group = null; - if ((m_state & State.SHOWING_CHANGES) > 0) - { - group = GetGroupByPrim(LocalId); - if (group != null) - { - view.DisplayAuras(model.UpdateNormalEntityEffects(group)); //Might be a normal entity (green aura) - m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura) - } - } - } - - /// - /// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied. - /// - private void ObjectDuplicated(CMModel model, CMView view, uint localId) - { - if ((m_state & State.SHOWING_CHANGES) > 0) - view.DisplayAuras(model.CheckForNewEntitiesMissingAuras(GetGroupByPrim(localId).Scene)); - } - - /// - /// Only called by the MainLoop. - /// - private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group) - { - if ((m_state & State.SHOWING_CHANGES) > 0) - { - view.RemoveOrUpdateDeletedEntity(group); - model.RemoveOrUpdateDeletedEntity(group); - } - } - - /// - /// Only called by the MainLoop. - /// - private void PrimitiveAdded(CMModel model, CMView view, Work currentJob) - { - if ((m_state & State.SHOWING_CHANGES) > 0) - { - foreach (Object scene in m_sceneList.Values) - m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene)); - } - } - - /// - /// Only called by the MainLoop. - /// - private void UndoDid(CMModel model, CMView view, UUID uuid) - { - if ((m_state & State.SHOWING_CHANGES) > 0) - { - ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid); - if (ent != null) - view.DisplayEntity(ent); - } - } - - #endregion Private Methods - - #region Protected Methods - - protected void GroupBeingDeleted(SceneObjectGroup group) - { - m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!"); - Work moreWork = new Work(); - moreWork.Type = WorkType.OBJECTKILLED; - moreWork.Data1 = group.Copy(); - m_WorkQueue.Enqueue(moreWork); - } - - protected void ObjectDuplicated(uint localID, Vector3 offset, uint dupeFlags, UUID AgentID, UUID GroupID) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.OBJECTDUPLICATED; - moreWork.LocalId = localID; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] dup queue"); - } - - protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID, - UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart, - bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.OBJECTDUPLICATED; - moreWork.LocalId = localID; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] dup queue"); - } - - protected void OnNewClient(IClientAPI client) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.NEWCLIENT; - moreWork.Data1 = client; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] new client"); - } - - protected void OnUnDid(IClientAPI remoteClient, UUID primId) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.UNDODID; - moreWork.UUID = primId; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] undid"); - } - - /// - /// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument. - /// - protected static System.Collections.Generic.List ScenesInOrderOfProximity(Hashtable sceneList, Scene scene) - { - int somethingAddedToList = 1; - System.Collections.Generic.List newList = new List(); - newList.Add(scene); - - if (!sceneList.ContainsValue(scene)) - { - foreach (Object sceneObj in sceneList) - newList.Add((Scene) sceneObj); - return newList; - } - - while (somethingAddedToList > 0) - { - somethingAddedToList = 0; - for (int i = 0; i < newList.Count; i++) - { - foreach (Object sceneObj in sceneList.Values) - { - if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (!newList.Contains((Scene)sceneObj))) - { - newList.Add((Scene)sceneObj); - somethingAddedToList++; - } - } - } - } - - foreach (Object sceneObj in sceneList.Values) - if (!newList.Contains((Scene)sceneObj)) - newList.Add((Scene)sceneObj); - - return newList; - } - - //This is stupid, the same information is contained in the first and second argument - protected void SimChatSent(Object x, OSChatMessage e) - { - m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!"); - m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message); - Work moreWork = new Work(); - moreWork.Type = WorkType.SIMCHAT; - moreWork.Data1 = e; - m_WorkQueue.Enqueue(moreWork); - } - - /// - /// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions. - /// - protected void StartManaging(IClientAPI client) - { - m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services."); - // client.OnChatFromClient += SimChatSent; - //init = true; - - OnNewClient(client); - - m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client."); - client.OnUpdatePrimScale += UpdateSingleScale; - client.OnUpdatePrimGroupScale += UpdateMultipleScale; - client.OnUpdatePrimGroupPosition += UpdateMultiplePosition; - client.OnUpdatePrimSinglePosition += UpdateSinglePosition; - client.OnUpdatePrimGroupRotation += UpdateMultipleRotation; - client.OnUpdatePrimSingleRotation += UpdateSingleRotation; - client.OnAddPrim += UpdateNewParts; - client.OnObjectDuplicate += ObjectDuplicated; - client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay; - client.OnUndo += OnUnDid; - //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation; - } - - /// - /// - /// - protected void StopManaging(UUID clientUUID) - { - foreach (Object sceneobj in m_sceneList.Values) - { - ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID); - if (presence != null) - { - IClientAPI client = presence.ControllingClient; - m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services."); - // client.OnChatFromViewer -= SimChatSent; - - m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client"); - client.OnUpdatePrimScale -= UpdateSingleScale; - client.OnUpdatePrimGroupScale -= UpdateMultipleScale; - client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition; - client.OnUpdatePrimSinglePosition -= UpdateSinglePosition; - client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation; - client.OnUpdatePrimSingleRotation -= UpdateSingleRotation; - client.OnAddPrim -= UpdateNewParts; - client.OnObjectDuplicate -= ObjectDuplicated; - client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay; - client.OnUndo -= OnUnDid; - //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation; - return; - } - } - } - - protected void UpdateMultiplePosition(uint localID, Vector3 pos, IClientAPI remoteClient) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; - moreWork.LocalId = localID; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] pos"); - } - - protected void UpdateMultipleRotation(uint localID, Quaternion rot, IClientAPI remoteClient) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; - moreWork.LocalId = localID; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] rot"); - } - - protected void UpdateMultipleScale(uint localID, Vector3 scale, IClientAPI remoteClient) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; - moreWork.LocalId = localID; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT]scale"); - } - - protected void UpdateNewParts(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape, - byte bypassRaycast, Vector3 RayStart, UUID RayTargetID, - byte RayEndIsIntersection) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.PRIMITIVEADDED; - moreWork.UUID = ownerID; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] new parts"); - } - - protected void UpdateSinglePosition(uint localID, Vector3 pos, IClientAPI remoteClient) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; - moreWork.LocalId = localID; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] move"); - } - - /// - /// - /// - protected void UpdateSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; - moreWork.LocalId = localID; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] rot"); - } - - protected void UpdateSingleScale(uint localID, Vector3 scale, IClientAPI remoteClient) - { - Work moreWork = new Work(); - moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; - moreWork.LocalId = localID; - m_WorkQueue.Enqueue(moreWork); - m_log.Debug("[CONTENT MANAGEMENT] scale"); - } - - /// - /// Only called from within the SimChat method. - /// - protected void commit(string message, Scene scene, CMModel model, CMView view) - { - System.Collections.Generic.List proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene); - - string[] args = message.Split(new char[] {' '}); - - char[] logMessage = {' '}; - if (args.Length > 1) - { - logMessage = new char[message.Length - (args[0].Length)]; - message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length)); - } - - m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region."); - foreach (Scene currScene in proximitySceneList) - { - model.CommitRegion(currScene, new String(logMessage)); - view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName); - } - - view.SendSimChatMessage(scene, "Successfully saved all regions."); - m_state |= State.DIRTY; - - if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES - { - view.SendSimChatMessage(scene, "Updating differences between new revision and current environment."); - //Hide objects from users and Forget about them - view.HideAllMetaEntities(); - view.HideAllAuras(); - model.DeleteAllMetaObjects(); - - //Recreate them from backend files - foreach (Scene currScene in proximitySceneList) - { - model.UpdateCMEntities(currScene); - view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName); - } - - //Display new objects to users1 - view.DisplayRecentChanges(); - view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE."); - m_state &= ~(State.DIRTY); - m_state |= State.SHOWING_CHANGES; - } - } - - /// - /// Only called from within the SimChat method. - /// - protected void diffmode(Scene scene, CMModel model, CMView view) - { - System.Collections.Generic.List proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene); - - if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF - { - view.SendSimChatMessage(scene, "Hiding all meta objects."); - view.HideAllMetaEntities(); - view.HideAllAuras(); - view.SendSimChatMessage(scene, "Diff-mode = OFF"); - - m_state &= ~State.SHOWING_CHANGES; - return; - } - else // TURN ON - { - if ((m_state & State.DIRTY) != 0 || m_state == State.NONE) - { - view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision"); - //Hide objects from users and Forget about them - view.HideAllMetaEntities(); - view.HideAllAuras(); - model.DeleteAllMetaObjects(); - //Recreate them from backend files - foreach (Object currScene in m_sceneList.Values) - model.UpdateCMEntities((Scene) currScene); - } - else if ((m_state & State.DIRTY) != 0) { - view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision"); - foreach (Scene currScene in proximitySceneList) - model.UpdateCMEntities(currScene); - } - - view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment"); - foreach (Scene currScene in proximitySceneList) - model.CheckForNewEntitiesMissingAuras(currScene); - view.DisplayRecentChanges(); - - view.SendSimChatMessage(scene, "Diff-mode = ON"); - m_state |= State.SHOWING_CHANGES; - m_state &= ~State.DIRTY; - } - } - - /// - /// Only called from within the SimChat method. Hides all auras and meta entities, - /// retrieves the current scene object list with the most recent revision retrieved from the model for each scene, - /// then lets the view update the clients of the new objects. - /// - protected void rollback(Scene scene, CMModel model, CMView view) - { - if ((m_state & State.SHOWING_CHANGES) > 0) - { - view.HideAllAuras(); - view.HideAllMetaEntities(); - } - - System.Collections.Generic.List proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene); - foreach (Scene currScene in proximitySceneList) - model.RollbackRegion(currScene); - - if ((m_state & State.DIRTY) != 0) - { - model.DeleteAllMetaObjects(); - foreach (Scene currScene in proximitySceneList) - model.UpdateCMEntities(currScene); - } - - if ((m_state & State.SHOWING_CHANGES) > 0) - view.DisplayRecentChanges(); - } - - #endregion Protected Methods - - #region Public Methods - - /// - /// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene. - /// - /// - /// A - /// - public void RegisterNewRegion(Scene scene) - { - m_sceneList.Add(scene.RegionInfo.RegionID, scene); - - m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID); - m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System."); - - scene.EventManager.OnNewClient += StartManaging; - scene.EventManager.OnChatFromClient += SimChatSent; - scene.EventManager.OnRemovePresence += StopManaging; - // scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; - scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted; - } - - /// - /// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command. - /// - public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel) - { - if (e.Channel != channel) - return; - if (e.Sender == null) - return; - - m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message); - - IClientAPI client = e.Sender; - Scene scene = (Scene) e.Scene; - string message = e.Message; - string[] args = e.Message.Split(new char[] {' '}); - - ScenePresence avatar = scene.GetScenePresence(client.AgentId); - - if (!(m_estateModule.IsManager(avatar.UUID))) - { - m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring."); - view.SendSimChatMessage(scene, "You must be an estate manager to perform that action."); - return; - } - - switch (args[0]) - { - case "ci": - case "commit": - commit(message, scene, model, view); - break; - case "dm": - case "diff-mode": - diffmode(scene, model, view); - break; - case "rb": - case "rollback": - rollback(scene, model, view); - break; - case "help": - m_view.DisplayHelpMenu(scene); - break; - default: - view.SendSimChatMessage(scene, "Command not found: " + args[0]); - break; - } - } - - #endregion Public Methods - - #region Other - - /// - /// 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. - /// - [Flags] - private enum State - { - NONE = 0, - DIRTY = 1, // The meta entities may not correctly represent the last revision. - SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user. - } - - /// - /// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem. - /// - private struct Work - { - #region Fields - - public Object Data1; //Just space for holding data. - public Object Data2; //Just more space for holding data. - public uint LocalId; //Convenient - public WorkType Type; - public UUID UUID; //Convenient - - #endregion Fields - } - - /// - /// Identifies what the data in struct Work should be used for. - /// - private enum WorkType - { - NONE, - OBJECTATTRIBUTECHANGE, - PRIMITIVEADDED, - OBJECTDUPLICATED, - OBJECTKILLED, - UNDODID, - NEWCLIENT, - SIMCHAT - } - - #endregion Other - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// CMEntityCollection.cs created with MonoDevelop -// User: bongiojp at 10:09 AM 7/7/2008 -// -// Creates, Deletes, Stores ContentManagementEntities -// - -#endregion Header - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Threading; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class CMEntityCollection - { - #region Fields - - // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - // Any ContentManagementEntities that represent old versions of current SceneObjectGroups or - // old versions of deleted SceneObjectGroups will be stored in this hash table. - // The UUID keys are from the SceneObjectGroup RootPart UUIDs - protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //UUID to ContentManagementEntity - - // SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable - // The UUID keys are from the SceneObjectPart that they are supposed to be on. - protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //UUID to AuraMetaEntity - - #endregion Fields - - #region Constructors - - public CMEntityCollection() - { - } - - #endregion Constructors - - #region Public Properties - - public Hashtable Auras - { - get {return m_NewlyCreatedEntityAura; } - } - - public Hashtable Entities - { - get { return m_CMEntityHash; } - } - - #endregion Public Properties - - #region Public Methods - - public bool AddAura(ContentManagementEntity aura) - { - if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID)) - return false; - m_NewlyCreatedEntityAura.Add(aura.UUID, aura); - return true; - } - - public bool AddEntity(ContentManagementEntity ent) - { - if (m_CMEntityHash.ContainsKey(ent.UUID)) - return false; - m_CMEntityHash.Add(ent.UUID, ent); - return true; - } - - // Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash - public System.Collections.ArrayList CheckForMissingEntities(EntityBase[] currList) - { - System.Collections.ArrayList missingList = new System.Collections.ArrayList(); - SceneObjectGroup temp = null; - foreach (EntityBase currObj in currList) - { - if (!(currObj is SceneObjectGroup)) - continue; - temp = (SceneObjectGroup) currObj; - - if (m_CMEntityHash.ContainsKey(temp.UUID)) - { - foreach (SceneObjectPart part in temp.Parts) - if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) - missingList.Add(part); - } - else //Entire group is missing from revision. (and is a new part in region) - { - foreach (SceneObjectPart part in temp.Parts) - missingList.Add(part); - } - } - return missingList; - } - - public void ClearAll() - { - m_CMEntityHash.Clear(); - m_NewlyCreatedEntityAura.Clear(); - } - - // Old uuid and new sceneobjectgroup - public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part) - { - AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene, - part.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - new Vector3(0,254,0), - part.Scale - ); - m_NewlyCreatedEntityAura.Add(part.UUID, ent); - return ent; - } - - // Old uuid and new sceneobjectgroup - public ContentManagementEntity CreateNewEntity(SceneObjectGroup group) - { - ContentManagementEntity ent = new ContentManagementEntity(group, false); - m_CMEntityHash.Add(group.UUID, ent); - return ent; - } - - public ContentManagementEntity CreateNewEntity(String xml, Scene scene) - { - ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false); - if (ent == null) - return null; - m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent); - return ent; - } - - public bool RemoveEntity(UUID uuid) - { - if (!m_CMEntityHash.ContainsKey(uuid)) - return false; - m_CMEntityHash.Remove(uuid); - return true; - } - - public bool RemoveNewlyCreatedEntityAura(UUID uuid) - { - if (!m_NewlyCreatedEntityAura.ContainsKey(uuid)) - return false; - m_NewlyCreatedEntityAura.Remove(uuid); - return true; - } - - #endregion Public Methods - } -} diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs deleted file mode 100644 index 3a6996e..0000000 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; - -using OpenMetaverse; - -using OpenSim; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Scenes.Serialization; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class CMModel - { - #region Static Fields - - static float TimeToUpdate = 0; - static float TimeToConvertXml = 0; - private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - #endregion Static Fields - - #region Fields - - /// - /// The class that contains all auras and metaentities used in the CMS. - /// - CMEntityCollection m_MetaEntityCollection = new CMEntityCollection(); - IContentDatabase m_database = null; - - #endregion Fields - - #region Constructors - - public CMModel() - { - } - - #endregion Constructors - - #region Public Properties - - public CMEntityCollection MetaEntityCollection - { - get { return m_MetaEntityCollection; } - } - - #endregion Public Properties - - #region Public Methods - - /// - /// 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 - /// it is a new part that must have a green aura (for diff mode). - /// Returns list of ContentManagementEntities - /// - public ArrayList CheckForNewEntitiesMissingAuras(Scene scene) - { - ArrayList missingList = null; - ArrayList newList = new ArrayList(); - - m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName); - - //Check if the current scene has groups not included in the current list of MetaEntities - //If so, then the current scene's parts that are new should be marked green. - missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities()); - - foreach (Object missingPart in missingList) - { - if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID)) - continue; - newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart)); - } - m_log.Info("Number of missing objects found: " + newList.Count); - return newList; - } - - /// - /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message. - /// - public void CommitRegion(Scene scene, String logMessage) - { - m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length); - m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage); - m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName); - } - - public void DeleteAllMetaObjects() - { - m_MetaEntityCollection.ClearAll(); - } - - public ContentManagementEntity FindMetaEntityAffectedByUndo(UUID uuid) - { - ContentManagementEntity ent = GetMetaGroupByPrim(uuid); - return ent; - } - - //-------------------------------- HELPERS --------------------------------------------------------------------// - public ContentManagementEntity GetMetaGroupByPrim(UUID uuid) - { - foreach (Object ent in m_MetaEntityCollection.Entities.Values) - { - if (((ContentManagementEntity)ent).HasChildPrim(uuid)) - return (ContentManagementEntity)ent; - } - return null; - } - - public void Initialise(string database) - { - if (database == "FileSystemDatabase") - m_database = new FileSystemDatabase(); - else if (database == "GitDatabase") - m_database = new GitDatabase(); - } - - public void InitialiseDatabase(Scene scene, string dir) - { - m_database.Initialise(scene, dir); - } - - /// - /// Should be called just once to finish initializing the database. - /// - public void PostInitialise() - { - m_database.PostInitialise(); - } - - /// - /// Removes the green aura when an a new scene object group is deleted. - /// - public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) - { - // Deal with new parts not revisioned that have been deleted. - SceneObjectPart[] parts = group.Parts; - for (int i = 0; i < parts.Length; i++) - { - if (m_MetaEntityCollection.Auras.ContainsKey(parts[i].UUID)) - m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(parts[i].UUID); - } - } - - /// - /// Retrieves the latest revision of a region in xml form, - /// converts it to scene object groups and scene presences, - /// swaps the current scene's entity list with the revision's list. - /// Note: Since deleted objects while - /// - public void RollbackRegion(Scene scene) - { - System.Collections.ArrayList xmllist = null; - SceneObjectGroup temp = null; - System.Collections.Hashtable deleteListUUIDs = new Hashtable(); -// Dictionary SearchList = new Dictionary(); - Dictionary ReplacementList = new Dictionary(); - int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID); -// EntityBase[] searchArray; - - xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision); - if (xmllist == null) - { - m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ")."); - return; - } - - m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ")."); - m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count); - m_log.Info("[CMMODEL]: Converting scene entities list to specified revision."); - - m_log.ErrorFormat("[CMMODEL]: 1"); - - foreach (string xml in xmllist) - { - try - { - temp = SceneObjectSerializer.FromXml2Format(xml); - temp.SetScene(scene); - - SceneObjectPart[] parts = temp.Parts; - for (int i = 0; i < parts.Length; i++) - parts[i].RegionHandle = scene.RegionInfo.RegionHandle; - - ReplacementList.Add(temp.UUID, (EntityBase)temp); - } - catch (Exception e) - { - m_log.Info("[CMMODEL]: Error while creating replacement list for rollback: " + e); - } - } - - //If in scene but not in revision and not a client, remove them - while (true) - { - try - { - foreach (EntityBase entity in scene.GetEntities()) - { - if (entity == null) - continue; - - if (entity is ScenePresence) - { - ReplacementList.Add(entity.UUID, entity); - continue; - } - else //if (!ReplacementList.ContainsKey(entity.UUID)) - deleteListUUIDs.Add(entity.UUID, 0); - } - } - catch(Exception e) - { - m_log.ErrorFormat("[CMMODEL]: " + e); - deleteListUUIDs.Clear(); - ReplacementList.Clear(); - continue; - } - break; - } - - foreach (UUID uuid in deleteListUUIDs.Keys) - { - try - { - // I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles. - ((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup(); - scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor); - scene.SendKillObject(scene.Entities[uuid].LocalId); - scene.SceneGraph.DeleteSceneObject(uuid, false); - ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroupFromScene(false); - } - catch(Exception e) - { - m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e); - } - } - - lock (scene) - { - scene.Entities.Clear(); - - foreach (KeyValuePair kvp in ReplacementList) - { - scene.Entities.Add(kvp.Value); - } - } - - foreach (EntityBase ent in ReplacementList.Values) - { - try - { - if (!(ent is SceneObjectGroup)) - continue; - - if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) PrimFlags.Phantom) == 0) - ((SceneObjectGroup)ent).ApplyPhysics(true); - ((SceneObjectGroup)ent).AttachToBackup(); - ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected. - ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); - } - catch(Exception e) - { - m_log.ErrorFormat("[CMMODEL]: Error while attaching new scene entities to backup and scheduling for a full update: " + e); - } - } - m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup."); - scene.Backup(true); - } - - /// - /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences - /// and display the differences to clients. - /// - public void UpdateCMEntities(Scene scene) - { - Stopwatch x = new Stopwatch(); - x.Start(); - - System.Collections.ArrayList xmllist = null; - m_log.Debug("[CONTENT MANAGEMENT] Retrieving object xml files for region: " + scene.RegionInfo.RegionID); - xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID); - m_log.Info("[FSDB]: got list"); - if (xmllist == null) - return; - - Stopwatch y = new Stopwatch(); - y.Start(); - foreach (string xml in xmllist) - m_MetaEntityCollection.CreateNewEntity(xml, scene); - y.Stop(); - TimeToConvertXml += y.ElapsedMilliseconds; - m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds); - m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml); - - m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras"); - CheckForNewEntitiesMissingAuras(scene); - - x.Stop(); - TimeToUpdate += x.ElapsedMilliseconds; - m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds); - m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate); - } - - /// - /// Detects if a scene object group from the scene list has moved or changed scale. The green aura - /// that surrounds the object is then moved or scaled with the group. - /// - public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group) - { - System.Collections.ArrayList auraList = new System.Collections.ArrayList(); - if (group == null) - return null; - - SceneObjectPart[] parts = group.Parts; - for (int i = 0; i < parts.Length; i++) - { - SceneObjectPart part = parts[i]; - if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) - { - ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0, 254, 0), part.Scale); - ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); - auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); - } - } - - return auraList; - } - - #endregion Public Methods - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// CMView.cs created with MonoDevelop -// User: bongiojp at 11:57 AM 7/3/2008 -// -// To change standard headers go to Edit->Preferences->Coding->Standard Headers -// - -#endregion Header - -using System; -using System.Collections; -using System.Collections.Generic; - -using OpenMetaverse; - -using OpenSim; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class CMView - { - #region Static Fields - - private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - #endregion Static Fields - - #region Fields - - CMModel m_model = null; - - #endregion Fields - - #region Constructors - - public CMView() - { - } - - #endregion Constructors - - #region Public Methods - - // Auras To - public void DisplayAuras(CMEntityCollection auraCollection) - { - foreach (Object ent in auraCollection.Auras.Values) - ((AuraMetaEntity)ent).SendFullUpdateToAll(); - } - - // Auras To Client - public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client) - { - foreach (Object ent in auraCollection.Auras.Values) - ((AuraMetaEntity)ent).SendFullUpdate(client); - } - - // Auras from List To ALL - public void DisplayAuras(ArrayList list) - { - foreach (Object ent in list) - { - m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW"); - ((AuraMetaEntity)ent).SendFullUpdateToAll(); - } - } - - // Entities to ALL - public void DisplayEntities(CMEntityCollection entityCollection) - { - foreach (Object ent in entityCollection.Entities.Values) - ((ContentManagementEntity)ent).SendFullDiffUpdateToAll(); - } - - // Entities to Client - public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client) - { - foreach (Object ent in entityCollection.Entities.Values) - ((ContentManagementEntity)ent).SendFullDiffUpdate(client); - } - - // Entities from List to ALL - public void DisplayEntities(ArrayList list) - { - foreach (Object ent in list) - ((ContentManagementEntity)ent).SendFullDiffUpdateToAll(); - } - - // Entity to ALL - public void DisplayEntity(ContentManagementEntity ent) - { - ent.SendFullDiffUpdateToAll(); - } - - public void DisplayHelpMenu(Scene scene) - { - string menu = "Menu:\n"; - menu += "commit (ci) - saves current state of the region to a database on the server\n"; - 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"; - SendSimChatMessage(scene, menu); - } - - public void DisplayMetaEntity(UUID uuid) - { - ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid); - if (group != null) - group.SendFullDiffUpdateToAll(); - } - - /// - /// update all clients of red/green/blue auras and meta entities that the model knows about. - /// - public void DisplayRecentChanges() - { - m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects."); - DisplayEntities(m_model.MetaEntityCollection); - DisplayAuras(m_model.MetaEntityCollection); - } - - public void Hide(ContentManagementEntity ent) - { - ent.HideFromAll(); - } - - public void HideAllAuras() - { - foreach (Object obj in m_model.MetaEntityCollection.Auras.Values) - ((MetaEntity)obj).HideFromAll(); - } - - public void HideAllMetaEntities() - { - foreach (Object obj in m_model.MetaEntityCollection.Entities.Values) - ((ContentManagementEntity)obj).HideFromAll(); - } - - public void Initialise(CMModel model) - { - m_model = model; - } - - /// - /// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted. - /// If it's a new scene object, any green aura attached to it is deleted. - /// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will - /// figure out that there should be a red aura and not a blue aura/beam. - /// - public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) - { - // Deal with revisioned parts that have been deleted. - if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID)) - ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); - - // Deal with new parts not revisioned that have been deleted. - foreach (SceneObjectPart part in group.Parts) - if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) - ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); - } - - public void SendMetaEntitiesToNewClient(IClientAPI client) - { - } - - public void SendSimChatMessage(Scene scene, string message) - { - scene.SimChat(Utils.StringToBytes(message), - ChatTypeEnum.Broadcast, 0, new Vector3(0,0,0), "Content Manager", UUID.Zero, false); - } - - #endregion Public Methods - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Drawing; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Scenes.Serialization; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class ContentManagementEntity : MetaEntity - { - #region Static Fields - -// static float TimeToDiff = 0; -// static float TimeToCreateEntities = 0; - - #endregion Static Fields - - #region Fields - - protected Dictionary m_AuraEntities = new Dictionary(); - protected Dictionary m_BeamEntities = new Dictionary(); - - // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different. - // This can come in handy. - protected SceneObjectGroup m_UnchangedEntity = null; - - /// - /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list. - /// - bool DiffersFromSceneGroup = false; - - #endregion Fields - - #region Constructors - - public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics) - : base(Unchanged, false) - { - m_UnchangedEntity = Unchanged.Copy(false); - } - - public ContentManagementEntity(string objectXML, Scene scene, bool physics) - : base(objectXML, scene, false) - { - m_UnchangedEntity = SceneObjectSerializer.FromXml2Format(objectXML); - } - - #endregion Constructors - - #region Public Properties - - public SceneObjectGroup UnchangedEntity - { - get { return m_UnchangedEntity; } - } - - #endregion Public Properties - - #region Private Methods - - /// - /// Check if an entitybase list (like that returned by scene.GetEntities()) contains a group with the rootpart uuid that matches the current uuid. - /// - private bool ContainsKey(List list, UUID uuid) - { - foreach (EntityBase part in list) - if (part.UUID == uuid) - return true; - return false; - } - - private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List list, UUID uuid) - { - foreach (EntityBase ent in list) - { - if (ent is SceneObjectGroup) - if (ent.UUID == uuid) - return (SceneObjectGroup)ent; - } - return null; - } - - #endregion Private Methods - - #region Public Methods - - /// - /// 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. - /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately. - /// - public void FindDifferences() - { - List sceneEntityList = new List(m_Entity.Scene.GetEntities()); - DiffersFromSceneGroup = false; - // if group is not contained in scene's list - if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) - { - foreach (SceneObjectPart part in m_UnchangedEntity.Parts) - { - // if scene list no longer contains this part, display translucent part and mark with red aura - if (!ContainsKey(sceneEntityList, part.UUID)) - { - // if already displaying a red aura over part, make sure its red - if (m_AuraEntities.ContainsKey(part.UUID)) - { - m_AuraEntities[part.UUID].SetAura(new Vector3(254, 0, 0), part.Scale); - } - else - { - AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, - part.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - new Vector3(254, 0, 0), - part.Scale - ); - m_AuraEntities.Add(part.UUID, auraGroup); - } - SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); - SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); - } - // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id - } - - // a deleted part has no where to point a beam particle system, - // if a metapart had a particle system (maybe it represented a moved part) remove it - if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) - { - m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); - m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); - } - - DiffersFromSceneGroup = true; - } - // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately - else - { - MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID)); - } - } - - /// - /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID. - /// - public bool HasChildPrim(UUID uuid) - { - return m_UnchangedEntity.ContainsPart(uuid); - } - - /// - /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId. - /// - public bool HasChildPrim(uint localID) - { - foreach (SceneObjectPart part in m_UnchangedEntity.Parts) - if (part.LocalId == localID) - return true; - - return false; - } - - public override void Hide(IClientAPI client) - { - base.Hide(client); - foreach (MetaEntity group in m_AuraEntities.Values) - group.Hide(client); - foreach (MetaEntity group in m_BeamEntities.Values) - group.Hide(client); - } - - public override void HideFromAll() - { - base.HideFromAll(); - foreach (MetaEntity group in m_AuraEntities.Values) - group.HideFromAll(); - foreach (MetaEntity group in m_BeamEntities.Values) - group.HideFromAll(); - } - - /// - /// Returns true if there was a change between meta entity and the entity group, false otherwise. - /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated). - /// - public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup) - { - SceneObjectPart sceneEntityPart; - SceneObjectPart metaEntityPart; - Diff differences; - bool changed = false; - - // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user - // had originally saved. - // m_Entity will NOT necessarily be the same entity as the user had saved. - foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Parts) - { - //This is the part that we use to show changes. - metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); - if (sceneEntityGroup.ContainsPart(UnchangedPart.UUID)) - { - sceneEntityPart = sceneEntityGroup.GetChildPart(UnchangedPart.UUID); - differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); - if (differences != Diff.NONE) - metaEntityPart.Text = "CHANGE: " + differences.ToString(); - if (differences != 0) - { - // Root Part that has been modified - if ((differences & Diff.POSITION) > 0) - { - // If the position of any part has changed, make sure the RootPart of the - // meta entity is pointing with a beam particle system - if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) - { - m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); - m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); - } - BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, - m_UnchangedEntity.RootPart.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - sceneEntityPart, - new Vector3(0, 0, 254) - ); - m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); - } - - if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) - { - m_AuraEntities[UnchangedPart.UUID].HideFromAll(); - m_AuraEntities.Remove(UnchangedPart.UUID); - } - AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, - UnchangedPart.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - new Vector3(0, 0, 254), - UnchangedPart.Scale - ); - m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); - SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); - - DiffersFromSceneGroup = true; - } - else // no differences between scene part and meta part - { - if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) - { - m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); - m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); - } - if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) - { - m_AuraEntities[UnchangedPart.UUID].HideFromAll(); - m_AuraEntities.Remove(UnchangedPart.UUID); - } - SetPartTransparency(metaEntityPart, MetaEntity.NONE); - } - } - else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. - { - if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) - { - m_AuraEntities[UnchangedPart.UUID].HideFromAll(); - m_AuraEntities.Remove(UnchangedPart.UUID); - } - AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, - UnchangedPart.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - new Vector3(254, 0, 0), - UnchangedPart.Scale - ); - m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); - SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); - - DiffersFromSceneGroup = true; - } - } - - return changed; - } - - public void SendFullAuraUpdate(IClientAPI client) - { - if (DiffersFromSceneGroup) - { - foreach (AuraMetaEntity group in m_AuraEntities.Values) - group.SendFullUpdate(client); - } - } - - public void SendFullAuraUpdateToAll() - { - if (DiffersFromSceneGroup) - { - foreach (AuraMetaEntity group in m_AuraEntities.Values) - group.SendFullUpdateToAll(); - } - } - - public void SendFullBeamUpdate(IClientAPI client) - { - if (DiffersFromSceneGroup) - { - foreach (BeamMetaEntity group in m_BeamEntities.Values) - group.SendFullUpdate(client); - } - } - - public void SendFullBeamUpdateToAll() - { - if (DiffersFromSceneGroup) - { - foreach (BeamMetaEntity group in m_BeamEntities.Values) - group.SendFullUpdateToAll(); - } - } - - public void SendFullDiffUpdate(IClientAPI client) - { - FindDifferences(); - if (DiffersFromSceneGroup) - { - SendFullUpdate(client); - SendFullAuraUpdate(client); - SendFullBeamUpdate(client); - } - } - - public void SendFullDiffUpdateToAll() - { - FindDifferences(); - if (DiffersFromSceneGroup) - { - SendFullUpdateToAll(); - SendFullAuraUpdateToAll(); - SendFullBeamUpdateToAll(); - } - } - - #endregion Public Methods - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// ContentManagementModule.cs -// User: bongiojp - -#endregion Header - -using System; -using System.Collections.Generic; -using System.Threading; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class ContentManagementModule : IRegionModule - { - #region Static Fields - - private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - #endregion Static Fields - - #region Fields - - bool initialised = false; - CMController m_control = null; - bool m_enabled = false; - CMModel m_model = null; - bool m_posted = false; - CMView m_view = null; - - #endregion Fields - - #region Public Properties - - public bool IsSharedModule - { - get { return true; } - } - - public string Name - { - get { return "ContentManagementModule"; } - } - - #endregion Public Properties - - #region Public Methods - - public void Close() - { - } - - public void Initialise(Scene scene, IConfigSource source) - { - string databaseDir = "./"; - string database = "FileSystemDatabase"; - int channel = 345; - try - { - if (source.Configs["CMS"] == null) - return; - - m_enabled = source.Configs["CMS"].GetBoolean("enabled", false); - databaseDir = source.Configs["CMS"].GetString("directory", databaseDir); - database = source.Configs["CMS"].GetString("database", database); - channel = source.Configs["CMS"].GetInt("channel", channel); - - if (database != "FileSystemDatabase" && database != "GitDatabase") - { - m_log.ErrorFormat("[Content Management]: The Database attribute must be defined as either FileSystemDatabase or GitDatabase"); - m_enabled = false; - } - } - catch (Exception e) - { - m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e); - m_enabled = false; - } - - if (!m_enabled) - { - m_log.Info("[Content Management]: Content Management System is not Enabled."); - return; - } - - lock (this) - { - if (!initialised) //only init once - { - m_view = new CMView(); - m_model = new CMModel(); - m_control = new CMController(m_model, m_view, scene, channel); - m_model.Initialise(database); - m_view.Initialise(m_model); - - initialised = true; - m_model.InitialiseDatabase(scene, databaseDir); - } - else - { - m_model.InitialiseDatabase(scene, databaseDir); - m_control.RegisterNewRegion(scene); - } - } - } - - public void PostInitialise() - { - if (! m_enabled) - return; - - lock (this) - { - if (!m_posted) //only post once - { - m_model.PostInitialise(); - m_posted = true; - } - } - } - - #endregion Public Methods - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// FileSystemDatabase.cs -// User: bongiojp - -#endregion Header - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using Slash = System.IO.Path; -using System.Reflection; -using System.Xml; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.CoreModules.World.Serialiser; -using OpenSim.Region.CoreModules.World.Terrain; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class FileSystemDatabase : IContentDatabase - { - #region Static Fields - - public static float TimeToDownload = 0; - public static float TimeToSave = 0; - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - #endregion Static Fields - - #region Fields - - private string m_repodir = null; - private Dictionary m_scenes = new Dictionary(); - private Dictionary m_serialiser = new Dictionary(); - - #endregion Fields - - #region Constructors - - public FileSystemDatabase() - { - } - - #endregion Constructors - - #region Private Methods - - // called by postinitialise - private void CreateDirectory() - { - string scenedir; - if (!Directory.Exists(m_repodir)) - Directory.CreateDirectory(m_repodir); - - foreach (UUID region in m_scenes.Keys) - { - scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar; - if (!Directory.Exists(scenedir)) - Directory.CreateDirectory(scenedir); - } - } - - // called by postinitialise - private void SetupSerialiser() - { - if (m_serialiser.Count == 0) - { - foreach (UUID region in m_scenes.Keys) - { - m_serialiser.Add(region, m_scenes[region].RequestModuleInterface()); - } - } - } - - #endregion Private Methods - - #region Public Methods - - public int GetMostRecentRevision(UUID regionid) - { - return NumOfRegionRev(regionid); - } - - public string GetRegionObjectHeightMap(UUID regionid) - { - String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + - Slash.DirectorySeparatorChar + "heightmap.r32"; - FileStream fs = new FileStream(filename, FileMode.Open); - StreamReader sr = new StreamReader(fs); - String result = sr.ReadToEnd(); - sr.Close(); - fs.Close(); - return result; - } - - public string GetRegionObjectHeightMap(UUID regionid, int revision) - { - String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + - Slash.DirectorySeparatorChar + "heightmap.r32"; - FileStream fs = new FileStream(filename, FileMode.Open); - StreamReader sr = new StreamReader(fs); - String result = sr.ReadToEnd(); - sr.Close(); - fs.Close(); - return result; - } - - public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision) - { - System.Collections.ArrayList objectList = new System.Collections.ArrayList(); - string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar + - + revision + Slash.DirectorySeparatorChar + "objects.xml"; - XmlDocument doc = new XmlDocument(); - XmlNode rootNode; - //int primCount = 0; - //SceneObjectGroup obj = null; - - if (File.Exists(filename)) - { - XmlTextReader reader = new XmlTextReader(filename); - reader.WhitespaceHandling = WhitespaceHandling.None; - doc.Load(reader); - reader.Close(); - rootNode = doc.FirstChild; - foreach (XmlNode aPrimNode in rootNode.ChildNodes) - { - objectList.Add(aPrimNode.OuterXml); - } - return objectList; - } - return null; - } - - public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid) - { - int revision = NumOfRegionRev(regionid); - m_log.Info("[FSDB]: found revisions:" + revision); - System.Collections.ArrayList xmlList = new System.Collections.ArrayList(); - string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar + - + revision + Slash.DirectorySeparatorChar + "objects.xml"; - XmlDocument doc = new XmlDocument(); - XmlNode rootNode; - - m_log.Info("[FSDB]: Checking if " + filename + " exists."); - if (File.Exists(filename)) - { - Stopwatch x = new Stopwatch(); - x.Start(); - - XmlTextReader reader = new XmlTextReader(filename); - reader.WhitespaceHandling = WhitespaceHandling.None; - doc.Load(reader); - reader.Close(); - rootNode = doc.FirstChild; - - foreach (XmlNode aPrimNode in rootNode.ChildNodes) - { - xmlList.Add(aPrimNode.OuterXml); - } - - x.Stop(); - TimeToDownload += x.ElapsedMilliseconds; - m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload); - - return xmlList; - } - return null; - } - - public void Initialise(Scene scene, string dir) - { - lock (this) - { - if (m_repodir == null) - m_repodir = dir; - } - lock (m_scenes) - m_scenes.Add(scene.RegionInfo.RegionID, scene); - } - - public System.Collections.Generic.SortedDictionary ListOfRegionRevisions(UUID regionid) - { - SortedDictionary revisionDict = new SortedDictionary(); - - string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; - string[] directories = Directory.GetDirectories(scenedir); - - FileStream fs = null; - StreamReader sr = null; - String logMessage = ""; - String logLocation = ""; - foreach (string revisionDir in directories) - { - try - { - logLocation = revisionDir + Slash.DirectorySeparatorChar + "log"; - fs = new FileStream(logLocation, FileMode.Open); - sr = new StreamReader(fs); - logMessage = sr.ReadToEnd(); - sr.Close(); - fs.Close(); - revisionDict.Add(revisionDir, logMessage); - } - catch (Exception) - { - } - } - - return revisionDict; - } - - public int NumOfRegionRev(UUID regionid) - { - string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; - m_log.Info("[FSDB]: Reading scene dir: " + scenedir); - string[] directories = Directory.GetDirectories(scenedir); - return directories.Length; - } - - // Run once and only once. - public void PostInitialise() - { - SetupSerialiser(); - - m_log.Info("[FSDB]: Creating repository in " + m_repodir + "."); - CreateDirectory(); - } - - public void SaveRegion(UUID regionid, string regionName, string logMessage) - { - m_log.Info("[FSDB]: ..............................."); - string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; - - m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir); - if (!Directory.Exists(scenedir)) - Directory.CreateDirectory(scenedir); - - int newRevisionNum = GetMostRecentRevision(regionid)+1; - string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar; - - m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir); - if (!Directory.Exists(revisiondir)) - Directory.CreateDirectory(revisiondir); - - try { - Stopwatch x = new Stopwatch(); - x.Start(); - if (m_scenes.ContainsKey(regionid)) - { - m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir); - } - x.Stop(); - TimeToSave += x.ElapsedMilliseconds; - m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds); - m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave); - } - catch (Exception e) - { - m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e); - return; - } - - try { - // Finish by writing log message. - FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite); - StreamWriter sw = new StreamWriter(file); - sw.Write(logMessage); - sw.Close(); - } - catch (Exception e) - { - m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e); - return; - } - } - - #endregion Public Methods - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// GitDatabase.cs -// -// -// - -#endregion Header - -using System; -using System.Collections.Generic; -using System.IO; -using Slash = System.IO.Path; -using System.Reflection; -using System.Xml; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.CoreModules.World.Serialiser; -using OpenSim.Region.CoreModules.World.Terrain; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - /// - /// Just a stub :-( - /// - public class GitDatabase : IContentDatabase - { - #region Constructors - - public GitDatabase() - { - } - - #endregion Constructors - - #region Public Methods - - public SceneObjectGroup GetMostRecentObjectRevision(UUID id) - { - return null; - } - - public int GetMostRecentRevision(UUID regionid) - { - return 0; - } - - public SceneObjectGroup GetObjectRevision(UUID id, int revision) - { - return null; - } - - public System.Collections.ArrayList GetObjectsFromRegion(UUID regionid, int revision) - { - return null; - } - - public string GetRegionObjectHeightMap(UUID regionid) - { - return null; - } - - public string GetRegionObjectHeightMap(UUID regionid, int revision) - { - return null; - } - - public string GetRegionObjectXML(UUID regionid) - { - return null; - } - - public string GetRegionObjectXML(UUID regionid, int revision) - { - return null; - } - - public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid) - { - return null; - } - - public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision) - { - return null; - } - - public bool InRepository(UUID id) - { - return false; - } - - public void Initialise(Scene scene, String dir) - { - } - - public System.Collections.Generic.SortedDictionary ListOfObjectRevisions(UUID id) - { - return null; - } - - public System.Collections.Generic.SortedDictionary ListOfRegionRevisions(UUID id) - { - return null; - } - - public int NumOfObjectRev(UUID id) - { - return 0; - } - - public int NumOfRegionRev(UUID regionid) - { - return 0; - } - - public void PostInitialise() - { - } - - public void SaveObject(SceneObjectGroup entity) - { - } - - public void SaveRegion(UUID regionid, string regionName, string logMessage) - { - } - - #endregion Public Methods - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// IContentDatabase.cs -// User: bongiojp -// -// -// - -#endregion Header - -using System; -using OpenMetaverse; -using OpenSim.Region.Framework.Scenes; -using Nini.Config; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public interface IContentDatabase - { - #region Methods - - /// - /// Returns the most recent revision number of a region. - /// - int GetMostRecentRevision(UUID regionid); - - string GetRegionObjectHeightMap(UUID regionid); - - string GetRegionObjectHeightMap(UUID regionid, int revision); - - /// - /// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region. - /// - System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid); - - System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision); - - /// - /// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database. - /// Initialise should be called one for each region to be contained in the database. The directory should be the full path - /// to the repository and will only be defined once, regardless of how many times the method is called. - /// - void Initialise(Scene scene, String dir); - - /// - /// Returns a list of the revision numbers and corresponding log messages for a given region. - /// - System.Collections.Generic.SortedDictionary ListOfRegionRevisions(UUID id); - - /// - /// Returns the total number of revisions saved for a specific region. - /// - int NumOfRegionRev(UUID regionid); - - /// - /// Should be called once after Initialise has been called. - /// - void PostInitialise(); - - /// - /// Saves the Region terrain map and objects within the region as xml to the database. - /// - void SaveRegion(UUID regionid, string regionName, string logMessage); - - #endregion Methods - } -} diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs deleted file mode 100644 index c7b1ed7..0000000 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Drawing; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Scenes.Serialization; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class MetaEntity - { - #region Constants - - public const float INVISIBLE = .95f; - - // Settings for transparency of metaentity - public const float NONE = 0f; - public const float TRANSLUCENT = .5f; - - #endregion Constants - - #region Static Fields - - //private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - #endregion Static Fields - - #region Fields - - protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity. - protected uint m_metaLocalid; - - #endregion Fields - - #region Constructors - - public MetaEntity() - { - } - - /// - /// Makes a new meta entity by copying the given scene object group. - /// The physics boolean is just a stub right now. - /// - public MetaEntity(SceneObjectGroup orig, bool physics) - { - m_Entity = orig.Copy(false); - Initialize(physics); - } - - /// - /// Takes an XML description of a scene object group and converts it to a meta entity. - /// - public MetaEntity(string objectXML, Scene scene, bool physics) - { - m_Entity = SceneObjectSerializer.FromXml2Format(objectXML); - m_Entity.SetScene(scene); - Initialize(physics); - } - - #endregion Constructors - - #region Public Properties - - public SceneObjectPart[] Parts - { - get { return m_Entity.Parts; } - } - - public uint LocalId - { - get { return m_Entity.LocalId; } - set { m_Entity.LocalId = value; } - } - - public SceneObjectGroup ObjectGroup - { - get { return m_Entity; } - } - - public int PrimCount - { - get { return m_Entity.PrimCount; } - } - - public SceneObjectPart RootPart - { - get { return m_Entity.RootPart; } - } - - public Scene Scene - { - get { return m_Entity.Scene; } - } - - public UUID UUID - { - get { return m_Entity.UUID; } - set { m_Entity.UUID = value; } - } - - #endregion Public Properties - - #region Protected Methods - - // The metaentity objectgroup must have unique localids as well as unique uuids. - // localids are used by the client to refer to parts. - // uuids are sent to the client and back to the server to identify parts on the server side. - /// - /// Changes localids and uuids of m_Entity. - /// - protected void Initialize(bool physics) - { - //make new uuids - Dictionary parts = new Dictionary(); - - foreach (SceneObjectPart part in m_Entity.Parts) - { - part.ResetIDs(part.LinkNum); - parts.Add(part.UUID, part); - } - - //finalize - m_Entity.RootPart.PhysActor = null; - foreach (SceneObjectPart part in parts.Values) - m_Entity.AddPart(part); - } - - #endregion Protected Methods - - #region Public Methods - - /// - /// Hides the metaentity from a single client. - /// - public virtual void Hide(IClientAPI client) - { - //This deletes the group without removing from any databases. - //This is important because we are not IN any database. - //m_Entity.FakeDeleteGroup(); - foreach (SceneObjectPart part in m_Entity.Parts) - client.SendKillObject(m_Entity.RegionHandle, part.LocalId); - } - - /// - /// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server. - /// - public virtual void HideFromAll() - { - foreach (SceneObjectPart part in m_Entity.Parts) - { - m_Entity.Scene.ForEachClient( - delegate(IClientAPI controller) - { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } - ); - } - } - - public void SendFullUpdate(IClientAPI client) - { - // Not sure what clientFlags should be but 0 seems to work - SendFullUpdate(client, 0); - } - - public void SendFullUpdate(IClientAPI client, uint clientFlags) - { - m_Entity.SendFullUpdateToClient(client); - } - - public void SendFullUpdateToAll() - { - m_Entity.Scene.ForEachClient( - delegate(IClientAPI controller) - { m_Entity.SendFullUpdateToClient(controller); } - ); - } - - /// - /// Makes a single SceneObjectPart see through. - /// - /// - /// A - /// The part to make see through - /// - /// - /// A - /// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible. - /// - public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount) - { - Primitive.TextureEntry tex = null; - Color4 texcolor; - try - { - tex = part.Shape.Textures; - texcolor = new Color4(); - } - catch(Exception) - { - //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e); - return; - } - - for (uint i = 0; i < tex.FaceTextures.Length; i++) - { - try { - if (tex.FaceTextures[i] != null) - { - texcolor = tex.FaceTextures[i].RGBA; - texcolor.A = transparencyAmount; - tex.FaceTextures[i].RGBA = texcolor; - } - } - catch (Exception) - { - //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e); - continue; - } - } - try { - texcolor = tex.DefaultTexture.RGBA; - texcolor.A = transparencyAmount; - tex.DefaultTexture.RGBA = texcolor; - part.Shape.TextureEntry = tex.GetBytes(); - } - catch (Exception) - { - //m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e); - } - } - - #endregion Public Methods - } -} 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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Drawing; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - public class PointMetaEntity : MetaEntity - { - #region Constructors - - public PointMetaEntity(Scene scene, Vector3 groupPos, float transparency) - : base() - { - CreatePointEntity(scene, UUID.Random(), groupPos); - SetPartTransparency(m_Entity.RootPart, transparency); - } - - public PointMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency) - : base() - { - CreatePointEntity(scene, uuid, groupPos); - SetPartTransparency(m_Entity.RootPart, transparency); - } - - #endregion Constructors - - #region Private Methods - - private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos) - { - SceneObjectPart y = new SceneObjectPart(); - - //Initialize part - y.Name = "Very Small Point"; - y.RegionHandle = scene.RegionInfo.RegionHandle; - y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; - y.OwnerID = UUID.Zero; - y.CreatorID = UUID.Zero; - y.LastOwnerID = UUID.Zero; - y.UUID = uuid; - - y.Shape = PrimitiveBaseShape.CreateBox(); - y.Scale = new Vector3(0.01f,0.01f,0.01f); - y.LastOwnerID = UUID.Zero; - y.GroupPosition = groupPos; - y.OffsetPosition = Vector3.Zero; - y.RotationOffset = Quaternion.Identity; - y.Velocity = Vector3.Zero; - y.AngularVelocity = Vector3.Zero; - y.Acceleration = Vector3.Zero; - - y.Flags = 0; - y.TrimPermissions(); - - //Initialize group and add part as root part - SceneObjectGroup x = new SceneObjectGroup(y); - x.SetScene(scene); - x.RegionHandle = scene.RegionInfo.RegionHandle; - x.SetScene(scene); - - m_Entity = x; - } - - #endregion Private Methods - } -} 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 @@ -This module is meant to be built alone and not added to the Opensim code base. References are made to required dlls through a -reference file, ContentManagement.mdp. Originally, for development, this project was contained in the Opensim/Region/Modules/ -directory. - -To compile: nant -To use: Copy ContentManagement.dll into the bin directory of your Opensim build. You should find many other dlls in the same directory. - - --------------------------------------------------------------------------------------------------------------------- -To build the libgit.so file: - -#Download GIT git repository -$ git clone git://git2.kernel.org/pub/OpenSim/Region/Environment/Modules/ContentManagementSystem/scm/git/git.git -$ cd git - -#Compile GIT -#Note that we are adding two extra flags to pass to gcc while compiling (-c and -fPIC) -$ autoconf -$ ./configure -$ CFLAGS="-g -O2 -Wall -c -fPIC" make - -#Copy necessary object files (and some not so necessary) to their own directory for shared object file creation -$ mkdir ../libgit-objects -$ cp builtin*.o ../libgit-objects -$ cp xdiff/*.o ../libgit-objects -$ cp libgit.a ../libgit-objects - -#Remove the main symbol from any object files (like git.o) -$ cd ../libgit-objects -$ strip -N main *.o - -#Uncompress the plumbing objects from archive created by git -$ ar x libgit.a - -#Create shared object file from all objects (including the zlib library) -$ ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o - - -#You can also just copy the following commands into a file and run as a script inside the git directory - -make clean -autoconf -./configure -CFLAGS="-g -O2 -Wall -c -fPIC" make -mkdir libgit-objects -cp builtin*.o libgit-objects -cp xdiff/*.o libgit-objects -cp libgit.a libgit-objects -cd libgit-objects -strip -N main *.o -ar x libgit.a -ld -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 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#region Header - -// SceneObjectGroupDiff.cs -// User: bongiojp - -#endregion Header - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; - -using OpenMetaverse; - -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Physics.Manager; - -using log4net; - -namespace OpenSim.Region.OptionalModules.ContentManagement -{ - #region Enumerations - - [Flags] - public enum Diff - { - NONE = 0, - FACECOLOR = 1, - SHAPE = 1<<1, - MATERIAL = 1<<2, - TEXTURE = 1<<3, - SCALE = 1<<4, - POSITION = 1<<5, - OFFSETPOSITION = 1<<6, - ROTATIONOFFSET = 1<<7, - ROTATIONALVELOCITY = 1<<8, - ACCELERATION = 1<<9, - ANGULARVELOCITY = 1<<10, - VELOCITY = 1<<11, - OBJECTOWNER = 1<<12, - PERMISSIONS = 1<<13, - DESCRIPTION = 1<<14, - NAME = 1<<15, - SCRIPT = 1<<16, - CLICKACTION = 1<<17, - PARTICLESYSTEM = 1<<18, - GLOW = 1<<19, - SALEPRICE = 1<<20, - SITNAME = 1<<21, - SITTARGETORIENTATION = 1<<22, - SITTARGETPOSITION = 1<<23, - TEXT = 1<<24, - TOUCHNAME = 1<<25 - } - - #endregion Enumerations - - public static class Difference - { - #region Static Fields - - static float TimeToDiff = 0; -// private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - #endregion Static Fields - - #region Private Methods - - private static bool AreQuaternionsEquivalent(Quaternion first, Quaternion second) - { - Vector3 firstVector = llRot2Euler(first); - Vector3 secondVector = llRot2Euler(second); - return AreVectorsEquivalent(firstVector, secondVector); - } - - private static bool AreVectorsEquivalent(Vector3 first, Vector3 second) - { - if (TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2) - && TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2) - && TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2) - ) - return true; - else - return false; - } - - // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs - private static double NormalizeAngle(double angle) - { - angle = angle % (Math.PI * 2); - if (angle < 0) angle = angle + Math.PI * 2; - return angle; - } - - private static int TruncateSignificant(float num, int digits) - { - return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits)); - // return (int) ((num * (10*digits))/10*digits); - } - - // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs - // Also changed the original function from LSL_Types to LL types - private static Vector3 llRot2Euler(Quaternion r) - { - Quaternion t = new Quaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W); - double m = (t.X + t.Y + t.Z + t.W); - if (m == 0) return new Vector3(); - double n = 2 * (r.Y * r.W + r.X * r.Z); - double p = m * m - n * n; - if (p > 0) - 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))), - (float)NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))), - (float)NormalizeAngle(Math.Atan2(2.0 * (r.Z * r.W - r.X * r.Y), (t.X - t.Y - t.Z + t.W)))); - else if (n > 0) - 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))); - else - 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))); - } - - #endregion Private Methods - - #region Public Methods - - /// - /// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts - /// and returns a Diff bitmask which details what the differences are. - /// - public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second) - { - Stopwatch x = new Stopwatch(); - x.Start(); - - Diff result = 0; - - // VECTOR COMPARISONS - if (!AreVectorsEquivalent(first.Acceleration, second.Acceleration)) - result |= Diff.ACCELERATION; - if (!AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition)) - result |= Diff.POSITION; - if (!AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity)) - result |= Diff.ANGULARVELOCITY; - if (!AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition)) - result |= Diff.OFFSETPOSITION; - if (!AreVectorsEquivalent(first.Scale, second.Scale)) - result |= Diff.SCALE; - if (!AreVectorsEquivalent(first.Velocity, second.Velocity)) - result |= Diff.VELOCITY; - - - // QUATERNION COMPARISONS - if (!AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset)) - result |= Diff.ROTATIONOFFSET; - - - // MISC COMPARISONS (UUID, Byte) - if (first.ClickAction != second.ClickAction) - result |= Diff.CLICKACTION; - if (first.OwnerID != second.OwnerID) - result |= Diff.OBJECTOWNER; - - - // STRING COMPARISONS - if (first.Description != second.Description) - result |= Diff.DESCRIPTION; - if (first.Material != second.Material) - result |= Diff.MATERIAL; - if (first.Name != second.Name) - result |= Diff.NAME; - if (first.SitName != second.SitName) - result |= Diff.SITNAME; - if (first.Text != second.Text) - result |= Diff.TEXT; - if (first.TouchName != second.TouchName) - result |= Diff.TOUCHNAME; - - x.Stop(); - TimeToDiff += x.ElapsedMilliseconds; - //m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff); - - return result; - } - - #endregion Public Methods - } -} -- cgit v1.1 From 78e76bba3825197b12e0796f3431d96909a32b0a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 5 Jun 2011 18:50:21 -0700 Subject: Removed unused dependency (that happened to have the wrong path) --- prebuild.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/prebuild.xml b/prebuild.xml index 0bdd14d..90f451d 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1582,7 +1582,6 @@ - -- cgit v1.1 From 6861606b6d8000aaa8f54a91de43f1ef05267974 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 5 Jun 2011 19:46:29 -0700 Subject: Narrow down the exception catching to exactly the exception of interest. This may decrease the time of processing prims with broken user data. --- .../Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index f721195..9051194 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -285,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement Uri uri = new Uri(parts[0]); user.LastName = "@" + uri.Authority; } - catch + catch (UriFormatException) { m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]); user.LastName = "@unknown"; -- cgit v1.1 From e77ca65e575e4f8f7645aec879b73b87ba505f49 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 6 Jun 2011 17:46:34 -0700 Subject: This should make offline IMs work again. It should work for incoming foreign IMs where the local recipient is offline. I can't test any of this, because I don't run an offline IM server. --- .../InstantMessage/HGMessageTransferModule.cs | 5 ++- .../HypergridService/HGInstantMessageService.cs | 51 ++++++++++++++++++++-- bin/Robust.HG.ini.example | 23 ++++++++-- 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index 4de197e..dee86df 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -213,7 +213,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } } - result(success); + if (!success && !foreigner) + HandleUndeliveredMessage(im, result); + else + result(success); }); return; diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index 4f68e55..66cf4de 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -67,6 +67,10 @@ namespace OpenSim.Services.HypergridService protected static Dictionary m_UserLocationMap = new Dictionary(); private static ExpiringCache m_RegionCache; + private static string m_RestURL; + private static bool m_ForwardOfflineGroupMessages; + private static bool m_InGatekeeper; + public HGInstantMessageService(IConfigSource config) : this(config, null) { @@ -81,8 +85,6 @@ namespace OpenSim.Services.HypergridService { m_Initialized = true; - m_log.DebugFormat("[HG IM SERVICE]: Starting..."); - IConfig serverConfig = config.Configs["HGInstantMessageService"]; if (serverConfig == null) throw new Exception(String.Format("No section HGInstantMessageService in config file")); @@ -90,6 +92,9 @@ namespace OpenSim.Services.HypergridService string gridService = serverConfig.GetString("GridService", String.Empty); string presenceService = serverConfig.GetString("PresenceService", String.Empty); string userAgentService = serverConfig.GetString("UserAgentService", String.Empty); + m_InGatekeeper = serverConfig.GetBoolean("InGatekeeper", false); + m_log.DebugFormat("[HG IM SERVICE]: Starting... InRobust? {0}", m_InGatekeeper); + if (gridService == string.Empty || presenceService == string.Empty) throw new Exception(String.Format("Incomplete specifications, InstantMessage Service cannot function.")); @@ -101,6 +106,21 @@ namespace OpenSim.Services.HypergridService m_RegionCache = new ExpiringCache(); + IConfig cnf = config.Configs["Messaging"]; + if (cnf == null) + { + return; + } + + m_RestURL = cnf.GetString("OfflineMessageURL", string.Empty); + if (m_RestURL == string.Empty) + { + m_log.Error("[HG IM SERVICE]: Offline IMs enabled, but no URL is given"); + return; + } + + m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", false); + } } @@ -109,13 +129,21 @@ namespace OpenSim.Services.HypergridService m_log.DebugFormat("[HG IM SERVICE]: Received message from {0} to {1}", im.fromAgentID, im.toAgentID); UUID toAgentID = new UUID(im.toAgentID); + bool success = false; if (m_IMSimConnector != null) { //m_log.DebugFormat("[XXX] SendIMToRegion local im connector"); - return m_IMSimConnector.SendInstantMessage(im); + success = m_IMSimConnector.SendInstantMessage(im); } else - return TrySendInstantMessage(im, "", true, false); + { + success = TrySendInstantMessage(im, "", true, false); + } + + if (!success && m_InGatekeeper) // we do this only in the Gatekeeper IM service + UndeliveredMessage(im); + + return success; } public bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner) @@ -129,6 +157,7 @@ namespace OpenSim.Services.HypergridService upd.RegionID = UUID.Zero; return TrySendInstantMessage(im, upd, true, foreigner); } + } protected bool TrySendInstantMessage(GridInstantMessage im, object previousLocation, bool firstTime, bool foreigner) @@ -313,5 +342,19 @@ namespace OpenSim.Services.HypergridService } } + + private bool UndeliveredMessage(GridInstantMessage im) + { + if (m_RestURL != string.Empty && (im.offline != 0) + && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) + { + return SynchronousRestObjectPoster.BeginPostObject( + "POST", m_RestURL + "/SaveMessage/", im); + + } + + else + return false; + } } } diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 7b2f8ac..812d265 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -356,8 +356,23 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" [HGInstantMessageService] - LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService" - GridService = "OpenSim.Services.GridService.dll:GridService" - PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" - UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" + LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService" + GridService = "OpenSim.Services.GridService.dll:GridService" + PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" + UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" + ; This should always be true in the Robust config + InGatekeeper = True + +[Messaging] + ; If you have an Offline IM server, set the vars in this section, so that + ; incomming IMs to local users from foreign grids can be saved + ; + ;# {OfflineMessageURL} {OfflineMessageModule:OfflineMessageModule} {URL of offline messaging service} {} + ;; URL of web service for offline message storage + ; OfflineMessageURL = http://yourserver/Offline.php + + ;; Control whether group messages are forwarded to offline users. + ;; Default is true. + ;; This applies to the core groups module (Flotsam) only. + ; ForwardOfflineGroupMessages = true -- cgit v1.1 From dce0e46eaa8c8f7f9a0fc99697cc78a3f561b3c3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 6 Jun 2011 18:20:02 -0700 Subject: Moved the Mono Addins declaration of the HGFriendsModule to where the one for FriendModule is -- CoreModulePlugin.addin.xml (trying to hunt down the slowness reported by Nebadon related to HGFriends) --- OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 1 - OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index b0a7567..f6f0e89 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -45,7 +45,6 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.Avatar.Friends { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 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 @@ + -- cgit v1.1 From 1a23d322ace6001130db24d11962850b333c8399 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 6 Jun 2011 19:52:50 -0700 Subject: More on the hunt for the slow down on HGFriendsModule. - Don't requests the online friends on foreign grids. If this works, there's another way of getting that info. --- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 119 ++++++++++++--------- 1 file changed, 71 insertions(+), 48 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index f6f0e89..ddf9289 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -87,25 +87,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (base.FetchFriendslist(client)) { UUID agentID = client.AgentId; - // We need to preload the user management cache with the names - // of foreign friends, just like we do with SOPs' creators - foreach (FriendInfo finfo in m_Friends[agentID].Friends) + // we do this only for the root agent + if (m_Friends[agentID].Refcount == 1) { - if (finfo.TheirFlags != -1) + // We need to preload the user management cache with the names + // of foreign friends, just like we do with SOPs' creators + foreach (FriendInfo finfo in m_Friends[agentID].Friends) { - UUID id; - if (!UUID.TryParse(finfo.Friend, out id)) + if (finfo.TheirFlags != -1) { - string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty; - if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp)) + UUID id; + if (!UUID.TryParse(finfo.Friend, out id)) { - IUserManagement uMan = m_Scenes[0].RequestModuleInterface(); - uMan.AddUser(id, url + ";" + first + " " + last); + string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty; + if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp)) + { + IUserManagement uMan = m_Scenes[0].RequestModuleInterface(); + uMan.AddUser(id, url + ";" + first + " " + last); + } } } } + return true; } - return true; } return false; } @@ -114,13 +118,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { if (base.SendFriendsOnlineIfNeeded(client)) { - UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId); - if (account == null) // foreign + AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId); + if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) { - FriendInfo[] friends = GetFriends(client.AgentId); - foreach (FriendInfo f in friends) + UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId); + if (account == null) // foreign { - client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags); + FriendInfo[] friends = GetFriends(client.AgentId); + foreach (FriendInfo f in friends) + { + client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags); + } } } } @@ -129,48 +137,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends protected override void GetOnlineFriends(UUID userID, List friendList, /*collector*/ List online) { - // Let's single out the UUIs - List localFriends = new List(); - List foreignFriends = new List(); - string tmp = string.Empty; - + List fList = new List(); foreach (string s in friendList) - { - UUID id; - if (UUID.TryParse(s, out id)) - localFriends.Add(s); - else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp)) - { - foreignFriends.Add(s); - // add it here too, who knows maybe the foreign friends happens to be on this grid - localFriends.Add(id.ToString()); - } - } + fList.Add(s.Substring(0, 36)); - // OK, see who's present on this grid - List toBeRemoved = new List(); - PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray()); + PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray()); foreach (PresenceInfo pi in presence) { UUID presenceID; if (UUID.TryParse(pi.UserID, out presenceID)) - { online.Add(presenceID); - foreach (string s in foreignFriends) - if (s.StartsWith(pi.UserID)) - toBeRemoved.Add(s); - } } - - foreach (string s in toBeRemoved) - foreignFriends.Remove(s); - - // OK, let's send this up the stack, and leave a closure here - // collecting online friends in other grids - Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); }); - } + //protected override void GetOnlineFriends(UUID userID, List friendList, /*collector*/ List online) + //{ + // // Let's single out the UUIs + // List localFriends = new List(); + // List foreignFriends = new List(); + // string tmp = string.Empty; + + // foreach (string s in friendList) + // { + // UUID id; + // if (UUID.TryParse(s, out id)) + // localFriends.Add(s); + // else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp)) + // { + // foreignFriends.Add(s); + // // add it here too, who knows maybe the foreign friends happens to be on this grid + // localFriends.Add(id.ToString()); + // } + // } + + // // OK, see who's present on this grid + // List toBeRemoved = new List(); + // PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray()); + // foreach (PresenceInfo pi in presence) + // { + // UUID presenceID; + // if (UUID.TryParse(pi.UserID, out presenceID)) + // { + // online.Add(presenceID); + // foreach (string s in foreignFriends) + // if (s.StartsWith(pi.UserID)) + // toBeRemoved.Add(s); + // } + // } + + // foreach (string s in toBeRemoved) + // foreignFriends.Remove(s); + + // // OK, let's send this up the stack, and leave a closure here + // // collecting online friends in other grids + // Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); }); + + //} + private void CollectOnlineFriendsElsewhere(UUID userID, List foreignFriends) { // let's divide the friends on a per-domain basis -- cgit v1.1 From f5d82350bb622baa6f49042882e6c5cb49b24cc0 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 7 Jun 2011 10:51:12 -0700 Subject: This fixes the crash reported in http://opensimulator.org/mantis/view.php?id=5529 related to sending IMs to foreign friends who are offline. Hopefully. --- .../InstantMessage/HGMessageTransferModule.cs | 8 ++++--- .../Handlers/Hypergrid/UserAgentServerConnector.cs | 24 +++++++++---------- .../HypergridService/HGInstantMessageService.cs | 28 ++++++++++------------ .../Services/HypergridService/UserAgentService.cs | 2 +- OpenSim/Services/Interfaces/IHypergridServices.cs | 2 +- bin/config-include/StandaloneHypergrid.ini | 1 + 6 files changed, 32 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index dee86df..7753c25 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -196,10 +196,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage Util.FireAndForget(delegate { - bool success = m_IMService.OutgoingInstantMessage(im, url, foreigner); - if (!success && account == null) + bool success = false; + if (foreigner && url == string.Empty) // we don't know about this user { - // One last chance string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID); m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI); if (recipientUUI != string.Empty) @@ -213,6 +212,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } } + else + success = m_IMService.OutgoingInstantMessage(im, url, foreigner); + if (!success && !foreigner) HandleUndeliveredMessage(im, result); else diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index 9961164..2022d8a 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -268,18 +268,18 @@ namespace OpenSim.Server.Handlers.Hypergrid ids.Add(requestData[key].ToString()); } - List online = m_HomeUsersService.GetOnlineFriends(userID, ids); - if (online.Count > 0) - { - int i = 0; - foreach (UUID id in online) - { - hash["friend_" + i.ToString()] = id.ToString(); - i++; - } - } - else - hash["result"] = "No Friends Online"; + //List online = m_HomeUsersService.GetOnlineFriends(userID, ids); + //if (online.Count > 0) + //{ + // int i = 0; + // foreach (UUID id in online) + // { + // hash["friend_" + i.ToString()] = id.ToString(); + // i++; + // } + //} + //else + // hash["result"] = "No Friends Online"; } XmlRpcResponse response = new XmlRpcResponse(); diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index 66cf4de..90a0bf2 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -185,7 +185,6 @@ namespace OpenSim.Services.HypergridService { lookupAgent = true; upd = null; - url = string.Empty; } } else @@ -221,19 +220,16 @@ namespace OpenSim.Services.HypergridService url = m_UserAgentService.LocateUser(toAgentID); } - if (upd != null || url != string.Empty) + // check if we've tried this before.. + // This is one way to end the recursive loop + // + if (!firstTime && ((previousLocation is PresenceInfo && upd != null && upd.RegionID == ((PresenceInfo)previousLocation).RegionID) || + (previousLocation is string && upd == null && previousLocation.Equals(url)))) { - // check if we've tried this before.. - // This is one way to end the recursive loop - // - if (!firstTime && ((previousLocation is PresenceInfo && upd != null && upd.RegionID == ((PresenceInfo)previousLocation).RegionID) || - (previousLocation is string && upd == null && previousLocation.Equals(url)))) - { - // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); - m_log.DebugFormat("[HG IM SERVICE]: Fail 2 {0} {1}", previousLocation, url); + // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); + m_log.DebugFormat("[HG IM SERVICE]: Fail 2 {0} {1}", previousLocation, url); - return false; - } + return false; } } @@ -332,10 +328,6 @@ namespace OpenSim.Services.HypergridService else { // try again, but lookup user this time. - // Warning, this must call the Async version - // of this method or we'll be making thousands of threads - // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync - // The version that spawns the thread is SendGridInstantMessageViaXMLRPC // This is recursive!!!!! return TrySendInstantMessage(im, url, false, foreigner); @@ -348,13 +340,17 @@ namespace OpenSim.Services.HypergridService if (m_RestURL != string.Empty && (im.offline != 0) && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) { + m_log.DebugFormat("[HG IM SERVICE]: Message saved"); return SynchronousRestObjectPoster.BeginPostObject( "POST", m_RestURL + "/SaveMessage/", im); } else + { + m_log.DebugFormat("[HG IM SERVICE]: No offline IM service, message not saved"); return false; + } } } } diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 2f2ebfb..8d78f97 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -482,7 +482,7 @@ namespace OpenSim.Services.HypergridService { foreach (TravelingAgentInfo t in m_TravelingAgents.Values) { - if (t.UserID == userID) + if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName)) return t.GridExternalName; } diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs index 82ec8ce..3c6fedf 100644 --- a/OpenSim/Services/Interfaces/IHypergridServices.cs +++ b/OpenSim/Services/Interfaces/IHypergridServices.cs @@ -62,7 +62,7 @@ namespace OpenSim.Services.Interfaces string GetUUI(UUID userID, UUID targetUserID); void StatusNotification(List friends, UUID userID, bool online); - List GetOnlineFriends(UUID userID, List friends); + //List GetOnlineFriends(UUID userID, List friends); bool AgentIsComingHome(UUID sessionID, string thisGridExternalName); bool VerifyAgent(UUID sessionID, string token); diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 574375e..8480a77 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -160,6 +160,7 @@ GridService = "OpenSim.Services.GridService.dll:GridService" PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" + InGatekeeper = True ;; This should always be the very last thing on this file -- cgit v1.1 From 41627bdf8a98358829a6a1210cb14ba143fdeee2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 7 Jun 2011 12:09:32 -0700 Subject: Remove scary error message --- OpenSim/Services/HypergridService/HGInstantMessageService.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index 90a0bf2..09dbc65 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -113,12 +113,6 @@ namespace OpenSim.Services.HypergridService } m_RestURL = cnf.GetString("OfflineMessageURL", string.Empty); - if (m_RestURL == string.Empty) - { - m_log.Error("[HG IM SERVICE]: Offline IMs enabled, but no URL is given"); - return; - } - m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", false); } -- cgit v1.1 From 02b40670be7d6c42de7235285f2e136aa6109fd3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 7 Jun 2011 12:10:57 -0700 Subject: This makes the display names work better for foreigners --- OpenSim/Region/Framework/Scenes/Scene.cs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 77301d8..588d627 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2571,12 +2571,38 @@ namespace OpenSim.Region.Framework.Scenes if (GetScenePresence(client.AgentId) != null) { m_LastLogin = Util.EnvironmentTickCount(); + + // Cache the user's name + CacheUserName(aCircuit); + EventManager.TriggerOnNewClient(client); if (vialogin) EventManager.TriggerOnClientLogin(client); } } + private void CacheUserName(AgentCircuitData aCircuit) + { + IUserManagement uMan = RequestModuleInterface(); + if (uMan != null) + { + string homeURL = string.Empty; + string first = aCircuit.firstname, last = aCircuit.lastname; + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + homeURL = aCircuit.ServiceURLs["HomeURI"].ToString(); + if (aCircuit.lastname.StartsWith("@")) + { + string[] parts = aCircuit.firstname.Split('.'); + if (parts.Length >= 2) + { + first = parts[0]; + last = parts[1]; + } + } + uMan.AddUser(aCircuit.AgentID, first, last, homeURL); + } + } + private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin) { vialogin = false; -- cgit v1.1 From 3307db5d4aedec5cc31541e9a28a95abdd4999d0 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 7 Jun 2011 19:36:04 -0700 Subject: This hopefully fixes all issues with online/offline notifications across grids. http://opensimulator.org/mantis/view.php?id=5528 --- .../CoreModules/Avatar/Friends/FriendsModule.cs | 2 +- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 11 ++++- .../Handlers/Hypergrid/UserAgentServerConnector.cs | 16 +++++-- .../Hypergrid/UserAgentServiceConnector.cs | 55 +++++++++++++++++++++- .../Services/HypergridService/UserAgentService.cs | 28 ++++++++--- OpenSim/Services/Interfaces/IHypergridServices.cs | 3 +- 6 files changed, 99 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index f82716d..daee4ca 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -830,10 +830,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends public bool LocalStatusNotification(UUID userID, UUID friendID, bool online) { + m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online); IClientAPI friendClient = LocateClientObject(friendID); if (friendClient != null) { - //m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online); // the friend in this sim as root agent if (online) friendClient.SendAgentOnline(new UUID[] { userID }); diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index ddf9289..b9d6719 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends /// friend whose status changed /// status /// - public bool StatusNotify(UUID userID, UUID friendID, bool online) + public bool StatusNotify(UUID friendID, UUID userID, bool online) { return LocalStatusNotification(friendID, userID, online); } @@ -279,7 +279,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends foreach (FriendInfo f in kvp.Value) ids.Add(f.Friend); UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); - uConn.StatusNotification(ids, userID, online); + List friendsOnline = uConn.StatusNotification(ids, userID, online); + // need to debug this here + if (online) + { + IClientAPI client = LocateClientObject(userID); + if (client != null) + client.SendAgentOnline(friendsOnline.ToArray()); + } } } } diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index 2022d8a..72a4aea 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -237,10 +237,20 @@ namespace OpenSim.Server.Handlers.Hypergrid bool online = false; bool.TryParse(requestData["online"].ToString(), out online); - hash["result"] = "true"; - // let's spawn a thread for this, because it may take a long time... - Util.FireAndForget(delegate { m_HomeUsersService.StatusNotification(ids, userID, online); }); + List friendsOnline = m_HomeUsersService.StatusNotification(ids, userID, online); + if (friendsOnline.Count > 0) + { + int i = 0; + foreach (UUID id in friendsOnline) + { + hash["friend_" + i.ToString()] = id.ToString(); + i++; + } + } + else + hash["result"] = "No Friends Online"; + } XmlRpcResponse response = new XmlRpcResponse(); diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 046f755..853e524 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -404,7 +404,7 @@ namespace OpenSim.Services.Connectors.Hypergrid GetBoolResponse(request, out reason); } - public void StatusNotification(List friends, UUID userID, bool online) + public List StatusNotification(List friends, UUID userID, bool online) { Hashtable hash = new Hashtable(); hash["userID"] = userID.ToString(); @@ -421,8 +421,59 @@ namespace OpenSim.Services.Connectors.Hypergrid XmlRpcRequest request = new XmlRpcRequest("status_notification", paramList); string reason = string.Empty; - GetBoolResponse(request, out reason); + // Send and get reply + List friendsOnline = new List(); + XmlRpcResponse response = null; + try + { + response = request.Send(m_ServerURL, 10000); + } + catch (Exception e) + { + m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); + reason = "Exception: " + e.Message; + return friendsOnline; + } + + if (response.IsFault) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); + reason = "XMLRPC Fault"; + return friendsOnline; + } + + hash = (Hashtable)response.Value; + //foreach (Object o in hash) + // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); + try + { + if (hash == null) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL); + reason = "Internal error 1"; + return friendsOnline; + } + + // Here is the actual response + foreach (object key in hash.Keys) + { + if (key is string && ((string)key).StartsWith("friend_") && hash[key] != null) + { + UUID uuid; + if (UUID.TryParse(hash[key].ToString(), out uuid)) + friendsOnline.Add(uuid); + } + } + + } + catch (Exception e) + { + m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response."); + reason = "Exception: " + e.Message; + } + + return friendsOnline; } public List GetOnlineFriends(UUID userID, List friends) diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 8d78f97..29d8b3d 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -324,14 +324,16 @@ namespace OpenSim.Services.HypergridService return false; } - public void StatusNotification(List friends, UUID foreignUserID, bool online) + public List StatusNotification(List friends, UUID foreignUserID, bool online) { if (m_FriendsService == null || m_PresenceService == null) { m_log.WarnFormat("[USER AGENT SERVICE]: Unable to perform status notifications because friends or presence services are missing"); - return; + return new List(); } + List localFriendsOnline = new List(); + m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: foreign user {0} wants to notify {1} local friends", foreignUserID, friends.Count); // First, let's double check that the reported friends are, indeed, friends of that user @@ -372,8 +374,12 @@ namespace OpenSim.Services.HypergridService if (friendSession != null) { - ForwardStatusNotificationToSim(friendSession.RegionID, friendSession.UserID, foreignUserID, online); + ForwardStatusNotificationToSim(friendSession.RegionID, foreignUserID, friendSession.UserID, online); usersToBeNotified.Remove(friendSession.UserID.ToString()); + UUID id; + if (UUID.TryParse(friendSession.UserID, out id)) + localFriendsOnline.Add(id); + } } @@ -388,9 +394,17 @@ namespace OpenSim.Services.HypergridService m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url); } } + + // and finally, let's send the online friends + if (online) + { + return localFriendsOnline; + } + else + return new List(); } - protected void ForwardStatusNotificationToSim(UUID regionID, string user, UUID foreignUserID, bool online) + protected void ForwardStatusNotificationToSim(UUID regionID, UUID foreignUserID, string user, bool online) { UUID userID; if (UUID.TryParse(user, out userID)) @@ -398,15 +412,15 @@ namespace OpenSim.Services.HypergridService if (m_FriendsLocalSimConnector != null) { m_log.DebugFormat("[USER AGENT SERVICE]: Local Notify, user {0} is {1}", foreignUserID, (online ? "online" : "offline")); - m_FriendsLocalSimConnector.StatusNotify(userID, foreignUserID, online); + m_FriendsLocalSimConnector.StatusNotify(foreignUserID, userID, online); } else { GridRegion region = m_GridService.GetRegionByUUID(UUID.Zero /* !!! */, regionID); if (region != null) { - m_log.DebugFormat("[USER AGENT SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, user, foreignUserID, (online ? "online" : "offline")); - m_FriendsSimConnector.StatusNotify(region, userID, foreignUserID, online); + m_log.DebugFormat("[USER AGENT SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, foreignUserID, (online ? "online" : "offline")); + m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID, online); } } } diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs index 3c6fedf..220caef 100644 --- a/OpenSim/Services/Interfaces/IHypergridServices.cs +++ b/OpenSim/Services/Interfaces/IHypergridServices.cs @@ -61,7 +61,8 @@ namespace OpenSim.Services.Interfaces // on behalf of the userID string GetUUI(UUID userID, UUID targetUserID); - void StatusNotification(List friends, UUID userID, bool online); + // Returns the local friends online + List StatusNotification(List friends, UUID userID, bool online); //List GetOnlineFriends(UUID userID, List friends); bool AgentIsComingHome(UUID sessionID, string thisGridExternalName); -- cgit v1.1 From eabfc9ca153b1b9775bada56c2c0120768a77fda Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 7 Jun 2011 20:05:24 -0700 Subject: Added error message to help understand http://opensimulator.org/mantis/view.php?id=5527 --- OpenSim/Services/HypergridService/UserAgentService.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 29d8b3d..7ed5ea5 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -496,6 +496,11 @@ namespace OpenSim.Services.HypergridService { foreach (TravelingAgentInfo t in m_TravelingAgents.Values) { + if (t == null) + { + m_log.ErrorFormat("[USER AGENT SERVICE]: Oops! Null TravelingAgentInfo. Please report this on mantis"); + continue; + } if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName)) return t.GridExternalName; } -- cgit v1.1 From 39323055bd205ba2bc241e3c52313d2aa4717dfe Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Wed, 25 May 2011 18:45:10 +0300 Subject: When a plugin fails to load because a DLL is missing, log which DLL it is --- OpenSim/Server/Base/ServerUtils.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 6743a2e..8effdd2 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -128,6 +128,13 @@ namespace OpenSim.Server.Base return null; } + catch (ReflectionTypeLoadException rtle) + { + m_log.Error(string.Format("Error loading plugin from {0}:\n{1}", dllName, + String.Join("\n", Array.ConvertAll(rtle.LoaderExceptions, e => e.ToString()))), + rtle); + return null; + } catch (Exception e) { m_log.Error(string.Format("Error loading plugin from {0}", dllName), e); -- cgit v1.1 From 61f1c2b2c517ccd00bf1e7c4efe9c7567c891fe0 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 26 May 2011 13:41:56 +0300 Subject: Write estate errors on startup to the log --- OpenSim/Region/Application/OpenSimBase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index ea9edf6..00b080c 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -836,7 +836,7 @@ namespace OpenSim if (regInfo.EstateSettings.EstateID == 0) // No record at all { - MainConsole.Instance.OutputFormat("Region {0} is not part of an estate.", regInfo.RegionName); + m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName); List estates = EstateDataService.LoadEstateSettingsAll(); List estateNames = new List(); @@ -847,7 +847,7 @@ namespace OpenSim { if (estates.Count == 0) { - MainConsole.Instance.Output("No existing estates found. You must create a new one."); + m_log.Info("[ESTATE] No existing estates found. You must create a new one."); if (CreateEstate(regInfo, estateNames)) break; -- cgit v1.1 From 90f657d77d2df4ff0867431a8bcf34cbed13057f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 8 Jun 2011 13:45:38 -0700 Subject: Deleted wrong debug message. --- OpenSim/Services/HypergridService/HGInstantMessageService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index 09dbc65..ded589d 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -342,7 +342,6 @@ namespace OpenSim.Services.HypergridService else { - m_log.DebugFormat("[HG IM SERVICE]: No offline IM service, message not saved"); return false; } } -- cgit v1.1 From 9759b2a4bb5e5e2bed4c74cea05be58640c8e7c3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 8 Jun 2011 15:18:14 -0700 Subject: Added EventManager.OnPrimsLoaded, an event that modules can hook up onto so that they know when the scene's objects have been loaded from the DB. --- OpenSim/Region/Framework/Scenes/EventManager.cs | 24 ++++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 1 + 2 files changed, 25 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index b43d5f0..b67937d 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -392,6 +392,9 @@ namespace OpenSim.Region.Framework.Scenes public delegate void LoginsEnabled(string regionName); public event LoginsEnabled OnLoginsEnabled; + public delegate void PrimsLoaded(Scene s); + public event PrimsLoaded OnPrimsLoaded; + public class MoneyTransferArgs : EventArgs { public UUID sender; @@ -2242,5 +2245,26 @@ namespace OpenSim.Region.Framework.Scenes } } } + + public void TriggerPrimsLoaded(Scene s) + { + PrimsLoaded handler = OnPrimsLoaded; + + if (handler != null) + { + foreach (PrimsLoaded d in handler.GetInvocationList()) + { + try + { + d(s); + } + catch (Exception e) + { + m_log.ErrorFormat("[EVENT MANAGER]: Delegate for PrimsLoaded failed - continuing {0} - {1}", + e.Message, e.StackTrace); + } + } + } + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 588d627..f122b58 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1754,6 +1754,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); LoadingPrims = false; + EventManager.TriggerPrimsLoaded(this); } -- cgit v1.1 From 80fc607d7536d4f375da4d01280a00fe656654c4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 8 Jun 2011 16:01:33 -0700 Subject: Fixed "Unknown User" listed as creator/owner on prims created with the Build button by foreign visitors. Added command to the UserManagementModule to list all the known bindings between user UUIDs and their names: show user-names. --- .../UserManagement/UserManagementModule.cs | 74 +++++++++++++++++++--- .../Region/Framework/Interfaces/IUserManagement.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++ 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 9051194..ae4336c 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -30,6 +30,7 @@ using System.IO; using System.Reflection; using OpenSim.Framework; +using OpenSim.Framework.Console; using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; @@ -80,6 +81,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement // } // } //} + MainConsole.Instance.Commands.AddCommand("grid", true, + "show user-names", + "show user-names", + "Show the bindings between user UUIDs and user names", + String.Empty, + HandleShowUsers); + + } public bool IsSharedModule @@ -103,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); + scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); } public void RemoveRegion(Scene scene) @@ -111,18 +121,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement m_Scenes.Remove(scene); } - public void RegionLoaded(Scene scene) + public void RegionLoaded(Scene s) { } public void PostInitialise() { - foreach (Scene s in m_Scenes) - { - // let's sniff all the user names referenced by objects in the scene - m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length); - s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); }); - } } public void Close() @@ -136,6 +140,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement #region Event Handlers + void EventManager_OnPrimsLoaded(Scene s) + { + // let's sniff all the user names referenced by objects in the scene + m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length); + s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); }); + } + + void EventManager_OnNewClient(IClientAPI client) { client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); @@ -143,7 +155,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) { - //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0}", uuid); if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) { remote_client.SendNameReply(uuid, "Mr", "OpenSim"); @@ -153,6 +164,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement string[] names = GetUserNames(uuid); if (names.Length == 2) { + //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]); remote_client.SendNameReply(uuid, names[0], names[1]); } @@ -254,6 +266,32 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement return string.Empty; } + public string GetUserUUI(UUID userID) + { + UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID); + if (account != null) + return userID.ToString(); + + if (m_UserCache.ContainsKey(userID)) + { + UserData ud = m_UserCache[userID]; + string homeURL = ud.HomeURL; + string first = ud.FirstName, last = ud.LastName; + if (ud.LastName.StartsWith("@")) + { + string[] parts = ud.FirstName.Split('.'); + if (parts.Length >= 2) + { + first = parts[0]; + last = parts[1]; + } + return userID + ";" + homeURL + ";" + first + " " + last; + } + } + + return userID.ToString(); + } + public void AddUser(UUID id, string creatorData) { if (m_UserCache.ContainsKey(id)) @@ -343,5 +381,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement //} #endregion IUserManagement + + private void HandleShowUsers(string module, string[] cmd) + { + if (m_UserCache.Count == 0) + { + MainConsole.Instance.Output("No users not found"); + return; + } + + MainConsole.Instance.Output("UUID User Name"); + MainConsole.Instance.Output("-----------------------------------------------------------------------------"); + foreach (KeyValuePair kvp in m_UserCache) + { + MainConsole.Instance.Output(String.Format("{0} {1} {2}", + kvp.Key, kvp.Value.FirstName, kvp.Value.LastName)); + } + return; + } + + } } diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs index 9cac3b0..5d30aa8 100644 --- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs +++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs @@ -9,6 +9,7 @@ namespace OpenSim.Region.Framework.Interfaces { string GetUserName(UUID uuid); string GetUserHomeURL(UUID uuid); + string GetUserUUI(UUID uuid); string GetUserServerURL(UUID uuid, string serverType); void AddUser(UUID uuid, string userData); void AddUser(UUID uuid, string firstName, string lastName, string profileURL); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f122b58..bdf3d1d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1910,6 +1910,10 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.SetGroup(groupID, null); } + IUserManagement uman = RequestModuleInterface(); + if (uman != null) + sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID); + sceneObject.ScheduleGroupForFullUpdate(); return sceneObject; -- cgit v1.1 From 1bd712c541bb4f26a0547f5ae463092c21997713 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 8 Jun 2011 16:12:47 -0700 Subject: Reverting the [HG]MapModule to its buggy behavior above 4096. Ppl seem to prefer the color blue, and I have given up trying to make things work above 4096. Revert "Improved reuse on the WorldMap/WorldMapModule.cs" This reverts commit d473d9975e70366d0fd16276c9bafd5ec269dcd9. --- .../CoreModules/World/WorldMap/WorldMapModule.cs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 10e1631..0cacf2d 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -233,8 +233,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } if (lookup) { - List mapBlocks = GetAndSendBlocks(avatarPresence.ControllingClient, (int)(m_scene.RegionInfo.RegionLocX) - 4, (int)(m_scene.RegionInfo.RegionLocY) - 4, - (int)(m_scene.RegionInfo.RegionLocX) + 4, (int)(m_scene.RegionInfo.RegionLocY) + 4, 0); + List mapBlocks = new List(); ; + + List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, + (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, + (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, + (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, + (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); + foreach (GridRegion r in regions) + { + MapBlockData block = new MapBlockData(); + MapBlockFromGridRegion(block, r); + mapBlocks.Add(block); + } + avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); lock (cachedMapBlocks) cachedMapBlocks = mapBlocks; @@ -820,7 +832,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } } - protected virtual List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + protected virtual void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, @@ -835,8 +847,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap mapBlocks.Add(block); } remoteClient.SendMapBlock(mapBlocks, 0); - - return mapBlocks; } protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r) -- cgit v1.1 From 2a46f756d673f4caa2049f2ddda219fdba810eed Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 8 Jun 2011 16:38:25 -0700 Subject: Fixed a compilation problem. Also added a lengthy comment on the Map hack, so that it never goes unnoticed again. --- .../CoreModules/Hypergrid/HGWorldMapModule.cs | 3 +- .../CoreModules/World/WorldMap/WorldMapModule.cs | 83 +++++++++++++--------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index 0781de0..f066f83 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid #endregion - protected override List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + protected override void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, @@ -96,7 +96,6 @@ namespace OpenSim.Region.CoreModules.Hypergrid remoteClient.SendMapBlock(mapBlocks, 0); - return mapBlocks; } diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 0cacf2d..ed3677b 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 //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", // path, param, agentID.ToString()); - // this is here because CAPS map requests work even beyond the 10,000 limit. - ScenePresence avatarPresence = null; - - m_scene.TryGetScenePresence(agentID, out avatarPresence); - - if (avatarPresence != null) + // There is a major hack going on in this method. The viewer doesn't request + // map blocks (RequestMapBlocks) above 4096. That means that if we don't hack, + // grids above that cell don't have a map at all. So, here's the hack: we wait + // for this CAP request to come, and we inject the map blocks at this point. + // In a normal scenario, this request simply sends back the MapLayer (the blue color). + // In the hacked scenario, it also sends the map blocks via UDP. + // + // 6/8/2011 -- I'm adding an explicit 4096 check, so that we never forget that there is + // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. + + if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY > 4096) { - bool lookup = false; + ScenePresence avatarPresence = null; - lock (cachedMapBlocks) - { - if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) - { - List mapBlocks; + m_scene.TryGetScenePresence(agentID, out avatarPresence); - mapBlocks = cachedMapBlocks; - avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); - } - else - { - lookup = true; - } - } - if (lookup) + if (avatarPresence != null) { - List mapBlocks = new List(); ; + bool lookup = false; - List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, - (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, - (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, - (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); - foreach (GridRegion r in regions) + lock (cachedMapBlocks) { - MapBlockData block = new MapBlockData(); - MapBlockFromGridRegion(block, r); - mapBlocks.Add(block); + if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) + { + List mapBlocks; + + mapBlocks = cachedMapBlocks; + avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); + } + else + { + lookup = true; + } } - avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); + if (lookup) + { + List mapBlocks = new List(); ; + + List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, + (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, + (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, + (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, + (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); + foreach (GridRegion r in regions) + { + MapBlockData block = new MapBlockData(); + MapBlockFromGridRegion(block, r); + mapBlocks.Add(block); + } + avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); - lock (cachedMapBlocks) - cachedMapBlocks = mapBlocks; + lock (cachedMapBlocks) + cachedMapBlocks = mapBlocks; - cachedTime = Util.UnixTimeSinceEpoch(); + cachedTime = Util.UnixTimeSinceEpoch(); + } } } + LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); return mapResponse.ToString(); -- cgit v1.1 From 49e4e5392899a274e9c05d00e8abba35d3c25b02 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 8 Jun 2011 16:41:58 -0700 Subject: Consistency fix on the last commit. --- OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index ed3677b..30cf1db 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -218,7 +218,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // 6/8/2011 -- I'm adding an explicit 4096 check, so that we never forget that there is // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. - if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY > 4096) + if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY >= 4096) { ScenePresence avatarPresence = null; -- cgit v1.1 From 4cf60c5d9d95b5d7566c24f79f321e39fc2e2679 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 8 Jun 2011 19:51:48 -0700 Subject: Removing special casing on failures. This may also fix reports of this issue: 22:07:53 - [USER AGENT CONNECTOR]: remote call to http://hg.osgrid.org:80/ returned an error: Requested method [locate_user] from 127.0.0.1 threw exception: Object reference not set to an instance of an object at OpenSim.Services.HypergridService.UserAgentService.LocateUser (UUID userID) [0x00000] in :0 --- OpenSim/Services/HypergridService/UserAgentService.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 7ed5ea5..1559cf3 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -197,9 +197,11 @@ namespace OpenSim.Services.HypergridService agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); // restore the old travel info - if(reason != "Logins Disabled") + lock (m_TravelingAgents) { - lock (m_TravelingAgents) + if (old == null) + m_TravelingAgents.Remove(agentCircuit.SessionID); + else m_TravelingAgents[agentCircuit.SessionID] = old; } -- cgit v1.1 From e3e1f6308d4636b546798f6aa2f7624b8dc52c9e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 9 Jun 2011 16:11:47 -0700 Subject: Change the name of the newest command to "show names" so that it doesn't conflict with the existing "show users" --- .../CoreModules/Framework/UserManagement/UserManagementModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index ae4336c..accd094 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -82,8 +82,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement // } //} MainConsole.Instance.Commands.AddCommand("grid", true, - "show user-names", - "show user-names", + "show names", + "show names", "Show the bindings between user UUIDs and user names", String.Empty, HandleShowUsers); -- cgit v1.1 From 8d3a8a0a8150e856103a152228b736ab74f821d7 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 9 Jun 2011 16:51:47 -0700 Subject: The map breakage is actually at 2048! --- OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 30cf1db..69d3005 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -209,16 +209,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // path, param, agentID.ToString()); // There is a major hack going on in this method. The viewer doesn't request - // map blocks (RequestMapBlocks) above 4096. That means that if we don't hack, + // map blocks (RequestMapBlocks) above 2048. That means that if we don't hack, // grids above that cell don't have a map at all. So, here's the hack: we wait // for this CAP request to come, and we inject the map blocks at this point. // In a normal scenario, this request simply sends back the MapLayer (the blue color). // In the hacked scenario, it also sends the map blocks via UDP. // - // 6/8/2011 -- I'm adding an explicit 4096 check, so that we never forget that there is + // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. - if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY >= 4096) + if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) { ScenePresence avatarPresence = null; -- cgit v1.1 From 2bc8dcfdbd987ca4a47270c62b77a7eb9ac0f851 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 10 Jun 2011 02:27:45 +0100 Subject: minor: add method doc to make it clear that click action is fired when the click action is changed, not when a prim is clicked --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index cdb4e41..a078291 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1504,7 +1504,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// + /// Handle a prim description set request from a viewer. /// /// /// @@ -1521,8 +1521,17 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Set a click action for the prim. + /// + /// + /// + /// protected internal void PrimClickAction(IClientAPI remoteClient, uint primLocalID, string clickAction) { +// m_log.DebugFormat( +// "[SCENEGRAPH]: User {0} set click action for {1} to {2}", remoteClient.Name, primLocalID, clickAction); + SceneObjectGroup group = GetGroupByPrim(primLocalID); if (group != null) { -- cgit v1.1 From 9149ef6c89a5dd5de144022530e5a4facdc91919 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 10 Jun 2011 02:33:50 +0100 Subject: For MySQL, migrate region tables to the MyISAM storage engine rather than InnoDB Using MyISAM proves vastly faster for persisting scene objects. For instance, a scene object that took 9 seconds to persist before now takes 1. This also improves the experience of loading large OARs. We don't use any of the transactional features of InnoDB. The only thing that may have an impact is that InnoDB does row locking on inserts while MyISAM does table locking. However, field reports say there is no noticeable difference. --- OpenSim/Data/MySQL/Resources/RegionStore.migrations | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index ba8d538..987625b 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -826,3 +826,19 @@ ALTER TABLE `prims` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT ''; ALTER TABLE `primitems` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT ''; COMMIT; + +:VERSION 38 #--------------------- + +BEGIN; + +alter table land ENGINE = MyISAM; +alter table landaccesslist ENGINE = MyISAM; +alter table migrations ENGINE = MyISAM; +alter table primitems ENGINE = MyISAM; +alter table prims ENGINE = MyISAM; +alter table primshapes ENGINE = MyISAM; +alter table regionban ENGINE = MyISAM; +alter table regionsettings ENGINE = MyISAM; +alter table terrain ENGINE = MyISAM; + +COMMIT; \ No newline at end of file -- cgit v1.1 From 387b228d68b579bf978c091d8873608e016d0c3d Mon Sep 17 00:00:00 2001 From: dahlia Date: Fri, 10 Jun 2011 00:38:38 -0700 Subject: partial update for new mesh asset format - handle both old and new formats for physics mesh --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index f89b824..99b2d84 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -303,7 +303,11 @@ namespace OpenSim.Region.Physics.Meshing if (meshOsd is OSDMap) { OSDMap map = (OSDMap)meshOsd; - OSDMap physicsParms = (OSDMap)map["physics_shape"]; + OSDMap physicsParms = (OSDMap)map["physics_shape"]; // old asset format + + if (physicsParms.Count == 0) + physicsParms = (OSDMap)map["physics_mesh"]; // new asset format + int physOffset = physicsParms["offset"].AsInteger() + (int)start; int physSize = physicsParms["size"].AsInteger(); -- cgit v1.1 From 98d1e7768af945d3516243f3e010cc4e1fc0788a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 10 Jun 2011 09:16:43 -0700 Subject: New method for resetting the map on HG: do it only once upon changing grids, and reset only exactly the map blocks that had regions in them. WARNING: this fetches all the regions from the Grid service, so there is a chance that this is a really bad idea in large grids. Pushing it for testing. --- .../EntityTransfer/HGEntityTransferModule.cs | 26 +++++++++ .../CoreModules/Hypergrid/HGWorldMapModule.cs | 66 +++++++++++----------- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 37d81a3..8df89ad 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -147,8 +147,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { base.AgentHasMovedAway(sp, logout); if (logout) + { + // Reset the map + ResetMap(sp); + // Log them out of this grid m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); + } } protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) @@ -280,6 +285,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } + protected void ResetMap(ScenePresence sp) + { + List regions = m_Scenes[0].GridService.GetRegionRange(m_Scenes[0].RegionInfo.ScopeID, 0, 17000 * (int)Constants.RegionSize, 0, 17000 * (int)Constants.RegionSize); + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Resetting {0} tiles on the map", regions.Count); + if (regions != null) + { + List mapBlocks = new List(); + foreach (GridRegion r in regions) + { + MapBlockData mblock = new MapBlockData(); + mblock.X = (ushort)(r.RegionLocX / Constants.RegionSize); + mblock.Y = (ushort)(r.RegionLocY / Constants.RegionSize); + mblock.Name = ""; + mblock.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's + mblock.MapImageId = UUID.Zero; + mapBlocks.Add(mblock); + } + sp.ControllingClient.SendMapBlock(mapBlocks, 0); + } + + } #endregion diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index f066f83..fd2cc20 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -59,44 +59,44 @@ namespace OpenSim.Region.CoreModules.Hypergrid #endregion - protected override void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) - { - List mapBlocks = new List(); - List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - minX * (int)Constants.RegionSize, maxX * (int)Constants.RegionSize, - minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize); + //protected override void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + //{ + // List mapBlocks = new List(); + // List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, + // minX * (int)Constants.RegionSize, maxX * (int)Constants.RegionSize, + // minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize); - foreach (GridRegion r in regions) - { - uint x = 0, y = 0; - long handle = 0; - if (r.RegionSecret != null && r.RegionSecret != string.Empty) - { - if (long.TryParse(r.RegionSecret, out handle)) - { - Utils.LongToUInts((ulong)handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - } - } + // foreach (GridRegion r in regions) + // { + // uint x = 0, y = 0; + // long handle = 0; + // if (r.RegionSecret != null && r.RegionSecret != string.Empty) + // { + // if (long.TryParse(r.RegionSecret, out handle)) + // { + // Utils.LongToUInts((ulong)handle, out x, out y); + // x = x / Constants.RegionSize; + // y = y / Constants.RegionSize; + // } + // } - if (handle == 0 || - // Check the distance from the current region - (handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096)) - { - MapBlockData block = new MapBlockData(); - MapBlockFromGridRegion(block, r); - mapBlocks.Add(block); - } - } + // if (handle == 0 || + // // Check the distance from the current region + // (handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096)) + // { + // MapBlockData block = new MapBlockData(); + // MapBlockFromGridRegion(block, r); + // mapBlocks.Add(block); + // } + // } - // Different from super - FillInMap(mapBlocks, minX, minY, maxX, maxY); - // + // // Different from super + // //FillInMap(mapBlocks, minX, minY, maxX, maxY); + // // - remoteClient.SendMapBlock(mapBlocks, 0); + // remoteClient.SendMapBlock(mapBlocks, 0); - } + //} private void FillInMap(List mapBlocks, int minX, int minY, int maxX, int maxY) -- cgit v1.1 From b5518dc90631014a4aa3dbb6c27fd5d4c9f612c9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 10 Jun 2011 20:40:14 +0100 Subject: minor: Add some commented out destructor logging messages for potential future use. At the moment, client and scene objects are being garbage collected as expected, at least in simple scenarios. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 5 +++++ OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 5 +++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index cefceb0..f53e236 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -428,6 +428,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Properties +// ~LLClientView() +// { +// m_log.DebugFormat("[LLCLIENTVIEW]: Destructor called for {0}, circuit code {1}", Name, CircuitCode); +// } + /// /// Constructor /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 9b9374b..79660a3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -469,6 +469,11 @@ namespace OpenSim.Region.Framework.Scenes #endregion +// ~SceneObjectGroup() +// { +// m_log.DebugFormat("[SCENE OBJECT GROUP]: Destructor called for {0}, local id {1}", Name, LocalId); +// } + #region Constructors /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 331abb2..a215b20 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -346,6 +346,13 @@ namespace OpenSim.Region.Framework.Scenes #endregion Fields +// ~SceneObjectPart() +// { +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Destructor called for {0}, local id {1}, parent {2} {3}", +// Name, LocalId, ParentGroup.Name, ParentGroup.LocalId); +// } + #region Constructors /// -- cgit v1.1 From 804fe2d9b00e7e974600f17d64375fab8676ad11 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Fri, 20 May 2011 12:52:09 +0300 Subject: Save the sun's position in OARs --- .../Framework/Serialization/External/RegionSettingsSerializer.cs | 8 ++++++-- OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | 3 +++ OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs index 6ba4c5a..931898c 100644 --- a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs +++ b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs @@ -182,6 +182,9 @@ namespace OpenSim.Framework.Serialization.External case "FixedSun": settings.FixedSun = bool.Parse(xtr.ReadElementContentAsString()); break; + case "SunPosition": + settings.SunPosition = double.Parse(xtr.ReadElementContentAsString()); + break; } } @@ -237,8 +240,9 @@ namespace OpenSim.Framework.Serialization.External xtw.WriteElementString("TerrainLowerLimit", settings.TerrainLowerLimit.ToString()); xtw.WriteElementString("UseEstateSun", settings.UseEstateSun.ToString()); xtw.WriteElementString("FixedSun", settings.FixedSun.ToString()); - // XXX: Need to expose interface to get sun phase information from sun module - // xtw.WriteStartElement("SunPhase", + xtw.WriteElementString("SunPosition", settings.SunPosition.ToString()); + // Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which + // calculates it automatically according to the date and other factors. xtw.WriteEndElement(); xtw.WriteEndElement(); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 6461636..48130e7 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -488,6 +488,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver currentRegionSettings.Elevation2SE = loadedRegionSettings.Elevation2SE; currentRegionSettings.Elevation2SW = loadedRegionSettings.Elevation2SW; currentRegionSettings.FixedSun = loadedRegionSettings.FixedSun; + currentRegionSettings.SunPosition = loadedRegionSettings.SunPosition; currentRegionSettings.ObjectBonus = loadedRegionSettings.ObjectBonus; currentRegionSettings.RestrictPushing = loadedRegionSettings.RestrictPushing; currentRegionSettings.TerrainLowerLimit = loadedRegionSettings.TerrainLowerLimit; @@ -500,6 +501,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; currentRegionSettings.Save(); + + m_scene.TriggerEstateSunUpdate(); IEstateModule estateModule = m_scene.RequestModuleInterface(); diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 34e2e23..6ba3459 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -440,6 +440,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests rs.Elevation2SE = 9.2; rs.Elevation2SW = 2.1; rs.FixedSun = true; + rs.SunPosition = 12.0; rs.ObjectBonus = 1.4; rs.RestrictPushing = true; rs.TerrainLowerLimit = 0.4; @@ -485,6 +486,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Assert.That(loadedRs.Elevation2SE, Is.EqualTo(9.2)); Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1)); Assert.That(loadedRs.FixedSun, Is.True); + Assert.AreEqual(12.0, loadedRs.SunPosition); Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4)); Assert.That(loadedRs.RestrictPushing, Is.True); Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4)); -- cgit v1.1 From c7bdb66a1f02c968f61f82333751e7f144fb59d8 Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Thu, 9 Jun 2011 22:26:03 +0900 Subject: Added missing "Old Guids=true" to ConnectionString --- OpenSim/Tests/Clients/Presence/OpenSim.Server.ini | 2 +- OpenSim/Tests/Clients/UserAccounts/OpenSim.Server.ini | 2 +- bin/config-include/GridCommon.ini.example | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Tests/Clients/Presence/OpenSim.Server.ini b/OpenSim/Tests/Clients/Presence/OpenSim.Server.ini index 47e73f9..8610c78 100644 --- a/OpenSim/Tests/Clients/Presence/OpenSim.Server.ini +++ b/OpenSim/Tests/Clients/Presence/OpenSim.Server.ini @@ -29,5 +29,5 @@ port = 8003 [PresenceService] LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService" StorageProvider = "OpenSim.Data.MySQL.dll" - ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;" + ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;Old Guids=true;" diff --git a/OpenSim/Tests/Clients/UserAccounts/OpenSim.Server.ini b/OpenSim/Tests/Clients/UserAccounts/OpenSim.Server.ini index eb1f473..453e17e 100644 --- a/OpenSim/Tests/Clients/UserAccounts/OpenSim.Server.ini +++ b/OpenSim/Tests/Clients/UserAccounts/OpenSim.Server.ini @@ -29,5 +29,5 @@ port = 8003 [UserAccountService] LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" StorageProvider = "OpenSim.Data.MySQL.dll" - ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;" + ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;Old Guids=true;" diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index e2e6459..27f262f 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -10,9 +10,9 @@ ; Uncomment these lines if you want to use mysql storage ; Change the connection string to your db details ;StorageProvider = "OpenSim.Data.MySQL.dll" - ;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;" + ;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;" ; Uncomment this line if you are using MySQL and want to use a different database for estates - ;EstateConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;" + ;EstateConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;" ; MSSQL ; Uncomment these lines if you want to use MSSQL storage -- cgit v1.1 From fc7e17baf74a4b3ce4c47480f24266180dd4353d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 10 Jun 2011 21:49:25 +0100 Subject: When serializing objects, stop accidentally using the green text colour value for alpha This addresses http://opensimulator.org/mantis/view.php?id=5111 --- OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 6ae4f38..fcf7e0c 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -1171,7 +1171,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture)); writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture)); writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture)); - writer.WriteElementString("A", sop.Color.G.ToString(Utils.EnUsCulture)); + writer.WriteElementString("A", sop.Color.A.ToString(Utils.EnUsCulture)); writer.WriteEndElement(); writer.WriteElementString("Text", sop.Text); -- cgit v1.1 From b13b54c5268d8acada132b678946ceba925f6419 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 11 Jun 2011 00:04:21 +0100 Subject: Make the internal flotsam asset cache defaults match config-include/FlotsamCache.ini.example. Enable the flotsam console commands even if FlotsamCache.ini isn't present. For the most part, defaults are made to match those already in FlotsamCache.ini.example. The one exception is that the 48 hour file timeout from the code is used instead of the 0 hours that was in the example file. This can be tweaked if necessary. Most importantly, the default cache directory is now ./assetcache (as in FlotsamCache.ini.example) rather than ./FlotsamAssetCache (as was the internal code default). Therefore, if you were using flotasm without using the config file, then please rename your cache directory or start using the ini file and change the default there if you want to keep using your existing cache. --- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 64 ++++++++++++---------- bin/config-include/FlotsamCache.ini.example | 2 +- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 9adb68b..d9280c6 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -64,13 +64,13 @@ namespace Flotsam.RegionModules.AssetCache private bool m_Enabled; private const string m_ModuleName = "FlotsamAssetCache"; - private const string m_DefaultCacheDirectory = m_ModuleName; + private const string m_DefaultCacheDirectory = "./assetcache"; private string m_CacheDirectory = m_DefaultCacheDirectory; private readonly List m_InvalidChars = new List(); private int m_LogLevel = 0; - private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests + private ulong m_HitRateDisplay = 100; // How often to display hit statistics, given in requests private static ulong m_Requests; private static ulong m_RequestsForInprogress; @@ -87,14 +87,14 @@ namespace Flotsam.RegionModules.AssetCache #endif private ExpiringCache m_MemoryCache; - private bool m_MemoryCacheEnabled = true; + private bool m_MemoryCacheEnabled = false; // Expiration is expressed in hours. - private const double m_DefaultMemoryExpiration = 1.0; + private const double m_DefaultMemoryExpiration = 2; private const double m_DefaultFileExpiration = 48; private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration); private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); - private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(m_DefaultFileExpiration); + private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(0.166); private static int m_CacheDirectoryTiers = 1; private static int m_CacheDirectoryTierLen = 3; @@ -141,26 +141,38 @@ namespace Flotsam.RegionModules.AssetCache IConfig assetConfig = source.Configs["AssetCache"]; if (assetConfig == null) { - m_log.Warn("[FLOTSAM ASSET CACHE]: AssetCache missing from OpenSim.ini, using defaults."); - m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory); - return; + m_log.Warn( + "[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults."); } + else + { + m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); - m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); - m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_CacheDirectory); + m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled); + m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration)); + + #if WAIT_ON_INPROGRESS_REQUESTS + m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000); + #endif + + m_LogLevel = assetConfig.GetInt("LogLevel", m_LogLevel); + m_HitRateDisplay = (ulong)assetConfig.GetLong("HitRateDisplay", (long)m_HitRateDisplay); - m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", false); - m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration)); + m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration)); + m_FileExpirationCleanupTimer + = TimeSpan.FromHours( + assetConfig.GetDouble("FileCleanupTimer", m_FileExpirationCleanupTimer.TotalHours)); -#if WAIT_ON_INPROGRESS_REQUESTS - m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000); -#endif + m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", m_CacheDirectoryTiers); + m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen); + + m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt); - m_LogLevel = assetConfig.GetInt("LogLevel", 0); - m_HitRateDisplay = (ulong)assetConfig.GetInt("HitRateDisplay", 1000); + m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", m_DeepScanBeforePurge); + } + + m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory); - m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration)); - m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration)); if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero)) { m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds); @@ -170,7 +182,6 @@ namespace Flotsam.RegionModules.AssetCache m_CacheCleanTimer.Start(); } - m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", 1); if (m_CacheDirectoryTiers < 1) { m_CacheDirectoryTiers = 1; @@ -180,7 +191,6 @@ namespace Flotsam.RegionModules.AssetCache m_CacheDirectoryTiers = 3; } - m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", 3); if (m_CacheDirectoryTierLen < 1) { m_CacheDirectoryTierLen = 1; @@ -190,14 +200,10 @@ namespace Flotsam.RegionModules.AssetCache m_CacheDirectoryTierLen = 4; } - m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", 30000); - - m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", false); - - MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand); - MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand); - MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); - MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache expire", "fcache expire ", "Purge cached assets older then the specified date/time", HandleConsoleCommand); + MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand); + MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand); + MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); + MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire ", "Purge cached assets older then the specified date/time", HandleConsoleCommand); } } } diff --git a/bin/config-include/FlotsamCache.ini.example b/bin/config-include/FlotsamCache.ini.example index 026dee7..1f2bf03 100644 --- a/bin/config-include/FlotsamCache.ini.example +++ b/bin/config-include/FlotsamCache.ini.example @@ -29,7 +29,7 @@ ; How long {in hours} to keep assets cached on disk, .5 == 30 minutes ; Specify 0 if you do not want your disk cache to expire - FileCacheTimeout = 0 + FileCacheTimeout = 48 ; How often {in hours} should the disk be checked for expired filed ; Specify 0 to disable expiration checking -- cgit v1.1 From c7cef650db6bbbabfefa7a2fb47a028147b7e822 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 11 Jun 2011 00:10:40 +0100 Subject: Make it clear that WaitOnInprogressTimeout is currently a dead setting in FlotsamCache.ini.example --- bin/config-include/FlotsamCache.ini.example | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/config-include/FlotsamCache.ini.example b/bin/config-include/FlotsamCache.ini.example index 1f2bf03..ad38ad1 100644 --- a/bin/config-include/FlotsamCache.ini.example +++ b/bin/config-include/FlotsamCache.ini.example @@ -38,6 +38,7 @@ ; If WAIT_ON_INPROGRESS_REQUESTS has been defined then this specifies how ; long (in miliseconds) to block a request thread while trying to complete ; an existing write to disk. + ; NOTE: THIS PARAMETER IS NOT CURRENTLY USED BY THE CACHE ; WaitOnInprogressTimeout = 3000 ; Number of tiers to use for cache directories (current valid -- cgit v1.1 From 39e878eb8f23cdae67b917d16f3dfc8709abcd9c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 11 Jun 2011 00:35:31 +0100 Subject: Align CenomeCache.ini.example values with CenomeCache defaults. --- bin/config-include/CenomeCache.ini.example | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/bin/config-include/CenomeCache.ini.example b/bin/config-include/CenomeCache.ini.example index 8ef4e03..4340493 100644 --- a/bin/config-include/CenomeCache.ini.example +++ b/bin/config-include/CenomeCache.ini.example @@ -1,13 +1,14 @@ [AssetCache] ;; - ;; Options for CenmoeAssetCache + ;; Options for CenomeAssetCache ;; - ; 256 MB (default: 134217728) - MaxSize = 268435456 + ; Max size of the cache in bytes + ; 134217728 = 128 MB, 26843556 = 256 MB, etc (default: 134217728) + MaxSize = 134217728 - ; How many assets it is possible to store cache (default: 4096) - MaxCount = 16384 + ; How many assets it is possible to store in the cache (default: 4096) + MaxCount = 4096 - ; Expiration time - 1 hour (default: 30 minutes) - ExpirationTime = 60 + ; Expiration time in minutes (default: 30) + ExpirationTime = 30 -- cgit v1.1 From 9a62bfab0ea6c60ad2ce8b853b3dae95ef57ac69 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 11 Jun 2011 00:50:20 +0100 Subject: If the flotsam asset cache console command "fcache clear" is specified on its own, clear both memory and file caches --- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 37 +++++++++++++++------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index d9280c6..48ee277 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -201,7 +201,7 @@ namespace Flotsam.RegionModules.AssetCache } MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand); - MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand); + MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand); MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire ", "Purge cached assets older then the specified date/time", HandleConsoleCommand); } @@ -729,24 +729,39 @@ namespace Flotsam.RegionModules.AssetCache break; case "clear": - if (cmdparams.Length < 3) + if (cmdparams.Length < 2) { - m_log.Warn("[FLOTSAM ASSET CACHE] Please specify memory and/or file cache."); + m_log.Warn("[FLOTSAM ASSET CACHE] Usage is fcache clear [file] [memory]"); break; } + + bool clearMemory = false, clearFile = false; + + if (cmdparams.Length == 2) + { + clearMemory = true; + clearFile = true; + } foreach (string s in cmdparams) { if (s.ToLower() == "memory") - { - m_MemoryCache.Clear(); - m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared."); - } + clearMemory = true; else if (s.ToLower() == "file") - { - ClearFileCache(); - m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared."); - } + clearFile = true; + } + + if (clearMemory) + { + m_MemoryCache.Clear(); + m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared."); } + + if (clearFile) + { + ClearFileCache(); + m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared."); + } + break; -- cgit v1.1 From 487cb51f69ac2f713797de03eb26a4b53afcfade Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 10 Jun 2011 17:22:17 -0700 Subject: 3rd way of reseting the HG Map. This time, don't use the grid service; instead keep track of which map blocks each client has seen in the region, and reset exactly those when the client closes. --- .../EntityTransfer/HGEntityTransferModule.cs | 25 ----- .../CoreModules/Hypergrid/HGWorldMapModule.cs | 121 ++++++++++++--------- .../CoreModules/World/WorldMap/WorldMapModule.cs | 4 +- 3 files changed, 71 insertions(+), 79 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 8df89ad..4d77ef4 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -148,9 +148,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer base.AgentHasMovedAway(sp, logout); if (logout) { - // Reset the map - ResetMap(sp); - // Log them out of this grid m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); } @@ -285,28 +282,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } - protected void ResetMap(ScenePresence sp) - { - List regions = m_Scenes[0].GridService.GetRegionRange(m_Scenes[0].RegionInfo.ScopeID, 0, 17000 * (int)Constants.RegionSize, 0, 17000 * (int)Constants.RegionSize); - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Resetting {0} tiles on the map", regions.Count); - if (regions != null) - { - List mapBlocks = new List(); - foreach (GridRegion r in regions) - { - MapBlockData mblock = new MapBlockData(); - mblock.X = (ushort)(r.RegionLocX / Constants.RegionSize); - mblock.Y = (ushort)(r.RegionLocY / Constants.RegionSize); - mblock.Name = ""; - mblock.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's - mblock.MapImageId = UUID.Zero; - mapBlocks.Add(mblock); - } - sp.ControllingClient.SendMapBlock(mapBlocks, 0); - } - - } - #endregion #region IUserAgentVerificationModule diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index fd2cc20..0c60391 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -41,7 +41,10 @@ namespace OpenSim.Region.CoreModules.Hypergrid { public class HGWorldMapModule : WorldMapModule { - //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + // Remember the map area that each client has been exposed to in this region + private Dictionary> m_SeenMapBlocks = new Dictionary>(); #region INonSharedRegionModule Members @@ -52,6 +55,13 @@ namespace OpenSim.Region.CoreModules.Hypergrid m_Enabled = true; } + public override void AddRegion(Scene scene) + { + base.AddRegion(scene); + + scene.EventManager.OnClientClosed += new EventManager.ClientClosed(EventManager_OnClientClosed); + } + public override string Name { get { return "HGWorldMap"; } @@ -59,65 +69,70 @@ namespace OpenSim.Region.CoreModules.Hypergrid #endregion - //protected override void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) - //{ - // List mapBlocks = new List(); - // List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - // minX * (int)Constants.RegionSize, maxX * (int)Constants.RegionSize, - // minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize); - - // foreach (GridRegion r in regions) - // { - // uint x = 0, y = 0; - // long handle = 0; - // if (r.RegionSecret != null && r.RegionSecret != string.Empty) - // { - // if (long.TryParse(r.RegionSecret, out handle)) - // { - // Utils.LongToUInts((ulong)handle, out x, out y); - // x = x / Constants.RegionSize; - // y = y / Constants.RegionSize; - // } - // } - - // if (handle == 0 || - // // Check the distance from the current region - // (handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096)) - // { - // MapBlockData block = new MapBlockData(); - // MapBlockFromGridRegion(block, r); - // mapBlocks.Add(block); - // } - // } - - // // Different from super - // //FillInMap(mapBlocks, minX, minY, maxX, maxY); - // // - - // remoteClient.SendMapBlock(mapBlocks, 0); - - //} - - - private void FillInMap(List mapBlocks, int minX, int minY, int maxX, int maxY) + void EventManager_OnClientClosed(UUID clientID, Scene scene) { - for (int x = minX; x <= maxX; x++) + ScenePresence sp = scene.GetScenePresence(clientID); + if (sp != null) { - for (int y = minY; y <= maxY; y++) + if (m_SeenMapBlocks.ContainsKey(clientID)) { - MapBlockData mblock = mapBlocks.Find(delegate(MapBlockData mb) { return ((mb.X == x) && (mb.Y == y)); }); - if (mblock == null) + List mapBlocks = m_SeenMapBlocks[clientID]; + foreach (MapBlockData b in mapBlocks) { - mblock = new MapBlockData(); - mblock.X = (ushort)x; - mblock.Y = (ushort)y; - mblock.Name = ""; - mblock.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's - mblock.MapImageId = UUID.Zero; - mapBlocks.Add(mblock); + b.Name = string.Empty; + b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's } + + m_log.DebugFormat("[HG MAP]: Reseting {0} blocks", mapBlocks.Count); + sp.ControllingClient.SendMapBlock(mapBlocks, 0); + m_SeenMapBlocks.Remove(clientID); } } } + + protected override List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + { + List mapBlocks = base.GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); + lock (m_SeenMapBlocks) + { + if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId)) + { + m_SeenMapBlocks.Add(remoteClient.AgentId, mapBlocks); + } + else + { + List seen = m_SeenMapBlocks[remoteClient.AgentId]; + List newBlocks = new List(); + foreach (MapBlockData b in mapBlocks) + if (seen.Find(delegate(MapBlockData bdata) { return bdata.X == b.X && bdata.Y == b.Y; }) == null) + newBlocks.Add(b); + seen.AddRange(newBlocks); + } + } + + return mapBlocks; + } + + } + + class MapArea + { + public int minX; + public int minY; + public int maxX; + public int maxY; + + public MapArea(int mix, int miy, int max, int may) + { + minX = mix; + minY = miy; + maxX = max; + maxY = may; + } + + public void Print() + { + Console.WriteLine(String.Format(" --> Area is minX={0} minY={1} minY={2} maxY={3}", minX, minY, maxY, maxY)); + } } } diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 69d3005..3553c9a 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -845,7 +845,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } } - protected virtual void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) + protected virtual List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, @@ -860,6 +860,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap mapBlocks.Add(block); } remoteClient.SendMapBlock(mapBlocks, 0); + + return mapBlocks; } protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r) -- cgit v1.1 From 0ae022d68822c05130f76a6e80bccd669a3d76ed Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 10 Jun 2011 20:59:57 -0700 Subject: Decreased timeout of HG StatusNotification to 4secs. http://opensimulator.org/mantis/view.php?id=5516 --- OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 853e524..b7e09e8 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -427,7 +427,7 @@ namespace OpenSim.Services.Connectors.Hypergrid XmlRpcResponse response = null; try { - response = request.Send(m_ServerURL, 10000); + response = request.Send(m_ServerURL, 4000); } catch (Exception e) { -- cgit v1.1 From 5f311c91c781d09e266fb76cb7747550fe2afc16 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 10 Jun 2011 21:07:50 -0700 Subject: More tweaking on the UserAgentServiceConnector: add constructor that does not do DNS lookup, and use that for friends notification. --- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 2 +- .../Hypergrid/UserAgentServiceConnector.cs | 35 ++++++++++++++-------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index b9d6719..b8342ef 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -278,7 +278,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends List ids = new List(); foreach (FriendInfo f in kvp.Value) ids.Add(f.Friend); - UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); + UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key, false); List friendsOnline = uConn.StatusNotification(ids, userID, online); // need to debug this here if (online) diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index b7e09e8..2a5fb40 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -51,22 +51,31 @@ namespace OpenSim.Services.Connectors.Hypergrid MethodBase.GetCurrentMethod().DeclaringType); string m_ServerURL; - public UserAgentServiceConnector(string url) + + public UserAgentServiceConnector(string url) : this(url, true) + { + } + + public UserAgentServiceConnector(string url, bool dnsLookup) { m_ServerURL = url; - // Doing this here, because XML-RPC or mono have some strong ideas about - // caching DNS translations. - try - { - Uri m_Uri = new Uri(m_ServerURL); - IPAddress ip = Util.GetHostFromDNS(m_Uri.Host); - m_ServerURL = m_ServerURL.Replace(m_Uri.Host, ip.ToString()); - if (!m_ServerURL.EndsWith("/")) - m_ServerURL += "/"; - } - catch (Exception e) + + if (dnsLookup) { - m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message); + // Doing this here, because XML-RPC or mono have some strong ideas about + // caching DNS translations. + try + { + Uri m_Uri = new Uri(m_ServerURL); + IPAddress ip = Util.GetHostFromDNS(m_Uri.Host); + m_ServerURL = m_ServerURL.Replace(m_Uri.Host, ip.ToString()); + if (!m_ServerURL.EndsWith("/")) + m_ServerURL += "/"; + } + catch (Exception e) + { + m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message); + } } m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL); } -- cgit v1.1 From e07d71d2982ac2c128035fee29991eda949bd8dd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 10 Jun 2011 21:17:34 -0700 Subject: Added a Sleep in between each site call, to slow the xml-rpc requests down. --- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 77 +++++++++++----------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index b8342ef..40506a5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -29,6 +29,8 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; +using System.Threading; + using log4net; using Nini.Config; using Nwc.XmlRpc; @@ -194,46 +196,46 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends //} - private void CollectOnlineFriendsElsewhere(UUID userID, List foreignFriends) - { - // let's divide the friends on a per-domain basis - Dictionary> friendsPerDomain = new Dictionary>(); - foreach (string friend in foreignFriends) - { - UUID friendID; - if (!UUID.TryParse(friend, out friendID)) - { - // it's a foreign friend - string url = string.Empty, tmp = string.Empty; - if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp)) - { - if (!friendsPerDomain.ContainsKey(url)) - friendsPerDomain[url] = new List(); - friendsPerDomain[url].Add(friend); - } - } - } + //private void CollectOnlineFriendsElsewhere(UUID userID, List foreignFriends) + //{ + // // let's divide the friends on a per-domain basis + // Dictionary> friendsPerDomain = new Dictionary>(); + // foreach (string friend in foreignFriends) + // { + // UUID friendID; + // if (!UUID.TryParse(friend, out friendID)) + // { + // // it's a foreign friend + // string url = string.Empty, tmp = string.Empty; + // if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp)) + // { + // if (!friendsPerDomain.ContainsKey(url)) + // friendsPerDomain[url] = new List(); + // friendsPerDomain[url].Add(friend); + // } + // } + // } - // Now, call those worlds + // // Now, call those worlds - foreach (KeyValuePair> kvp in friendsPerDomain) - { - List ids = new List(); - foreach (string f in kvp.Value) - ids.Add(f); - UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); - List online = uConn.GetOnlineFriends(userID, ids); - // Finally send the notifications to the user - // this whole process may take a while, so let's check at every - // iteration that the user is still here - IClientAPI client = LocateClientObject(userID); - if (client != null) - client.SendAgentOnline(online.ToArray()); - else - break; - } + // foreach (KeyValuePair> kvp in friendsPerDomain) + // { + // List ids = new List(); + // foreach (string f in kvp.Value) + // ids.Add(f); + // UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); + // List online = uConn.GetOnlineFriends(userID, ids); + // // Finally send the notifications to the user + // // this whole process may take a while, so let's check at every + // // iteration that the user is still here + // IClientAPI client = LocateClientObject(userID); + // if (client != null) + // client.SendAgentOnline(online.ToArray()); + // else + // break; + // } - } + //} protected override void StatusNotify(List friendList, UUID userID, bool online) { @@ -280,6 +282,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends ids.Add(f.Friend); UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key, false); List friendsOnline = uConn.StatusNotification(ids, userID, online); + Thread.Sleep(100); // need to debug this here if (online) { -- cgit v1.1 From d99277939750247ad100395394720c73a3580c72 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 11 Jun 2011 09:36:57 -0700 Subject: Switched order of SQL statements in Friends migration -- resulted in the wrong key --- OpenSim/Data/MySQL/Resources/FriendsStore.migrations | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations index 7848e49..55d82ec 100644 --- a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations +++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations @@ -25,8 +25,8 @@ COMMIT; BEGIN; +ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; ALTER TABLE `Friends` DROP PRIMARY KEY; ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36)); -ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; COMMIT; -- cgit v1.1 From e1ca77a0dbc68431131b0505f03cf45dbfe5b7d9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 11 Jun 2011 17:22:35 -0700 Subject: Only send AgentOnline to the client if the friendsOnline list has elements. Also, increased the timeout on UserAgentServiceConnector, StatusNotification again. --- OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 2 +- OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 40506a5..2c91514 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -284,7 +284,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends List friendsOnline = uConn.StatusNotification(ids, userID, online); Thread.Sleep(100); // need to debug this here - if (online) + if (online && friendsOnline.Count > 0) { IClientAPI client = LocateClientObject(userID); if (client != null) diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 2a5fb40..6265bcd 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -436,7 +436,7 @@ namespace OpenSim.Services.Connectors.Hypergrid XmlRpcResponse response = null; try { - response = request.Send(m_ServerURL, 4000); + response = request.Send(m_ServerURL, 6000); } catch (Exception e) { -- cgit v1.1 From 06e254c392c754bf7e7a1c80400a3ef5b1a82ca3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 11 Jun 2011 17:48:19 -0700 Subject: A few more cleanups on the way to close http://opensimulator.org/mantis/view.php?id=5516 once and for all. Moral of the story: don't send AgentOnline/Offline to viewers with a zero-length array. --- .../Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 2c91514..dda67f9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -280,10 +280,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends List ids = new List(); foreach (FriendInfo f in kvp.Value) ids.Add(f.Friend); - UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key, false); + UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); List friendsOnline = uConn.StatusNotification(ids, userID, online); - Thread.Sleep(100); - // need to debug this here + if (online && friendsOnline.Count > 0) { IClientAPI client = LocateClientObject(userID); @@ -305,15 +304,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp)) { IUserManagement userMan = m_Scenes[0].RequestModuleInterface(); - userMan.AddUser(agentID, url + ";" + first + " " + last); + userMan.AddUser(agentID, first, last, url); - try // our best - { - string[] parts = userMan.GetUserName(agentID).Split(); - first = parts[0]; - last = parts[1]; - } - catch { } return true; } return false; -- cgit v1.1 From fd57c91b4a10cf7ee1e94dc8fe4e81eb0d5bae3d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 15:37:42 -0700 Subject: First pass at making the V2 map work. Standalones only for now. There are some issues with the zoom level -- TBD. --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 4 +- .../MapImage/MapImageServiceInConnectorModule.cs | 111 ++++++++ .../MapImage/MapImageServiceModule.cs | 232 ++++++++++++++++ .../CoreModules/World/WorldMap/WorldMapModule.cs | 8 +- .../Server/Handlers/Map/MapAddServerConnector.cs | 61 +++++ .../Server/Handlers/Map/MapGetServerConnector.cs | 105 ++++++++ .../MapImage/MapImageServiceConnector.cs | 158 +++++++++++ OpenSim/Services/Interfaces/IMapImageService.cs | 40 +++ OpenSim/Services/Interfaces/IMapService.cs | 38 --- .../Services/MapImageService/MapImageService.cs | 295 +++++++++++++++++++++ bin/config-include/Standalone.ini | 7 + bin/config-include/StandaloneCommon.ini.example | 3 + bin/config-include/StandaloneHypergrid.ini | 11 +- prebuild.xml | 30 +++ 14 files changed, 1057 insertions(+), 46 deletions(-) create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs create mode 100644 OpenSim/Server/Handlers/Map/MapAddServerConnector.cs create mode 100644 OpenSim/Server/Handlers/Map/MapGetServerConnector.cs create mode 100644 OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs create mode 100644 OpenSim/Services/Interfaces/IMapImageService.cs delete mode 100644 OpenSim/Services/Interfaces/IMapService.cs create mode 100644 OpenSim/Services/MapImageService/MapImageService.cs diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 598e5d1..cb1117a 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -412,7 +412,7 @@ namespace OpenSim.Framework.Servers.HttpServer // OpenSim.Framework.WebUtil.OSHeaderRequestID if (request.Headers["opensim-request-id"] != null) reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]); - // m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl); + //m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl); Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true); @@ -440,7 +440,7 @@ namespace OpenSim.Framework.Servers.HttpServer string path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); -// m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); + //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); if (TryGetStreamHandler(handlerKey, out requestHandler)) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs new file mode 100644 index 0000000..b570155 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs @@ -0,0 +1,111 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections.Generic; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Server.Base; +using OpenSim.Server.Handlers.Base; +using OpenSim.Server.Handlers.MapImage; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MapImageServiceInConnectorModule : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static bool m_Enabled = false; + + private IConfigSource m_Config; + bool m_Registered = false; + + #region IRegionModule interface + + public void Initialise(IConfigSource config) + { + m_Config = config; + IConfig moduleConfig = config.Configs["Modules"]; + if (moduleConfig != null) + { + m_Enabled = moduleConfig.GetBoolean("MapImageServiceInConnector", false); + if (m_Enabled) + { + m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled"); + new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService"); + } + + } + + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public string Name + { + get { return "MapImageServiceIn"; } + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + } + + #endregion + + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs new file mode 100644 index 0000000..ee90859 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs @@ -0,0 +1,232 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Net; +using System.IO; +using System.Timers; +using System.Drawing; +using System.Drawing.Imaging; + +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage +{ + /// + /// + /// + /// + + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MapImageServiceModule : ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private bool m_enabled = false; + private IMapImageService m_MapService; + + private string m_serverUrl = String.Empty; + private Dictionary m_scenes = new Dictionary(); + + private int m_refreshtime = 0; + private int m_lastrefresh = 0; + private System.Timers.Timer m_refreshTimer = new System.Timers.Timer(); + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public string Name { get { return "MapImageServiceModule"; } } + public void RegionLoaded(Scene scene) { } + public void Close() { } + public void PostInitialise() { } + + + /// + /// + /// + public void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("MapImageService", ""); + if (name != Name) + return; + } + + IConfig config = source.Configs["MapImageService"]; + if (config == null) + return; + + int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime")); + if (refreshminutes <= 0) + { + m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled."); + return; + } + + m_refreshtime = refreshminutes * 60 * 1000; // convert from minutes to ms + + string service = config.GetString("LocalServiceModule", string.Empty); + if (service == string.Empty) + { + m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No service dll given in config. Unable to proceed."); + return; + } + + Object[] args = new Object[] { source }; + m_MapService = ServerUtils.LoadPlugin(service, args); + + m_refreshTimer.Enabled = true; + m_refreshTimer.AutoReset = true; + m_refreshTimer.Interval = m_refreshtime; + m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh); + + m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0}min and service object {1}", + refreshminutes, service); + + m_enabled = true; + } + + /// + /// + /// + + + /// + /// + /// + public void AddRegion(Scene scene) + { + if (! m_enabled) + return; + + // Every shared region module has to maintain an indepedent list of + // currently running regions + lock (m_scenes) + m_scenes[scene.RegionInfo.RegionID] = scene; + + scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); + } + + /// + /// + /// + public void RemoveRegion(Scene scene) + { + if (! m_enabled) + return; + + lock (m_scenes) + m_scenes.Remove(scene.RegionInfo.RegionID); + } + + #endregion ISharedRegionModule + + void EventManager_OnPrimsLoaded(Scene s) + { + UploadMapTile(s); + } + + + /// + /// + /// + private void HandleMaptileRefresh(object sender, EventArgs ea) + { + // this approach is a bit convoluted becase we want to wait for the + // first upload to happen on startup but after all the objects are + // loaded and initialized + if (m_lastrefresh > 0 && Util.EnvironmentTickCountSubtract(m_lastrefresh) < m_refreshtime) + return; + + m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: map refresh!"); + lock (m_scenes) + { + foreach (IScene scene in m_scenes.Values) + { + try + { + UploadMapTile(scene); + } + catch (Exception ex) + { + m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: something bad happened {0}", ex.Message); + } + } + } + + m_lastrefresh = Util.EnvironmentTickCount(); + } + + /// + /// + /// + private void UploadMapTile(IScene scene) + { + m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: upload maptile for {0}", scene.RegionInfo.RegionName); + + // Create a PNG map tile and upload it to the AddMapTile API + byte[] jpgData = Utils.EmptyBytes; + IMapImageGenerator tileGenerator = scene.RequestModuleInterface(); + if (tileGenerator == null) + { + m_log.Warn("[MAP IMAGE SERVICE MODULE]: Cannot upload PNG map tile without an ImageGenerator"); + return; + } + + using (Image mapTile = tileGenerator.CreateMapTile()) + { + using (MemoryStream stream = new MemoryStream()) + { + mapTile.Save(stream, ImageFormat.Jpeg); + jpgData = stream.ToArray(); + } + } + + string reason = string.Empty; + if (!m_MapService.AddMapTile((int)scene.RegionInfo.RegionLocX, (int)scene.RegionInfo.RegionLocY, jpgData, out reason)) + { + m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}", + scene.RegionInfo.RegionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, reason); + } + + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 3553c9a..079b1c2 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -849,10 +849,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - (minX - 4) * (int)Constants.RegionSize, - (maxX + 4) * (int)Constants.RegionSize, - (minY - 4) * (int)Constants.RegionSize, - (maxY + 4) * (int)Constants.RegionSize); + (minX - 8) * (int)Constants.RegionSize, + (maxX + 8) * (int)Constants.RegionSize, + (minY - 8) * (int)Constants.RegionSize, + (maxY + 8) * (int)Constants.RegionSize); foreach (GridRegion r in regions) { MapBlockData block = new MapBlockData(); diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs new file mode 100644 index 0000000..a953cd7 --- /dev/null +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -0,0 +1,61 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; + +namespace OpenSim.Server.Handlers.MapImage +{ + public class MapAddServiceConnector : ServiceConnector + { + private IMapImageService m_MapService; + private string m_ConfigName = "MapImageService"; + + public MapAddServiceConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); + + string gridService = serverConfig.GetString("LocalServiceModule", + String.Empty); + + if (gridService == String.Empty) + throw new Exception("No LocalServiceModule in config file"); + + Object[] args = new Object[] { config }; + m_MapService = ServerUtils.LoadPlugin(gridService, args); + + //server.AddStreamHandler(new PresenceServerPostHandler(m_PresenceService)); + } + } +} diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs new file mode 100644 index 0000000..9448af7 --- /dev/null +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs @@ -0,0 +1,105 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Net; +using System.Reflection; + +using Nini.Config; +using log4net; + +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; + +namespace OpenSim.Server.Handlers.MapImage +{ + public class MapGetServiceConnector : ServiceConnector + { + private IMapImageService m_MapService; + private string m_ConfigName = "MapImageService"; + + public MapGetServiceConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); + + string gridService = serverConfig.GetString("LocalServiceModule", + String.Empty); + + if (gridService == String.Empty) + throw new Exception("No LocalServiceModule in config file"); + + Object[] args = new Object[] { config }; + m_MapService = ServerUtils.LoadPlugin(gridService, args); + + server.AddStreamHandler(new MapServerGetHandler(m_MapService)); + } + } + + class MapServerGetHandler : BaseStreamHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IMapImageService m_MapService; + + public MapServerGetHandler(IMapImageService service) : + base("GET", "/map") + { + m_MapService = service; + } + + public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: retrieving {0}", path); + byte[] result = new byte[0]; + + string format = string.Empty; + result = m_MapService.GetMapTile(path.Trim('/'), out format); + + if (result.Length > 0) + { + httpResponse.StatusCode = (int)HttpStatusCode.OK; + if (format.Equals("png")) + httpResponse.ContentType = "image/png"; + else if (format.Equals("jpg") || format.Equals("jpeg")) + httpResponse.ContentType = "image/jpeg"; + } + else + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + httpResponse.ContentType = "text/plain"; + } + + return result; + } + + } +} diff --git a/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs new file mode 100644 index 0000000..ff0e9d9 --- /dev/null +++ b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs @@ -0,0 +1,158 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; + +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Services.Connectors +{ + public class MapImageServicesConnector : IMapImageService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + private IImprovedAssetCache m_Cache = null; + + public MapImageServicesConnector() + { + } + + public MapImageServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public MapImageServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig config = source.Configs["MapImageService"]; + if (config == null) + { + m_log.Error("[MAP IMAGE CONNECTOR]: MapImageService missing"); + throw new Exception("MapImage connector init error"); + } + + string serviceURI = config.GetString("MapImageServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[MAP IMAGE CONNECTOR]: No Server URI named in section MapImageService"); + throw new Exception("MapImage connector init error"); + } + m_ServerURI = serviceURI; + } + + public bool AddMapTile(int x, int y, byte[] pngData, out string reason) + { + List postParameters = new List() + { + new MultipartForm.Parameter("X", x.ToString()), + new MultipartForm.Parameter("Y", y.ToString()), + new MultipartForm.File("Tile", "tile.png", "image/png", pngData) + }; + + reason = string.Empty; + int tickstart = Util.EnvironmentTickCount(); + + // Make the remote storage request + try + { + HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_ServerURI); + request.Timeout = 20000; + request.ReadWriteTimeout = 5000; + + using (HttpWebResponse response = MultipartForm.Post(request, postParameters)) + { + using (Stream responseStream = response.GetResponseStream()) + { + string responseStr = responseStream.GetStreamString(); + OSD responseOSD = OSDParser.Deserialize(responseStr); + if (responseOSD.Type == OSDType.Map) + { + OSDMap responseMap = (OSDMap)responseOSD; + if (responseMap["Success"].AsBoolean()) + return true; + + reason = "Upload failed: " + responseMap["Message"].AsString(); + } + else + { + reason = "Response format was invalid:\n" + responseStr; + } + } + } + } + catch (WebException we) + { + reason = we.Message; + if (we.Status == WebExceptionStatus.ProtocolError) + { + HttpWebResponse webResponse = (HttpWebResponse)we.Response; + reason = String.Format("[{0}] {1}", webResponse.StatusCode, webResponse.StatusDescription); + } + } + catch (Exception ex) + { + reason = ex.Message; + } + finally + { + // This just dumps a warning for any operation that takes more than 100 ms + int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile uploaded in {0}ms", tickdiff); + } + + return false; + } + + public byte[] GetMapTile(string fileName, out string format) + { + format = string.Empty; + new Exception("GetMapTile method not Implemented"); + return null; + } + } +} diff --git a/OpenSim/Services/Interfaces/IMapImageService.cs b/OpenSim/Services/Interfaces/IMapImageService.cs new file mode 100644 index 0000000..a7b2cf1 --- /dev/null +++ b/OpenSim/Services/Interfaces/IMapImageService.cs @@ -0,0 +1,40 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Framework; +using System.Collections.Generic; +using OpenMetaverse; + +namespace OpenSim.Services.Interfaces +{ + public interface IMapImageService + { + //List GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY); + bool AddMapTile(int x, int y, byte[] imageData, out string reason); + byte[] GetMapTile(string fileName, out string format); + } +} diff --git a/OpenSim/Services/Interfaces/IMapService.cs b/OpenSim/Services/Interfaces/IMapService.cs deleted file mode 100644 index c70f484..0000000 --- a/OpenSim/Services/Interfaces/IMapService.cs +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using OpenSim.Framework; -using System.Collections.Generic; -using OpenMetaverse; - -namespace OpenSim.Services.Interfaces -{ - public interface IMapService - { - List GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY); - } -} diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs new file mode 100644 index 0000000..596c4a6 --- /dev/null +++ b/OpenSim/Services/MapImageService/MapImageService.cs @@ -0,0 +1,295 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Net; +using System.Reflection; + +using Nini.Config; +using log4net; +using OpenMetaverse; + +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Services.Interfaces; + + +namespace OpenSim.Services.MapImageService +{ + public class MapImageService : IMapImageService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private const int ZOOM_LEVELS = 8; + private const int IMAGE_WIDTH = 256; + private const int HALF_WIDTH = 128; + private const int JPEG_QUALITY = 80; + + private static string m_TilesStoragePath = "maptiles"; + + private static object m_Sync = new object(); + private static bool m_Initialized = false; + private static string m_WaterTileFile = string.Empty; + private static Color m_Watercolor = Color.FromArgb(29, 71, 95); + + public MapImageService(IConfigSource config) + { + if (!m_Initialized) + { + m_Initialized = true; + m_log.Debug("[MAP IMAGE SERVICE]: Starting MapImage service"); + + IConfig serviceConfig = config.Configs["MapImageService"]; + if (serviceConfig != null) + { + m_TilesStoragePath = serviceConfig.GetString("TilesStoragePath", m_TilesStoragePath); + if (!Directory.Exists(m_TilesStoragePath)) + Directory.CreateDirectory(m_TilesStoragePath); + + + m_WaterTileFile = Path.Combine(m_TilesStoragePath, "water.jpg"); + if (!File.Exists(m_WaterTileFile)) + { + Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); + FillImage(waterTile, m_Watercolor); + waterTile.Save(m_WaterTileFile); + } + } + } + } + + #region IMapImageService + + public bool AddMapTile(int x, int y, byte[] imageData, out string reason) + { + reason = string.Empty; + string fileName = GetFileName(1, x, y); + + lock (m_Sync) + { + try + { + using (FileStream f = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write)) + f.Write(imageData, 0, imageData.Length); + } + catch (Exception e) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to save image file {0}: {1}", fileName, e); + reason = e.Message; + return false; + } + + // Also save in png format? + + // Stitch seven more aggregate tiles together + for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++) + { + // Calculate the width (in full resolution tiles) and bottom-left + // corner of the current zoom level + int width = (int)Math.Pow(2, (double)(zoomLevel - 1)); + int x1 = x - (x % width); + int y1 = y - (y % width); + + if (!CreateTile(zoomLevel, x1, y1)) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0} at zoom level {1}", fileName, zoomLevel); + reason = string.Format("Map tile at zoom level {0} failed", zoomLevel); + return false; + } + } + } + + return true; + } + + public byte[] GetMapTile(string fileName, out string format) + { + format = "jpg"; + string fullName = Path.Combine(m_TilesStoragePath, fileName); + if (File.Exists(fullName)) + { + format = Path.GetExtension(fileName).ToLower(); + m_log.DebugFormat("[MAP IMAGE SERVICE]: Found file {0}, extension {1}", fileName, format); + return File.ReadAllBytes(fullName); + } + else if (File.Exists(m_WaterTileFile)) + { + m_log.DebugFormat("[MAP IMAGE SERVICE]: File not found {0}, sending water", fileName); + return File.ReadAllBytes(m_WaterTileFile); + } + else + { + m_log.DebugFormat("[MAP IMAGE SERVICE]: unable to get file {0}", fileName); + return new byte[0]; + } + } + + #endregion + + + private string GetFileName(uint zoomLevel, int x, int y) + { + string extension = "jpg"; + return Path.Combine(m_TilesStoragePath, string.Format("map-{0}-{1}-{2}-objects.{3}", zoomLevel, x, y, extension)); + } + + private Bitmap GetInputTileImage(string fileName) + { + try + { + if (File.Exists(fileName)) + return new Bitmap(fileName); + } + catch (Exception e) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to read image data from {0}: {1}", fileName, e); + } + + return null; + } + + private Bitmap GetOutputTileImage(string fileName) + { + try + { + if (File.Exists(fileName)) + return new Bitmap(fileName); + + else + { + // Create a new output tile with a transparent background + Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); + bm.MakeTransparent(); + return bm; + } + } + catch (Exception e) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to read image data from {0}: {1}", fileName, e); + } + + return null; + } + + private bool CreateTile(uint zoomLevel, int x, int y) + { + m_log.DebugFormat("[MAP IMAGE SERVICE]: Create tile for {0} {1}, zoom {2}", x, y, zoomLevel); + int prevWidth = (int)Math.Pow(2, (double)zoomLevel - 2); + int thisWidth = (int)Math.Pow(2, (double)zoomLevel - 1); + + // Convert x and y to the bottom left tile for this zoom level + int xIn = x - (x % prevWidth); + int yIn = y - (y % prevWidth); + + // Convert x and y to the bottom left tile for the next zoom level + int xOut = x - (x % thisWidth); + int yOut = y - (y % thisWidth); + + // Try to open the four input tiles from the previous zoom level + Bitmap inputBL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn)); + Bitmap inputBR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn)); + Bitmap inputTL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn + prevWidth)); + Bitmap inputTR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn + prevWidth)); + + // Open the output tile (current zoom level) + string outputFile = GetFileName(zoomLevel, xOut, yOut); + Bitmap output = GetOutputTileImage(outputFile); + if (output == null) + return false; + FillImage(output, m_Watercolor); + + if (inputBL != null) + { + ImageCopyResampled(output, inputBL, 0, HALF_WIDTH, 0, 0); + inputBL.Dispose(); + } + if (inputBR != null) + { + ImageCopyResampled(output, inputBR, HALF_WIDTH, HALF_WIDTH, 0, 0); + inputBR.Dispose(); + } + if (inputTL != null) + { + ImageCopyResampled(output, inputTL, 0, 0, 0, 0); + inputTL.Dispose(); + } + if (inputTR != null) + { + ImageCopyResampled(output, inputTR, HALF_WIDTH, 0, 0, 0); + inputTR.Dispose(); + } + + // Write the modified output + try + { + using (Bitmap final = new Bitmap(output)) + { + output.Dispose(); + final.Save(outputFile); + } + } + catch (Exception e) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Oops on saving {0} {1}", outputFile, e); + } + + // Save also as png? + + return true; + } + + #region Image utilities + + private void FillImage(Bitmap bm, Color c) + { + for (int x = 0; x < bm.Width; x++) + for (int y = 0; y < bm.Height; y++) + bm.SetPixel(x, y, c); + } + + private void ImageCopyResampled(Bitmap output, Bitmap input, int destX, int destY, int srcX, int srcY) + { + int resamplingRateX = 2; // (input.Width - srcX) / (output.Width - destX); + int resamplingRateY = 2; // (input.Height - srcY) / (output.Height - destY); + + for (int x = destX; x < destX + HALF_WIDTH; x++) + for (int y = destY; y < destY + HALF_WIDTH; y++) + { + Color p = input.GetPixel(srcX + (x - destX) * resamplingRateX, srcY + (y - destY) * resamplingRateY); + output.SetPixel(x, y, p); + } + } + + #endregion + } +} diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index 4ff1a26..bf89d0b 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -17,10 +17,12 @@ AvatarServices = "LocalAvatarServicesConnector" EntityTransferModule = "BasicEntityTransferModule" InventoryAccessModule = "BasicInventoryAccessModule" + MapImageService = "MapImageServiceModule" LibraryModule = true LLLoginServiceInConnector = true GridInfoServiceInConnector = true + MapImageServiceInConnector = true [Profile] Module = "BasicProfileModule" @@ -91,6 +93,11 @@ WelcomeMessage = "Welcome, Avatar!" +[MapImageService] + LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" + ; in minutes + RefreshTime = 60 + ;; This should always be the very last thing on this file [Includes] Include-Common = "config-include/StandaloneCommon.ini" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 7359bba..69349d2 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -99,6 +99,9 @@ SRV_FriendsServerURI = "http://127.0.0.1:9000" SRV_IMServerURI = "http://127.0.0.1:9000" + ;; For Viewer 2 + MapTileURL = "http://127.0.0.1:9000" + ;; Regular expressions for controlling which client versions are accepted/denied. ;; An empty string means nothing is checked. ;; diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 8480a77..719df5c 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -18,9 +18,10 @@ GridUserServices = "LocalGridUserServicesConnector" SimulationServices = "RemoteSimulationConnectorModule" AvatarServices = "LocalAvatarServicesConnector" + MapImageService = "MapImageServiceModule" EntityTransferModule = "HGEntityTransferModule" InventoryAccessModule = "HGInventoryAccessModule" - FriendsModule = "HGFriendsModule" + FriendsModule = "HGFriendsModule" InventoryServiceInConnector = true AssetServiceInConnector = true @@ -31,6 +32,7 @@ GridInfoServiceInConnector = true AuthenticationServiceInConnector = true SimulationServiceInConnector = true + MapImageServiceInConnector = true [Profile] Module = "BasicProfileModule" @@ -116,7 +118,12 @@ GridService = "OpenSim.Services.GridService.dll:GridService" AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" - + +[MapImageService] + LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" + ; in minutes + RefreshTime = 60 + [GatekeeperService] LocalServiceModule = "OpenSim.Services.HypergridService.dll:GatekeeperService" ;; for the service diff --git a/prebuild.xml b/prebuild.xml index 90f451d..ed79b40 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1269,6 +1269,36 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + -- cgit v1.1 From 78c16da5444a2e363de50bc88c8d2b929dec0989 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 17:05:45 -0700 Subject: A few bug fixes on map V2. Zoom level weirdness still there. --- .../CoreModules/World/WorldMap/WorldMapModule.cs | 18 ++++++++++++------ OpenSim/Server/Handlers/Map/MapGetServerConnector.cs | 5 ++--- OpenSim/Services/MapImageService/MapImageService.cs | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 079b1c2..6e142bb 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -836,7 +836,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap block.Access = 254; // means 'simulator is offline' response.Add(block); } - remoteClient.SendMapBlock(response, 0); + if ((flag & 2) == 2) // V2 !!! + remoteClient.SendMapBlock(response, 2); + else + remoteClient.SendMapBlock(response, 0); } else { @@ -849,17 +852,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - (minX - 8) * (int)Constants.RegionSize, - (maxX + 8) * (int)Constants.RegionSize, - (minY - 8) * (int)Constants.RegionSize, - (maxY + 8) * (int)Constants.RegionSize); + (minX - 4) * (int)Constants.RegionSize, + (maxX + 4) * (int)Constants.RegionSize, + (minY - 4) * (int)Constants.RegionSize, + (maxY + 4) * (int)Constants.RegionSize); foreach (GridRegion r in regions) { MapBlockData block = new MapBlockData(); MapBlockFromGridRegion(block, r); mapBlocks.Add(block); } - remoteClient.SendMapBlock(mapBlocks, 0); + if ((flag & 2) == 2) // V2 !!! + remoteClient.SendMapBlock(mapBlocks, 2); + else + remoteClient.SendMapBlock(mapBlocks, 0); return mapBlocks; } diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs index 9448af7..76dd695 100644 --- a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs @@ -83,13 +83,12 @@ namespace OpenSim.Server.Handlers.MapImage string format = string.Empty; result = m_MapService.GetMapTile(path.Trim('/'), out format); - if (result.Length > 0) { httpResponse.StatusCode = (int)HttpStatusCode.OK; - if (format.Equals("png")) + if (format.Equals(".png")) httpResponse.ContentType = "image/png"; - else if (format.Equals("jpg") || format.Equals("jpeg")) + else if (format.Equals(".jpg") || format.Equals(".jpeg")) httpResponse.ContentType = "image/jpeg"; } else diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs index 596c4a6..ee424e1 100644 --- a/OpenSim/Services/MapImageService/MapImageService.cs +++ b/OpenSim/Services/MapImageService/MapImageService.cs @@ -134,7 +134,7 @@ namespace OpenSim.Services.MapImageService public byte[] GetMapTile(string fileName, out string format) { - format = "jpg"; + format = ".jpg"; string fullName = Path.Combine(m_TilesStoragePath, fileName); if (File.Exists(fullName)) { -- cgit v1.1 From 07d7c1cd2d0d5ccf6d40a3616ecaeb565e9bfab4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 18:29:44 -0700 Subject: Trailing / in MapTileURL must be there! --- bin/config-include/StandaloneCommon.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 69349d2..29c2af1 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -100,7 +100,7 @@ SRV_IMServerURI = "http://127.0.0.1:9000" ;; For Viewer 2 - MapTileURL = "http://127.0.0.1:9000" + MapTileURL = "http://127.0.0.1:9000/" ;; Regular expressions for controlling which client versions are accepted/denied. ;; An empty string means nothing is checked. -- cgit v1.1 From 2e77518c6dd5f06c965df758ebd0a20a39c96dc8 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 21:51:26 -0700 Subject: bit depth: 24!!! begeez! -- zoom levels work now. --- OpenSim/Server/Handlers/Map/MapGetServerConnector.cs | 4 +++- OpenSim/Services/MapImageService/MapImageService.cs | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs index 76dd695..53d08fa 100644 --- a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs @@ -42,11 +42,13 @@ namespace OpenSim.Server.Handlers.MapImage { public class MapGetServiceConnector : ServiceConnector { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IMapImageService m_MapService; + private string m_ConfigName = "MapImageService"; public MapGetServiceConnector(IConfigSource config, IHttpServer server, string configName) : - base(config, server, configName) + base(config, server, configName) { IConfig serverConfig = config.Configs[m_ConfigName]; if (serverConfig == null) diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs index ee424e1..736fa2e 100644 --- a/OpenSim/Services/MapImageService/MapImageService.cs +++ b/OpenSim/Services/MapImageService/MapImageService.cs @@ -144,7 +144,6 @@ namespace OpenSim.Services.MapImageService } else if (File.Exists(m_WaterTileFile)) { - m_log.DebugFormat("[MAP IMAGE SERVICE]: File not found {0}, sending water", fileName); return File.ReadAllBytes(m_WaterTileFile); } else @@ -188,7 +187,7 @@ namespace OpenSim.Services.MapImageService else { // Create a new output tile with a transparent background - Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); + Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH, PixelFormat.Format24bppRgb); bm.MakeTransparent(); return bm; } @@ -255,7 +254,7 @@ namespace OpenSim.Services.MapImageService using (Bitmap final = new Bitmap(output)) { output.Dispose(); - final.Save(outputFile); + final.Save(outputFile, ImageFormat.Jpeg); } } catch (Exception e) -- cgit v1.1 From 95e050130c42c21ca4f26b31abce1c4a83194525 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 22:10:16 -0700 Subject: People are bound to forget the '/' at the end of MapTileURL, so let's correct that from the inside. --- OpenSim/Services/LLLoginService/LLLoginService.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 5d1779a..2b15896 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -112,6 +112,14 @@ namespace OpenSim.Services.LLLoginService m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty); m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty); + // Clean up some of these vars + if (m_MapTileURL != String.Empty) + { + m_MapTileURL = m_MapTileURL.Trim(); + if (!m_MapTileURL.EndsWith("/")) + m_MapTileURL = m_MapTileURL + "/"; + } + // These are required; the others aren't if (accountService == string.Empty || authService == string.Empty) throw new Exception("LoginService is missing service specifications"); -- cgit v1.1 From 4b9de140ab9aa9312219610de68138c4288b840a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 22:25:30 -0700 Subject: Add credit and link to SimianGrid project. Thanks, guys! --- OpenSim/Services/MapImageService/MapImageService.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs index 736fa2e..27722bb 100644 --- a/OpenSim/Services/MapImageService/MapImageService.cs +++ b/OpenSim/Services/MapImageService/MapImageService.cs @@ -23,6 +23,10 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The design of this map service is based on SimianGrid's PHP-based + * map service. See this URL for the original PHP version: + * https://github.com/openmetaversefoundation/simiangrid/ */ using System; -- cgit v1.1 From dc978d02a723440a3860da0ad6a2b61b09769f39 Mon Sep 17 00:00:00 2001 From: Michael Cerquoni aka Nebadon Izumi Date: Mon, 13 Jun 2011 03:46:24 -0700 Subject: match water color for warp3d map tiler and adjust lighting --- OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs index 6eb57eb..6163fd1 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs @@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule { private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); - private static readonly Color4 WATER_COLOR = new Color4(29, 71, 95, 216); + private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap private IRendering m_primMesher; private IConfigSource m_config; private Dictionary m_colors = new Dictionary(); - private bool m_useAntiAliasing = true; // TODO: Make this a config option + private bool m_useAntiAliasing = false; // TODO: Make this a config option private bool m_Enabled = false; #region IRegionModule Members @@ -192,8 +192,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap #endregion Camera - renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(0.2f, 0.2f, 1f), 0xffffff, 320, 80)); - renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 100, 40)); + renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(1.0f, 0.5f, 1f), 0xffffff, 0, 320, 40)); + renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 0, 100, 40)); CreateWater(renderer); CreateTerrain(renderer, textureTerrain); @@ -237,6 +237,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f); renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR)); + renderer.Scene.material("WaterColor").setReflectivity(0); // match water color with standard map module thanks lkalif renderer.Scene.material("WaterColor").setTransparency((byte)((1f - WATER_COLOR.A) * 255f)); renderer.SetObjectMaterial("Water", "WaterColor"); } @@ -322,6 +323,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap warp_Material material = new warp_Material(texture); material.setReflectivity(50); renderer.Scene.addMaterial("TerrainColor", material); + renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif renderer.SetObjectMaterial("Terrain", "TerrainColor"); } @@ -653,4 +655,4 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap return result; } } -} +} \ No newline at end of file -- cgit v1.1 From 0e4db3ca3911d8ac7080f51931ffe71b388e7180 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 13 Jun 2011 07:56:52 -0700 Subject: Added experimental new capability URL called MapImageService meant to work with Kokua viewer if devs are willing to do it. --- .../ClientStack/Linden/Caps/MiscCapsModule.cs | 119 +++++++++++++++++++++ bin/OpenSim.ini.example | 5 + 2 files changed, 124 insertions(+) create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs new file mode 100644 index 0000000..d084a73 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs @@ -0,0 +1,119 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Reflection; +using log4net; +using Nini.Config; +using Mono.Addins; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; +using OpenSim.Capabilities.Handlers; + +namespace OpenSim.Region.ClientStack.Linden +{ + /// + /// A module to place miscellaneous capabilities + /// + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MiscCapsModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; + + private bool m_Enabled = false; + private string m_MapImageServerURL; + + #region ISharedRegionModule Members + + public void Initialise(IConfigSource source) + { + m_Enabled = true; + IConfig config = source.Configs["ClientStack.LindenCaps"]; + if (config == null) + return; + + m_MapImageServerURL = config.GetString("Cap_MapImageService", string.Empty); + } + + public void AddRegion(Scene s) + { + if (!m_Enabled) + return; + + m_scene = s; + } + + public void RemoveRegion(Scene s) + { + if (!m_Enabled) + return; + + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; + m_scene = null; + } + + public void RegionLoaded(Scene s) + { + if (!m_Enabled) + return; + + m_scene.EventManager.OnRegisterCaps += RegisterCaps; + } + + public void PostInitialise() + { + } + + public void Close() { } + + public string Name { get { return "MiscCapsModule"; } } + + public Type ReplaceableInterface + { + get { return null; } + } + + #endregion + + public void RegisterCaps(UUID agentID, Caps caps) + { + m_log.InfoFormat("[MISC CAPS MODULE]: {0} in region {1}", m_MapImageServerURL, m_scene.RegionInfo.RegionName); + if (m_MapImageServerURL != string.Empty) + caps.RegisterHandler("MapImageService", m_MapImageServerURL); + } + + } +} diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 813c5b8..a9ce284 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -306,6 +306,11 @@ ; This is disabled by default. Change if you see fit. Note that ; serving this cap from the simulators may lead to poor performace. Cap_WebFetchInventoryDescendents = "" + ; Experimental new capability for Kokua viewers meant to override + ; the MapImage server url given at login, and varying switching on + ; a sim-basis (as it should). + ; Viewers that don't understand it, will ignore it + Cap_MapImageService = "http://127.0.0.1:9000/ [Chat] ;# {whisper_distance} {} {Distance at which a whisper is heard, in meters?} {} 10 -- cgit v1.1 From ab11835aeb341a34f479d9a6eb18de1ca9500c4a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 13 Jun 2011 07:59:28 -0700 Subject: Same processing of the "/" in the MapImageService Cap as the one in the login service. --- OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs index d084a73..3dcd1e3 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs @@ -66,6 +66,12 @@ namespace OpenSim.Region.ClientStack.Linden return; m_MapImageServerURL = config.GetString("Cap_MapImageService", string.Empty); + if (m_MapImageServerURL != string.Empty) + { + m_MapImageServerURL = m_MapImageServerURL.Trim(); + if (!m_MapImageServerURL.EndsWith("/")) + m_MapImageServerURL = m_MapImageServerURL + "/"; + } } public void AddRegion(Scene s) -- cgit v1.1 From ecb28ae130d1fc212c72af887fc75ae2bf64ab97 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 13 Jun 2011 09:13:44 -0700 Subject: V2 map now working in grids too. WARNING: A few visible configuration variables added in order for this to work. See .ini.example changes --- .../Server/Handlers/Map/MapAddServerConnector.cs | 124 ++++++++++++++++++++- .../Server/Handlers/Map/MapGetServerConnector.cs | 1 - .../MapImage/MapImageServiceConnector.cs | 81 +++++++------- .../Services/MapImageService/MapImageService.cs | 2 +- bin/Robust.HG.ini.example | 8 +- bin/Robust.ini.example | 9 +- bin/config-include/Grid.ini | 6 + bin/config-include/GridCommon.ini.example | 3 + bin/config-include/GridHypergrid.ini | 8 +- 9 files changed, 193 insertions(+), 49 deletions(-) diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs index a953cd7..99f98b6 100644 --- a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -26,7 +26,14 @@ */ using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Xml; + using Nini.Config; +using log4net; + using OpenSim.Server.Base; using OpenSim.Services.Interfaces; using OpenSim.Framework.Servers.HttpServer; @@ -55,7 +62,122 @@ namespace OpenSim.Server.Handlers.MapImage Object[] args = new Object[] { config }; m_MapService = ServerUtils.LoadPlugin(gridService, args); - //server.AddStreamHandler(new PresenceServerPostHandler(m_PresenceService)); + server.AddStreamHandler(new MapServerPostHandler(m_MapService)); + } + } + + class MapServerPostHandler : BaseStreamHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IMapImageService m_MapService; + + public MapServerPostHandler(IMapImageService service) : + base("POST", "/map") + { + m_MapService = service; + } + + public override byte[] Handle(string path, Stream requestData, OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: Received {0}", path); + StreamReader sr = new StreamReader(requestData); + string body = sr.ReadToEnd(); + sr.Close(); + body = body.Trim(); + + try + { + Dictionary request = ServerUtils.ParseQueryString(body); + + if (!request.ContainsKey("X") || !request.ContainsKey("Y") || !request.ContainsKey("DATA")) + { + httpResponse.StatusCode = (int)OSHttpStatusCode.ClientErrorBadRequest; + return FailureResult("Bad request."); + } + int x = 0, y = 0; + Int32.TryParse(request["X"].ToString(), out x); + Int32.TryParse(request["Y"].ToString(), out y); + string type = "image/jpeg"; + if (request.ContainsKey("TYPE")) + type = request["TYPE"].ToString(); + byte[] data = Convert.FromBase64String(request["DATA"].ToString()); + + string reason = string.Empty; + bool result = m_MapService.AddMapTile(x, y, data, out reason); + + if (result) + return SuccessResult(); + else + return FailureResult(reason); + + } + catch (Exception e) + { + m_log.ErrorFormat("[MAP SERVICE IMAGE HANDLER]: Exception {0} {1}", e.Message, e.StackTrace); + } + + return FailureResult("Unexpected server error"); + + } + + private byte[] SuccessResult() + { + XmlDocument doc = new XmlDocument(); + + XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, + "", ""); + + doc.AppendChild(xmlnode); + + XmlElement rootElement = doc.CreateElement("", "ServerResponse", + ""); + + doc.AppendChild(rootElement); + + XmlElement result = doc.CreateElement("", "Result", ""); + result.AppendChild(doc.CreateTextNode("Success")); + + rootElement.AppendChild(result); + + return DocToBytes(doc); + } + + private byte[] FailureResult(string msg) + { + XmlDocument doc = new XmlDocument(); + + XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, + "", ""); + + doc.AppendChild(xmlnode); + + XmlElement rootElement = doc.CreateElement("", "ServerResponse", + ""); + + doc.AppendChild(rootElement); + + XmlElement result = doc.CreateElement("", "Result", ""); + result.AppendChild(doc.CreateTextNode("Failure")); + + rootElement.AppendChild(result); + + XmlElement message = doc.CreateElement("", "Message", ""); + message.AppendChild(doc.CreateTextNode(msg)); + + rootElement.AppendChild(message); + + return DocToBytes(doc); + } + + private byte[] DocToBytes(XmlDocument doc) + { + MemoryStream ms = new MemoryStream(); + XmlTextWriter xw = new XmlTextWriter(ms, null); + xw.Formatting = Formatting.Indented; + doc.WriteTo(xw); + xw.Flush(); + + return ms.ToArray(); } } } diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs index 53d08fa..e8a424f 100644 --- a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs @@ -80,7 +80,6 @@ namespace OpenSim.Server.Handlers.MapImage public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { - m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: retrieving {0}", path); byte[] result = new byte[0]; string format = string.Empty; diff --git a/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs index ff0e9d9..520d639 100644 --- a/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs +++ b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs @@ -36,6 +36,7 @@ using Nini.Config; using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Framework.Communications; +using OpenSim.Server.Base; using OpenSim.Services.Interfaces; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -83,60 +84,57 @@ namespace OpenSim.Services.Connectors throw new Exception("MapImage connector init error"); } m_ServerURI = serviceURI; + m_ServerURI = serviceURI.TrimEnd('/'); } - public bool AddMapTile(int x, int y, byte[] pngData, out string reason) + public bool AddMapTile(int x, int y, byte[] jpgData, out string reason) { - List postParameters = new List() - { - new MultipartForm.Parameter("X", x.ToString()), - new MultipartForm.Parameter("Y", y.ToString()), - new MultipartForm.File("Tile", "tile.png", "image/png", pngData) - }; - - reason = string.Empty; + reason = string.Empty; int tickstart = Util.EnvironmentTickCount(); + Dictionary sendData = new Dictionary(); + sendData["X"] = x.ToString(); + sendData["Y"] = y.ToString(); + sendData["TYPE"] = "image/jpeg"; + sendData["DATA"] = Convert.ToBase64String(jpgData); + + string reqString = ServerUtils.BuildQueryString(sendData); - // Make the remote storage request try { - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_ServerURI); - request.Timeout = 20000; - request.ReadWriteTimeout = 5000; - - using (HttpWebResponse response = MultipartForm.Post(request, postParameters)) + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/map", + reqString); + if (reply != string.Empty) { - using (Stream responseStream = response.GetResponseStream()) + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "success")) { - string responseStr = responseStream.GetStreamString(); - OSD responseOSD = OSDParser.Deserialize(responseStr); - if (responseOSD.Type == OSDType.Map) - { - OSDMap responseMap = (OSDMap)responseOSD; - if (responseMap["Success"].AsBoolean()) - return true; - - reason = "Upload failed: " + responseMap["Message"].AsString(); - } - else - { - reason = "Response format was invalid:\n" + responseStr; - } + return true; } + else if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "failure")) + { + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Registration failed: {0}", replyData["Message"].ToString()); + reason = replyData["Message"].ToString(); + return false; + } + else if (!replyData.ContainsKey("Result")) + { + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: reply data does not contain result field"); + } + else + { + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: unexpected result {0}", replyData["Result"].ToString()); + reason = "Unexpected result " + replyData["Result"].ToString(); + } + } + else + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: RegisterRegion received null reply"); } - catch (WebException we) - { - reason = we.Message; - if (we.Status == WebExceptionStatus.ProtocolError) - { - HttpWebResponse webResponse = (HttpWebResponse)we.Response; - reason = String.Format("[{0}] {1}", webResponse.StatusCode, webResponse.StatusDescription); - } - } - catch (Exception ex) + catch (Exception e) { - reason = ex.Message; + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Exception when contacting grid server: {0}", e.Message); } finally { @@ -146,6 +144,7 @@ namespace OpenSim.Services.Connectors } return false; + } public byte[] GetMapTile(string fileName, out string format) diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs index 27722bb..7e7391c 100644 --- a/OpenSim/Services/MapImageService/MapImageService.cs +++ b/OpenSim/Services/MapImageService/MapImageService.cs @@ -143,7 +143,7 @@ namespace OpenSim.Services.MapImageService if (File.Exists(fullName)) { format = Path.GetExtension(fileName).ToLower(); - m_log.DebugFormat("[MAP IMAGE SERVICE]: Found file {0}, extension {1}", fileName, format); + //m_log.DebugFormat("[MAP IMAGE SERVICE]: Found file {0}, extension {1}", fileName, format); return File.ReadAllBytes(fullName); } else if (File.Exists(m_WaterTileFile)) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 812d265..00ece88 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -21,7 +21,7 @@ ; * [[@]/][:] ; * [Startup] -ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector,8002/OpenSim.Server.Handlers.dll:HGFriendsServerConnector,8002/OpenSim.Server.Handlers.dll:InstantMessageServerConnector" +ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector,8002/OpenSim.Server.Handlers.dll:HGFriendsServerConnector,8002/OpenSim.Server.Handlers.dll:InstantMessageServerConnector,8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector,8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector" ; * This is common for all services, it's the network setup for the entire ; * server instance, if none is specified above @@ -206,6 +206,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 WelcomeMessage = "Welcome, Avatar!" AllowRemoteSetLoginLevel = "false" + ; For V2 map + ; MapTileURL = "http://127.0.0.1:8002"; + ; If you run this login server behind a proxy, set this to true ; HasProxy = false @@ -237,6 +240,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ;AllowedClients = "" ;DeniedClients = "" +[MapImageService] + LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" + [GridInfoService] ; These settings are used to return information on a get_grid_info call. ; Client launcher scripts and third-party clients make use of this to diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 5d0ec09..e29e9db 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -13,7 +13,7 @@ ; * [[@]/][:] ; * [Startup] -ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector" +ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector,8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector" ; * This is common for all services, it's the network setup for the entire ; * server instance, if none is specified above @@ -191,8 +191,8 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 WelcomeMessage = "Welcome, Avatar!" AllowRemoteSetLoginLevel = "false" - ; For snowglobe's web map - ; MapTileURL = ""; + ; For V2 map + ; MapTileURL = "http://127.0.0.1:8002"; ; If you run this login server behind a proxy, set this to true ; HasProxy = false @@ -214,6 +214,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ;AllowedClients = "" ;DeniedClients = "" +[MapImageService] + LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" + [GridInfoService] ; These settings are used to return information on a get_grid_info call. ; Client launcher scripts and third-party clients make use of this to diff --git a/bin/config-include/Grid.ini b/bin/config-include/Grid.ini index 5220573..da860c6 100644 --- a/bin/config-include/Grid.ini +++ b/bin/config-include/Grid.ini @@ -21,6 +21,7 @@ EntityTransferModule = "BasicEntityTransferModule" InventoryAccessModule = "BasicInventoryAccessModule" LandServices = "RemoteLandServicesConnector" + MapImageService = "MapImageServiceModule" LandServiceInConnector = true NeighbourServiceInConnector = true @@ -50,3 +51,8 @@ [Friends] Connector = "OpenSim.Services.Connectors.dll:FriendsServicesConnector" + +[MapImageService] + LocalServiceModule = "OpenSim.Services.Connectors.dll:MapImageServicesConnector" + ; in minutes + RefreshTime = 60 diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index 27f262f..4eb6fcf 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -116,6 +116,9 @@ ; UserAgentServerURI = "http://mygridserver.com:8002" +[MapImageService] + MapImageServerURI = "http://mygridserver.com:8003" + [Modules] ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. ;; Copy the config .example file into your own .ini file and change configs there diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index b8e66c2..60a3c62 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -25,6 +25,7 @@ InventoryAccessModule = "HGInventoryAccessModule" LandServices = "RemoteLandServicesConnector" FriendsModule = "HGFriendsModule" + MapImageService = "MapImageServiceModule" LandServiceInConnector = true NeighbourServiceInConnector = true @@ -76,4 +77,9 @@ LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService" GridService = "OpenSim.Services.Connectors.dll:GridServicesConnector" PresenceService = "OpenSim.Services.Connectors.dll:PresenceServicesConnector" - UserAgentService = "OpenSim.Services.Connectors.dll:UserAgentServiceConnector" \ No newline at end of file + UserAgentService = "OpenSim.Services.Connectors.dll:UserAgentServiceConnector" + +[MapImageService] + LocalServiceModule = "OpenSim.Services.Connectors.dll:MapImageServicesConnector" + ; in minutes + RefreshTime = 60 -- cgit v1.1 From 822b9e085fca9dcf04e61b29b98daeecf7893d85 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 13 Jun 2011 10:21:29 -0700 Subject: Added SimulatorFeatures capability. Thanks Aurora devs for the bootstrap on the contents of the response. Changed the experimental capability introduced a couple of commits ago: now sending that extra information as part of the response in the SimulatorFeatures cap. --- .../ClientStack/Linden/Caps/MiscCapsModule.cs | 125 ----------------- .../Linden/Caps/SimulatorFeaturesModule.cs | 152 +++++++++++++++++++++ bin/OpenSim.ini.example | 11 +- 3 files changed, 159 insertions(+), 129 deletions(-) delete mode 100644 OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs deleted file mode 100644 index 3dcd1e3..0000000 --- a/OpenSim/Region/ClientStack/Linden/Caps/MiscCapsModule.cs +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Reflection; -using log4net; -using Nini.Config; -using Mono.Addins; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; -using Caps = OpenSim.Framework.Capabilities.Caps; -using OpenSim.Capabilities.Handlers; - -namespace OpenSim.Region.ClientStack.Linden -{ - /// - /// A module to place miscellaneous capabilities - /// - /// - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class MiscCapsModule : INonSharedRegionModule - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene; - - private bool m_Enabled = false; - private string m_MapImageServerURL; - - #region ISharedRegionModule Members - - public void Initialise(IConfigSource source) - { - m_Enabled = true; - IConfig config = source.Configs["ClientStack.LindenCaps"]; - if (config == null) - return; - - m_MapImageServerURL = config.GetString("Cap_MapImageService", string.Empty); - if (m_MapImageServerURL != string.Empty) - { - m_MapImageServerURL = m_MapImageServerURL.Trim(); - if (!m_MapImageServerURL.EndsWith("/")) - m_MapImageServerURL = m_MapImageServerURL + "/"; - } - } - - public void AddRegion(Scene s) - { - if (!m_Enabled) - return; - - m_scene = s; - } - - public void RemoveRegion(Scene s) - { - if (!m_Enabled) - return; - - m_scene.EventManager.OnRegisterCaps -= RegisterCaps; - m_scene = null; - } - - public void RegionLoaded(Scene s) - { - if (!m_Enabled) - return; - - m_scene.EventManager.OnRegisterCaps += RegisterCaps; - } - - public void PostInitialise() - { - } - - public void Close() { } - - public string Name { get { return "MiscCapsModule"; } } - - public Type ReplaceableInterface - { - get { return null; } - } - - #endregion - - public void RegisterCaps(UUID agentID, Caps caps) - { - m_log.InfoFormat("[MISC CAPS MODULE]: {0} in region {1}", m_MapImageServerURL, m_scene.RegionInfo.RegionName); - if (m_MapImageServerURL != string.Empty) - caps.RegisterHandler("MapImageService", m_MapImageServerURL); - } - - } -} diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs new file mode 100644 index 0000000..9f78948 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -0,0 +1,152 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Reflection; +using log4net; +using Nini.Config; +using Mono.Addins; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.ClientStack.Linden +{ + /// + /// SimulatorFeatures capability. This is required for uploading Mesh. + /// Since is accepts an open-ended response, we also send more information + /// for viewers that care to interpret it. + /// + /// NOTE: Part of this code was adapted from the Aurora project, specifically + /// the normal part of the response in the capability handler. + /// + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimulatorFeaturesModule : ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; + + private string m_MapImageServerURL = string.Empty; + private string m_SearchURL = string.Empty; + + #region ISharedRegionModule Members + + public void Initialise(IConfigSource source) + { + IConfig config = source.Configs["SimulatorFeatures"]; + if (config == null) + return; + + m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty); + if (m_MapImageServerURL != string.Empty) + { + m_MapImageServerURL = m_MapImageServerURL.Trim(); + if (!m_MapImageServerURL.EndsWith("/")) + m_MapImageServerURL = m_MapImageServerURL + "/"; + } + + m_SearchURL = config.GetString("SearchServerURI", string.Empty); + } + + public void AddRegion(Scene s) + { + m_scene = s; + m_scene.EventManager.OnRegisterCaps += RegisterCaps; + } + + public void RemoveRegion(Scene s) + { + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; + } + + public void RegionLoaded(Scene s) + { + } + + public void PostInitialise() + { + } + + public void Close() { } + + public string Name { get { return "SimulatorFeaturesModule"; } } + + public Type ReplaceableInterface + { + get { return null; } + } + + #endregion + + public void RegisterCaps(UUID agentID, Caps caps) + { + IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), SimulatorFeatures); + caps.RegisterHandler("SimulatorFeatures", reqHandler); + } + + private Hashtable SimulatorFeatures(Hashtable mDhttpMethod) + { + m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request"); + OSDMap data = new OSDMap(); + data["MeshRezEnabled"] = true; + data["MeshUploadEnabled"] = true; + data["MeshXferEnabled"] = true; + data["PhysicsMaterialsEnabled"] = true; + + OSDMap typesMap = new OSDMap(); + typesMap["convex"] = true; + typesMap["none"] = true; + typesMap["prim"] = true; + data["PhysicsShapeTypes"] = typesMap; + + // Extra information for viewers that want to use it + OSDMap gridServicesMap = new OSDMap(); + if (m_MapImageServerURL != string.Empty) + gridServicesMap["map-server-url"] = m_MapImageServerURL; + if (m_SearchURL != string.Empty) + gridServicesMap["search"] = m_SearchURL; + data["GridServices"] = gridServicesMap; + + //Send back data + Hashtable responsedata = new Hashtable(); + responsedata["int_response_code"] = 200; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data); + return responsedata; + } + + } +} diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index a9ce284..bab118f 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -306,11 +306,14 @@ ; This is disabled by default. Change if you see fit. Note that ; serving this cap from the simulators may lead to poor performace. Cap_WebFetchInventoryDescendents = "" - ; Experimental new capability for Kokua viewers meant to override - ; the MapImage server url given at login, and varying switching on - ; a sim-basis (as it should). + +[SimulatorFeatures] + ; Experimental new information sent in SimulatorFeatures cap for Kokua viewers + ; meant to override the MapImage and search server url given at login, and varying + ; on a sim-basis. ; Viewers that don't understand it, will ignore it - Cap_MapImageService = "http://127.0.0.1:9000/ + ;MapImageServerURI = "http://127.0.0.1:9000/ + ;SearchServerURI = "http://127.0.0.1:9000/ [Chat] ;# {whisper_distance} {} {Distance at which a whisper is heard, in meters?} {} 10 -- cgit v1.1 From 603dbea190de26dce5160f5ab9730ffc1375ec26 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 14 Jun 2011 00:51:18 +0100 Subject: tweak messages. Make verbose inventory item save message give the item name as well as item id and asset id --- .../Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | 4 +++- OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index c2ad079..36ecb3b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -147,7 +147,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary options, IUserAccountService userAccountService) { if (options.ContainsKey("verbose")) - m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving item {0} with asset {1}", inventoryItem.ID, inventoryItem.AssetID); + m_log.InfoFormat( + "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}", + inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID); string filename = path + CreateArchiveItemName(inventoryItem); diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index 3078ab3..6a9c3d0 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs @@ -198,11 +198,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_log.ErrorFormat( "[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT); - m_log.Error("[ARCHIVER]: OAR save aborted. PLEASE DO NOT USE THIS OAR, IT WILL BE INCOMPLETE."); + m_log.Error("[ARCHIVER]: Archive save aborted. PLEASE DO NOT USE THIS ARCHIVE, IT WILL BE INCOMPLETE."); } catch (Exception e) { - m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}", e); + m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}{1}", e.Message, e.StackTrace); } finally { -- cgit v1.1 From bbe489e64a4c1bfdae591f3b6cf60ee0b1809176 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 15 Jun 2011 11:11:14 -0700 Subject: Added missing config var for map image service. --- bin/Robust.HG.ini.example | 2 ++ bin/Robust.ini.example | 3 +++ bin/config-include/StandaloneCommon.ini.example | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 00ece88..ea271b8 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -242,6 +242,8 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 [MapImageService] LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" + ; Set this if you want to change the default + ; TilesStoragePath = "maptiles" [GridInfoService] ; These settings are used to return information on a get_grid_info call. diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index e29e9db..14f79aa 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -216,6 +216,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 [MapImageService] LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" + ; Set this if you want to change the default + ; TilesStoragePath = "maptiles" + [GridInfoService] ; These settings are used to return information on a get_grid_info call. diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 29c2af1..cbe3fa0 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -223,3 +223,7 @@ ; password help: optional: page providing password assistance for users of your grid ; currently unused ;password = http://127.0.0.1/password + +[MapImageService] + ; Set this if you want to change the default + ; TilesStoragePath = "maptiles" -- cgit v1.1 From 7a4fbdac7c18415d442f6af0b75fe8fcdc2eb509 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 15 Jun 2011 11:22:51 -0700 Subject: Added an expiring cache for region information to the RemoteGridService connector. Timeout is currently set at five minutes. Negative results are not cached. The result is that operations like send an instant message do not have to go through the grid service every time. --- .../ServiceConnectorsOut/Grid/RegionInfoCache.cs | 137 +++++++++++++++++++++ .../Grid/RemoteGridServiceConnector.cs | 34 ++++- 2 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs new file mode 100644 index 0000000..786e0b5 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs @@ -0,0 +1,137 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Reflection; +using System.Collections.Generic; +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenMetaverse; +using log4net; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid +{ + public class RegionInfoCache + { + private const double CACHE_EXPIRATION_SECONDS = 300.0; // 5 minutes + +// private static readonly ILog m_log = +// LogManager.GetLogger( +// MethodBase.GetCurrentMethod().DeclaringType); + + internal struct ScopedRegionUUID + { + public UUID m_scopeID; + public UUID m_regionID; + public ScopedRegionUUID(UUID scopeID, UUID regionID) + { + m_scopeID = scopeID; + m_regionID = regionID; + } + } + + internal struct ScopedRegionName + { + public UUID m_scopeID; + public string m_name; + public ScopedRegionName(UUID scopeID, string name) + { + m_scopeID = scopeID; + m_name = name; + } + } + + private ExpiringCache m_UUIDCache; + private ExpiringCache m_NameCache; + + public RegionInfoCache() + { + m_UUIDCache = new ExpiringCache(); + m_NameCache = new ExpiringCache(); + } + + public void Cache(GridRegion rinfo) + { + if (rinfo != null) + this.Cache(rinfo.ScopeID,rinfo.RegionID,rinfo); + } + + public void Cache(UUID scopeID, UUID regionID, GridRegion rinfo) + { + // for now, do not cache negative results; this is because + // we need to figure out how to handle regions coming online + // in a timely way + if (rinfo == null) + return; + + ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID); + + // Cache even null accounts + m_UUIDCache.AddOrUpdate(id, rinfo, CACHE_EXPIRATION_SECONDS); + if (rinfo != null) + { + ScopedRegionName name = new ScopedRegionName(scopeID,rinfo.RegionName); + m_NameCache.AddOrUpdate(name, id, CACHE_EXPIRATION_SECONDS); + } + } + + public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache) + { + inCache = false; + + GridRegion rinfo = null; + ScopedRegionUUID id = new ScopedRegionUUID(scopeID,regionID); + if (m_UUIDCache.TryGetValue(id, out rinfo)) + { + inCache = true; + return rinfo; + } + + return null; + } + + public GridRegion Get(UUID scopeID, string name, out bool inCache) + { + inCache = false; + + ScopedRegionName sname = new ScopedRegionName(scopeID,name); + + ScopedRegionUUID id; + if (m_NameCache.TryGetValue(sname, out id)) + { + GridRegion rinfo = null; + if (m_UUIDCache.TryGetValue(id, out rinfo)) + { + inCache = true; + return rinfo; + } + } + + return null; + } + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs index 33cc838..6f364ae 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs @@ -53,6 +53,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid private IGridService m_LocalGridService; private IGridService m_RemoteGridService; + private RegionInfoCache m_RegionInfoCache = new RegionInfoCache(); + public RemoteGridServicesConnector() { } @@ -169,10 +171,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) { - GridRegion rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID); + bool inCache = false; + GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionID,out inCache); + if (inCache) + return rinfo; + + rinfo = m_LocalGridService.GetRegionByUUID(scopeID, regionID); if (rinfo == null) rinfo = m_RemoteGridService.GetRegionByUUID(scopeID, regionID); + m_RegionInfoCache.Cache(scopeID,regionID,rinfo); return rinfo; } @@ -187,10 +195,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public GridRegion GetRegionByName(UUID scopeID, string regionName) { - GridRegion rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName); + bool inCache = false; + GridRegion rinfo = m_RegionInfoCache.Get(scopeID,regionName, out inCache); + if (inCache) + return rinfo; + + rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName); if (rinfo == null) rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName); + // can't cache negative results for name lookups + m_RegionInfoCache.Cache(rinfo); return rinfo; } @@ -204,8 +219,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionsByName {0} found {1} regions", name, grinfo.Count); foreach (GridRegion r in grinfo) + { + m_RegionInfoCache.Cache(r); if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) rinfo.Add(r); + } } return rinfo; @@ -221,8 +239,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetRegionRange {0} found {1} regions", name, grinfo.Count); foreach (GridRegion r in grinfo) + { + m_RegionInfoCache.Cache(r); if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) rinfo.Add(r); + } } return rinfo; @@ -238,8 +259,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultRegions {0} found {1} regions", name, grinfo.Count); foreach (GridRegion r in grinfo) + { + m_RegionInfoCache.Cache(r); if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) rinfo.Add(r); + } } return rinfo; @@ -255,8 +279,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetFallbackRegions {0} found {1} regions", name, grinfo.Count); foreach (GridRegion r in grinfo) + { + m_RegionInfoCache.Cache(r); if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) rinfo.Add(r); + } } return rinfo; @@ -272,8 +299,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetHyperlinks {0} found {1} regions", name, grinfo.Count); foreach (GridRegion r in grinfo) + { + m_RegionInfoCache.Cache(r); if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) rinfo.Add(r); + } } return rinfo; -- cgit v1.1 From 29da57e3802948bbffce43c071e6c97742cabf84 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 15 Jun 2011 11:26:45 -0700 Subject: Add the PhysActor to the correct SOP when duplicating a physical prim. Thanks, MisterBlue --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 79660a3..f745169 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1449,18 +1449,23 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in partList) { + SceneObjectPart newPart; if (part.UUID != m_rootPart.UUID) { - SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); + newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); newPart.LinkNum = part.LinkNum; } + else + { + newPart = dupe.m_rootPart; + } // Need to duplicate the physics actor as well if (part.PhysActor != null && userExposed) { PrimitiveBaseShape pbs = part.Shape; - part.PhysActor + newPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( string.Format("{0}/{1}", part.Name, part.UUID), pbs, @@ -1469,8 +1474,8 @@ namespace OpenSim.Region.Framework.Scenes part.RotationOffset, part.PhysActor.IsPhysical); - part.PhysActor.LocalID = part.LocalId; - part.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); + newPart.PhysActor.LocalID = part.LocalId; + newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); } } -- cgit v1.1 From ad84728aba1ea5efe0d237c89e1578657e6d8288 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 15 Jun 2011 11:31:32 -0700 Subject: Add localID to physical object creation functions. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- OpenSim/Region/Physics/Manager/PhysicsActor.cs | 7 ++++++- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 15 +++++++++++++++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f745169..42ac9aa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1467,6 +1467,7 @@ namespace OpenSim.Region.Framework.Scenes newPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( + part.LocalId, string.Format("{0}/{1}", part.Name, part.UUID), pbs, part.AbsolutePosition, @@ -1474,7 +1475,6 @@ namespace OpenSim.Region.Framework.Scenes part.RotationOffset, part.PhysActor.IsPhysical); - newPart.PhysActor.LocalID = part.LocalId; newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a215b20..c6d8c73 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1582,6 +1582,7 @@ namespace OpenSim.Region.Framework.Scenes if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) { PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( + LocalId, string.Format("{0}/{1}", Name, UUID), Shape, AbsolutePosition, @@ -1594,7 +1595,6 @@ namespace OpenSim.Region.Framework.Scenes { PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info PhysActor.SOPDescription = this.Description; - PhysActor.LocalID = LocalId; DoPhysicsPropertyUpdate(RigidBody, true); PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); } @@ -4410,6 +4410,7 @@ namespace OpenSim.Region.Framework.Scenes { // It's not phantom anymore. So make sure the physics engine get's knowledge of it PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( + LocalId, string.Format("{0}/{1}", Name, UUID), Shape, AbsolutePosition, @@ -4420,7 +4421,6 @@ namespace OpenSim.Region.Framework.Scenes pa = PhysActor; if (pa != null) { - pa.LocalID = LocalId; DoPhysicsPropertyUpdate(UsePhysics, true); if (m_parentGroup != null) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f6295b1..80aafd0 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3295,7 +3295,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3 pVec = AbsolutePosition; // Old bug where the height was in centimeters instead of meters - m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, + m_physicsActor = scene.AddAvatar(LocalId, Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); scene.AddPhysicsActorTaint(m_physicsActor); diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 880c3ea..1c36e55 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -142,7 +142,12 @@ namespace OpenSim.Region.Physics.Manager public abstract PrimitiveBaseShape Shape { set; } - public abstract uint LocalID { set; } + uint m_baseLocalID; + public virtual uint LocalID + { + set { m_baseLocalID = value; } + get { return m_baseLocalID; } + } public abstract bool Grabbed { set; } diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 217d307..54c50f8 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -66,6 +66,13 @@ namespace OpenSim.Region.Physics.Manager public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying); + public virtual PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying) + { + PhysicsActor ret = AddAvatar(avName, position, size, isFlying); + if (ret != null) ret.LocalID = localID; + return ret; + } + public abstract void RemoveAvatar(PhysicsActor actor); public abstract void RemovePrim(PhysicsActor prim); @@ -75,6 +82,14 @@ namespace OpenSim.Region.Physics.Manager public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical); + public virtual PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical) + { + PhysicsActor ret = AddPrimShape(primName, pbs, position, size, rotation, isPhysical); + if (ret != null) ret.LocalID = localID; + return ret; + } + public virtual float TimeDilation { get { return 1.0f; } -- cgit v1.1 From 409738726d91791fbd3ea2328cea998f644f8787 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 16 Jun 2011 17:14:41 -0700 Subject: Added a couple of guards and warnings to the MapImage/MapImageServiceModule. --- .../ServiceConnectorsOut/MapImage/MapImageServiceModule.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs index ee90859..e224670 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs @@ -112,6 +112,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage Object[] args = new Object[] { source }; m_MapService = ServerUtils.LoadPlugin(service, args); + if (m_MapService == null) + { + m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Unable to load LocalServiceModule from {0}. MapService module disabled. Please fix the configuration.", service); + return; + } m_refreshTimer.Enabled = true; m_refreshTimer.AutoReset = true; @@ -202,7 +207,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage { m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: upload maptile for {0}", scene.RegionInfo.RegionName); - // Create a PNG map tile and upload it to the AddMapTile API + // Create a JPG map tile and upload it to the AddMapTile API byte[] jpgData = Utils.EmptyBytes; IMapImageGenerator tileGenerator = scene.RequestModuleInterface(); if (tileGenerator == null) @@ -220,13 +225,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage } } + if (jpgData == Utils.EmptyBytes) + { + m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Tile image generation failed"); + return; + } + string reason = string.Empty; if (!m_MapService.AddMapTile((int)scene.RegionInfo.RegionLocX, (int)scene.RegionInfo.RegionLocY, jpgData, out reason)) { m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}", scene.RegionInfo.RegionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, reason); } - } } } \ No newline at end of file -- cgit v1.1