29 using System.Collections;
30 using System.Collections.Generic;
34 using System.Reflection;
39 using OpenSim.Framework;
40 using OpenSim.Framework.Console;
42 using OpenSim.Server.Base;
43 using OpenSim.Services.Interfaces;
44 using OpenSim.Services.Connectors.Hypergrid;
48 namespace OpenSim.Services.GridService
52 private static readonly ILog m_log =
54 MethodBase.GetCurrentMethod().DeclaringType);
56 private static uint m_autoMappingX = 0;
57 private static uint m_autoMappingY = 0;
58 private static bool m_enableAutoMapping =
false;
65 protected UUID m_ScopeID = UUID.Zero;
67 protected string m_MapTileDirectory = string.Empty;
68 protected string m_ThisGatekeeper = string.Empty;
69 protected Uri m_ThisGatekeeperURI = null;
76 if (m_DefaultRegion == null)
78 List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID);
79 if (defs != null && defs.Count > 0)
80 m_DefaultRegion = defs[0];
84 defs = m_GridService.GetRegionsByName(m_ScopeID,
"", 1);
85 if (defs != null && defs.Count > 0)
86 m_DefaultRegion = defs[0];
91 m_log.Error(
"[HYPERGRID LINKER]: Something is wrong with this grid. It has no regions?");
95 return m_DefaultRegion;
101 IConfig gridConfig = config.Configs[
"GridService"];
102 if (gridConfig == null)
105 if (!gridConfig.GetBoolean(
"HypergridLinker",
false))
109 m_GridService = gridService;
110 m_log.DebugFormat(
"[HYPERGRID LINKER]: Starting with db {0}", db.GetType());
112 string assetService = gridConfig.GetString(
"AssetService", string.Empty);
114 Object[] args =
new Object[] { config };
116 if (assetService !=
string.Empty)
117 m_AssetService = ServerUtils.LoadPlugin<
IAssetService>(assetService, args);
119 string scope = gridConfig.GetString(
"ScopeID", string.Empty);
120 if (scope !=
string.Empty)
121 UUID.TryParse(scope, out m_ScopeID);
125 m_MapTileDirectory = gridConfig.GetString(
"MapTileDirectory",
"maptiles");
127 m_ThisGatekeeper = Util.GetConfigVarFromSections<
string>(config,
"GatekeeperURI",
128 new string[] {
"Startup",
"Hypergrid",
"GridService" }, String.Empty);
130 m_ThisGatekeeper = gridConfig.GetString(
"Gatekeeper", m_ThisGatekeeper);
133 m_ThisGatekeeperURI =
new Uri(m_ThisGatekeeper);
137 m_log.WarnFormat(
"[HYPERGRID LINKER]: Malformed URL in [GridService], variable Gatekeeper = {0}", m_ThisGatekeeper);
142 m_log.Debug(
"[HYPERGRID LINKER]: Loaded all services...");
144 if (!
string.IsNullOrEmpty(m_MapTileDirectory))
148 Directory.CreateDirectory(m_MapTileDirectory);
152 m_log.WarnFormat(
"[HYPERGRID LINKER]: Could not create map tile storage directory {0}: {1}", m_MapTileDirectory, e);
153 m_MapTileDirectory = string.Empty;
159 MainConsole.Instance.Commands.AddCommand(
"Hypergrid",
false,
"link-region",
160 "link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]",
161 "Link a HyperGrid Region. Examples for <ServerURI>: http://grid.net:8002/ or http://example.org/path/foo.php", RunCommand);
162 MainConsole.Instance.Commands.AddCommand(
"Hypergrid",
false,
"link-region",
163 "link-region <Xloc> <Yloc> <RegionIP> <RegionPort> [<RemoteRegionName>]",
164 "Link a hypergrid region (deprecated)", RunCommand);
165 MainConsole.Instance.Commands.AddCommand(
"Hypergrid",
false,
"unlink-region",
166 "unlink-region <local name>",
167 "Unlink a hypergrid region", RunCommand);
168 MainConsole.Instance.Commands.AddCommand(
"Hypergrid",
false,
"link-mapping",
"link-mapping [<x> <y>]",
169 "Set local coordinate to map HG regions to", RunCommand);
170 MainConsole.Instance.Commands.AddCommand(
"Hypergrid",
false,
"show hyperlinks",
"show hyperlinks",
171 "List the HG regions", HandleShow);
181 string reason = string.Empty;
182 uint xloc = Util.RegionToWorldLoc((uint)random.Next(0, Int16.MaxValue));
183 return TryLinkRegionToCoords(scopeID, regionDescriptor, (
int)xloc, 0, out reason);
186 private static Random random =
new Random();
189 private GridRegion TryLinkRegionToCoords(UUID scopeID,
string mapName,
int xloc,
int yloc, out
string reason)
191 return TryLinkRegionToCoords(scopeID, mapName, xloc, yloc, UUID.Zero, out reason);
196 reason = string.Empty;
199 mapName = mapName.Trim();
201 if (!mapName.StartsWith(
"http"))
210 string regionName =
"";
212 string[] parts = mapName.Split(
new char[] {
':' });
214 if (parts.Length == 0)
216 reason =
"Wrong format for link-region";
222 if (parts.Length >= 2)
225 if (!UInt32.TryParse(parts[1], out port))
226 regionName = parts[1];
230 if (parts.Length >= 3)
232 regionName = parts[2];
235 bool success = TryCreateLink(scopeID, xloc, yloc, regionName, port, host, ownerID, out regInfo, out reason);
238 regInfo.RegionName = mapName;
249 string regionName =
"";
251 string[] parts = mapName.Split(
new char[] {
' ' });
253 if (parts.Length == 0)
255 reason =
"Wrong format for link-region";
259 serverURI = parts[0];
261 if (parts.Length >= 2)
263 regionName = mapName.Substring(serverURI.Length);
264 regionName = regionName.Trim(
new char[] {
'"',
' ' });
267 if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, serverURI, ownerID, out regInfo, out reason))
269 regInfo.RegionName = mapName;
277 private bool TryCreateLink(UUID scopeID,
int xloc,
int yloc,
string remoteRegionName, uint externalPort,
string externalHostName, UUID ownerID, out
GridRegion regInfo, out
string reason)
279 return TryCreateLink(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, null, ownerID, out regInfo, out reason);
282 private bool TryCreateLink(UUID scopeID,
int xloc,
int yloc,
string remoteRegionName, uint externalPort,
string externalHostName,
string serverURI, UUID ownerID, out
GridRegion regInfo, out
string reason)
286 return TryCreateLinkImpl(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, serverURI, ownerID, out regInfo, out reason);
290 private bool TryCreateLinkImpl(UUID scopeID,
int xloc,
int yloc,
string remoteRegionName, uint externalPort,
string externalHostName,
string serverURI, UUID ownerID, out
GridRegion regInfo, out
string reason)
292 m_log.InfoFormat(
"[HYPERGRID LINKER]: Link to {0} {1}, in <{2},{3}>",
293 ((serverURI == null) ? (externalHostName +
":" + externalPort) : serverURI),
294 remoteRegionName, Util.WorldToRegionLoc((uint)xloc), Util.WorldToRegionLoc((uint)yloc));
296 reason = string.Empty;
300 if (externalPort > 0)
301 regInfo.HttpPort = externalPort;
303 regInfo.HttpPort = 80;
304 if (externalHostName != null)
305 regInfo.ExternalHostName = externalHostName;
307 regInfo.ExternalHostName =
"0.0.0.0";
308 if (serverURI != null)
310 regInfo.ServerURI = serverURI;
313 uri =
new Uri(serverURI);
314 regInfo.ExternalHostName = uri.Host;
315 regInfo.HttpPort = (uint)uri.Port;
320 if (remoteRegionName !=
string.Empty)
321 regInfo.RegionName = remoteRegionName;
323 regInfo.RegionLocX = xloc;
324 regInfo.RegionLocY = yloc;
325 regInfo.ScopeID = scopeID;
326 regInfo.EstateOwner = ownerID;
329 if (m_ThisGatekeeperURI != null)
331 if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port)
333 m_log.InfoFormat(
"[HYPERGRID LINKER]: Cannot hyperlink to regions on the same grid");
334 reason =
"Cannot hyperlink to regions on the same grid";
339 m_log.WarnFormat(
"[HYPERGRID LINKER]: Please set this grid's Gatekeeper's address in [GridService]!");
342 GridRegion region = m_GridService.GetRegionByPosition(regInfo.ScopeID, regInfo.RegionLocX, regInfo.RegionLocY);
345 m_log.WarnFormat(
"[HYPERGRID LINKER]: Coordinates <{0},{1}> are already occupied by region {2} with uuid {3}",
346 Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY),
347 region.RegionName, region.RegionID);
348 reason =
"Coordinates are already in use";
354 regInfo.InternalEndPoint =
new IPEndPoint(IPAddress.Parse(
"0.0.0.0"), (int)0);
358 m_log.Warn(
"[HYPERGRID LINKER]: Wrong format for link-region: " + e.Message);
359 reason =
"Internal error";
365 UUID regionID = UUID.Zero;
366 string externalName = string.Empty;
367 string imageURL = string.Empty;
368 if (!m_GatekeeperConnector.LinkRegion(regInfo, out regionID, out handle, out externalName, out imageURL, out reason))
371 if (regionID ==
UUID.Zero)
373 m_log.Warn(
"[HYPERGRID LINKER]: Unable to link region");
374 reason =
"Remote region could not be found";
378 region = m_GridService.GetRegionByUUID(scopeID, regionID);
381 m_log.DebugFormat(
"[HYPERGRID LINKER]: Region already exists in coordinates <{0},{1}>", Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY));
399 regInfo.RegionID = regionID;
401 if (externalName ==
string.Empty)
402 regInfo.RegionName = regInfo.ServerURI;
404 regInfo.RegionName = externalName;
406 m_log.DebugFormat(
"[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString());
409 regInfo.TerrainImage = GetMapImage(regionID, imageURL);
412 regInfo.RegionSecret = handle.ToString();
414 AddHyperlinkRegion(regInfo, handle);
415 m_log.InfoFormat(
"[HYPERGRID LINKER]: Successfully linked to region {0} at <{1},{2}> with image {3}",
416 regInfo.RegionName, Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY), regInfo.TerrainImage);
422 m_log.DebugFormat(
"[HYPERGRID LINKER]: Request to unlink {0}", mapName);
425 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(mapName), m_ScopeID);
426 if (regions != null && regions.Count > 0)
429 if ((rflags &
OpenSim.Framework.RegionFlags.Hyperlink) != 0)
432 regInfo.RegionID = regions[0].RegionID;
433 regInfo.ScopeID = m_ScopeID;
439 RemoveHyperlinkRegion(regInfo.RegionID);
444 m_log.InfoFormat(
"[HYPERGRID LINKER]: Region {0} not found", mapName);
495 private void AddHyperlinkRegion(
GridRegion regionInfo, ulong regionHandle)
497 RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo);
498 int flags = (int)
OpenSim.Framework.RegionFlags.Hyperlink + (
int)OpenSim.Framework.RegionFlags.NoDirectLogin + (int)
OpenSim.Framework.RegionFlags.RegionOnline;
499 rdata.
Data[
"flags"] = flags.ToString();
501 m_Database.Store(rdata);
504 private void RemoveHyperlinkRegion(UUID regionID)
506 m_Database.Delete(regionID);
511 return m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory);
516 #region Console Commands
522 MainConsole.Instance.Output(
"Syntax: show hyperlinks");
525 List<RegionData> regions = m_Database.GetHyperlinks(UUID.Zero);
526 if (regions == null || regions.Count < 1)
528 MainConsole.Instance.Output(
"No hyperlinks");
532 MainConsole.Instance.Output(
"Region Name");
533 MainConsole.Instance.Output(
"Location Region UUID");
534 MainConsole.Instance.Output(
new string(
'-', 72));
537 MainConsole.Instance.Output(
538 String.Format(
"{0}\n{2,-32} {1}\n",
539 r.RegionName, r.RegionID,
540 String.Format(
"{0},{1} ({2},{3})", r.posX, r.posY,
541 Util.WorldToRegionLoc((uint)r.
posX), Util.WorldToRegionLoc((uint)r.
posY)
551 List<string> args =
new List<string>(cmdparams);
555 string command = args[0];
558 cmdparams = args.ToArray();
560 RunHGCommand(command, cmdparams);
564 private void RunLinkRegionCommand(
string[] cmdparams)
568 string remoteName = null;
569 xloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[0]));
570 yloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[1]));
571 serverURI = cmdparams[2];
572 if (cmdparams.Length > 3)
573 remoteName = string.Join(
" ", cmdparams, 3, cmdparams.Length - 3);
574 string reason = string.Empty;
576 if (TryCreateLink(UUID.Zero, xloc, yloc, remoteName, 0, null, serverURI, UUID.Zero, out regInfo, out reason))
579 MainConsole.Instance.Output(
"Failed to link region: " + reason);
582 private void RunHGCommand(
string command,
string[] cmdparams)
584 if (command.Equals(
"link-mapping"))
586 if (cmdparams.Length == 2)
590 m_autoMappingX = Convert.ToUInt32(cmdparams[0]);
591 m_autoMappingY = Convert.ToUInt32(cmdparams[1]);
592 m_enableAutoMapping =
true;
598 m_enableAutoMapping =
false;
602 else if (command.Equals(
"link-region"))
604 if (cmdparams.Length < 3)
606 if ((cmdparams.Length == 1) || (cmdparams.Length == 2))
608 LoadXmlLinkFile(cmdparams);
612 LinkRegionCmdUsage();
618 if (cmdparams[2].StartsWith(
"http"))
620 RunLinkRegionCommand(cmdparams);
622 else if (cmdparams[2].Contains(
":"))
625 string[] parts = cmdparams[2].Split(
':');
626 if (parts.Length > 2)
629 ArrayList parameters =
new ArrayList(cmdparams);
630 parameters.Insert(3, parts[2]);
631 cmdparams = (
string[])parameters.ToArray(typeof(
string));
633 cmdparams[2] =
"http://" + parts[0] +
':' + parts[1];
635 RunLinkRegionCommand(cmdparams);
643 string externalHostName;
646 xloc = Convert.ToUInt32(cmdparams[0]);
647 yloc = Convert.ToUInt32(cmdparams[1]);
648 externalPort = Convert.ToUInt32(cmdparams[3]);
649 externalHostName = cmdparams[2];
655 MainConsole.Instance.Output(
"[HGrid] Wrong format for link-region command: " + e.Message);
656 LinkRegionCmdUsage();
661 xloc = Util.RegionToWorldLoc(xloc);
662 yloc = Util.RegionToWorldLoc(yloc);
663 string reason = string.Empty;
664 if (TryCreateLink(
UUID.Zero, (
int)xloc, (int)yloc,
665 string.Empty, externalPort, externalHostName,
UUID.Zero, out regInfo, out reason))
679 else if (command.Equals(
"unlink-region"))
681 if (cmdparams.Length < 1)
683 UnlinkRegionCmdUsage();
686 string region = string.Join(
" ", cmdparams);
687 if (TryUnlinkRegion(region))
690 MainConsole.Instance.Output(
"Unable to unlink " + region +
", region not found.");
694 private void LoadXmlLinkFile(
string[] cmdparams)
699 XmlReader r = XmlReader.Create(cmdparams[0]);
700 XmlConfigSource cs =
new XmlConfigSource(r);
701 string[] excludeSections = null;
703 if (cmdparams.Length == 2)
705 if (cmdparams[1].ToLower().StartsWith(
"excludelist:"))
707 string excludeString = cmdparams[1].ToLower();
708 excludeString = excludeString.Remove(0, 12);
709 char[] splitter = {
';' };
711 excludeSections = excludeString.Split(splitter);
715 for (
int i = 0; i < cs.Configs.Count; i++)
718 if ((excludeSections != null) && (excludeSections.Length > 0))
720 for (
int n = 0; n < excludeSections.Length; n++)
722 if (excludeSections[n] == cs.Configs[i].Name.ToLower())
731 ReadLinkFromConfig(cs.Configs[i]);
737 m_log.Error(e.ToString());
742 private void ReadLinkFromConfig(IConfig config)
747 string externalHostName;
748 uint realXLoc, realYLoc;
750 xloc = Convert.ToUInt32(config.GetString(
"xloc",
"0"));
751 yloc = Convert.ToUInt32(config.GetString(
"yloc",
"0"));
752 externalPort = Convert.ToUInt32(config.GetString(
"externalPort",
"0"));
753 externalHostName = config.GetString(
"externalHostName",
"");
754 realXLoc = Convert.ToUInt32(config.GetString(
"real-xloc",
"0"));
755 realYLoc = Convert.ToUInt32(config.GetString(
"real-yloc",
"0"));
757 if (m_enableAutoMapping)
759 xloc = (xloc % 100) + m_autoMappingX;
760 yloc = (yloc % 100) + m_autoMappingY;
763 if (((realXLoc == 0) && (realYLoc == 0)) ||
764 (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) &&
765 ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896))))
767 xloc = Util.RegionToWorldLoc(xloc);
768 yloc = Util.RegionToWorldLoc(yloc);
769 string reason = string.Empty;
770 if (TryCreateLink(
UUID.Zero, (
int)xloc, (int)yloc,
771 string.Empty, externalPort, externalHostName,
UUID.Zero, out regInfo, out reason))
773 regInfo.RegionName = config.GetString(
"localName",
"");
776 MainConsole.Instance.Output(
"Unable to link " + externalHostName +
": " + reason);
781 private void LinkRegionCmdUsage()
783 MainConsole.Instance.Output(
"Usage: link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]");
784 MainConsole.Instance.Output(
"Usage (deprecated): link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>]");
785 MainConsole.Instance.Output(
"Usage (deprecated): link-region <Xloc> <Yloc> <HostName> <HttpPort> [<LocalName>]");
786 MainConsole.Instance.Output(
"Usage: link-region <URI_of_xml> [<exclude>]");
789 private void UnlinkRegionCmdUsage()
791 MainConsole.Instance.Output(
"Usage: unlink-region <LocalName>");
UUID GetMapImage(UUID regionID, string imageURL)
int posX
The position in meters of this region.
An interface for connecting to the authentication datastore
void RunCommand(string module, string[] cmdparams)
IAssetService m_AssetService
bool TryUnlinkRegion(string mapName)
GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, UUID ownerID, out string reason)
int posY
The position in meters of this region.
Dictionary< string, object > Data
GridRegion LinkRegion(UUID scopeID, string regionDescriptor)
RegionFlags
Region flags used internally by OpenSimulator to store installation specific information about region...
GatekeeperServiceConnector m_GatekeeperConnector
static ICommandConsole Instance
OpenSim.Services.Interfaces.GridRegion GridRegion
GridRegion m_DefaultRegion
GridService m_GridService
void Output(string text, string level)
Interactive OpenSim region server
HypergridLinker(IConfigSource config, GridService gridService, IRegionData db)
void HandleShow(string module, string[] cmd)