123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- /*
- * 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 OpenMetaverse;
- using OpenSim.Framework;
- using OpenSim.Framework.Communications;
- namespace OpenSim.Region.Communications.Local
- {
- public class LocalBackEndServices : IGridServices
- {
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- protected Dictionary<ulong, RegionInfo> m_regions = new Dictionary<ulong, RegionInfo>();
- protected Dictionary<ulong, RegionCommsListener> m_regionListeners =
- new Dictionary<ulong, RegionCommsListener>();
- // private Dictionary<ulong, RegionInfo> m_remoteRegionInfoCache = new Dictionary<ulong, RegionInfo>();
- private Dictionary<string, string> m_queuedGridSettings = new Dictionary<string, string>();
- public string _gdebugRegionName = String.Empty;
- public bool RegionLoginsEnabled
- {
- get { return m_regionLoginsEnabled; }
- set { m_regionLoginsEnabled = value; }
- }
- private bool m_regionLoginsEnabled;
- public bool CheckRegion(string address, uint port)
- {
- return true;
- }
- public string gdebugRegionName
- {
- get { return _gdebugRegionName; }
- set { _gdebugRegionName = value; }
- }
- public string _rdebugRegionName = String.Empty;
- public string rdebugRegionName
- {
- get { return _rdebugRegionName; }
- set { _rdebugRegionName = value; }
- }
- /// <summary>
- /// Register a region method with the BackEnd Services.
- /// </summary>
- /// <param name="regionInfo"></param>
- /// <returns></returns>
- public RegionCommsListener RegisterRegion(RegionInfo regionInfo)
- {
- //m_log.Debug("CommsManager - Region " + regionInfo.RegionHandle + " , " + regionInfo.RegionLocX + " , "+ regionInfo.RegionLocY +" is registering");
- if (!m_regions.ContainsKey(regionInfo.RegionHandle))
- {
- //m_log.Debug("CommsManager - Adding Region " + regionInfo.RegionHandle);
- m_regions.Add(regionInfo.RegionHandle, regionInfo);
- RegionCommsListener regionHost = new RegionCommsListener();
- if (m_regionListeners.ContainsKey(regionInfo.RegionHandle))
- {
- m_log.Error("[INTERREGION STANDALONE]: " +
- "Error:Region registered twice as an Events listener for Interregion Communications but not as a listed region. " +
- "In Standalone mode this will cause BIG issues. In grid mode, it means a region went down and came back up.");
- m_regionListeners.Remove(regionInfo.RegionHandle);
- }
- m_regionListeners.Add(regionInfo.RegionHandle, regionHost);
- return regionHost;
- }
- else
- {
- // Already in our list, so the region went dead and restarted.
- // don't replace the old regioninfo.. this might be a locking issue.. however we need to
- // remove it and let it add normally below or we get extremely strange and intermittant
- // connectivity errors.
- // Don't change this line below to 'm_regions[regionInfo.RegionHandle] = regionInfo' unless you
- // *REALLY* know what you are doing here.
- m_regions[regionInfo.RegionHandle] = regionInfo;
- m_log.Warn("[INTERREGION STANDALONE]: Region registered twice. Region went down and came back up.");
- RegionCommsListener regionHost = new RegionCommsListener();
- if (m_regionListeners.ContainsKey(regionInfo.RegionHandle))
- {
- m_regionListeners.Remove(regionInfo.RegionHandle);
- }
- m_regionListeners.Add(regionInfo.RegionHandle, regionHost);
- return regionHost;
- }
- }
- public bool DeregisterRegion(RegionInfo regionInfo)
- {
- if (m_regions.ContainsKey(regionInfo.RegionHandle))
- {
- m_regions.Remove(regionInfo.RegionHandle);
- if (m_regionListeners.ContainsKey(regionInfo.RegionHandle))
- {
- m_regionListeners.Remove(regionInfo.RegionHandle);
- }
- return true;
- }
- return false;
- }
- /// <summary>
- /// </summary>
- /// <param name="regionInfo"></param>
- /// <returns></returns>
- public List<SimpleRegionInfo> RequestNeighbours(uint x, uint y)
- {
- // m_log.Debug("Finding Neighbours to " + regionInfo.RegionHandle);
- List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>();
- foreach (RegionInfo reg in m_regions.Values)
- {
- // m_log.Debug("CommsManager- RequestNeighbours() checking region " + reg.RegionLocX + " , "+ reg.RegionLocY);
- if (reg.RegionLocX != x || reg.RegionLocY != y)
- {
- //m_log.Debug("CommsManager- RequestNeighbours() - found a different region in list, checking location");
- if ((reg.RegionLocX > (x - 2)) && (reg.RegionLocX < (x + 2)))
- {
- if ((reg.RegionLocY > (y - 2)) && (reg.RegionLocY < (y + 2)))
- {
- neighbours.Add(reg);
- }
- }
- }
- }
- return neighbours;
- }
- /// <summary>
- /// Get information about a neighbouring region
- /// </summary>
- /// <param name="regionHandle"></param>
- /// <returns></returns>
- public RegionInfo RequestNeighbourInfo(ulong regionHandle)
- {
- if (m_regions.ContainsKey(regionHandle))
- {
- return m_regions[regionHandle];
- }
-
- return null;
- }
- /// <summary>
- /// Get information about a neighbouring region
- /// </summary>
- /// <param name="regionHandle"></param>
- /// <returns></returns>
- public RegionInfo RequestNeighbourInfo(UUID regionID)
- {
- // TODO add a dictionary for faster lookup
- foreach (RegionInfo info in m_regions.Values)
- {
- if (info.RegionID == regionID)
- return info;
- }
-
- return null;
- }
- /// <summary>
- /// Get information about a neighbouring region
- /// </summary>
- /// <param name="regionHandle"></param>
- /// <returns></returns>
- public RegionInfo RequestNeighbourInfo(string name)
- {
- foreach (RegionInfo info in m_regions.Values)
- {
- if (info.RegionName == name)
- return info;
- }
- return null;
- }
- /// <summary>
- /// Get information about a neighbouring region
- /// </summary>
- /// <param name="regionHandle"></param>
- /// <returns></returns>
- public RegionInfo RequestNeighbourInfo(string host, uint port)
- {
- foreach (RegionInfo info in m_regions.Values)
- {
- if ((info.ExternalHostName == host) && (info.HttpPort == port))
- return info;
- }
- return null;
- }
- /// <summary>
- /// Get information about the closet region given a region name.
- /// </summary>
- /// <param name="regionName"></param>
- /// <returns></returns>
- public RegionInfo RequestClosestRegion(string regionName)
- {
- foreach (RegionInfo regInfo in m_regions.Values)
- {
- if (regInfo.RegionName == regionName)
- return regInfo;
- }
- return null;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="minX"></param>
- /// <param name="minY"></param>
- /// <param name="maxX"></param>
- /// <param name="maxY"></param>
- /// <returns></returns>
- public List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY)
- {
- List<MapBlockData> mapBlocks = new List<MapBlockData>();
- foreach (RegionInfo regInfo in m_regions.Values)
- {
- if (((regInfo.RegionLocX >= minX) && (regInfo.RegionLocX <= maxX)) &&
- ((regInfo.RegionLocY >= minY) && (regInfo.RegionLocY <= maxY)))
- {
- MapBlockData map = new MapBlockData();
- map.Name = regInfo.RegionName;
- map.X = (ushort) regInfo.RegionLocX;
- map.Y = (ushort) regInfo.RegionLocY;
- map.WaterHeight = (byte) regInfo.RegionSettings.WaterHeight;
- map.MapImageId = regInfo.RegionSettings.TerrainImageID;
- map.Agents = 1;
- map.RegionFlags = 72458694;
- map.Access = regInfo.AccessLevel;
- mapBlocks.Add(map);
- }
- }
- return mapBlocks;
- }
- // This function is only here to keep this class in line with the Grid Interface.
- // It never gets called.
- public virtual Dictionary<string, string> GetGridSettings()
- {
- Dictionary<string, string> returnGridSettings = new Dictionary<string, string>();
- lock (m_queuedGridSettings)
- {
- returnGridSettings = m_queuedGridSettings;
- m_queuedGridSettings.Clear();
- }
- return returnGridSettings;
- }
- public virtual void SetForcefulBanlistsDisallowed()
- {
- m_queuedGridSettings.Add("allow_forceful_banlines", "FALSE");
- }
- /// <summary>
- /// Is a Sandbox mode method, used by the local Login server to inform a region of a connection user/session
- /// </summary>
- /// <param name="regionHandle"></param>
- /// <param name="loginData"></param>
- /// <returns></returns>
- public void AddNewSession(ulong regionHandle, Login loginData)
- {
- AgentCircuitData agent = new AgentCircuitData();
- agent.AgentID = loginData.Agent;
- agent.firstname = loginData.First;
- agent.lastname = loginData.Last;
- agent.SessionID = loginData.Session;
- agent.SecureSessionID = loginData.SecureSession;
- agent.circuitcode = loginData.CircuitCode;
- agent.BaseFolder = loginData.BaseFolder;
- agent.InventoryFolder = loginData.InventoryFolder;
- agent.startpos = loginData.StartPos;
- agent.CapsPath = loginData.CapsPath;
- if (loginData.Appearance != null)
- agent.Appearance = loginData.Appearance;
- else
- {
- m_log.WarnFormat("[INTER]: Appearance not found for {0} {1}. Creating default.", agent.firstname, agent.lastname);
- agent.Appearance = new AvatarAppearance(agent.AgentID);
- }
- TriggerExpectUser(regionHandle, agent);
- }
- public void TriggerExpectUser(ulong regionHandle, AgentCircuitData agent)
- {
- //m_log.Info("[INTER]: " + rdebugRegionName + ":Local BackEnd: Other region is sending child agent our way: " + agent.firstname + " " + agent.lastname);
- if (m_regionListeners.ContainsKey(regionHandle))
- {
- //m_log.Info("[INTER]: " + rdebugRegionName + ":Local BackEnd: FoundLocalRegion To send it to: " + agent.firstname + " " + agent.lastname);
- m_regionListeners[regionHandle].TriggerExpectUser(agent);
- }
- }
- public void TriggerLogOffUser(ulong regionHandle, UUID agentID, UUID RegionSecret, string message)
- {
- if (m_regionListeners.ContainsKey(regionHandle))
- {
- //m_log.Info("[INTER]: " + rdebugRegionName + ":Local BackEnd: FoundLocalRegion To send it to: " + agent.firstname + " " + agent.lastname);
- m_regionListeners[regionHandle].TriggerLogOffUser(agentID, RegionSecret, message);
- }
- }
- public void PingCheckReply(Hashtable respData)
- {
- foreach (ulong region in m_regions.Keys)
- {
- Hashtable regData = new Hashtable();
- RegionInfo reg = m_regions[region];
- regData["status"] = "active";
- regData["handle"] = region.ToString();
- respData[reg.RegionID.ToString()] = regData;
- }
- }
- public LandData RequestLandData (ulong regionHandle, uint x, uint y)
- {
- m_log.DebugFormat("[INTERREGION STANDALONE] requests land data in {0}, at {1}, {2}",
- regionHandle, x, y);
- if (m_regionListeners.ContainsKey(regionHandle))
- {
- LandData land = m_regionListeners[regionHandle].TriggerGetLandData(x, y);
- return land;
- }
- m_log.Debug("[INTERREGION STANDALONE] didn't find land data locally.");
- return null;
- }
- public List<RegionInfo> RequestNamedRegions (string name, int maxNumber)
- {
- List<RegionInfo> lowercase_regions = new List<RegionInfo>();
- List<RegionInfo> regions = new List<RegionInfo>();
- foreach (RegionInfo info in m_regions.Values)
- {
- // Prioritizes exact match
- if (info.RegionName.StartsWith(name))
- {
- regions.Add(info);
- if (regions.Count >= maxNumber) break;
- }
- // But still saves lower case matches
- else if (info.RegionName.ToLower().StartsWith(name))
- {
- if (lowercase_regions.Count < maxNumber)
- {
- lowercase_regions.Add(info);
- }
- }
- }
- // If no exact matches found, return lowercase matches (libOMV compatiblity)
- if (regions.Count == 0 && lowercase_regions.Count != 0)
- {
- return lowercase_regions;
- }
- return regions;
- }
- }
- }
|