aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs8
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs10
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs8
-rw-r--r--OpenSim/Services/HypergridService/HGAssetService.cs11
-rw-r--r--OpenSim/Services/HypergridService/HGInventoryService.cs9
-rw-r--r--bin/Robust.HG.ini.example4
-rw-r--r--bin/config-include/GridCommon.ini.example2
-rw-r--r--bin/config-include/StandaloneCommon.ini.example6
11 files changed, 46 insertions, 33 deletions
diff --git a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
index 6e8c2ee..7447ac2 100644
--- a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
+++ b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
@@ -44,13 +44,13 @@ namespace OpenSim.Framework.Serialization.External
44 /// with creator data added to it. 44 /// with creator data added to it.
45 /// </summary> 45 /// </summary>
46 /// <param name="xml">The SceneObjectPart represented in XML2</param> 46 /// <param name="xml">The SceneObjectPart represented in XML2</param>
47 /// <param name="profileURL">The URL of the profile service for the creator</param> 47 /// <param name="homeURL">The URL of the user agents service (home) for the creator</param>
48 /// <param name="userService">The service for retrieving user account information</param> 48 /// <param name="userService">The service for retrieving user account information</param>
49 /// <param name="scopeID">The scope of the user account information (Grid ID)</param> 49 /// <param name="scopeID">The scope of the user account information (Grid ID)</param>
50 /// <returns>The SceneObjectPart represented in XML2</returns> 50 /// <returns>The SceneObjectPart represented in XML2</returns>
51 public static string RewriteSOP(string xml, string profileURL, IUserAccountService userService, UUID scopeID) 51 public static string RewriteSOP(string xml, string homeURL, IUserAccountService userService, UUID scopeID)
52 { 52 {
53 if (xml == string.Empty || profileURL == string.Empty || userService == null) 53 if (xml == string.Empty || homeURL == string.Empty || userService == null)
54 return xml; 54 return xml;
55 55
56 XmlDocument doc = new XmlDocument(); 56 XmlDocument doc = new XmlDocument();
@@ -83,7 +83,7 @@ namespace OpenSim.Framework.Serialization.External
83 if (!hasCreatorData && creator != null) 83 if (!hasCreatorData && creator != null)
84 { 84 {
85 XmlElement creatorData = doc.CreateElement("CreatorData"); 85 XmlElement creatorData = doc.CreateElement("CreatorData");
86 creatorData.InnerText = profileURL + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName; 86 creatorData.InnerText = homeURL + ";" + creator.FirstName + " " + creator.LastName;
87 sop.AppendChild(creatorData); 87 sop.AppendChild(creatorData);
88 } 88 }
89 } 89 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index d20c9eb..eaadc1b 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -55,16 +55,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
55// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>(); 55// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>();
56 56
57 private Scene m_scene; 57 private Scene m_scene;
58 private string m_ProfileServerURI; 58 private string m_HomeURI;
59 59
60 #endregion 60 #endregion
61 61
62 #region Constructor 62 #region Constructor
63 63
64 public HGAssetMapper(Scene scene, string profileURL) 64 public HGAssetMapper(Scene scene, string homeURL)
65 { 65 {
66 m_scene = scene; 66 m_scene = scene;
67 m_ProfileServerURI = profileURL; 67 m_HomeURI = homeURL;
68 } 68 }
69 69
70 #endregion 70 #endregion
@@ -150,7 +150,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
150 UUID.TryParse(meta.CreatorID, out uuid); 150 UUID.TryParse(meta.CreatorID, out uuid);
151 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); 151 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
152 if (creator != null) 152 if (creator != null)
153 meta.CreatorID = m_ProfileServerURI + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName; 153 meta.CreatorID = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName;
154 } 154 }
155 } 155 }
156 156
@@ -193,7 +193,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
193 if (!hasCreatorData && creator != null) 193 if (!hasCreatorData && creator != null)
194 { 194 {
195 XmlElement creatorData = doc.CreateElement("CreatorData"); 195 XmlElement creatorData = doc.CreateElement("CreatorData");
196 creatorData.InnerText = m_ProfileServerURI + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName; 196 creatorData.InnerText = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName;
197 sop.AppendChild(creatorData); 197 sop.AppendChild(creatorData);
198 } 198 }
199 } 199 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index bf24ebc..0c4ff7f 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
54 get { return m_assMapper; } 54 get { return m_assMapper; }
55 } 55 }
56 56
57 private string m_ProfileServerURI; 57 private string m_HomeURI;
58 private bool m_OutboundPermission; 58 private bool m_OutboundPermission;
59 private string m_ThisGatekeeper; 59 private string m_ThisGatekeeper;
60 60
@@ -84,7 +84,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
84 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; 84 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
85 if (thisModuleConfig != null) 85 if (thisModuleConfig != null)
86 { 86 {
87 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); 87 // legacy configuration [obsolete]
88 m_HomeURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
89 // preferred
90 m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI);
88 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); 91 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
89 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty); 92 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
90 } 93 }
@@ -100,7 +103,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
100 return; 103 return;
101 104
102 base.AddRegion(scene); 105 base.AddRegion(scene);
103 m_assMapper = new HGAssetMapper(scene, m_ProfileServerURI); 106 m_assMapper = new HGAssetMapper(scene, m_HomeURI);
104 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; 107 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
105 108
106 } 109 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index f44a3ba..0707cbe 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -125,8 +125,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
125 Dictionary<string, object> options = new Dictionary<string, object>(); 125 Dictionary<string, object> options = new Dictionary<string, object>();
126 126
127 OptionSet ops = new OptionSet(); 127 OptionSet ops = new OptionSet();
128// ops.Add("v|version=", delegate(string v) { options["version"] = v; }); 128
129 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); 129 // legacy argument [obsolete]
130 ops.Add("p|profile=", delegate(string v) { Console.WriteLine("\n WARNING: -profile option is obsolete and it will not work. Use -home instead.\n"); });
131 // preferred
132 ops.Add("h|home=", delegate(string v) { options["home"] = v; });
133
130 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); 134 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
131 ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); 135 ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
132 136
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 51d3586..e9c33eb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -394,7 +394,7 @@ namespace OpenSim.Region.Framework.Scenes
394 394
395 private string m_creatorData = string.Empty; 395 private string m_creatorData = string.Empty;
396 /// <summary> 396 /// <summary>
397 /// Data about the creator in the form profile_url;name 397 /// Data about the creator in the form home_url;name
398 /// </summary> 398 /// </summary>
399 public string CreatorData 399 public string CreatorData
400 { 400 {
@@ -405,7 +405,7 @@ namespace OpenSim.Region.Framework.Scenes
405 /// <summary> 405 /// <summary>
406 /// Used by the DB layer to retrieve / store the entire user identification. 406 /// Used by the DB layer to retrieve / store the entire user identification.
407 /// The identification can either be a simple UUID or a string of the form 407 /// The identification can either be a simple UUID or a string of the form
408 /// uuid[;profile_url[;name]] 408 /// uuid[;home_url[;name]]
409 /// </summary> 409 /// </summary>
410 public string CreatorIdentification 410 public string CreatorIdentification
411 { 411 {
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 38d1231..7c60ddd 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -1134,12 +1134,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1134 1134
1135 if (sop.CreatorData != null && sop.CreatorData != string.Empty) 1135 if (sop.CreatorData != null && sop.CreatorData != string.Empty)
1136 writer.WriteElementString("CreatorData", sop.CreatorData); 1136 writer.WriteElementString("CreatorData", sop.CreatorData);
1137 else if (options.ContainsKey("profile")) 1137 else if (options.ContainsKey("home"))
1138 { 1138 {
1139 if (m_UserManagement == null) 1139 if (m_UserManagement == null)
1140 m_UserManagement = sop.ParentGroup.Scene.RequestModuleInterface<IUserManagement>(); 1140 m_UserManagement = sop.ParentGroup.Scene.RequestModuleInterface<IUserManagement>();
1141 string name = m_UserManagement.GetUserName(sop.CreatorID); 1141 string name = m_UserManagement.GetUserName(sop.CreatorID);
1142 writer.WriteElementString("CreatorData", (string)options["profile"] + "/" + sop.CreatorID + ";" + name); 1142 writer.WriteElementString("CreatorData", (string)options["home"] + ";" + name);
1143 } 1143 }
1144 1144
1145 WriteUUID(writer, "FolderID", sop.FolderID, options); 1145 WriteUUID(writer, "FolderID", sop.FolderID, options);
@@ -1282,12 +1282,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1282 1282
1283 if (item.CreatorData != null && item.CreatorData != string.Empty) 1283 if (item.CreatorData != null && item.CreatorData != string.Empty)
1284 writer.WriteElementString("CreatorData", item.CreatorData); 1284 writer.WriteElementString("CreatorData", item.CreatorData);
1285 else if (options.ContainsKey("profile")) 1285 else if (options.ContainsKey("home"))
1286 { 1286 {
1287 if (m_UserManagement == null) 1287 if (m_UserManagement == null)
1288 m_UserManagement = scene.RequestModuleInterface<IUserManagement>(); 1288 m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
1289 string name = m_UserManagement.GetUserName(item.CreatorID); 1289 string name = m_UserManagement.GetUserName(item.CreatorID);
1290 writer.WriteElementString("CreatorData", (string)options["profile"] + "/" + item.CreatorID + ";" + name); 1290 writer.WriteElementString("CreatorData", (string)options["home"] + ";" + name);
1291 } 1291 }
1292 1292
1293 writer.WriteElementString("Description", item.Description); 1293 writer.WriteElementString("Description", item.Description);
diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs
index e518329..22e233a 100644
--- a/OpenSim/Services/HypergridService/HGAssetService.cs
+++ b/OpenSim/Services/HypergridService/HGAssetService.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Services.HypergridService
53 LogManager.GetLogger( 53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType); 54 MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 private string m_ProfileServiceURL; 56 private string m_HomeURL;
57 private IUserAccountService m_UserAccountService; 57 private IUserAccountService m_UserAccountService;
58 58
59 private UserAccountCache m_Cache; 59 private UserAccountCache m_Cache;
@@ -74,7 +74,10 @@ namespace OpenSim.Services.HypergridService
74 if (m_UserAccountService == null) 74 if (m_UserAccountService == null)
75 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll)); 75 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll));
76 76
77 m_ProfileServiceURL = assetConfig.GetString("ProfileServerURI", string.Empty); 77 // legacy configuration [obsolete]
78 m_HomeURL = assetConfig.GetString("ProfileServerURI", string.Empty);
79 // Preferred
80 m_HomeURL = assetConfig.GetString("HomeURI", m_HomeURL);
78 81
79 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); 82 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService);
80 } 83 }
@@ -134,13 +137,13 @@ namespace OpenSim.Services.HypergridService
134 137
135 UserAccount creator = m_Cache.GetUser(meta.CreatorID); 138 UserAccount creator = m_Cache.GetUser(meta.CreatorID);
136 if (creator != null) 139 if (creator != null)
137 meta.CreatorID = m_ProfileServiceURL + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName; 140 meta.CreatorID = meta.CreatorID + ";" + m_HomeURL + "/" + creator.FirstName + " " + creator.LastName;
138 } 141 }
139 142
140 protected byte[] AdjustIdentifiers(byte[] data) 143 protected byte[] AdjustIdentifiers(byte[] data)
141 { 144 {
142 string xml = Utils.BytesToString(data); 145 string xml = Utils.BytesToString(data);
143 return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, m_ProfileServiceURL, m_Cache, UUID.Zero)); 146 return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, m_HomeURL, m_Cache, UUID.Zero));
144 } 147 }
145 148
146 } 149 }
diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs
index 4eb61ba..daf8c3a 100644
--- a/OpenSim/Services/HypergridService/HGInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGInventoryService.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Services.HypergridService
55 55
56 protected new IXInventoryData m_Database; 56 protected new IXInventoryData m_Database;
57 57
58 private string m_ProfileServiceURL; 58 private string m_HomeURL;
59 private IUserAccountService m_UserAccountService; 59 private IUserAccountService m_UserAccountService;
60 60
61 private UserAccountCache m_Cache; 61 private UserAccountCache m_Cache;
@@ -100,7 +100,10 @@ namespace OpenSim.Services.HypergridService
100 if (m_UserAccountService == null) 100 if (m_UserAccountService == null)
101 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll)); 101 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll));
102 102
103 m_ProfileServiceURL = invConfig.GetString("ProfileServerURI", string.Empty); 103 // legacy configuration [obsolete]
104 m_HomeURL = invConfig.GetString("ProfileServerURI", string.Empty);
105 // Preferred
106 m_HomeURL = invConfig.GetString("HomeURI", m_HomeURL);
104 107
105 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); 108 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService);
106 } 109 }
@@ -321,7 +324,7 @@ namespace OpenSim.Services.HypergridService
321 324
322 // Adjust the creator data 325 // Adjust the creator data
323 if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) 326 if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty))
324 it.CreatorData = m_ProfileServiceURL + "/" + it.CreatorId + ";" + user.FirstName + " " + user.LastName; 327 it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName;
325 328
326 return it; 329 return it;
327 } 330 }
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example
index 49ee41a..668fabc 100644
--- a/bin/Robust.HG.ini.example
+++ b/bin/Robust.HG.ini.example
@@ -380,7 +380,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
380 ; For the InventoryServiceInConnector 380 ; For the InventoryServiceInConnector
381 LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService" 381 LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService"
382 UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" 382 UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
383 ProfileServerURI = "http://127.0.0.1:8002/user" 383 HomeURI = "http://127.0.0.1:8002"
384 384
385; * The interface that local users get when they are in other grids. 385; * The interface that local users get when they are in other grids.
386; * This restricts the access that the rest of the world has to 386; * This restricts the access that the rest of the world has to
@@ -389,7 +389,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
389[HGAssetService] 389[HGAssetService]
390 LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGAssetService" 390 LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGAssetService"
391 UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" 391 UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
392 ProfileServerURI = "http://127.0.0.1:8002/user" 392 HomeURI = "http://127.0.0.1:8002"
393 393
394[HGFriendsService] 394[HGFriendsService]
395 LocalServiceModule = "OpenSim.Services.FriendsService.dll:FriendsService" 395 LocalServiceModule = "OpenSim.Services.FriendsService.dll:FriendsService"
diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example
index e368249..815e08c 100644
--- a/bin/config-include/GridCommon.ini.example
+++ b/bin/config-include/GridCommon.ini.example
@@ -123,7 +123,7 @@
123 ; Change this to your server 123 ; Change this to your server
124 ; accessible from other grids 124 ; accessible from other grids
125 ; 125 ;
126 ProfileServerURI = "http://mygridserver.com:8002/user" 126 HomeURI = "http://mygridserver.com:8002/user"
127 Gatekeeper = "http://mygridserver.com:8002" 127 Gatekeeper = "http://mygridserver.com:8002"
128 ;; If you want to protect your assets from being copied by foreign visitors 128 ;; If you want to protect your assets from being copied by foreign visitors
129 ;; uncomment the next line. You may want to do this on sims that have licensed content. 129 ;; uncomment the next line. You may want to do this on sims that have licensed content.
diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example
index 84611ec..2f39218 100644
--- a/bin/config-include/StandaloneCommon.ini.example
+++ b/bin/config-include/StandaloneCommon.ini.example
@@ -48,13 +48,13 @@
48 AssetLoaderArgs = "assets/AssetSets.xml" 48 AssetLoaderArgs = "assets/AssetSets.xml"
49 49
50[HGInventoryService] 50[HGInventoryService]
51 ProfileServerURI = "http://127.0.0.1:9000/profiles" 51 HomeURI = "http://127.0.0.1:9000"
52 52
53[HGAssetService] 53[HGAssetService]
54 ProfileServerURI = "http://127.0.0.1:9000/profiles" 54 HomeURI = "http://127.0.0.1:9000"
55 55
56[HGInventoryAccessModule] 56[HGInventoryAccessModule]
57 ProfileServerURI = "http://127.0.0.1:9000/profiles" 57 HomeURI = "http://127.0.0.1:9000"
58 Gatekeeper = "http://127.0.0.1:9000" 58 Gatekeeper = "http://127.0.0.1:9000"
59 59
60 ;; If you want to protect your assets from being copied by foreign visitors 60 ;; If you want to protect your assets from being copied by foreign visitors