aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJohan Berntsson2008-03-04 05:31:54 +0000
committerJohan Berntsson2008-03-04 05:31:54 +0000
commit279e0061c515ee0a03036bef68eea9738273d785 (patch)
tree4502228eb7b87a760e0b0e67aded9d1d870d0bed
parentAdded copyright heaaders. Minor cleanup. (diff)
downloadopensim-SC_OLD-279e0061c515ee0a03036bef68eea9738273d785.zip
opensim-SC_OLD-279e0061c515ee0a03036bef68eea9738273d785.tar.gz
opensim-SC_OLD-279e0061c515ee0a03036bef68eea9738273d785.tar.bz2
opensim-SC_OLD-279e0061c515ee0a03036bef68eea9738273d785.tar.xz
Merged 3Di code that provides scene and avatar serialization, and plugin support for region move/split/merge. See ThirdParty/3Di/README.txt. Unless the new modules are used there should be no noticeable changes when running OpenSim.
-rw-r--r--OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs4
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs2
-rw-r--r--OpenSim/Framework/AvatarWearable.cs35
-rw-r--r--OpenSim/Framework/BlockingQueue.cs5
-rw-r--r--OpenSim/Framework/ClientManager.cs2
-rw-r--r--OpenSim/Framework/Data.MySQL/MySQLGridData.cs28
-rw-r--r--OpenSim/Framework/Data.MySQL/MySQLManager.cs42
-rw-r--r--OpenSim/Framework/Data.MySQL/Resources/CreateRegionsTable.sql3
-rw-r--r--OpenSim/Framework/Data.MySQL/Resources/UpgradeRegionsTableToVersion2.sql3
-rw-r--r--OpenSim/Framework/Data/RegionProfileData.cs10
-rw-r--r--OpenSim/Framework/IClientAPI.cs19
-rw-r--r--OpenSim/Framework/IScene.cs5
-rw-r--r--OpenSim/Framework/PacketPool.cs104
-rw-r--r--OpenSim/Framework/RegionInfo.cs23
-rw-r--r--OpenSim/Framework/SerializableRegionInfo.cs60
-rw-r--r--OpenSim/Framework/Util.cs58
-rw-r--r--OpenSim/Grid/GridServer/GridManager.cs76
-rw-r--r--OpenSim/Grid/GridServer/Main.cs1
-rw-r--r--OpenSim/Grid/UserServer/UserLoginService.cs8
-rw-r--r--OpenSim/Region/Application/OpenSimMain.cs152
-rw-r--r--OpenSim/Region/ClientStack/ClientView.cs145
-rw-r--r--OpenSim/Region/ClientStack/PacketQueue.cs12
-rw-r--r--OpenSim/Region/ClientStack/PacketServer.cs8
-rw-r--r--OpenSim/Region/ClientStack/RegionApplicationBase.cs11
-rw-r--r--OpenSim/Region/ClientStack/UDPServer.cs92
-rw-r--r--OpenSim/Region/Communications/OGS1/OGS1GridServices.cs28
-rw-r--r--OpenSim/Region/Environment/Scenes/AvatarAppearance.cs49
-rw-r--r--OpenSim/Region/Environment/Scenes/EntityBase.cs91
-rw-r--r--OpenSim/Region/Environment/Scenes/InnerScene.cs43
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs55
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectPart.cs119
-rw-r--r--OpenSim/Region/Environment/Scenes/ScenePresence.cs416
-rw-r--r--OpenSim/Region/Environment/Types/UpdateQueue.cs50
-rw-r--r--OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs13
-rw-r--r--ThirdParty/3Di/LoadBalancer/LoadBalancerPlugin.cs1101
-rw-r--r--ThirdParty/3Di/LoadBalancer/TcpClient.cs240
-rw-r--r--ThirdParty/3Di/LoadBalancer/TcpServer.cs219
-rw-r--r--ThirdParty/3Di/README.txt82
-rw-r--r--ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MonitorGUI/View.pm214
-rw-r--r--ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MyCGI.pm91
-rw-r--r--ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/monitor.cgi202
-rw-r--r--ThirdParty/3Di/RegionMonitor/ServerPlugin/RegionMonitorPlugin.cs129
-rw-r--r--ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs513
-rw-r--r--prebuild.xml64
44 files changed, 4502 insertions, 125 deletions
diff --git a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs
index ff88021..07c9def 100644
--- a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs
+++ b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs
@@ -66,7 +66,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
66 for (int i = 0; i < regionsToLoad.Length; i++) 66 for (int i = 0; i < regionsToLoad.Length; i++)
67 { 67 {
68 m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")"); 68 m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")");
69 openSim.CreateRegion(regionsToLoad[i]); 69 openSim.CreateRegion(regionsToLoad[i], true);
70 } 70 }
71 71
72 openSim.ModuleLoader.PostInitialise(); 72 openSim.ModuleLoader.PostInitialise();
@@ -96,7 +96,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
96 if (regionhandle == regionsToLoad[i].RegionHandle) 96 if (regionhandle == regionsToLoad[i].RegionHandle)
97 { 97 {
98 m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")"); 98 m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")");
99 openSim.CreateRegion(regionsToLoad[i]); 99 openSim.CreateRegion(regionsToLoad[i], true);
100 } 100 }
101 } 101 }
102 } 102 }
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index 005bfd7..fba0c3b 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -269,7 +269,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
269 newRegionData.MasterAvatarFirstName = (string) requestData["region_master_first"]; 269 newRegionData.MasterAvatarFirstName = (string) requestData["region_master_first"];
270 newRegionData.MasterAvatarLastName = (string) requestData["region_master_last"]; 270 newRegionData.MasterAvatarLastName = (string) requestData["region_master_last"];
271 271
272 m_app.CreateRegion(newRegionData); 272 m_app.CreateRegion(newRegionData, true);
273 273
274 responseData["created"] = "true"; 274 responseData["created"] = "true";
275 response.Value = responseData; 275 response.Value = responseData;
diff --git a/OpenSim/Framework/AvatarWearable.cs b/OpenSim/Framework/AvatarWearable.cs
index c7083f3..e7c2338 100644
--- a/OpenSim/Framework/AvatarWearable.cs
+++ b/OpenSim/Framework/AvatarWearable.cs
@@ -26,10 +26,14 @@
26* 26*
27*/ 27*/
28using libsecondlife; 28using libsecondlife;
29using System;
30using System.Runtime.Serialization;
31using System.Security.Permissions;
29 32
30namespace OpenSim.Framework 33namespace OpenSim.Framework
31{ 34{
32 public class AvatarWearable 35 [Serializable]
36 public class AvatarWearable : ISerializable
33 { 37 {
34 public LLUUID AssetID = new LLUUID("00000000-0000-0000-0000-000000000000"); 38 public LLUUID AssetID = new LLUUID("00000000-0000-0000-0000-000000000000");
35 public LLUUID ItemID = new LLUUID("00000000-0000-0000-0000-000000000000"); 39 public LLUUID ItemID = new LLUUID("00000000-0000-0000-0000-000000000000");
@@ -67,5 +71,32 @@ namespace OpenSim.Framework
67 return defaultWearables; 71 return defaultWearables;
68 } 72 }
69 } 73 }
74 protected AvatarWearable(SerializationInfo info, StreamingContext context)
75 {
76 //System.Console.WriteLine("AvatarWearable Deserialize BGN");
77 if (info == null)
78 {
79 throw new System.ArgumentNullException("info");
80 }
81
82 AssetID = new LLUUID((Guid)info.GetValue("AssetID", typeof(Guid)));
83 ItemID = new LLUUID((Guid)info.GetValue("ItemID", typeof(Guid)));
84
85 //System.Console.WriteLine("AvatarWearable Deserialize END");
86 }
87
88 [SecurityPermission(SecurityAction.LinkDemand,
89 Flags = SecurityPermissionFlag.SerializationFormatter)]
90 public virtual void GetObjectData(
91 SerializationInfo info, StreamingContext context)
92 {
93 if (info == null)
94 {
95 throw new System.ArgumentNullException("info");
96 }
97
98 info.AddValue("AssetID", AssetID.UUID);
99 info.AddValue("ItemID", ItemID.UUID);
100 }
70 } 101 }
71} \ No newline at end of file 102}
diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs
index e72884c..6f56782 100644
--- a/OpenSim/Framework/BlockingQueue.cs
+++ b/OpenSim/Framework/BlockingQueue.cs
@@ -69,5 +69,10 @@ namespace OpenSim.Framework
69 { 69 {
70 return m_queue.Count; 70 return m_queue.Count;
71 } 71 }
72
73 public T[] GetQueueArray()
74 {
75 return m_queue.ToArray();
76 }
72 } 77 }
73} 78}
diff --git a/OpenSim/Framework/ClientManager.cs b/OpenSim/Framework/ClientManager.cs
index cfdcbf0..39d8d99 100644
--- a/OpenSim/Framework/ClientManager.cs
+++ b/OpenSim/Framework/ClientManager.cs
@@ -137,7 +137,7 @@ namespace OpenSim.Framework
137 } 137 }
138 } 138 }
139 139
140 private uint[] GetAllCircuits(LLUUID agentId) 140 public uint[] GetAllCircuits(LLUUID agentId)
141 { 141 {
142 List<uint> circuits = new List<uint>(); 142 List<uint> circuits = new List<uint>();
143 // Wasteful, I know 143 // Wasteful, I know
diff --git a/OpenSim/Framework/Data.MySQL/MySQLGridData.cs b/OpenSim/Framework/Data.MySQL/MySQLGridData.cs
index 3737e48..eefb4e9 100644
--- a/OpenSim/Framework/Data.MySQL/MySQLGridData.cs
+++ b/OpenSim/Framework/Data.MySQL/MySQLGridData.cs
@@ -97,6 +97,11 @@ namespace OpenSim.Framework.Data.MySQL
97 database.ExecuteResourceSql("CreateRegionsTable.sql"); 97 database.ExecuteResourceSql("CreateRegionsTable.sql");
98 return; 98 return;
99 } 99 }
100 else if (oldVersion.Contains("Rev. 1"))
101 {
102 database.ExecuteResourceSql("UpgradeRegionsTableToVersion2.sql");
103 return;
104 }
100 } 105 }
101 106
102 #endregion 107 #endregion
@@ -260,6 +265,27 @@ namespace OpenSim.Framework.Data.MySQL
260 } 265 }
261 266
262 /// <summary> 267 /// <summary>
268 /// Deletes a profile from the database
269 /// </summary>
270 /// <param name="profile">The profile to delete</param>
271 /// <returns>Successful?</returns>
272 //public DataResponse DeleteProfile(RegionProfileData profile)
273 public DataResponse DeleteProfile(string uuid)
274 {
275 lock (database)
276 {
277 if (database.deleteRegion(uuid))
278 {
279 return DataResponse.RESPONSE_OK;
280 }
281 else
282 {
283 return DataResponse.RESPONSE_ERROR;
284 }
285 }
286 }
287
288 /// <summary>
263 /// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret. 289 /// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret.
264 /// </summary> 290 /// </summary>
265 /// <param name="uuid">The UUID of the challenger</param> 291 /// <param name="uuid">The UUID of the challenger</param>
@@ -328,4 +354,4 @@ namespace OpenSim.Framework.Data.MySQL
328 } 354 }
329 } 355 }
330 } 356 }
331} \ No newline at end of file 357}
diff --git a/OpenSim/Framework/Data.MySQL/MySQLManager.cs b/OpenSim/Framework/Data.MySQL/MySQLManager.cs
index ea11aa0..0410643 100644
--- a/OpenSim/Framework/Data.MySQL/MySQLManager.cs
+++ b/OpenSim/Framework/Data.MySQL/MySQLManager.cs
@@ -301,6 +301,7 @@ namespace OpenSim.Framework.Data.MySQL
301 301
302 // non-critical parts 302 // non-critical parts
303 retval.regionName = (string)reader["regionName"]; 303 retval.regionName = (string)reader["regionName"];
304 retval.originUUID = new LLUUID((string) reader["originUUID"]);
304 305
305 // Secrets 306 // Secrets
306 retval.regionRecvKey = (string) reader["regionRecvKey"]; 307 retval.regionRecvKey = (string) reader["regionRecvKey"];
@@ -752,13 +753,13 @@ namespace OpenSim.Framework.Data.MySQL
752 // server for the UUID of the region's owner (master avatar). It consists of the addition of the column and value to the relevant sql, 753 // server for the UUID of the region's owner (master avatar). It consists of the addition of the column and value to the relevant sql,
753 // as well as the related parameterization 754 // as well as the related parameterization
754 sql += 755 sql +=
755 "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort, owner_uuid) VALUES "; 756 "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort, owner_uuid, originUUID) VALUES ";
756 757
757 sql += "(?regionHandle, ?regionName, ?uuid, ?regionRecvKey, ?regionSecret, ?regionSendKey, ?regionDataURI, "; 758 sql += "(?regionHandle, ?regionName, ?uuid, ?regionRecvKey, ?regionSecret, ?regionSendKey, ?regionDataURI, ";
758 sql += 759 sql +=
759 "?serverIP, ?serverPort, ?serverURI, ?locX, ?locY, ?locZ, ?eastOverrideHandle, ?westOverrideHandle, ?southOverrideHandle, ?northOverrideHandle, ?regionAssetURI, ?regionAssetRecvKey, "; 760 "?serverIP, ?serverPort, ?serverURI, ?locX, ?locY, ?locZ, ?eastOverrideHandle, ?westOverrideHandle, ?southOverrideHandle, ?northOverrideHandle, ?regionAssetURI, ?regionAssetRecvKey, ";
760 sql += 761 sql +=
761 "?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort, ?owner_uuid)"; 762 "?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort, ?owner_uuid, ?originUUID)";
762 763
763 if (GRID_ONLY_UPDATE_NECESSARY_DATA) 764 if (GRID_ONLY_UPDATE_NECESSARY_DATA)
764 { 765 {
@@ -798,6 +799,7 @@ namespace OpenSim.Framework.Data.MySQL
798 parameters["?serverHttpPort"] = regiondata.httpPort.ToString(); 799 parameters["?serverHttpPort"] = regiondata.httpPort.ToString();
799 parameters["?serverRemotingPort"] = regiondata.remotingPort.ToString(); 800 parameters["?serverRemotingPort"] = regiondata.remotingPort.ToString();
800 parameters["?owner_uuid"] = regiondata.owner_uuid.ToString(); 801 parameters["?owner_uuid"] = regiondata.owner_uuid.ToString();
802 parameters["?originUUID"] = regiondata.originUUID.ToString();
801 803
802 bool returnval = false; 804 bool returnval = false;
803 805
@@ -821,5 +823,41 @@ namespace OpenSim.Framework.Data.MySQL
821 823
822 return returnval; 824 return returnval;
823 } 825 }
826 /// <summary>
827 /// Delete a region from the database
828 /// </summary>
829 /// <param name="profile">The region to insert</param>
830 /// <returns>Success?</returns>
831 //public bool deleteRegion(RegionProfileData regiondata)
832 public bool deleteRegion(string uuid)
833 {
834 bool returnval = false;
835
836 string sql =
837 "DELETE FROM regions WHERE uuid = ?uuid;";
838
839 Dictionary<string, string> parameters = new Dictionary<string, string>();
840
841 try
842 {
843 parameters["?uuid"] = uuid;
844
845 IDbCommand result = Query(sql, parameters);
846
847 int x;
848 if ((x = result.ExecuteNonQuery()) > 0)
849 {
850 returnval = true;
851 }
852 result.Dispose();
853 }
854 catch (Exception e)
855 {
856 m_log.Error(e.ToString());
857 return false;
858 }
859
860 return returnval;
861 }
824 } 862 }
825} 863}
diff --git a/OpenSim/Framework/Data.MySQL/Resources/CreateRegionsTable.sql b/OpenSim/Framework/Data.MySQL/Resources/CreateRegionsTable.sql
index 07b0d9b..23535af 100644
--- a/OpenSim/Framework/Data.MySQL/Resources/CreateRegionsTable.sql
+++ b/OpenSim/Framework/Data.MySQL/Resources/CreateRegionsTable.sql
@@ -23,8 +23,9 @@ CREATE TABLE `regions` (
23 `regionUserRecvKey` varchar(128) default NULL, 23 `regionUserRecvKey` varchar(128) default NULL,
24 `regionUserSendKey` varchar(128) default NULL, `regionMapTexture` varchar(36) default NULL, 24 `regionUserSendKey` varchar(128) default NULL, `regionMapTexture` varchar(36) default NULL,
25 `serverHttpPort` int(10) default NULL, `serverRemotingPort` int(10) default NULL, 25 `serverHttpPort` int(10) default NULL, `serverRemotingPort` int(10) default NULL,
26 `originUUID` varchar(36),
26 PRIMARY KEY (`uuid`), 27 PRIMARY KEY (`uuid`),
27 KEY `regionName` (`regionName`), 28 KEY `regionName` (`regionName`),
28 KEY `regionHandle` (`regionHandle`), 29 KEY `regionHandle` (`regionHandle`),
29 KEY `overrideHandles` (`eastOverrideHandle`,`westOverrideHandle`,`southOverrideHandle`,`northOverrideHandle`) 30 KEY `overrideHandles` (`eastOverrideHandle`,`westOverrideHandle`,`southOverrideHandle`,`northOverrideHandle`)
30) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Rev. 1'; 31) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Rev. 2';
diff --git a/OpenSim/Framework/Data.MySQL/Resources/UpgradeRegionsTableToVersion2.sql b/OpenSim/Framework/Data.MySQL/Resources/UpgradeRegionsTableToVersion2.sql
new file mode 100644
index 0000000..5880954
--- /dev/null
+++ b/OpenSim/Framework/Data.MySQL/Resources/UpgradeRegionsTableToVersion2.sql
@@ -0,0 +1,3 @@
1ALTER TABLE `regions`
2 ADD COLUMN `originUUID` varchar(36),
3COMMENT='Rev. 2';
diff --git a/OpenSim/Framework/Data/RegionProfileData.cs b/OpenSim/Framework/Data/RegionProfileData.cs
index f9f4283..e4b48b7 100644
--- a/OpenSim/Framework/Data/RegionProfileData.cs
+++ b/OpenSim/Framework/Data/RegionProfileData.cs
@@ -130,6 +130,12 @@ namespace OpenSim.Framework.Data
130 public LLUUID owner_uuid = LLUUID.Zero; 130 public LLUUID owner_uuid = LLUUID.Zero;
131 131
132 /// <summary> 132 /// <summary>
133 /// OGS/OpenSim Specific original ID for a region after move/split
134 /// </summary>
135 public LLUUID originUUID;
136
137
138 /// <summary>
133 /// Get Sim profile data from grid server when in grid mode 139 /// Get Sim profile data from grid server when in grid mode
134 /// </summary> 140 /// </summary>
135 /// <param name="region_uuid"></param> 141 /// <param name="region_uuid"></param>
@@ -162,7 +168,7 @@ namespace OpenSim.Framework.Data
162 simData.serverPort = Convert.ToUInt32((string) responseData["sim_port"]); 168 simData.serverPort = Convert.ToUInt32((string) responseData["sim_port"]);
163 simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]); 169 simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]);
164 simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]); 170 simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]);
165 simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/"; 171 simData.serverURI = (string)responseData["server_uri"];
166 simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/"; 172 simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/";
167 simData.UUID = new LLUUID((string) responseData["region_UUID"]); 173 simData.UUID = new LLUUID((string) responseData["region_UUID"]);
168 simData.regionName = (string) responseData["region_name"]; 174 simData.regionName = (string) responseData["region_name"];
@@ -205,7 +211,7 @@ namespace OpenSim.Framework.Data
205 simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]); 211 simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]);
206 simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]); 212 simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]);
207 simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/"; 213 simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/";
208 simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/"; 214 simData.serverURI = (string)responseData["server_uri"];
209 simData.UUID = new LLUUID((string) responseData["region_UUID"]); 215 simData.UUID = new LLUUID((string) responseData["region_UUID"]);
210 simData.regionName = (string) responseData["region_name"]; 216 simData.regionName = (string) responseData["region_name"];
211 217
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 5001f00..7a0a232 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -665,5 +665,24 @@ namespace OpenSim.Framework
665 void SendBlueBoxMessage(LLUUID FromAvatarID, LLUUID fromSessionID, String FromAvatarName, String Message); 665 void SendBlueBoxMessage(LLUUID FromAvatarID, LLUUID fromSessionID, String FromAvatarName, String Message);
666 666
667 void SendLogoutPacket(); 667 void SendLogoutPacket();
668 ClientInfo GetClientInfo();
669 void SetClientInfo(ClientInfo info);
670 void Terminate();
671 }
672
673 [Serializable]
674 public class ClientInfo
675 {
676 public byte[] usecircuit;
677 public EndPoint userEP;
678 public EndPoint proxyEP;
679 public sAgentCircuitData agentcircuit;
680
681 public Dictionary<uint, uint> pendingAcks;
682 public Dictionary<uint, byte[]> needAck;
683
684 public List<byte[]> out_packets;
685
686 public uint sequence;
668 } 687 }
669} 688}
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index 3445050..0bb0efb 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -38,7 +38,8 @@ namespace OpenSim.Framework
38 Down = 0, 38 Down = 0,
39 Up = 1, 39 Up = 1,
40 Crashed = 2, 40 Crashed = 2,
41 Starting = 3 41 Starting = 3,
42 SlaveScene = 4
42 } ; 43 } ;
43 44
44 public interface IScene 45 public interface IScene
@@ -63,4 +64,4 @@ namespace OpenSim.Framework
63 64
64 ClientManager ClientManager { get; } 65 ClientManager ClientManager { get; }
65 } 66 }
66} \ No newline at end of file 67}
diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Framework/PacketPool.cs
index 30b6d6a..2c44ae3 100644
--- a/OpenSim/Framework/PacketPool.cs
+++ b/OpenSim/Framework/PacketPool.cs
@@ -26,6 +26,7 @@
26* 26*
27*/ 27*/
28using System; 28using System;
29using System.Net;
29using System.Collections; 30using System.Collections;
30using libsecondlife.Packets; 31using libsecondlife.Packets;
31 32
@@ -33,29 +34,68 @@ namespace OpenSim.Framework
33{ 34{
34 public sealed class PacketPool 35 public sealed class PacketPool
35 { 36 {
37 static public void EncodeProxyMessage(byte[] bytes, ref int numBytes, EndPoint trueEP)
38 {
39 if( numBytes > 4090 ) // max UPD size = 4096
40 {
41 throw new Exception("ERROR: No space to encode the proxy EP");
42 }
43
44 ushort port = (ushort) ((IPEndPoint) trueEP).Port;
45 bytes[numBytes++] = (byte)(port % 256);
46 bytes[numBytes++] = (byte)(port / 256);
47
48 foreach (byte b in ((IPEndPoint)trueEP).Address.GetAddressBytes())
49 {
50 bytes[numBytes++] = b;
51 }
52
53 int x = numBytes;
54
55 DecodeProxyMessage(bytes, ref numBytes);
56
57 numBytes = x;
58 }
59
60 static public EndPoint DecodeProxyMessage(byte[] bytes, ref int numBytes)
61 {
62 // IPv4 Only
63 byte[] addr = new byte[4];
64
65 addr[3] = bytes[--numBytes];
66 addr[2] = bytes[--numBytes];
67 addr[1] = bytes[--numBytes];
68 addr[0] = bytes[--numBytes];
69
70 ushort port = (ushort)(bytes[--numBytes] * 256);
71 port += (ushort)bytes[--numBytes];
72
73 return (EndPoint) new IPEndPoint(new IPAddress(addr), (int)port);
74 }
75
36 // Set up a thread-safe singleton pattern 76 // Set up a thread-safe singleton pattern
37 static PacketPool() 77 static PacketPool()
38 { 78 {
39 } 79 }
40 80
41 private static readonly PacketPool instance = new PacketPool(); 81 static readonly PacketPool instance = new PacketPool();
42 82
43 public static PacketPool Instance 83 public static PacketPool Instance
44 { 84 {
45 get { return instance; } 85 get
86 {
87 return instance;
88 }
46 } 89 }
47 90
48 private Hashtable pool = new Hashtable(); 91 private Hashtable pool = new Hashtable();
49 92
50 public Packet GetPacket(PacketType type) 93 public Packet GetPacket(PacketType type) {
51 {
52 return Packet.BuildPacket(type);
53/* Skip until PacketPool performance problems have been resolved (mantis 281)
54 Packet packet = null; 94 Packet packet = null;
55 95
56 lock (pool) 96 lock(pool)
57 { 97 {
58 if (pool[type] == null || ((Stack) pool[type]).Count == 0) 98 if(pool[type] == null || ((Stack) pool[type]).Count == 0)
59 { 99 {
60 // Creating a new packet if we cannot reuse an old package 100 // Creating a new packet if we cannot reuse an old package
61 packet = Packet.BuildPacket(type); 101 packet = Packet.BuildPacket(type);
@@ -63,39 +103,16 @@ namespace OpenSim.Framework
63 else 103 else
64 { 104 {
65 // Recycle old packages 105 // Recycle old packages
66 packet = (Packet) ((Stack) pool[type]).Pop(); 106 packet=(Packet) ((Stack) pool[type]).Pop();
67 } 107 }
68 } 108 }
69 109
70 return packet; 110 return packet;
71*/
72 }
73
74 // Copied from LibSL, and added a check to avoid overwriting the
75 // buffer
76 private void ZeroDecodeCommand(byte[] src, byte[] dest)
77 {
78 for (int srcPos = 6, destPos = 6; destPos < 10; ++srcPos)
79 {
80 if (src[srcPos] == 0x00)
81 {
82 for (byte j = 0; j < src[srcPos + 1] && destPos < 10; ++j)
83 {
84 dest[destPos++] = 0x00;
85 }
86 ++srcPos;
87 }
88 else
89 {
90 dest[destPos++] = src[srcPos];
91 }
92 }
93 } 111 }
94 112
113 private byte[] decoded_header = new byte[10];
95 private PacketType GetType(byte[] bytes) 114 private PacketType GetType(byte[] bytes)
96 { 115 {
97 byte[] decoded_header = new byte[10];
98
99 ushort id; 116 ushort id;
100 libsecondlife.PacketFrequency freq; 117 libsecondlife.PacketFrequency freq;
101 118
@@ -103,7 +120,7 @@ namespace OpenSim.Framework
103 120
104 if((bytes[0] & libsecondlife.Helpers.MSG_ZEROCODED)!=0) 121 if((bytes[0] & libsecondlife.Helpers.MSG_ZEROCODED)!=0)
105 { 122 {
106 ZeroDecodeCommand(bytes, decoded_header); 123 libsecondlife.Helpers.ZeroDecodeCommand(bytes, decoded_header);
107 } 124 }
108 125
109 if (decoded_header[6] == 0xFF) 126 if (decoded_header[6] == 0xFF)
@@ -138,21 +155,22 @@ namespace OpenSim.Framework
138 return packet; 155 return packet;
139 } 156 }
140 157
141 public void ReturnPacket(Packet packet) 158 public void ReturnPacket(Packet packet) {
142 { 159 return; // packet pool disabled
143/* Skip until PacketPool performance problems have been resolved (mantis 281) 160
144 lock (pool) 161 lock(pool)
145 { 162 {
146 PacketType type = packet.Type; 163 PacketType type=packet.Type;
147 164
148 if (pool[type] == null) 165 if(pool[type] == null)
149 { 166 {
150 pool[type] = new Stack(); 167 pool[type] = new Stack();
151 } 168 }
152 169 if (((Stack)pool[type]).Count < 50)
153 ((Stack) pool[type]).Push(packet); 170 {
171 ((Stack)pool[type]).Push(packet);
172 }
154 } 173 }
155*/
156 } 174 }
157 } 175 }
158} 176}
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index f97db5c..43e2a24 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -71,6 +71,7 @@ namespace OpenSim.Framework
71 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; 71 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
72 RemotingAddress = ConvertFrom.RemotingAddress; 72 RemotingAddress = ConvertFrom.RemotingAddress;
73 RegionID = LLUUID.Zero; 73 RegionID = LLUUID.Zero;
74 ServerURI = ConvertFrom.ServerURI;
74 } 75 }
75 76
76 public LLUUID RegionID = LLUUID.Zero; 77 public LLUUID RegionID = LLUUID.Zero;
@@ -84,6 +85,19 @@ namespace OpenSim.Framework
84 } 85 }
85 public bool m_allow_alternate_ports; 86 public bool m_allow_alternate_ports;
86 87
88 public string m_serverURI;
89 public string ServerURI
90 {
91 get
92 {
93 return m_serverURI;
94 }
95 set
96 {
97 m_serverURI = value;
98 }
99 }
100
87 public string RemotingAddress; 101 public string RemotingAddress;
88 102
89 public IPEndPoint ExternalEndPoint 103 public IPEndPoint ExternalEndPoint
@@ -175,6 +189,8 @@ namespace OpenSim.Framework
175 public string MasterAvatarFirstName = String.Empty; 189 public string MasterAvatarFirstName = String.Empty;
176 public string MasterAvatarLastName = String.Empty; 190 public string MasterAvatarLastName = String.Empty;
177 public string MasterAvatarSandboxPassword = String.Empty; 191 public string MasterAvatarSandboxPassword = String.Empty;
192 public string proxyUrl = "";
193 public LLUUID originRegionID = LLUUID.Zero;
178 194
179 // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. 195 // Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
180 private EstateSettings m_estateSettings; 196 private EstateSettings m_estateSettings;
@@ -227,6 +243,10 @@ namespace OpenSim.Framework
227 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; 243 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
228 RemotingAddress = ConvertFrom.RemotingAddress; 244 RemotingAddress = ConvertFrom.RemotingAddress;
229 RegionID = LLUUID.Zero; 245 RegionID = LLUUID.Zero;
246 proxyUrl = ConvertFrom.ProxyUrl;
247 originRegionID = ConvertFrom.OriginRegionID;
248 RegionName = ConvertFrom.RegionName;
249 ServerURI = ConvertFrom.ServerURI;
230 } 250 }
231 251
232 public RegionInfo(SimpleRegionInfo ConvertFrom) 252 public RegionInfo(SimpleRegionInfo ConvertFrom)
@@ -239,6 +259,7 @@ namespace OpenSim.Framework
239 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; 259 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
240 RemotingAddress = ConvertFrom.RemotingAddress; 260 RemotingAddress = ConvertFrom.RemotingAddress;
241 RegionID = LLUUID.Zero; 261 RegionID = LLUUID.Zero;
262 ServerURI = ConvertFrom.ServerURI;
242 } 263 }
243 264
244 //not in use, should swap to nini though. 265 //not in use, should swap to nini though.
@@ -411,4 +432,4 @@ namespace OpenSim.Framework
411 432
412 } 433 }
413 } 434 }
414} \ No newline at end of file 435}
diff --git a/OpenSim/Framework/SerializableRegionInfo.cs b/OpenSim/Framework/SerializableRegionInfo.cs
index 077ed8d..48ddbdf 100644
--- a/OpenSim/Framework/SerializableRegionInfo.cs
+++ b/OpenSim/Framework/SerializableRegionInfo.cs
@@ -51,6 +51,10 @@ namespace OpenSim.Framework
51 m_remotingPort = ConvertFrom.RemotingPort; 51 m_remotingPort = ConvertFrom.RemotingPort;
52 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; 52 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
53 RemotingAddress = ConvertFrom.RemotingAddress; 53 RemotingAddress = ConvertFrom.RemotingAddress;
54 m_proxyUrl = ConvertFrom.proxyUrl;
55 OriginRegionID = ConvertFrom.originRegionID;
56 RegionName = ConvertFrom.RegionName;
57 ServerURI = ConvertFrom.ServerURI;
54 } 58 }
55 59
56 public SearializableRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) 60 public SearializableRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri)
@@ -157,5 +161,57 @@ namespace OpenSim.Framework
157 { 161 {
158 get { return Util.UIntsToLong((RegionLocX * (uint)Constants.RegionSize), (RegionLocY * (uint)Constants.RegionSize)); } 162 get { return Util.UIntsToLong((RegionLocX * (uint)Constants.RegionSize), (RegionLocY * (uint)Constants.RegionSize)); }
159 } 163 }
160 } 164
161} \ No newline at end of file 165 protected string m_proxyUrl;
166 public string ProxyUrl
167 {
168 get
169 {
170 return m_proxyUrl;
171 }
172 set
173 {
174 m_proxyUrl = value;
175 }
176 }
177
178 protected Guid m_originRegionID = LLUUID.Zero.UUID;
179 public LLUUID OriginRegionID
180 {
181 get
182 {
183 return new LLUUID(m_originRegionID);
184 }
185 set
186 {
187 m_originRegionID = value.UUID;
188 }
189 }
190
191 protected string m_regionName;
192 public string RegionName
193 {
194 get
195 {
196 return m_regionName;
197 }
198 set
199 {
200 m_regionName = value;
201 }
202 }
203
204 protected string m_serverURI;
205 public string ServerURI
206 {
207 get
208 {
209 return m_serverURI;
210 }
211 set
212 {
213 m_serverURI = value;
214 }
215 }
216 }
217}
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 35e795b..8ba6643 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -37,6 +37,8 @@ using System.Text;
37using libsecondlife; 37using libsecondlife;
38using Nini.Config; 38using Nini.Config;
39 39
40using System.Runtime.Serialization;
41using System.Runtime.Serialization.Formatters.Binary;
40namespace OpenSim.Framework 42namespace OpenSim.Framework
41{ 43{
42 public class Util 44 public class Util
@@ -509,7 +511,63 @@ namespace OpenSim.Framework
509 { 511 {
510 return ""; 512 return "";
511 } 513 }
514 }
515
516 public static void SerializeToFile(string filename, Object obj)
517 {
518 IFormatter formatter = new BinaryFormatter();
519 Stream stream = null;
520
521 try
522 {
523 stream = new FileStream(
524 filename, FileMode.Create,
525 FileAccess.Write, FileShare.None);
526
527 formatter.Serialize(stream, obj);
528 }
529 catch (Exception e)
530 {
531 System.Console.WriteLine(e.Message);
532 System.Console.WriteLine(e.StackTrace);
533 }
534 finally
535 {
536 if (stream != null)
537 {
538 stream.Close();
539 }
540 }
541 }
542
543 public static Object DeserializeFromFile(string filename)
544 {
545 IFormatter formatter = new BinaryFormatter();
546 Stream stream = null;
547 Object ret = null;
548
549 try
550 {
551 stream = new FileStream(
552 filename, FileMode.Open,
553 FileAccess.Read, FileShare.None);
554
555 ret = formatter.Deserialize(stream);
556 }
557 catch (Exception e)
558 {
559 System.Console.WriteLine(e.Message);
560 System.Console.WriteLine(e.StackTrace);
561 }
562 finally
563 {
564 if (stream != null)
565 {
566 stream.Close();
567 }
568 }
512 569
570 return ret;
513 } 571 }
514 } 572 }
515} 573}
diff --git a/OpenSim/Grid/GridServer/GridManager.cs b/OpenSim/Grid/GridServer/GridManager.cs
index e32f551..2e6a892 100644
--- a/OpenSim/Grid/GridServer/GridManager.cs
+++ b/OpenSim/Grid/GridServer/GridManager.cs
@@ -37,6 +37,7 @@ using OpenSim.Framework;
37using OpenSim.Framework.Console; 37using OpenSim.Framework.Console;
38using OpenSim.Framework.Data; 38using OpenSim.Framework.Data;
39using OpenSim.Framework.Servers; 39using OpenSim.Framework.Servers;
40using OpenSim.Framework.Data.MySQL;
40 41
41namespace OpenSim.Grid.GridServer 42namespace OpenSim.Grid.GridServer
42{ 43{
@@ -301,16 +302,20 @@ namespace OpenSim.Grid.GridServer
301 catch (KeyNotFoundException) { } 302 catch (KeyNotFoundException) { }
302 303
303 TheSim.regionHandle = Helpers.UIntsToLong((TheSim.regionLocX * Constants.RegionSize), (TheSim.regionLocY * Constants.RegionSize)); 304 TheSim.regionHandle = Helpers.UIntsToLong((TheSim.regionLocX * Constants.RegionSize), (TheSim.regionLocY * Constants.RegionSize));
304 TheSim.serverURI = "http://" + TheSim.serverIP + ":" + TheSim.serverPort + "/"; 305 TheSim.serverURI = (string)requestData["server_uri"];
306 Console.WriteLine("adding region " + TheSim.regionLocX + " , " + TheSim.regionLocY + " , " +
307 TheSim.serverURI);
305 308
306 TheSim.httpServerURI = "http://" + TheSim.serverIP + ":" + TheSim.httpPort + "/"; 309 TheSim.httpServerURI = "http://" + TheSim.serverIP + ":" + TheSim.httpPort + "/";
307 310
308 TheSim.regionName = (string)requestData["sim_name"]; 311 TheSim.regionName = (string)requestData["sim_name"];
309 TheSim.UUID = new LLUUID((string)requestData["UUID"]); 312 TheSim.UUID = new LLUUID((string)requestData["UUID"]);
313 TheSim.originUUID = new LLUUID((string) requestData["originUUID"]);
310 314
311 //make sure there is not an existing region at this location 315 //make sure there is not an existing region at this location
312 OldSim = getRegion(TheSim.regionHandle); 316 OldSim = getRegion(TheSim.regionHandle);
313 if (OldSim == null || OldSim.UUID == TheSim.UUID) 317 //if (OldSim == null || OldSim.UUID == TheSim.UUID)
318 if (OldSim == null || OldSim.UUID == TheSim.UUID || TheSim.UUID != TheSim.originUUID)
314 { 319 {
315 bool brandNew = ( OldSim == null && TheSim.regionRecvKey == config.SimSendKey && 320 bool brandNew = ( OldSim == null && TheSim.regionRecvKey == config.SimSendKey &&
316 TheSim.regionSendKey == config.SimRecvKey); 321 TheSim.regionSendKey == config.SimRecvKey);
@@ -502,6 +507,69 @@ namespace OpenSim.Grid.GridServer
502 507
503 /// <summary> 508 /// <summary>
504 /// Returns an XML RPC response to a simulator profile request 509 /// Returns an XML RPC response to a simulator profile request
510 /// Performed after moving a region.
511 /// </summary>
512 /// <param name="request"></param>
513 /// <returns></returns>
514 /// <param name="request">The XMLRPC Request</param>
515 /// <returns>Processing parameters</returns>
516 public XmlRpcResponse XmlRpcDeleteRegionMethod(XmlRpcRequest request)
517 {
518 XmlRpcResponse response = new XmlRpcResponse();
519 Hashtable responseData = new Hashtable();
520 response.Value = responseData;
521
522 //RegionProfileData TheSim = null;
523 string uuid = String.Empty;;
524 Hashtable requestData = (Hashtable) request.Params[0];
525 string myword;
526 if (requestData.ContainsKey("UUID")) {
527 //TheSim = getRegion(new LLUUID((string) requestData["UUID"]));
528 uuid = requestData["UUID"].ToString();
529 Console.WriteLine("deleting region " + uuid);
530// logToDB((new LLUUID((string)requestData["UUID"])).ToString(),"XmlRpcDeleteRegionMethod","", 5,"Attempting delete with UUID.");
531 }
532 else {
533 responseData["error"] = "No UUID or region_handle passed to grid server - unable to delete";
534 return response;
535 }
536
537 foreach (KeyValuePair<string, IGridData> kvp in _plugins) {
538 //OpenSim.Framework.Data.MySQL.MySQLGridData dbengine = new OpenSim.Framework.Data.MySQL.MySQLGridData();
539 try {
540 OpenSim.Framework.Data.MySQL.MySQLGridData mysqldata = (OpenSim.Framework.Data.MySQL.MySQLGridData)(kvp.Value);
541 //DataResponse insertResponse = mysqldata.DeleteProfile(TheSim);
542 DataResponse insertResponse = mysqldata.DeleteProfile(uuid);
543 switch (insertResponse) {
544 case DataResponse.RESPONSE_OK:
545 //MainLog.Instance.Verbose("grid", "Deleting region successful: " + uuid);
546 responseData["status"] = "Deleting region successful: " + uuid;
547 break;
548 case DataResponse.RESPONSE_ERROR:
549 //MainLog.Instance.Warn("storage", "Deleting region failed (Error): " + uuid);
550 responseData["status"] = "Deleting region failed (Error): " + uuid;
551 break;
552 case DataResponse.RESPONSE_INVALIDCREDENTIALS:
553 //MainLog.Instance.Warn("storage", "Deleting region failed (Invalid Credentials): " + uuid);
554 responseData["status"] = "Deleting region (Invalid Credentials): " + uuid;
555 break;
556 case DataResponse.RESPONSE_AUTHREQUIRED:
557 //MainLog.Instance.Warn("storage", "Deleting region failed (Authentication Required): " + uuid);
558 responseData["status"] = "Deleting region (Authentication Required): " + uuid;
559 break;
560 }
561 }
562 catch (Exception e) {
563 m_log.Error("storage Unable to delete region " + uuid + " via MySQL");
564 //MainLog.Instance.Warn("storage", e.ToString());
565 }
566 }
567
568 return response;
569 }
570
571 /// <summary>
572 /// Returns an XML RPC response to a simulator profile request
505 /// </summary> 573 /// </summary>
506 /// <param name="request"></param> 574 /// <param name="request"></param>
507 /// <returns></returns> 575 /// <returns></returns>
@@ -533,6 +601,7 @@ namespace OpenSim.Grid.GridServer
533 (string) requestData["region_handle"]); 601 (string) requestData["region_handle"]);
534 responseData["sim_ip"] = Util.GetHostFromDNS(simData.serverIP).ToString(); 602 responseData["sim_ip"] = Util.GetHostFromDNS(simData.serverIP).ToString();
535 responseData["sim_port"] = simData.serverPort.ToString(); 603 responseData["sim_port"] = simData.serverPort.ToString();
604 responseData["server_uri"] = simData.serverURI;
536 responseData["http_port"] = simData.httpPort.ToString(); 605 responseData["http_port"] = simData.httpPort.ToString();
537 responseData["remoting_port"] = simData.remotingPort.ToString(); 606 responseData["remoting_port"] = simData.remotingPort.ToString();
538 responseData["region_locx"] = simData.regionLocX.ToString(); 607 responseData["region_locx"] = simData.regionLocX.ToString();
@@ -798,8 +867,7 @@ namespace OpenSim.Grid.GridServer
798 } 867 }
799 } 868 }
800 869
801 TheSim.serverURI = "http://" + TheSim.serverIP + ":" + TheSim.serverPort + "/"; 870 TheSim.serverURI = "http://" + TheSim.serverIP + ":" + TheSim.serverPort + "/";
802
803 bool requirePublic = false; 871 bool requirePublic = false;
804 bool requireValid = true; 872 bool requireValid = true;
805 873
diff --git a/OpenSim/Grid/GridServer/Main.cs b/OpenSim/Grid/GridServer/Main.cs
index ff4a888..ff4cfa2 100644
--- a/OpenSim/Grid/GridServer/Main.cs
+++ b/OpenSim/Grid/GridServer/Main.cs
@@ -113,6 +113,7 @@ namespace OpenSim.Grid.GridServer
113 113
114 httpServer.AddXmlRPCHandler("simulator_login", m_gridManager.XmlRpcSimulatorLoginMethod); 114 httpServer.AddXmlRPCHandler("simulator_login", m_gridManager.XmlRpcSimulatorLoginMethod);
115 httpServer.AddXmlRPCHandler("simulator_data_request", m_gridManager.XmlRpcSimulatorDataRequestMethod); 115 httpServer.AddXmlRPCHandler("simulator_data_request", m_gridManager.XmlRpcSimulatorDataRequestMethod);
116 httpServer.AddXmlRPCHandler("simulator_after_region_moved", m_gridManager.XmlRpcDeleteRegionMethod);
116 httpServer.AddXmlRPCHandler("map_block", m_gridManager.XmlRpcMapBlockMethod); 117 httpServer.AddXmlRPCHandler("map_block", m_gridManager.XmlRpcMapBlockMethod);
117 118
118 // Message Server ---> Grid Server 119 // Message Server ---> Grid Server
diff --git a/OpenSim/Grid/UserServer/UserLoginService.cs b/OpenSim/Grid/UserServer/UserLoginService.cs
index 0b832f4..e03ac3a 100644
--- a/OpenSim/Grid/UserServer/UserLoginService.cs
+++ b/OpenSim/Grid/UserServer/UserLoginService.cs
@@ -99,8 +99,8 @@ namespace OpenSim.Grid.UserServer
99 //CFK: the next one for X & Y and comment this one. 99 //CFK: the next one for X & Y and comment this one.
100 //CFK: m_log.Info("[LOGIN]: CUSTOMISERESPONSE: Region X: " + SimInfo.regionLocX + 100 //CFK: m_log.Info("[LOGIN]: CUSTOMISERESPONSE: Region X: " + SimInfo.regionLocX +
101 //CFK: "; Region Y: " + SimInfo.regionLocY); 101 //CFK: "; Region Y: " + SimInfo.regionLocY);
102 response.SimAddress = Util.GetHostFromDNS(SimInfo.serverIP).ToString(); 102 response.SimAddress = Util.GetHostFromDNS(SimInfo.serverURI.Split(new char[] { '/', ':' })[3]).ToString();
103 response.SimPort = (uint) SimInfo.serverPort; 103 response.SimPort = uint.Parse(SimInfo.serverURI.Split(new char[] { '/', ':' })[4]);
104 response.RegionX = SimInfo.regionLocX; 104 response.RegionX = SimInfo.regionLocX;
105 response.RegionY = SimInfo.regionLocY; 105 response.RegionY = SimInfo.regionLocY;
106 106
@@ -190,8 +190,8 @@ namespace OpenSim.Grid.UserServer
190 m_log.Info("[LOGIN]: " + 190 m_log.Info("[LOGIN]: " +
191 "CUSTOMISERESPONSE: Region X: " + SimInfo.regionLocX + "; Region Y: " + 191 "CUSTOMISERESPONSE: Region X: " + SimInfo.regionLocX + "; Region Y: " +
192 SimInfo.regionLocY); 192 SimInfo.regionLocY);
193 response.SimAddress = Util.GetHostFromDNS(SimInfo.serverIP).ToString(); 193 response.SimAddress = Util.GetHostFromDNS(SimInfo.serverURI.Split(new char[] { '/', ':' })[3]).ToString();
194 response.SimPort = (uint) SimInfo.serverPort; 194 response.SimPort = uint.Parse(SimInfo.serverURI.Split(new char[] { '/', ':' })[4]);
195 response.RegionX = SimInfo.regionLocX; 195 response.RegionX = SimInfo.regionLocX;
196 response.RegionY = SimInfo.regionLocY; 196 response.RegionY = SimInfo.regionLocY;
197 197
diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs
index bdefd0f..2c9e50e 100644
--- a/OpenSim/Region/Application/OpenSimMain.cs
+++ b/OpenSim/Region/Application/OpenSimMain.cs
@@ -33,8 +33,6 @@ using System.IO;
33using System.Text; 33using System.Text;
34using System.Threading; 34using System.Threading;
35using System.Timers; 35using System.Timers;
36using libsecondlife;
37using Mono.Addins;
38using Nini.Config; 36using Nini.Config;
39using OpenSim.Framework; 37using OpenSim.Framework;
40using OpenSim.Framework.Communications.Cache; 38using OpenSim.Framework.Communications.Cache;
@@ -49,6 +47,13 @@ using OpenSim.Region.Environment.Interfaces;
49using OpenSim.Region.Environment.Scenes; 47using OpenSim.Region.Environment.Scenes;
50using OpenSim.Region.Physics.Manager; 48using OpenSim.Region.Physics.Manager;
51using Timer=System.Timers.Timer; 49using Timer=System.Timers.Timer;
50using System.Net;
51using Nwc.XmlRpc;
52using System.Collections;
53using System.Reflection;
54using libsecondlife;
55using Mono.Addins;
56using Mono.Addins.Description;
52 57
53namespace OpenSim 58namespace OpenSim
54{ 59{
@@ -57,6 +62,8 @@ namespace OpenSim
57 public class OpenSimMain : RegionApplicationBase, conscmd_callback 62 public class OpenSimMain : RegionApplicationBase, conscmd_callback
58 { 63 {
59 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 64 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
65 private string proxyUrl;
66 private int proxyOffset = 0;
60 67
61 private const string DEFAULT_PRIM_BACKUP_FILENAME = "prim-backup.xml"; 68 private const string DEFAULT_PRIM_BACKUP_FILENAME = "prim-backup.xml";
62 69
@@ -110,6 +117,16 @@ namespace OpenSim
110 get { return m_httpServer; } 117 get { return m_httpServer; }
111 } 118 }
112 119
120 public List<UDPServer> UdpServers
121 {
122 get { return m_udpServers; }
123 }
124
125 public List<RegionInfo> RegionData
126 {
127 get { return m_regionData; }
128 }
129
113 private ModuleLoader m_moduleLoader; 130 private ModuleLoader m_moduleLoader;
114 131
115 public ModuleLoader ModuleLoader 132 public ModuleLoader ModuleLoader
@@ -350,20 +367,34 @@ namespace OpenSim
350 m_httpServer.AddStreamHandler(new SimStatusHandler()); 367 m_httpServer.AddStreamHandler(new SimStatusHandler());
351 } 368 }
352 369
370 proxyUrl = ConfigSource.Configs["Network"].GetString("proxy_url", "");
371 proxyOffset = Int32.Parse(ConfigSource.Configs["Network"].GetString("proxy_offset", "0"));
372
353 // Create a ModuleLoader instance 373 // Create a ModuleLoader instance
354 m_moduleLoader = new ModuleLoader(m_config); 374 m_moduleLoader = new ModuleLoader(m_config);
355 375
356 ExtensionNodeList nodes = AddinManager.GetExtensionNodes("/OpenSim/Startup"); 376 ExtensionNodeList nodes = AddinManager.GetExtensionNodes("/OpenSim/Startup");
357 m_log.InfoFormat("[PLUGINS]: Loading {0} OpenSim application plugins", nodes.Count); 377 m_log.InfoFormat("[PLUGINS]: Loading {0} OpenSim application plugins", nodes.Count);
358
359 foreach (TypeExtensionNode node in nodes) 378 foreach (TypeExtensionNode node in nodes)
360 { 379 {
361 IApplicationPlugin plugin = (IApplicationPlugin)node.CreateInstance(); 380 // First load the proxy server (if present)
362 381 if(node.Path.Contains("Proxy"))
363 plugin.Initialise(this); 382 {
364 m_plugins.Add(plugin); 383 IApplicationPlugin plugin = (IApplicationPlugin)node.CreateInstance();
384 plugin.Initialise(this);
385 m_plugins.Add(plugin);
386 }
387 }
388 // then load the other modules
389 foreach (TypeExtensionNode node in nodes)
390 {
391 if(!node.Path.Contains("Proxy"))
392 {
393 IApplicationPlugin plugin = (IApplicationPlugin)node.CreateInstance();
394 plugin.Initialise(this);
395 m_plugins.Add(plugin);
396 }
365 } 397 }
366
367 // Start UDP servers 398 // Start UDP servers
368 //for (int i = 0; i < m_udpServers.Count; i++) 399 //for (int i = 0; i < m_udpServers.Count; i++)
369 //{ 400 //{
@@ -436,10 +467,25 @@ namespace OpenSim
436 return m_commsManager.AddUser(tempfirstname,templastname,tempPasswd,regX,regY); 467 return m_commsManager.AddUser(tempfirstname,templastname,tempPasswd,regX,regY);
437 } 468 }
438 469
439 public UDPServer CreateRegion(RegionInfo regionInfo) 470 public UDPServer CreateRegion(RegionInfo regionInfo, bool portadd_flag)
440 { 471 {
472 int port = regionInfo.InternalEndPoint.Port;
473 if ((proxyOffset != 0) && (portadd_flag))
474 {
475 // set proxy url to RegionInfo
476 regionInfo.proxyUrl = proxyUrl;
477
478 // set initial RegionID to originRegionID in RegionInfo. (it needs for loding prims)
479 regionInfo.originRegionID = regionInfo.RegionID;
480
481 // set initial ServerURI
482 regionInfo.ServerURI = "http://" + regionInfo.ExternalHostName
483 + ":" + regionInfo.InternalEndPoint.Port.ToString();
484
485 ProxyCommand(proxyUrl, "AddPort", port, port + proxyOffset, regionInfo.ExternalHostName);
486 }
441 UDPServer udpServer; 487 UDPServer udpServer;
442 Scene scene = SetupScene(regionInfo, out udpServer, m_permissions); 488 Scene scene = SetupScene(regionInfo, proxyOffset, out udpServer, m_permissions);
443 489
444 m_log.Info("[MODULES]: Loading Region's modules"); 490 m_log.Info("[MODULES]: Loading Region's modules");
445 491
@@ -546,7 +592,7 @@ namespace OpenSim
546 m_regionData.RemoveAt(RegionHandleElement); 592 m_regionData.RemoveAt(RegionHandleElement);
547 } 593 }
548 594
549 CreateRegion(whichRegion); 595 CreateRegion(whichRegion, true);
550 //UDPServer restartingRegion = CreateRegion(whichRegion); 596 //UDPServer restartingRegion = CreateRegion(whichRegion);
551 //restartingRegion.ServerListener(); 597 //restartingRegion.ServerListener();
552 //m_sceneManager.SendSimOnlineNotification(restartingRegion.RegionHandle); 598 //m_sceneManager.SendSimOnlineNotification(restartingRegion.RegionHandle);
@@ -594,6 +640,8 @@ namespace OpenSim
594 /// </summary> 640 /// </summary>
595 public virtual void Shutdown() 641 public virtual void Shutdown()
596 { 642 {
643 ProxyCommand(proxyUrl, "Stop");
644
597 if (m_startupCommandsFile != String.Empty) 645 if (m_startupCommandsFile != String.Empty)
598 { 646 {
599 RunCommandScript(m_shutdownCommandsFile); 647 RunCommandScript(m_shutdownCommandsFile);
@@ -609,7 +657,7 @@ namespace OpenSim
609 657
610 m_console.Close(); 658 m_console.Close();
611 Environment.Exit(0); 659 Environment.Exit(0);
612 } 660 }
613 661
614 private void RunAutoTimerScript(object sender, EventArgs e) 662 private void RunAutoTimerScript(object sender, EventArgs e)
615 { 663 {
@@ -882,9 +930,8 @@ namespace OpenSim
882 break; 930 break;
883 931
884 case "create-region": 932 case "create-region":
885 CreateRegion(new RegionInfo(cmdparams[0], "Regions/" + cmdparams[1],false)); 933 CreateRegion(new RegionInfo(cmdparams[0], "Regions/" + cmdparams[1],false), true);
886 break; 934 break;
887
888 case "remove-region": 935 case "remove-region":
889 string regName = CombineParams(cmdparams, 0); 936 string regName = CombineParams(cmdparams, 0);
890 937
@@ -1120,6 +1167,8 @@ namespace OpenSim
1120 presence.ControllingClient.CircuitCode, 1167 presence.ControllingClient.CircuitCode,
1121 ep, 1168 ep,
1122 regionName)); 1169 regionName));
1170 m_console.Notice(" {0}", (((ClientView)presence.ControllingClient).PacketProcessingEnabled)?"Active client":"Standby client");
1171
1123 } 1172 }
1124 1173
1125 break; 1174 break;
@@ -1167,5 +1216,80 @@ namespace OpenSim
1167 } 1216 }
1168 1217
1169 #endregion 1218 #endregion
1219 // TODO: remove me!! (almost same as XmlRpcCommand)
1220 public object ProxyCommand(string url, string methodName, params object[] args)
1221 {
1222 if(proxyUrl.Length==0) return null;
1223 return SendXmlRpcCommand(url, methodName, args);
1224 }
1225
1226 public object XmlRpcCommand(uint port, string methodName, params object[] args)
1227 {
1228 return SendXmlRpcCommand("http://localhost:"+port, methodName, args);
1229 }
1230
1231 public object XmlRpcCommand(string url, string methodName, params object[] args)
1232 {
1233 return SendXmlRpcCommand(url, methodName, args);
1234 }
1235
1236 private object SendXmlRpcCommand(string url, string methodName, object[] args)
1237 {
1238 try {
1239 //MainLog.Instance.Verbose("XMLRPC", "Sending command {0} to {1}", methodName, url);
1240 XmlRpcRequest client = new XmlRpcRequest(methodName, args);
1241 //MainLog.Instance.Verbose("XMLRPC", client.ToString());
1242 XmlRpcResponse response = client.Send(url, 6000);
1243 if(!response.IsFault) return response.Value;
1244 }
1245 catch(Exception e)
1246 {
1247 m_log.ErrorFormat("XMLRPC Failed to send command {0} to {1}: {2}", methodName, url, e.Message);
1248 }
1249 return null;
1250 }
1251
1252 /// <summary>
1253 /// Get the start time and up time of Region server
1254 /// </summary>
1255 /// <param name="starttime">The first out parameter describing when the Region server started</param>
1256 /// <param name="uptime">The second out parameter describing how long the Region server has run</param>
1257 public void GetRunTime(out string starttime, out string uptime)
1258 {
1259 starttime = m_startuptime.ToString();
1260 uptime = (DateTime.Now - m_startuptime).ToString();
1261 }
1262
1263 /// <summary>
1264 /// Get the number of the avatars in the Region server
1265 /// </summary>
1266 /// <param name="usernum">The first out parameter describing the number of all the avatars in the Region server</param>
1267 public void GetAvatarNumber(out int usernum)
1268 {
1269 int accounter = 0;
1270
1271 foreach (ScenePresence presence in m_sceneManager.GetCurrentSceneAvatars()) {
1272 //presence.RegionHandle;
1273 accounter++;
1274 }
1275
1276 usernum = accounter;
1277 }
1278
1279 /// <summary>
1280 /// Get the number of the avatars in the Region server
1281 /// </summary>
1282 /// <param name="usernum">The first out parameter describing the number of all the avatars in the Region server</param>
1283 public void GetRegionNumber(out int regionnum)
1284 {
1285 int accounter = 0;
1286 //List<string> regionNameList = new List<string>();
1287
1288 m_sceneManager.ForEachScene(delegate(Scene scene) {
1289 accounter++;
1290 });
1291 regionnum = accounter;
1292
1293 }
1170 } 1294 }
1171} 1295}
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs
index b719086..b5cd6fb 100644
--- a/OpenSim/Region/ClientStack/ClientView.cs
+++ b/OpenSim/Region/ClientStack/ClientView.cs
@@ -61,6 +61,8 @@ namespace OpenSim.Region.ClientStack
61 /* static variables */ 61 /* static variables */
62 public static TerrainManager TerrainManager; 62 public static TerrainManager TerrainManager;
63 63
64 public delegate bool SynchronizeClientHandler(IScene scene, Packet packet, LLUUID agentID, ThrottleOutPacketType throttlePacketType);
65 public static SynchronizeClientHandler SynchronizeClient = null;
64 /* private variables */ 66 /* private variables */
65 private readonly LLUUID m_sessionId; 67 private readonly LLUUID m_sessionId;
66 private LLUUID m_secureSessionId = LLUUID.Zero; 68 private LLUUID m_secureSessionId = LLUUID.Zero;
@@ -118,6 +120,7 @@ namespace OpenSim.Region.ClientStack
118 protected Thread m_clientThread; 120 protected Thread m_clientThread;
119 protected LLVector3 m_startpos; 121 protected LLVector3 m_startpos;
120 protected EndPoint m_userEndPoint; 122 protected EndPoint m_userEndPoint;
123 protected EndPoint m_proxyEndPoint;
121 124
122 /* Instantiated Designated Event Delegates */ 125 /* Instantiated Designated Event Delegates */
123 //- used so we don't create new objects for each incoming packet and then toss it out later */ 126 //- used so we don't create new objects for each incoming packet and then toss it out later */
@@ -291,7 +294,7 @@ namespace OpenSim.Region.ClientStack
291 /* METHODS */ 294 /* METHODS */
292 295
293 public ClientView(EndPoint remoteEP, IScene scene, AssetCache assetCache, PacketServer packServer, 296 public ClientView(EndPoint remoteEP, IScene scene, AssetCache assetCache, PacketServer packServer,
294 AgentCircuitManager authenSessions, LLUUID agentId, LLUUID sessionId, uint circuitCode) 297 AgentCircuitManager authenSessions, LLUUID agentId, LLUUID sessionId, uint circuitCode, EndPoint proxyEP)
295 { 298 {
296 m_moneyBalance = 1000; 299 m_moneyBalance = 1000;
297 300
@@ -311,6 +314,7 @@ namespace OpenSim.Region.ClientStack
311 m_circuitCode = circuitCode; 314 m_circuitCode = circuitCode;
312 315
313 m_userEndPoint = remoteEP; 316 m_userEndPoint = remoteEP;
317 m_proxyEndPoint = proxyEP;
314 318
315 m_startpos = m_authenticateSessionsHandler.GetPosition(circuitCode); 319 m_startpos = m_authenticateSessionsHandler.GetPosition(circuitCode);
316 320
@@ -411,7 +415,37 @@ namespace OpenSim.Region.ClientStack
411 415
412 public void Stop() 416 public void Stop()
413 { 417 {
414 m_log.Info("[BUG]: Stop called, please find out where and remove it"); 418 // Shut down timers
419 m_ackTimer.Stop();
420 m_clientPingTimer.Stop();
421 }
422
423 public void Restart()
424 {
425 // re-construct
426 m_pendingAcks = new Dictionary<uint, uint>();
427 m_needAck = new Dictionary<uint, Packet>();
428 m_sequence += 1000000;
429
430 m_ackTimer = new Timer(750);
431 m_ackTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
432 m_ackTimer.Start();
433
434 m_clientPingTimer = new Timer(5000);
435 m_clientPingTimer.Elapsed += new ElapsedEventHandler(CheckClientConnectivity);
436 m_clientPingTimer.Enabled = true;
437 }
438
439 public void Terminate()
440 {
441 // disable blocking queue
442 m_packetQueue.Enqueue(null);
443
444 // wait for thread stoped
445 m_clientThread.Join();
446
447 // delete circuit code
448 m_networkServer.CloseClient(this);
415 } 449 }
416 450
417 #endregion 451 #endregion
@@ -507,6 +541,10 @@ namespace OpenSim.Region.ClientStack
507 while (true) 541 while (true)
508 { 542 {
509 QueItem nextPacket = m_packetQueue.Dequeue(); 543 QueItem nextPacket = m_packetQueue.Dequeue();
544 if (nextPacket == null)
545 {
546 break;
547 }
510 if (nextPacket.Incoming) 548 if (nextPacket.Incoming)
511 { 549 {
512 if (nextPacket.Packet.Type != PacketType.AgentUpdate) 550 if (nextPacket.Packet.Type != PacketType.AgentUpdate)
@@ -2642,7 +2680,7 @@ namespace OpenSim.Region.ClientStack
2642 try 2680 try
2643 { 2681 {
2644 byte[] sendbuffer = Pack.ToBytes(); 2682 byte[] sendbuffer = Pack.ToBytes();
2645 PacketPool.Instance.ReturnPacket(Pack); 2683 PacketPool.Instance.ReturnPacket(Pack);
2646 2684
2647 if (Pack.Header.Zerocoded) 2685 if (Pack.Header.Zerocoded)
2648 { 2686 {
@@ -2651,8 +2689,11 @@ namespace OpenSim.Region.ClientStack
2651 } 2689 }
2652 else 2690 else
2653 { 2691 {
2654 m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode); 2692 //Need some extra space in case we need to add proxy information to the message later
2693 Buffer.BlockCopy(sendbuffer, 0, ZeroOutBuffer, 0, sendbuffer.Length);
2694 m_networkServer.SendPacketTo(ZeroOutBuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode);
2655 } 2695 }
2696
2656 } 2697 }
2657 catch (Exception e) 2698 catch (Exception e)
2658 { 2699 {
@@ -2666,6 +2707,12 @@ namespace OpenSim.Region.ClientStack
2666 2707
2667 public virtual void InPacket(Packet NewPack) 2708 public virtual void InPacket(Packet NewPack)
2668 { 2709 {
2710 if(!m_packetProcessingEnabled && NewPack.Type != PacketType.LogoutRequest)
2711 {
2712 PacketPool.Instance.ReturnPacket(NewPack);
2713 return;
2714 }
2715
2669 // Handle appended ACKs 2716 // Handle appended ACKs
2670 if (NewPack != null) 2717 if (NewPack != null)
2671 { 2718 {
@@ -2726,6 +2773,15 @@ namespace OpenSim.Region.ClientStack
2726 2773
2727 public virtual void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType) 2774 public virtual void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType)
2728 { 2775 {
2776 if ((SynchronizeClient != null) && (!PacketProcessingEnabled))
2777 {
2778 // Sending packet to active client's server.
2779 if (SynchronizeClient(m_scene, NewPack, m_agentId, throttlePacketType))
2780 {
2781 return;
2782 }
2783 }
2784
2729 QueItem item = new QueItem(); 2785 QueItem item = new QueItem();
2730 item.Packet = NewPack; 2786 item.Packet = NewPack;
2731 item.Incoming = false; 2787 item.Incoming = false;
@@ -2853,6 +2909,13 @@ namespace OpenSim.Region.ClientStack
2853 } 2909 }
2854 } 2910 }
2855 2911
2912 private bool m_packetProcessingEnabled = true;
2913
2914 public bool PacketProcessingEnabled {
2915 get { return m_packetProcessingEnabled; }
2916 set { m_packetProcessingEnabled = value; }
2917 }
2918
2856 protected void ProcessInPacket(Packet Pack) 2919 protected void ProcessInPacket(Packet Pack)
2857 { 2920 {
2858 ack_pack(Pack); 2921 ack_pack(Pack);
@@ -4373,5 +4436,79 @@ namespace OpenSim.Region.ClientStack
4373 4436
4374 OutPacket(logReply, ThrottleOutPacketType.Task); 4437 OutPacket(logReply, ThrottleOutPacketType.Task);
4375 } 4438 }
4439
4440 public ClientInfo GetClientInfo()
4441 {
4442 //MainLog.Instance.Verbose("CLIENT", "GetClientInfo BGN");
4443
4444 ClientInfo info = new ClientInfo();
4445 info.userEP = this.m_userEndPoint;
4446 info.proxyEP = this.m_proxyEndPoint;
4447 info.agentcircuit = new sAgentCircuitData(RequestClientInfo());
4448
4449 info.pendingAcks = m_pendingAcks;
4450
4451 info.needAck = new Dictionary<uint,byte[]>();
4452
4453 lock (m_needAck)
4454 {
4455 foreach (uint key in m_needAck.Keys)
4456 {
4457 info.needAck.Add(key, m_needAck[key].ToBytes());
4458 }
4459 }
4460
4461/* pending
4462 QueItem[] queitems = m_packetQueue.GetQueueArray();
4463
4464 MainLog.Instance.Verbose("CLIENT", "Queue Count : [{0}]", queitems.Length);
4465
4466 for (int i = 0; i < queitems.Length; i++)
4467 {
4468 if (queitems[i].Incoming == false)
4469 {
4470 info.out_packets.Add(queitems[i].Packet.ToBytes());
4471 MainLog.Instance.Verbose("CLIENT", "Add OutPacket [{0}]", queitems[i].Packet.Type.ToString());
4472 }
4473 }
4474*/
4475
4476 info.sequence = m_sequence;
4477
4478 //MainLog.Instance.Verbose("CLIENT", "GetClientInfo END");
4479
4480 return info;
4481 }
4482
4483 public void SetClientInfo(ClientInfo info)
4484 {
4485 m_pendingAcks = info.pendingAcks;
4486
4487 m_needAck = new Dictionary<uint,Packet>();
4488
4489 Packet packet = null;
4490 int packetEnd = 0;
4491 byte[] zero = new byte[3000];
4492
4493 foreach (uint key in info.needAck.Keys)
4494 {
4495 byte[] buff = info.needAck[key];
4496
4497 packetEnd = buff.Length - 1;
4498
4499 try
4500 {
4501 packet = PacketPool.Instance.GetPacket(buff, ref packetEnd, zero);
4502 }
4503 catch (Exception)
4504 {
4505 //MainLog.Instance.Debug("UDPSERVER", e.ToString());
4506 }
4507
4508 m_needAck.Add(key, packet);
4509 }
4510
4511 m_sequence = info.sequence;
4512 }
4376 } 4513 }
4377} 4514}
diff --git a/OpenSim/Region/ClientStack/PacketQueue.cs b/OpenSim/Region/ClientStack/PacketQueue.cs
index a04828f..82f96e8 100644
--- a/OpenSim/Region/ClientStack/PacketQueue.cs
+++ b/OpenSim/Region/ClientStack/PacketQueue.cs
@@ -142,8 +142,13 @@ namespace OpenSim.Region.ClientStack
142 // We could micro lock, but that will tend to actually 142 // We could micro lock, but that will tend to actually
143 // probably be worse than just synchronizing on SendQueue 143 // probably be worse than just synchronizing on SendQueue
144 144
145 lock (this) 145 if (item == null)
146 { 146 {
147 SendQueue.Enqueue(item);
148 return;
149 }
150
151 lock (this) {
147 switch (item.throttleType) 152 switch (item.throttleType)
148 { 153 {
149 case ThrottleOutPacketType.Resend: 154 case ThrottleOutPacketType.Resend:
@@ -518,5 +523,10 @@ namespace OpenSim.Region.ClientStack
518 TextureOutgoingPacketQueue.Count, 523 TextureOutgoingPacketQueue.Count,
519 AssetOutgoingPacketQueue.Count); 524 AssetOutgoingPacketQueue.Count);
520 } 525 }
526
527 public QueItem[] GetQueueArray()
528 {
529 return SendQueue.GetQueueArray();
530 }
521 } 531 }
522} 532}
diff --git a/OpenSim/Region/ClientStack/PacketServer.cs b/OpenSim/Region/ClientStack/PacketServer.cs
index 250b90a..02ae79b 100644
--- a/OpenSim/Region/ClientStack/PacketServer.cs
+++ b/OpenSim/Region/ClientStack/PacketServer.cs
@@ -74,14 +74,14 @@ namespace OpenSim.Region.ClientStack
74 protected virtual IClientAPI CreateNewClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, 74 protected virtual IClientAPI CreateNewClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack,
75 ClientManager clientManager, IScene scene, AssetCache assetCache, 75 ClientManager clientManager, IScene scene, AssetCache assetCache,
76 PacketServer packServer, AgentCircuitManager authenSessions, 76 PacketServer packServer, AgentCircuitManager authenSessions,
77 LLUUID agentId, LLUUID sessionId, uint circuitCode) 77 LLUUID agentId, LLUUID sessionId, uint circuitCode, EndPoint proxyEP)
78 { 78 {
79 return 79 return
80 new ClientView(remoteEP, scene, assetCache, packServer, authenSessions, agentId, sessionId, circuitCode); 80 new ClientView(remoteEP, scene, assetCache, packServer, authenSessions, agentId, sessionId, circuitCode, proxyEP);
81 } 81 }
82 82
83 public virtual bool AddNewClient(EndPoint epSender, UseCircuitCodePacket useCircuit, AssetCache assetCache, 83 public virtual bool AddNewClient(EndPoint epSender, UseCircuitCodePacket useCircuit, AssetCache assetCache,
84 AgentCircuitManager authenticateSessionsClass) 84 AgentCircuitManager authenticateSessionsClass, EndPoint proxyEP)
85 { 85 {
86 IClientAPI newuser; 86 IClientAPI newuser;
87 87
@@ -93,7 +93,7 @@ namespace OpenSim.Region.ClientStack
93 { 93 {
94 newuser = CreateNewClient(epSender, useCircuit, m_scene.ClientManager, m_scene, assetCache, this, 94 newuser = CreateNewClient(epSender, useCircuit, m_scene.ClientManager, m_scene, assetCache, this,
95 authenticateSessionsClass, useCircuit.CircuitCode.ID, 95 authenticateSessionsClass, useCircuit.CircuitCode.ID,
96 useCircuit.CircuitCode.SessionID, useCircuit.CircuitCode.Code); 96 useCircuit.CircuitCode.SessionID, useCircuit.CircuitCode.Code, proxyEP);
97 97
98 m_scene.ClientManager.Add(useCircuit.CircuitCode.Code, newuser); 98 m_scene.ClientManager.Add(useCircuit.CircuitCode.Code, newuser);
99 99
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
index a760712..660c3b3 100644
--- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs
+++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
@@ -104,13 +104,18 @@ namespace OpenSim.Region.ClientStack
104 104
105 protected Scene SetupScene(RegionInfo regionInfo, out UDPServer udpServer, bool m_permissions) 105 protected Scene SetupScene(RegionInfo regionInfo, out UDPServer udpServer, bool m_permissions)
106 { 106 {
107 return SetupScene(regionInfo, 0, out udpServer, m_permissions);
108 }
109
110 protected Scene SetupScene(RegionInfo regionInfo, int proxyOffset, out UDPServer udpServer, bool m_permissions)
111 {
107 AgentCircuitManager circuitManager = new AgentCircuitManager(); 112 AgentCircuitManager circuitManager = new AgentCircuitManager();
108 IPAddress listenIP = regionInfo.InternalEndPoint.Address; 113 IPAddress listenIP = regionInfo.InternalEndPoint.Address;
109 //if (!IPAddress.TryParse(regionInfo.InternalEndPoint, out listenIP)) 114 //if (!IPAddress.TryParse(regionInfo.InternalEndPoint, out listenIP))
110 // listenIP = IPAddress.Parse("0.0.0.0"); 115 // listenIP = IPAddress.Parse("0.0.0.0");
111 116
112 uint port = (uint) regionInfo.InternalEndPoint.Port; 117 uint port = (uint) regionInfo.InternalEndPoint.Port;
113 udpServer = new UDPServer(listenIP, ref port, regionInfo.m_allow_alternate_ports, m_assetCache, circuitManager); 118 udpServer = new UDPServer(listenIP, ref port, proxyOffset, regionInfo.m_allow_alternate_ports, m_assetCache, circuitManager);
114 regionInfo.InternalEndPoint.Port = (int)port; 119 regionInfo.InternalEndPoint.Port = (int)port;
115 120
116 Scene scene = CreateScene(regionInfo, m_storageManager, circuitManager); 121 Scene scene = CreateScene(regionInfo, m_storageManager, circuitManager);
@@ -148,8 +153,8 @@ namespace OpenSim.Region.ClientStack
148 scene.RegionInfo.MasterAvatarAssignedUUID = LLUUID.Zero; 153 scene.RegionInfo.MasterAvatarAssignedUUID = LLUUID.Zero;
149 } 154 }
150 155
151 scene.LoadPrimsFromStorage(m_permissions); 156 scene.LoadPrimsFromStorage(m_permissions, regionInfo.originRegionID);
152 scene.loadAllLandObjectsFromStorage(); 157 scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
153 scene.performParcelPrimCountUpdate(); 158 scene.performParcelPrimCountUpdate();
154 scene.StartTimer(); 159 scene.StartTimer();
155 return scene; 160 return scene;
diff --git a/OpenSim/Region/ClientStack/UDPServer.cs b/OpenSim/Region/ClientStack/UDPServer.cs
index 9c572cf..5501d3f 100644
--- a/OpenSim/Region/ClientStack/UDPServer.cs
+++ b/OpenSim/Region/ClientStack/UDPServer.cs
@@ -43,12 +43,15 @@ namespace OpenSim.Region.ClientStack
43 43
44 protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>(); 44 protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
45 public Dictionary<uint, EndPoint> clientCircuits_reverse = new Dictionary<uint, EndPoint>(); 45 public Dictionary<uint, EndPoint> clientCircuits_reverse = new Dictionary<uint, EndPoint>();
46 protected Dictionary<uint, EndPoint> proxyCircuits = new Dictionary<uint, EndPoint>();
46 public Socket Server; 47 public Socket Server;
47 protected IPEndPoint ServerIncoming; 48 protected IPEndPoint ServerIncoming;
48 protected byte[] RecvBuffer = new byte[4096]; 49 protected byte[] RecvBuffer = new byte[4096];
49 protected byte[] ZeroBuffer = new byte[8192]; 50 protected byte[] ZeroBuffer = new byte[8192];
50 protected IPEndPoint ipeSender; 51 protected IPEndPoint ipeSender;
51 protected EndPoint epSender; 52 protected EndPoint epSender;
53 protected EndPoint epProxy;
54 protected int proxyPortOffset;
52 protected AsyncCallback ReceivedData; 55 protected AsyncCallback ReceivedData;
53 protected PacketServer m_packetServer; 56 protected PacketServer m_packetServer;
54 protected ulong m_regionHandle; 57 protected ulong m_regionHandle;
@@ -85,10 +88,11 @@ namespace OpenSim.Region.ClientStack
85 { 88 {
86 } 89 }
87 90
88 public UDPServer(IPAddress _listenIP, ref uint port, bool allow_alternate_port, AssetCache assetCache, AgentCircuitManager authenticateClass) 91 public UDPServer(IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, AssetCache assetCache, AgentCircuitManager authenticateClass)
89 { 92 {
93 this.proxyPortOffset = proxyPortOffset;
94 listenPort = (uint) (port + proxyPortOffset);
90 listenIP = _listenIP; 95 listenIP = _listenIP;
91 listenPort = port;
92 Allow_Alternate_Port = allow_alternate_port; 96 Allow_Alternate_Port = allow_alternate_port;
93 m_assetCache = assetCache; 97 m_assetCache = assetCache;
94 m_authenticateSessionsClass = authenticateClass; 98 m_authenticateSessionsClass = authenticateClass;
@@ -97,7 +101,7 @@ namespace OpenSim.Region.ClientStack
97 // Return new port 101 // Return new port
98 // This because in Grid mode it is not really important what port the region listens to as long as it is correctly registered. 102 // This because in Grid mode it is not really important what port the region listens to as long as it is correctly registered.
99 // So the option allow_alternate_ports="true" was added to default.xml 103 // So the option allow_alternate_ports="true" was added to default.xml
100 port = listenPort; 104 port = (uint)(listenPort - proxyPortOffset);
101 } 105 }
102 106
103 protected virtual void CreatePacketServer() 107 protected virtual void CreatePacketServer()
@@ -211,6 +215,13 @@ namespace OpenSim.Region.ClientStack
211 //return; 215 //return;
212 } 216 }
213 217
218 //System.Console.WriteLine("UDPServer : recieved message from {0}", epSender.ToString());
219 epProxy = epSender;
220 if (proxyPortOffset != 0)
221 {
222 epSender = PacketPool.DecodeProxyMessage(RecvBuffer, ref numBytes);
223 }
224
214 int packetEnd = numBytes - 1; 225 int packetEnd = numBytes - 1;
215 226
216 try 227 try
@@ -318,6 +329,9 @@ namespace OpenSim.Region.ClientStack
318 329
319 protected virtual void AddNewClient(Packet packet) 330 protected virtual void AddNewClient(Packet packet)
320 { 331 {
332 //Slave regions don't accept new clients
333 if(m_localScene.Region_Status != RegionStatus.SlaveScene)
334 {
321 UseCircuitCodePacket useCircuit = (UseCircuitCodePacket) packet; 335 UseCircuitCodePacket useCircuit = (UseCircuitCodePacket) packet;
322 lock (clientCircuits) 336 lock (clientCircuits)
323 { 337 {
@@ -334,7 +348,17 @@ namespace OpenSim.Region.ClientStack
334 m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding."); 348 m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
335 } 349 }
336 350
337 PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_authenticateSessionsClass); 351 lock (proxyCircuits)
352 {
353 if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
354 proxyCircuits.Add(useCircuit.CircuitCode.Code, epProxy);
355 else
356 m_log.Error("[UDPSERVER]: proxyCircuits already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
357 }
358
359 PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_authenticateSessionsClass, epProxy);
360 }
361 PacketPool.Instance.ReturnPacket(packet);
338 } 362 }
339 363
340 public void ServerListener() 364 public void ServerListener()
@@ -387,10 +411,20 @@ namespace OpenSim.Region.ClientStack
387 lock (clientCircuits_reverse) 411 lock (clientCircuits_reverse)
388 { 412 {
389 if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto)) 413 if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto))
390 { 414 {
391 //we found the endpoint so send the packet to it 415 //we found the endpoint so send the packet to it
392 Server.SendTo(buffer, size, flags, sendto); 416 if (proxyPortOffset != 0)
393 } 417 {
418 //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo proxy " + proxyCircuits[circuitcode].ToString() + ": client " + sendto.ToString());
419 PacketPool.EncodeProxyMessage(buffer, ref size, sendto);
420 Server.SendTo(buffer, size, flags, proxyCircuits[circuitcode]);
421 }
422 else
423 {
424 //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo : client " + sendto.ToString());
425 Server.SendTo(buffer, size, flags, sendto);
426 }
427 }
394 } 428 }
395 } 429 }
396 430
@@ -404,8 +438,50 @@ namespace OpenSim.Region.ClientStack
404 clientCircuits.Remove(sendto); 438 clientCircuits.Remove(sendto);
405 439
406 clientCircuits_reverse.Remove(circuitcode); 440 clientCircuits_reverse.Remove(circuitcode);
441 proxyCircuits.Remove(circuitcode);
407 } 442 }
408 } 443 }
409 } 444 }
445
446 public void RestoreClient(AgentCircuitData circuit, EndPoint userEP, EndPoint proxyEP)
447 {
448 //MainLog.Instance.Verbose("UDPSERVER", "RestoreClient");
449
450 UseCircuitCodePacket useCircuit = new UseCircuitCodePacket();
451 useCircuit.CircuitCode.Code = circuit.circuitcode;
452 useCircuit.CircuitCode.ID = circuit.AgentID;
453 useCircuit.CircuitCode.SessionID = circuit.SessionID;
454
455 lock (clientCircuits)
456 {
457 if (!clientCircuits.ContainsKey(userEP))
458 clientCircuits.Add(userEP, useCircuit.CircuitCode.Code);
459 else
460 m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
461 }
462 lock (clientCircuits_reverse)
463 {
464 if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code))
465 clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, userEP);
466 else
467 m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
468 }
469
470 lock (proxyCircuits)
471 {
472 if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
473 {
474 proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
475 }
476 else
477 {
478 // re-set proxy endpoint
479 proxyCircuits.Remove(useCircuit.CircuitCode.Code);
480 proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
481 }
482 }
483
484 PacketServer.AddNewClient(userEP, useCircuit, m_assetCache, m_authenticateSessionsClass, proxyEP);
485 }
410 } 486 }
411} 487}
diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
index 12c91ac..cdafad3 100644
--- a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
+++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
@@ -111,6 +111,8 @@ namespace OpenSim.Region.Communications.OGS1
111 GridParams["http_port"] = serversInfo.HttpListenerPort.ToString(); 111 GridParams["http_port"] = serversInfo.HttpListenerPort.ToString();
112 GridParams["remoting_port"] = NetworkServersInfo.RemotingListenerPort.ToString(); 112 GridParams["remoting_port"] = NetworkServersInfo.RemotingListenerPort.ToString();
113 GridParams["map-image-id"] = regionInfo.EstateSettings.terrainImageID.ToString(); 113 GridParams["map-image-id"] = regionInfo.EstateSettings.terrainImageID.ToString();
114 GridParams["originUUID"] = regionInfo.originRegionID.ToString();
115 GridParams["server_uri"] = regionInfo.ServerURI;
114 116
115 // part of an initial brutish effort to provide accurate information (as per the xml region spec) 117 // part of an initial brutish effort to provide accurate information (as per the xml region spec)
116 // wrt the ownership of a given region 118 // wrt the ownership of a given region
@@ -165,7 +167,30 @@ namespace OpenSim.Region.Communications.OGS1
165 167
166 public bool DeregisterRegion(RegionInfo regionInfo) 168 public bool DeregisterRegion(RegionInfo regionInfo)
167 { 169 {
168 return false; 170 Hashtable GridParams = new Hashtable();
171
172 GridParams["UUID"] = regionInfo.RegionID.ToString();
173
174 // Package into an XMLRPC Request
175 ArrayList SendParams = new ArrayList();
176 SendParams.Add(GridParams);
177
178 // Send Request
179 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_after_region_moved", SendParams);
180 XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 10000);
181 Hashtable GridRespData = (Hashtable) GridResp.Value;
182
183 Hashtable griddatahash = GridRespData;
184
185 // Process Response
186 if (GridRespData.ContainsKey("error")) {
187 string errorstring = (string)GridRespData["error"];
188 m_log.Error("Unable to connect to grid: " + errorstring);
189 return false;
190 }
191
192 // What does DeregisterRegion() do?
193 return m_localBackend.DeregisterRegion(regionInfo);
169 } 194 }
170 195
171 public virtual Dictionary<string, string> GetGridSettings() 196 public virtual Dictionary<string, string> GetGridSettings()
@@ -1209,7 +1234,6 @@ namespace OpenSim.Region.Communications.OGS1
1209 } 1234 }
1210 1235
1211 return m_localBackend.TriggerRegionUp(new RegionInfo(regionData), regionhandle); 1236 return m_localBackend.TriggerRegionUp(new RegionInfo(regionData), regionhandle);
1212
1213 } 1237 }
1214 1238
1215 catch (RemotingException e) 1239 catch (RemotingException e)
diff --git a/OpenSim/Region/Environment/Scenes/AvatarAppearance.cs b/OpenSim/Region/Environment/Scenes/AvatarAppearance.cs
index b54f777..fcc8fdf 100644
--- a/OpenSim/Region/Environment/Scenes/AvatarAppearance.cs
+++ b/OpenSim/Region/Environment/Scenes/AvatarAppearance.cs
@@ -26,13 +26,16 @@
26* 26*
27*/ 27*/
28 28
29using System;
29using libsecondlife; 30using libsecondlife;
30using libsecondlife.Packets; 31using libsecondlife.Packets;
31using OpenSim.Framework; 32using OpenSim.Framework;
32 33using System.Runtime.Serialization;
34using System.Security.Permissions;
33namespace OpenSim.Region.Environment.Scenes 35namespace OpenSim.Region.Environment.Scenes
34{ 36{
35 public class AvatarAppearance 37 [Serializable]
38 public class AvatarAppearance : ISerializable
36 { 39 {
37 protected LLUUID m_scenePresenceID; 40 protected LLUUID m_scenePresenceID;
38 41
@@ -149,5 +152,45 @@ namespace OpenSim.Region.Environment.Scenes
149 textu.CreateFace(6).TextureID = new LLUUID("00000000-0000-1111-9999-000000000011"); 152 textu.CreateFace(6).TextureID = new LLUUID("00000000-0000-1111-9999-000000000011");
150 return textu; 153 return textu;
151 } 154 }
155
156 protected AvatarAppearance(SerializationInfo info, StreamingContext context)
157 {
158 //System.Console.WriteLine("AvatarAppearance Deserialize BGN");
159
160 if (info == null)
161 {
162 throw new System.ArgumentNullException("info");
163 }
164
165 m_scenePresenceID = new LLUUID((Guid)info.GetValue("m_scenePresenceID", typeof(Guid)));
166 m_wearablesSerial = (int)info.GetValue("m_wearablesSerial", typeof(int));
167 m_visualParams = (byte[])info.GetValue("m_visualParams", typeof(byte[]));
168 m_wearables = (AvatarWearable[])info.GetValue("m_wearables", typeof(AvatarWearable[]));
169
170 byte[] m_textureEntry_work = (byte[])info.GetValue("m_textureEntry", typeof(byte[]));
171 m_textureEntry = new LLObject.TextureEntry(m_textureEntry_work, 0, m_textureEntry_work.Length);
172
173 m_avatarHeight = (float)info.GetValue("m_avatarHeight", typeof(float));
174
175 //System.Console.WriteLine("AvatarAppearance Deserialize END");
176 }
177
178 [SecurityPermission(SecurityAction.LinkDemand,
179 Flags = SecurityPermissionFlag.SerializationFormatter)]
180 public virtual void GetObjectData(
181 SerializationInfo info, StreamingContext context)
182 {
183 if (info == null)
184 {
185 throw new System.ArgumentNullException("info");
186 }
187
188 info.AddValue("m_scenePresenceID", m_scenePresenceID.UUID);
189 info.AddValue("m_wearablesSerial", m_wearablesSerial);
190 info.AddValue("m_visualParams", m_visualParams);
191 info.AddValue("m_wearables", m_wearables);
192 info.AddValue("m_textureEntry", m_textureEntry.ToBytes());
193 info.AddValue("m_avatarHeight", m_avatarHeight);
194 }
152 } 195 }
153} \ No newline at end of file 196}
diff --git a/OpenSim/Region/Environment/Scenes/EntityBase.cs b/OpenSim/Region/Environment/Scenes/EntityBase.cs
index 91dda74..2a8c1e9 100644
--- a/OpenSim/Region/Environment/Scenes/EntityBase.cs
+++ b/OpenSim/Region/Environment/Scenes/EntityBase.cs
@@ -30,9 +30,14 @@ using System.Collections.Generic;
30using Axiom.Math; 30using Axiom.Math;
31using libsecondlife; 31using libsecondlife;
32 32
33using System;
34using System.Runtime.Serialization;
35using System.Security.Permissions;
36
33namespace OpenSim.Region.Environment.Scenes 37namespace OpenSim.Region.Environment.Scenes
34{ 38{
35 public abstract class EntityBase 39 [Serializable]
40 public abstract class EntityBase : ISerializable
36 { 41 {
37 protected Scene m_scene; 42 protected Scene m_scene;
38 43
@@ -134,6 +139,90 @@ namespace OpenSim.Region.Environment.Scenes
134 139
135 140
136 public abstract void SetText(string text, Vector3 color, double alpha); 141 public abstract void SetText(string text, Vector3 color, double alpha);
142
143 protected EntityBase(SerializationInfo info, StreamingContext context)
144 {
145 //System.Console.WriteLine("EntityBase Deserialize BGN");
146
147 if (info == null)
148 {
149 throw new System.ArgumentNullException("info");
150 }
151
152 //JB m_children = (List<EntityBase>)info.GetValue("m_children", typeof(List<EntityBase>));
153// m_scene = (Scene)info.GetValue("m_scene", typeof(Scene));
154 m_uuid = new LLUUID((Guid)info.GetValue("m_uuid", typeof(Guid)));
155 m_name = (string)info.GetValue("m_name", typeof(string));
156
157 m_pos
158 = new LLVector3(
159 (float)info.GetValue("m_pos.X", typeof(float)),
160 (float)info.GetValue("m_pos.Y", typeof(float)),
161 (float)info.GetValue("m_pos.Z", typeof(float)));
162
163 m_velocity
164 = new LLVector3(
165 (float)info.GetValue("m_velocity.X", typeof(float)),
166 (float)info.GetValue("m_velocity.Y", typeof(float)),
167 (float)info.GetValue("m_velocity.Z", typeof(float)));
168
169 m_rotationalvelocity
170 = new LLVector3(
171 (float)info.GetValue("m_rotationalvelocity.X", typeof(float)),
172 (float)info.GetValue("m_rotationalvelocity.Y", typeof(float)),
173 (float)info.GetValue("m_rotationalvelocity.Z", typeof(float)));
174
175 m_rotation
176 = new Quaternion(
177 (float)info.GetValue("m_rotation.w", typeof(float)),
178 (float)info.GetValue("m_rotation.x", typeof(float)),
179 (float)info.GetValue("m_rotation.y", typeof(float)),
180 (float)info.GetValue("m_rotation.z", typeof(float)));
181
182 m_localId = (uint)info.GetValue("m_localId", typeof(uint));
183
184 //System.Console.WriteLine("EntityBase Deserialize END");
185 }
186
187 [SecurityPermission(SecurityAction.LinkDemand,
188 Flags = SecurityPermissionFlag.SerializationFormatter)]
189 public virtual void GetObjectData(
190 SerializationInfo info, StreamingContext context)
191 {
192 if (info == null)
193 {
194 throw new System.ArgumentNullException("info");
195 }
196
197 //JB info.AddValue("m_children", m_children);
198
199// info.AddValue("m_scene", m_scene);
200 info.AddValue("m_uuid", m_uuid.UUID);
201 info.AddValue("m_name", m_name);
202
203 // LLVector3
204 info.AddValue("m_pos.X", m_pos.X);
205 info.AddValue("m_pos.Y", m_pos.Y);
206 info.AddValue("m_pos.Z", m_pos.Z);
207
208 // LLVector3
209 info.AddValue("m_velocity.X", m_velocity.X);
210 info.AddValue("m_velocity.Y", m_velocity.Y);
211 info.AddValue("m_velocity.Z", m_velocity.Z);
212
213 // LLVector3
214 info.AddValue("m_rotationalvelocity.X", m_rotationalvelocity.X);
215 info.AddValue("m_rotationalvelocity.Y", m_rotationalvelocity.Y);
216 info.AddValue("m_rotationalvelocity.Z", m_rotationalvelocity.Z);
217
218 // Quaternion
219 info.AddValue("m_rotation.w", m_rotation.w);
220 info.AddValue("m_rotation.x", m_rotation.x);
221 info.AddValue("m_rotation.y", m_rotation.y);
222 info.AddValue("m_rotation.z", m_rotation.z);
223
224 info.AddValue("m_localId", m_localId);
225 }
137 } 226 }
138 227
139 //Nested Classes 228 //Nested Classes
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs
index 860f5fb..882e589 100644
--- a/OpenSim/Region/Environment/Scenes/InnerScene.cs
+++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs
@@ -57,6 +57,7 @@ namespace OpenSim.Region.Environment.Scenes
57 // SceneObjects is not currently populated or used. 57 // SceneObjects is not currently populated or used.
58 //public Dictionary<LLUUID, SceneObjectGroup> SceneObjects; 58 //public Dictionary<LLUUID, SceneObjectGroup> SceneObjects;
59 public Dictionary<LLUUID, EntityBase> Entities; 59 public Dictionary<LLUUID, EntityBase> Entities;
60 public Dictionary<LLUUID, ScenePresence> RestorePresences;
60 61
61 public BasicQuadTreeNode QuadTree; 62 public BasicQuadTreeNode QuadTree;
62 63
@@ -455,6 +456,48 @@ namespace OpenSim.Region.Environment.Scenes
455 return newAvatar; 456 return newAvatar;
456 } 457 }
457 458
459 public void AddScenePresence(ScenePresence presence)
460 {
461 bool child = presence.IsChildAgent;
462
463 if (child)
464 {
465 m_numChildAgents++;
466 m_log.Info("[SCENE]"+ m_regInfo.RegionName + ": Creating new child agent.");
467 }
468 else
469 {
470 m_numRootAgents++;
471 m_log.Info("[SCENE] "+ m_regInfo.RegionName + ": Creating new root agent.");
472 m_log.Info("[SCENE] "+ m_regInfo.RegionName + ": Adding Physical agent.");
473
474 presence.AddToPhysicalScene();
475 }
476
477 lock (Entities)
478 {
479 if (!Entities.ContainsKey(presence.m_uuid))
480 {
481 Entities.Add(presence.m_uuid, presence);
482 }
483 else
484 {
485 Entities[presence.m_uuid] = presence;
486 }
487 }
488 lock (ScenePresences)
489 {
490 if (ScenePresences.ContainsKey(presence.m_uuid))
491 {
492 ScenePresences[presence.m_uuid] = presence;
493 }
494 else
495 {
496 ScenePresences.Add(presence.m_uuid, presence);
497 }
498 }
499 }
500
458 public void SwapRootChildAgent(bool direction_RC_CR_T_F) 501 public void SwapRootChildAgent(bool direction_RC_CR_T_F)
459 { 502 {
460 if (direction_RC_CR_T_F) 503 if (direction_RC_CR_T_F)
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 845de22..43e7e99 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -54,6 +54,10 @@ namespace OpenSim.Region.Environment.Scenes
54 54
55 public partial class Scene : SceneBase 55 public partial class Scene : SceneBase
56 { 56 {
57 public delegate void SynchronizeSceneHandler(Scene scene);
58 public SynchronizeSceneHandler SynchronizeScene = null;
59 public int splitID = 0;
60
57 #region Fields 61 #region Fields
58 62
59 protected Timer m_heartbeatTimer = new Timer(); 63 protected Timer m_heartbeatTimer = new Timer();
@@ -216,7 +220,11 @@ namespace OpenSim.Region.Environment.Scenes
216 get { return m_innerScene.Entities; } 220 get { return m_innerScene.Entities; }
217 set { m_innerScene.Entities = value; } 221 set { m_innerScene.Entities = value; }
218 } 222 }
219 223 public Dictionary<LLUUID, ScenePresence> m_restorePresences
224 {
225 get { return m_innerScene.RestorePresences; }
226 set { m_innerScene.RestorePresences = value; }
227 }
220 #endregion 228 #endregion
221 229
222 #region Constructors 230 #region Constructors
@@ -276,6 +284,7 @@ namespace OpenSim.Region.Environment.Scenes
276 Entities = new Dictionary<LLUUID, EntityBase>(); 284 Entities = new Dictionary<LLUUID, EntityBase>();
277 m_scenePresences = new Dictionary<LLUUID, ScenePresence>(); 285 m_scenePresences = new Dictionary<LLUUID, ScenePresence>();
278 //m_sceneObjects = new Dictionary<LLUUID, SceneObjectGroup>(); 286 //m_sceneObjects = new Dictionary<LLUUID, SceneObjectGroup>();
287 m_restorePresences = new Dictionary<LLUUID, ScenePresence>();
279 288
280 m_log.Info("[SCENE]: Creating LandMap"); 289 m_log.Info("[SCENE]: Creating LandMap");
281 Terrain = new TerrainEngine((int)RegionInfo.RegionLocX, (int)RegionInfo.RegionLocY); 290 Terrain = new TerrainEngine((int)RegionInfo.RegionLocX, (int)RegionInfo.RegionLocY);
@@ -701,6 +710,8 @@ namespace OpenSim.Region.Environment.Scenes
701 physicsFPS = m_innerScene.UpdatePhysics( 710 physicsFPS = m_innerScene.UpdatePhysics(
702 Math.Max(SinceLastFrame.TotalSeconds, m_timespan) 711 Math.Max(SinceLastFrame.TotalSeconds, m_timespan)
703 ); 712 );
713 if (m_frame % m_update_physics == 0 && SynchronizeScene != null)
714 SynchronizeScene(this);
704 715
705 physicsMS = System.Environment.TickCount - physicsMS; 716 physicsMS = System.Environment.TickCount - physicsMS;
706 physicsMS += physicsMS2; 717 physicsMS += physicsMS2;
@@ -719,6 +730,8 @@ namespace OpenSim.Region.Environment.Scenes
719 if (m_frame % m_update_presences == 0) 730 if (m_frame % m_update_presences == 0)
720 m_innerScene.UpdatePresences(); 731 m_innerScene.UpdatePresences();
721 732
733 if (Region_Status != RegionStatus.SlaveScene)
734 {
722 if (m_frame % m_update_events == 0) 735 if (m_frame % m_update_events == 0)
723 UpdateEvents(); 736 UpdateEvents();
724 737
@@ -747,7 +760,7 @@ namespace OpenSim.Region.Environment.Scenes
747 m_statsReporter.addOtherMS(otherMS); 760 m_statsReporter.addOtherMS(otherMS);
748 m_statsReporter.SetActiveScripts(m_innerScene.GetActiveScripts()); 761 m_statsReporter.SetActiveScripts(m_innerScene.GetActiveScripts());
749 m_statsReporter.addScriptLines(m_innerScene.GetScriptLPS()); 762 m_statsReporter.addScriptLines(m_innerScene.GetScriptLPS());
750 763 }
751 } 764 }
752 catch (NotImplementedException) 765 catch (NotImplementedException)
753 { 766 {
@@ -1058,10 +1071,10 @@ namespace OpenSim.Region.Environment.Scenes
1058 1071
1059 #region Load Land 1072 #region Load Land
1060 1073
1061 public void loadAllLandObjectsFromStorage() 1074 public void loadAllLandObjectsFromStorage(LLUUID regionID)
1062 { 1075 {
1063 m_log.Info("[SCENE]: Loading land objects from storage"); 1076 m_log.Info("[SCENE]: Loading land objects from storage");
1064 List<LandData> landData = m_storageManager.DataStore.LoadLandObjects(RegionInfo.RegionID); 1077 List<LandData> landData = m_storageManager.DataStore.LoadLandObjects(regionID);
1065 1078
1066 if (landData.Count == 0) 1079 if (landData.Count == 0)
1067 { 1080 {
@@ -1080,11 +1093,11 @@ namespace OpenSim.Region.Environment.Scenes
1080 /// <summary> 1093 /// <summary>
1081 /// Loads the World's objects 1094 /// Loads the World's objects
1082 /// </summary> 1095 /// </summary>
1083 public virtual void LoadPrimsFromStorage(bool m_permissions) 1096 public virtual void LoadPrimsFromStorage(bool m_permissions, LLUUID regionID)
1084 { 1097 {
1085 m_log.Info("[SCENE]: Loading objects from datastore"); 1098 m_log.Info("[SCENE]: Loading objects from datastore");
1086 1099
1087 List<SceneObjectGroup> PrimsFromDB = m_storageManager.DataStore.LoadObjects(m_regInfo.RegionID); 1100 List<SceneObjectGroup> PrimsFromDB = m_storageManager.DataStore.LoadObjects(regionID);
1088 foreach (SceneObjectGroup group in PrimsFromDB) 1101 foreach (SceneObjectGroup group in PrimsFromDB)
1089 { 1102 {
1090 AddEntityFromStorage(group); 1103 AddEntityFromStorage(group);
@@ -1339,13 +1352,35 @@ namespace OpenSim.Region.Environment.Scenes
1339 { 1352 {
1340 m_log.Warn("[CONNECTION DEBUGGING]: Creating new client for " + client.AgentId.ToString()); 1353 m_log.Warn("[CONNECTION DEBUGGING]: Creating new client for " + client.AgentId.ToString());
1341 SubscribeToClientEvents(client); 1354 SubscribeToClientEvents(client);
1355 ScenePresence presence = null;
1356
1357 if (m_restorePresences.ContainsKey(client.AgentId))
1358 {
1359 m_log.Info("REGION Restore Scene Presence");
1360
1361 presence = m_restorePresences[client.AgentId];
1362 m_restorePresences.Remove(client.AgentId);
1363
1364 presence.initializeScenePresence(client, RegionInfo, this);
1365
1366 m_innerScene.AddScenePresence(presence);
1342 1367
1343 m_estateManager.sendRegionHandshake(client); 1368 lock (m_restorePresences)
1369 {
1370 Monitor.PulseAll(m_restorePresences);
1371 }
1372 }
1373 else
1374 {
1375 m_log.Info("REGION Add New Scene Presence");
1344 1376
1345 CreateAndAddScenePresence(client, child); 1377 m_estateManager.sendRegionHandshake(client);
1346 1378
1347 m_LandManager.sendParcelOverlay(client); 1379 CreateAndAddScenePresence(client, child);
1348 CommsManager.UserProfileCacheService.AddNewUser(client.AgentId); 1380
1381 m_LandManager.sendParcelOverlay(client);
1382 CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
1383 }
1349 } 1384 }
1350 1385
1351 protected virtual void SubscribeToClientEvents(IClientAPI client) 1386 protected virtual void SubscribeToClientEvents(IClientAPI client)
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index a6a5063..46bb89c 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -39,6 +39,8 @@ using OpenSim.Framework.Console;
39using OpenSim.Region.Environment.Interfaces; 39using OpenSim.Region.Environment.Interfaces;
40using OpenSim.Region.Environment.Scenes.Scripting; 40using OpenSim.Region.Environment.Scenes.Scripting;
41using OpenSim.Region.Physics.Manager; 41using OpenSim.Region.Physics.Manager;
42using System.Runtime.Serialization;
43using System.Security.Permissions;
42 44
43namespace OpenSim.Region.Environment.Scenes 45namespace OpenSim.Region.Environment.Scenes
44{ 46{
@@ -82,7 +84,8 @@ namespace OpenSim.Region.Environment.Scenes
82 SCALE = 0x40 84 SCALE = 0x40
83 } 85 }
84 86
85 public partial class SceneObjectPart : IScriptHost 87 [Serializable]
88 public partial class SceneObjectPart : IScriptHost, ISerializable
86 { 89 {
87 90
88 [XmlIgnore] public PhysicsActor PhysActor = null; 91 [XmlIgnore] public PhysicsActor PhysActor = null;
@@ -1859,5 +1862,119 @@ namespace OpenSim.Region.Environment.Scenes
1859 (int) (color.z*0xff)); 1862 (int) (color.z*0xff));
1860 Text = text; 1863 Text = text;
1861 } 1864 }
1865
1866 protected SceneObjectPart(SerializationInfo info, StreamingContext context)
1867 {
1868 //System.Console.WriteLine("SceneObjectPart Deserialize BGN");
1869
1870 if (info == null)
1871 {
1872 throw new System.ArgumentNullException("info");
1873 }
1874
1875 /*
1876 m_queue = (Queue<SceneObjectPart>)info.GetValue("m_queue", typeof(Queue<SceneObjectPart>));
1877 m_ids = (List<LLUUID>)info.GetValue("m_ids", typeof(List<LLUUID>));
1878 */
1879
1880 //System.Console.WriteLine("SceneObjectPart Deserialize END");
1881 }
1882
1883 [SecurityPermission(SecurityAction.LinkDemand,
1884 Flags = SecurityPermissionFlag.SerializationFormatter)]
1885 public virtual void GetObjectData(
1886 SerializationInfo info, StreamingContext context)
1887 {
1888 if (info == null)
1889 {
1890 throw new System.ArgumentNullException("info");
1891 }
1892
1893 info.AddValue("m_inventoryFileName", m_inventoryFileName);
1894 info.AddValue("m_folderID", m_folderID.UUID);
1895 info.AddValue("PhysActor", PhysActor);
1896
1897 Dictionary<Guid, TaskInventoryItem> TaskInventory_work = new Dictionary<Guid, TaskInventoryItem>();
1898
1899 foreach (LLUUID id in TaskInventory.Keys)
1900 {
1901 TaskInventory_work.Add(id.UUID, TaskInventory[id]);
1902 }
1903
1904 info.AddValue("TaskInventory", TaskInventory_work);
1905
1906 info.AddValue("LastOwnerID", LastOwnerID.UUID);
1907 info.AddValue("OwnerID", OwnerID.UUID);
1908 info.AddValue("GroupID", GroupID.UUID);
1909
1910 info.AddValue("OwnershipCost", OwnershipCost);
1911 info.AddValue("ObjectSaleType", ObjectSaleType);
1912 info.AddValue("SalePrice", SalePrice);
1913 info.AddValue("Category", Category);
1914
1915 info.AddValue("CreationDate", CreationDate);
1916 info.AddValue("ParentID", ParentID);
1917
1918 info.AddValue("OwnerMask", OwnerMask);
1919 info.AddValue("NextOwnerMask", NextOwnerMask);
1920 info.AddValue("GroupMask", GroupMask);
1921 info.AddValue("EveryoneMask", EveryoneMask);
1922 info.AddValue("BaseMask", BaseMask);
1923
1924 info.AddValue("m_particleSystem", m_particleSystem);
1925
1926 info.AddValue("TimeStampFull", TimeStampFull);
1927 info.AddValue("TimeStampTerse", TimeStampTerse);
1928 info.AddValue("TimeStampLastActivity", TimeStampLastActivity);
1929
1930 info.AddValue("m_updateFlag", m_updateFlag);
1931 info.AddValue("CreatorID", CreatorID.UUID);
1932
1933 info.AddValue("m_inventorySerial", m_inventorySerial);
1934 info.AddValue("m_uuid", m_uuid.UUID);
1935 info.AddValue("m_localID", m_localID);
1936 info.AddValue("m_name", m_name);
1937 info.AddValue("m_flags", Flags);
1938 info.AddValue("m_material", m_material);
1939 info.AddValue("m_regionHandle", m_regionHandle);
1940
1941 info.AddValue("m_groupPosition.X", m_groupPosition.X);
1942 info.AddValue("m_groupPosition.Y", m_groupPosition.Y);
1943 info.AddValue("m_groupPosition.Z", m_groupPosition.Z);
1944
1945 info.AddValue("m_offsetPosition.X", m_offsetPosition.X);
1946 info.AddValue("m_offsetPosition.Y", m_offsetPosition.Y);
1947 info.AddValue("m_offsetPosition.Z", m_offsetPosition.Z);
1948
1949 info.AddValue("m_rotationOffset.W", m_rotationOffset.W);
1950 info.AddValue("m_rotationOffset.X", m_rotationOffset.X);
1951 info.AddValue("m_rotationOffset.Y", m_rotationOffset.Y);
1952 info.AddValue("m_rotationOffset.Z", m_rotationOffset.Z);
1953
1954 info.AddValue("m_velocity.X", m_velocity.X);
1955 info.AddValue("m_velocity.Y", m_velocity.Y);
1956 info.AddValue("m_velocity.Z", m_velocity.Z);
1957
1958 info.AddValue("m_rotationalvelocity.X", m_rotationalvelocity.X);
1959 info.AddValue("m_rotationalvelocity.Y", m_rotationalvelocity.Y);
1960 info.AddValue("m_rotationalvelocity.Z", m_rotationalvelocity.Z);
1961
1962 info.AddValue("m_angularVelocity.X", m_angularVelocity.X);
1963 info.AddValue("m_angularVelocity.Y", m_angularVelocity.Y);
1964 info.AddValue("m_angularVelocity.Z", m_angularVelocity.Z);
1965
1966 info.AddValue("m_acceleration.X", m_acceleration.X);
1967 info.AddValue("m_acceleration.Y", m_acceleration.Y);
1968 info.AddValue("m_acceleration.Z", m_acceleration.Z);
1969
1970 info.AddValue("m_description", m_description);
1971 info.AddValue("m_color", m_color);
1972 info.AddValue("m_text", m_text);
1973 info.AddValue("m_sitName", m_sitName);
1974 info.AddValue("m_touchName", m_touchName);
1975 info.AddValue("m_clickAction", m_clickAction);
1976 info.AddValue("m_shape", m_shape);
1977 info.AddValue("m_parentGroup", m_parentGroup);
1978 }
1862 } 1979 }
1863} 1980}
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
index 2c201ba..fabc3ed 100644
--- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
@@ -34,10 +34,14 @@ using OpenSim.Framework;
34using OpenSim.Framework.Console; 34using OpenSim.Framework.Console;
35using OpenSim.Region.Environment.Types; 35using OpenSim.Region.Environment.Types;
36using OpenSim.Region.Physics.Manager; 36using OpenSim.Region.Physics.Manager;
37using OpenSim.Region.Environment.Interfaces;
38using System.Runtime.Serialization;
39using System.Security.Permissions;
37 40
38namespace OpenSim.Region.Environment.Scenes 41namespace OpenSim.Region.Environment.Scenes
39{ 42{
40 public class ScenePresence : EntityBase 43 [Serializable]
44 public class ScenePresence : EntityBase, ISerializable
41 { 45 {
42// ~ScenePresence() 46// ~ScenePresence()
43// { 47// {
@@ -156,6 +160,12 @@ namespace OpenSim.Region.Environment.Scenes
156 get { return m_physicsActor; } 160 get { return m_physicsActor; }
157 } 161 }
158 162
163 public byte MovementFlag
164 {
165 set { m_movementflag = value; }
166 get { return m_movementflag; }
167 }
168
159 public bool KnownPrim(LLUUID primID) 169 public bool KnownPrim(LLUUID primID)
160 { 170 {
161 if (m_knownPrimUUID.Contains(primID)) 171 if (m_knownPrimUUID.Contains(primID))
@@ -215,13 +225,14 @@ namespace OpenSim.Region.Environment.Scenes
215 /// <summary> 225 /// <summary>
216 /// This works out to be the ClientView object associated with this avatar, or it's UDP connection manager 226 /// This works out to be the ClientView object associated with this avatar, or it's UDP connection manager
217 /// </summary> 227 /// </summary>
218 private readonly IClientAPI m_controllingClient; 228 private IClientAPI m_controllingClient;
219 229
220 protected PhysicsActor m_physicsActor; 230 protected PhysicsActor m_physicsActor;
221 231
222 public IClientAPI ControllingClient 232 public IClientAPI ControllingClient
223 { 233 {
224 get { return m_controllingClient; } 234 get { return m_controllingClient; }
235 set { m_controllingClient = value; }
225 } 236 }
226 237
227 protected LLVector3 m_parentPosition = new LLVector3(); 238 protected LLVector3 m_parentPosition = new LLVector3();
@@ -379,7 +390,7 @@ namespace OpenSim.Region.Environment.Scenes
379 m_appearance = appearance; 390 m_appearance = appearance;
380 } 391 }
381 392
382 private void RegisterToEvents() 393 public void RegisterToEvents()
383 { 394 {
384 m_controllingClient.OnRequestWearables += SendOwnAppearance; 395 m_controllingClient.OnRequestWearables += SendOwnAppearance;
385 m_controllingClient.OnSetAppearance += SetAppearance; 396 m_controllingClient.OnSetAppearance += SetAppearance;
@@ -1706,6 +1717,7 @@ namespace OpenSim.Region.Environment.Scenes
1706 DefaultTexture = textu.ToBytes(); 1717 DefaultTexture = textu.ToBytes();
1707 } 1718 }
1708 1719
1720 [Serializable]
1709 public class NewForce 1721 public class NewForce
1710 { 1722 {
1711 public float X; 1723 public float X;
@@ -1717,7 +1729,8 @@ namespace OpenSim.Region.Environment.Scenes
1717 } 1729 }
1718 } 1730 }
1719 1731
1720 public class ScenePartUpdate 1732 [Serializable]
1733 public class ScenePartUpdate : ISerializable
1721 { 1734 {
1722 public LLUUID FullID; 1735 public LLUUID FullID;
1723 public uint LastFullUpdateTime; 1736 public uint LastFullUpdateTime;
@@ -1729,6 +1742,38 @@ namespace OpenSim.Region.Environment.Scenes
1729 LastFullUpdateTime = 0; 1742 LastFullUpdateTime = 0;
1730 LastTerseUpdateTime = 0; 1743 LastTerseUpdateTime = 0;
1731 } 1744 }
1745
1746 protected ScenePartUpdate(SerializationInfo info, StreamingContext context)
1747 {
1748 //System.Console.WriteLine("ScenePartUpdate Deserialize BGN");
1749
1750 if (info == null)
1751 {
1752 throw new System.ArgumentNullException("info");
1753 }
1754
1755 FullID = new LLUUID((Guid)info.GetValue("FullID", typeof(Guid)));
1756 LastFullUpdateTime = (uint)info.GetValue("LastFullUpdateTime", typeof(uint));
1757 LastTerseUpdateTime = (uint)info.GetValue("LastTerseUpdateTime", typeof(uint));
1758
1759 //System.Console.WriteLine("ScenePartUpdate Deserialize END");
1760 }
1761
1762 [SecurityPermission(SecurityAction.LinkDemand,
1763 Flags = SecurityPermissionFlag.SerializationFormatter)]
1764 public virtual void GetObjectData(
1765 SerializationInfo info, StreamingContext context)
1766 {
1767 if (info == null)
1768 {
1769 throw new System.ArgumentNullException("info");
1770 }
1771
1772 info.AddValue("FullID", FullID.UUID);
1773 info.AddValue("LastFullUpdateTime", LastFullUpdateTime);
1774 info.AddValue("LastTerseUpdateTime", LastTerseUpdateTime);
1775
1776 }
1732 } 1777 }
1733 1778
1734 public override void SetText(string text, Vector3 color, double alpha) 1779 public override void SetText(string text, Vector3 color, double alpha)
@@ -1787,5 +1832,368 @@ namespace OpenSim.Region.Environment.Scenes
1787 RemoveFromPhysicalScene(); 1832 RemoveFromPhysicalScene();
1788 GC.Collect(); 1833 GC.Collect();
1789 } 1834 }
1835
1836 public ScenePresence()
1837 {
1838/* JB
1839 if (Animations == null)
1840 {
1841 Animations = new AvatarAnimations();
1842 Animations.LoadAnims();
1843 }
1844*/
1845 if (DefaultTexture == null)
1846 {
1847 LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry();
1848 DefaultTexture = textu.ToBytes();
1849 }
1850 }
1851
1852 public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene)
1853 {
1854 m_controllingClient = client;
1855 m_regionInfo = region;
1856 m_scene = scene;
1857 RegisterToEvents();
1858
1859 /*
1860 AbsolutePosition = client.StartPos;
1861
1862 Animations = new AvatarAnimations();
1863 Animations.LoadAnims();
1864
1865 m_animations = new List<LLUUID>();
1866 m_animations.Add(Animations.AnimsLLUUID["STAND"]);
1867 m_animationSeqs.Add(1);
1868
1869 SetDirectionVectors();
1870 */
1871 }
1872
1873 protected ScenePresence(SerializationInfo info, StreamingContext context)
1874 : base (info, context)
1875 {
1876 //System.Console.WriteLine("ScenePresence Deserialize BGN");
1877
1878 if (info == null)
1879 {
1880 throw new System.ArgumentNullException("info");
1881 }
1882/* JB
1883 if (Animations == null)
1884 {
1885 Animations = new AvatarAnimations();
1886 Animations.LoadAnims();
1887 }
1888*/
1889 if (DefaultTexture == null)
1890 {
1891 LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry();
1892 DefaultTexture = textu.ToBytes();
1893 }
1894
1895 List<Guid> animations_work = (List<Guid>)info.GetValue("m_animations", typeof(List<Guid>));
1896
1897 foreach (Guid guid in animations_work)
1898 {
1899 m_animations.Add(new LLUUID(guid));
1900 }
1901
1902 m_animationSeqs = (List<int>)info.GetValue("m_animationSeqs", typeof(List<int>));
1903 m_updateflag = (bool)info.GetValue("m_updateflag", typeof(bool));
1904 m_movementflag = (byte)info.GetValue("m_movementflag", typeof(byte));
1905 m_forcesList = (List<NewForce>)info.GetValue("m_forcesList", typeof(List<NewForce>));
1906 m_updateCount = (short)info.GetValue("m_updateCount", typeof(short));
1907 m_requestedSitTargetID = (uint)info.GetValue("m_requestedSitTargetID", typeof(uint));
1908
1909 m_requestedSitOffset
1910 = new LLVector3(
1911 (float)info.GetValue("m_requestedSitOffset.X", typeof(float)),
1912 (float)info.GetValue("m_requestedSitOffset.Y", typeof(float)),
1913 (float)info.GetValue("m_requestedSitOffset.Z", typeof(float)));
1914
1915 m_sitAvatarHeight = (float)info.GetValue("m_sitAvatarHeight", typeof(float));
1916 m_godlevel = (float)info.GetValue("m_godlevel", typeof(float));
1917 m_setAlwaysRun = (bool)info.GetValue("m_setAlwaysRun", typeof(bool));
1918
1919 m_bodyRot
1920 = new Quaternion(
1921 (float)info.GetValue("m_bodyRot.w", typeof(float)),
1922 (float)info.GetValue("m_bodyRot.x", typeof(float)),
1923 (float)info.GetValue("m_bodyRot.y", typeof(float)),
1924 (float)info.GetValue("m_bodyRot.z", typeof(float)));
1925
1926 IsRestrictedToRegion = (bool)info.GetValue("IsRestrictedToRegion", typeof(bool));
1927 m_newForce = (bool)info.GetValue("m_newForce", typeof(bool));
1928 //m_newAvatar = (bool)info.GetValue("m_newAvatar", typeof(bool));
1929 m_newCoarseLocations = (bool)info.GetValue("m_newCoarseLocations", typeof(bool));
1930 m_gotAllObjectsInScene = (bool)info.GetValue("m_gotAllObjectsInScene", typeof(bool));
1931 m_avHeight = (float)info.GetValue("m_avHeight", typeof(float));
1932 crossingFromRegion = (ulong)info.GetValue("crossingFromRegion", typeof(ulong));
1933
1934 List<float[]> Dir_Vectors_work = (List<float[]>)info.GetValue("Dir_Vectors", typeof(List<float[]>));
1935 List<Vector3> Dir_Vectors_work2 = new List<Vector3>();
1936
1937 foreach (float[] f3 in Dir_Vectors_work)
1938 {
1939 Dir_Vectors_work2.Add(new Vector3(f3[0], f3[1], f3[2]));
1940 }
1941
1942 Dir_Vectors = Dir_Vectors_work2.ToArray();
1943
1944 lastPhysPos
1945 = new LLVector3(
1946 (float)info.GetValue("lastPhysPos.X", typeof(float)),
1947 (float)info.GetValue("lastPhysPos.Y", typeof(float)),
1948 (float)info.GetValue("lastPhysPos.Z", typeof(float)));
1949
1950 m_CameraCenter
1951 = new Vector3(
1952 (float)info.GetValue("m_CameraCenter.X", typeof(float)),
1953 (float)info.GetValue("m_CameraCenter.Y", typeof(float)),
1954 (float)info.GetValue("m_CameraCenter.Z", typeof(float)));
1955
1956 m_CameraAtAxis
1957 = new Vector3(
1958 (float)info.GetValue("m_CameraAtAxis.X", typeof(float)),
1959 (float)info.GetValue("m_CameraAtAxis.Y", typeof(float)),
1960 (float)info.GetValue("m_CameraAtAxis.Z", typeof(float)));
1961
1962 m_CameraLeftAxis
1963 = new Vector3(
1964 (float)info.GetValue("m_CameraLeftAxis.X", typeof(float)),
1965 (float)info.GetValue("m_CameraLeftAxis.Y", typeof(float)),
1966 (float)info.GetValue("m_CameraLeftAxis.Z", typeof(float)));
1967
1968 m_CameraUpAxis
1969 = new Vector3(
1970 (float)info.GetValue("m_CameraUpAxis.X", typeof(float)),
1971 (float)info.GetValue("m_CameraUpAxis.Y", typeof(float)),
1972 (float)info.GetValue("m_CameraUpAxis.Z", typeof(float)));
1973
1974 m_DrawDistance = (float)info.GetValue("m_DrawDistance", typeof(float));
1975 m_appearance = (AvatarAppearance)info.GetValue("m_appearance", typeof(AvatarAppearance));
1976 m_knownChildRegions = (List<ulong>)info.GetValue("m_knownChildRegions", typeof(List<ulong>));
1977
1978 posLastSignificantMove
1979 = new LLVector3(
1980 (float)info.GetValue("posLastSignificantMove.X", typeof(float)),
1981 (float)info.GetValue("posLastSignificantMove.Y", typeof(float)),
1982 (float)info.GetValue("posLastSignificantMove.Z", typeof(float)));
1983
1984 // m_partsUpdateQueue = (UpdateQueue)info.GetValue("m_partsUpdateQueue", typeof(UpdateQueue));
1985
1986 /*
1987 Dictionary<Guid, ScenePartUpdate> updateTimes_work
1988 = (Dictionary<Guid, ScenePartUpdate>)info.GetValue("m_updateTimes", typeof(Dictionary<Guid, ScenePartUpdate>));
1989
1990 foreach (Guid id in updateTimes_work.Keys)
1991 {
1992 m_updateTimes.Add(new LLUUID(id), updateTimes_work[id]);
1993 }
1994 */
1995 m_regionHandle = (ulong)info.GetValue("m_regionHandle", typeof(ulong));
1996 m_firstname = (string)info.GetValue("m_firstname", typeof(string));
1997 m_lastname = (string)info.GetValue("m_lastname", typeof(string));
1998 m_allowMovement = (bool)info.GetValue("m_allowMovement", typeof(bool));
1999 m_parentPosition = new LLVector3((float)info.GetValue("m_parentPosition.X", typeof(float)),
2000 (float)info.GetValue("m_parentPosition.Y", typeof(float)),
2001 (float)info.GetValue("m_parentPosition.Z", typeof(float)));
2002
2003 m_isChildAgent = (bool)info.GetValue("m_isChildAgent", typeof(bool));
2004 m_parentID = (uint)info.GetValue("m_parentID", typeof(uint));
2005
2006// for OpenSim_v0.5
2007 currentParcelUUID = new LLUUID((Guid)info.GetValue("currentParcelUUID", typeof(Guid)));
2008
2009 lastKnownAllowedPosition
2010 = new Vector3(
2011 (float)info.GetValue("lastKnownAllowedPosition.X", typeof(float)),
2012 (float)info.GetValue("lastKnownAllowedPosition.Y", typeof(float)),
2013 (float)info.GetValue("lastKnownAllowedPosition.Z", typeof(float)));
2014
2015 sentMessageAboutRestrictedParcelFlyingDown = (bool)info.GetValue("sentMessageAboutRestrictedParcelFlyingDown", typeof(bool));
2016
2017 m_LastChildAgentUpdatePosition
2018 = new LLVector3(
2019 (float)info.GetValue("m_LastChildAgentUpdatePosition.X", typeof(float)),
2020 (float)info.GetValue("m_LastChildAgentUpdatePosition.Y", typeof(float)),
2021 (float)info.GetValue("m_LastChildAgentUpdatePosition.Z", typeof(float)));
2022
2023 m_perfMonMS = (int)info.GetValue("m_perfMonMS", typeof(int));
2024 m_AgentControlFlags = (uint)info.GetValue("m_AgentControlFlags", typeof(uint));
2025
2026 m_headrotation
2027 = new LLQuaternion(
2028 (float)info.GetValue("m_headrotation.W", typeof(float)),
2029 (float)info.GetValue("m_headrotation.X", typeof(float)),
2030 (float)info.GetValue("m_headrotation.Y", typeof(float)),
2031 (float)info.GetValue("m_headrotation.Z", typeof(float)));
2032
2033 m_state = (byte)info.GetValue("m_state", typeof(byte));
2034
2035 List<Guid> knownPrimUUID_work = (List<Guid>)info.GetValue("m_knownPrimUUID", typeof(List<Guid>));
2036
2037 foreach (Guid id in knownPrimUUID_work)
2038 {
2039 m_knownPrimUUID.Add(new LLUUID(id));
2040 }
2041
2042 //System.Console.WriteLine("ScenePresence Deserialize END");
2043 }
2044
2045 [SecurityPermission(SecurityAction.LinkDemand,
2046 Flags = SecurityPermissionFlag.SerializationFormatter)]
2047 public override void GetObjectData(
2048 SerializationInfo info, StreamingContext context)
2049 {
2050 if (info == null)
2051 {
2052 throw new System.ArgumentNullException("info");
2053 }
2054
2055 base.GetObjectData(info, context);
2056
2057 List<Guid> animations_work = new List<Guid>();
2058
2059 foreach (LLUUID uuid in m_animations)
2060 {
2061 animations_work.Add(uuid.UUID);
2062 }
2063
2064 info.AddValue("m_animations", animations_work);
2065
2066 info.AddValue("m_animationSeqs", m_animationSeqs);
2067 info.AddValue("m_updateflag", m_updateflag);
2068 info.AddValue("m_movementflag", m_movementflag);
2069 info.AddValue("m_forcesList", m_forcesList);
2070 info.AddValue("m_updateCount", m_updateCount);
2071 info.AddValue("m_requestedSitTargetID", m_requestedSitTargetID);
2072
2073 // LLVector3
2074 info.AddValue("m_requestedSitOffset.X", m_requestedSitOffset.X);
2075 info.AddValue("m_requestedSitOffset.Y", m_requestedSitOffset.Y);
2076 info.AddValue("m_requestedSitOffset.Z", m_requestedSitOffset.Z);
2077
2078 info.AddValue("m_sitAvatarHeight", m_sitAvatarHeight);
2079 info.AddValue("m_godlevel", m_godlevel);
2080 info.AddValue("m_setAlwaysRun", m_setAlwaysRun);
2081
2082 // Quaternion
2083 info.AddValue("m_bodyRot.w", m_bodyRot.w);
2084 info.AddValue("m_bodyRot.x", m_bodyRot.x);
2085 info.AddValue("m_bodyRot.y", m_bodyRot.y);
2086 info.AddValue("m_bodyRot.z", m_bodyRot.z);
2087
2088 info.AddValue("IsRestrictedToRegion", IsRestrictedToRegion);
2089 info.AddValue("m_newForce", m_newForce);
2090 //info.AddValue("m_newAvatar", m_newAvatar);
2091 info.AddValue("m_newCoarseLocations", m_newCoarseLocations);
2092 info.AddValue("m_gotAllObjectsInScene", m_gotAllObjectsInScene);
2093 info.AddValue("m_avHeight", m_avHeight);
2094
2095 // info.AddValue("m_regionInfo", m_regionInfo);
2096
2097 info.AddValue("crossingFromRegion", crossingFromRegion);
2098
2099 List<float[]> Dir_Vectors_work = new List<float[]>();
2100
2101 foreach (Vector3 v3 in Dir_Vectors)
2102 {
2103 Dir_Vectors_work.Add(new float[] { v3.x, v3.y, v3.z });
2104 }
2105
2106 info.AddValue("Dir_Vectors", Dir_Vectors_work);
2107
2108 // LLVector3
2109 info.AddValue("lastPhysPos.X", lastPhysPos.X);
2110 info.AddValue("lastPhysPos.Y", lastPhysPos.Y);
2111 info.AddValue("lastPhysPos.Z", lastPhysPos.Z);
2112
2113 // Vector3
2114 info.AddValue("m_CameraCenter.X", m_CameraCenter.x);
2115 info.AddValue("m_CameraCenter.Y", m_CameraCenter.y);
2116 info.AddValue("m_CameraCenter.Z", m_CameraCenter.z);
2117
2118 // Vector3
2119 info.AddValue("m_CameraAtAxis.X", m_CameraAtAxis.x);
2120 info.AddValue("m_CameraAtAxis.Y", m_CameraAtAxis.y);
2121 info.AddValue("m_CameraAtAxis.Z", m_CameraAtAxis.z);
2122
2123 // Vector3
2124 info.AddValue("m_CameraLeftAxis.X", m_CameraLeftAxis.x);
2125 info.AddValue("m_CameraLeftAxis.Y", m_CameraLeftAxis.y);
2126 info.AddValue("m_CameraLeftAxis.Z", m_CameraLeftAxis.z);
2127
2128 // Vector3
2129 info.AddValue("m_CameraUpAxis.X", m_CameraUpAxis.x);
2130 info.AddValue("m_CameraUpAxis.Y", m_CameraUpAxis.y);
2131 info.AddValue("m_CameraUpAxis.Z", m_CameraUpAxis.z);
2132
2133 info.AddValue("m_DrawDistance", m_DrawDistance);
2134 info.AddValue("m_appearance", m_appearance);
2135 info.AddValue("m_knownChildRegions", m_knownChildRegions);
2136
2137 // LLVector3
2138 info.AddValue("posLastSignificantMove.X", posLastSignificantMove.X);
2139 info.AddValue("posLastSignificantMove.Y", posLastSignificantMove.Y);
2140 info.AddValue("posLastSignificantMove.Z", posLastSignificantMove.Z);
2141
2142 //info.AddValue("m_partsUpdateQueue", m_partsUpdateQueue);
2143
2144 /*
2145 Dictionary<Guid, ScenePartUpdate> updateTimes_work = new Dictionary<Guid, ScenePartUpdate>();
2146
2147 foreach ( LLUUID id in m_updateTimes.Keys)
2148 {
2149 updateTimes_work.Add(id.UUID, m_updateTimes[id]);
2150 }
2151
2152 info.AddValue("m_updateTimes", updateTimes_work);
2153 */
2154
2155 info.AddValue("m_regionHandle", m_regionHandle);
2156 info.AddValue("m_firstname", m_firstname);
2157 info.AddValue("m_lastname", m_lastname);
2158 info.AddValue("m_allowMovement", m_allowMovement);
2159 //info.AddValue("m_physicsActor", m_physicsActor);
2160 info.AddValue("m_parentPosition.X", m_parentPosition.X);
2161 info.AddValue("m_parentPosition.Y", m_parentPosition.Y);
2162 info.AddValue("m_parentPosition.Z", m_parentPosition.Z);
2163 info.AddValue("m_isChildAgent", m_isChildAgent);
2164 info.AddValue("m_parentID", m_parentID);
2165
2166// for OpenSim_v0.5
2167 info.AddValue("currentParcelUUID", currentParcelUUID.UUID);
2168
2169 info.AddValue("lastKnownAllowedPosition.X", lastKnownAllowedPosition.x);
2170 info.AddValue("lastKnownAllowedPosition.Y", lastKnownAllowedPosition.y);
2171 info.AddValue("lastKnownAllowedPosition.Z", lastKnownAllowedPosition.z);
2172
2173 info.AddValue("sentMessageAboutRestrictedParcelFlyingDown", sentMessageAboutRestrictedParcelFlyingDown);
2174
2175 info.AddValue("m_LastChildAgentUpdatePosition.X", m_LastChildAgentUpdatePosition.X);
2176 info.AddValue("m_LastChildAgentUpdatePosition.Y", m_LastChildAgentUpdatePosition.Y);
2177 info.AddValue("m_LastChildAgentUpdatePosition.Z", m_LastChildAgentUpdatePosition.Z);
2178
2179 info.AddValue("m_perfMonMS", m_perfMonMS);
2180 info.AddValue("m_AgentControlFlags", m_AgentControlFlags);
2181
2182 info.AddValue("m_headrotation.W", m_headrotation.W);
2183 info.AddValue("m_headrotation.X", m_headrotation.X);
2184 info.AddValue("m_headrotation.Y", m_headrotation.Y);
2185 info.AddValue("m_headrotation.Z", m_headrotation.Z);
2186
2187 info.AddValue("m_state", m_state);
2188
2189 List<Guid> knownPrimUUID_work = new List<Guid>();
2190
2191 foreach (LLUUID id in m_knownPrimUUID)
2192 {
2193 knownPrimUUID_work.Add(id.UUID);
2194 }
2195
2196 info.AddValue("m_knownPrimUUID", knownPrimUUID_work);
2197 }
1790 } 2198 }
1791} 2199}
diff --git a/OpenSim/Region/Environment/Types/UpdateQueue.cs b/OpenSim/Region/Environment/Types/UpdateQueue.cs
index 0078678..ce0927c 100644
--- a/OpenSim/Region/Environment/Types/UpdateQueue.cs
+++ b/OpenSim/Region/Environment/Types/UpdateQueue.cs
@@ -30,9 +30,14 @@ using System.Collections.Generic;
30using libsecondlife; 30using libsecondlife;
31using OpenSim.Region.Environment.Scenes; 31using OpenSim.Region.Environment.Scenes;
32 32
33using System;
34using System.Runtime.Serialization;
35using System.Security.Permissions;
36
33namespace OpenSim.Region.Environment.Types 37namespace OpenSim.Region.Environment.Types
34{ 38{
35 public class UpdateQueue 39 [Serializable]
40 public class UpdateQueue : ISerializable
36 { 41 {
37 private Queue<SceneObjectPart> m_queue; 42 private Queue<SceneObjectPart> m_queue;
38 43
@@ -86,5 +91,46 @@ namespace OpenSim.Region.Environment.Types
86 91
87 return part; 92 return part;
88 } 93 }
94
95 protected UpdateQueue(SerializationInfo info, StreamingContext context)
96 {
97 //System.Console.WriteLine("UpdateQueue Deserialize BGN");
98
99 if (info == null)
100 {
101 throw new System.ArgumentNullException("info");
102 }
103
104 m_queue = (Queue<SceneObjectPart>)info.GetValue("m_queue", typeof(Queue<SceneObjectPart>));
105 List<Guid> ids_work = (List<Guid>)info.GetValue("m_ids", typeof(List<Guid>));
106
107 foreach (Guid guid in ids_work)
108 {
109 m_ids.Add(new LLUUID(guid));
110 }
111
112 //System.Console.WriteLine("UpdateQueue Deserialize END");
113 }
114
115 [SecurityPermission(SecurityAction.LinkDemand,
116 Flags = SecurityPermissionFlag.SerializationFormatter)]
117 public virtual void GetObjectData(
118 SerializationInfo info, StreamingContext context)
119 {
120 if (info == null)
121 {
122 throw new System.ArgumentNullException("info");
123 }
124
125 List<Guid> ids_work = new List<Guid>();
126
127 foreach (LLUUID uuid in m_ids)
128 {
129 ids_work.Add(uuid.UUID);
130 }
131
132 info.AddValue("m_queue", m_queue);
133 info.AddValue("m_ids", ids_work);
134 }
89 } 135 }
90} \ No newline at end of file 136}
diff --git a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs
index cb2c908..68fea97 100644
--- a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs
@@ -538,5 +538,18 @@ namespace SimpleApp
538 public void SendLogoutPacket() 538 public void SendLogoutPacket()
539 { 539 {
540 } 540 }
541
542 public void Terminate()
543 {
544 }
545
546 public ClientInfo GetClientInfo()
547 {
548 return null;
549 }
550
551 public void SetClientInfo(ClientInfo info)
552 {
553 }
541 } 554 }
542} 555}
diff --git a/ThirdParty/3Di/LoadBalancer/LoadBalancerPlugin.cs b/ThirdParty/3Di/LoadBalancer/LoadBalancerPlugin.cs
new file mode 100644
index 0000000..6812777
--- /dev/null
+++ b/ThirdParty/3Di/LoadBalancer/LoadBalancerPlugin.cs
@@ -0,0 +1,1101 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.IO;
31using System.Net;
32using System.Xml;
33using System.Text;
34using System.Xml.Serialization;
35using System.Net.Sockets;
36using System.Collections;
37using System.Collections.Generic;
38using System.Diagnostics;
39using System.Threading;
40
41using OpenSim.Framework;
42using OpenSim.Framework.Console;
43using OpenSim.Framework.Servers;
44using OpenSim.Region.Environment;
45using OpenSim.Region.Environment.Scenes;
46using OpenSim.Region.ClientStack;
47
48using Nwc.XmlRpc;
49using Nini.Config;
50
51using Mono.Addins;
52
53using libsecondlife;
54using libsecondlife.Packets;
55
56[assembly:Addin]
57[assembly:AddinDependency ("OpenSim", "0.5")]
58
59namespace OpenSim.ApplicationPlugins.LoadBalancer
60{
61 [Extension("/OpenSim/Startup")]
62 public class LoadBalancerPlugin : IApplicationPlugin
63 {
64 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
65
66 private OpenSimMain simMain;
67 private BaseHttpServer commandServer;
68
69 private List<UDPServer> udpServers;
70 private List<RegionInfo> regionData;
71
72 private int proxyOffset;
73 private string proxyURL;
74 private SceneManager sceneManager;
75 private string serializeDir;
76
77 private TcpServer mTcpServer;
78 private TcpClient mTcpClient;
79
80 public void Initialise(OpenSimMain openSim)
81 {
82 m_log.Info("[BALANCER] "+"Entering Initialize()");
83
84 StartTcpServer();
85 ClientView.SynchronizeClient = new ClientView.SynchronizeClientHandler(SynchronizePackets);
86 AsynchronousSocketListener.PacketHandler = new AsynchronousSocketListener.PacketRecieveHandler(SynchronizePacketRecieve);
87
88 this.sceneManager = openSim.SceneManager;
89 this.udpServers = openSim.UdpServers;
90 this.regionData = openSim.RegionData;
91 this.simMain = openSim;
92 this.commandServer = openSim.HttpServer;
93
94 proxyOffset = Int32.Parse(openSim.ConfigSource.Configs["Network"].GetString("proxy_offset", "0"));
95 proxyURL = openSim.ConfigSource.Configs["Network"].GetString("proxy_url", "");
96 if(proxyURL.Length==0) return;
97
98 serializeDir = openSim.ConfigSource.Configs["Network"].GetString("serialize_dir", "/tmp/");
99
100 commandServer.AddXmlRPCHandler("SerializeRegion", SerializeRegion);
101 commandServer.AddXmlRPCHandler("DeserializeRegion_Move", DeserializeRegion_Move);
102 commandServer.AddXmlRPCHandler("DeserializeRegion_Clone", DeserializeRegion_Clone);
103 commandServer.AddXmlRPCHandler("TerminateRegion", TerminateRegion);
104
105 commandServer.AddXmlRPCHandler("SplitRegion", SplitRegion);
106 commandServer.AddXmlRPCHandler("MergeRegions", MergeRegions);
107 commandServer.AddXmlRPCHandler("UpdatePhysics", UpdatePhysics);
108 commandServer.AddXmlRPCHandler("GetStatus", GetStatus);
109
110 m_log.Info("[BALANCER] "+"Exiting Initialize()");
111 }
112
113 private void StartTcpServer()
114 {
115 Thread server_thread = new Thread(new ThreadStart(
116 delegate {
117 mTcpServer = new TcpServer(10001);
118 mTcpServer.start();
119 }));
120 server_thread.Start();
121 }
122
123 public void Close()
124 {
125 }
126
127 private XmlRpcResponse GetStatus(XmlRpcRequest request)
128 {
129 XmlRpcResponse response = new XmlRpcResponse();
130 try
131 {
132 m_log.Info("[BALANCER] "+"Entering RegionStatus()");
133
134 int src_port = (int)request.Params[0];
135 Scene scene = null;
136 // try to get the scene object
137 RegionInfo src_region = SearchRegionFromPortNum(src_port);
138 if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false)
139 {
140 m_log.Error("[BALANCER] "+"The Scene is not found");
141 return response;
142 }
143 // serialization of client's informations
144 List<ScenePresence> presences = scene.GetScenePresences();
145 int get_scene_presence = presences.Count;
146 int get_scene_presence_filter = 0;
147 foreach (ScenePresence pre in presences)
148 {
149 ClientView client = (ClientView) pre.ControllingClient;
150 //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) {
151 if(client.PacketProcessingEnabled==true) {
152 get_scene_presence_filter++;
153 }
154 }
155 List<ScenePresence> avatars = scene.GetAvatars();
156 int get_avatar = avatars.Count;
157 int get_avatar_filter = 0;
158 string avatar_names = "";
159 foreach (ScenePresence pre in avatars)
160 {
161 ClientView client = (ClientView) pre.ControllingClient;
162 //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) {
163 if(client.PacketProcessingEnabled==true) {
164 get_avatar_filter++;
165 avatar_names += pre.Firstname + " " + pre.Lastname + "; ";
166 }
167 }
168
169 Hashtable responseData = new Hashtable();
170 responseData["get_scene_presence_filter"] = get_scene_presence_filter;
171 responseData["get_scene_presence"] = get_scene_presence;
172 responseData["get_avatar_filter"] = get_avatar_filter;
173 responseData["get_avatar"] = get_avatar;
174 responseData["avatar_names"] = avatar_names;
175 response.Value = responseData;
176
177 m_log.Info("[BALANCER] "+"Exiting RegionStatus()");
178 }
179 catch (Exception e)
180 {
181 m_log.Error("[BALANCER] "+e.ToString());
182 m_log.Error("[BALANCER] "+e.StackTrace);
183 }
184 return response;
185 }
186
187 private XmlRpcResponse SerializeRegion(XmlRpcRequest request)
188 {
189 try
190 {
191 m_log.Info("[BALANCER] "+"Entering SerializeRegion()");
192
193 string src_url = (string)request.Params[0];
194 int src_port = (int)request.Params[1];
195
196 SerializeRegion(src_url, src_port);
197
198 m_log.Info("[BALANCER] "+"Exiting SerializeRegion()");
199 }
200 catch (Exception e)
201 {
202 m_log.Error("[BALANCER] "+e.ToString());
203 m_log.Error("[BALANCER] "+e.StackTrace);
204 }
205
206 return new XmlRpcResponse();
207 }
208
209 private XmlRpcResponse DeserializeRegion_Move(XmlRpcRequest request)
210 {
211 try
212 {
213 m_log.Info("[BALANCER] "+"Entering DeserializeRegion_Move()");
214
215 string src_url = (string)request.Params[0];
216 int src_port = (int)request.Params[1];
217 string dst_url = (string)request.Params[2];
218 int dst_port = (int)request.Params[3];
219
220 DeserializeRegion_Move(src_port, dst_port, src_url, dst_url);
221
222 m_log.Info("[BALANCER] "+"Exiting DeserializeRegion_Move()");
223 }
224 catch (Exception e)
225 {
226 m_log.Error("[BALANCER] "+e.ToString());
227 m_log.Error("[BALANCER] "+e.StackTrace);
228 }
229
230 return new XmlRpcResponse();
231 }
232
233 private XmlRpcResponse DeserializeRegion_Clone(XmlRpcRequest request)
234 {
235 try
236 {
237 m_log.Info("[BALANCER] "+"Entering DeserializeRegion_Clone()");
238
239 string src_url = (string)request.Params[0];
240 int src_port = (int)request.Params[1];
241 string dst_url = (string)request.Params[2];
242 int dst_port = (int)request.Params[3];
243
244 DeserializeRegion_Clone(src_port, dst_port, src_url, dst_url);
245
246 m_log.Info("[BALANCER] "+"Exiting DeserializeRegion_Clone()");
247 }
248 catch (Exception e)
249 {
250 m_log.Error("[BALANCER] "+e.ToString());
251 m_log.Error("[BALANCER] "+e.StackTrace);
252 throw e;
253 }
254
255 return new XmlRpcResponse();
256 }
257
258 private XmlRpcResponse TerminateRegion(XmlRpcRequest request)
259 {
260 try
261 {
262 m_log.Info("[BALANCER] "+"Entering TerminateRegion()");
263
264 int src_port = (int)request.Params[0];
265
266 // backgroud
267 WaitCallback callback = new WaitCallback(TerminateRegion);
268 ThreadPool.QueueUserWorkItem(callback, src_port);
269
270 m_log.Info("[BALANCER] "+"Exiting TerminateRegion()");
271 }
272 catch (Exception e)
273 {
274 m_log.Error("[BALANCER] "+e.ToString());
275 m_log.Error("[BALANCER] "+e.StackTrace);
276 }
277
278 return new XmlRpcResponse();
279 }
280
281 // internal functions
282
283 private void SerializeRegion(string src_url, int src_port)
284 {
285 RegionInfo src_region = null;
286
287 //------------------------------------------
288 // Processing of origin region
289 //------------------------------------------
290
291 // search origin region
292 src_region = SearchRegionFromPortNum(src_port);
293
294 if (src_region == null)
295 {
296 m_log.Error("[BALANCER] "+"Region not found");
297 return;
298 }
299
300 simMain.ProxyCommand(src_region.proxyUrl, "BlockClientMessages", src_url, src_port + proxyOffset);
301
302 // serialization of origin region's data
303 SerializeRegion(src_region, serializeDir);
304 }
305
306 private void DeserializeRegion_Move(int src_port, int dst_port, string src_url, string dst_url)
307 {
308 RegionInfo dst_region = null;
309
310 //------------------------------------------
311 // Processing of destination region
312 //------------------------------------------
313
314 // import the source region's data
315 dst_region = DeserializeRegion(dst_port, true, serializeDir);
316
317 simMain.ProxyCommand(dst_region.proxyUrl, "ChangeRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url);
318 simMain.ProxyCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset);
319 }
320
321 private void DeserializeRegion_Clone(int src_port, int dst_port, string src_url, string dst_url)
322 {
323 RegionInfo dst_region = null;
324
325 //------------------------------------------
326 // Processing of destination region
327 //------------------------------------------
328
329 // import the source region's data
330 dst_region = DeserializeRegion(dst_port, false, serializeDir);
331
332 // Decide who is in charge for each section
333 int[] port = new int[] { src_port, dst_port };
334 string[] url = new string[] { "http://" + src_url + ":" + commandServer.Port, "http://" + dst_url + ":" + commandServer.Port };
335 for(int i=0; i<2; i++) simMain.XmlRpcCommand(url[i], "SplitRegion", i, 2, port[0], port[1], url[0], url[1]);
336
337 // Enable the proxy
338 simMain.ProxyCommand(dst_region.proxyUrl, "AddRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url);
339 simMain.ProxyCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset);
340 }
341
342 private void TerminateRegion(object param)
343 {
344 RegionInfo src_region = null;
345 int src_port = (int)param;
346
347 //------------------------------------------
348 // Processing of remove region
349 //------------------------------------------
350
351 // search origin region
352 src_region = SearchRegionFromPortNum(src_port);
353
354 if (src_region == null)
355 {
356 m_log.Error("[BALANCER] "+"Region not found");
357 return;
358 }
359
360 isSplit = false;
361
362 // remove client resources
363 RemoveAllClientResource(src_region);
364 // remove old region
365 RemoveRegion(src_region.RegionID, src_region.InternalEndPoint.Port);
366
367 m_log.Info("[BALANCER] "+"Region terminated");
368 }
369
370 private RegionInfo SearchRegionFromPortNum(int portnum)
371 {
372 RegionInfo result = null;
373
374 foreach (RegionInfo rinfo in regionData)
375 {
376 if (rinfo.InternalEndPoint.Port == portnum)
377 {
378// m_log.Info("BALANCER",
379// "Region found. Internal Port = {0}, Handle={1}",
380// rinfo.InternalEndPoint.Port, rinfo.RegionHandle);
381 result = rinfo;
382 break;
383 }
384 }
385
386 return result;
387 }
388
389 private UDPServer SearchUDPServerFromPortNum(int portnum)
390 {
391 return udpServers.Find( delegate(UDPServer server) { return (portnum + proxyOffset == ((IPEndPoint) server.Server.LocalEndPoint).Port); });
392 }
393
394 private void SerializeRegion(RegionInfo src_region, string export_dir)
395 {
396 Scene scene = null;
397 List<ScenePresence> presences;
398 string filename;
399 int i = 0;
400
401 // try to get the scene object
402 if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false)
403 {
404 m_log.Error("[BALANCER] "+"The Scene is not found");
405 return;
406 }
407
408 // create export directory
409 DirectoryInfo dirinfo = new DirectoryInfo(export_dir);
410 if (!dirinfo.Exists)
411 {
412 dirinfo.Create();
413 }
414
415 // serialization of client's informations
416 presences = scene.GetScenePresences();
417
418 foreach (ScenePresence pre in presences)
419 {
420 SerializeClient(i, scene, pre, export_dir);
421 i++;
422 }
423
424 // serialization of region data
425 SearializableRegionInfo dst_region = new SearializableRegionInfo(src_region);
426
427 filename = export_dir + "RegionInfo_" + src_region.RegionID.ToString() + ".bin";
428 Util.SerializeToFile(filename, dst_region);
429
430 // backup current scene's entities
431 //scene.Backup();
432
433 m_log.InfoFormat("[BALANCER] "+"region serialization completed [{0}]",
434 src_region.RegionID.ToString());
435 }
436
437 private void SerializeClient(int idx, Scene scene, ScenePresence pre, string export_dir)
438 {
439 string filename;
440 IClientAPI controller = null;
441
442 m_log.InfoFormat("[BALANCER] "+"agent id : {0}", pre.m_uuid);
443
444 uint[] circuits = scene.ClientManager.GetAllCircuits(pre.m_uuid);
445
446 foreach (uint code in circuits)
447 {
448 m_log.InfoFormat("[BALANCER] "+"circuit code : {0}", code);
449
450 if (scene.ClientManager.TryGetClient(code, out controller))
451 {
452 ClientInfo info = controller.GetClientInfo();
453
454 filename = export_dir + "ClientInfo-" + String.Format("{0:0000}", idx) + "_" + controller.CircuitCode.ToString() + ".bin";
455
456 Util.SerializeToFile(filename, info);
457
458 m_log.InfoFormat("[BALANCER] "+"client info serialized [filename={0}]", filename);
459 }
460 }
461
462 //filename = export_dir + "Presence_" + controller.AgentId.ToString() + ".bin";
463 filename = export_dir + "Presence_" + String.Format("{0:0000}", idx) + ".bin";
464
465 Util.SerializeToFile(filename, pre);
466
467 m_log.InfoFormat("[BALANCER] "+"scene presence serialized [filename={0}]", filename);
468 }
469
470 private RegionInfo DeserializeRegion(int dst_port, bool move_flag, string import_dir)
471 {
472 string[] files = null;
473 RegionInfo dst_region = null;
474
475 try
476 {
477 // deserialization of region data
478 files = Directory.GetFiles(import_dir, "RegionInfo_*.bin");
479
480 foreach (string filename in files)
481 {
482 m_log.InfoFormat("[BALANCER] RegionInfo filename = [{0}]", filename);
483
484 dst_region = new RegionInfo((SearializableRegionInfo)Util.DeserializeFromFile(filename));
485
486 m_log.InfoFormat("[BALANCER] "+"RegionID = [{0}]", dst_region.RegionID.ToString());
487 m_log.InfoFormat("[BALANCER] "+"RegionHandle = [{0}]", dst_region.RegionHandle);
488 m_log.InfoFormat("[BALANCER] "+"ProxyUrl = [{0}]", dst_region.proxyUrl);
489 m_log.InfoFormat("[BALANCER] "+"OriginRegionID = [{0}]", dst_region.originRegionID.ToString());
490
491 CreateCloneRegion(dst_region, dst_port, true);
492
493 File.Delete(filename);
494
495 m_log.InfoFormat("[BALANCER] "+"region deserialized [{0}]", dst_region.RegionID);
496 }
497
498 // deserialization of client data
499 DeserializeClient(dst_region, import_dir);
500
501 m_log.InfoFormat("[BALANCER] "+"region deserialization completed [{0}]",
502 dst_region.ToString());
503 }
504 catch (Exception e)
505 {
506 m_log.Error("[BALANCER] "+e.ToString());
507 m_log.Error("[BALANCER] "+e.StackTrace);
508 throw e;
509 }
510
511 return dst_region;
512 }
513
514 private void DeserializeClient(RegionInfo dst_region, string import_dir)
515 {
516 ScenePresence sp = null;
517 ClientInfo data = null;
518 Scene scene = null;
519 string[] files = null;
520 IClientAPI controller = null;
521 UDPServer udpserv = null;
522
523 if (sceneManager.TryGetScene(dst_region.RegionID, out scene))
524 {
525 // search udpserver
526 udpserv = SearchUDPServerFromPortNum(scene.RegionInfo.InternalEndPoint.Port);
527
528 // restore the scene presence
529/*
530 files = Directory.GetFiles(import_dir, "Presence_*.bin");
531 Array.Sort(files);
532
533 foreach (string filename in files)
534 {
535 sp = (ScenePresence)Util.DeserializeFromFile(filename);
536 Console.WriteLine("agent id = {0}", sp.m_uuid);
537
538 scene.m_restorePresences.Add(sp.m_uuid, sp);
539 File.Delete(filename);
540
541 m_log.InfoFormat("[BALANCER] "+"scene presence deserialized [{0}]", sp.m_uuid);
542 }
543*/
544 for (int i = 0; ; i++)
545 {
546 string filename = import_dir + "Presence_" + String.Format("{0:0000}", i) + ".bin";
547
548 if (!File.Exists(filename))
549 {
550 break;
551 }
552
553 sp = (ScenePresence)Util.DeserializeFromFile(filename);
554 Console.WriteLine("agent id = {0}", sp.m_uuid);
555
556 scene.m_restorePresences.Add(sp.m_uuid, sp);
557 File.Delete(filename);
558
559 m_log.InfoFormat("[BALANCER] " + "scene presence deserialized [{0}]", sp.m_uuid);
560
561 // restore the ClientView
562
563 files = Directory.GetFiles(import_dir, "ClientInfo-" + String.Format("{0:0000}", i) + "_*.bin");
564
565 foreach (string fname in files)
566 {
567 int start = fname.IndexOf('_');
568 int end = fname.LastIndexOf('.');
569 uint circuit_code = uint.Parse(fname.Substring(start + 1, end - start - 1));
570 m_log.InfoFormat("[BALANCER] " + "client circuit code = {0}", circuit_code);
571
572 data = (ClientInfo)Util.DeserializeFromFile(fname);
573
574 AgentCircuitData agentdata = new AgentCircuitData(data.agentcircuit);
575 scene.AuthenticateHandler.AddNewCircuit(circuit_code, agentdata);
576
577 udpserv.RestoreClient(agentdata, data.userEP, data.proxyEP);
578
579 // waiting for the scene-presense restored
580 lock (scene.m_restorePresences)
581 {
582 Monitor.Wait(scene.m_restorePresences, 3000);
583 }
584
585 if (scene.ClientManager.TryGetClient(circuit_code, out controller))
586 {
587 m_log.InfoFormat("[BALANCER] " + "get client [{0}]", circuit_code);
588 controller.SetClientInfo(data);
589 }
590
591 File.Delete(fname);
592
593 m_log.InfoFormat("[BALANCER] " + "client info deserialized [{0}]", circuit_code);
594 }
595
596 // backup new scene's entities
597 //scene.Backup();
598 }
599 }
600 }
601
602 private void CreateCloneRegion(RegionInfo dst_region, int dst_port, bool createID_flag)
603 {
604 if (createID_flag)
605 {
606 dst_region.RegionID = LLUUID.Random();
607 }
608
609 // change RegionInfo (memory only)
610 dst_region.InternalEndPoint.Port = dst_port;
611 dst_region.ExternalHostName = proxyURL.Split(new char[] { '/', ':' })[3];
612
613 // Create new region
614 simMain.CreateRegion(dst_region, false);
615 }
616
617 private void RemoveRegion(LLUUID regionID, int port)
618 {
619 Scene killScene;
620 if (sceneManager.TryGetScene(regionID, out killScene))
621 {
622 Console.WriteLine("scene found.");
623
624 if ((sceneManager.CurrentScene != null)
625 && (sceneManager.CurrentScene.RegionInfo.RegionID == killScene.RegionInfo.RegionID))
626 {
627 sceneManager.TrySetCurrentScene("..");
628 }
629
630 m_log.Info("Removing region : " + killScene.RegionInfo.RegionName);
631 regionData.Remove(killScene.RegionInfo);
632 sceneManager.CloseScene(killScene);
633 }
634
635 // Shutting down the UDP server
636 UDPServer udpsvr = SearchUDPServerFromPortNum(port);
637
638 if (udpsvr != null)
639 {
640 udpsvr.Server.Close();
641 udpServers.Remove(udpsvr);
642 }
643 }
644
645 private void RemoveAllClientResource(RegionInfo src_region)
646 {
647 Scene scene = null;
648 List<ScenePresence> presences;
649 IClientAPI controller = null;
650
651 // try to get the scene object
652 if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false)
653 {
654 m_log.Error("[BALANCER] "+"The Scene is not found");
655 return;
656 }
657
658 // serialization of client's informations
659 presences = scene.GetScenePresences();
660
661 // remove all scene presences
662 foreach (ScenePresence pre in presences)
663 {
664 uint[] circuits = scene.ClientManager.GetAllCircuits(pre.m_uuid);
665
666 foreach (uint code in circuits)
667 {
668 m_log.InfoFormat("[BALANCER] "+"circuit code : {0}", code);
669
670 if (scene.ClientManager.TryGetClient(code, out controller))
671 {
672 // stopping clientview thread
673 if (((ClientView)controller).PacketProcessingEnabled)
674 {
675 controller.Stop();
676 ((ClientView)controller).PacketProcessingEnabled = false;
677 }
678 // teminateing clientview thread
679 controller.Terminate();
680 m_log.Info("[BALANCER] "+"client thread stopped");
681 }
682 }
683
684 // remove scene presence
685 scene.RemoveClient(pre.m_uuid);
686 }
687 }
688
689 /*
690 * This section implements scene splitting and synchronization
691 */
692
693 private bool[] isLocalNeighbour;
694 private string[] sceneURL;
695 private int[] regionPortList;
696 private TcpClient[] tcpClientList;
697 private bool isSplit = false;
698
699 private XmlRpcResponse SplitRegion(XmlRpcRequest request)
700 {
701 try
702 {
703 int myID = (int) request.Params[0];
704 int numRegions = (int) request.Params[1];
705 regionPortList = new int[numRegions];
706 sceneURL = new string[numRegions];
707 tcpClientList = new TcpClient[numRegions];
708
709 for(int i=0; i<numRegions; i++)
710 {
711 regionPortList[i]=(int) request.Params[i+2];
712 sceneURL[i]=(string) request.Params[i+2+numRegions];
713 }
714
715 string hostname;
716
717 for(int i=0; i<numRegions; i++)
718 {
719 hostname = sceneURL[i].Split(new char[] { '/', ':' })[3];
720 m_log.InfoFormat("[SPLITSCENE] "+"creating tcp client host:{0}", hostname);
721 tcpClientList[i] = new TcpClient(hostname, 10001);
722 }
723
724 bool isMaster = (myID == 0);
725
726 isLocalNeighbour = new bool[numRegions];
727 for(int i=0; i<numRegions; i++) isLocalNeighbour[i] = (sceneURL[i] == sceneURL[myID]);
728
729 RegionInfo region = SearchRegionFromPortNum(regionPortList[myID]);
730
731 //Console.WriteLine("\n === SplitRegion {0}\n", region.RegionID);
732
733 Scene scene;
734 if (sceneManager.TryGetScene(region.RegionID, out scene))
735 {
736 // Disable event updates, backups etc in the slave(s)
737 if (isMaster) {
738 scene.Region_Status = RegionStatus.Up;
739 }
740 else
741 {
742 scene.Region_Status = RegionStatus.SlaveScene;
743 }
744
745 //Console.WriteLine("=== SplitRegion {0}: Scene found, status {1}", region.RegionID, scene.Region_Status);
746
747 // Disabling half of the avatars in master, and the other half in slave
748
749 int i = 0;
750 List<ScenePresence> presences = scene.GetScenePresences();
751presences.Sort();
752 foreach (ScenePresence pre in presences)
753 {
754 // Divide the presences evenly over the set of subscenes
755 ClientView client = (ClientView) pre.ControllingClient;
756 client.PacketProcessingEnabled = (( (i + myID) % sceneURL.Length) == 0);
757
758 m_log.InfoFormat("[SPLITSCENE] === SplitRegion {0}: SP.PacketEnabled {1}", region.RegionID, client.PacketProcessingEnabled);
759
760 if (!client.PacketProcessingEnabled)
761 {
762 // stopping clientview thread
763 client.Stop();
764 }
765
766 ++i;
767 }
768
769 scene.splitID = myID;
770 scene.SynchronizeScene = new Scene.SynchronizeSceneHandler(SynchronizeScenes);
771 isSplit = true;
772 }
773 else
774 {
775 m_log.Error("[SPLITSCENE] "+String.Format("Scene not found {0}", region.RegionID));
776 }
777 }
778 catch (Exception e)
779 {
780 m_log.Error("[SPLITSCENE] "+e.ToString());
781 m_log.Error("[SPLITSCENE] "+e.StackTrace);
782 }
783
784 return new XmlRpcResponse();
785 }
786
787 private XmlRpcResponse MergeRegions(XmlRpcRequest request)
788 {
789 // This should only be called for the master scene
790 try
791 {
792 m_log.Info("[BALANCER] "+"Entering MergeRegions()");
793
794 string src_url = (string) request.Params[0];
795 int src_port = (int) request.Params[1];
796
797 RegionInfo region = SearchRegionFromPortNum(src_port);
798
799 simMain.ProxyCommand(region.proxyUrl, "BlockClientMessages", src_url, src_port + proxyOffset);
800
801 Scene scene;
802 if (sceneManager.TryGetScene(region.RegionID, out scene))
803 {
804 isSplit = false;
805
806 scene.SynchronizeScene = null;
807 scene.Region_Status = RegionStatus.Up;
808
809 List<ScenePresence> presences = scene.GetScenePresences();
810 foreach (ScenePresence pre in presences)
811 {
812 ClientView client = (ClientView) pre.ControllingClient;
813 if (!client.PacketProcessingEnabled)
814 {
815 client.Restart();
816 client.PacketProcessingEnabled = true;
817 }
818 }
819 }
820
821 // Delete the slave scenes
822 for(int i=1; i<sceneURL.Length; i++)
823 {
824 string url = (sceneURL[i].Split('/')[2]).Split(':')[0]; // get URL part from EP
825 simMain.ProxyCommand(region.proxyUrl, "DeleteRegion", regionPortList[i] + proxyOffset, url);
826 Thread.Sleep(1000);
827 simMain.XmlRpcCommand(sceneURL[i], "TerminateRegion", regionPortList[i]); // TODO: need + proxyOffset?
828 }
829
830 simMain.ProxyCommand(region.proxyUrl, "UnblockClientMessages", src_url, src_port + proxyOffset);
831 }
832 catch (Exception e)
833 {
834 m_log.Error("[BALANCER] "+e.ToString());
835 m_log.Error("[BALANCER] "+e.StackTrace);
836 throw e;
837 }
838
839 return new XmlRpcResponse();
840 }
841
842 private XmlRpcResponse UpdatePhysics(XmlRpcRequest request)
843 {
844 // this callback receives physic scene updates from the other sub-scenes (in split mode)
845
846 int regionPort = (int) request.Params[0];
847 LLUUID scenePresenceID = new LLUUID((byte[]) request.Params[1], 0);
848 LLVector3 position = new LLVector3((byte[]) request.Params[2], 0);
849 LLVector3 velocity = new LLVector3((byte[]) request.Params[3], 0);
850 bool flying = (bool) request.Params[4];
851
852 LocalUpdatePhysics(regionPort, scenePresenceID, position, velocity, flying);
853
854 return new XmlRpcResponse();
855 }
856
857 private void LocalUpdatePhysics(int regionPort, LLUUID scenePresenceID, LLVector3 position, LLVector3 velocity, bool flying)
858 {
859 //m_log.Info("[SPLITSCENE] "+String.Format("UpdatePhysics called {0}", regionID));
860
861 //m_log.Info("[SPLITSCENE] "+"LocalUpdatePhysics [region port:{0}, client:{1}, position:{2}, velocity:{3}, flying:{4}]",
862 // regionPort, scenePresenceID.ToString(), position.ToString(),
863 // velocity.ToString(), flying);
864
865 RegionInfo region = SearchRegionFromPortNum(regionPort);
866
867 // Find and update the scene precense
868 Scene scene;
869 if (sceneManager.TryGetScene(region.RegionID, out scene))
870 {
871 ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == scenePresenceID; });
872
873 if (pre == null)
874 {
875 m_log.ErrorFormat("[SPLITSCENE] [LocalUpdatePhysics] ScenePresence is missing... ({0})", scenePresenceID.ToString());
876 return;
877 }
878
879// m_log.Info("[SPLITSCENE] "+"LocalUpdatePhysics [region:{0}, client:{1}]",
880// regionID.ToString(), pre.UUID.ToString());
881
882 pre.AbsolutePosition = position;// will set PhysicsActor.Position
883 pre.Velocity = velocity; // will set PhysicsActor.Velocity
884 pre.PhysicsActor.Flying = flying;
885 }
886 }
887
888 object padlock=new object();
889 private void SynchronizeScenes(Scene scene)
890 {
891 if (!isSplit)
892 {
893 return;
894 }
895
896 lock(padlock)
897 {
898 // Callback activated after a physics scene update
899// int i = 0;
900 List<ScenePresence> presences = scene.GetScenePresences();
901 foreach (ScenePresence pre in presences)
902 {
903 ClientView client = (ClientView) pre.ControllingClient;
904
905 // Because data changes by the physics simulation when the client doesn't move,
906 // if MovementFlag is false, It is necessary to synchronize.
907 //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true)
908 if(client.PacketProcessingEnabled==true)
909 {
910 //m_log.Info("[SPLITSCENE] "+String.Format("Client moving in {0} {1}", scene.RegionInfo.RegionID, pre.AbsolutePosition));
911
912 for (int i = 0; i < sceneURL.Length; i++)
913 {
914 if (i == scene.splitID)
915 {
916 continue;
917 }
918
919 if(isLocalNeighbour[i])
920 {
921 //m_log.Info("[SPLITSCENE] "+"Synchronize ScenePresence (Local) [region:{0}=>{1}, client:{2}]",
922 // scene.RegionInfo.RegionID, regionPortList[i], pre.UUID.ToString());
923 LocalUpdatePhysics(regionPortList[i], pre.UUID, pre.AbsolutePosition, pre.Velocity, pre.PhysicsActor.Flying);
924 }
925 else
926 {
927 //m_log.Info("[SPLITSCENE] "+"Synchronize ScenePresence (Remote) [region port:{0}, client:{1}, position:{2}, velocity:{3}, flying:{4}]",
928 // regionPortList[i], pre.UUID.ToString(), pre.AbsolutePosition.ToString(),
929 // pre.Velocity.ToString(), pre.PhysicsActor.Flying);
930
931
932 simMain.XmlRpcCommand(sceneURL[i], "UpdatePhysics",
933 regionPortList[i], pre.UUID.GetBytes(),
934 pre.AbsolutePosition.GetBytes(), pre.Velocity.GetBytes(),
935 pre.PhysicsActor.Flying);
936
937/*
938 byte[] buff = new byte[12+12+1];
939
940 Buffer.BlockCopy(pre.AbsolutePosition.GetBytes(), 0, buff, 0, 12);
941 Buffer.BlockCopy(pre.Velocity.GetBytes(), 0, buff, 12, 12);
942 buff[24] = (byte)((pre.PhysicsActor.Flying)?1:0);
943
944 // create header
945 InternalPacketHeader header = new InternalPacketHeader();
946
947 header.type = 1;
948 header.throttlePacketType = 0;
949 header.numbytes = buff.Length;
950 header.agent_id = pre.UUID.UUID;
951 header.region_port = regionPortList[i];
952
953 //Send
954 tcpClientList[i].send(header, buff);
955*/
956 }
957 }
958 }
959// ++i;
960 }
961 }
962 }
963
964 public bool SynchronizePackets(IScene scene, Packet packet, LLUUID agentID, ThrottleOutPacketType throttlePacketType)
965 {
966 if (!isSplit)
967 {
968 return false;
969 }
970
971 Scene localScene = (Scene)scene;
972
973 for (int i = 0; i < sceneURL.Length; i++)
974 {
975 if (i == localScene.splitID)
976 {
977 continue;
978 }
979
980 if(isLocalNeighbour[i])
981 {
982 //m_log.Info("[SPLITSCENE] "+"Synchronize Packet (Local) [type:{0}, client:{1}]",
983 // packet.Type.ToString(), agentID.ToString());
984 LocalUpdatePacket(regionPortList[i], agentID, packet, throttlePacketType);
985 }
986 else
987 {
988 //m_log.Info("[SPLITSCENE] "+"Synchronize Packet (Remote) [type:{0}, client:{1}]",
989 // packet.Type.ToString(), agentID.ToString());
990 // to bytes
991 byte[] buff = packet.ToBytes();
992
993 // create header
994 InternalPacketHeader header = new InternalPacketHeader();
995
996 header.type = 0;
997 header.throttlePacketType = (int)throttlePacketType;
998 header.numbytes = buff.Length;
999 header.agent_id = agentID.UUID;
1000 header.region_port = regionPortList[i];
1001
1002 //Send
1003 tcpClientList[i].send(header, buff);
1004
1005 PacketPool.Instance.ReturnPacket(packet);
1006 }
1007 }
1008
1009 return true;
1010 }
1011
1012 private void LocalUpdatePacket(int regionPort, LLUUID agentID, Packet packet, ThrottleOutPacketType throttlePacketType)
1013 {
1014 Scene scene;
1015
1016 RegionInfo region = SearchRegionFromPortNum(regionPort);
1017
1018// m_log.Info("[SPLITSCENE] "+"LocalUpdatePacket [region port:{0}, client:{1}, packet type:{2}]",
1019// regionPort, agentID.ToString(), packet.GetType().ToString());
1020
1021 if (sceneManager.TryGetScene(region.RegionID, out scene))
1022 {
1023 ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == agentID; });
1024
1025 if (pre == null)
1026 {
1027 m_log.ErrorFormat("[SPLITSCENE] [LocalUpdatePacket] ScenePresence is missing... ({0})", agentID.ToString());
1028 return;
1029 }
1030
1031 if (((ClientView)pre.ControllingClient).PacketProcessingEnabled==true)
1032 {
1033 pre.ControllingClient.OutPacket(packet, throttlePacketType);
1034 }
1035 else
1036 {
1037 PacketPool.Instance.ReturnPacket(packet);
1038 }
1039 }
1040 }
1041
1042 public void SynchronizePacketRecieve(InternalPacketHeader header, byte[] buff)
1043 {
1044// m_log.Info("[SPLITSCENE] "+"entering SynchronizePacketRecieve[type={0}]", header.type);
1045
1046 if (!isSplit)
1047 {
1048 return;
1049 }
1050
1051 switch (header.type)
1052 {
1053 case 0:
1054
1055 Packet packet = null;
1056 byte[] zero = new byte[3000];
1057 int packetEnd = 0;
1058
1059 // deserialize packet
1060 packetEnd = buff.Length - 1;
1061// packetEnd = buff.Length;
1062
1063 try
1064 {
1065 //m_log.Info("[SPLITSCENE] "+"PacketPool.Instance : {0}", (PacketPool.Instance == null)?"null":"not null");
1066 //m_log.Info("[SPLITSCENE] "+"buff length={0}", buff.Length);
1067
1068 packet = PacketPool.Instance.GetPacket(buff, ref packetEnd, zero);
1069
1070 LocalUpdatePacket(header.region_port, new LLUUID(header.agent_id),
1071 packet, (ThrottleOutPacketType)header.throttlePacketType);
1072 }
1073 catch (Exception e)
1074 {
1075 m_log.Error("[SPLITSCENE] "+e.ToString());
1076 m_log.Error("[SPLITSCENE] "+e.StackTrace);
1077 }
1078
1079 break;
1080
1081 case 1:
1082
1083 int regionPort = header.region_port;
1084 LLUUID scenePresenceID = new LLUUID(header.agent_id);
1085 LLVector3 position = new LLVector3(buff, 0);
1086 LLVector3 velocity = new LLVector3(buff, 12);
1087 bool flying = ((buff[24] == (byte)1)?true:false);
1088
1089 LocalUpdatePhysics(regionPort, scenePresenceID, position, velocity, flying);
1090
1091 break;
1092
1093 default:
1094 m_log.Info("[SPLITSCENE] "+"Invalid type");
1095 break;
1096 }
1097
1098// m_log.Info("[SPLITSCENE] "+"exiting SynchronizePacketRecieve");
1099 }
1100 }
1101}
diff --git a/ThirdParty/3Di/LoadBalancer/TcpClient.cs b/ThirdParty/3Di/LoadBalancer/TcpClient.cs
new file mode 100644
index 0000000..9f62d33
--- /dev/null
+++ b/ThirdParty/3Di/LoadBalancer/TcpClient.cs
@@ -0,0 +1,240 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.IO;
31using System.Net;
32using System.Net.Sockets;
33using System.Threading;
34using System.Text;
35using System.Runtime.Serialization.Formatters.Binary;
36
37namespace OpenSim.ApplicationPlugins.LoadBalancer {
38 public class AsynchronousClient {
39 private static ManualResetEvent connectDone = new ManualResetEvent(false);
40 private static ManualResetEvent sendDone = new ManualResetEvent(false);
41 private static ManualResetEvent receiveDone = new ManualResetEvent(false);
42 private static String response = String.Empty;
43
44 public static Socket StartClient(string hostname, int port) {
45 try {
46 IPHostEntry ipHostInfo = Dns.GetHostEntry(hostname);
47 IPAddress ipAddress = ipHostInfo.AddressList[0];
48 IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
49
50 Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
51 client.BeginConnect( remoteEP, new AsyncCallback(ConnectCallback), client);
52 connectDone.WaitOne();
53 /*
54 Send(client,"This is a test<EOF>");
55 sendDone.WaitOne();
56 Receive(client);
57 receiveDone.WaitOne();
58 client.Shutdown(SocketShutdown.Both);
59 client.Close();
60 */
61 return client;
62 } catch (Exception e) {
63 Console.WriteLine(e.ToString());
64 throw new Exception("socket error !!");
65 }
66 }
67
68 private static void ConnectCallback(IAsyncResult ar) {
69 try {
70 Socket client = (Socket) ar.AsyncState;
71 client.EndConnect(ar);
72 Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
73 connectDone.Set();
74 } catch (Exception e) {
75 Console.WriteLine(e.ToString());
76 }
77 }
78
79/*
80 public static void Receive(Socket client) {
81 try {
82 StateObject state = new StateObject();
83 state.workSocket = client;
84 client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
85 } catch (Exception e) {
86 Console.WriteLine(e.ToString());
87 }
88 }
89
90 private static void ReceiveCallback( IAsyncResult ar ) {
91 try {
92 StateObject state = (StateObject) ar.AsyncState;
93 Socket client = state.workSocket;
94
95 int bytesRead = client.EndReceive(ar);
96 if (bytesRead > 0) {
97 state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
98 client.BeginReceive(state.buffer,0,StateObject.BufferSize,0, new AsyncCallback(ReceiveCallback), state);
99 } else {
100 if (state.sb.Length > 1) {
101 response = state.sb.ToString();
102 }
103 receiveDone.Set();
104 }
105 } catch (Exception e) {
106 Console.WriteLine(e.ToString());
107 }
108 }
109*/
110 public static void Send(Socket client, byte[] byteData) {
111 client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
112 }
113
114 private static void SendCallback(IAsyncResult ar) {
115 try {
116 Socket client = (Socket) ar.AsyncState;
117 int bytesSent = client.EndSend(ar);
118 //Console.WriteLine("Sent {0} bytes to server.", bytesSent);
119 sendDone.Set();
120 } catch (Exception e) {
121 Console.WriteLine(e.ToString());
122 }
123 }
124 }
125
126public class InternalPacketHeader
127{
128 private byte[] buffer = new byte[32];
129 public int type;
130 public int throttlePacketType;
131 public int numbytes;
132 public Guid agent_id;
133 public int region_port;
134
135 public void FromBytes(byte[] bytes)
136 {
137 int i = 0; // offset
138 try
139 {
140 this.type = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
141 this.throttlePacketType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
142 this.numbytes = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
143 this.agent_id = new Guid(
144 bytes[i++] | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24,
145 (short)(bytes[i++] | (bytes[i++] << 8)),
146 (short)(bytes[i++] | (bytes[i++] << 8)),
147 bytes[i++], bytes[i++], bytes[i++], bytes[i++],
148 bytes[i++], bytes[i++], bytes[i++], bytes[i++]);
149 this.region_port = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
150 }
151 catch (Exception)
152 {
153 throw new Exception("bad format!!!");
154 }
155 }
156
157 public byte[] ToBytes()
158 {
159 int i = 0;
160 this.buffer[i++] = (byte)(this.type % 256);
161 this.buffer[i++] = (byte)((this.type >> 8) % 256);
162 this.buffer[i++] = (byte)((this.type >> 16) % 256);
163 this.buffer[i++] = (byte)((this.type >> 24) % 256);
164
165 this.buffer[i++] = (byte)(this.throttlePacketType % 256);
166 this.buffer[i++] = (byte)((this.throttlePacketType >> 8) % 256);
167 this.buffer[i++] = (byte)((this.throttlePacketType >> 16) % 256);
168 this.buffer[i++] = (byte)((this.throttlePacketType >> 24) % 256);
169
170 this.buffer[i++] = (byte)(this.numbytes % 256);
171 this.buffer[i++] = (byte)((this.numbytes >> 8) % 256);
172 this.buffer[i++] = (byte)((this.numbytes >> 16) % 256);
173 this.buffer[i++] = (byte)((this.numbytes >> 24) % 256);
174
175 // no endian care
176 Buffer.BlockCopy(agent_id.ToByteArray(), 0, this.buffer, i, 16); i += 16;
177
178 this.buffer[i++] = (byte)(this.region_port % 256);
179 this.buffer[i++] = (byte)((this.region_port >> 8) % 256);
180 this.buffer[i++] = (byte)((this.region_port >> 16) % 256);
181 this.buffer[i++] = (byte)((this.region_port >> 24) % 256);
182
183 return this.buffer;
184 }
185}
186 public class TcpClient {
187
188 public static int internalPacketHeaderSize = 4*4 + 16*1;
189
190 private string mHostname;
191 private int mPort;
192 private Socket mConnection;
193 public TcpClient(string hostname, int port) {
194 this.mHostname = hostname;
195 this.mPort = port;
196 this.mConnection = null;
197 }
198 public void connect() {
199 this.mConnection = AsynchronousClient.StartClient(mHostname, mPort);
200 }
201/*
202 public void recevie() {
203 if (mConnection == null) {
204 throw new Exception("client not initialized");
205 }
206 try
207 {
208 AsynchronousClient.Receive(this.mConnection);
209 }
210 catch (Exception e)
211 {
212 Console.WriteLine(e.ToString());
213 mConnection = null;
214 }
215 }
216*/
217 public void send(InternalPacketHeader header, byte[] packet) {
218
219 lock (this)
220 {
221
222 if (mConnection == null) {
223// throw new Exception("client not initialized");
224 connect();
225 }
226
227 AsynchronousClient.Send(this.mConnection, header.ToBytes());
228
229/*
230for (int i = 0; i < 10; i++)
231{
232 Console.Write(packet[i] + " ");
233}
234Console.WriteLine("");
235*/
236 AsynchronousClient.Send(this.mConnection, packet);
237 }
238 }
239 }
240}
diff --git a/ThirdParty/3Di/LoadBalancer/TcpServer.cs b/ThirdParty/3Di/LoadBalancer/TcpServer.cs
new file mode 100644
index 0000000..ee8bcba
--- /dev/null
+++ b/ThirdParty/3Di/LoadBalancer/TcpServer.cs
@@ -0,0 +1,219 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.IO;
31using System.Net;
32using System.Net.Sockets;
33using System.Text;
34using System.Threading;
35using System.Runtime.Serialization.Formatters.Binary;
36
37using OpenSim.Framework.Console;
38
39namespace OpenSim.ApplicationPlugins.LoadBalancer {
40
41 public class StateObject {
42 public Socket workSocket = null;
43 public const int BufferSize = 2048;
44 public byte[] buffer = new byte[BufferSize];
45 public MemoryStream ms_ptr = new MemoryStream();
46 public InternalPacketHeader header = null;
47 }
48
49 public class AsynchronousSocketListener {
50 public static string data = null;
51 public static ManualResetEvent allDone = new ManualResetEvent(false);
52
53#region KIRYU
54 public delegate void PacketRecieveHandler(InternalPacketHeader header, byte[] buff);
55 public static PacketRecieveHandler PacketHandler = null;
56#endregion
57
58 public AsynchronousSocketListener() { }
59
60 public static void StartListening(int port) {
61 IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
62 IPAddress ipAddress = ipHostInfo.AddressList[0];
63 IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
64
65 Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
66 try {
67 listener.Bind(localEndPoint);
68 listener.Listen(100);
69 while (true) {
70 allDone.Reset();
71 listener.BeginAccept( new AsyncCallback(AcceptCallback), listener );
72 allDone.WaitOne();
73 }
74 } catch (Exception e) {
75 Console.WriteLine(e.ToString());
76 }
77 /*
78 Console.WriteLine("\nPress ENTER to continue...");
79 Console.Read();
80 */
81 }
82
83 public static void AcceptCallback(IAsyncResult ar) {
84 allDone.Set();
85 Socket listener = (Socket) ar.AsyncState;
86 Socket handler = listener.EndAccept(ar);
87 StateObject state = new StateObject();
88 state.workSocket = handler;
89 handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
90 }
91
92 public static void ReadCallback(IAsyncResult ar) {
93 String content = String.Empty;
94 StateObject state = (StateObject) ar.AsyncState;
95 Socket handler = state.workSocket;
96
97 try
98 {
99
100 int bytesRead = handler.EndReceive(ar);
101
102 //MainLog.Instance.Verbose("TCPSERVER", "Received packet [{0}]", bytesRead);
103
104 if (bytesRead > 0) {
105 state.ms_ptr.Write(state.buffer, 0, bytesRead);
106 }
107 else
108 {
109 //MainLog.Instance.Verbose("TCPSERVER", "Connection terminated");
110 return;
111 }
112
113 long rest_size = state.ms_ptr.Length;
114 long current_pos = 0;
115 while (rest_size > TcpClient.internalPacketHeaderSize) {
116
117 if ((state.header == null) && (rest_size >= TcpClient.internalPacketHeaderSize))
118 {
119 //MainLog.Instance.Verbose("TCPSERVER", "Processing header");
120
121 // reading header
122 state.header = new InternalPacketHeader();
123
124 byte[] headerbytes = new byte[TcpClient.internalPacketHeaderSize];
125 state.ms_ptr.Position = current_pos;
126 state.ms_ptr.Read(headerbytes, 0, TcpClient.internalPacketHeaderSize);
127 state.ms_ptr.Seek(0, SeekOrigin.End);
128 state.header.FromBytes(headerbytes);
129 }
130
131 if ((state.header != null) && (rest_size >= state.header.numbytes + TcpClient.internalPacketHeaderSize))
132 {
133 //MainLog.Instance.Verbose("TCPSERVER", "Processing body");
134
135 // reading body
136 byte[] packet = new byte[state.header.numbytes];
137 state.ms_ptr.Position = current_pos + TcpClient.internalPacketHeaderSize;
138 state.ms_ptr.Read(packet, 0, state.header.numbytes);
139
140/*
141 for(int i=0; i<state.header.numbytes; i++) {
142 System.Console.Write(packet[i] + " ");
143 }
144 System.Console.WriteLine();
145*/
146
147 state.ms_ptr.Seek(0, SeekOrigin.End);
148 // call loadbarancer function
149 if (PacketHandler != null)
150 {
151 //MainLog.Instance.Verbose("TCPSERVER", "calling PacketHandler");
152 PacketHandler(state.header, packet);
153 }
154 else
155 {
156 //MainLog.Instance.Verbose("TCPSERVER", "PacketHandler not found");
157 }
158
159 int read_size = state.header.numbytes + TcpClient.internalPacketHeaderSize;
160 state.header = null;
161
162 rest_size -= read_size;
163 current_pos += read_size;
164
165 if (rest_size < TcpClient.internalPacketHeaderSize) {
166
167 byte[] rest_bytes = new byte[rest_size];
168 state.ms_ptr.Position = read_size;
169 state.ms_ptr.Read(rest_bytes, 0, (int)rest_size);
170 state.ms_ptr.Close();
171 state.ms_ptr = new MemoryStream();
172 state.ms_ptr.Write(rest_bytes, 0, (int)rest_size);
173 break;
174 }
175 }
176
177 } // while (true)
178
179 }
180 catch (Exception e)
181 {
182 //MainLog.Instance.Verbose("TCPSERVER", e.ToString());
183 //MainLog.Instance.Verbose("TCPSERVER", e.StackTrace);
184 }
185
186 handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
187 }
188
189 private static void Send(Socket handler, String data) {
190 byte[] byteData = Encoding.ASCII.GetBytes(data);
191 handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
192 }
193
194 private static void SendCallback(IAsyncResult ar) {
195 try {
196 Socket handler = (Socket) ar.AsyncState;
197 int bytesSent = handler.EndSend(ar);
198 //Console.WriteLine("Sent {0} bytes to client.", bytesSent);
199 handler.Shutdown(SocketShutdown.Both);
200 handler.Close();
201 } catch (Exception e) {
202 Console.WriteLine(e.ToString());
203 }
204 }
205 }
206
207 public class TcpServer {
208 private int mPort = 11000;
209 public TcpServer() {
210 }
211 public TcpServer(int port) {
212 mPort = port;
213 }
214 public void start() {
215 AsynchronousSocketListener.StartListening(mPort);
216 }
217 }
218}
219
diff --git a/ThirdParty/3Di/README.txt b/ThirdParty/3Di/README.txt
new file mode 100644
index 0000000..fd7980b
--- /dev/null
+++ b/ThirdParty/3Di/README.txt
@@ -0,0 +1,82 @@
1INTRODUCTION
2
3This folder contains code that implement:
4
51. Dynamic load balancing
6
7OpenSim is allowing many regions to share a region server, but the optimal
8number of regions on each server depends on the load of each region, something
9which may change as time goes on. 3Di is working on a load balancer that
10allows the current load to be monitored and regions to be reassigned without
11requiring the servers to be restarted. To move a region, its state is
12serialized, and a new clone is created on the target server using this
13stream. The old region is then destroyed and the client viewer updated to use
14the new region address.
15
162. Region splitting
17
18Currently each region can hold only a small number of avatars. To allow more
19avatars in each region, 3Di has implemented region splitting, in which several
20copies of a given region can be distributed across the region servers. Each
21sub-region updates a fraction of the avatars, and sends state updates to the
22other sub-regions.
23
24IMPLEMENTATION
25
26The code is organised as follows:
27
28* LoadBalancer: communicates with other region servers and creates/destroys
29regions on command
30* RegionMonitor/MonitorGUI: provides a browser GUI, showing the state of the
31grid, and provides buttons for controlling region movement, splitting, and
32merging.
33* RegionMonitor/ServerPlugin: this is a region server plugin which
34communicates with the load balancer GUI to provide information
35on the identity and status of the regions on the grid
36* RegionProxy: maps messages from a clients to the true location of a region.
37
38USAGE
39
40In order to use these additions the following lines have to be added to
41OpenSim.ini:
42
43proxy_offset = -1000
44proxy_url = http://10.8.1.50:9001
45serialize_dir = /mnt/temp/
46
47If defined, proxy_offset defines how to calculate the true region port, e.g.
48if the XML defines the port as 9000 the actual port is 8000 if proxy_offset
49is -1000. The RegionProxy module will open a port at 9000 which the clients
50can connect to, and route all traffic from there to port 8000. This allows
51the region proxy to run on region server together with regions without
52blocking them by using the same port number.
53
54The proxy location is defined in proxy_url. When splitting, the region state
55is stored on a file in the folder specified in serialize_dir. This has to be
56a shared folder which both region servers involved in the split have access to.
57
583. Monitor GUI
59
60RegionMonitor/MonitorGUI is used to view status of all the managed Region
61servers, and send "Move", "Split", "Merge" commands to a specified Regions
62server.
63
64MonitorGUI is a web-based application. You can access it through a web browser.
65Its back-end is written in perl. (CGI script)
66
67Pre-requierments (CentOS, Fedora)
68
69RPM package "perl-XML-RPC" and relevant packages.
70
71Installation
72
731. Install Apache
742. copy all the files undef "ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs" to
75"$APACHE_ROOT/htdocs"
763. Configuration in "monitor.cgi"
77 * 10th line, set the value to your "monitor.cgi"'s location.
78 * 11th line, set the value to your Grid server.
79 * 12th line, set your region proxy port number here.
80 (ref. OpenSim.ini::NetWork::http_listener_port)
81* The code also works fine with mod_perl.
82
diff --git a/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MonitorGUI/View.pm b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MonitorGUI/View.pm
new file mode 100644
index 0000000..bab462f
--- /dev/null
+++ b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MonitorGUI/View.pm
@@ -0,0 +1,214 @@
1package MonitorGUI::View;
2
3use strict;
4
5my @server_list;
6my $max_port;
7my $regions;
8
9sub screen_header {
10 return << "HEADER";
11<HTML>
12<HEAD>
13<STYLE TYPE="text/css">
14<!--
15a:link {font-size: 12pt; text-decoration:none; color:#0000ff ;}
16a:visited {font-size: 12pt; text-decoration:none; color:#ff0000 ;}
17a:active {font-size: 12pt; text-decoration:none; color:#00ff00 ;}
18a:hover {font-size: 12pt; text-decoration:underline; color:#ff00ff ;}
19td {font-size: 12pt;border:0;}
20th {background-color:#000000; font-size: 12pt;border:0; color:#FFFFFF; }
21tr {background-color:#FFFFFF; }
22b {font-size: 12pt;}
23//table {background-color:#000000; }
24-->
25</STYLE>
26<META http-equiv="content-type" content="text/html;charset=UTF-8" />
27<META name="refresh" content="300" />
28<TITLE>Region Monitor GUI, 3Di</TITLE>
29</HEAD>
30<BODY>
31HEADER
32}
33
34sub screen_footer {
35 return << "FOOTER";
36</BODY>
37</HTML>
38FOOTER
39}
40
41sub html {
42 my $grid_info = shift;
43 my $regions_list = $grid_info->{"sim-profiles"};
44 $regions = undef;
45 foreach(@$regions_list) {
46 my $ip = $_->{sim_ip} || "UNKNOWN";
47 my $port = $_->{sim_port} || "UNKNOWN";
48 $regions->{$ip}->{$port} = $_;
49 if (!$regions->{max_port} || $regions->{max_port} < $port) {
50 $regions->{max_port} = $port;
51 }
52 }
53 @server_list = keys %$regions;
54 $max_port = $regions->{max_port};
55 my $html = "";
56 foreach my $machine (@server_list) {
57 next if ($machine eq "max_port");
58 $html .= &_machine_view($machine, $regions->{$machine});
59 }
60 return $html;
61}
62
63sub _machine_view {
64 my ($ip, $info) = @_;
65 my $region_html = "";
66 foreach my $region (keys %$info) {
67 $region_html .= &_region_html($info->{$region});
68 }
69 my $html =<< "MACHINE_HTML";
70<h3>$ip</h3>
71$region_html
72<hr size=0 noshade />
73MACHINE_HTML
74}
75
76sub _region_html {
77 my $region_info = shift;
78 my $name = $region_info->{name} || "UNKNOWN";
79 my $x = $region_info->{x} || -1;
80 my $y = $region_info->{y} || -1;
81 my $ip = $region_info->{sim_ip} || "UNKNOWN";
82 my $port = $region_info->{sim_port} || "UNKNOWN";
83 my $get_scene_presence_filter = $region_info->{get_scene_presence_filter};
84 my $get_scene_presence = $region_info->{get_scene_presence};
85 my $get_avatar_filter = $region_info->{get_avatar_filter};
86 my $get_avatar = $region_info->{get_avatar};
87 my $avatar_names = $region_info->{avatar_names};
88 my $action_forms = &_action_forms($region_info);
89 my $html = <<"REGION_HTML";
90<strong>$name</strong><br/>
91$ip:$port | X: $x Y: $y<br/>
92<table border="0">
93<tr>
94<td>get_avatar</td>
95<td>$get_avatar</td>
96<td></td>
97</tr>
98<tr>
99<td>get_avatar_filter</td>
100<td>$get_avatar_filter</td>
101<td>$avatar_names</td>
102</tr>
103<tr>
104<td>get_scene_presence</td>
105<td>$get_scene_presence</td>
106<td></td>
107</tr>
108<tr>
109<td>get_scene_presence_filter</td>
110<td>$get_scene_presence_filter</td>
111<td></td>
112</tr>
113</table>
114$action_forms
115REGION_HTML
116 return $html;
117}
118
119sub _action_forms {
120 my $region_info = shift;
121 my $ip = $region_info->{sim_ip};
122 my $port = $region_info->{sim_port};
123 my $default_input_port = $max_port + 1;
124 my $move_to_options = "";
125 my $split_to_options = "";
126 my $merge_ip_options = "";
127 foreach(@server_list) {
128 next if ($_ eq "max_port");
129 $merge_ip_options .= "<option value=\"$_\">$_\n";
130 $split_to_options .= "<option value=\"$_\">$_\n";
131 #next if ($_ eq $ip);
132 $move_to_options .= "<option value=\"$_\">$_\n";
133 }
134 my $merge_port_options = "";
135 my $merge_disabled = "disabled";
136
137 foreach(keys %{$regions->{$ip}}) {
138 next if ($_ eq $port);
139 $merge_disabled = "";
140 }
141# for(9000..$max_port) { # TODO :
142# next if ($_ eq $port);
143# $merge_port_options .= "<option value=\"$_\">$_\n";
144# }
145 my %port = ();
146 foreach my $ip (keys %$regions) {
147 next if ($ip eq "max_port");
148 print STDERR "--" . $ip . "\n";
149 foreach my $region_port (keys %{$regions->{$ip}}) {
150 print STDERR "---" . $region_port . "\n";
151 $port{$region_port} = 1;
152 }
153 }
154 foreach (keys %port) {
155 $merge_port_options .= "<option value=\"$_\">$_\n";
156 $merge_disabled = "";
157 }
158 return << "ACTION_FORMS";
159<table>
160<tr>
161<form method="POST">
162<td>
163<input type="hidden" name="A" value="move" />
164<input type="hidden" name="from_ip" value="$ip" />
165<input type="hidden" name="from_port" value="$port" />
166<input type="submit" value="Move to" />
167<select name="to_ip">
168$move_to_options
169</select>:
170<input type="text" name="to_port" size="5" value="$default_input_port"/>
171</td>
172</form>
173
174<td>
175&nbsp;&nbsp;|&nbsp;&nbsp;
176</td>
177
178<form method="POST">
179<td>
180<input type="hidden" name="A" value="split" />
181<input type="hidden" name="from_ip" value="$ip" />
182<input type="hidden" name="from_port" value="$port" />
183<input type="submit" value="Split to" />
184<select name="to_ip">
185$split_to_options
186</select>:
187<input type="text" name="to_port" size="5" value="$default_input_port"/>
188</td>
189</form>
190
191<td>
192&nbsp;&nbsp;|&nbsp;&nbsp;
193</td>
194
195<form method="POST">
196<td>
197<input type="hidden" name="A" value="merge" />
198<input type="hidden" name="from_ip" value="$ip" />
199<input type="hidden" name="master_port" value="$port" />
200<input type="submit" value="Merge" $merge_disabled />
201<select name="slave_ip" $merge_disabled>
202$merge_ip_options
203</select>
204<select name="slave_port" $merge_disabled>
205$merge_port_options
206</select>
207</td>
208</form>
209</tr>
210</table>
211ACTION_FORMS
212}
213
2141;
diff --git a/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MyCGI.pm b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MyCGI.pm
new file mode 100644
index 0000000..1f232aa
--- /dev/null
+++ b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/MyCGI.pm
@@ -0,0 +1,91 @@
1package MyCGI;
2
3use strict;
4use CGI;
5
6sub getParam {
7 my $cgi;
8 if ($ARGV[0]) {
9 $cgi = new CGI($ARGV[0]);
10 } else {
11 $cgi = new CGI;
12 }
13 my @param_names = $cgi->param();
14 my %param = ();
15 foreach (@param_names) {
16 $param{$_} = $cgi->param($_);
17 }
18 return \%param;
19}
20
21sub getCookie {
22 my $name = shift;
23 my $cookie_value = &CGI::cookie($name);
24 return &_parse($cookie_value);
25}
26
27sub outputHtml {
28 my ($charset, $html) = @_;
29 print &CGI::header(-charset => $charset);
30 print $html;
31}
32
33sub outputXml {
34 my ($charset, $xml) = @_;
35 print &CGI::header( -type => 'text/xml', -charset => $charset );
36 print $xml;
37}
38
39sub makeCookieValue {
40 my $param = shift;
41 my @data = ();
42 foreach(keys %$param) {
43 push(@data, $_ . "=" . $param->{$_});
44 }
45 return join("&", @data);
46}
47
48sub setCookie {
49 my $param = shift;
50 my $cookie = &CGI::cookie(
51 -name => $param->{name} || return,
52 -value => $param->{value},
53 -domain => $param->{domain},
54 -path => $param->{path},
55 -expires => $param->{expires},
56 );
57 return &CGI::header(-cookie => $cookie);
58}
59
60sub redirect {
61 my $dest = shift;
62 &CGI::redirect($dest);
63}
64
65sub urlEncode {
66 my $str = shift;
67 $str =~ s/([^\w ])/'%'.unpack('H2', $1)/eg;
68 $str =~ tr/ /+/;
69 return $str;
70}
71
72sub urlDecode {
73 my $str = shift;
74 $str =~ tr/+/ /;
75 $str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
76 return $str;
77}
78
79sub _parse {
80 my $value = shift;
81 my @pair = split(/&/, $value);
82 my %data = ();
83 foreach(@pair) {
84 my ($name, $value) = split(/=/, $_);
85 $data{$name} = $value;
86 }
87 return \%data;
88}
89
901;
91
diff --git a/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/monitor.cgi b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/monitor.cgi
new file mode 100644
index 0000000..a5f6445
--- /dev/null
+++ b/ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs/monitor.cgi
@@ -0,0 +1,202 @@
1#!/usr/bin/perl -w
2
3use strict;
4use Carp;
5use MyCGI;
6use XML::RPC;
7use MonitorGUI::View;
8
9use vars qw ($THIS_URL $GRID_SERVER_URL $DEFAULT_PROXY_PORT);
10$THIS_URL = "http://10.8.1.165/monitorgui/monitor.cgi";
11$GRID_SERVER_URL = "http://10.8.1.165/opensim/grid.cgi";
12$DEFAULT_PROXY_PORT = 9000;
13
14my %ACTIONS = (
15 # Region commands
16 move => \&move_command,
17 split => \&split_command,
18 merge => \&merge_command,
19 # display commands
20 default => \&main_screen,
21 refresh => \&refresh,
22);
23
24# ##################
25# main
26my $param = &MyCGI::getParam;
27my $act = $param->{A} || "default";
28my $contents = "";
29if (!$ACTIONS{$act}) {
30 &gui_error("404 NOT FOUND");
31} else {
32 eval {
33 $ACTIONS{$act}->($param);
34 };
35 if ($@) {
36 &gui_error($@);
37 }
38}
39
40# #################
41# Region Commands
42sub move_command {
43 my $param = shift;
44 # from
45 my $from_ip = $param->{from_ip} || Carp::croak("not enough params (from_ip)");
46 my $from_port = $param->{from_port} || Carp::croak("not enough params (from_port)");
47 my $from_url = "http://" . $param->{from_ip} . ":" . $DEFAULT_PROXY_PORT;
48 # to
49 my $to_ip = $param->{to_ip} || Carp::croak("not enough params (to_ip)");
50 my $to_port = $param->{to_port} || Carp::croak("not enough params (to_port)");
51 my $to_url = "http://" . $param->{to_ip} . ":" . $DEFAULT_PROXY_PORT;
52 # commands
53 eval {
54 &OpenSim::Utility::XMLRPCCall_array($from_url, "SerializeRegion", [$from_ip, $from_port]);
55 &OpenSim::Utility::XMLRPCCall_array($to_url, "DeserializeRegion_Move", [$from_ip, $from_port, $to_ip, $to_port]);
56 &OpenSim::Utility::XMLRPCCall_array($from_url, "TerminateRegion", [$from_port]);
57 };
58 if ($@) {
59 print STDERR "Get Status Error: $@\n";
60 }
61
62 # client refresh
63 &redirect_refresh({wait=>5, force=>"$from_url|$to_url", msg=>"Move region $from_ip:$from_port from $from_url to $to_url"});
64}
65
66sub split_command {
67 my $param = shift;
68 # from
69 my $from_ip = $param->{from_ip} || Carp::croak("not enough params (from_ip)");
70 my $from_port = $param->{from_port} || Carp::croak("not enough params (from_port)");
71 my $from_url = "http://" . $param->{from_ip} . ":" . $DEFAULT_PROXY_PORT;
72 # to
73 my $to_ip = $param->{to_ip} || Carp::croak("not enough params (to_ip)");
74 my $to_port = $param->{to_port} || Carp::croak("not enough params (to_port)");
75 my $to_url = "http://" . $param->{to_ip} . ":" . $DEFAULT_PROXY_PORT;
76 # commands
77 eval {
78 &OpenSim::Utility::XMLRPCCall_array($from_url, "SerializeRegion", [$from_ip, $from_port]);
79 &OpenSim::Utility::XMLRPCCall_array($to_url, "DeserializeRegion_Clone", [$from_ip, $from_port, $to_ip, $to_port]);
80 };
81 if ($@) {
82 print STDERR "Get Status Error: $@\n";
83 }
84
85 &redirect_refresh({wait=>5, force=>"$from_url", msg=>"Split region $from_ip:$from_port"});
86}
87
88sub merge_command {
89 my $param = shift;
90 # from
91 my $from_ip = $param->{from_ip} || Carp::croak("not enough params (from_ip)");
92 my $url = "http://" . $param->{from_ip} . ":" . $DEFAULT_PROXY_PORT;
93 # ports
94 my $master_port = $param->{master_port} || Carp::croak("not enough params (master_port)");
95 my $slave_ip = $param->{slave_ip} || Carp::croak("not enough params (slave_ip)");
96 my $slave_port = $param->{slave_port} || Carp::croak("not enough params (slave_port)");
97 my $slave_url = "http://" . $param->{slave_ip} . ":" . $DEFAULT_PROXY_PORT;
98 # commands
99 eval {
100 &XMLRPCCall_array($url, "MergeRegions", [$from_ip, $master_port]);
101 &XMLRPCCall_array($slave_url, "TerminateRegion", [$slave_port]);
102 };
103 if ($@) {
104 print STDERR "Get Status Error: $@\n";
105 }
106 &redirect_refresh({wait=>5, force=>"$url", msg=>"Merge region $from_ip:$master_port, $slave_port"});
107}
108
109# #################
110# Display
111sub main_screen {
112 my %xml_rpc_param = (
113 # TODO: should be 0 - 65535 ?
114 xmin => 999, ymin => 999, xmax => 1010, ymax => 1010,
115 );
116 my $res_obj = undef;
117 eval {
118 $res_obj = &XMLRPCCall($GRID_SERVER_URL, "map_block", \%xml_rpc_param);
119 };
120 if ($@) {
121 &gui_error("map_block Error: " . $@);
122 }
123 my %copy_obj = %$res_obj;
124 my $getstatus_failed = "<font color=\"red\">GetStatus Failed</font>";
125 my $regions_list = $res_obj->{"sim-profiles"};
126 foreach(@$regions_list) {
127 if ($_->{sim_ip} && $_->{sim_port}) {
128 my $url = "http://" . $_->{sim_ip} . ":" . $DEFAULT_PROXY_PORT;
129 my $port = $_->{sim_port};
130 my $res = undef;
131 eval {
132 $res = &XMLRPCCall_array($url, "GetStatus", [$port]);
133 };
134 if ($@) {
135 print STDERR "Get Status Error: $@\n";
136 }
137 $_->{get_scene_presence_filter} = $res ? $res->{get_scene_presence_filter} : $getstatus_failed;
138 $_->{get_scene_presence} = $res ? $res->{get_scene_presence} : $getstatus_failed;
139 $_->{get_avatar_filter} = $res ? $res->{get_avatar_filter} : $getstatus_failed;
140 $_->{get_avatar} = $res ? $res->{get_avatar} : $getstatus_failed;
141 $_->{avatar_names} = $res ? $res->{avatar_names} : "NO USER";
142 }
143 }
144 my $html = &MonitorGUI::View::html(\%copy_obj);
145 &MyCGI::outputHtml("UTF-8", &MonitorGUI::View::screen_header . $html . &MonitorGUI::View::screen_footer);
146}
147
148sub gui_error {
149 my $msg = shift;
150 &MyCGI::outputHtml("UTF-8", "<h1>ERROR</h1><hr />$msg");
151}
152
153sub redirect_refresh {
154 my $args = shift;
155 my $wait = $args->{wait};
156 my $force = $args->{force} || "";
157 my $msg = $args->{msg} || "";
158 my $param = "A=refresh&wait=$wait&ip=$force&msg=$msg";
159 my $dist_url = $THIS_URL . "?" . $param;
160 &MyCGI::redirect($dist_url);
161}
162
163sub refresh {
164 my $param = shift;
165 my $msg = $param->{msg} || "";
166 my $wait = $param->{wait} || 0;
167 my $force = $param->{ip} || "";
168 #my $jump_url = $force ? "$THIS_URL?A=force&ip=$force" : $THIS_URL;
169 my $jump_url = $THIS_URL;
170 my $html =<< "HTML";
171<html>
172<head>
173<meta http-equiv="Refresh" content="$wait;URL=$jump_url" />
174<title>Region Monitor GUI REFRESH</title>
175</head>
176<body>
177<h3>$msg</h3>
178<br>
179wait <font color="red"><b>$wait</b></font> sec for server to take effect ... <br>
180(* The page will jump to "Monitor Screen" automatically)
181</body>
182</html>
183HTML
184 &MyCGI::outputHtml("UTF-8", $html);
185}
186
187# ##################
188# Utility
189sub XMLRPCCall {
190 my ($url, $methodname, $param) = @_;
191 my $xmlrpc = new XML::RPC($url);
192 my $result = $xmlrpc->call($methodname, $param);
193 return $result;
194}
195
196sub XMLRPCCall_array {
197 my ($url, $methodname, $param) = @_;
198 my $xmlrpc = new XML::RPC($url);
199 my $result = $xmlrpc->call($methodname, @$param);
200 return $result;
201}
202
diff --git a/ThirdParty/3Di/RegionMonitor/ServerPlugin/RegionMonitorPlugin.cs b/ThirdParty/3Di/RegionMonitor/ServerPlugin/RegionMonitorPlugin.cs
new file mode 100644
index 0000000..5d2df3a
--- /dev/null
+++ b/ThirdParty/3Di/RegionMonitor/ServerPlugin/RegionMonitorPlugin.cs
@@ -0,0 +1,129 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Runtime.Remoting;
30using System.Threading;
31using Mono.Addins;
32using OpenSim;
33using OpenSim.Framework.Console;
34using MonitorLib;
35
36[assembly:Addin]
37[assembly:AddinDependency ("OpenSim", "0.5")]
38
39namespace OpenSim.ApplicationPlugins.RegionMonitor
40{
41 [Extension("/OpenSim/Startup")]
42 public class RegionMonitorPlugin : MonitorLibBase, IApplicationPlugin
43 {
44 protected Thread m_mointorThread;
45 protected static OpenSimMain m_openSimMain;
46
47 public void Initialise(OpenSimMain opensim)
48 {
49 m_openSimMain = opensim;
50 Start();
51 MainLog.Instance.Verbose("Monitor", "Region monitor is runing ...");
52 }
53
54 public void Close()
55 {
56 }
57
58 public void Start()
59 {
60 // start monitor thread (remoting module)
61 m_mointorThread = new Thread(new ThreadStart(StartMonitor));
62 m_mointorThread.IsBackground = true;
63 m_mointorThread.Start();
64 }
65
66 private void StartMonitor()
67 {
68 try
69 {
70 Object lockObj = new Object();
71
72 RemotingConfiguration.Configure("monitorS.config", false);
73
74 lock (lockObj)
75 {
76 System.Threading.Monitor.Wait(lockObj);
77 }
78 }
79 catch (Exception e)
80 {
81 MainLog.Instance.Warn("MONITOR", "Error - " + e.Message);
82 }
83 }
84
85 public override bool FetchInfo(out string outstr)
86 {
87 MainLog.Instance.Verbose("MONITOR", "Fetch Information from Region server");
88 bool status = true;
89 string startTime = "";
90 string upTime = "";
91 int userNumber = 0;
92 int regionNumber = 0;
93 m_openSimMain.GetRunTime(out startTime, out upTime);
94 m_openSimMain.GetAvatarNumber(out userNumber);
95 m_openSimMain.GetRegionNumber(out regionNumber);
96 outstr = startTime
97 + "," + upTime
98 + "," + regionNumber
99 + "," + userNumber;
100 return status;
101 }
102
103
104 public override bool MoveRegion()
105 {
106 MainLog.Instance.Verbose("MONITOR", "Move Region");
107 bool status = true;
108
109 return status;
110 }
111
112 public override bool SplitRegion()
113 {
114 MainLog.Instance.Verbose("MONITOR", "Split Region");
115 bool status = true;
116
117 return status;
118 }
119
120 public override bool MergeScenes()
121 {
122 MainLog.Instance.Verbose("MONITOR", "Merge Scenes");
123 bool status = true;
124
125 return status;
126 }
127
128 }
129}
diff --git a/ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs b/ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs
new file mode 100644
index 0000000..13aec48
--- /dev/null
+++ b/ThirdParty/3Di/RegionProxy/RegionProxyPlugin.cs
@@ -0,0 +1,513 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.IO;
31using System.Net;
32using System.Xml;
33using System.Text;
34using System.Xml.Serialization;
35using System.Net.Sockets;
36using System.Collections;
37using System.Collections.Generic;
38using System.Diagnostics;
39
40using OpenSim.Framework;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Console;
43using Nwc.XmlRpc;
44
45using Mono.Addins;
46
47[assembly:Addin]
48[assembly:AddinDependency ("OpenSim", "0.5")]
49
50namespace OpenSim.ApplicationPlugins.RegionProxy
51{
52 /* This module has an interface to OpenSim clients that is constant, and is responsible for relaying
53 * messages to and from clients to the region objects. Since the region objects can be duplicated and
54 * moved dynamically, the proxy provides methods for changing and adding regions. If more than one region
55 * is associated with a client port, then the message will be broadcasted to all those regions.
56 *
57 * The client interface port may be blocked. While being blocked, all messages from the clients will be
58 * stored in the proxy. Once the interface port is unblocked again, all stored messages will be resent
59 * to the regions. This functionality is used when moving or cloning an region to make sure that no messages
60 * are sent to the region while it is being reconfigured.
61 *
62 * The proxy opens a XmlRpc interface with these public methods:
63 * - AddPort
64 * - AddRegion
65 * - ChangeRegion
66 * - BlockClientMessages
67 * - UnblockClientMessages
68 */
69
70 [Extension("/OpenSim/Startup")]
71 public class RegionProxyPlugin : IApplicationPlugin
72 {
73 private ProxyServer proxy;
74 private BaseHttpServer command_server;
75 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
76
77 public void Initialise(OpenSimMain openSim)
78 {
79 Console.WriteLine("Starting proxy");
80 string proxyURL = openSim.ConfigSource.Configs["Network"].GetString("proxy_url", "");
81 if(proxyURL.Length==0) return;
82
83 uint port = (uint) Int32.Parse(proxyURL.Split(new char[] { ':' })[2]);
84 command_server = new BaseHttpServer(port);
85 command_server.Start();
86 command_server.AddXmlRPCHandler("AddPort", AddPort);
87 command_server.AddXmlRPCHandler("AddRegion", AddRegion);
88 command_server.AddXmlRPCHandler("DeleteRegion", DeleteRegion);
89 command_server.AddXmlRPCHandler("ChangeRegion", ChangeRegion);
90 command_server.AddXmlRPCHandler("BlockClientMessages", BlockClientMessages);
91 command_server.AddXmlRPCHandler("UnblockClientMessages", UnblockClientMessages);
92 command_server.AddXmlRPCHandler("Stop", Stop);
93
94 proxy=new ProxyServer(m_log);
95 }
96
97 public void Close()
98 {
99 }
100
101 private XmlRpcResponse Stop(XmlRpcRequest request)
102 {
103 try
104 {
105 proxy.Stop();
106 }
107 catch (Exception e)
108 {
109 m_log.Error("[PROXY]" + e.Message);
110 m_log.Error("[PROXY]" + e.StackTrace);
111 }
112 return new XmlRpcResponse();
113 }
114
115 private XmlRpcResponse AddPort(XmlRpcRequest request)
116 {
117 try {
118 int clientPort = (int) request.Params[0];
119 int regionPort = (int) request.Params[1];
120 string regionUrl = (string) request.Params[2];
121 proxy.AddPort(clientPort, regionPort, regionUrl);
122 } catch(Exception e) {
123 m_log.Error("[PROXY]"+e.Message);
124 m_log.Error("[PROXY]"+e.StackTrace);
125 }
126 return new XmlRpcResponse();
127 }
128
129 private XmlRpcResponse AddRegion(XmlRpcRequest request)
130 {
131 try {
132 int currentRegionPort = (int) request.Params[0];
133 string currentRegionUrl = (string) request.Params[1];
134 int newRegionPort = (int) request.Params[2];
135 string newRegionUrl = (string) request.Params[3];
136 proxy.AddRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl);
137 } catch(Exception e) {
138 m_log.Error("[PROXY]"+e.Message);
139 m_log.Error("[PROXY]"+e.StackTrace);
140 }
141 return new XmlRpcResponse();
142 }
143
144 private XmlRpcResponse ChangeRegion(XmlRpcRequest request)
145 {
146 try {
147 int currentRegionPort = (int) request.Params[0];
148 string currentRegionUrl = (string) request.Params[1];
149 int newRegionPort = (int) request.Params[2];
150 string newRegionUrl = (string) request.Params[3];
151 proxy.ChangeRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl);
152 } catch(Exception e) {
153 m_log.Error("[PROXY]"+e.Message);
154 m_log.Error("[PROXY]"+e.StackTrace);
155 }
156 return new XmlRpcResponse();
157 }
158
159 private XmlRpcResponse DeleteRegion(XmlRpcRequest request)
160 {
161 try {
162 int currentRegionPort = (int) request.Params[0];
163 string currentRegionUrl = (string) request.Params[1];
164 proxy.DeleteRegion(currentRegionPort, currentRegionUrl);
165 } catch(Exception e) {
166 m_log.Error("[PROXY]"+e.Message);
167 m_log.Error("[PROXY]"+e.StackTrace);
168 }
169 return new XmlRpcResponse();
170 }
171
172 private XmlRpcResponse BlockClientMessages(XmlRpcRequest request)
173 {
174 try {
175 string regionUrl = (string) request.Params[0];
176 int regionPort = (int) request.Params[1];
177 proxy.BlockClientMessages(regionUrl, regionPort);
178 } catch(Exception e) {
179 m_log.Error("[PROXY]"+e.Message);
180 m_log.Error("[PROXY]"+e.StackTrace);
181 }
182 return new XmlRpcResponse();
183 }
184
185 private XmlRpcResponse UnblockClientMessages(XmlRpcRequest request)
186 {
187 try {
188 string regionUrl = (string) request.Params[0];
189 int regionPort = (int) request.Params[1];
190 proxy.UnblockClientMessages(regionUrl, regionPort);
191 } catch(Exception e) {
192 m_log.Error("[PROXY]"+e.Message);
193 m_log.Error("[PROXY]"+e.StackTrace);
194 }
195 return new XmlRpcResponse();
196 }
197 }
198
199
200 public class ProxyServer {
201 protected AsyncCallback receivedData;
202 protected ProxyMap proxy_map = new ProxyMap();
203 protected readonly log4net.ILog m_log;
204 protected bool running;
205
206 protected class ProxyMap
207 {
208 public class RegionData
209 {
210 public bool isBlocked = false;
211 public Queue storedMessages = new Queue();
212 public List<EndPoint> regions = new List<EndPoint>();
213 }
214
215 private Dictionary<EndPoint, RegionData> map;
216
217 public ProxyMap() {
218 map = new Dictionary<EndPoint, RegionData>();
219 }
220
221 public void Add(EndPoint client, EndPoint region)
222 {
223 if(map.ContainsKey(client))
224 {
225 map[client].regions.Add(region);
226 }
227 else
228 {
229 RegionData regions = new RegionData();
230 map.Add(client, regions);
231 regions.regions.Add(region);
232 }
233 }
234
235 public RegionData GetRegionData(EndPoint client)
236 {
237 return map[client];
238 }
239
240 public EndPoint GetClient(EndPoint region)
241 {
242 foreach (KeyValuePair<EndPoint, RegionData> pair in map)
243 {
244 if(pair.Value.regions.Contains(region))
245 {
246 return pair.Key;
247 }
248 }
249 return null;
250 }
251 }
252
253 protected class ServerData {
254 public Socket server;
255 public EndPoint clientEP;
256 public EndPoint senderEP;
257 public IPEndPoint serverIP;
258 public byte[] recvBuffer = new byte[4096];
259
260 public ServerData()
261 {
262 server = null;
263 }
264 }
265
266 protected class StoredMessage
267 {
268 public byte[] buffer;
269 public int length;
270 public EndPoint senderEP;
271 public ServerData sd;
272
273 public StoredMessage(byte[] buffer, int length, int maxLength, EndPoint senderEP, ServerData sd)
274 {
275 this.buffer = new byte[maxLength];
276 this.length = length;
277 for(int i=0; i<length; i++) this.buffer[i]=buffer[i];
278 this.senderEP = senderEP;
279 this.sd = sd;
280 }
281 }
282
283 public ProxyServer(log4net.ILog log)
284 {
285 m_log = log;
286 running=false;
287 receivedData = new AsyncCallback(OnReceivedData);
288 }
289
290 public void BlockClientMessages(string regionUrl, int regionPort)
291 {
292 EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(regionUrl), regionPort));
293 ProxyMap.RegionData rd = proxy_map.GetRegionData(client);
294 rd.isBlocked = true;
295 }
296
297 public void UnblockClientMessages(string regionUrl, int regionPort)
298 {
299 EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(regionUrl), regionPort));
300 ProxyMap.RegionData rd = proxy_map.GetRegionData(client);
301
302 rd.isBlocked = false;
303 while(rd.storedMessages.Count > 0) {
304 StoredMessage msg = (StoredMessage) rd.storedMessages.Dequeue();
305 //m_log.Verbose("[PROXY]"+"Resending blocked message from {0}", msg.senderEP);
306 SendMessage(msg.buffer, msg.length, msg.senderEP, msg.sd);
307 }
308 }
309
310 public void AddRegion(int oldRegionPort, string oldRegionUrl, int newRegionPort, string newRegionUrl)
311 {
312 //m_log.Verbose("[PROXY]"+"AddRegion {0} {1}", oldRegionPort, newRegionPort);
313 EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort));
314 ProxyMap.RegionData data = proxy_map.GetRegionData(client);
315 data.regions.Add(new IPEndPoint(IPAddress.Parse(newRegionUrl), newRegionPort));
316 }
317
318 public void ChangeRegion(int oldRegionPort, string oldRegionUrl, int newRegionPort, string newRegionUrl)
319 {
320 //m_log.Verbose("[PROXY]"+"ChangeRegion {0} {1}", oldRegionPort, newRegionPort);
321 EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort));
322 ProxyMap.RegionData data = proxy_map.GetRegionData(client);
323 data.regions.Clear();
324 data.regions.Add(new IPEndPoint(IPAddress.Parse(newRegionUrl), newRegionPort));
325 }
326
327 public void DeleteRegion(int oldRegionPort, string oldRegionUrl)
328 {
329 m_log.InfoFormat("[PROXY]"+"DeleteRegion {0} {1}", oldRegionPort, oldRegionUrl);
330 EndPoint regionEP = new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort);
331 EndPoint client = proxy_map.GetClient(regionEP);
332 ProxyMap.RegionData data = proxy_map.GetRegionData(client);
333 data.regions.Remove(regionEP);
334 }
335
336 public void AddPort(int clientPort, int regionPort, string regionUrl)
337 {
338 running = true;
339
340 //m_log.Verbose("[PROXY]"+"AddPort {0} {1}", clientPort, regionPort);
341 IPEndPoint clientEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), clientPort);
342 proxy_map.Add(clientEP, new IPEndPoint(IPAddress.Parse(regionUrl), regionPort));
343
344 ServerData sd = new ServerData();
345 sd.clientEP = new IPEndPoint(clientEP.Address, clientEP.Port);
346
347 OpenPort(sd);
348 }
349
350 protected void OpenPort(ServerData sd)
351 {
352 // sd.clientEP must be set before calling this function
353
354 ClosePort(sd);
355
356 try
357 {
358
359 m_log.InfoFormat("[PROXY] Opening UDP socket on {0}", sd.clientEP);
360 sd.serverIP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), ((IPEndPoint)sd.clientEP).Port);
361 sd.server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
362 sd.server.Bind(sd.serverIP);
363
364 sd.senderEP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
365 //receivedData = new AsyncCallback(OnReceivedData);
366 sd.server.BeginReceiveFrom(sd.recvBuffer, 0, sd.recvBuffer.Length, SocketFlags.None, ref sd.senderEP, receivedData, sd);
367 }
368 catch (Exception e)
369 {
370 m_log.ErrorFormat("[PROXY] Failed to (re)open socket {0}", sd.clientEP);
371 m_log.Error("[PROXY]" + e.Message);
372 m_log.Error("[PROXY]" + e.StackTrace);
373 }
374 }
375
376 protected void ClosePort(ServerData sd)
377 {
378 // Close the port if it exists and is open
379 if (sd.server == null) return;
380
381 try
382 {
383 sd.server.Shutdown(SocketShutdown.Both);
384 sd.server.Close();
385 }
386 catch (Exception)
387 {
388 }
389 }
390
391 public void Stop()
392 {
393 running = false;
394 m_log.InfoFormat("[PROXY] Stopping the proxy server");
395
396 }
397
398
399 protected virtual void OnReceivedData(IAsyncResult result)
400 {
401 if(!running) return;
402
403 ServerData sd = (ServerData)result.AsyncState;
404 sd.senderEP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
405
406 try
407 {
408 int numBytes = sd.server.EndReceiveFrom(result, ref sd.senderEP);
409 if (numBytes > 0)
410 {
411 SendMessage(sd.recvBuffer, numBytes, sd.senderEP, sd);
412 }
413 }
414 catch (Exception e)
415 {
416// OpenPort(sd); // reopen the port just in case
417 m_log.ErrorFormat("[PROXY] EndReceiveFrom failed in {0}", sd.clientEP);
418 m_log.Error("[PROXY]" + e.Message);
419 m_log.Error("[PROXY]" + e.StackTrace);
420 }
421
422 WaitForNextMessage(sd);
423 }
424
425 protected void WaitForNextMessage(ServerData sd)
426 {
427 bool error = true;
428 while (error)
429 {
430 error = false;
431 try
432 {
433 sd.server.BeginReceiveFrom(sd.recvBuffer, 0, sd.recvBuffer.Length, SocketFlags.None, ref sd.senderEP, receivedData, sd);
434 }
435 catch (Exception e)
436 {
437 error = true;
438 m_log.ErrorFormat("[PROXY] BeginReceiveFrom failed, retrying... {0}", sd.clientEP);
439 m_log.Error("[PROXY]" + e.Message);
440 m_log.Error("[PROXY]" + e.StackTrace);
441 OpenPort(sd);
442 }
443 }
444 }
445
446 protected void SendMessage(byte[] buffer, int length, EndPoint senderEP, ServerData sd)
447 {
448 int numBytes = length;
449
450 //m_log.ErrorFormat("[PROXY] Got message from {0} in thread {1}, size {2}", senderEP, sd.clientEP, numBytes);
451 EndPoint client = proxy_map.GetClient(senderEP);
452
453 if (client != null)
454 {
455 try
456 {
457 client = PacketPool.DecodeProxyMessage(buffer, ref numBytes);
458 try
459 {
460 // This message comes from a region object, forward it to the its client
461 sd.server.SendTo(buffer, numBytes, SocketFlags.None, client);
462 //m_log.InfoFormat("[PROXY] Sending region message from {0} to {1}, size {2}", senderEP, client, numBytes);
463 }
464 catch (Exception e)
465 {
466 OpenPort(sd); // reopen the port just in case
467 m_log.ErrorFormat("[PROXY] Failed sending region message from {0} to {1}", senderEP, client);
468 m_log.Error("[PROXY]" + e.Message);
469 m_log.Error("[PROXY]" + e.StackTrace);
470 return;
471 }
472 }
473 catch (Exception e)
474 {
475 OpenPort(sd); // reopen the port just in case
476 m_log.ErrorFormat("[PROXY] Failed decoding region message from {0}", senderEP);
477 m_log.Error("[PROXY]" + e.Message);
478 m_log.Error("[PROXY]" + e.StackTrace);
479 return;
480 }
481
482 }
483 else
484 {
485 // This message comes from a client object, forward it to the the region(s)
486 PacketPool.EncodeProxyMessage(buffer, ref numBytes, senderEP);
487 ProxyMap.RegionData rd = proxy_map.GetRegionData(sd.clientEP);
488 foreach (EndPoint region in rd.regions)
489 {
490 if(rd.isBlocked) {
491 rd.storedMessages.Enqueue(new StoredMessage(buffer, length, numBytes, senderEP, sd));
492 }
493 else
494 {
495 try
496 {
497 sd.server.SendTo(buffer, numBytes, SocketFlags.None, region);
498 //m_log.InfoFormat("[PROXY] Sending client message from {0} to {1}", senderEP, region);
499 }
500 catch (Exception e)
501 {
502 OpenPort(sd); // reopen the port just in case
503 m_log.ErrorFormat("[PROXY] Failed sending client message from {0} to {1}", senderEP, region);
504 m_log.Error("[PROXY]" + e.Message);
505 m_log.Error("[PROXY]" + e.StackTrace);
506 return;
507 }
508 }
509 }
510 }
511 }
512 }
513}
diff --git a/prebuild.xml b/prebuild.xml
index 26d795f..4d99c8f 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -1111,6 +1111,7 @@
1111 <Reference name="OpenSim.Framework.Console"/> 1111 <Reference name="OpenSim.Framework.Console"/>
1112 <Reference name="OpenSim.Framework.Servers"/> 1112 <Reference name="OpenSim.Framework.Servers"/>
1113 <Reference name="OpenSim.Framework.Data"/> 1113 <Reference name="OpenSim.Framework.Data"/>
1114 <Reference name="OpenSim.Framework.Data.MySQL"/>
1114 <Reference name="libsecondlife.dll"/> 1115 <Reference name="libsecondlife.dll"/>
1115 <Reference name="Db4objects.Db4o.dll"/> 1116 <Reference name="Db4objects.Db4o.dll"/>
1116 <Reference name="XMLRPC.dll"/> 1117 <Reference name="XMLRPC.dll"/>
@@ -1509,6 +1510,69 @@
1509 </Files> 1510 </Files>
1510 </Project> 1511 </Project>
1511 1512
1513 <Project name="OpenSim.ApplicationPlugins.RegionProxy" path="ThirdParty/3Di/RegionProxy" type="Library">
1514 <Configuration name="Debug">
1515 <Options>
1516 <OutputPath>../../../bin/</OutputPath>
1517 </Options>
1518 </Configuration>
1519 <Configuration name="Release">
1520 <Options>
1521 <OutputPath>../../../bin/</OutputPath>
1522 </Options>
1523 </Configuration>
1524
1525 <ReferencePath>../../../bin/</ReferencePath>
1526 <Reference name="log4net" />
1527 <Reference name="Mono.Addins.dll" />
1528 <Reference name="System"/>
1529 <Reference name="System.Xml"/>
1530 <Reference name="XMLRPC.dll"/>
1531 <Reference name="Nini.dll" />
1532 <Reference name="OpenSim"/>
1533 <Reference name="OpenSim.Framework"/>
1534 <Reference name="OpenSim.Framework.Data"/>
1535 <Reference name="OpenSim.Framework.Servers"/>
1536 <Reference name="OpenSim.Framework.Console"/>
1537 <Reference name="OpenSim.Region.ClientStack"/>
1538 <Files>
1539 <Match pattern="*.cs" recurse="true"/>
1540 </Files>
1541 </Project>
1542
1543 <Project name="OpenSim.ApplicationPlugins.LoadBalancer" path="ThirdParty/3Di/LoadBalancer" type="Library">
1544 <Configuration name="Debug">
1545 <Options>
1546 <OutputPath>../../../bin/</OutputPath>
1547 </Options>
1548 </Configuration>
1549 <Configuration name="Release">
1550 <Options>
1551 <OutputPath>../../../bin/</OutputPath>
1552 </Options>
1553 </Configuration>
1554
1555 <ReferencePath>../../../bin/</ReferencePath>
1556 <Reference name="log4net" />
1557 <Reference name="Mono.Addins.dll" />
1558 <Reference name="System"/>
1559 <Reference name="System.Xml"/>
1560 <Reference name="XMLRPC.dll"/>
1561 <Reference name="Nini.dll" />
1562 <Reference name="OpenSim"/>
1563 <Reference name="OpenSim.Framework"/>
1564 <Reference name="OpenSim.Framework.Data"/>
1565 <Reference name="OpenSim.Framework.Servers"/>
1566 <Reference name="OpenSim.Framework.Console"/>
1567 <Reference name="OpenSim.Region.Environment"/>
1568 <Reference name="OpenSim.Region.ClientStack"/>
1569 <Reference name="OpenSim.Region.Physics.Manager"/>
1570 <Reference name="libsecondlife.dll"/>
1571 <Files>
1572 <Match pattern="*.cs" recurse="true"/>
1573 </Files>
1574 </Project>
1575
1512 </Solution> 1576 </Solution>
1513 1577
1514 <!-- Prebuild tool --> 1578 <!-- Prebuild tool -->